Compare commits

..

7 Commits

Author SHA1 Message Date
bryanthaboi aea38240b2 Merge pull request #1780 from bryanthaboi/dev
gender name string
2026-08-24 13:08:31 -04:00
bryanthaboi 0142468125 gender name string 2026-08-24 13:07:11 -04:00
github-actions e7d898625d chore(ios): update app-repo.json [skip ci] 2026-08-24 12:48:34 -04:00
bryanthaboi 5ee4a3cd35 Merge pull request #1778 from bryanthaboi/dev
some fixes
2026-08-24 12:38:35 -04:00
bryanthaboi 4794ddcfdf chris (and all gen2) fix 2026-08-24 12:35:35 -04:00
bryanthaboi 6503e982db potential fix for shaders 2026-08-24 12:10:15 -04:00
github-actions 72ce1fe33e chore(ios): update app-repo.json [skip ci] 2026-08-24 11:46:51 -04:00
11 changed files with 99 additions and 17 deletions
+14
View File
@@ -12,6 +12,20 @@
"tintColor": "3b5ca8", "tintColor": "3b5ca8",
"category": "games", "category": "games",
"versions": [ "versions": [
{
"version": "0.2.23",
"date": "2026-08-24",
"size": 14060437,
"downloadURL": "https://github.com/bryanthaboi/gen1recomp/releases/download/v0.2.23/gen1recomp++-0.2.23-ios.ipa",
"localizedDescription": "Download the correct version for your computer below.\n\n## Contributors\n\n- @bryanthaboi"
},
{
"version": "0.2.22",
"date": "2026-08-24",
"size": 14060365,
"downloadURL": "https://github.com/bryanthaboi/gen1recomp/releases/download/v0.2.22/gen1recomp++-0.2.22-ios.ipa",
"localizedDescription": "Download the correct version for your computer below.\n\n## Contributors\n\n- @bryanthaboi\n- @ShaneMcGovernIE\n- @thibautbus"
},
{ {
"version": "0.2.21", "version": "0.2.21",
"date": "2026-08-24", "date": "2026-08-24",
+9 -1
View File
@@ -9,6 +9,9 @@ local GameVersion = require("src.core.GameVersion")
local CacheContract = {} local CacheContract = {}
CacheContract.FORMAT = "rom-cache-v10:" CacheContract.FORMAT = "rom-cache-v10:"
CacheContract.VERSION_FORMAT = {
crystal = "rom-cache-v10-crystal2:",
}
CacheContract.MARKER_PATH = "rom-cache.complete" CacheContract.MARKER_PATH = "rom-cache.complete"
CacheContract.REQUIRED_FILES = { CacheContract.REQUIRED_FILES = {
@@ -136,8 +139,13 @@ function CacheContract.requiredFilesFor(version)
return CacheContract.REQUIRED_FILES, false return CacheContract.REQUIRED_FILES, false
end end
function CacheContract.formatFor(version)
return CacheContract.VERSION_FORMAT[version] or CacheContract.FORMAT
end
function CacheContract.markerFor(version, sha1) function CacheContract.markerFor(version, sha1)
return CacheContract.FORMAT .. (sha1 or GameVersion.info(version).sha1) return CacheContract.formatFor(version)
.. (sha1 or GameVersion.info(version).sha1)
end end
function CacheContract.markerMatches(version, marker) function CacheContract.markerMatches(version, marker)
+6 -6
View File
@@ -56,9 +56,6 @@ local MAP_GROUP_COUNT = 26 -- constants/map_constants.asm NUM_MAP_GROUPS
-- "bank13" (../pokecrystal/main.asm:192-195). -- "bank13" (../pokecrystal/main.asm:192-195).
local PAL_MAP_BANK = 0x02 local PAL_MAP_BANK = 0x02
local PAL_MAP_BANK_CRYSTAL = 0x13 local PAL_MAP_BANK_CRYSTAL = 0x13
-- LoadBallIconGFX.gfx (engine/battle/trainer_huds.asm:225-232); bank $0b
-- carries no manifest symbol to resolve it through.
local BALL_ICON_GFX = { 0x0b, 0x41a4 }
-- A tileset sheet is 96 tiles (128x48 at 8x8), and its PalMap packs two -- A tileset sheet is 96 tiles (128x48 at 8x8), and its PalMap packs two
-- tiles per byte: low nibble first tile, high nibble second (`dn` in the -- tiles per byte: low nibble first tile, high nibble second (`dn` in the
-- tilepal macro). The high bit of each nibble is the VRAM bank, not colour. -- tilepal macro). The high bit of each nibble is the VRAM bank, not colour.
@@ -2852,7 +2849,10 @@ function RomExtractorGen2:decodeGen2Text(bank, address, charmap, buffers)
out[#out + 1] = "\f" out[#out + 1] = "\f"
elseif b == 0x55 then elseif b == 0x55 then
out[#out + 1] = "\v" out[#out + 1] = "\v"
elseif b == 0x52 then elseif b == 0x52
or (b == 0x14 and inString and self.edition == "crystal") then
-- ../pokecrystal/constants/charmap.asm:6 <PLAY_G>,
-- ../pokecrystal/home/text.asm:243,380 PlaceGenderedPlayerName
out[#out + 1] = "{PLAYER}" out[#out + 1] = "{PLAYER}"
elseif b == 0x53 then elseif b == 0x53 then
out[#out + 1] = "{RIVAL}" out[#out + 1] = "{RIVAL}"
@@ -5716,8 +5716,8 @@ function RomExtractorGen2:extractMenuGfx()
-- Four OAM tiles at $31 -- normal, statused, fainted, empty -- and OBJ -- Four OAM tiles at $31 -- normal, statused, fainted, empty -- and OBJ
-- colour 0 is transparent (engine/battle/trainer_huds.asm:47-99, :225-232). -- colour 0 is transparent (engine/battle/trainer_huds.asm:47-99, :225-232).
local balls = self.symbols["LoadBallIconGFX.gfx"] or BALL_ICON_GFX local balls = self:symbol("LoadBallIconGFX.gfx")
self:write2bpp(self.rom:bytes(balls[1], balls[2], 4 * 16), 32, 8, self:write2bpp(self.rom:bytes(balls.bank, balls.address, 4 * 16), 32, 8,
"battle/hud/balls.png", true) "battle/hud/balls.png", true)
hud.balls = "assets/generated/battle/hud/balls.png" hud.balls = "assets/generated/battle/hud/balls.png"
hud.ballsFirstTile = 0x31 hud.ballsFirstTile = 0x31
+13 -3
View File
@@ -371,9 +371,13 @@ end
-- `es`: true for GLSL ES 1.00 (mobile), false for GLSL 1.20 (desktop). Only -- `es`: true for GLSL ES 1.00 (mobile), false for GLSL 1.20 (desktop). Only
-- ever called from ShaderFX.convert(). -- ever called from ShaderFX.convert().
function ShaderFX.translate(fullPath, es) function ShaderFX.translate(fullPath, es)
local ffi = require("ffi") local okFfi, ffi = pcall(require, "ffi")
local ok, l = pcall(ensureLib) if not okFfi or type(ffi) ~= "table" then
return nil, "this build has no ffi, so presets cannot be converted here"
end
local ok, l, lerr = pcall(ensureLib)
if not ok then return nil, "ffi.load failed: " .. tostring(l) end if not ok then return nil, "ffi.load failed: " .. tostring(l) end
if not l then return nil, tostring(lerr or libError or "librashader bridge not available") end
local ptr = l.librashader_translate_preset(fullPath, es and 1 or 0) local ptr = l.librashader_translate_preset(fullPath, es and 1 or 0)
if ptr == nil then return nil, "librashader_translate_preset returned NULL" end if ptr == nil then return nil, "librashader_translate_preset returned NULL" end
local json = ffi.string(ptr) local json = ffi.string(ptr)
@@ -780,7 +784,7 @@ end
-- Translates `entry` via the bridge and writes ShaderFX.artifactPath(entry). -- Translates `entry` via the bridge and writes ShaderFX.artifactPath(entry).
-- Sets entry.converted on success; an existing artifact survives a failure. -- Sets entry.converted on success; an existing artifact survives a failure.
function ShaderFX.convert(entry, es) local function doConvert(entry, es)
ShaderSourcePatches.apply(entry) ShaderSourcePatches.apply(entry)
local preset, err = ShaderFX.translate(entry.fullPath, es == nil and defaultEs() or es) local preset, err = ShaderFX.translate(entry.fullPath, es == nil and defaultEs() or es)
if not preset then return false, err end if not preset then return false, err end
@@ -797,6 +801,12 @@ function ShaderFX.convert(entry, es)
return true return true
end end
function ShaderFX.convert(entry, es)
local ok, res, err = pcall(doConvert, entry, es)
if not ok then return false, tostring(res) end
return res, err
end
-- Two independent slots. "shaderfx" stays main's option key, so existing -- Two independent slots. "shaderfx" stays main's option key, so existing
-- saves keep meaning what they already meant. -- saves keep meaning what they already meant.
ShaderFX.SLOTS = { "main", "secondary" } ShaderFX.SLOTS = { "main", "secondary" }
+1
View File
@@ -119,6 +119,7 @@ function ShaderFXScreen.new(game, slot)
item.entry.name, tostring(err)) item.entry.name, tostring(err))
end end
applyRowState(item) applyRowState(item)
if not ok then item.right = Strings("FAILED") end
return return
end end
+12 -7
View File
@@ -114,21 +114,26 @@ check(CacheContract.VERSION_REQUIRED_FILES.yellow ~= nil,
local CRYSTAL_1_0 = "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133" local CRYSTAL_1_0 = "f4cd194bdee0d04ca4eac29e09b8e4e9d818c133"
local CRYSTAL_1_1 = "f2f52230b536214ef7c9924f483392993e226cfb" local CRYSTAL_1_1 = "f2f52230b536214ef7c9924f483392993e226cfb"
local CRYSTAL_FORMAT = CacheContract.formatFor("crystal")
eq(CacheContract.markerFor("crystal", CRYSTAL_1_1), eq(CacheContract.markerFor("crystal", CRYSTAL_1_1),
CacheContract.FORMAT .. CRYSTAL_1_1, CRYSTAL_FORMAT .. CRYSTAL_1_1,
"markerFor with an explicit sha1 uses that sha1, not the canonical one") "markerFor with an explicit sha1 uses that sha1, not the canonical one")
eq(CacheContract.markerFor("crystal"), CacheContract.FORMAT .. CRYSTAL_1_0, eq(CacheContract.markerFor("crystal"), CRYSTAL_FORMAT .. CRYSTAL_1_0,
"markerFor with no sha1 still defaults to the canonical (1.0) sha1") "markerFor with no sha1 still defaults to the canonical (1.0) sha1")
check(CacheContract.markerMatches("crystal", CacheContract.FORMAT .. CRYSTAL_1_0), check(CacheContract.markerMatches("crystal", CRYSTAL_FORMAT .. CRYSTAL_1_0),
"a marker written from the 1.0 hash matches crystal") "a marker written from the 1.0 hash matches crystal")
check(CacheContract.markerMatches("crystal", CacheContract.FORMAT .. CRYSTAL_1_1), check(CacheContract.markerMatches("crystal", CRYSTAL_FORMAT .. CRYSTAL_1_1),
"a marker written from the 1.1 hash also matches crystal") "a marker written from the 1.1 hash also matches crystal")
check(not CacheContract.markerMatches("crystal", check(not CacheContract.markerMatches("crystal",
CacheContract.FORMAT .. "ea9bcae617fdf159b045185467ae58b2e4a48b9a"), CRYSTAL_FORMAT .. "ea9bcae617fdf159b045185467ae58b2e4a48b9a"),
"a marker written from Red's hash does not match crystal") "a marker written from Red's hash does not match crystal")
check(not CacheContract.markerMatches("red", CacheContract.FORMAT .. CRYSTAL_1_1), check(not CacheContract.markerMatches("red", CRYSTAL_FORMAT .. CRYSTAL_1_1),
"a marker written from Crystal's 1.1 hash does not match red") "a marker written from Crystal's 1.1 hash does not match red")
check(not CacheContract.markerMatches("crystal",
CacheContract.FORMAT .. CRYSTAL_1_0),
"a crystal marker written on the shared format no longer matches")
local crystalFs = { prefix = "crystal-marker-test/", files = {} } local crystalFs = { prefix = "crystal-marker-test/", files = {} }
function crystalFs.exists(path) return crystalFs.files[crystalFs.prefix .. path] ~= nil end function crystalFs.exists(path) return crystalFs.files[crystalFs.prefix .. path] ~= nil end
@@ -146,7 +151,7 @@ end
local published11 = CacheContract.publish("crystal", crystalFs, CRYSTAL_1_1) local published11 = CacheContract.publish("crystal", crystalFs, CRYSTAL_1_1)
check(published11, "publishing with the 1.1 sha1 succeeds") check(published11, "publishing with the 1.1 sha1 succeeds")
eq(crystalFs.files["crystal/" .. CacheContract.MARKER_PATH], eq(crystalFs.files["crystal/" .. CacheContract.MARKER_PATH],
CacheContract.FORMAT .. CRYSTAL_1_1, "the marker records the 1.1 sha1") CRYSTAL_FORMAT .. CRYSTAL_1_1, "the marker records the 1.1 sha1")
check(CacheContract.isReady("crystal", crystalFs), check(CacheContract.isReady("crystal", crystalFs),
"a cache published with the 1.1 sha1 still reads ready for crystal") "a cache published with the 1.1 sha1 still reads ready for crystal")
+29
View File
@@ -91,6 +91,35 @@ do
:format(extra)) :format(extra))
end end
-- ---- the gendered player name ---------------------------------------------
-- ../pokecrystal/constants/charmap.asm:6 <PLAY_G> ($14),
-- ../pokecrystal/home/text.asm:243,380 PlaceGenderedPlayerName
do
local Extractor = require("src.import.RomExtractorGen2")
local charmap = manifest("tools/rom_manifest_crystal.json").charmap
local function decode(edition, bytes)
local rom = {}
function rom:byte(_, address) return bytes[address] or 0x50 end
function rom:word(_, address)
return (bytes[address] or 0) + (bytes[address + 1] or 0) * 0x100
end
local extractor = setmetatable({ rom = rom, edition = edition }, Extractor)
return extractor:decodeGen2Text(0, 0, charmap)
end
local H, i, comma, space, bang = 0x87, 0xa8, 0xf4, 0x7f, 0xe7
local inString = { [0] = 0x00, H, i, comma, space, 0x14, bang, 0x57 }
eq(decode("crystal", inString), "Hi, {PLAYER}!",
"an in-string $14 decodes as the player's name")
eq(decode("gold", inString), "Hi, !",
"and only on Crystal, which is the only edition that writes one")
local command = { [0] = 0x14, 0x03, 0x00, H, i, 0x57 }
eq(decode("crystal", command), "{STRBUF}Hi",
"a $14 outside a string is still TX_STRINGBUFFER and eats its buffer id")
end
-- ---- the slots RomText fills ---------------------------------------------- -- ---- the slots RomText fills ----------------------------------------------
-- decodeGen2Text emits {USER}, {TARGET} and {ENEMY} for the three names -- decodeGen2Text emits {USER}, {TARGET} and {ENEMY} for the three names
-- PlaceMoveUsersName / PlaceMoveTargetsName / PlaceEnemysName write at -- PlaceMoveUsersName / PlaceMoveTargetsName / PlaceEnemysName write at
+3
View File
@@ -778,6 +778,9 @@ REQUIRED_SYMBOLS = {
# nine fill cells. "HP:" and the ten HP-bar cells come from # nine fill cells. "HP:" and the ten HP-bar cells come from
# FontBattleExtra, which is already extracted. # FontBattleExtra, which is already extracted.
"EnemyHPBarBorderGFX", "HPExpBarBorderGFX", "ExpBarGFX", "EnemyHPBarBorderGFX", "HPExpBarBorderGFX", "ExpBarGFX",
# gfx/battle/balls.2bpp, the four party-ball OAM tiles
# (engine/battle/trainer_huds.asm LoadBallIconGFX).
"LoadBallIconGFX.gfx",
# gfx/stats/stats_tiles.png + gfx/stats/pages.pal, StatsScreen_LoadFont # gfx/stats/stats_tiles.png + gfx/stats/pages.pal, StatsScreen_LoadFont
# and _CGB_StatsScreenHPPals (#1558) # and _CGB_StatsScreenHPPals (#1558)
"StatsScreenPageTilesGFX", "StatsScreenPagePals", "StatsScreenPageTilesGFX", "StatsScreenPagePals",
+4
View File
@@ -17024,6 +17024,10 @@
32, 32,
21684 21684
], ],
"LoadBallIconGFX.gfx": [
11,
16754
],
"LoadOpponentTrainerAndPokemon.resample": [ "LoadOpponentTrainerAndPokemon.resample": [
126, 126,
16418 16418
+4
View File
@@ -15084,6 +15084,10 @@
64, 64,
24169 24169
], ],
"LoadBallIconGFX.gfx": [
11,
16804
],
"LoadOrientedFrontpic": [ "LoadOrientedFrontpic": [
20, 20,
22948 22948
+4
View File
@@ -15084,6 +15084,10 @@
64, 64,
24169 24169
], ],
"LoadBallIconGFX.gfx": [
11,
16804
],
"LoadOrientedFrontpic": [ "LoadOrientedFrontpic": [
20, 20,
22948 22948