pokecrystal-board/home/map.asm

2585 lines
39 KiB
NASM

; Functions dealing with rendering and interacting with maps.
CheckScenes::
; Checks wCurMapSceneScriptPointer. If it's empty, returns -1 in a. Otherwise, returns the active scene ID in a.
push hl
ld hl, wCurMapSceneScriptPointer
ld a, [hli]
ld h, [hl]
ld l, a
or h
ld a, [hl]
jr nz, .scene_exists
ld a, -1
.scene_exists
pop hl
ret
GetCurrentMapSceneID::
; Grabs the wram map scene script pointer for the current map and loads it into wCurMapSceneScriptPointer.
; If there is no scene, both bytes of wCurMapSceneScriptPointer are wiped clean.
; Copy the current map group and number into bc. This is needed for GetMapSceneID.
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
; Blank out wCurMapSceneScriptPointer; this is the default scenario.
xor a
ld [wCurMapSceneScriptPointer], a
ld [wCurMapSceneScriptPointer + 1], a
call GetMapSceneID
ret c ; The map is not in the scene script table
; Load the scene script pointer from de into wCurMapSceneScriptPointer
ld a, e
ld [wCurMapSceneScriptPointer], a
ld a, d
ld [wCurMapSceneScriptPointer + 1], a
xor a
ret
GetMapSceneID::
; Searches the scene_var table for the map group and number loaded in bc, and returns the wram pointer in de.
; If the map is not in the scene_var table, returns carry.
push bc
ldh a, [hROMBank]
push af
ld a, BANK(MapScenes)
rst Bankswitch
ld hl, MapScenes
.loop
push hl
ld a, [hli] ; map group, or terminator
cp -1
jr z, .end ; the current map is not in the scene_var table
cp b
jr nz, .next ; map group did not match
ld a, [hli] ; map number
cp c
jr nz, .next ; map number did not match
jr .found ; we found our map
.next
pop hl
ld de, 4 ; scene_var size
add hl, de
jr .loop
.end
scf
jr .done
.found
ld e, [hl]
inc hl
ld d, [hl]
.done
pop hl
pop bc
ld a, b
rst Bankswitch
pop bc
ret
LoadScreenTilemapAndAttrmapPals::
call LoadScreenTilemap
call LoadScreenAttrmapPals
ret
LoadScreenTilemap::
ldh a, [hROMBank]
push af
ld a, [wTilesetBlocksBank]
rst Bankswitch
call LoadMetatiles
ld a, "■"
hlcoord 0, 0
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
call ByteFill
ld a, BANK(_LoadScreenTilemap)
rst Bankswitch
call _LoadScreenTilemap
pop af
rst Bankswitch
ret
LoadMetatiles::
; de <- wOverworldMapAnchor
ld a, [wOverworldMapAnchor]
ld e, a
ld a, [wOverworldMapAnchor + 1]
ld d, a
ld hl, wSurroundingTiles
ld b, SCREEN_META_HEIGHT
.row
push de
push hl
ld c, SCREEN_META_WIDTH
.col
push de
push hl
; Load the current map block.
; If the current map block is a border block, load the border block.
ld a, [de]
and a
jr nz, .ok
ld a, [wMapBorderBlock]
.ok
; Load the current wSurroundingTiles address into de.
ld e, l
ld d, h
; Set hl to the address of the current metatile data ([wTilesetBlocksAddress] + (a) tiles).
ld l, a
ld h, 0
add hl, hl
add hl, hl
add hl, hl
add hl, hl
ld a, [wTilesetBlocksAddress]
add l
ld l, a
ld a, [wTilesetBlocksAddress + 1]
adc h
ld h, a
; copy the 4x4 metatile
rept METATILE_WIDTH - 1
rept METATILE_WIDTH
ld a, [hli]
ld [de], a
inc de
endr
ld a, e
add SURROUNDING_WIDTH - METATILE_WIDTH
ld e, a
jr nc, .next\@
inc d
.next\@
endr
rept METATILE_WIDTH
ld a, [hli]
ld [de], a
inc de
endr
; Next metatile
pop hl
ld de, METATILE_WIDTH
add hl, de
pop de
inc de
dec c
jp nz, .col
; Next metarow
pop hl
ld de, SURROUNDING_WIDTH * METATILE_WIDTH
add hl, de
pop de
ld a, [wMapWidth]
add MAP_CONNECTION_PADDING_WIDTH * 2
add e
ld e, a
jr nc, .ok2
inc d
.ok2
dec b
jp nz, .row
ret
ReturnToMapFromSubmenu::
ld a, MAPSETUP_SUBMENU
ldh [hMapEntryMethod], a
farcall RunMapSetupScript
xor a
ldh [hMapEntryMethod], a
ret
CheckWarpTile::
call GetDestinationWarpNumber
ret nc
push bc
farcall CheckDirectionalWarp
pop bc
ret nc
call CopyWarpData
scf
ret
WarpCheck::
call GetDestinationWarpNumber
ret nc
call CopyWarpData
ret
GetDestinationWarpNumber::
farcall CheckWarpCollision
ret nc
ldh a, [hROMBank]
push af
call SwitchToMapScriptsBank
call .GetDestinationWarpNumber
pop de
ld a, d
rst Bankswitch
ret
.GetDestinationWarpNumber:
ld a, [wPlayerMapY]
sub 4
ld e, a
ld a, [wPlayerMapX]
sub 4
ld d, a
ld a, [wCurMapWarpEventCount]
and a
ret z
ld c, a
ld hl, wCurMapWarpEventsPointer
ld a, [hli]
ld h, [hl]
ld l, a
.loop
push hl
ld a, [hli]
cp e
jr nz, .next
ld a, [hli]
cp d
jr nz, .next
jr .found_warp
.next
pop hl
ld a, WARP_EVENT_SIZE
add l
ld l, a
jr nc, .okay
inc h
.okay
dec c
jr nz, .loop
xor a
ret
.found_warp
pop hl
call .IncreaseHLTwice
ret nc ; never encountered
ld a, [wCurMapWarpEventCount]
inc a
sub c
ld c, a
scf
ret
.IncreaseHLTwice:
inc hl
inc hl
scf
ret
CopyWarpData::
ldh a, [hROMBank]
push af
call SwitchToMapScriptsBank
call .CopyWarpData
pop af
rst Bankswitch
scf
ret
.CopyWarpData:
push bc
ld hl, wCurMapWarpEventsPointer
ld a, [hli]
ld h, [hl]
ld l, a
ld a, c
dec a
ld bc, WARP_EVENT_SIZE
call AddNTimes
ld bc, 2 ; warp number
add hl, bc
ld a, [hli]
cp -1
jr nz, .skip
ld hl, wBackupWarpNumber
ld a, [hli]
.skip
pop bc
ld [wNextWarp], a
ld a, [hli]
ld [wNextMapGroup], a
ld a, [hli]
ld [wNextMapNumber], a
ld a, c
ld [wPrevWarp], a
ld a, [wMapGroup]
ld [wPrevMapGroup], a
ld a, [wMapNumber]
ld [wPrevMapNumber], a
scf
ret
CheckOutdoorMap::
cp INDOOR_ENVIRONMENT
jr c, .outdoor
ret ; nz
.outdoor
xor a
ret ; z
CheckIndoorMap::
cp INDOOR_ENVIRONMENT
jr nc, .indoor
ret ; nz
.indoor
xor a
ret ; z
BackupMapObjects::
; this map setup command is called just before the EnterMap* map setup command,
; when wMapGroup and wMapNumber still contain the about-to-leave map.
; there is no need to backup map objects when going through connections during View Map mode,
; as during this mode there is no possible interaction that leads to a map object changing status.
; BackupMapObjectsOnEnterViewMapMode is called when entering View Map mode.
ldh a, [hCurBoardEvent]
cp BOARDEVENT_VIEW_MAP_MODE
ret z
; fallthrough
BackupMapObjectsOnEnterViewMapMode::
ld hl, wMapGroup
ld a, [hli]
ld d, a ; d = wMapGroup
ld e, [hl] ; e = wMapNumber
ld a, BANK(wMapObjectsBackups)
ld [rSVBK], a
ld hl, wMap1ObjectsBackup
ld bc, wMap2ObjectsBackup - wMap1ObjectsBackup - 2
.find_loop
ld a, [hl]
cp GROUP_N_A
jr z, .found_available_entry
and a ; cp $00 (terminator at wMapObjectsBackupsEnd)
jr z, .done
cp d ; wMap<N>ObjectsBackupMapGroup == wMapGroup?
jr nz, .next
inc hl
ld a, [hl]
cp e ; wMap<N>ObjectsBackupMapNumber == wMapNumber?
jr nz, .next2
inc hl
jr .found_matching_entry
.next
inc hl
.next2
inc hl
add hl, bc
jr .find_loop
.found_available_entry
ld [hl], d ; wMapGroup
inc hl
ld [hl], e ; wMapNumber
inc hl
.found_matching_entry
ld a, 1
ld [rSVBK], a
ld de, wMapObject1
ld a, [wCurMapObjectEventCount] ; how many object events are in the about-to-leave map?
and a
jr z, .done ; return if there's zero object events to be saved
sla a
sla a
sla a
sla a
ld c, a ; c = [wCurMapObjectEventCount] * MAPOBJECT_LENGTH
.copy_loop
ld a, 1
ld [rSVBK], a
ld a, c
and %00001111
ld a, $ff ; StructID (first byte) of each object event must be set to $ff
jr z, .got_value
ld a, [de]
.got_value
inc de
ld b, a
ld a, BANK(wMapObjectsBackups)
ld [rSVBK], a
ld a, b
ld [hli], a
dec c
jr nz, .copy_loop
.done
ld a, 1
ld [rSVBK], a
ret
LoadMapAttributes::
call CopyMapPartialAndAttributes
call SwitchToMapScriptsBank
call ReadMapScripts
xor a ; do not skip object events
call ReadMapEvents
ret
LoadMapAttributes_SkipObjects::
call CopyMapPartialAndAttributes
call SwitchToMapScriptsBank
call ReadMapScripts
ld a, TRUE ; skip object events
call ReadMapEvents
ret
CopyMapPartialAndAttributes::
call CopyMapPartial
call SwitchToMapAttributesBank
call GetMapAttributesPointer
call CopyMapAttributes
call GetMapConnections
ret
CopyMapPartialAndAttributesPartial::
; used by LoadDisabledSpaces only
ld a, [hROMBank]
push af
call CopyMapPartial
call SwitchToMapAttributesBank
call GetMapAttributesPointer
call CopyMapAttributesPartial
pop af
rst Bankswitch
ret
ReadMapEvents::
push af
ld hl, wMapEventsPointer
ld a, [hli]
ld h, [hl]
ld l, a
inc hl
inc hl
call ReadWarpEvents
call ReadAnchorEvents
call ReadCoordEvents
call ReadBGEvents
pop af
and a ; skip object events?
ret nz
call ReadObjectEvents
ret
ReadMapScripts::
ld hl, wMapScriptsPointer
ld a, [hli]
ld h, [hl]
ld l, a
call ReadMapSceneScripts
call ReadMapCallbacks
ret
CopyMapAttributes::
ld de, wMapAttributes
ld c, wMapAttributesEnd - wMapAttributes
.loop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .loop
ret
CopyMapAttributesPartial::
; copy only: wMapScriptsBank, wMapScriptsPointer, wMapEventsPointer, wMapSpacesPointer
ld bc, wMapScriptsBank - wMapAttributes
add hl, bc
ld de, wMapScriptsBank
ld c, wMapSpacesPointer + $2 - wMapScriptsBank
.loop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .loop
ret
GetMapConnections::
ld a, $ff
ld [wNorthConnectedMapGroup], a
ld [wSouthConnectedMapGroup], a
ld [wWestConnectedMapGroup], a
ld [wEastConnectedMapGroup], a
ld a, [wMapConnections]
ld b, a
bit NORTH_F, b
jr z, .no_north
ld de, wNorthMapConnection
call GetMapConnection
.no_north
bit SOUTH_F, b
jr z, .no_south
ld de, wSouthMapConnection
call GetMapConnection
.no_south
bit WEST_F, b
jr z, .no_west
ld de, wWestMapConnection
call GetMapConnection
.no_west
bit EAST_F, b
jr z, .no_east
ld de, wEastMapConnection
call GetMapConnection
.no_east
ret
GetMapConnection::
; Load map connection struct at hl into de.
ld c, wSouthMapConnection - wNorthMapConnection
.loop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .loop
ret
ReadMapSceneScripts::
ld a, [hli] ; scene_script count
ld c, a
ld [wCurMapSceneScriptCount], a
ld a, l
ld [wCurMapSceneScriptsPointer], a
ld a, h
ld [wCurMapSceneScriptsPointer + 1], a
ld a, c
and a
ret z
ld bc, SCENE_SCRIPT_SIZE
call AddNTimes
ret
ReadMapCallbacks::
ld a, [hli]
ld c, a
ld [wCurMapCallbackCount], a
ld a, l
ld [wCurMapCallbacksPointer], a
ld a, h
ld [wCurMapCallbacksPointer + 1], a
ld a, c
and a
ret z
ld bc, CALLBACK_SIZE
call AddNTimes
ret
ReadWarpEvents::
ld a, [hli]
ld c, a
ld [wCurMapWarpEventCount], a
ld a, l
ld [wCurMapWarpEventsPointer], a
ld a, h
ld [wCurMapWarpEventsPointer + 1], a
ld a, c
and a
ret z
ld bc, WARP_EVENT_SIZE
call AddNTimes
ret
ReadAnchorEvents::
ld a, [hli]
ld c, a
ld [wCurMapAnchorEventCount], a
ld a, l
ld [wCurMapAnchorEventsPointer], a
ld a, h
ld [wCurMapAnchorEventsPointer + 1], a
ld a, c
and a
ret z
ld bc, ANCHOR_EVENT_SIZE
call AddNTimes
ret
ReadCoordEvents::
ld a, [hli]
ld c, a
ld [wCurMapCoordEventCount], a
ld a, l
ld [wCurMapCoordEventsPointer], a
ld a, h
ld [wCurMapCoordEventsPointer + 1], a
ld a, c
and a
ret z
ld bc, COORD_EVENT_SIZE
call AddNTimes
ret
ReadBGEvents::
ld a, [hli]
ld c, a
ld [wCurMapBGEventCount], a
ld a, l
ld [wCurMapBGEventsPointer], a
ld a, h
ld [wCurMapBGEventsPointer + 1], a
ld a, c
and a
ret z
ld bc, BG_EVENT_SIZE
call AddNTimes
ret
ReadObjectEvents::
push hl
call ClearNonPlayerObjectStructs
pop de
ld hl, wMapObject1
ld a, [de]
inc de
ld [wCurMapObjectEventCount], a
ld a, e
ld [wCurMapObjectEventsPointer], a
ld a, d
ld [wCurMapObjectEventsPointer + 1], a
call CopyMapObjectEvents
; get NUM_OBJECTS - [wCurMapObjectEventCount] - 1
ld a, [wCurMapObjectEventCount]
ld c, a
ld a, NUM_OBJECTS - 1
sub c
jr z, .skip
jr c, .skip
push af
ld a, [wCurMapObjectEventCount]
ld bc, MAPOBJECT_LENGTH
call AddNTimes
inc hl
; Fill the remaining MAPOBJECT_SPRITE and MAPOBJECT_Y_COORD with 0 and -1, respectively.
pop af ; a = (NUM_OBJECTS - 1) - [wCurMapObjectEventCount], a > 0
ld bc, MAPOBJECT_LENGTH
.loop
ld [hl], 0
inc hl
ld [hl], -1
dec hl
add hl, bc
dec a
jr nz, .loop
.skip
ld h, d
ld l, e
ret
CopyMapObjectEvents::
ld a, [wCurMapObjectEventCount]
and a
ret z
push hl
push de
call .FindMapObjectsBackup
pop de
pop hl
ret c
; hl = wMapObject1
; de = [wCurMapObjectEventsPointer]
ld a, [wCurMapObjectEventCount]
ld c, a
.loop
push bc
push hl
ld a, $ff
ld [hli], a
ld b, OBJECT_EVENT_SIZE
.loop2
ld a, [de]
inc de
ld [hli], a
dec b
jr nz, .loop2
pop hl
ld bc, MAPOBJECT_LENGTH
add hl, bc
pop bc
dec c
jr nz, .loop
ret
.FindMapObjectsBackup:
; this is called from the LoadMapAttributes map map setup command.
; at this point wMapGroup and wMapNumber contain the about-to-enter map.
; if map is found in wMapObjectsBackups, copy object data from there and return carry.
; return nc otherwise.
ld hl, wMapGroup
ld a, [hli]
ld d, a ; d = wMapGroup
ld e, [hl] ; e = wMapNumber
ld a, BANK(wMapObjectsBackups)
ld [rSVBK], a
ld hl, wMap1ObjectsBackup
ld bc, wMap2ObjectsBackup - wMap1ObjectsBackup - 2
.find_loop
ld a, [hl]
cp GROUP_N_A
jr z, .no_match
and a ; cp $00 (terminator at wMapObjectsBackupsEnd)
jr z, .no_match
cp d ; wMap<N>ObjectsBackupMapGroup == wMapGroup?
jr nz, .next
inc hl
ld a, [hl]
cp e ; wMap<N>ObjectsBackupMapNumber == wMapNumber?
jr nz, .next2
inc hl
jr .found_matching_entry
.next
inc hl
.next2
inc hl
add hl, bc
jr .find_loop
.found_matching_entry
ld a, 1
ld [rSVBK], a
ld de, wMapObject1
ld a, [wCurMapObjectEventCount]
and a
jr z, .done ; return if there's zero object events to be read
sla a
sla a
sla a
sla a
ld c, a ; c = [wCurMapObjectEventCount] * OBJECT_LENGTH
.copy_loop
ld a, BANK(wMapObjectsBackups)
ld [rSVBK], a
ld a, [hli]
ld b, a
ld a, 1
ld [rSVBK], a
ld a, b
ld [de], a
inc de
dec c
jr nz, .copy_loop
.done
ld a, 1
ld [rSVBK], a
scf
ret
.no_match
ld a, 1
ld [rSVBK], a
xor a
ret
ClearObjectStructs::
ld hl, wObjectStructs
ld bc, OBJECT_LENGTH * NUM_OBJECT_STRUCTS
xor a
jp ByteFill
ClearNonPlayerObjectStructs::
ld hl, wObject1Struct
ld bc, OBJECT_LENGTH * (NUM_OBJECT_STRUCTS - 1)
xor a
jp ByteFill
GetWarpDestCoords::
call GetMapScriptsBank
rst Bankswitch
ld hl, wMapEventsPointer
ld a, [hli]
ld h, [hl]
ld l, a
rept 3 ; get to the warp coords
inc hl
endr
ld a, [wWarpNumber]
dec a
ld c, a
ld b, 0
ld a, WARP_EVENT_SIZE
call AddNTimes
ld a, [hli]
ld [wYCoord], a
ld a, [hli]
ld [wXCoord], a
; destination warp number
ld a, [hli]
cp -1
jr nz, .skip
call .backup
.skip
farcall GetMapScreenCoords
ret
.backup
ld a, [wPrevWarp]
ld [wBackupWarpNumber], a
ld a, [wPrevMapGroup]
ld [wBackupMapGroup], a
ld a, [wPrevMapNumber]
ld [wBackupMapNumber], a
ret
LoadBlockData::
ld hl, wOverworldMapBlocks
ld bc, wOverworldMapBlocksEnd - wOverworldMapBlocks
ld a, 0
call ByteFill
call ChangeMap
call FillMapConnections
ld a, MAPCALLBACK_TILES
call RunMapCallback
ret
ChangeMap::
ldh a, [hROMBank]
push af
ld hl, wOverworldMapBlocks
ld a, [wMapWidth]
ldh [hConnectedMapWidth], a
add $6
ldh [hConnectionStripLength], a
ld c, a
ld b, 0
add hl, bc
add hl, bc
add hl, bc
ld c, 3
add hl, bc
ld a, [wMapBlocksBank]
rst Bankswitch
ld a, [wMapBlocksPointer]
ld e, a
ld a, [wMapBlocksPointer + 1]
ld d, a
ld a, [wMapHeight]
ld b, a
.row
push hl
ldh a, [hConnectedMapWidth]
ld c, a
.col
ld a, [de]
inc de
ld [hli], a
dec c
jr nz, .col
pop hl
ldh a, [hConnectionStripLength]
add l
ld l, a
jr nc, .okay
inc h
.okay
dec b
jr nz, .row
pop af
rst Bankswitch
ret
FillMapConnections::
; North
ld a, [wNorthConnectedMapGroup]
cp $ff
jr z, .South
ld b, a
ld a, [wNorthConnectedMapNumber]
ld c, a
call GetAnyMapBlocksBank
ld a, [wNorthConnectionStripPointer]
ld l, a
ld a, [wNorthConnectionStripPointer + 1]
ld h, a
ld a, [wNorthConnectionStripLocation]
ld e, a
ld a, [wNorthConnectionStripLocation + 1]
ld d, a
ld a, [wNorthConnectionStripLength]
ldh [hConnectionStripLength], a
ld a, [wNorthConnectedMapWidth]
ldh [hConnectedMapWidth], a
call FillNorthConnectionStrip
.South:
ld a, [wSouthConnectedMapGroup]
cp $ff
jr z, .West
ld b, a
ld a, [wSouthConnectedMapNumber]
ld c, a
call GetAnyMapBlocksBank
ld a, [wSouthConnectionStripPointer]
ld l, a
ld a, [wSouthConnectionStripPointer + 1]
ld h, a
ld a, [wSouthConnectionStripLocation]
ld e, a
ld a, [wSouthConnectionStripLocation + 1]
ld d, a
ld a, [wSouthConnectionStripLength]
ldh [hConnectionStripLength], a
ld a, [wSouthConnectedMapWidth]
ldh [hConnectedMapWidth], a
call FillSouthConnectionStrip
.West:
ld a, [wWestConnectedMapGroup]
cp $ff
jr z, .East
ld b, a
ld a, [wWestConnectedMapNumber]
ld c, a
call GetAnyMapBlocksBank
ld a, [wWestConnectionStripPointer]
ld l, a
ld a, [wWestConnectionStripPointer + 1]
ld h, a
ld a, [wWestConnectionStripLocation]
ld e, a
ld a, [wWestConnectionStripLocation + 1]
ld d, a
ld a, [wWestConnectionStripLength]
ld b, a
ld a, [wWestConnectedMapWidth]
ldh [hConnectionStripLength], a
call FillWestConnectionStrip
.East:
ld a, [wEastConnectedMapGroup]
cp $ff
jr z, .Done
ld b, a
ld a, [wEastConnectedMapNumber]
ld c, a
call GetAnyMapBlocksBank
ld a, [wEastConnectionStripPointer]
ld l, a
ld a, [wEastConnectionStripPointer + 1]
ld h, a
ld a, [wEastConnectionStripLocation]
ld e, a
ld a, [wEastConnectionStripLocation + 1]
ld d, a
ld a, [wEastConnectionStripLength]
ld b, a
ld a, [wEastConnectedMapWidth]
ldh [hConnectionStripLength], a
call FillEastConnectionStrip
.Done:
ret
FillNorthConnectionStrip::
FillSouthConnectionStrip::
ld c, 3
.y
push de
push hl
ldh a, [hConnectionStripLength]
ld b, a
.x
ld a, [hli]
ld [de], a
inc de
dec b
jr nz, .x
pop hl
ldh a, [hConnectedMapWidth]
ld e, a
ld d, 0
add hl, de
pop de
ld a, [wMapWidth]
add 6
add e
ld e, a
jr nc, .okay
inc d
.okay
dec c
jr nz, .y
ret
FillWestConnectionStrip::
FillEastConnectionStrip::
.loop
ld a, [wMapWidth]
add 6
ldh [hConnectedMapWidth], a
push de
push hl
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
inc de
pop hl
ldh a, [hConnectionStripLength]
ld e, a
ld d, 0
add hl, de
pop de
ldh a, [hConnectedMapWidth]
add e
ld e, a
jr nc, .okay
inc d
.okay
dec b
jr nz, .loop
ret
LoadMapStatus::
ld [wMapStatus], a
ret
CallScript::
; Call a script at a:hl.
ld [wScriptBank], a
ld a, l
ld [wScriptPos], a
ld a, h
ld [wScriptPos + 1], a
ld a, PLAYEREVENT_MAPSCRIPT
ld [wScriptRunning], a
scf
ret
CallMapScript::
; Call a script at hl in the current bank if there isn't already a script running
ld a, [wScriptRunning]
and a
ret nz
call GetMapScriptsBank
jr CallScript
RunMapCallback::
; Will run the first callback found with execution index equal to a.
ld b, a
ldh a, [hROMBank]
push af
call SwitchToMapScriptsBank
call .FindCallback
jr nc, .done
call GetMapScriptsBank
ld b, a
ld d, h
ld e, l
call ExecuteCallbackScript
.done
pop af
rst Bankswitch
ret
.FindCallback:
ld a, [wCurMapCallbackCount]
ld c, a
and a
ret z
ld hl, wCurMapCallbacksPointer
ld a, [hli]
ld h, [hl]
ld l, a
or h
ret z
ld de, CALLBACK_SIZE
.loop
ld a, [hl]
cp b
jr z, .found
add hl, de
dec c
jr nz, .loop
xor a
ret
.found
inc hl
ld a, [hli]
ld h, [hl]
ld l, a
scf
ret
ExecuteCallbackScript::
; Do map callback de and return to script bank b.
farcall CallCallback
ld a, [wScriptMode]
push af
ld hl, wScriptFlags
ld a, [hl]
push af
set 1, [hl]
farcall EnableScriptMode
farcall ScriptEvents
pop af
ld [wScriptFlags], a
pop af
ld [wScriptMode], a
ret
MapTextbox::
ldh a, [hROMBank]
push af
ld a, b
rst Bankswitch
push hl
call ClearTextbox
lda_coord 17, 17
ldcoord_a 18, 17
call SafeUpdateSprites
ld a, 1
ldh [hOAMUpdate], a
call ApplyTilemap
pop hl
call PrintTextboxText
xor a
ldh [hOAMUpdate], a
pop af
rst Bankswitch
ret
Call_a_de::
; Call a:de.
ldh [hTempBank], a
ldh a, [hROMBank]
push af
ldh a, [hTempBank]
rst Bankswitch
call .de
pop af
rst Bankswitch
ret
.de
push de
ret
GetMovementData::
; Initialize the movement data for object c at b:hl
ldh a, [hROMBank]
push af
ld a, b
rst Bankswitch
ld a, c
call LoadMovementDataPointer
pop hl
ld a, h
rst Bankswitch
ret
GetScriptByte::
; Return byte at wScriptBank:wScriptPos in a.
push hl
push bc
ldh a, [hROMBank]
push af
ld a, [wScriptBank]
rst Bankswitch
ld hl, wScriptPos
ld c, [hl]
inc hl
ld b, [hl]
ld a, [bc]
inc bc
ld [hl], b
dec hl
ld [hl], c
ld b, a
pop af
rst Bankswitch
ld a, b
pop bc
pop hl
ret
ObjectEvent::
jumptextfaceplayer ObjectEventText
ObjectEventText::
text_far _ObjectEventText
text_end
BGEventText::
text_far _BGEventText
text_end
CoordinatesEventText::
text_far _CoordinatesEventText
text_end
CheckObjectMask::
ldh a, [hMapObjectIndex]
ld e, a
ld d, 0
ld hl, wObjectMasks
add hl, de
ld a, [hl]
ret
MaskObject::
ldh a, [hMapObjectIndex]
ld e, a
ld d, 0
ld hl, wObjectMasks
add hl, de
ld [hl], -1 ; masked
ret
UnmaskObject::
ldh a, [hMapObjectIndex]
ld e, a
ld d, 0
ld hl, wObjectMasks
add hl, de
ld [hl], 0 ; unmasked
ret
if DEF(_DEBUG)
ComputeROMXChecksum::
ldh a, [hROMBank]
push af
ld a, c
rst Bankswitch
ld hl, $4000 ; ROMX start
.loop
ld a, [hli]
add e
ld e, a
ld a, d
adc 0
ld d, a
ld a, h
cp $80 ; HIGH(ROMX end)
jr c, .loop
pop af
rst Bankswitch
ret
endc
ScrollMapUp::
hlcoord 0, 0
ld de, wBGMapBuffer
call BackupBGMapRow
ld c, 2 * SCREEN_WIDTH
call ScrollBGMapPalettes
ld a, [wBGMapAnchor]
ld e, a
ld a, [wBGMapAnchor + 1]
ld d, a
call UpdateBGMapRow
ld a, $1
ldh [hBGMapUpdate], a
ret
ScrollMapDown::
hlcoord 0, SCREEN_HEIGHT - 2
ld de, wBGMapBuffer
call BackupBGMapRow
ld c, 2 * SCREEN_WIDTH
call ScrollBGMapPalettes
ld a, [wBGMapAnchor]
ld l, a
ld a, [wBGMapAnchor + 1]
ld h, a
ld bc, BG_MAP_WIDTH tiles
add hl, bc
; cap d at HIGH(vBGMap0)
ld a, h
and %00000011
or HIGH(vBGMap0)
ld e, l
ld d, a
call UpdateBGMapRow
ld a, $1
ldh [hBGMapUpdate], a
ret
ScrollMapLeft::
hlcoord 0, 0
ld de, wBGMapBuffer
call BackupBGMapColumn
ld c, 2 * SCREEN_HEIGHT
call ScrollBGMapPalettes
ld a, [wBGMapAnchor]
ld e, a
ld a, [wBGMapAnchor + 1]
ld d, a
call UpdateBGMapColumn
ld a, $1
ldh [hBGMapUpdate], a
ret
ScrollMapRight::
hlcoord SCREEN_WIDTH - 2, 0
ld de, wBGMapBuffer
call BackupBGMapColumn
ld c, 2 * SCREEN_HEIGHT
call ScrollBGMapPalettes
ld a, [wBGMapAnchor]
ld e, a
and %11100000
ld b, a
ld a, e
add SCREEN_HEIGHT
and %00011111
or b
ld e, a
ld a, [wBGMapAnchor + 1]
ld d, a
call UpdateBGMapColumn
ld a, $1
ldh [hBGMapUpdate], a
ret
BackupBGMapRow::
ld c, 2 * SCREEN_WIDTH
.loop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .loop
ret
BackupBGMapColumn::
ld c, SCREEN_HEIGHT
.loop
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
inc de
ld a, SCREEN_WIDTH - 1
add l
ld l, a
jr nc, .skip
inc h
.skip
dec c
jr nz, .loop
ret
UpdateBGMapRow::
ld hl, wBGMapBufferPointers
push de
call .iteration
pop de
ld a, BG_MAP_WIDTH
add e
ld e, a
.iteration
ld c, 10
.loop
ld a, e
ld [hli], a
ld a, d
ld [hli], a
ld a, e
inc a
inc a
and $1f
ld b, a
ld a, e
and $e0
or b
ld e, a
dec c
jr nz, .loop
ld a, SCREEN_WIDTH
ldh [hBGMapTileCount], a
ret
UpdateBGMapColumn::
ld hl, wBGMapBufferPointers
ld c, SCREEN_HEIGHT
.loop
ld a, e
ld [hli], a
ld a, d
ld [hli], a
ld a, BG_MAP_WIDTH
add e
ld e, a
jr nc, .skip
inc d
; cap d at HIGH(vBGMap0)
ld a, d
and %11
or HIGH(vBGMap0)
ld d, a
.skip
dec c
jr nz, .loop
ld a, SCREEN_HEIGHT
ldh [hBGMapTileCount], a
ret
LoadTilesetGFX::
ld hl, wTilesetAddress
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [wTilesetBank]
ld e, a
ld a, [wTilesetVariableSpaces]
ldh [hTilesetVariableSpaces], a
ldh a, [rSVBK]
push af
ld a, BANK(wDecompressScratch)
ldh [rSVBK], a
ld a, e
ld de, wDecompressScratch
call FarDecompress
ld hl, wDecompressScratch
ld de, vTiles2
ld bc, $7f tiles
call CopyBytes
ldh a, [rVBK]
push af
ld a, BANK(vTiles5)
ldh [rVBK], a
ld hl, wDecompressScratch + $80 tiles
ld de, vTiles5
ld bc, $80 tiles - (TILESET_FIXED_SPACES_NUM_TILES + TILESET_VARIABLE_SPACES_NUM_TILES) tiles
call CopyBytes
ldh a, [hROMBank]
push af
ld a, BANK(TilesetFixedSpaces) ; BANK(TilesetVariableSpaces*)
ldh [hROMBank], a
ld [MBC5RomBankLo], a
ld hl, TilesetFixedSpaces
ld de, wDecompressScratch
call Decompress
ld hl, wDecompressScratch
ld de, vTiles5 + $80 tiles - (TILESET_FIXED_SPACES_NUM_TILES + TILESET_VARIABLE_SPACES_NUM_TILES) tiles
ld bc, TILESET_FIXED_SPACES_NUM_TILES tiles
call CopyBytes
ld hl, TilesetVariableSpacesPointers
ldh a, [hTilesetVariableSpaces]
ld c, a
ld b, $0
add hl, bc
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
ld de, wDecompressScratch
call Decompress
ld hl, wDecompressScratch
ld de, vTiles5 + $80 tiles - TILESET_VARIABLE_SPACES_NUM_TILES tiles
ld bc, TILESET_VARIABLE_SPACES_NUM_TILES tiles
call CopyBytes
pop af
ldh [hROMBank], a
ld [MBC5RomBankLo], a
pop af
ldh [rVBK], a
pop af
ldh [rSVBK], a
; These tilesets support dynamic per-mapgroup roof tiles.
ld a, [wMapTileset]
cp TILESET_JOHTO
jr z, .load_roof
cp TILESET_JOHTO_MODERN
jr z, .load_roof
cp TILESET_BATTLE_TOWER_OUTSIDE
jr z, .load_roof
jr .skip_roof
.load_roof
farcall LoadMapGroupRoof
.skip_roof
xor a
ldh [hTileAnimFrame], a
ret
BufferScreen::
ld hl, wOverworldMapAnchor
ld a, [hli]
ld h, [hl]
ld l, a
ld de, wScreenSave
ld c, SCREEN_META_HEIGHT
ld b, SCREEN_META_WIDTH
.row
push bc
push hl
.col
ld a, [hli]
ld [de], a
inc de
dec b
jr nz, .col
pop hl
ld a, [wMapWidth]
add 6
ld c, a
ld b, 0
add hl, bc
pop bc
dec c
jr nz, .row
ret
SaveScreen::
ld hl, wOverworldMapAnchor
ld a, [hli]
ld h, [hl]
ld l, a
ld de, wScreenSave
ld a, [wMapWidth]
add 6
ldh [hMapObjectIndex], a
ld a, [wPlayerStepDirection]
and a
jr z, .down
cp UP
jr z, .up
cp LEFT
jr z, .left
cp RIGHT
jr z, .right
ret
.up
ld de, wScreenSave + SCREEN_META_WIDTH
ldh a, [hMapObjectIndex]
ld c, a
ld b, 0
add hl, bc
jr .vertical
.down
ld de, wScreenSave
.vertical
ld b, SCREEN_META_WIDTH
ld c, SCREEN_META_HEIGHT - 1
jr SaveScreen_LoadConnection
.left
ld de, wScreenSave + 1
inc hl
jr .horizontal
.right
ld de, wScreenSave
.horizontal
ld b, SCREEN_META_WIDTH - 1
ld c, SCREEN_META_HEIGHT
jr SaveScreen_LoadConnection
LoadConnectionBlockData::
ld hl, wOverworldMapAnchor
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [wMapWidth]
add 6
ldh [hConnectionStripLength], a
ld de, wScreenSave
ld b, SCREEN_META_WIDTH
ld c, SCREEN_META_HEIGHT
SaveScreen_LoadConnection::
.row
push bc
push hl
push de
.col
ld a, [de]
inc de
ld [hli], a
dec b
jr nz, .col
pop de
ld a, e
add 6
ld e, a
jr nc, .okay
inc d
.okay
pop hl
ldh a, [hConnectionStripLength]
ld c, a
ld b, 0
add hl, bc
pop bc
dec c
jr nz, .row
ret
GetMovementPermissions::
; permissions are ignored in View Map mode
; collisions are handled differently in View Map mode
ldh a, [hCurBoardEvent]
cp BOARDEVENT_VIEW_MAP_MODE
ret z
xor a
ld [wTilePermissions], a
call .LeftRight
call .UpDown
; get coords of current tile
ld a, [wPlayerMapX]
ld d, a
ld a, [wPlayerMapY]
ld e, a
call GetCoordTile
ld [wPlayerTile], a
call .CheckHiNybble
ret nz
ld a, [wPlayerTile]
and 7
ld hl, .MovementPermissionsData
add l
ld l, a
ld a, 0
adc h
ld h, a
ld a, [hl]
ld hl, wTilePermissions
or [hl]
ld [hl], a
ret
.MovementPermissionsData:
db DOWN_MASK
db UP_MASK
db LEFT_MASK
db RIGHT_MASK
db DOWN_MASK | RIGHT_MASK
db UP_MASK | RIGHT_MASK
db DOWN_MASK | LEFT_MASK
db UP_MASK | LEFT_MASK
.UpDown:
ld a, [wPlayerMapX]
ld d, a
ld a, [wPlayerMapY]
ld e, a
push de
inc e
call GetCoordTile
ld [wTileDown], a
call .Down
pop de
dec e
call GetCoordTile
ld [wTileUp], a
call .Up
ret
.LeftRight:
ld a, [wPlayerMapX]
ld d, a
ld a, [wPlayerMapY]
ld e, a
push de
dec d
call GetCoordTile
ld [wTileLeft], a
call .Left
pop de
inc d
call GetCoordTile
ld [wTileRight], a
call .Right
ret
.Down:
call .CheckHiNybble
ret nz
ld a, [wTileDown]
and %111
cp COLL_UP_WALL & %111 ; COLL_UP_BUOY & %111
jr z, .ok_down
cp COLL_UP_RIGHT_WALL & %111 ; COLL_UP_RIGHT_BUOY & %111
jr z, .ok_down
cp COLL_UP_LEFT_WALL & %111 ; COLL_UP_LEFT_BUOY & %111
ret nz
.ok_down
ld a, [wTilePermissions]
or FACE_DOWN
ld [wTilePermissions], a
ret
.Up:
call .CheckHiNybble
ret nz
ld a, [wTileUp]
and %111
cp COLL_DOWN_WALL & %111 ; COLL_DOWN_BUOY & %111
jr z, .ok_up
cp COLL_DOWN_RIGHT_WALL & %111 ; COLL_DOWN_RIGHT_BUOY & %111
jr z, .ok_up
cp COLL_DOWN_LEFT_WALL & %111 ; COLL_DOWN_LEFT_BUOY & %111
ret nz
.ok_up
ld a, [wTilePermissions]
or FACE_UP
ld [wTilePermissions], a
ret
.Right:
call .CheckHiNybble
ret nz
ld a, [wTileRight]
and %111
cp COLL_LEFT_WALL & %111 ; COLL_LEFT_BUOY & %111
jr z, .ok_right
cp COLL_DOWN_LEFT_WALL & %111 ; COLL_DOWN_LEFT_BUOY & %111
jr z, .ok_right
cp COLL_UP_LEFT_WALL & %111 ; COLL_UP_LEFT_BUOY & %111
ret nz
.ok_right
ld a, [wTilePermissions]
or FACE_RIGHT
ld [wTilePermissions], a
ret
.Left:
call .CheckHiNybble
ret nz
ld a, [wTileLeft]
and %111
cp COLL_RIGHT_WALL & %111 ; COLL_RIGHT_BUOY & %111
jr z, .ok_left
cp COLL_DOWN_RIGHT_WALL & %111 ; COLL_DOWN_RIGHT_BUOY & %111
jr z, .ok_left
cp COLL_UP_RIGHT_WALL & %111 ; COLL_UP_RIGHT_BUOY & %111
ret nz
.ok_left
ld a, [wTilePermissions]
or FACE_LEFT
ld [wTilePermissions], a
ret
.CheckHiNybble:
and $f0
cp HI_NYBBLE_SIDE_WALLS
ret z
cp HI_NYBBLE_SIDE_BUOYS
ret
GetFacingTileCoord::
; Return map coordinates in (d, e) and tile id in a
; of the tile the player is facing.
ld a, [wPlayerDirection]
and %1100
srl a
srl a
ld l, a
ld h, 0
add hl, hl
add hl, hl
ld de, .Directions
add hl, de
ld d, [hl]
inc hl
ld e, [hl]
inc hl
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [wPlayerMapX]
add d
ld d, a
ld a, [wPlayerMapY]
add e
ld e, a
ld a, [hl]
ret
.Directions:
; x, y
db 0, 1
dw wTileDown
db 0, -1
dw wTileUp
db -1, 0
dw wTileLeft
db 1, 0
dw wTileRight
GetCoordTile::
; Get the collision byte for tile d, e
call GetBlockLocation
ld a, [hl]
and a
jr z, .nope
ld l, a
ld h, 0
add hl, hl
add hl, hl
ld a, [wTilesetCollisionAddress]
ld c, a
ld a, [wTilesetCollisionAddress + 1]
ld b, a
add hl, bc
rr d
jr nc, .nocarry
inc hl
.nocarry
rr e
jr nc, .nocarry2
inc hl
inc hl
.nocarry2
ld a, [wTilesetCollisionBank]
call GetFarByte
ret
.nope
ld a, COLL_OUT_OF_BOUNDS
ret
GetBlockLocation::
ld a, [wMapWidth]
add 6
ld c, a
ld b, 0
ld hl, wOverworldMapBlocks + 1
add hl, bc
ld a, e
srl a
jr z, .nope
and a
.loop
srl a
jr nc, .ok
add hl, bc
.ok
sla c
rl b
and a
jr nz, .loop
.nope
ld c, d
srl c
ld b, 0
add hl, bc
ret
CheckAndApplyAnchorPoint::
; c = [wCurMapAnchorEventCount] (non-0)
; d = [wXCoord]
; e = [wYCoord]
; hl = [wCurMapAnchorEventsPointer]
; if currently at coords of any anchor point, copy its next space byte to wCurSpaceNextSpace.
; return nc if anchor point matched, carry otherwise.
ldh a, [hROMBank]
push af
call SwitchToMapScriptsBank
.loop
ld a, [hli]
cp d ; x
jr nz, .next1
ld a, [hli]
cp e ; y
jr nz, .next2
; found anchor point in current player coords
ld a, [hl]
ld [wCurSpaceNextSpace], a
pop af
rst Bankswitch
xor a
ret
.next1
inc hl
.next2
inc hl
dec c
jr nz, .loop
pop af
rst Bankswitch
scf
ret
CheckFacingBGEvent::
call GetFacingTileCoord
; Load facing into b.
ld b, a
; Convert the coordinates at de to within-boundaries coordinates.
ld a, d
sub 4
ld d, a
ld a, e
sub 4
ld e, a
; If there are no BG events, we don't need to be here.
ld a, [wCurMapBGEventCount]
and a
ret z
ld c, a
ldh a, [hROMBank]
push af
call SwitchToMapScriptsBank
call CheckIfFacingTileCoordIsBGEvent
pop hl
ld a, h
rst Bankswitch
ret
CheckIfFacingTileCoordIsBGEvent::
; Checks to see if you are facing a BG event. If so, copies it into wCurBGEvent and sets carry.
ld hl, wCurMapBGEventsPointer
ld a, [hli]
ld h, [hl]
ld l, a
.loop
push hl
ld a, [hli]
cp e
jr nz, .next
ld a, [hli]
cp d
jr nz, .next
jr .copysign
.next
pop hl
ld a, BG_EVENT_SIZE
add l
ld l, a
jr nc, .nocarry
inc h
.nocarry
dec c
jr nz, .loop
xor a
ret
.copysign
pop hl
ld de, wCurBGEvent
ld bc, BG_EVENT_SIZE
call CopyBytes
scf
ret
CheckCurrentMapCoordEvents::
; If there are no coord events, we don't need to be here.
ld a, [wCurMapCoordEventCount]
and a
ret z
; Copy the coord event count into c.
ld c, a
ldh a, [hROMBank]
push af
call SwitchToMapScriptsBank
call .CoordEventCheck
pop hl
ld a, h
rst Bankswitch
ret
.CoordEventCheck:
; Checks to see if you are standing on a coord event. If yes, copies the event to wCurCoordEvent and sets carry.
ld hl, wCurMapCoordEventsPointer
ld a, [hli]
ld h, [hl]
ld l, a
; Load the active scene ID into b
call CheckScenes
ld b, a
; Load your current coordinates into de. This will be used to check if your position is in the coord event table for the current map.
ld a, [wPlayerMapX]
sub 4
ld d, a
ld a, [wPlayerMapY]
sub 4
ld e, a
.loop
push hl
ld a, [hli]
cp b
jr z, .got_id
cp -1
jr nz, .next
.got_id
ld a, [hli]
cp e
jr nz, .next
ld a, [hli]
cp d
jr nz, .next
jr .copy_coord_event
.next
pop hl
ld a, COORD_EVENT_SIZE
add l
ld l, a
jr nc, .nocarry
inc h
.nocarry
dec c
jr nz, .loop
xor a
ret
.copy_coord_event
pop hl
ld de, wCurCoordEvent
ld bc, COORD_EVENT_SIZE
call CopyBytes
scf
ret
FadeToMenu::
xor a
ldh [hBGMapMode], a
call LoadStandardMenuHeader
farcall FadeOutPalettesToWhite
call ClearSprites
call DisableSpriteUpdates
ret
CloseSubmenu::
call ClearBGPalettes
call ReloadTilesetAndPalettes
call UpdateSprites
call Call_ExitMenu
jr FinishExitMenu
ExitAllMenus::
call ClearBGPalettes
call Call_ExitMenu
call ReloadTilesetAndPalettes
call UpdateSprites
FinishExitMenu::
ld b, CGB_MAPPALS
call GetCGBLayout
call WaitBGMap2
farcall FadeInPalettesFromWhite
call EnableSpriteUpdates
ret
ReturnToMapWithSpeechTextbox::
push af
ld a, $1
ld [wSpriteUpdatesEnabled], a
call ClearBGPalettes
call ClearSprites
call ReloadTilesetAndPalettes
call SpeechTextbox ; 1bpp or 2bpp according to wTextboxFlags[TEXT_2BPP_F]
ld hl, wVramState
set 0, [hl]
call UpdateSprites
call WaitBGMap2
ld b, CGB_MAPPALS
call GetCGBLayout
call UpdateTimePals
call DelayFrame
ld a, $1
ldh [hMapAnims], a
pop af
ret
ReloadTilesetAndPalettes::
call DisableLCD
call ClearSprites
farcall RefreshSprites
ld a, [wText2bpp]
and a
jr nz, .2bpp
call LoadStandardFont
call LoadFrame
jr .font_done
.2bpp
call LoadOverworldFontAndFrame
.font_done
ldh a, [hROMBank]
push af
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
call SwitchToAnyMapAttributesBank
farcall UpdateTimeOfDayPal
call LoadScreenTilemapAndAttrmapPals
call LoadTilesetGFX
ld a, 9
call SkipMusic
pop af
rst Bankswitch
call EnableLCD
ret
GetMapPointer::
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
GetAnyMapPointer::
; Prior to calling this function, you must have switched banks so that
; MapGroupPointers is visible.
; inputs:
; b = map group, c = map number
; outputs:
; hl points to the map within its group
push bc ; save map number for later
; get pointer to map group
dec b
ld c, b
ld b, 0
ld hl, MapGroupPointers
add hl, bc
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
pop bc ; restore map number
; find the cth map within the group
dec c
ld b, 0
ld a, MAP_LENGTH
call AddNTimes
ret
GetMapField::
; Extract data from the current map's group entry.
; inputs:
; de = offset of desired data within the map (a MAP_* constant)
; outputs:
; bc = data from the current map's field
; (e.g., de = MAP_TILESET would return a pointer to the tileset id)
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
GetAnyMapField::
; bankswitch
ldh a, [hROMBank]
push af
ld a, BANK(MapGroupPointers)
rst Bankswitch
call GetAnyMapPointer
add hl, de
ld c, [hl]
inc hl
ld b, [hl]
; bankswitch back
pop af
rst Bankswitch
ret
SwitchToMapAttributesBank::
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
SwitchToAnyMapAttributesBank::
call GetAnyMapAttributesBank
rst Bankswitch
ret
GetAnyMapAttributesBank::
push hl
push de
ld de, MAP_MAPATTRIBUTES_BANK
call GetAnyMapField
ld a, c
pop de
pop hl
ret
CopyMapPartial::
; Copy map data bank, tileset, environment, and map data address
; from the current map's entry within its group.
ldh a, [hROMBank]
push af
ld a, BANK(MapGroupPointers)
rst Bankswitch
call GetMapPointer
ld de, wMapPartial
ld bc, wMapPartialEnd - wMapPartial
call CopyBytes
pop af
rst Bankswitch
ret
SwitchToMapScriptsBank::
ld a, [wMapScriptsBank]
rst Bankswitch
ret
GetMapScriptsBank::
ld a, [wMapScriptsBank]
ret
GetAnyMapBlocksBank::
; Return the blockdata bank for group b map c.
push hl
push de
push bc
push bc
ld de, MAP_MAPATTRIBUTES
call GetAnyMapField
ld l, c
ld h, b
pop bc
push hl
ld de, MAP_MAPATTRIBUTES_BANK
call GetAnyMapField
pop hl
ld de, MAP_MAPATTRIBUTES ; blockdata bank
add hl, de
ld a, c
call GetFarByte
rst Bankswitch
pop bc
pop de
pop hl
ret
GetMapAttributesPointer::
; returns the current map's data pointer in hl.
push bc
push de
ld de, MAP_MAPATTRIBUTES
call GetMapField
ld l, c
ld h, b
pop de
pop bc
ret
GetMapEnvironment::
push hl
push de
push bc
ld de, MAP_ENVIRONMENT
call GetMapField
ld a, c
pop bc
pop de
pop hl
ret
GetAnyMapEnvironment::
push hl
push de
push bc
ld de, MAP_ENVIRONMENT
call GetAnyMapField
ld a, c
pop bc
pop de
pop hl
ret
GetAnyMapTileset::
ld de, MAP_TILESET
call GetAnyMapField
ld a, c
ret
GetWorldMapLocation::
; given a map group/id in bc, return its location on the Pokégear map.
push hl
push de
push bc
ld de, MAP_LOCATION
call GetAnyMapField
ld a, c
pop bc
pop de
pop hl
ret
GetMapMusic::
push hl
push bc
ld de, MAP_MUSIC
call GetMapField
ld a, c
cp MUSIC_MAHOGANY_MART
jr z, .mahoganymart
bit RADIO_TOWER_MUSIC_F, c
jr nz, .radiotower
ld e, c
ld d, 0
.done
pop bc
pop hl
ret
.radiotower
ld a, [wStatusFlags2]
bit STATUSFLAGS2_ROCKETS_IN_RADIO_TOWER_F, a
jr z, .clearedradiotower
ld de, MUSIC_ROCKET_OVERTURE
jr .done
.clearedradiotower
; the rest of the byte
ld a, c
and RADIO_TOWER_MUSIC - 1
ld e, a
ld d, 0
jr .done
.mahoganymart
ld a, [wStatusFlags2]
bit STATUSFLAGS2_ROCKETS_IN_MAHOGANY_F, a
jr z, .clearedmahogany
ld de, MUSIC_ROCKET_HIDEOUT
jr .done
.clearedmahogany
ld de, MUSIC_CHERRYGROVE_CITY
jr .done
GetMapTimeOfDay::
call GetPhoneServiceTimeOfDayByte
and $f
ret
GetMapPhoneService::
call GetPhoneServiceTimeOfDayByte
and $f0
swap a
ret
GetPhoneServiceTimeOfDayByte::
push hl
push bc
ld de, MAP_PALETTE
call GetMapField
ld a, c
pop bc
pop hl
ret
GetFishingGroup::
push de
push hl
push bc
ld de, MAP_FISHGROUP
call GetMapField
ld a, c
pop bc
pop hl
pop de
ret
LoadMapTileset::
push hl
push bc
ld hl, Tilesets
ld bc, TILESET_LENGTH
ld a, [wMapTileset]
call AddNTimes
ld de, wTileset
ld bc, TILESET_LENGTH
ld a, BANK(Tilesets)
call FarCopyBytes
pop bc
pop hl
ret
; a: which space to load
LoadTempSpaceData::
ld de, wTempSpaceStruct
jr LoadSpaceData
LoadCurSpaceData::
ld de, wCurSpaceStruct
ld a, [wCurSpace]
; fallthrough
; de: location where to load
; a: which space to load
LoadSpaceData::
push de
push af
ld hl, wMapSpacesPointer
ld a, [hli]
ld h, [hl]
ld l, a
ld bc, wCurSpaceStructEnd - wCurSpaceStruct ; wTempSpaceStructEnd - wTempSpaceStruct
pop af
call AddNTimes
pop de
ld a, [wMapScriptsBank]
jp FarCopyBytes
; load the branch data of the space at wCurSpaceStruct to wTempSpaceBranchStruct
LoadTempSpaceBranchData::
ld hl, wCurSpaceBranchStructPtr
ld a, [hli]
ld h, [hl]
ld l, a
ld de, wTempSpaceBranchStruct
ld bc, wTempSpaceBranchStructEnd - wTempSpaceBranchStruct
ld a, [wMapScriptsBank]
jp FarCopyBytes