yellow copyright diff

This commit is contained in:
bryanthaboi
2026-08-10 14:27:00 -04:00
parent aa45f05c63
commit 9d73ff4110
8 changed files with 114 additions and 19 deletions
+11 -1
View File
@@ -1756,7 +1756,7 @@ end
function RomExtractor:extractField() function RomExtractor:extractField()
self:beginStage("Interface artwork") self:beginStage("Interface artwork")
local done, total = 0, 50 local done, total = 0, 51
local function tick() local function tick()
done = done + 1 done = done + 1
self:tick("Interface artwork", math.min(done, total), total) self:tick("Interface artwork", math.min(done, total), total)
@@ -1772,6 +1772,16 @@ function RomExtractor:extractField()
"title/copyright.png"); tick() "title/copyright.png"); tick()
self:raw2bpp("GameFreakLogoGraphics", 72, 8, self:raw2bpp("GameFreakLogoGraphics", 72, 8,
"title/gamefreak_inc.png"); tick() "title/gamefreak_inc.png"); tick()
do
local gf = self.symbols["GameFreakLogoGraphics"]
local tb = self.symbols["TextBoxGraphics"]
if gf and tb and tb[2] == gf[2] + 9 * 16 + 16 then
local raw = self.rom:bytes(gf[1], gf[2] + 9 * 16, 16)
self:save(ImageWriter.decode2bpp(raw, 8, 8, false), "title/nine.png")
end
end
tick()
-- Yellow fixed Pikachu title art (no-op on Red/Blue manifests). -- Yellow fixed Pikachu title art (no-op on Red/Blue manifests).
self:extractYellowTitleArt(); tick() self:extractYellowTitleArt(); tick()
+27 -8
View File
@@ -31,6 +31,7 @@
-- to just THE END. -- to just THE END.
local Font = require("src.render.Font") local Font = require("src.render.Font")
local GameVersion = require("src.core.GameVersion")
local Music = require("src.core.Music") local Music = require("src.core.Music")
local Strings = require("src.core.Strings") local Strings = require("src.core.Strings")
@@ -64,11 +65,12 @@ local MON_PREP_FRAMES = 9
-- LoadCopyrightTiles (engine/movie/title.asm CopyrightTextString): tile -- LoadCopyrightTiles (engine/movie/title.asm CopyrightTextString): tile
-- sequences into the extracted title/copyright.png strip (tiles $60-$72: -- sequences into the extracted title/copyright.png strip (tiles $60-$72:
-- (c)'95.'96.'98 + Nintendo + Creatures inc.); the GAME FREAK inc. row is -- Red/Blue (c)'95.'96.'98, Yellow (c)1995-1999 + NineTile) + Nintendo +
-- the title/gamefreak_inc.png strip (GameFreakLogoGraphics, tiles -- Creatures inc.; the GAME FREAK inc. row is title/gamefreak_inc.png
-- $73-$7B), with the intro's composed gamefreak_text.png as a fallback -- (GameFreakLogoGraphics, tiles $73-$7B), with the intro's composed
-- for pre-regeneration data. -- gamefreak_text.png as a fallback for pre-regeneration data.
local COPY_PREFIX = { 0, 1, 2, 1, 3, 1, 4 } -- (c)'95.'96.'98 local COPY_PREFIX_RB = { 0, 1, 2, 1, 3, 1, 4 } -- (c)'95.'96.'98
local COPY_PREFIX_YELLOW = { 0, 1, 2, 3, 1, 2 } -- (c)1995-199
local COPY_NINTENDO = { 5, 6, 7, 8, 9, 10 } -- Nintendo local COPY_NINTENDO = { 5, 6, 7, 8, 9, 10 } -- Nintendo
local COPY_CREATURES = { 11, 12, 13, 14, 15, 16, 17, 18 } -- Creatures inc. local COPY_CREATURES = { 11, 12, 13, 14, 15, 16, 17, 18 } -- Creatures inc.
@@ -140,6 +142,12 @@ function Credits.new(game, onDone, onTheEnd)
and title.gamefreakInc.path) and title.gamefreakInc.path)
or tryImage(intro and intro.gamefreakText or tryImage(intro and intro.gamefreakText
and intro.gamefreakText.path) and intro.gamefreakText.path)
self.yellowCopy = GameVersion.isYellow()
or (title and title.layout == "yellow_pikachu")
self.copyPrefix = self.yellowCopy and COPY_PREFIX_YELLOW or COPY_PREFIX_RB
self.nineImg = self.yellowCopy and tryImage(
title and title.nine and title.nine.path
or "assets/generated/title/nine.png") or nil
return self return self
end end
@@ -255,6 +263,17 @@ function Credits:drawPage(screen, xoff, shade)
if screen.copyright then self:drawCopyright(xoff) end if screen.copyright then self:drawCopyright(xoff) end
end end
function Credits:drawCopyPrefix(x, y)
local img = self.copyImg
for _, t in ipairs(self.copyPrefix) do
love.graphics.draw(img, self.copyQuads[t], x, y)
x = x + 8
end
if self.nineImg then
love.graphics.draw(self.nineImg, x, y)
end
end
function Credits:drawCopyright(xoff) function Credits:drawCopyright(xoff)
local img = self.copyImg local img = self.copyImg
if img then if img then
@@ -267,11 +286,11 @@ function Credits:drawCopyright(xoff)
end end
return x return x
end end
row(COPY_PREFIX, xoff + 16, 56) self:drawCopyPrefix(xoff + 16, 56)
row(COPY_NINTENDO, xoff + 80, 56) row(COPY_NINTENDO, xoff + 80, 56)
row(COPY_PREFIX, xoff + 16, 72) self:drawCopyPrefix(xoff + 16, 72)
row(COPY_CREATURES, xoff + 80, 72) row(COPY_CREATURES, xoff + 80, 72)
row(COPY_PREFIX, xoff + 16, 88) self:drawCopyPrefix(xoff + 16, 88)
if self.gfImg then if self.gfImg then
love.graphics.draw(self.gfImg, xoff + 80, 88) love.graphics.draw(self.gfImg, xoff + 80, 88)
else else
+25 -3
View File
@@ -2,6 +2,7 @@
-- ..(engine/movie/splash.asm ln 27) -- ..(engine/movie/splash.asm ln 27)
local Font = require("src.render.Font") local Font = require("src.render.Font")
local GameVersion = require("src.core.GameVersion")
local Music = require("src.core.Music") local Music = require("src.core.Music")
local Sound = require("src.core.Sound") local Sound = require("src.core.Sound")
local Strings = require("src.core.Strings") local Strings = require("src.core.Strings")
@@ -56,8 +57,13 @@ local SPLASH_FRAMES = WAVES_END + 40 -- ld c, 40 (intro.asm:329-331)
local LOGO_X, LOGO_Y = 72, 56 local LOGO_X, LOGO_Y = 72, 56
local TEXT_X, TEXT_Y = 40, 80 local TEXT_X, TEXT_Y = 40, 80
-- ..(engine/movie/title.asm ln 390) -- CopyrightTextString (engine/movie/title.asm). Red/Blue years are
local COPY_PREFIX = { 0, 1, 2, 1, 3, 1, 4 } -- (c)'95.'96.'98; Yellow's sheet spells (c)1995-1999 and finishes the
-- last digit with NineTile (title screen). Intro originally overflows
-- into the font "A" tile for that digit; we draw NineTile so both
-- screens read 1999.
local COPY_PREFIX_RB = { 0, 1, 2, 1, 3, 1, 4 }
local COPY_PREFIX_YELLOW = { 0, 1, 2, 3, 1, 2 }
local COPY_NINTENDO = { 5, 6, 7, 8, 9, 10 } local COPY_NINTENDO = { 5, 6, 7, 8, 9, 10 }
local COPY_CREATURES = { 11, 12, 13, 14, 15, 16, 17, 18 } local COPY_CREATURES = { 11, 12, 13, 14, 15, 16, 17, 18 }
@@ -143,6 +149,12 @@ function IntroMovie.new(game, onDone)
end end
self.gfInc = img(titleCfg.gamefreakInc) self.gfInc = img(titleCfg.gamefreakInc)
or tryImage("assets/generated/title/gamefreak_inc.png") or tryImage("assets/generated/title/gamefreak_inc.png")
-- ..(pokeyellow engine/movie/title.asm CopyrightTextString / NineTile)
self.yellowCopy = GameVersion.isYellow()
or titleCfg.layout == "yellow_pikachu"
self.copyPrefix = self.yellowCopy and COPY_PREFIX_YELLOW or COPY_PREFIX_RB
self.nineImg = self.yellowCopy and (
img(titleCfg.nine) or tryImage("assets/generated/title/nine.png")) or nil
self.studioLogo = tryImage(self.studio.logo) self.studioLogo = tryImage(self.studio.logo)
if self.studioLogo then if self.studioLogo then
self.studioLogo:setFilter("nearest", "nearest") self.studioLogo:setFilter("nearest", "nearest")
@@ -364,6 +376,16 @@ function IntroMovie:drawFight()
end end
end end
function IntroMovie:drawCopyPrefix(x, y)
for _, t in ipairs(self.copyPrefix) do
love.graphics.draw(self.copyright, self.copyQuads[t], x, y)
x = x + 8
end
if self.nineImg then
love.graphics.draw(self.nineImg, x, y)
end
end
function IntroMovie:drawCopyright() function IntroMovie:drawCopyright()
if self.studio.card or self.studio.credit then if self.studio.card or self.studio.credit then
local card = self.studio.card or "" local card = self.studio.card or ""
@@ -378,7 +400,7 @@ function IntroMovie:drawCopyright()
x = x + 8 x = x + 8
end end
end end
for _, y in ipairs({ 56, 72, 88 }) do row(COPY_PREFIX, 16, y) end for _, y in ipairs({ 56, 72, 88 }) do self:drawCopyPrefix(16, y) end
row(COPY_NINTENDO, 80, 56) row(COPY_NINTENDO, 80, 56)
row(COPY_CREATURES, 80, 72) row(COPY_CREATURES, 80, 72)
love.graphics.draw(self.gfInc, 80, 88) love.graphics.draw(self.gfInc, 80, 88)
+10 -4
View File
@@ -226,6 +226,11 @@ function TitleState.new(game, opts)
self.blue = GameVersion.isBlue() self.blue = GameVersion.isBlue()
self.yellow = GameVersion.isYellow() self.yellow = GameVersion.isYellow()
or title.layout == "yellow_pikachu" or title.layout == "yellow_pikachu"
-- ..(pokeyellow engine/movie/title.asm .tileScreenCopyrightTiles / NineTile)
self.nineImg = self.yellow and tryImage(imagePath(title.nine)
or "assets/generated/title/nine.png") or nil
self.copyPrefix = self.yellow
and { 0, 1, 2, 3, 1, 2 } or { 0, 1, 2, 1, 3, 1, 4 }
-- Yellow title is a fixed Pikachu composition (title_yellow.asm), not -- Yellow title is a fixed Pikachu composition (title_yellow.asm), not
-- TitleMons cycling. Prefer composed pikachu.png from the Yellow import. -- TitleMons cycling. Prefer composed pikachu.png from the Yellow import.
self.yellowPikachu = self.yellow and tryImage(imagePath(title.pikachu) self.yellowPikachu = self.yellow and tryImage(imagePath(title.pikachu)
@@ -665,16 +670,17 @@ function TitleState:draw()
self:drawCopyright(136 + (preRibbon and 0 or scrollY)) self:drawCopyright(136 + (preRibbon and 0 or scrollY))
end end
-- ..(engine/movie/title.asm ln 117)
local COPY_PREFIX = { 0, 1, 2, 1, 3, 1, 4 }
function TitleState:drawCopyright(y) function TitleState:drawCopyright(y)
if not self.title.copyrightText and self.copyImg and self.gfInc then if not self.title.copyrightText and self.copyImg and self.gfInc then
local x = 16 local x = 16
for _, t in ipairs(COPY_PREFIX) do for _, t in ipairs(self.copyPrefix) do
love.graphics.draw(self.copyImg, self.copyQuads[t], x, y) love.graphics.draw(self.copyImg, self.copyQuads[t], x, y)
x = x + 8 x = x + 8
end end
if self.nineImg then
love.graphics.draw(self.nineImg, x, y)
x = x + 8
end
love.graphics.draw(self.gfInc, x, y) love.graphics.draw(self.gfInc, x, y)
return return
end end
+7 -1
View File
@@ -37,7 +37,8 @@ end
local Y_TITLE = { local Y_TITLE = {
"pikachu.png", "pika_bubble.png", "eyes_half.png", "eyes_closed.png", "pikachu.png", "pika_bubble.png", "eyes_half.png", "eyes_closed.png",
"player.png", "copyright.png", "gamefreak_inc.png", "yellow_version.png", "player.png", "copyright.png", "gamefreak_inc.png", "nine.png",
"yellow_version.png",
} }
for _, name in ipairs(Y_TITLE) do for _, name in ipairs(Y_TITLE) do
seed("yellow/assets/generated/title/" .. name) seed("yellow/assets/generated/title/" .. name)
@@ -207,6 +208,11 @@ check(pre ~= nil, "the IntroMovie pre-roll was constructed")
eq(pre and pre.copyright and pre.copyright.path, eq(pre and pre.copyright and pre.copyright.path,
"yellow/assets/generated/title/copyright.png", "yellow/assets/generated/title/copyright.png",
"copyright card resolves to the yellow/ copy") "copyright card resolves to the yellow/ copy")
eq(pre and pre.nineImg and pre.nineImg.path,
"yellow/assets/generated/title/nine.png",
"copyright NineTile resolves to the yellow/ copy")
check(pre and pre.yellowCopy == true,
"IntroMovie selects the Yellow (c)1995-1999 tile sequence")
eq(pre and pre.studioLogo and pre.studioLogo.path, eq(pre and pre.studioLogo and pre.studioLogo.path,
"yellow/assets/generated/intro/studio_logo.png", "yellow/assets/generated/intro/studio_logo.png",
"data-driven studio logo resolves to the yellow/ copy") "data-driven studio logo resolves to the yellow/ copy")
+11
View File
@@ -1747,6 +1747,17 @@ def extract_field(rom, symbols, manifest, out_dir, assets_dir):
"title/copyright.png") "title/copyright.png")
raw_2bpp( raw_2bpp(
"GameFreakLogoGraphics", 72, 8, "title/gamefreak_inc.png") "GameFreakLogoGraphics", 72, 8, "title/gamefreak_inc.png")
# Yellow NineTile (pokeyellow gfx/font.asm): final "9" of (c)1995-1999,
# parked in the 16 bytes between GameFreakLogoGraphics and TextBoxGraphics.
if _has_symbol(symbols, "GameFreakLogoGraphics") \
and _has_symbol(symbols, "TextBoxGraphics"):
gf = _symbol(symbols, "GameFreakLogoGraphics")
tb = _symbol(symbols, "TextBoxGraphics")
if tb.address == gf.address + 9 * 16 + 16:
nine_raw = rom.bytes(gf.bank, gf.address + 9 * 16, 16)
_save_png(
_decode_2bpp(nine_raw, 8, 8, False),
os.path.join(assets_dir, "title/nine.png"))
# Yellow fixed Pikachu title (pret/pokeyellow title_yellow.asm): tilemap # Yellow fixed Pikachu title (pret/pokeyellow title_yellow.asm): tilemap
# composition over both tile banks -- PokemonLogoGraphics in vChars2 # composition over both tile banks -- PokemonLogoGraphics in vChars2
+4 -2
View File
@@ -1471,9 +1471,11 @@ def extract(pokered, out_dir):
util.die("bike riding tileset extraction sanity check failed") util.die("bike riding tileset extraction sanity check failed")
if indoor_encounters["firstIndoorMap"] != 0x25: if indoor_encounters["firstIndoorMap"] != 0x25:
util.die("indoor encounter boundary sanity check failed") util.die("indoor encounter boundary sanity check failed")
if len(title) != 5 or any(not v["width"] for v in title.values()) \ if len(title) not in (5, 6) or any(not v["width"] for v in title.values()) \
or (title["gamefreakInc"]["width"], or (title["gamefreakInc"]["width"],
title["gamefreakInc"]["height"]) != (72, 8): title["gamefreakInc"]["height"]) != (72, 8) \
or ("nine" in title and (title["nine"]["width"],
title["nine"]["height"]) != (8, 8)):
util.die("title asset extraction sanity check failed") util.die("title asset extraction sanity check failed")
if any((intro["gengar"][f]["width"], intro["gengar"][f]["height"]) if any((intro["gengar"][f]["width"], intro["gengar"][f]["height"])
!= (56, 56) for f in ("frame1", "frame2", "frame3")) \ != (56, 56) for f in ("frame1", "frame2", "frame3")) \
+19
View File
@@ -130,6 +130,12 @@ TITLE_GRAPHICS = [
("gamefreakInc", "gfx/title/gamefreak_inc.png", False), ("gamefreakInc", "gfx/title/gamefreak_inc.png", False),
] ]
# Yellow only (pokeyellow gfx/font.asm NineTile): final "9" of (c)1995-1999
# on the title copyright line and intro/credits copyright card.
OPTIONAL_TITLE_GRAPHICS = [
("nine", "gfx/title/nine.png", False),
]
def extract_title(pokered, assets_dir): def extract_title(pokered, assets_dir):
"""Convert the title-screen graphics to assets/generated/title/. """Convert the title-screen graphics to assets/generated/title/.
@@ -150,6 +156,19 @@ def extract_title(pokered, assets_dir):
"height": size[1], "height": size[1],
"source": src_rel, "source": src_rel,
} }
for key, src_rel, matte in OPTIONAL_TITLE_GRAPHICS:
src = os.path.join(pokered, src_rel)
if not os.path.isfile(src):
continue
base = os.path.basename(src_rel)
size = convert_png(src, os.path.join(assets_dir, "title", base),
transparent_matte=matte)
out[key] = {
"path": f"assets/generated/title/{base}",
"width": size[0],
"height": size[1],
"source": src_rel,
}
return out return out