diff --git a/ff4.s b/ff4.s index 6679e62..7b03dd6 100644 --- a/ff4.s +++ b/ff4.s @@ -30,6 +30,9 @@ Final Fantasy IV the new hack. .import "dialog" .import "ingame/init_bg_scroll_hdma" .import "ingame/items_menu_vwf" +.import "ingame/places_names" +.import "ingame/new_game" +.import "ingame/credits" .import "ingame/places_names_window" .import "intro" .import "kerning" @@ -45,45 +48,42 @@ Final Fantasy IV the new hack. .include "src/libmz.i" -.include "src/items.i" -.include "src/lib/rolling_buffer.s" +.import "items" +.include "src/lib/rolling_buffer.i" .include "src/menus/system_menus_text.i" -.include "src/minimal_vwf_patches.s" +.import "minimal_vwf_patches" .if BATTLE_ENABLED { - .include "src/battle/math_patches.s" - .include "src/battle/graphics_patches.s" + .import "battle/math_patches" + .import "battle/graphics_patches" .if MAGIC_ENABLED { - .include "src/battle/magic/patches.s" - .include "src/battle/commands_patches.s" + .import "battle/magic/patches" + .import "battle/commands_patches" } - .include "src/battle/message_patches.s" - .include "src/battle/sram_patches.s" + .import "battle/message_patches" + .import "battle/sram_patches" .if BATTLE_MONSTERS_VWF { - .include "src/battle/monsters_patches.s" + .import "battle/monsters_patches" } - .include "src/battle/items_patches.s" - .include "src/battle/redraw_writer_patches.s" + .import "battle/items_patches" + .import "battle/redraw_writer_patches" .if INVENTORY_ROLLING_BUFFER { - .include "src/battle/inventory_rolling_patches.s" + .import "battle/inventory_rolling_patches" } .if TREASURE_DEBUG_ALWAYS_DROP { - .include "src/battle/debug_always_drop.s" + .import "battle/debug_always_drop" } } -.include "src/ingame/places_names.s" -.include "src/ingame/new_game.s" -.include "src/ingame/credits.s" .include "src/ingame/menus.i" ; item name expansion patches -.include "src/ingame/items_menu.s" +.import "ingame/items_menu" ; Relocated init_bg_scroll_hdma (was at $01:EBD2, frees 566 bytes in bank $01). ; Blob with internal absolute references - pinned to offset $EBD2 within an ; expansion bank. Caller patch retargets the single JSL at $02:818A. .if INVENTORY_ROLLING_BUFFER { - .include "src/ingame/init_bg_scroll_hdma_patches.s" - .include "src/ingame/inventory_rolling_trampolines.s" + .import "ingame/init_bg_scroll_hdma_patches" + .import "ingame/inventory_rolling_trampolines" } @@ -365,23 +365,23 @@ signature byte sits at PB:(PC - 1). .if INVENTORY_ROLLING_BUFFER { .import "ingame/init_bg_scroll_hdma" - .include "src/ingame/inventory_rolling.s" - .include "src/lib/rolling_inventory_engine.s" } .if TREASURE_INVENTORY_ROLLING { - .include "src/ingame/treasure_rolling.s" - .include "src/ingame/drops_rolling.s" - .include "src/ingame/key_item_picker.s" - .include "src/ingame/shop_sell_rolling.s" + .import "ingame/key_item_picker" + .import "ingame/drops_rolling" + .import "ingame/inventory_rolling" + .import "lib/rolling_inventory_engine" + .import "ingame/treasure_rolling" + .import "ingame/shop_sell_rolling" } ; --- Binary text assets ------------------------------------------------- .if TREASURE_INVENTORY_ROLLING { - .include "src/ingame/key_item_picker_patches.s" - .include "src/ingame/shop_sell_rolling_patches.s" + .import "ingame/key_item_picker_patches" + .import "ingame/shop_sell_rolling_patches" } .if TRIGGER_ENDING_CUTSCENE { diff --git a/pyproject.toml b/pyproject.toml index e5363e5..1364494 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ authors = [{ name = "Emmanuel Peralta", email = "manz@ringum.net" }] requires-python = ">=3.13" dependencies = [ - "a816==1.1.0a31", + "a816==1.1.0a33", "kintsuki[visual]==0.0.0a13", ] diff --git a/src/bank20.i b/src/bank20.i index 7ad5774..ea2a22f 100644 --- a/src/bank20.i +++ b/src/bank20.i @@ -8,6 +8,9 @@ linker dedupes identical ranges via `_merge_one_pool_decl`. """ +; The pool sits in bank $20, so the ROM map has to be in scope with it. +.include "src/rom_map.i" + .pool bank20_reloc { range 0x208000 0x20FFFF strategy order diff --git a/src/battle/commands_patches.s b/src/battle/commands_patches.s index 26f31e5..767d737 100644 --- a/src/battle/commands_patches.s +++ b/src/battle/commands_patches.s @@ -2,6 +2,9 @@ In-place patches that resize the battle command-window layout when `BATTLE_CMD_VWF` is enabled (shorter slot stride, command-id base, format-buffer pointer). """ + +.include "src/rom_map.i" + .include "config.i" command_buffer_ptr = 0x97a6 + 0x601 ; old spell lists buffers .if BATTLE_CMD_VWF { diff --git a/src/battle/debug_always_drop.s b/src/battle/debug_always_drop.s index aa52510..d5816ce 100644 --- a/src/battle/debug_always_drop.s +++ b/src/battle/debug_always_drop.s @@ -2,6 +2,9 @@ Debug patch (gated by `TREASURE_DEBUG_ALWAYS_DROP`) that forces every battle to roll a successful drop by NOPing the random-roll gate at $03:ED0D. """ + +.include "src/rom_map.i" + ; Debug: force every battle to drop an item. ; diff --git a/src/battle/graphics_patches.s b/src/battle/graphics_patches.s index dd124bb..7ccdb33 100644 --- a/src/battle/graphics_patches.s +++ b/src/battle/graphics_patches.s @@ -2,6 +2,10 @@ Battle graphics asset patches: MISS sprite glyphs, defend/row text overrides and other small tile fixups that piggyback on `defend_row` data. """ + +.include "src/rom_map.i" +.extern assets_battle_statuses_dat + .extern defend_row ; MISS sprite graphics diff --git a/src/battle/inventory_rolling.s b/src/battle/inventory_rolling.s index a15ec16..f57258c 100644 --- a/src/battle/inventory_rolling.s +++ b/src/battle/inventory_rolling.s @@ -4,7 +4,7 @@ Battle inventory rolling-buffer engine (single column, 5 visible rows + 1 prefet runs the field-menu NMI DMA check. """ .include "config.i" -.include "../items.i" +.import "items" .extern assets_items_dat .extern assets_items_unleashed_dat .extern mult8_trampoline diff --git a/src/battle/inventory_rolling_patches.s b/src/battle/inventory_rolling_patches.s index da8a778..e97bf1d 100644 --- a/src/battle/inventory_rolling_patches.s +++ b/src/battle/inventory_rolling_patches.s @@ -2,6 +2,10 @@ ROM patches that wire the battle inventory rolling-buffer engine into bank $02 (JSL trampolines for cross-bank calls, JML hooks for the scroll animation, surgical NOPs / RTS overrides). """ + +.include "src/rom_map.i" +.extern draw_window_render_hook + .include "config.i" .extern init_inventory_text_buf_rolling .extern tfr_inventory_list_rolling diff --git a/src/battle/items_patches.s b/src/battle/items_patches.s index cb9d8f0..c87ab5d 100644 --- a/src/battle/items_patches.s +++ b/src/battle/items_patches.s @@ -2,6 +2,10 @@ Patches for 12-byte (instead of 9-byte) item names in battle: rewrites every `cpx`/`cmp` boundary check and every $0F8000 item-data reference to land on `assets_items_dat`. """ + +.include "src/rom_map.i" +.extern assets_items_dat + ; Item name expansion patches for battle graphics ; Changes 9-byte items to 12-byte items ; Redirects 0x0F8000 references to assets_items_dat diff --git a/src/battle/magic/patches.s b/src/battle/magic/patches.s index 266bd7e..6f791b3 100644 --- a/src/battle/magic/patches.s +++ b/src/battle/magic/patches.s @@ -2,6 +2,13 @@ ROM patches that wire the battle magic system to the relocated `draw_magic_list_direct` renderer + the long-form attack-name copier. """ + +.include "src/rom_map.i" +.extern assets_attack_names_dat +.extern assets_attack_names_ptr +.extern assets_magic_dat +.extern battle_magic_length + .extern draw_magic_list_direct .extern magic_list_ptrs diff --git a/src/battle/math_patches.s b/src/battle/math_patches.s index 31d375e..9278b66 100644 --- a/src/battle/math_patches.s +++ b/src/battle/math_patches.s @@ -2,6 +2,9 @@ Patches that re-point the bank-2 hardware multiplier (`Mult8` at $8560) at our reimplementation, plus the JMP trampoline at $83B9 jumping into `_hw_mult16`. """ + +.include "src/rom_map.i" + ; =========================================================================== ; Mult8 Hardware Implementation - Bank 2 version at $8560 ; Input: $26, $28 → Output: $2a = $26 * $28 diff --git a/src/battle/message.s b/src/battle/message.s index 1d7a84f..cb41f7b 100644 --- a/src/battle/message.s +++ b/src/battle/message.s @@ -1044,7 +1044,7 @@ toggling battle_flags mid-stream. Caller setup mirrors the vanilla draw_text contract: $EF50: 16-bit format buffer ptr (source bytes) - $EF52: 16-bit destination tilemap-buffer ptr (in bank \$7E) + $EF52: 16-bit destination tilemap-buffer ptr (in bank $7E) $EF54: line length (tiles per row, currently 15) $EF55: palette $7EEF82: rolling_slot_index (0..5) for VWF allocator base @@ -1110,7 +1110,7 @@ _di_clear: bne _di_clear ; X = src (format buffer ptr), Y = dest offset (0-relative into the -; tilemap buffer pointed to by \$32 / \$34). +; tilemap buffer pointed to by $32 / $34). ldx 0xEF50 ldy.w #0x0000 @@ -1151,7 +1151,7 @@ _di_loop: jmp.w _di_loop _di_fixed_char: -; Fixed-mode raw char: write current byte as tile_id at (\$34),y. No +; Fixed-mode raw char: write current byte as tile_id at ($34),y. No ; ora #0x01 on the attr -- the +0x100 high bit is only for VWF tiles ; in the 0x1xx range, fixed font tiles live in 0x00..0xFF. sta (0x34), y @@ -1167,7 +1167,7 @@ _di_fixed_char: _di_fixed: -; 0x03 BB -> write fixed tile_id BB at (\$34),y. Same shape as +; 0x03 BB -> write fixed tile_id BB at ($34),y. Same shape as ; _di_fixed_char (mirror of wram.put_char), no +0x100 bit set. inx lda.w 0x0000, x diff --git a/src/battle/message_patches.s b/src/battle/message_patches.s index 739f361..5bdcd90 100644 --- a/src/battle/message_patches.s +++ b/src/battle/message_patches.s @@ -2,6 +2,12 @@ Pinned-address overlay rewiring original battle-message pointer loads ($02C909, $02CC07, ...) to the relocated translated-string tables. """ + +.include "src/rom_map.i" +.extern msg_window_draw_text_trampoline +.extern assets_battle_text_ptr +.extern assets_battle_messages_ptr + .extern messages_vwf .scope message_patches { diff --git a/src/battle/monsters_patches.s b/src/battle/monsters_patches.s index d775c5f..f06c511 100644 --- a/src/battle/monsters_patches.s +++ b/src/battle/monsters_patches.s @@ -2,6 +2,10 @@ Patches that switch the battle monster-name loader from a fixed-size table to a pointer-indirected one (long names) and forward to `load_monster_pointer`. """ + +.include "src/rom_map.i" +.extern assets_monsters_long_dat + .extern load_monster_pointer .extern initialize_monster_slot .extern tab_escape_code diff --git a/src/battle/redraw_writer_patches.s b/src/battle/redraw_writer_patches.s index 6f73129..bef0b04 100644 --- a/src/battle/redraw_writer_patches.s +++ b/src/battle/redraw_writer_patches.s @@ -12,6 +12,9 @@ follow-up patches. """ +.include "src/rom_map.i" + + .extern set_active_char_and_dirty .extern messages_vwf .extern messages_vwf.init_monsters_gated diff --git a/src/battle/sram_patches.s b/src/battle/sram_patches.s index fc4c9ed..b656b7f 100644 --- a/src/battle/sram_patches.s +++ b/src/battle/sram_patches.s @@ -2,6 +2,9 @@ ROM patches that route every battle-text draw call (commands, monster names, char names, attack names, message window) through our messages-VWF init/deinit trampolines. """ + +.include "src/rom_map.i" + .include "config.i" .extern draw_command_list_for_character .extern battle_display_char diff --git a/src/ingame/credits.s b/src/ingame/credits.s index 7312d8a..d55ce20 100644 --- a/src/ingame/credits.s +++ b/src/ingame/credits.s @@ -3,6 +3,10 @@ In-place patches for the staff credits screen: re-point the credits text loader `assets_credits_text_bin` block. """ +.include "src/rom_map.i" +.extern assets_credits_text_bin + + .alloc at 0x13d7ef { ldx.w #assets_credits_text_bin & 0xffff } diff --git a/src/ingame/drops_rolling.s b/src/ingame/drops_rolling.s index 1c01362..1289141 100644 --- a/src/ingame/drops_rolling.s +++ b/src/ingame/drops_rolling.s @@ -40,6 +40,18 @@ State RAM layout (12 bytes from $1BE0, struct: RollingBufferState): """ +.import "items" + +; Labels borrowed from neighbouring modules. As an include these resolved +; because ff4.s composed one translation unit; a module names what it uses. +.extern check_can_use_item_trampoline +.extern draw_item_slot_inner_trampoline +.extern draw_window_trampoline +.extern drops_select_bg4_trampoline +.extern treasure_drops_window +.extern rolling_engine + + DROPS_VISIBLE_ITEMS := 5 DROPS_BUFFER_SLOTS := 6 DROPS_TOTAL_ITEMS := 8 @@ -51,11 +63,7 @@ DROPS_SCROLL_TOTAL_PIXELS := 16 ; code writes to bytes past $1BEB) to clean $7E:9C30. Engine path needs ; the full 35-byte struct ; the macro path only ever touched the first ; 12 bytes so the original $1BE0 base worked there. -; `RollingBufferState` is declared in items.i, which ff4.s includes -; ahead of this module - the assembler resolves the cast, the lint -; sees one file at a time and cannot. Codes are comma-separated, so -; the reason has to sit here rather than after the marker. -drops_rolling := (0x7E9C30 as RollingBufferState) ; noqa: S001 +drops_rolling := (0x7E9C30 as RollingBufferState) ; Drops scroll position lives one byte past the state block so it ; doesn't collide with the engine's RollingBufferState fields. Other @@ -95,6 +103,7 @@ DROPS_SCROLL_STATE_SCROLLING := 1 .include "../bank20.i" + .alloc drops_rolling_block in bank20_reloc { drops_ensure_hdma_initialized: """Lazy init: pin BG4VOFS shadow to 0 + configure ch4 driving BG4VOFS on first scroll.""" diff --git a/src/ingame/init_bg_scroll_hdma_patches.s b/src/ingame/init_bg_scroll_hdma_patches.s index fd0a7cb..150bf90 100644 --- a/src/ingame/init_bg_scroll_hdma_patches.s +++ b/src/ingame/init_bg_scroll_hdma_patches.s @@ -2,6 +2,10 @@ Caller-side patches retargeting `JSL $01EBD2` (original `InitBGScrollHDMA`) to the relocated copy in bank $21 after the original's ROM space is reclaimed. """ + +.include "src/rom_map.i" +.extern init_bg_scroll_hdma + ;; Caller patches for init_bg_scroll_hdma after relocation to bank $21. ;; Original `JSL $01EBD2` at $02:818A becomes `JSL $21EBD2`. ;; (In LoROM bank $21 is the only thing that changes; offset $EBD2 within diff --git a/src/ingame/inventory_rolling.s b/src/ingame/inventory_rolling.s index 79502cd..c97f5b7 100644 --- a/src/ingame/inventory_rolling.s +++ b/src/ingame/inventory_rolling.s @@ -2,6 +2,18 @@ Field-menu inventory rolling-buffer engine (single column, 5 visible rows + 1 prefetch): adapts the battle approach for the main menu items list with HDMA-based circular scrolling. """ + +.import "items" +.include "src/lib/rolling_buffer.i" + +; Borrowed from neighbouring modules; inlining used to supply them. +.extern check_can_use_item_trampoline +.extern draw_item_slot_inner_trampoline +.extern draw_window_trampoline +.extern reset_sprites_trampoline +.extern draw_trash_single_column +.extern rolling_engine + ; Rolling Buffer Implementation for Main Menu Inventory (Single Column) ; ; HDMA-based circular buffer scrolling for single-column menu inventory. diff --git a/src/ingame/inventory_rolling_trampolines.s b/src/ingame/inventory_rolling_trampolines.s index d2a1c60..b3eecaa 100644 --- a/src/ingame/inventory_rolling_trampolines.s +++ b/src/ingame/inventory_rolling_trampolines.s @@ -2,6 +2,47 @@ Bank-$01 trampolines (jsr.l + rts) into the inventory rolling routines that live in bank $21, plus small wrappers around original bank-$01 helpers used by the rolling code. """ + +.include "src/rom_map.i" +.extern drops_start_scroll_up_impl +.extern drops_start_scroll_down_impl +.extern drops_refresh_slots_impl +.extern drops_init_impl +.extern treasure_menu_exit_hook_impl +.extern treasure_menu_entry_hook_impl +.extern drops_finish_scroll_impl +.extern drops_update_scroll_frame_impl +.import "items" +.extern items_description +.extern shops + +; Typed views over the profiles' state blocks. A cast is compile-time, +; so it cannot be imported the way a label is: each module that reads +; these fields binds its own view over the same addresses, the way +; battle/inventory_rolling.s already does. +treasure_rolling := (0x7E9C00 as RollingBufferState) +drops_rolling := (0x7E9C30 as RollingBufferState) +.extern TREASURE_SCROLL_COOLDOWN_FRAMES +.extern treasure_finish_scroll_impl +.extern treasure_update_scroll_frame_impl +.extern treasure_start_scroll_up_impl +.extern treasure_start_scroll_down_impl +.extern treasure_swap_redraw_hook_impl_body +.extern treasure_refresh_slots_impl +.extern init_treasure_rolling_buffer_impl +.extern treasure_check_and_clear_count_impl +.extern sell_disable_hdma +.extern sell_scroll_down_impl +.extern sell_scroll_up_impl +.extern sell_init_impl +.extern finish_scroll_impl +.extern update_scroll_frame_impl +.extern start_scroll_up_impl +.extern start_scroll_down_impl +.extern swap_redraw_hook_impl_body +.extern init_menu_rolling_buffer_impl +.extern check_and_clear_count_impl + .include "config.i" .include "src/ingame/macros.i" diff --git a/src/ingame/items_menu.s b/src/ingame/items_menu.s index b732ba7..03e3608 100644 --- a/src/ingame/items_menu.s +++ b/src/ingame/items_menu.s @@ -6,6 +6,12 @@ DrawItemSlot at $01:9000, so patching here switches them in one go. """ +.include "src/rom_map.i" +.extern draw_field_item_name_trampoline +.extern assets_items_unleashed_dat +.extern multiply_item_index_17 + + .extern items_menu_vwf.draw_field_item_name ; Item name expansion for menu system ; Patches the multiply-by-9 to multiply-by-17 diff --git a/src/ingame/items_menu_vwf.s b/src/ingame/items_menu_vwf.s index e19d0bd..5689fd5 100644 --- a/src/ingame/items_menu_vwf.s +++ b/src/ingame/items_menu_vwf.s @@ -41,7 +41,7 @@ Status: """ -.include "src/items.i" +.import "items" .include "../bank20.i" .include "src/battle/inventory_budget.i" diff --git a/src/ingame/key_item_picker.s b/src/ingame/key_item_picker.s index 899c136..c6e3878 100644 --- a/src/ingame/key_item_picker.s +++ b/src/ingame/key_item_picker.s @@ -45,6 +45,17 @@ State RAM layout (12 bytes from $1BF0, struct: RollingBufferState): """ +.import "items" + +; Labels borrowed from neighbouring modules. As an include these resolved +; because ff4.s composed one translation unit; a module names what it uses. +.extern check_can_use_item_trampoline +.extern draw_item_slot_inner_trampoline +.extern wait_for_vblank_long +.extern rolling_engine +.extern render + + ; Four rows on screen, matching the window vanilla draws ; the engine ; adds the prefetch slot itself, and it stays inside the staging page ; without being pushed. @@ -59,11 +70,7 @@ KEY_ITEM_SCROLL_TOTAL_PIXELS := 16 ; the same reason as treasure ($9C00) + drops ($9C30) : engine path ; needs 35 bytes per instance, $1B00-$1BFF is too small and vanilla ; sprite code stomps past $1BEB. -; `RollingBufferState` is declared in items.i, which ff4.s includes -; ahead of this module - the assembler resolves the cast, the lint -; sees one file at a time and cannot. Codes are comma-separated, so -; the reason has to sit here rather than after the marker. -key_item_rolling := (0x7E9C60 as RollingBufferState) ; noqa: S001 +key_item_rolling := (0x7E9C60 as RollingBufferState) KEY_ITEM_SLIDE_OPEN_DONE := 0x08 @@ -128,6 +135,7 @@ KEY_ITEM_HDMA4_SRC_LO := 0x4342 KEY_ITEM_HDMA4_SRC_BANK := 0x4344 .include "src/rolling_state.i" + .include "../bank20.i" .alloc key_item_picker_block in bank20_reloc { diff --git a/src/ingame/key_item_picker_patches.s b/src/ingame/key_item_picker_patches.s index fef235a..f2d157f 100644 --- a/src/ingame/key_item_picker_patches.s +++ b/src/ingame/key_item_picker_patches.s @@ -30,6 +30,18 @@ Patched: """ +.include "src/rom_map.i" +.extern assets_items_unleashed_dat +.extern multiply_by_17 +.extern key_item_after_open_impl +.extern key_item_cursor_slot_impl +.extern key_item_scroll_limit_impl +.extern key_item_close_impl +.extern key_item_scroll_down_impl +.extern key_item_scroll_up_impl +.include "src/libmz.i" + + .include "config.i" .if TREASURE_INVENTORY_ROLLING { ; Silence vanilla's own list draw. UpdateItemText ($00:B22B) lays the diff --git a/src/ingame/new_game.s b/src/ingame/new_game.s index aecd166..56b48ab 100644 --- a/src/ingame/new_game.s +++ b/src/ingame/new_game.s @@ -7,6 +7,19 @@ geometry and Cecil sprite position that go with them. """ +.include "src/rom_map.i" +.include "src/menus/system_menus_text.i" + +; The macro above expands to a call into the menus text module, and the +; strings it points at live in the start-screen text module. +.extern load_text_with_destination_in_x +.extern display_window_with_text +.extern display_time +.extern display_text_in_menus +.extern newgame +.extern display_build_number + + .include "config.i" .include "src/ingame/macros.i" diff --git a/src/ingame/places_names.s b/src/ingame/places_names.s index 004bf0a..ee7361e 100644 --- a/src/ingame/places_names.s +++ b/src/ingame/places_names.s @@ -2,6 +2,12 @@ Place-name window patches: increase the window length to fit French names and re-route the loader through our pointer table. """ + +.include "src/rom_map.i" +.extern places_bottom_window +.extern places_top_window +.extern assets_places_names_dat + { place_name_length = 0x1A .alloc at 0x00B90E { diff --git a/src/ingame/shop_sell_rolling.s b/src/ingame/shop_sell_rolling.s index 38a14fa..559e273 100644 --- a/src/ingame/shop_sell_rolling.s +++ b/src/ingame/shop_sell_rolling.s @@ -26,6 +26,18 @@ the field menu. .include "../bank20.i" .include "config.i" +.import "items" + +; Labels this module borrows from its neighbours. As an include these +; resolved because ff4.s composed one translation unit; a module has to +; name what it uses. +.extern check_can_use_item_trampoline +.extern draw_item_slot_inner_trampoline +.extern draw_window_trampoline +.extern tfr_bg3_tiles_vblank_trampoline +.extern sell_select_bg3_trampoline +.extern wait_for_vblank_long +.extern rolling_engine SELL_VISIBLE_ITEMS := 8 SELL_BUFFER_SLOTS := 9 @@ -33,11 +45,7 @@ SELL_TOTAL_ITEMS := 48 ; State block in the shared $7E:99xx arena, past drops ($9C30) and the ; key-item picker ($9C60); the field profile sits at $9C90. -; `RollingBufferState` is declared in items.i, which ff4.s includes -; ahead of this module - the assembler resolves the cast, the lint -; sees one file at a time and cannot. Codes are comma-separated, so -; the reason has to sit here rather than after the marker. -sell_rolling := (0x7E9CC0 as RollingBufferState) ; noqa: S001 +sell_rolling := (0x7E9CC0 as RollingBufferState) ; Vanilla's own sell scroll position ($1B96, "first visible row") and ; cursor row ($1B94). The profile reads them rather than keeping its diff --git a/src/ingame/shop_sell_rolling_patches.s b/src/ingame/shop_sell_rolling_patches.s index 28ac262..dd1e561 100644 --- a/src/ingame/shop_sell_rolling_patches.s +++ b/src/ingame/shop_sell_rolling_patches.s @@ -10,6 +10,14 @@ length. """ +.include "src/rom_map.i" +.extern sell_leave +.extern sell_scroll_down +.extern sell_scroll_up +.extern sell_init +.include "src/libmz.i" + + .include "config.i" .if TREASURE_INVENTORY_ROLLING { ; Sell list draw, on entry and after a sale changes quantities. diff --git a/src/ingame/treasure_rolling.s b/src/ingame/treasure_rolling.s index e647058..4d8112d 100644 --- a/src/ingame/treasure_rolling.s +++ b/src/ingame/treasure_rolling.s @@ -2,6 +2,20 @@ Treasure inventory rolling-buffer engine (single column, 5 visible, 6 buffer slots, scroll limit 43) ; cloned from `inventory_rolling.s` and tuned for the chest UI. """ + +.import "items" +.include "src/lib/rolling_buffer.i" + +; Labels borrowed from neighbouring modules. As an include these resolved +; because ff4.s composed one translation unit; a module names what it uses. +.extern check_can_use_item_trampoline +.extern draw_item_slot_inner_trampoline +.extern draw_window_trampoline +.extern reset_sprites_trampoline +.extern treasure_inventory_window +.extern rolling_engine +.extern tfr_bg3_tiles_vblank_trampoline + ; Treasure inventory rolling buffer (single-column, 5 visible). ; @@ -16,6 +30,7 @@ from `inventory_rolling.s` and tuned for the chest UI. ; Layout (single column) .include "config.i" + TREASURE_VISIBLE_ITEMS := 5 ; Visible items at once TREASURE_BUFFER_SLOTS := 6 ; 6 slots (5 visible + 1 pre-render) TREASURE_TOTAL_ITEMS := 48 ; Total inventory items @@ -46,11 +61,7 @@ TREASURE_ITEM_LIST_HEIGHT := 80 ; 5 items × 16 pixels ; region. Engine path needs the full 35-byte struct (state + config + ; hook far-ptrs) ; the macro path only ever touched the first 12 bytes ; so the original $1BD0 base worked despite vanilla's later collisions. -; `RollingBufferState` is declared in items.i, which ff4.s includes -; ahead of this module - the assembler resolves the cast, the lint -; sees one file at a time and cannot. Codes are comma-separated, so -; the reason has to sit here rather than after the marker. -treasure_rolling := (0x7E9C00 as RollingBufferState) ; noqa: S001 +treasure_rolling := (0x7E9C00 as RollingBufferState) TREASURE_SCROLL_COOLDOWN_FRAMES := 0x0C ; 12 frames between scrolls while DOWN/UP is held diff --git a/src/items.i b/src/items.s similarity index 100% rename from src/items.i rename to src/items.s diff --git a/src/lib/rolling_buffer.s b/src/lib/rolling_buffer.i similarity index 100% rename from src/lib/rolling_buffer.s rename to src/lib/rolling_buffer.i diff --git a/src/lib/rolling_inventory_engine.s b/src/lib/rolling_inventory_engine.s index 0243dca..65d0869 100644 --- a/src/lib/rolling_inventory_engine.s +++ b/src/lib/rolling_inventory_engine.s @@ -17,6 +17,24 @@ sites that remain in the per-menu source files. """ +.import "items" + +; The profiles call into the engine and the engine dispatches back into +; their HDMA builders, so the two sides are mutually dependent. That is +; fine across modules: each compiles against the names it declares here +; and the linker resolves them. +.extern update_menu_scroll_hdma +.extern update_treasure_scroll_hdma +.extern update_drops_scroll_hdma +.extern update_key_item_scroll_hdma +.extern update_sell_scroll_hdma +.extern clear_inventory_slot +.extern draw_item_cursors_trampoline +.extern tfr_bg2_tiles_vblank_trampoline +.extern tfr_sprites_vblank_trampoline +.extern update_ctrl_after_scroll_trampoline + + .include "src/rolling_state.i" .include "../bank20.i" diff --git a/src/minimal_vwf_patches.s b/src/minimal_vwf_patches.s index b6634af..9035c85 100644 --- a/src/minimal_vwf_patches.s +++ b/src/minimal_vwf_patches.s @@ -2,6 +2,10 @@ Minimal dialog-VWF wiring: pointer-loading helpers + entry hooks called from the existing dialog routines so the VWF layer kicks in without rewriting the message window. """ + +.include "src/rom_map.i" +.include "src/libmz.i" + ;===================================================================== ; Les Fonctions de chargement de pointeur de dialogue ;===================================================================== diff --git a/src/rolling_state.i b/src/rolling_state.i index 1383b5f..bb8daae 100644 --- a/src/rolling_state.i +++ b/src/rolling_state.i @@ -6,6 +6,12 @@ bodies, and placement directives cannot nest. """ +; The cart SRAM map travels with the pool. `.map` is per translation +; unit and an imported module does not inherit the patch-main's, so a +; module that reserves from this pool needs bank $70 described here or +; the reservation has no region to sit in. +.map identifier=3 bank_range=0x70, 0x70 addr_range=0x0000, 0x7fff mask=0x8000 writable=1 + ; --- Rolling-menu state pool ------------------------------------------- ; ; Hand-picking scratch addresses has cost us repeatedly: bank-$00 diff --git a/src/rom_map.i b/src/rom_map.i new file mode 100644 index 0000000..3ad4095 --- /dev/null +++ b/src/rom_map.i @@ -0,0 +1,12 @@ +""" +The cart's ROM bus map. + +`.map` is per translation unit and an imported module does not inherit +the patch-main's, so any module that places code at an absolute address +needs the mapping described where it can see it. Kept in its own header +rather than copied per module: the declaration is identical everywhere +and the linker accepts the repeats. +""" + + +.map identifier=1 bank_range=0x00, 0x6f addr_range=0x8000, 0xffff mask=0x8000 mirror_bank_range=0x80, 0xcf diff --git a/src/small_vwf/item_description.s b/src/small_vwf/item_description.s index 7eabfce..dd6f9fc 100644 --- a/src/small_vwf/item_description.s +++ b/src/small_vwf/item_description.s @@ -1,6 +1,6 @@ """Small-VWF item-description renderer.""" .include "src/vwf_state.i" -.include "src/items.i" +.import "items" .scope items_description { """Small-VWF item-description renderer entry-points.""" diff --git a/src/small_vwf/render.s b/src/small_vwf/render.s index 2cea3bb..5aea771 100644 --- a/src/small_vwf/render.s +++ b/src/small_vwf/render.s @@ -15,7 +15,7 @@ vwf_state.i). .include "config.i" -.include "src/items.i" +.import "items" .include "src/vwf_state.i" VARS_BUFFER = 0x710000