Commit Graph

87 Commits

Author SHA1 Message Date
bryanthaboi d920f7acdb clean up 2026-09-22 17:05:12 -04:00
bryanthaboi 9208d83a28 Merge branch 'dev' into pr-2409
# Conflicts:
#	src/ui/game3/save_menu.lua
2026-09-22 16:41:00 -04:00
bryanthaboi 23617f43b4 CLOSES #2290, CLOSES #2338, CLOSES #2186, CLOSES #2305, CLOSES #2332, CLOSES #2320, CLOSES #2344, CLOSES #2291, CLOSES #2335, CLOSES #2340, CLOSES #2385, CLOSES #2352, CLOSES #2378, CLOSES #2403, CLOSES #2404, CLOSES #2405, CLOSES #2367, CLOSES #2037, CLOSES #2177, CLOSES #2368, CLOSES #2382, CLOSES #1951
CLOSES #2290, CLOSES #2338, CLOSES #2186, CLOSES #2305, CLOSES #2332, CLOSES #2320, CLOSES #2344, CLOSES #2291, CLOSES #2335, CLOSES #2340, CLOSES #2385, CLOSES #2352, CLOSES #2378, CLOSES #2403, CLOSES #2404, CLOSES #2405, CLOSES #2367, CLOSES #2037, CLOSES #2177, CLOSES #2368, CLOSES #2382, CLOSES #1951
2026-09-22 16:27:28 -04:00
Shane McGovern 3cf9e23178 test: fold the harness and parity-seam fixes into one gate-hardening commit
Ships the CI fix together with the test-harness work that supports it, so
every tier stays honest on every machine.

scripts/test.sh
- T6 records missing-artifact failures as skips when no imported game3 data
  exists at all (empty CI identity, no data/generated): the data-driven
  top-level suites assert instead of self-skipping on a fresh runner.  The
  skipped suite names are printed with that reason; with data present the
  same failure gates exactly as before.
- The T3 content verdict now weighs the exit code and the FAIL-line allowlist
  together.  The exit code used to be discarded, so a mid-run crash
  (unresolvable require under POKEPORT_DATA_DIR) printed green checks, zero
  FAIL lines, and passed.  A non-zero exit with no FAIL line is reported as a
  crash with the error line captured - a crash is not a pass.

Test-suite fixes, each run green (several twice)
- tests/run_tests.lua: restore per-suite leaked state and add the Data seam,
  so one suite's loaded data cannot leak into the next.
- tests/mod_runtime_tests.lua: save and restore the environment around each
  case.
- tests/parity_ss_anne_rooms.lua: _loadModule raw-order fix (30/30).
- tests/parity_ss_anne_departure.lua: the Data seams plus the playMap stub.
- playMap stubs for parity_rival_walkoff, parity_tower_rival,
  parity_silph_rival_bug2241 and parity_ss_anne_guard.
- Class-B seams in mod_registry_tests, mod_catalog_tests, mod_ui_tests,
  parity_ball_shake_anim, parity_wavy_screen, parity_hidden_coins_bcd_bug1810,
  parity_mart_stock and parity_rocket3_sight_bug1814.

Together these close the 57 failing checks that were on the content tier
(allowlist stays at 0), so a content run on a machine with imports ends
ALL TESTS PASSED.
2026-09-22 19:17:22 +01:00
bryanthaboi dccc90ead7 CLOSES #1709, CLOSES #2202, CLOSES #2217, CLOSES #2234, CLOSES #2237, CLOSES #2238, CLOSES #2239, CLOSES #2240, CLOSES #2241, CLOSES #2242, CLOSES #2243, CLOSES #2244, CLOSES #2247, CLOSES #2248, CLOSES #2249, CLOSES #2250, CLOSES #2251 2026-09-10 17:50:42 -04:00
bryanthaboi 2e24febaca CLOSES #2199, CLOSES #2200, CLOSES #2203, CLOSES #2204, CLOSES #2205, CLOSES #2206, CLOSES #2212, CLOSES #2214, CLOSES #2218, CLOSES #2219, CLOSES #2223, CLOSES #2224, CLOSES #2225, CLOSES #2226 2026-09-09 07:32:12 -04:00
bryanthaboi 16d684297e battle: status moves print the cart's refusal lines 2026-09-04 09:25:34 -04:00
bryanthaboi 7f1336a830 CLOSES #2114, CLOSES #2115, CLOSES #2116, CLOSES #2117, CLOSES #2118, CLOSES #2124, CLOSES #2125, CLOSES #2126, CLOSES #2148, CLOSES #2149, CLOSES #2150, CLOSES #2151, CLOSES #2152, CLOSES #2153, CLOSES #2155, CLOSES #2156, CLOSES #2158, CLOSES #2159, CLOSES #2161, CLOSES #2162, CLOSES #2163, CLOSES #2164, CLOSES #2170, CLOSES #2173, CLOSES #2174, CLOSES #2175, CLOSES #2176, CLOSES #2178, CLOSES #2179, CLOSES #2180, CLOSES #2181, CLOSES #2182 2026-09-04 09:15:16 -04:00
bryanthaboi d31e412a50 CLOSES #2139, CLOSES #2140, CLOSES #2142, CLOSES #2143 2026-09-03 06:33:23 -04:00
bryanthaboi 67ff7463ab CLOSES #2119, CLOSES #2121, CLOSES #2122, CLOSES #2123, CLOSES #2127 2026-09-02 23:46:27 -04:00
bryanthaboi 4e32ca1de3 Strip Gen 2 text terminator from intro and gender select, use × glyph in Gen 1 item lists 2026-09-02 18:05:09 -04:00
1jamie 395c0542a3 crystal bank 1 / attrmap overworld + proper IN_GRASS feet compositing (pret 1:1)
wire up Crystal PalMap tile attrs (bank 1, flips, BG_PRIO) through map bake,
attr grid, and BG-over-OAM blits instead of the gold/silver grassAtlasFor shortcut.
crystal-only: MapAttrGrid + TileAttrs, OAM bottom/top split for IN_GRASS,
keyed grass over feet strip via attrmap, drawBgPriorityOver for wAttrmap bit 7.
gold/silver left alone on the old path — all of this gated behind isCrystal().
fixes standing still in grass with tufts on torso / feet on top of grass (#2080).
RomExtractorGen2 pulls crystal PalMap attrs; SpriteRenderer splits standing
sheets on frameHeight; tests for tile attrs + feet strip regression.
2026-09-02 14:46:24 -05:00
bryanthaboi 700331cb8f CLOSES #2057, CLOSES #2058, CLOSES #2059, CLOSES #2060, CLOSES #2061, CLOSES #2062, CLOSES #2063, CLOSES #2064, CLOSES #2066, CLOSES #2067, CLOSES #2069, CLOSES #2070, CLOSES #2072 2026-09-01 19:03:13 -04:00
bryanthaboi 5c850d670e CLOSES #1938, CLOSES #1940, CLOSES #1941, CLOSES #1943, CLOSES #1945, CLOSES #1946, CLOSES #1948, CLOSES #1949, CLOSES #1950, CLOSES #1953, CLOSES #1955, CLOSES #1957, CLOSES #1960, CLOSES #1961, CLOSES #1962, CLOSES #1963, CLOSES #1964 2026-08-30 08:04:35 -04:00
bryanthaboi 36ad59bdbb CLOSES #1590, CLOSES #1592, CLOSES #1625, CLOSES #1657, CLOSES #1698, CLOSES #1699, CLOSES #1700, CLOSES #1843, CLOSES #1875, CLOSES #1898, CLOSES #1902, CLOSES #1905, CLOSES #1906, CLOSES #1907, CLOSES #1908, CLOSES #1909, CLOSES #1912, CLOSES #1915, CLOSES #1917, CLOSES #1919, CLOSES #1920, CLOSES #1921, CLOSES #1922, CLOSES #1923, CLOSES #1924, CLOSES #1925, CLOSES #1926, CLOSES #1927 2026-08-29 06:59:38 -04:00
Colson Rice ebd315b01e Import Gen 2 cart saves
Gold, Silver and Crystal battery saves import now. Export is still refused.

GenSave.lua is pokered's SRAM window and nothing else, which is why the
guard refusing Gen 2 was right to be there. This adds Gen2Save.lua beside
it, covering pokegold and pokecrystal.

Every offset is generated, not transcribed. tools/gen2_sram_offsets.py
reads pokegold.sym and pokecrystal.sym from a pret build and emits
Gen2Layout.lua, including the text table from constants/charmap.asm and
Crystal's backup-save layout. Gen 2 copies a contiguous WRAM block into
SRAM bank 1, so a field's file offset is sPlayerData + (wField -
wPlayerData); the generator asserts that relation against sPokemonData
rather than assuming it, and range-guards anything outside
sGameData..sGameDataEnd.

Gold and Crystal are separate tables because they disagree about nearly
every field. Reading a Crystal save with Gold's numbers gives a party
count of 133 and 13113 hours played, with a checksum that validates.

The cart stores numbers and the engine is keyed by name, so the codec
crosswalks species, moves and items through the generated tables the same
way GenSave.crosswalks does for Gen 1. Without that, an import looks
perfect and the engine cannot read a byte of it.

Shapes that have to match what the engine reads:
  * events is byte index -> packed byte, which Save.scrubEvents validates
    with tonumber. A set of booleans is silently emptied.
  * the bag is one flat save.inventory keyed by item id, which PackMenu
    buckets by each item's pocket. Nothing reads save.keyItems or
    save.balls, and the TM/HM pocket lands here too.
  * position carries the map id, or Save.summary falls through to
    save.spawn and the player resumes somewhere else at their old
    coordinates.
  * mon.status is an ItemEffects.STATUS_CLASS key with statusTurns beside
    it, nil when healthy. 0 is truthy in Lua.

A save the real cartridge would open is not refused: TryLoadSaveFile falls
back to VerifyBackupChecksum, so this does too. Crystal's backup is
contiguous and laid out like the primary; Gold and Silver split theirs
across three sections and have none to offer.

Three suites that pinned Gen 2 import being refused now pin what refuses
instead. Tests live in tests/engine so the ROM-free tier actually runs
them.

./scripts/test.sh passes end to end, and luacheck is clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 10:32:40 -04:00
bryanthaboi bd3e02986d test fix and iOS close hide 2026-08-27 07:11:43 -04:00
bryanthaboi c9d06779d8 Merge pull request #1844 from colsonrice/fix/gen2-save-refusal-message
Refuse a Gen 2 cart save as a Gen 2 save, not as a broken Gen 1 one
2026-08-27 06:04:27 -04:00
bryanthaboi 48d8a4e922 CLOSES #1562, CLOSES #1804, CLOSES #1805, CLOSES #1810, CLOSES #1811, CLOSES #1814, CLOSES #1817, CLOSES #1818, CLOSES #1819, CLOSES #1821, CLOSES #1826, CLOSES #1827, CLOSES #1829, CLOSES #1833, CLOSES #1840, CLOSES #1842, CLOSES #1845, CLOSES #1846, CLOSES #1847, CLOSES #1848, CLOSES #1849, CLOSES #1853, CLOSES #1858, CLOSES #1862 2026-08-27 05:09:26 -04:00
Colson Rice fe31293566 Refuse a Gen 2 cart save as a Gen 2 save, not as a broken Gen 1 one
#1832 reports a Crystal .sav failing to import with "save data checksum
invalid (main data checksum mismatch)". The save is fine. It is being
measured with the wrong generation's ruler.

SaveFileIO.importToSlot sends anything that is not exactly SAVE_SIZE into
mainChecksumValid, which is pokered's main-data checksum. Gen 2 carts are
MBC3+TIMER, so a real Gold, Silver or Crystal battery save carries an RTC
footer: 32786 bytes, never 32768. It misses the size test, falls into the
checksum branch, and is told it is damaged by a rule written for a
different game. Every real Gen 2 cart save takes that path, every time.

The generation check already exists, it just lives too late, inside
importSav and behind the size gate that has already rejected the save.
This lifts it into SaveConvert.importSupported and exportSupported and
asks before the bytes are measured. Both existing guards route through
the same predicates now, so the early caller and the late one cannot
describe the same game two different ways.

Nothing changes for Gen 1, and Gen 2 is still refused, for the real
reason and in a sentence a player can do something with.

tests/gen2_save_import_message_test.lua covers it. Against the code as it
stands it is 20/26, and the failures are the report itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 14:52:44 -04:00
bryanthaboi 1905261c5b Spider Car Unleashed
CLOSES #1483, CLOSES #1610, CLOSES #1615, CLOSES #1646, CLOSES #1649, CLOSES #1651, CLOSES #1653, CLOSES #1656, CLOSES #1683, CLOSES #1685, CLOSES #1686, CLOSES #1687, CLOSES #1688, CLOSES #1689, CLOSES #1690, CLOSES #1693, CLOSES #1694, CLOSES #1695, CLOSES #1696, CLOSES #1702, CLOSES #1704, CLOSES #1705, CLOSES #1706, CLOSES #1707, CLOSES #1708, CLOSES #1710, CLOSES #1711, CLOSES #1712, CLOSES #1713, CLOSES #1716, CLOSES #1717, CLOSES #1718, CLOSES #1719, CLOSES #1720, CLOSES #1721, CLOSES #1725, CLOSES #1732, CLOSES #1745, CLOSES #1748, CLOSES #1749, CLOSES #1751, CLOSES #1754
2026-08-24 07:52:05 -04:00
bryanthaboi ca4d3d283c Add Pokemon Crystal as a sixth supported version
Crystal boots from a user-supplied ROM, imports a full cache and is playable:
copyright, the Crystal intro movie, the animated title, gender select, Oak,
and out into Johto. 122 of the cart's 169 script specials are implemented.

Import and data
- tools/make_crystal_manifest.py derives the manifest by importing
  make_gold_manifest as a library, with three additive keyword seams. Gold and
  Silver still regenerate byte-identical, which is the standing requirement for
  touching that generator.
- crystal_symbol_deltas.py and crystal_movie_symbols.py carry the symbol delta:
  Crystal renames the credits mons, splits the trainer card, Pokegear and
  pack-pal blocks by gender, and replaces the intro and title outright.
- Crystal-only manifest keys: engineFlagOrder (162 flags to Gold's 93, so the
  badge block sits one higher) and unownCharmap (the main charmap parser stops
  at the first newcharmap so the two cannot contaminate each other).

Extractor
- RomExtractorGen2 becomes three-edition. Crystal corrections: PAL_MAP_BANK
  0x13, a flat PICS_FIX pic bank, audio bank 0x5e, the mapSongs id-100 hole,
  seven NPC trades, a TradeTexts stride of 8, the five Crystal tileset anim
  steps with per-row degrade, and the column-major trainer card portraits.
- New: animated front sprites (frames, bitmasks, play and idle scripts), the
  Battle Tower roster, Kris assets, Mobile System GB art, and the Crystal
  intro and title via src/import/CrystalMovie.lua.

Engine
- GameVersion gains engine(id) and fixes(id). Gold and Silver keep their
  original bugs where the bug is not hardware dependent; Crystal gets the fixes
  Crystal shipped: Lucky Number boxes 10-14, surfing onto an NPC, and the
  Reflect and Light Screen defence overflow.
- Crystal story: Suicune and Eusine, Celebi behind the GS Ball flag, the Ruins
  of Alph chambers, Buena, the Move Tutor, the Poke Seer, and the Battle Tower
  including the wInBattleTowerBattle badge-boost guard.
- Kris and the gender flag, animated fronts in battle and the summary screen,
  and mon caught data.

Verification
- Every extracted asset is pixel-compared against pret's own source PNGs.
- Gold caches are byte-identical before and after, file for file.
- New Crystal suites plus a T2 Gen 2 tier; the full suite passes.
2026-08-23 12:10:28 -04:00
bryanthaboi d54f9a02e0 Merge pull request #1680 from colsonrice/feat/gen2-rom-text 2026-08-22 11:08:18 -04:00
Colson Rice e094b73536 Give Gen 2 the ROM text table Gen 1 has had all along
Gold and Silver had no label-keyed string table at all.  The manifests
carried no text section, RomExtractorGen2 had no extractText, and
game.data.text was never assigned, so every call through
src/core/RomText.lua fell back to the literal written beside it.  The only
Gen 2 text the cache held was the script text in data/generated/text.lua,
keyed by bank:address for the overworld VM, which nothing can look a battle
line up in.

make_gold_manifest.py now walks data/text/'s five dialogue files for their
labels, the way make_rom_manifest.text_metadata walks pokered's, and embeds
each one's symbol.  889 labels, all of them resolving in both editions.
make_silver_manifest.py inherits the list unchanged and re-resolves the
addresses from pokesilver.sym.

RomExtractorGen2:extractText decodes them into data/generated/rom_text.lua.
The mechanism is the one extractOakSpeech already used for _OakText1-7:
resolve the label, decode from the cart, key by name.  What is new is that
the list comes from the manifest rather than being written out in Lua, so
all of data/text/ arrives instead of seven strings.

decodeGen2Text also emits the three runtime name slots it used to drop.
PlaceMoveUsersName, PlaceMoveTargetsName and PlaceEnemysName (home/text.asm)
substitute a battler's name as the line prints, so <USER>, <TARGET> and
<ENEMY> are markers, not glyphs.  Skipped as control glyphs, SubTookDamageText
decoded as "The SUBSTITUTE / took damage for" with nothing after it.

Game2:load assigns the table to self.data.text, which is what makes the
existing shared RomText helper work on Gold and Silver at all.

The new cache file is listed in the Gold override rather than bumping
CACHE_FORMAT, so caches built before this stage re-import themselves and Red,
Blue and Yellow are left alone.
2026-08-21 23:08:26 -04:00
Colson Rice 921f565f1d Import the cart Choose ROM asked for
findPendingRom answered with the first dump in the save directory whose SHA-1
mapped to any not-yet-ready version.  On a device with no file picker that
scan IS the import, so with four dumps in the folder, choosing Red imported
and decoded Blue (#1274).

It now takes an optional version and narrows to it.  The two Choose paths
pass self.chooseVersion, since a Choose names the cart it is for.  The two
Android USB-drop scans pass nothing and still take the first pending cart of
any version, which is what they are for.

A chosen version with no dump present now imports nothing rather than the
wrong cart, and falls through to the notice that says where to put the file.
2026-08-21 22:21:41 -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 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
bryanthaboi 1151c188a7 CLOSES #1211, CLOSES #1228, CLOSES #1229, CLOSES #1232, CLOSES #1251, CLOSES #1265, CLOSES #1267, CLOSES #1276, CLOSES #1279, CLOSES #1282, CLOSES #1293, CLOSES #1296, CLOSES #1303, CLOSES #1329, CLOSES #1338, CLOSES #1341, CLOSES #1343, CLOSES #1344, CLOSES #1368, CLOSES #1385, CLOSES #1388, CLOSES #1389, CLOSES #1391 2026-08-16 08:55:40 -04:00
1jamie df0be1cba6 Add Gold save-editor support, rearrange the launcher, and ship a patch-notes modal.
The save editor now routes Gold vs RBY through a generation adapter so boxes, items, events, and maps write the right fields. The launcher layout is shuffled a bit, and patch notes can come from the updater, a packed file, or the iOS sidecar.
2026-08-14 18:48:06 -05:00
bryanthaboi a94fecfec8 Closes #919, closes #982, closes #1003, closes #1012, closes #1022, closes #1028, closes #1033 2026-08-14 10:05:51 -04:00
bryanthaboi 37051a26b5 CLOSES #1206, CLOSES #1189, CLOSES #1175, CLOSES #1129, CLOSES #1119, CLOSES #1089, CLOSES #1073, CLOSES #1069, CLOSES #1065, CLOSES #1010, CLOSES #990, CLOSES #989, CLOSES #988, CLOSES #978, CLOSES #944, CLOSES #936, CLOSES #1221, CLOSES #1220, CLOSES #1193, CLOSES #1101, CLOSES #1066, CLOSES #1056, CLOSES #1041, CLOSES #984, CLOSES #1225, CLOSES #1214, CLOSES #1011, CLOSES #1035, CLOSES #1219, CLOSES #1048, CLOSES #1047, CLOSES #964, CLOSES #949, CLOSES #1149, CLOSES #1007, CLOSES #914, CLOSES #1115, CLOSES #1146, CLOSES #999, CLOSES #1207, CLOSES #1029, CLOSES #1120, CLOSES #987, CLOSES #983 2026-08-13 13:07:20 -04:00
bryanthaboi 52e36ad7e4 fix testsZ 2026-08-13 06:05:27 -04:00
bryanthaboi ae6cac89e1 G2 support 2026-08-11 11:53:30 -04:00
bryanthaboi 9302bbcbf3 Merge branch 'fix1037' into fix1038
# Conflicts:
#	docs/modding.md
2026-08-10 14:12:21 -04:00
david 3c71afb9fa Per-category GAME SPEED: overworld/battle/menu + core.logic_speed hook (RFC 0007)
GameSpeed is a single fast-forward multiplier applied uniformly to the
whole logic clock -- overworld walking, menu navigation and battle turns
all scale together. A player who wants 4X battles but 1X overworld (so a
cutscene or NPC dialogue doesn't blur past) has no way to get both.

Splits save.options.speed into speedOverworld/speedBattle/speedMenu, each
cycling independently, with an automatic migration so an existing save's
speed choice carries over. Game.speedCategoryInStack resolves which
category is active by walking the state stack (the same idiom
wideBattleInStack/fillScaleInStack already use), so a menu opened mid-
battle inherits battle speed rather than resetting to whatever "menu"
defaults to. Adds a new core.logic_speed hook so a mod can read or
override the resolved multiplier for the current frame regardless of
which category produced it, sitting after the link-play and run-argument
overrides so neither is a seam a mod can defeat.

RFC 0007 status: Proposed.
2026-08-09 20:13:21 -07:00
Shane McGovern ff91481018 Fix Substitute zero-HP boundary
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-09 00:17:51 +01:00
bryanthaboi cb6cfb5556 CLOSES #883, CLOSES #887, CLOSES #894 2026-08-06 06:36:12 -04:00
bryanthaboi f6392e8932 CLOSES #788, CLOSES #795, CLOSES #796, CLOSES #797, CLOSES #805, CLOSES #826, CLOSES #833, CLOSES #835, CLOSES #837, CLOSES #844, CLOSES #845, CLOSES #846, CLOSES #847 2026-08-05 11:09:05 -04:00
johnjohto ba8ac3d143 Tick residuals after each move in Gen 1 mode
In pokered, MainInBattleLoop calls HandlePoisonBurnLeechSeed right
after every Execute*Move (core.asm:426-464), so a seeded, poisoned or
burned mon takes its residual before the slower side acts. The port
ran the whole sweep in endOfTurn, which made leech seed behave like
Gen 3+ and never showed the drain animation (#784).

The residual sweep now runs per action under the gen1_faithful
ruleset, gated by a new residualAfterMove flag; modern_clean keeps
the end of round sweep. The leech seed drain plays the ABSORB
animation from the healing side, the way the original flips
hWhoseTurn before PlayMoveAnimation. Item, ball, failed run and
ghost-fear turns still tick the player's residual, matching
ExecutePlayerMoveDone.
2026-08-04 12:06:21 -04:00
bryanthaboi 8fbe819493 bingus dingus 2026-08-04 10:32:51 -04:00
bryanthaboi dd4aface93 test fixes 2026-08-04 09:41:44 -04:00
Andrew Quenehen 44bfb1b93f test(nx): move ROM-free NX suites into the engine tier
platform_nx_* and rom_importer_nx_* run with the love stub and must execute
in CI's ROM-free lane via tests/run_engine.lua, not only T3.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 09:58:53 -03:00
Andrew Quenehen 8120f113af test(nx): wire saves inbox suite into run_tests
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 08:06:35 -03:00
Andrew Quenehen cbf622f4aa Merge branch 'dev' into feat/switch-nx
Bring feat/switch-nx up to date with origin/dev (72 commits). Resolve
Input/RomImporter conflicts by keeping GamepadMap (NX face remap + dual-path
gate) while adopting upstream joyBindings rebinds (#632) and Enable-all mods
(#647). Gate shoulder GAME SPEED hotkeys when Select is held so Select+L
display chords still work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 21:36:56 -03:00
bryanthaboi 35b3fa6d9c CLOSES #455, CLOSES #487, CLOSES #501, CLOSES #540, CLOSES #585, CLOSES #591, CLOSES #593, CLOSES #595, CLOSES #597, CLOSES #599, CLOSES #600, CLOSES #606, CLOSES #607, CLOSES #610, CLOSES #613, CLOSES #616, CLOSES #620, CLOSES #626, CLOSES #632, CLOSES #633, CLOSES #647 2026-08-02 08:19:28 -04:00
Andrew Quenehen 74e7474349 fix(nx-mods): skip ROM AppleDouble sidecars and surface mixed failures
Ignore hidden ._*.gb in the ROM inbox like zips, keep mixed-rescan success notices while appending sibling errors, and cover FileData mount / PK rejection in unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 05:58:17 -03:00
Andrew Quenehen 7d01242cd1 feat(nx-mods): add imports/mods inbox dir and MTP hint
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 05:19:26 -03:00
Andrew Quenehen df7cea4387 feat(import): scan NX inbox and import by canonical SHA-1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 03:20:16 -03:00
Andrew Quenehen c06991e03d fix(switch): disable unvalidated network features on NX
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 03:15:31 -03:00
Andrew Quenehen 2fcd7abbfd fix(platform): skip host shell spawn on NX
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 03:15:13 -03:00