Commit Graph

657 Commits

Author SHA1 Message Date
1jamie f5b8b6c85f feat: implement Diploma screen visual assets and add version-specific blink logic to TownMap
Fix for #1595 #1597 #1589 #1613 and maybe 1520.
2026-08-20 20:37:51 -04:00
bryanthaboi db25c14dfb save sync update 2026-08-20 20:36:23 -04:00
bryanthaboi 90163a3ff2 CLOSES #1619 2026-08-20 20:07:10 -04:00
bryanthaboi ada0d8abe1 updater stuff 2026-08-20 17:30:48 -04:00
bryanthaboi dbecc345e3 CLOSES #1478, CLOSES #1479, CLOSES #1488, CLOSES #1510, CLOSES #1511, CLOSES #1514, CLOSES #1521, CLOSES #1522, CLOSES #1545, CLOSES #1557, CLOSES #1563, CLOSES #1565, CLOSES #1566, CLOSES #1577, CLOSES #1594, CLOSES #1596, CLOSES #1606, CLOSES #1608 2026-08-20 17:30:18 -04:00
bryanthaboi 0f8f6d0e4f CLOSES #1474, CLOSES #1475, CLOSES #1477, CLOSES #1482, CLOSES #1512, CLOSES #1516, CLOSES #1558, CLOSES #1569, CLOSES #1578, CLOSES #1579 2026-08-20 17:29:51 -04:00
bryanthaboi d66a72ac95 Merge branch 'dev' of https://github.com/bryanthaboi/gen1recomp into dev 2026-08-20 12:43:05 -04:00
bryanthaboi 1b659dab01 CLOSES #1582, CLOSES #1583 2026-08-20 12:43:04 -04:00
bryanthaboi 5fa5005786 Merge pull request #1559 from thibautbus/fix/route-more-messages-through-romtext
Route more battle/overworld/menu messages through their real ROM text
2026-08-20 11:54:40 -04:00
bryanthaboi 1ac5b867bb for that one guy who has a mouse but for some reason it doesnt have a scroll wheel 2026-08-20 11:54:08 -04:00
bryanthaboi 9ed7e05dc1 Merge pull request #1601 from bryanthaboi/dev
bug fixes and uncles neighbor
2026-08-20 10:48:57 -04:00
bryanthaboi 25166ff3a1 CLOSES #1603 2026-08-20 10:46:27 -04:00
bryanthaboi 5b19259928 Merge pull request #1581 from 1Jamie/feat/pikachu-surf-and-gold-gamecorner
feat: surfing minigame overhaul + authentic Game Corner rendering
2026-08-20 09:46:43 -04:00
bryanthaboi 7c9c2380d2 Update LauncherView.lua 2026-08-20 09:19:59 -04:00
bryanthaboi 2468d5042d clean up and larger importer 2026-08-20 08:53:31 -04:00
bryanthaboi 51c4766ead Merge branch 'my-uncles-neighbor' into dev
# Conflicts:
#	src/import/RomImporter.lua
2026-08-20 08:28:19 -04:00
bryanthaboi ec9dc29646 Pokemon Silver as a full launcher version, plus launcher mods-list and title-tempo fixes
Silver: derived import manifest (tools/make_silver_manifest.py re-resolves
the Gold manifest's symbols from pokesilver.sym), silver GameVersion row,
generation-keyed extractor routing, required-files override, edition save
stamping (a Silver playthrough no longer writes into the Gold save),
checkver-driven edition data, SILVER/KAMON/OSCAR/MAX presets, GOLD rival
default, edition credits banner, Lugia title screen (OAM layouts, bob,
trail, palettes as title.lua data keys with Gold defaults so old caches
need no re-import), packaging for every build target, docs, and tests.

Launcher: the installed-mods list is one continuous scroll (rows culled to
the viewport) instead of a pager with an inner scroll viewport; the pad
cursor's edge-scroll no longer runs it to the bottom. The game dropdown
shows just the initial and caret. Find-tab behavior unchanged.

Title tempo: a sprite-anim frame shows duration+1 ticks
(engine/sprite_anims/core.asm GetSpriteAnimFrame), which locks both
editions' 64-tick wing beat to the 64-tick sine bob; the title screens no
longer run fast and out of phase.
2026-08-20 08:27:25 -04:00
thibautbus 8f88d01cf2 Route the link battle's opening line through its real ROM text
LinkBattle.lua's "%s wants\nto fight!" intro was a plain Lua literal,
even though the comment right above it already named the real label
(_TrainerWantsToFightText). The battle object built at this point is
already a BattleState, so this reuses its self:romText convenience
method rather than requiring the module-level helper separately.
2026-08-20 09:18:56 +02:00
thibautbus 2279617b29 Route the mart's price confirmation prompts through their real ROM text
ShopMenu.lua's buy/sell price confirmations were plain Lua literals,
even though the comment on each line already named the real label
(_PokemartTellBuyPriceText, _PokemartTellSellPriceText). This file's
own txt(game, key, fallback) helper doesn't support substitution
arguments, so it can't be reused as-is; added the module-level romText
helper instead, same as every other file in this batch.
2026-08-20 09:18:56 +02:00
thibautbus 17fbf6cec4 Route the slot machine's lined-up message through the real ROM text
SlotMachine.lua built "%s lined up!\nScored %d coins!" as a plain Lua
literal, substituting the symbol id (sym) as if it were part of the
translatable sentence. The real extracted _LinedUpText label
(" lined up!\nScored {RAM:wStringBuffer} coins!") shows the original
never had a slot for the symbol at all -- it was drawn separately and
only this fixed suffix was ROM text. Concatenate sym in front of
romText's real, already-translated label instead of interpolating it
into an engine literal.
2026-08-20 09:18:56 +02:00
thibautbus 34c4481f96 Route the box-release confirmation through the real ROM text
BoxMenu.lua's "Once released,\n%s is\ngone forever. OK?" prompt and its
"%s was\nreleased outside.\fBye %s!" follow-up (shown after confirming)
were both plain Lua literals, bypassing the extracted _OnceReleasedText
and _MonWasReleasedText labels entirely even though both exist and are
already translated in a real corpus build. Wrapped both in the same
t._X or Strings(...) pattern already used four lines above for the
Pikachu-unhappy prompt in this same function, with the same trailing
gsub to fill the {RAM:wStringBuffer} token(s) either branch leaves in
place -- _MonWasReleasedText's real text repeats the token twice (the
name appears at both ends of the sentence), and gsub's default
replace-all handles that the same way a single occurrence does.

Independent code review flagged a separate issue on this line and the
pre-existing Pikachu one right above it: both pass the nickname as a
bare gsub replacement string, which Lua %-escapes ("%" followed by a
digit 1-9 crashes with "invalid capture index", confirmed directly).
Checked how reachable that actually is: the naming screen's charset
can't produce a literal "%", and neither can a real cartridge import
(the Gen 1/2 character-decode tables never map any ROM byte to "%"
either) -- the only way in is editing a save's plain-Lua-source
nickname field directly. Not fixed here, to stay consistent with the
separate branch (fix/gsub-percent-escape-crash) already carrying this
exact fix across every callsite that shares it, including this one --
splitting the same bug's fix across two branches by which one happened
to touch the line first isn't a real reason to fix it in one place and
not the other.
2026-08-20 09:18:56 +02:00
thibautbus bff40a5d90 Route OverworldController's field messages through their real ROM text
Four message families in OverworldController.lua were plain Lua
literals instead of their already-extracted, already-translated ROM
text labels:

- applyFieldPoison()'s faint message: the third of three collapsed
  "%s\nfainted!" ROM strings (the other two, in BattleState.lua, are
  fixed in the previous commit) -- routed through _PokemonFaintedText.
- useSoftboiledFieldMove()'s two outcome messages: _ItemUseNoEffectText
  and _PotionText, the exact labels ItemEffects.lua's real potion
  message already uses, including _PotionText's second slot (the
  actual amount healed) the old literal never showed at all.
- tryHiddenObject()'s two hidden-item finds: _FoundHiddenItemText.
- The normal item-ball pickup path's two finds (one Yellow-only
  bag-full variant): a comment already named _FoundItemText
  ("FoundItemText: text_far, sound_get_item_1, text_end").

Both found-item labels lead with a {PLAYER} token that romText
auto-fills from a 2-arg call (player name, item name) in the same
order the literal already used. The fallback text for both is plain
"%s found\n%s!", matching the original literal's shape exactly --
an earlier version of this fix used a "{PLAYER} found\n%s!" fallback
that relied on TextBox.new's later TextBox.substitute pass to resolve
{PLAYER}, which works but needlessly made the fallback path depend on
a downstream call instead of being self-contained.
2026-08-20 09:18:56 +02:00
thibautbus 354a8b476d Route BattleState's trainer/catch/faint messages through their real ROM text
Nine message families in BattleState.lua were plain Lua literals,
bypassing already-extracted, already-translated ROM text labels --
some with a comment right next to them already naming the real label:

- storeCaughtMon(): the new-Pokedex-data line (_ItemUseBallText06) and
  the box-transfer line, which used a hardcoded "BILL's PC"/"someone's
  PC" as if it were a substituted argument in one shared template --
  _ItemUseBallText07/08 are two full, independently translated ROM
  strings, not a template with a substituted PC name.
- throwBall(): the dodged-ball and can't-be-caught lines were two
  separate Strings() calls; _ItemUseBallText00 is one \f-paged ROM
  label covering both. Unlike TextBox.new() (which splits \f itself),
  sayNext() goes through the battle queue's own startMessage(), which
  only splits on \n/\v -- confirmed live in a real build (the second
  sentence overflowed off the box instead of starting a fresh page).
  Resolves the label once, splits it the same way TextBox.lua does,
  and queues one sayNext per page.
- onFaint(): displayName(battler) runs the enemy name through a
  separate Strings("Enemy %s", ...) call, then the shared "%s\nfainted!"
  literal added the rest -- but _EnemyMonFaintedText already carries
  its own "Enemy" wording, so this passes the raw battler.name and
  picks _PlayerMonFaintedText/_EnemyMonFaintedText by battler.isPlayer.
- enter()'s pre-battle black-out message (_PlayerBlackedOutText2, a
  \f-paged pair like _ItemUseBallText00 above).
- The AI switch-in withdraw/send-out line and the enemy trainer's
  first send-out (3 callsites, one shared by the link-battle intro
  path): _AIBattleWithdrawText and _TrainerSentOutText.

Also investigated folding _TrainerAboutToUseText's SHIFT-switch offer
(say() then sayChoice(), both plain Strings(), which the label also
\f-pages) into one romText + sayChoice call the same way. That does
NOT work: tests/engine/trainer_shift_prompt_bug565.lua caught that the
battle queue's own text renderer pages a sayChoice string differently
from TextBox.lua's \f handling that the say()+say() merges above rely
on. Left as two calls, unchanged, with a comment explaining why.
2026-08-20 09:18:56 +02:00
1jamie f0d3c014a7 feat: surfing minigame overhaul + authentic Game Corner rendering
Surfing minigame:
- Add title screen (ROUTINE_TITLE) with Pikachu intro, logo banner, instructions
- Add GLSL HBlank wave distortion shader, OAM water spray/splash sprites
- Add multi-path asset loader, isMinigame/isFixedSpeed flags, crash recovery fixes
- Extract SurfingPikachu graphics + composite title_bg.png from ROM

Game Corner (built visual layer from ROM assets; logic existed, rendering was placeholder):
- SlotMachine: GBC tilemap background, authentic reel symbol sprites, Golem/Chansey
  near-miss animations, lit/unlit lights, payout panel
- CardFlip: GBC tilemap board, hardware-accurate card flip sequence, OAM cursor frame
- RomExtractorGen2: extract slots + card_flip sprite sheets and tilemaps

Tests: SurfingMinigame units 8-13; 500-spin SlotMachine and 500-hand CardFlip stress tests
2026-08-19 18:14:42 -05:00
bryanthaboi 032f894f7f Merge pull request #1495 from mleo2003/fix/fresh-skeleton-playthrough-id
SaveData: a fresh skeleton must not overwrite an existing playthrough binding
2026-08-19 16:57:30 -04:00
bryanthaboi 872d6b4516 Merge pull request #1572 from bryanthaboi/dev
bugs and bug reporting
2026-08-19 14:03:47 -04:00
bryanthaboi def270f7c7 Merge pull request #1560 from castdrian/device-report-bug-tab
feat(launcher): add bug tab and native device reporting
2026-08-19 13:54:38 -04:00
bryanthaboi 4c8c1cf36b CLOSES #998, CLOSES #1472, CLOSES #1526, CLOSES #1529, CLOSES #1530, CLOSES #1532, CLOSES #1534, CLOSES #1547, CLOSES #1549, CLOSES #1550, CLOSES #1551 2026-08-19 11:19:54 -04:00
Adrian Castro b27e5ab017 fix(launcher): simplify bug report card title 2026-08-19 15:51:23 +02:00
Adrian Castro a7c19be88f fix(launcher): use standard bug report icon 2026-08-19 15:51:22 +02:00
Adrian Castro 9ab80adaca feat(launcher): add bug tab and native device reporting 2026-08-19 15:50:50 +02:00
bryanthaboi 4349a1142f Merge pull request #1554 from bryanthaboi/dev
adrian if ur reading this im ....
2026-08-19 06:44:22 -04:00
bryanthaboi 9713977755 Merge branch 'dev' of https://github.com/bryanthaboi/gen1recomp into dev 2026-08-19 06:41:12 -04:00
bryanthaboi 63448ca640 shamona 2026-08-19 06:41:10 -04:00
bryanthaboi e24f812475 Merge pull request #1553 from bryanthaboi/dev
fix stuff baby
2026-08-19 06:10:44 -04:00
bryanthaboi fddf619ed2 Merge pull request #1527 from thibautbus/fix/status-abbreviation-translation
Translate the status abbreviations shown outside battle
2026-08-19 06:01:14 -04:00
bryanthaboi bf83509ef2 Merge pull request #1542 from AverageConsumer/codex/gen2-ball-cache-invalidation
fix(gen2): refresh caches missing trainer HUD balls
2026-08-19 06:00:48 -04:00
bryanthaboi 6c05b854c4 Merge pull request #1543 from AverageConsumer/codex/gen2-party-grid-navigation
fix(gen2): honor battle party grid navigation
2026-08-19 06:00:21 -04:00
bryanthaboi 2baafab027 Merge pull request #1544 from castdrian/safe-mode-report-issue
feat(launcher): add safe mode and issue reporting
2026-08-19 06:00:00 -04:00
bryanthaboi 813f9d959b Merge pull request #1546 from 1Jamie/feat/android-exit-game-to-launcher
feat(android): add adaptive icons, dynamic shortcuts, in-process hot-swap, and exit-to-launcher
2026-08-19 05:59:34 -04:00
bryanthaboi fba87f028c Merge pull request #1552 from thibautbus/fix/pikachu-unhappy-gsub-crash
Fix a crash releasing your own caught Pikachu in Yellow
2026-08-19 05:59:06 -04:00
bryanthaboi cb4647daf0 Merge branch 'dev' of https://github.com/bryanthaboi/gen1recomp into dev 2026-08-19 05:57:46 -04:00
bryanthaboi 93374fbbbb skin studio updates, save sync CLOSES #1533 2026-08-19 05:57:44 -04:00
thibautbus abe176b26c Fix a crash releasing your own caught Pikachu in Yellow
BoxMenu.lua's release() pushes both its "Once released...OK?" prompt
and its Yellow-only "Pikachu looks unhappy" message through
TextBox.new(game, (t._X or Strings(...)):gsub(...)) -- gsub returns
two values (the text and a substitution count), and since the gsub
call is the last argument in the TextBox.new(...) call with nothing
after it, Lua expands both into the call: the count lands in
TextBox.new's third parameter, onDone. TextBox.lua later calls
onDone() once the box is dismissed; a number is not callable, so
every release of your own caught Pikachu in Yellow crashed --
regardless of its nickname (unlike the separate %-escape gsub bug,
this one needs no special save content, ordinary play reaches it
every time).

Fixed by wrapping the gsub call in an extra pair of parens, which
truncates it to its first return value only -- the same fix already
applied to the neighboring _OnceReleasedText/_MonWasReleasedText
lines on the (separate, unmerged) fix/route-more-messages-through-romtext
branch, where this exact bug shape was first noticed while adding a
third callsite with the same pattern.

tests/engine/pikachu_unhappy_release_crash.lua: registers a fake
Data.pokemon.PIKACHU cloned from the fixture species (ROM-free) so
the species == "PIKACHU" check can be exercised, drives the real
interactive release flow in Yellow on a mon owned by the player, and
confirms the crash. Verified failing pre-fix (exact same
"attempt to call field 'onDone' (a number value)" error) and passing
post-fix.
2026-08-19 11:34:20 +02:00
thibautbus 9984958193 Translate the status abbreviations shown outside battle
src/ui/SummaryMenu.lua:148 and src/ui/PartyMenu.lua:824 drew mon.status
(PSN/PAR/BRN/FRZ/SLP) as a bare literal, bypassing translation. Unlike
plain text, a mod translates status labels through the statuses content
registry (mod.content.statuses:patch(id, { label = value }), the same
registry src/battle/BattleState.lua:statusLabel already reads in battle.
Route both screens through the same lookup, extracted as
Status.hudLabelFor(statuses, id) and shared with BattleState:statusLabel
so the hudLabel-or-label fallback rule lives in one place, with the raw
status id kept as the fallback when no record overrides it.

Found along the way: Status.RECORDS' five vanilla entries duplicated
hudLabel = label ("FRZ", hudLabel = "FRZ", ...) for no functional
reason. Since hudLabelFor reads hudLabel before label, and
Registry:patch only overrides fields a mod actually passes, a
translation mod's label-only patch (the natural shape for a status
catalog carrying one string per id, with no separate hudLabel data to
patch) was silently shadowed by the untouched vanilla hudLabel -- the
translation was stored but never displayed, in or out of battle. This
affected BattleState:statusLabel too, before this change and
independently of it. Dropped the redundant hudLabel field from all
five vanilla records: it's declared optional in the schema, and
nothing in this codebase ever gives it a value different from label --
setting it here only recreated the shadowing trap for no observed
benefit. Left a comment above Status.RECORDS warning against
re-adding it.
2026-08-19 08:08:20 +02:00
1jamie 302b2c9591 feat(android): add adaptive icons, dynamic shortcuts, in-process hot-swap, and exit-to-launcher 2026-08-18 20:37:25 -05:00
Adrian Castro 67a170fd6e feat(launcher): add safe mode and issue reporting 2026-08-19 00:44:30 +02:00
AverageConsumer 66079686fc fix(gen2): honor battle party grid navigation 2026-08-19 00:35:39 +02:00
AverageConsumer cc5ff987ac fix(gen2): refresh caches missing trainer HUD balls 2026-08-18 23:52:25 +02:00
bryanthaboi fb97318e87 Merge pull request #1541 from bryanthaboi/dev
tuesday afternoon squashing
2026-08-18 17:08:46 -04:00