diff options
-rw-r--r-- | constants.asm | 1 | ||||
-rw-r--r-- | constants/item_constants.asm | 2 | ||||
-rw-r--r-- | constants/map_data_constants.asm | 7 | ||||
-rw-r--r-- | constants/map_setup_constants.asm | 2 | ||||
-rwxr-xr-x | constants/script_constants.asm | 15 | ||||
-rwxr-xr-x | engine/events/overworld.asm | 103 | ||||
-rwxr-xr-x | engine/items/inventory.asm | 41 | ||||
-rwxr-xr-x | engine/overworld/spawn_points.asm | 60 | ||||
-rwxr-xr-x | engine/smallflag.asm | 72 | ||||
-rwxr-xr-x | home/items.asm | 24 | ||||
-rw-r--r-- | home/map.asm | 2 | ||||
-rw-r--r-- | home/overworld.asm | 16 | ||||
-rw-r--r-- | macros/text.asm | 10 | ||||
-rw-r--r-- | shim.sym | 4 | ||||
-rw-r--r-- | tools/disasm_coverage.py | 41 | ||||
-rw-r--r-- | wram.asm | 21 |
16 files changed, 375 insertions, 46 deletions
diff --git a/constants.asm b/constants.asm index 88dd7ee..c559622 100644 --- a/constants.asm +++ b/constants.asm @@ -25,6 +25,7 @@ INCLUDE "constants/map_constants.asm" INCLUDE "constants/map_setup_constants.asm" INCLUDE "constants/tileset_constants.asm" INCLUDE "constants/map_data_constants.asm" +INCLUDE "constants/script_constants.asm" INCLUDE "constants/serial_constants.asm" diff --git a/constants/item_constants.asm b/constants/item_constants.asm index 30af41c..ebc3aee 100644 --- a/constants/item_constants.asm +++ b/constants/item_constants.asm @@ -261,6 +261,8 @@ NUM_TMS = const_value - ITEM_TM01 - 2 ; discount ITEM_C8 and ITEM_E1 const ITEM_HM07 ; fe * NUM_HMS = const_value - ITEM_HM01 + const ITEM_FF + NUM_TMS_HMS = NUM_TMS + NUM_HMS ; leftovers from pokered diff --git a/constants/map_data_constants.asm b/constants/map_data_constants.asm index 075a7f1..ac9908a 100644 --- a/constants/map_data_constants.asm +++ b/constants/map_data_constants.asm @@ -7,3 +7,10 @@ const ENVIRONMENT_5 const GATE const DUNGEON + +; SpawnPoints indexes (see data/maps/spawn_points.asm) +const_value = -1 + const SPAWN_N_A + +; size of each spawn point data +SPAWN_POINT_SIZE EQU 4
\ No newline at end of file diff --git a/constants/map_setup_constants.asm b/constants/map_setup_constants.asm index 046fc65..7357058 100644 --- a/constants/map_setup_constants.asm +++ b/constants/map_setup_constants.asm @@ -3,7 +3,7 @@ const MAPSETUP_CONTINUE ; $f1 const MAPSETUP_F2 const MAPSETUP_RELOADMAP ; $f3 - const MAPSETUP_F4 + const MAPSETUP_TELEPORT ; $f4 const MAPSETUP_F5 ; Note: entry is duplicate of $F4 const MAPSETUP_WARP ; $f6 const MAPSETUP_CONNECTION ; $f7 diff --git a/constants/script_constants.asm b/constants/script_constants.asm new file mode 100755 index 0000000..3aa19b5 --- /dev/null +++ b/constants/script_constants.asm @@ -0,0 +1,15 @@ +
+; Script IDs
+ const_def
+ const SCRIPT_ID_00 ; 00
+ const SCRIPT_ID_01 ; 01
+ const SCRIPT_ID_02 ; 02
+ const SCRIPT_ID_03 ; 03
+
+; Flags
+SCRIPT_FINISHED EQU 7
+
+; Masks/Return Values
+SCRIPT_FINISHED_MASK = 1 << SCRIPT_FINISHED
+SCRIPT_SUCCESS EQU SCRIPT_FINISHED_MASK | $f
+SCRIPT_FAIL EQU SCRIPT_FINISHED_MASK | 0
\ No newline at end of file diff --git a/engine/events/overworld.asm b/engine/events/overworld.asm new file mode 100755 index 0000000..a5b4553 --- /dev/null +++ b/engine/events/overworld.asm @@ -0,0 +1,103 @@ +INCLUDE "constants.asm"
+
+SECTION "TeleportFunction", ROMX[$52db], BANK[$03]
+
+; Sets wFieldMoveSucceeded to $f if successful, $0 if not
+TeleportFunction: ; 03:52db
+ xor a
+ ld [wFieldMoveScriptID], a
+.loop
+ ld a, [wFieldMoveScriptID]
+ bit SCRIPT_FINISHED, a
+ jr nz, .finish
+ ld hl, .JumpTable
+ call CallJumptable
+ jr .loop
+
+; Finish by returning only the low nibble
+.finish
+ and $FF - SCRIPT_FINISHED_MASK
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.JumpTable
+ dw .TryTeleport
+ dw .DoTeleport
+ dw .FailTeleport
+ dw .CheckIfSpawnPoint
+
+.TryTeleport: ; 03:52fc
+ call GetMapEnvironment
+ cp TOWN
+ jr z, .success
+ cp ROUTE
+ jr z, .success
+ ld a, SCRIPT_ID_02
+ ld [wFieldMoveScriptID], a
+ ret
+.success
+ ld a, SCRIPT_ID_03
+ ld [wFieldMoveScriptID], a
+ ret
+
+.CheckIfSpawnPoint ; 03:5313
+ ld a, [wLastSpawnMapGroup]
+ ld d, a
+ ld a, [wLastSpawnMapNumber]
+ ld e, a
+ callab IsSpawnPoint
+ jr c, .not_spawn
+ ld hl, .Text_CantFindDestination
+ call MenuTextBoxBackup
+ ld a, SCRIPT_FAIL
+ ld [wFieldMoveScriptID], a
+ ret
+.not_spawn
+ ld a, c
+ ld [wDefaultSpawnpoint], a
+ ld a, SCRIPT_ID_01
+ ld [wFieldMoveScriptID], a
+ ret
+
+.Text_CantFindDestination: ; 03:533B
+ text "とびさきが みつかりません"
+ para
+ done
+
+.DoTeleport: ; 03:534b
+ ldh a, [hROMBank]
+ ld hl, .TeleportScript
+ call QueueScript
+ ld a, SCRIPT_SUCCESS
+ ld [wFieldMoveScriptID], a
+ ret
+
+.FailTeleport: ; 03:5359
+ ld hl, .Text_CantUseHere
+ call MenuTextBoxBackup
+ ld a, SCRIPT_FAIL
+ ld [wFieldMoveScriptID], a
+ scf
+ ret
+
+.Text_CantUseHere: ; 03:5366
+ text "ここでは つかえません!"
+ para
+ done
+
+.TeleportScript: ; 03:5375
+ call RefreshScreen
+ ld hl, .Text_ReturnToLastMonCenter
+ call MenuTextBox
+ ld c, 60
+ call DelayFrames
+ call CloseWindow
+ call Function1fea
+ ld a, MAPSETUP_TELEPORT
+ ldh [hMapEntryMethod], a
+ jpab Functionfcc24
+
+.Text_ReturnToLastMonCenter: ; 03:5395
+ text "さいごに たちよった"
+ line "#センターにもどります"
+ done
\ No newline at end of file diff --git a/engine/items/inventory.asm b/engine/items/inventory.asm index 4a95bac..9c5a1ec 100755 --- a/engine/items/inventory.asm +++ b/engine/items/inventory.asm @@ -6,9 +6,7 @@ _ReceiveItem: ; 03:4AA1 call DoesHLEqualwNumBagItems
jp nz, PutItemInPocket
push hl
- ld hl, CheckItemPocket
- ld a, BANK(CheckItemPocket)
- call FarCall_hl
+ callab CheckItemPocket
ld a, [wItemAttributeParamBuffer]
dec a
ld hl, .Pockets
@@ -47,9 +45,7 @@ _TossItem: ; 03:4AE0 call DoesHLEqualwNumBagItems
jr nz, .remove_item
push hl
- ld hl, CheckItemPocket
- ld a, BANK(CheckItemPocket)
- call FarCall_hl
+ callab CheckItemPocket
ld a, [wItemAttributeParamBuffer]
dec a
ld hl, .Pockets
@@ -90,9 +86,7 @@ _CheckItem: ; 03:4B1E call DoesHLEqualwNumBagItems
jr nz, .not_bag
push hl
- ld hl, CheckItemPocket
- ld a, BANK(CheckItemPocket)
- call FarCall_hl
+ callab CheckItemPocket
ld a, [wItemAttributeParamBuffer]
dec a
ld hl, .Pockets
@@ -570,10 +564,34 @@ GetTMHMNumber: ; 03:4CFF .not_machine
and a
ret
+
+GetNumberedTMHM: ; 03:4D1A
+; Return the item id of a TM/HM by number c.
+ ld a, c
+ ld c, 0
+; Adjust for any dummy items.
+ cp ITEM_C8 - ITEM_TM01 ; TM01-04
+ jr c, .finish
+ inc c
+ cp ITEM_E1 - ITEM_TM01 - 1 ; TM05-28
+ jr c, .finish
+ inc c
+ cp ITEM_FF - ITEM_TM01 - 2 ; End of list
+ jr nc, .not_machine
+.finish
+ add c
+ add ITEM_TM01
+ ld c, a
+ scf
+ ret
+.not_machine
+ and a
+ ret
SECTION "_CheckTossableItem", ROMX[$53AD], BANK[$03]
-; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be removed from the bag.
+; Return 1 in wItemAttributeParamBuffer and
+; carry if wCurItem can't be removed from the bag.
_CheckTossableItem: ; 03:53AD
ld a, ITEMATTR_PERMISSIONS
call GetItemAttr
@@ -582,7 +600,8 @@ _CheckTossableItem: ; 03:53AD and a
ret
-; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be selected.
+; Return 1 in wItemAttributeParamBuffer
+; and carry if wCurItem can't be selected.
CheckSelectableItem: ; 03:53B8
ld a, ITEMATTR_PERMISSIONS
call GetItemAttr
diff --git a/engine/overworld/spawn_points.asm b/engine/overworld/spawn_points.asm new file mode 100755 index 0000000..81b04b0 --- /dev/null +++ b/engine/overworld/spawn_points.asm @@ -0,0 +1,60 @@ +INCLUDE "constants.asm"
+
+SECTION "LoadSpawnPoint", ROMX[$4791], BANK[$03]
+
+LoadSpawnPoint: ; 03:4791
+; loads the spawn point in wDefaultSpawnpoint
+ push hl
+ push de
+ ld a, [wDefaultSpawnpoint]
+ and a
+ jr z, .skip
+ dec a
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ ld de, SpawnPoints
+ add hl, de
+ ld a, [hli]
+ ld [wMapGroup], a
+ ld a, [hli]
+ ld [wMapId], a
+ ld a, [hli]
+ ld [wXCoord], a
+ ld a, [hli]
+ ld [wYCoord], a
+.skip
+ pop de
+ pop hl
+ ret
+
+IsSpawnPoint: ; 03:47b6
+; Checks if the map loaded in de is a spawn point.
+; Returns carry if it's a spawn point.
+ ld hl, SpawnPoints
+ ld c, 1
+.loop
+ ld a, [hl]
+ cp SPAWN_N_A
+ jr z, .fail
+ cp d
+ jr nz, .next
+ inc hl
+ ld a, [hld]
+ cp e
+ jr z, .succeed
+.next
+ push bc
+ ld bc, SPAWN_POINT_SIZE
+ add hl, bc
+ pop bc
+ inc c
+ jr .loop
+.fail
+ and a
+ ret
+.succeed
+ scf
+ ret
+
diff --git a/engine/smallflag.asm b/engine/smallflag.asm new file mode 100755 index 0000000..dfce475 --- /dev/null +++ b/engine/smallflag.asm @@ -0,0 +1,72 @@ +SECTION "SmallFarFlagAction", ROMX[$4d33], BANK[$03]
+
+SmallFarFlagAction: ; 03:4d33
+; Perform action b on bit c in flag array hl.
+; If checking a flag, check flag array d:hl unless d is 0.
+
+; For longer flag arrays, see FlagAction.
+
+ push hl
+ push bc
+
+; Divide by 8 to get the byte we want.
+ push bc
+ srl c
+ srl c
+ srl c
+ ld b, 0
+ add hl, bc
+ pop bc
+
+; Which bit we want from the byte
+ ld a, c
+ and 7
+ ld c, a
+
+; Shift left until we can mask the bit
+ ld a, 1
+ jr z, .shifted
+.shift
+ add a
+ dec c
+ jr nz, .shift
+.shifted
+ ld c, a
+
+; What are we doing to this flag?
+ dec b
+ jr z, .set ; 1
+ dec b
+ jr z, .check ; 2
+
+.reset
+ ld a, c
+ cpl
+ and [hl]
+ ld [hl], a
+ jr .done
+
+.set
+ ld a, [hl]
+ or c
+ ld [hl], a
+ jr .done
+
+.check
+ ld a, d
+ cp 0
+ jr nz, .farcheck
+
+ ld a, [hl]
+ and c
+ jr .done
+
+.farcheck
+ call GetFarByte
+ and c
+
+.done
+ pop bc
+ pop hl
+ ld c, a
+ ret
\ No newline at end of file diff --git a/home/items.asm b/home/items.asm index 498edc6..46f510c 100755 --- a/home/items.asm +++ b/home/items.asm @@ -1,12 +1,28 @@ INCLUDE "constants.asm"
if DEBUG
-SECTION "AddItemToInventory", ROM0[$3259]
+SECTION "TossItem", ROM0[$3243]
else
-SECTION "AddItemToInventory", ROM0[$321D]
+SECTION "TossItem", ROM0[$3207]
endc
-AddItemToInventory:: ; 3259
+TossItem: ; 00:3243
+ ldh a, [hROMBank]
+ push af
+ ld a, BANK(_TossItem)
+ call Bankswitch
+ push hl
+ push de
+ push bc
+ call _TossItem
+ pop bc
+ pop de
+ pop hl
+ pop af
+ call Bankswitch
+ ret
+
+ReceiveItem:: ; 3259
; function to add an item (in varying quantities) to the player's bag or PC box
; INPUT:
; HL = address of inventory (either wNumBagItems or wNumBoxItems)
@@ -45,7 +61,7 @@ GiveItem:: ld a, c
ld [wItemQuantity], a
ld hl, wNumBagItems
- call AddItemToInventory
+ call ReceiveItem
ret nc
call GetItemName
call CopyStringToCD31
diff --git a/home/map.asm b/home/map.asm index aac770c..8105781 100644 --- a/home/map.asm +++ b/home/map.asm @@ -331,7 +331,7 @@ MapSetup_Continue:: ; 22e6 call DisableLCD call DisableAudio call VolumeOff - callab DebugWarp + callab LoadSpawnPoint call CopyMapPartialAndAttributes call SetUpMapBuffer call InitUnknownBuffercc9e diff --git a/home/overworld.asm b/home/overworld.asm index afa73cc..2b37b7c 100644 --- a/home/overworld.asm +++ b/home/overworld.asm @@ -29,11 +29,11 @@ CheckStartmenuSelectHook: ldh a, [hStartmenuCloseAndSelectHookEnable] and a ret z ; hook is disabled - ld hl, StartmenuCloseAndSelectHookPtr + ld hl, wQueuedScriptAddr ld a, [hli] ld h, [hl] ld l, a - ld a, [StartmenuCloseAndSelectHookBank] + ld a, [wQueuedScriptBank] call FarCall_hl ld hl, hStartmenuCloseAndSelectHookEnable xor a @@ -178,18 +178,18 @@ ScheduleColumnRedrawHelper: ; 2d10 (0:2d10) ret if DEBUG -SECTION "Install StartMenu Hook Function", ROM0[$35EC] +SECTION "QueueScript", ROM0[$35EC] else -SECTION "Install StartMenu Hook Function", ROM0[$35B0] +SECTION "QueueScript", ROM0[$35B0] endc -InstallStartmenuCloseAndSelectHook:: +QueueScript:: ; Install a function that is called as soon as ; the start menu is closed or directly after ; the select button function ran - ld [StartmenuCloseAndSelectHookBank], a + ld [wQueuedScriptBank], a ld a, l - ld [StartmenuCloseAndSelectHookPtr], a + ld [wQueuedScriptAddr], a ld a, h - ld [StartmenuCloseAndSelectHookPtr + 1], a + ld [wQueuedScriptAddr + 1], a ret diff --git a/macros/text.asm b/macros/text.asm index f95c300..fd88918 100644 --- a/macros/text.asm +++ b/macros/text.asm @@ -1,13 +1,21 @@ text EQUS "db $00," ; Start writing text. next EQUS "db \"<NEXT>\"," ; Move a line down. line EQUS "db \"<LINE>\"," ; Start writing at the bottom line. -para EQUS "db \"<PARA>\"," ; Start a new paragraph. cont EQUS "db \"<CONT>\"," ; Scroll to the next line. done EQUS "db \"<DONE>\"" ; End a text box. prompt EQUS "db \"<PROMPT>\"" ; Prompt the player to end a text box (initiating some other event). text_end EQUS "db $50" ; End control code for text processor ; different from @ +; Start a new paragraph +para: MACRO + if _NARG == 0 + db "<PARA>" + else + db "<PARA>", \1 ; Rest of text + endc +ENDM + ; TODO: determine if these are in ; Pokedex text commands are only used with pokered. ; They are included for compatibility. @@ -59,8 +59,7 @@ 02:5695 CheckSGB 03:4000 Functionc000 -03:4791 DebugWarp -03:479F DebugWarp.Destinations +03:47D5 SpawnPoints 03:488D Tilesets 03:4D33 Functioncd33 03:4D6F Functioncd6f @@ -460,6 +459,7 @@ 3A:52C7 Music 3F:40E9 InGameDebugMenu +3F:4C24 Functionfcc24 3F:4E3E Functionfce3e 3F:5B66 Functionfdb66 3F:6255 Functionfe255 diff --git a/tools/disasm_coverage.py b/tools/disasm_coverage.py index 39d1960..9fcd61e 100644 --- a/tools/disasm_coverage.py +++ b/tools/disasm_coverage.py @@ -10,13 +10,13 @@ import png from mapreader import MapReader from colorsys import hls_to_rgb -if __name__ == "__main__": +if __name__ == '__main__': # argument parser ap = argparse.ArgumentParser() - ap.add_argument("-o", dest="filename", default="coverage.png") - ap.add_argument("-s", dest="statsname", default="coverage.log") - ap.add_argument("-m", dest="mapfile", required=True) - ap.add_argument("-b", dest="num_banks", required=True, type=lambda x: int(x, 0)) + ap.add_argument('-r', dest='romname') + ap.add_argument('-o', dest='filename', default='coverage.png') + ap.add_argument('-m', dest='mapfile', required=True) + ap.add_argument('-b', dest='num_banks', required=True, type=lambda x: int(x, 0)) args = ap.parse_args() bank_mask = 0x3FFF @@ -24,6 +24,7 @@ if __name__ == "__main__": width = 256 # pixels per row bpp = 8 # bytes per pixel + romname = args.romname rom_size = args.num_banks * bank_size # bytes height = (args.num_banks * bank_size + (width * bpp - 1)) // (width * bpp) # pixels rows_per_bank = bank_size // (width * bpp) @@ -34,17 +35,37 @@ if __name__ == "__main__": l = f.readlines() except UnicodeDecodeError: # Python 3 seems to choke on the file's encoding, but the `encoding` keyword only works on Py3 - with open(args.mapfile, 'r', encoding= "utf-8") as f: + with open(args.mapfile, 'r', encoding= 'utf-8') as f: l = f.readlines() r.read_map_data(l) - hit_data = [[0] * width for _ in range(height)] default_bank_data = {'sections': [], 'used': 0, 'slack': bank_size} + filler = [0x00, 0xFF] + + if (romname is not None): + with open(romname, 'rb') as f: + for rb in range(0, args.num_banks): + data = r.bank_data['ROM Bank'].get(rb, default_bank_data) + bank = f.read(bank_size) + if (bank[bank_size - 1] in filler): + fill = bank[bank_size - 1] + for i in reversed(range(-1, bank_size - 1)): + if (i < 0 or bank[i] != fill): + break + # i is now pointing to first different byte + beg = i + 1 + (0 if rb == 0 else bank_size) + end = bank_size + (0 if rb == 0 else bank_size) + data['sections'].append({'beg': beg, 'end': end, 'name': 'Section_Trailing_Fill', 'symbols': []}) + + hit_data = [[0] * width for _ in range(height)] for bank in range(args.num_banks): data = r.bank_data['ROM Bank'].get(bank, default_bank_data) for s in data['sections']: beg = (s['beg'] & bank_mask) + bank * bank_size - end = (s['end'] & bank_mask) + bank * bank_size + end = ((s['end'] -1) & bank_mask) + bank * bank_size # end is exclusive + # skip zero-sized entries + if (s['beg'] == s['end']): + continue y_beg = beg // (width * bpp) x_beg = (beg % (width * bpp)) // bpp y_end = end // (width * bpp) @@ -63,10 +84,6 @@ if __name__ == "__main__": for x in range(x_line_beg, x_line_end + 1): hit_data[y][x] += bpp - with open(args.statsname, 'w') as stats: - # TODO: write stats - pass - png_data = [] for i, row in enumerate(hit_data): bank = i // rows_per_bank @@ -321,15 +321,17 @@ SECTION "CC32", WRAM0[$CC32] ; Please merge when more is disassembled wVBlankJoyFrameCounter: db ; cc32 wVBlankOccurred: db ; cc33 +wLastSpawnMapGroup: db ;cc34 +wLastSpawnMapNumber: db ; cc35 - ds 4 + ds 2 ;Controls what type of opening (fire/notes) you get. wcc38:: wTitleSequenceOpeningType:: ; cc38 db -wDebugWarpSelection:: ; cc39 +wDefaultSpawnpoint:: ; cc39 db wMovementBufferCount:: db ; cc3a @@ -404,8 +406,8 @@ wMenuScrollPosition:: db ; cd49 wTextDest:: ds 2; cd4a -StartmenuCloseAndSelectHookBank:: db ; cd4c -StartmenuCloseAndSelectHookPtr:: dw ; cd4d +wQueuedScriptBank:: db ; cd4c +wQueuedScriptAddr:: dw ; cd4d wPredefID:: ; cd4f db @@ -419,7 +421,9 @@ wPredefBC:: ; cd54 wFarCallBCBuffer:: ; cd54 dw - ds 3 ; TODO + ds 2 ; TODO + +wFieldMoveSucceeded:: db ; cd58 wVramState:: db ; cd59 ds 3 ; TODO @@ -466,11 +470,16 @@ wNextMapGroup:: db ; cdbf wNextMapId:: db ; cdc0 wPrevWarp:: db ; cdc1 - ds 11 + ds 1 + +wFieldMoveScriptID:: db ; cdc3 + + ds 9 wLinkBattleRNs:: ds 10 ; cdcd ; cddd + SECTION "CE00", WRAM0[$CE00] wBattleMode:: ; ce00 |