summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--constants.asm1
-rw-r--r--constants/item_constants.asm2
-rw-r--r--constants/map_data_constants.asm7
-rw-r--r--constants/map_setup_constants.asm2
-rwxr-xr-xconstants/script_constants.asm15
-rwxr-xr-xengine/events/overworld.asm103
-rwxr-xr-xengine/items/inventory.asm41
-rwxr-xr-xengine/overworld/spawn_points.asm60
-rwxr-xr-xengine/smallflag.asm72
-rwxr-xr-xhome/items.asm24
-rw-r--r--home/map.asm2
-rw-r--r--home/overworld.asm16
-rw-r--r--macros/text.asm10
-rw-r--r--shim.sym4
-rw-r--r--tools/disasm_coverage.py41
-rw-r--r--wram.asm21
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.
diff --git a/shim.sym b/shim.sym
index 95b1d2f..5b6e8f7 100644
--- a/shim.sym
+++ b/shim.sym
@@ -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
diff --git a/wram.asm b/wram.asm
index 132a833..cc5092e 100644
--- a/wram.asm
+++ b/wram.asm
@@ -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