diff options
| author | U-Fish-PC\Daniel <corrnondacqb@yahoo.com> | 2014-05-22 18:13:20 -0400 | 
|---|---|---|
| committer | U-Fish-PC\Daniel <corrnondacqb@yahoo.com> | 2014-05-22 18:13:20 -0400 | 
| commit | 15427f532085846ab6b51719be687951a094cb6c (patch) | |
| tree | edea9b189e91641a12dd521756894df84aeeace7 /engine/overworld | |
| parent | ea3ba4cde3706b7c77efb705555ec0c86321cbe2 (diff) | |
Pull a lot of engine out of main.asm
Diffstat (limited to 'engine/overworld')
| -rwxr-xr-x | engine/overworld/cable_club_npc.asm | 156 | ||||
| -rwxr-xr-x | engine/overworld/card_key.asm | 108 | ||||
| -rwxr-xr-x | engine/overworld/cinnabar_lab.asm | 125 | ||||
| -rwxr-xr-x | engine/overworld/cut.asm | 258 | ||||
| -rwxr-xr-x | engine/overworld/cut2.asm | 89 | ||||
| -rwxr-xr-x | engine/overworld/doors.asm | 88 | ||||
| -rwxr-xr-x | engine/overworld/elevator.asm | 69 | ||||
| -rwxr-xr-x | engine/overworld/emotion_bubbles.asm | 68 | ||||
| -rwxr-xr-x | engine/overworld/healing_machine.asm | 102 | ||||
| -rwxr-xr-x | engine/overworld/hidden_items.asm | 168 | ||||
| -rwxr-xr-x | engine/overworld/hidden_objects.asm | 129 | ||||
| -rwxr-xr-x | engine/overworld/ledges.asm | 87 | ||||
| -rwxr-xr-x | engine/overworld/map_sprites.asm | 440 | ||||
| -rwxr-xr-x | engine/overworld/npc_movement.asm | 291 | ||||
| -rwxr-xr-x | engine/overworld/oaks_aide.asm | 71 | ||||
| -rwxr-xr-x | engine/overworld/pewter_guys.asm | 101 | ||||
| -rwxr-xr-x | engine/overworld/player_animations.asm | 520 | ||||
| -rwxr-xr-x | engine/overworld/pokecenter.asm | 68 | ||||
| -rwxr-xr-x | engine/overworld/pokemart.asm | 256 | ||||
| -rwxr-xr-x | engine/overworld/saffron_guards.asm | 18 | ||||
| -rwxr-xr-x | engine/overworld/ssanne.asm | 88 | ||||
| -rwxr-xr-x | engine/overworld/trainers.asm | 347 | 
22 files changed, 3647 insertions, 0 deletions
| diff --git a/engine/overworld/cable_club_npc.asm b/engine/overworld/cable_club_npc.asm new file mode 100755 index 00000000..88bf177f --- /dev/null +++ b/engine/overworld/cable_club_npc.asm @@ -0,0 +1,156 @@ +CableClubNPC: ; 71c5 (1:71c5) +	ld hl, CableClubNPCText1 +	call PrintText +	ld a, [$d74b] +	bit 5, a +	jp nz, Func_71e1 +	ld c, $3c +	call DelayFrames +	ld hl, CableClubNPCText6 +	call PrintText +	jp Func_7298 + +Func_71e1: ; 71e1 (1:71e1) +	ld a, $1 +	ld [$cc34], a +	ld a, $5a +	ld [$cc47], a +.asm_71eb +	ld a, [$ffaa] +	cp $2 +	jr z, .asm_721a ; 0x71ef $29 +	cp $1 +	jr z, .asm_721a ; 0x71f3 $25 +	ld a, $ff +	ld [$ffaa], a +	ld a, $2 +	ld [$ff01], a +	xor a +	ld [$ffad], a +	ld a, $80 +	ld [$ff02], a +	ld a, [$cc47] +	dec a +	ld [$cc47], a +	jr z, .asm_7287 ; 0x720b $7a +	ld a, $1 +	ld [$ff01], a +	ld a, $81 +	ld [$ff02], a +	call DelayFrame +	jr .asm_71eb ; 0x7218 $d1 +.asm_721a +	call Func_22ed +	call DelayFrame +	call Func_22ed +	ld c, $32 +	call DelayFrames +	ld hl, CableClubNPCText2 +	call PrintText +	xor a +	ld [$cc34], a +	call YesNoChoice +	ld a, $1 +	ld [$cc34], a +	ld a, [$cc26] +	and a +	jr nz, .asm_728f ; 0x723e $4f +	callab SaveSAVtoSRAM +	call WaitForSoundToFinish +	ld a, (SFX_02_5d - SFX_Headers_02) / 3 +	call PlaySoundWaitForCurrent +	ld hl, CableClubNPCText3 +	call PrintText +	ld hl, $cc47 +	ld a, $3 +	ld [hli], a +	xor a +	ld [hl], a +	ld [$ffa9], a +	ld [$cc42], a +	call Func_227f +	ld hl, $cc47 +	ld a, [hli] +	inc a +	jr nz, Func_72a8 ; 0x726b $3b +	ld a, [hl] +	inc a +	jr nz, Func_72a8 ; 0x726f $37 +	ld b, $a +.asm_7273 +	call DelayFrame +	call Func_22ed +	dec b +	jr nz, .asm_7273 ; 0x727a $f7 +	call Func_72d7 +	ld hl, CableClubNPCText4 +	call PrintText +	jr Func_7298 ; 0x7285 $11 +.asm_7287 +	ld hl, CableClubNPCText7 +	call PrintText +	jr Func_7298 ; 0x728d $9 +.asm_728f +	call Func_72d7 +	ld hl, CableClubNPCText5 +	call PrintText +	; fall through + +Func_7298: ; 7298 (1:7298) +	xor a +	ld hl, $cc47 +	ld [hli], a +	ld [hl], a +	ld hl, $d72e +	res 6, [hl] +	xor a +	ld [$cc34], a +	ret + +Func_72a8: ; 72a8 (1:72a8) +	xor a +	ld [hld], a +	ld [hl], a +	ld hl, LinkMenu +	ld b, BANK(LinkMenu) +	jp Bankswitch + +CableClubNPCText7: ; 72b3 (1:72b3) +	TX_FAR _CableClubNPCText7 +	db "@" + +CableClubNPCText1: ; 72b8 (1:72b8) +	TX_FAR _CableClubNPCText1 +	db "@" + +CableClubNPCText2: ; 72bd (1:72bd) +	TX_FAR _CableClubNPCText2 +	db "@" + +CableClubNPCText3: ; 72c2 (1:72c2) +	TX_FAR _CableClubNPCText3 +	db $a, "@" + +CableClubNPCText4: ; 72c8 (1:72c8) +	TX_FAR _CableClubNPCText4 +	db "@" + +CableClubNPCText5: ; 72cd (1:72cd) +	TX_FAR _CableClubNPCText5 +	db "@" + +CableClubNPCText6: ; 72d2 (1:72d2) +	TX_FAR _CableClubNPCText6 +	db "@" + +Func_72d7: ; 72d7 (1:72d7) +	call Delay3 +	ld a, $ff +	ld [$ffaa], a +	ld a, $2 +	ld [$ff01], a +	xor a +	ld [$ffad], a +	ld a, $80 +	ld [$ff02], a +	ret diff --git a/engine/overworld/card_key.asm b/engine/overworld/card_key.asm new file mode 100755 index 00000000..658f4712 --- /dev/null +++ b/engine/overworld/card_key.asm @@ -0,0 +1,108 @@ +PrintCardKeyText: ; 52673 (14:6673) +	ld hl, SilphCoMapList +	ld a, [W_CURMAP] +	ld b, a +.asm_5267a +	ld a, [hli] +	cp $ff +	ret z +	cp b +	jr nz, .asm_5267a +	ld a, $35 +	call Predef ; indirect jump to Func_c586 (c586 (3:4586)) +	ld a, [$cfc6] +	cp $18 +	jr z, .asm_5269c +	cp $24 +	jr z, .asm_5269c +	ld b, a +	ld a, [W_CURMAP] +	cp SILPH_CO_11F +	ret nz +	ld a, b +	cp $5e +	ret nz +.asm_5269c +	ld b, CARD_KEY +	call IsItemInBag +	jr z, .asm_526dc +	call Func_526fd +	push de +	ld a, $1 +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	call PrintPredefTextID +	pop de +	srl d +	ld a, d +	ld b, a +	ld [$d73f], a +	srl e +	ld a, e +	ld c, a +	ld [$d740], a +	ld a, [W_CURMAP] ; $d35e +	cp SILPH_CO_11F +	jr nz, .asm_526c8 +	ld a, $3 +	jr .asm_526ca +.asm_526c8 +	ld a, $e +.asm_526ca +	ld [$d09f], a +	ld a, $17 +	call Predef ; indirect jump to Func_ee9e +	ld hl, $d126 +	set 5, [hl] +	ld a, (SFX_1f_57 - SFX_Headers_1f) / 3 +	jp PlaySound +.asm_526dc +	ld a, $2 +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	jp PrintPredefTextID + +SilphCoMapList: ; 526e3 (14:66e3) +	db SILPH_CO_2F +	db SILPH_CO_3F +	db SILPH_CO_4F +	db SILPH_CO_5F +	db SILPH_CO_6F +	db SILPH_CO_7F +	db SILPH_CO_8F +	db SILPH_CO_9F +	db SILPH_CO_10F +	db SILPH_CO_11F +	db $FF + +CardKeySuccessText: ; 526ee (14:66ee) +	TX_FAR _CardKeySuccessText1 +	db $0b +	TX_FAR _CardKeySuccessText2 +	db "@" + +CardKeyFailText: ; 526f8 (14:66f8) +	TX_FAR _CardKeyFailText +	db "@" + +Func_526fd: ; 526fd (14:66fd) +	ld a, [W_YCOORD] ; $d361 +	ld d, a +	ld a, [W_XCOORD] ; $d362 +	ld e, a +	ld a, [$c109] +	and a +	jr nz, .asm_5270d +	inc d +	ret +.asm_5270d +	cp $4 +	jr nz, .asm_52713 +	dec d +	ret +.asm_52713 +	cp $8 +	jr nz, .asm_52719 +	dec e +	ret +.asm_52719 +	inc e +	ret diff --git a/engine/overworld/cinnabar_lab.asm b/engine/overworld/cinnabar_lab.asm new file mode 100755 index 00000000..4087b334 --- /dev/null +++ b/engine/overworld/cinnabar_lab.asm @@ -0,0 +1,125 @@ +GiveFossilToCinnabarLab: ; 61006 (18:5006) +	ld hl, $d730 +	set 6, [hl] +	xor a +	ld [wCurrentMenuItem], a ; $cc26 +	ld a, $3 +	ld [wMenuWatchedKeys], a ; $cc29 +	ld a, [$cd37] +	dec a +	ld [wMaxMenuItem], a ; $cc28 +	ld a, $2 +	ld [wTopMenuItemY], a ; $cc24 +	ld a, $1 +	ld [wTopMenuItemX], a ; $cc25 +	ld a, [$cd37] +	dec a +	ld bc, $2 +	ld hl, $3 +	call AddNTimes +	dec l +	ld b, l +	ld c, $d +	ld hl, wTileMap +	call TextBoxBorder +	call UpdateSprites +	call Func_610c2 +	ld hl, $d730 +	res 6, [hl] +	call HandleMenuInput +	bit 1, a +	jr nz, .asm_610a7 +	ld hl, $cc5b +	ld a, [wCurrentMenuItem] ; $cc26 +	ld d, $0 +	ld e, a +	add hl, de +	ld a, [hl] +	ld [$ffdb], a +	cp DOME_FOSSIL +	jr z, .choseDomeFossil +	cp HELIX_FOSSIL +	jr z, .choseHelixFossil +	ld b, AERODACTYL +	jr .fossilSelected +.choseHelixFossil +	ld b, OMANYTE +	jr .fossilSelected +.choseDomeFossil +	ld b, KABUTO +.fossilSelected +	ld [W_FOSSILITEM], a +	ld a, b +	ld [W_FOSSILMON], a +	call LoadFossilItemAndMonName +	ld hl, LabFossil_610ae +	call PrintText +	call YesNoChoice +	ld a, [wCurrentMenuItem] ; $cc26 +	and a +	jr nz, .asm_610a7 +	ld hl, LabFossil_610b3 +	call PrintText +	ld a, [W_FOSSILITEM] +	ld [$ffdb], a +	callba RemoveItemByID +	ld hl, LabFossil_610b8 +	call PrintText +	ld hl, $d7a3 +	set 0, [hl] +	set 1, [hl] +	ret +.asm_610a7 +	ld hl, LabFossil_610bd +	call PrintText +	ret + +LabFossil_610ae: ; 610ae (18:50ae) +	TX_FAR _Lab4Text_610ae +	db "@" + +LabFossil_610b3: ; 610b3 (18:50b3) +	TX_FAR _Lab4Text_610b3 +	db "@" + +LabFossil_610b8: ; 610b8 (18:50b8) +	TX_FAR _Lab4Text_610b8 +	db "@" + +LabFossil_610bd: ; 610bd (18:50bd) +	TX_FAR _Lab4Text_610bd +	db "@" + +Func_610c2: ; 610c2 (18:50c2) +	ld hl, $cc5b +	xor a +	ld [$ffdb], a +.asm_610c8 +	ld a, [hli] +	cp $ff +	ret z +	push hl +	ld [$d11e], a +	call GetItemName +	FuncCoord 2, 2 ; $c3ca +	ld hl, Coord +	ld a, [$ffdb] +	ld bc, $28 +	call AddNTimes +	ld de, $cd6d +	call PlaceString +	ld hl, $ffdb +	inc [hl] +	pop hl +	jr .asm_610c8 + +; loads the names of the fossil item and the resulting mon +LoadFossilItemAndMonName: ; 610eb (18:50eb) +	ld a, [W_FOSSILMON] +	ld [$d11e], a +	call GetMonName +	call CopyStringToCF4B +	ld a, [W_FOSSILITEM] +	ld [$d11e], a +	call GetItemName +	ret diff --git a/engine/overworld/cut.asm b/engine/overworld/cut.asm new file mode 100755 index 00000000..6c888e7f --- /dev/null +++ b/engine/overworld/cut.asm @@ -0,0 +1,258 @@ +UsedCut: ; ef54 (3:6f54) +	xor a +	ld [$cd6a], a +	ld a, [W_CURMAPTILESET] ; $d367 +	and a ; OVERWORLD +	jr z, .asm_ef6b +	cp GYM +	jr nz, .asm_ef77 +	ld a, [$cfc6] +	cp $50 ; gym cut tree +	jr nz, .asm_ef77 +	jr asm_ef82 +.asm_ef6b +	dec a +	ld a, [$cfc6] +	cp $3d ; cut tree +	jr z, asm_ef82 +	cp $52 ; grass +	jr z, asm_ef82 +.asm_ef77 +	ld hl, NothingToCutText +	jp PrintText + +NothingToCutText: ; ef7d (3:6f7d) +	TX_FAR _NothingToCutText +	db "@" + +asm_ef82: ; ef82 (3:6f82) +	ld [$cd4d], a +	ld a, $1 +	ld [$cd6a], a +	ld a, [wWhichPokemon] ; $cf92 +	ld hl, W_PARTYMON1NAME ; $d2b5 +	call GetPartyMonName +	ld hl, $d730 +	set 6, [hl] +	call GBPalWhiteOutWithDelay3 +	call CleanLCD_OAM +	call Func_3dbe +	ld a, $90 +	ld [$ffb0], a +	call Delay3 +	call LoadGBPal +	call LoadCurrentMapView +	call SaveScreenTilesToBuffer2 +	call Delay3 +	xor a +	ld [$ffb0], a +	ld hl, UsedCutText +	call PrintText +	call LoadScreenTilesFromBuffer2 +	ld hl, $d730 +	res 6, [hl] +	ld a, $ff +	ld [$cfcb], a +	call AnimateCutTree +	ld de, CutTreeBlockSwaps ; $7100 +	call Func_f09f +	call Func_eedc +	callba Func_79e96 +	ld a, $1 +	ld [$cfcb], a +	ld a, (SFX_02_56 - SFX_Headers_02) / 3 +	call PlaySound +	ld a, $90 +	ld [$ffb0], a +	call UpdateSprites +	jp Func_eedc + +UsedCutText: ; eff2 (3:6ff2) +	TX_FAR _UsedCutText +	db "@" + +AnimateCutTree: ; eff7 (3:6ff7) +	xor a +	ld [$cd50], a +	ld a, $e4 +	ld [rOBP1], a ; $ff49 +	ld a, [$cd4d] +	cp $52 +	jr z, .asm_f020 +	ld de, Overworld_GFX + $2d0 ; $42d0 ; cuttable tree sprite top row +	ld hl, $8fc0 +	ld bc, (BANK(Overworld_GFX) << 8) + $02 +	call CopyVideoData +	ld de, Overworld_GFX + $3d0 ; $43d0 ; cuttable tree sprite bottom row +	ld hl, $8fe0 +	ld bc, (BANK(Overworld_GFX) << 8) + $02 +	call CopyVideoData +	jr asm_f055 +.asm_f020 +	ld hl, $8fc0 +	call LoadCutTreeOAM +	ld hl, $8fd0 +	call LoadCutTreeOAM +	ld hl, $8fe0 +	call LoadCutTreeOAM +	ld hl, $8ff0 +	call LoadCutTreeOAM +	call asm_f055 +	ld hl, $c393 +	ld de, $4 +	ld a, $30 +	ld c, e +.asm_f044 +	ld [hl], a +	add hl, de +	xor $60 +	dec c +	jr nz, .asm_f044 +	ret + +LoadCutTreeOAM: ; f04c (3:704c) +	ld de, AnimationTileset2 + $60 ; $474e ; tile depicting a leaf +	ld bc, (BANK(AnimationTileset2) << 8) + $01 +	jp CopyVideoData +asm_f055: ; f055 (3:7055) +	call Func_f068 +	ld a, $9 +	ld de, CutTreeOAM ; $7060 +	jp WriteOAMBlock + +CutTreeOAM: ; f060 (3:7060) +	db $FC,$10,$FD,$10 +	db $FE,$10,$FF,$10 + +Func_f068: ; f068 (3:7068) +	ld hl, $c104 +	ld a, [hli] +	ld b, a +	inc hl +	ld a, [hli] +	ld c, a ; bc holds ypos/xpos of player's sprite +	inc hl +	inc hl +	ld a, [hl] ; a holds direction of player (00: down, 04: up, 08: left, 0C: right) +	srl a +	ld e, a +	ld d, $0 ; de holds direction (00: down, 02: up, 04: left, 06: right) +	ld a, [$cd50] +	and a +	ld hl, CutTreeAnimationOffsets ; $708f +	jr z, .asm_f084 +	ld hl, CutTreeAnimationOffsets2 ; $7097 +.asm_f084 +	add hl, de +	ld e, [hl] +	inc hl +	ld d, [hl] +	ld a, b +	add d +	ld b, a +	ld a, c +	add e +	ld c, a +	ret + +CutTreeAnimationOffsets: ; f08f (3:708f) +; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn +	db  8, 36 ; player is facing down +	db  8,  4 ; player is facing up +	db -8, 20 ; player is facing left +	db 24, 20 ; player is facing right + +CutTreeAnimationOffsets2: ; f097 (3:7097) +; Not sure if these ever get used. CutTreeAnimationOffsets only seems to be used. +; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn +; These offsets represent 2 blocks away from the player +	db  8,  52 ; player is facing down +	db  8, -12 ; player is facing up +	db -24, 20 ; player is facing left +	db 40,  20 ; player is facing right + +Func_f09f: ; f09f (3:709f) +	push de +	ld a, [W_CURMAPWIDTH] ; $d369 +	add $6 +	ld c, a +	ld b, $0 +	ld d, $0 +	ld hl, $d35f +	ld a, [hli] +	ld h, [hl] +	ld l, a +	add hl, bc +	ld a, [$c109] +	and a +	jr z, .asm_f0c7 +	cp $4 +	jr z, .asm_f0cf +	cp $8 +	jr z, .asm_f0d7 +	ld a, [W_XBLOCKCOORD] ; $d364 +	and a +	jr z, .asm_f0e0 +	jr .asm_f0ec +.asm_f0c7 +	ld a, [W_YBLOCKCOORD] ; $d363 +	and a +	jr z, .asm_f0e0 +	jr .asm_f0df +.asm_f0cf +	ld a, [W_YBLOCKCOORD] ; $d363 +	and a +	jr z, .asm_f0e1 +	jr .asm_f0e0 +.asm_f0d7 +	ld a, [W_XBLOCKCOORD] ; $d364 +	and a +	jr z, .asm_f0e6 +	jr .asm_f0e0 +.asm_f0df +	add hl, bc +.asm_f0e0 +	add hl, bc +.asm_f0e1 +	ld e, $2 +	add hl, de +	jr .asm_f0f0 +.asm_f0e6 +	ld e, $1 +	add hl, bc +	add hl, de +	jr .asm_f0f0 +.asm_f0ec +	ld e, $3 +	add hl, bc +	add hl, de +.asm_f0f0 +	pop de +	ld a, [hl] +	ld c, a +.asm_f0f3 +	ld a, [de] +	inc de +	inc de +	cp $ff +	ret z +	cp c +	jr nz, .asm_f0f3 +	dec de +	ld a, [de] +	ld [hl], a +	ret + +CutTreeBlockSwaps: ; f100 (3:7100) +; first byte = tileset block containing the cut tree +; second byte = corresponding tileset block after the cut animation happens +	db $32, $6D +	db $33, $6C +	db $34, $6F +	db $35, $4C +	db $60, $6E +	db $0B, $0A +	db $3C, $35 +	db $3F, $35 +	db $3D, $36 +	db $FF ; list terminator diff --git a/engine/overworld/cut2.asm b/engine/overworld/cut2.asm new file mode 100755 index 00000000..c83e571b --- /dev/null +++ b/engine/overworld/cut2.asm @@ -0,0 +1,89 @@ +Func_79e96: ; 79e96 (1e:5e96) +	ld a, [$cd4d] +	cp $52 +	jr z, .asm_79ec8 +	ld c, $8 +.asm_79e9f +	push bc +	ld hl, $c391 +	ld a, $1 +	ld [$d08a], a +	ld c, $2 +	call Func_79339 +	ld hl, $c399 +	ld a, $ff +	ld [$d08a], a +	ld c, $2 +	call Func_79339 +	ld a, [rOBP1] ; $ff49 +	xor $64 +	ld [rOBP1], a ; $ff49 +	call DelayFrame +	pop bc +	dec c +	jr nz, .asm_79e9f +	ret +.asm_79ec8 +	ld c, $2 +.asm_79eca +	push bc +	ld c, $8 +	call Func_79eed +	call Func_79f30 +	ld c, $8 +	call Func_79eed +	call Func_79f30 +	ld hl, $c390 +	ld a, $2 +	ld [$d08a], a +	ld c, $4 +	call Func_79352 +	pop bc +	dec c +	jr nz, .asm_79eca +	ret + +Func_79eed: ; 79eed (1e:5eed) +	push bc +	ld hl, $c391 +	ld a, $1 +	ld [$d08a], a +	ld c, $1 +	call Func_79339 +	ld hl, $c395 +	ld a, $2 +	ld [$d08a], a +	ld c, $1 +	call Func_79339 +	ld hl, $c399 +	ld a, $fe +	ld [$d08a], a +	ld c, $1 +	call Func_79339 +	ld hl, $c39d +	ld a, $ff +	ld [$d08a], a +	ld c, $1 +	call Func_79339 +	ld a, [rOBP1] ; $ff49 +	xor $64 +	ld [rOBP1], a ; $ff49 +	call DelayFrame +	pop bc +	dec c +	jr nz, Func_79eed +	ret + +Func_79f30: ; 79f30 (1e:5f30) +	ld hl, $c390 +	ld de, $cee9 +	ld bc, $8 +	call CopyData +	ld hl, $c398 +	ld de, $c390 +	ld bc, $8 +	call CopyData +	ld hl, $cee9 +	ld de, $c398 +	ld bc, $8 +	jp CopyData diff --git a/engine/overworld/doors.asm b/engine/overworld/doors.asm new file mode 100755 index 00000000..ff58b752 --- /dev/null +++ b/engine/overworld/doors.asm @@ -0,0 +1,88 @@ +HandleDoors: ; 1a609 (6:6609) +	push de +	ld hl, DoorTileIDPointers ; $662c +	ld a, [W_CURMAPTILESET] ; $d367 +	ld de, $3 +	call IsInArray +	pop de +	jr nc, .asm_1a62a +	inc hl +	ld a, [hli] +	ld h, [hl] +	ld l, a +	FuncCoord 8, 9 ; $c45c +	ld a, [Coord] +	ld b, a +.asm_1a621 +	ld a, [hli] +	and a +	jr z, .asm_1a62a +	cp b +	jr nz, .asm_1a621 +	scf +	ret +.asm_1a62a +	and a +	ret + +DoorTileIDPointers: ; 1a62c (6:662c) +	db OVERWORLD +	dw OverworldDoorTileIDs +	db FOREST +	dw ForestDoorTileIDs +	db MART +	dw MartDoorTileIDs +	db HOUSE +	dw HouseDoorTileIDs +	db FOREST_GATE +	dw TilesetMuseumDoorTileIDs +	db MUSEUM +	dw TilesetMuseumDoorTileIDs +	db GATE +	dw TilesetMuseumDoorTileIDs +	db SHIP +	dw ShipDoorTileIDs +	db LOBBY +	dw LobbyDoorTileIDs +	db MANSION +	dw MansionDoorTileIDs +	db LAB +	dw LabDoorTileIDs +	db FACILITY +	dw FacilityDoorTileIDs +	db PLATEAU +	dw PlateauDoorTileIDs +	db $ff + +OverworldDoorTileIDs: ; 1a654 (6:6654) +	db $1B,$58,$00 + +ForestDoorTileIDs: ; 1a657 (6:6657) +	db $3a,$00 + +MartDoorTileIDs: ; 1a659 (6:6659) +	db $5e,$00 + +HouseDoorTileIDs: ; 1a65b (6:665b) +	db $54,$00 + +TilesetMuseumDoorTileIDs: ; 1a65d (6:665d) +	db $3b,$00 + +ShipDoorTileIDs: ; 1a65f (6:665f) +	db $1e,$00 + +LobbyDoorTileIDs: ; 1a661 (6:6661) +	db $1c,$38,$1a,$00 + +MansionDoorTileIDs: ; 1a665 (6:6665) +	db $1a,$1c,$53,$00 + +LabDoorTileIDs: ; 1a669 (6:6669) +	db $34,$00 + +FacilityDoorTileIDs: ; 1a66b (6:666b) +	db $43,$58,$1b,$00 + +PlateauDoorTileIDs: ; 1a66f (6:666f) +	db $3b,$1b,$00 diff --git a/engine/overworld/elevator.asm b/engine/overworld/elevator.asm new file mode 100755 index 00000000..e483e0c3 --- /dev/null +++ b/engine/overworld/elevator.asm @@ -0,0 +1,69 @@ +ShakeElevator: ; 7bf15 (1e:7f15) +	ld de, $ffe0 +	call Func_7bf64 +	ld de, $240 +	call Func_7bf64 +	call Delay3 +	ld a, $ff +	call PlaySound +	ld a, [$ffaf] +	ld d, a +	ld e, $1 +	; number of times to play collision sfx +	ld b, $64 +.asm_7bf30 +	ld a, e +	xor $fe +	ld e, a +	add d +	ld [$ffaf], a +	push bc +	ld c, BANK(SFX_02_5b) +	ld a, (SFX_02_5b - SFX_Headers_02) / 3 +	call PlayMusic +	pop bc +	ld c, $2 +	call DelayFrames +	dec b +	jr nz, .asm_7bf30 +	ld a, d +	ld [$ffaf], a +	ld a, $ff +	call PlaySound +	ld c, BANK(SFX_02_5f) +	ld a, (SFX_02_5f - SFX_Headers_02) / 3 +	call PlayMusic +.asm_7bf57 +	ld a, [$c02a] +	cp $b9 +	jr z, .asm_7bf57 +	call UpdateSprites +	jp Func_2307 + +Func_7bf64: ; 7bf64 (1e:7f64) +	ld hl, $d527 +	ld a, [hld] +	push af +	ld a, [hl] +	push af +	push hl +	push hl +	ld a, [hli] +	ld h, [hl] +	ld l, a +	add hl, de +	ld a, h +	and $3 +	or $98 +	ld d, a +	ld a, l +	pop hl +	ld [hli], a +	ld [hl], d +	call ScheduleNorthRowRedraw +	pop hl +	pop af +	ld [hli], a +	pop af +	ld [hl], a +	jp Delay3 diff --git a/engine/overworld/emotion_bubbles.asm b/engine/overworld/emotion_bubbles.asm new file mode 100755 index 00000000..b480c06d --- /dev/null +++ b/engine/overworld/emotion_bubbles.asm @@ -0,0 +1,68 @@ +PrintEmotionBubble: ; 17c47 (5:7c47) +	ld a, [$cd50] +	ld c, a +	ld b, $0 +	ld hl, EmotionBubblesPointerTable ; $7caf +	add hl, bc +	add hl, bc +	ld e, [hl] +	inc hl +	ld d, [hl] +	ld hl, $8f80 +	ld bc, (BANK(EmotionBubblesPointerTable) << 8) + $04 +	call CopyVideoData +	ld a, [$cfcb] +	push af +	ld a, $ff +	ld [$cfcb], a +	ld a, [$d736] +	bit 6, a +	ld hl, $c38f +	ld de, $c39f +	jr z, .asm_17c7a +	ld hl, $c37f +	ld de, $c38f +.asm_17c7a +	ld bc, $90 +.asm_17c7d +	ld a, [hl] +	ld [de], a +	dec hl +	dec de +	dec bc +	ld a, c +	or b +	jr nz, .asm_17c7d +	ld hl, $c104 +	ld a, [$cd4f] +	swap a +	ld c, a +	ld b, $0 +	add hl, bc +	ld a, [hli] +	ld b, a +	inc hl +	ld a, [hl] +	add $8 +	ld c, a +	ld de, EmotionBubblesOAM ; $7cb5 +	xor a +	call WriteOAMBlock +	ld c, $3c +	call DelayFrames +	pop af +	ld [$cfcb], a +	call DelayFrame +	jp UpdateSprites + +EmotionBubblesPointerTable: ; 17caf (5:7caf) +	dw EmotionBubbles +	dw EmotionBubbles + $40 +	dw EmotionBubbles + $80 + +EmotionBubblesOAM: ; 17cb5 (5:7cb5) +	db $F8,$00,$F9,$00 +	db $FA,$00,$FB,$00 + +EmotionBubbles: ; 17cbd (5:7cbd) +	INCBIN "gfx/emotion_bubbles.w16.2bpp" diff --git a/engine/overworld/healing_machine.asm b/engine/overworld/healing_machine.asm new file mode 100755 index 00000000..77ff4ccc --- /dev/null +++ b/engine/overworld/healing_machine.asm @@ -0,0 +1,102 @@ +AnimateHealingMachine: ; 70433 (1c:4433) +	ld de, PokeCenterFlashingMonitorAndHealBall ; $44b7 +	ld hl, $87c0 +	ld bc, (BANK(PokeCenterFlashingMonitorAndHealBall) << 8) + $03 +	call CopyVideoData +	ld hl, $cfcb +	ld a, [hl] +	push af +	ld [hl], $ff +	push hl +	ld a, [rOBP1] ; $ff49 +	push af +	ld a, $e0 +	ld [rOBP1], a ; $ff49 +	ld hl, $c384 +	ld de, PokeCenterOAMData ; $44d7 +	call Func_70503 +	ld a, $4 +	ld [wMusicHeaderPointer], a +	ld a, $ff +	ld [$c0ee], a +	call PlaySound +.asm_70464 +	ld a, [wMusicHeaderPointer] +	and a +	jr nz, .asm_70464 +	ld a, [W_NUMINPARTY] ; $d163 +	ld b, a +.asm_7046e +	call Func_70503 +	ld a, (SFX_02_4a - SFX_Headers_02) / 3 +	call PlaySound +	ld c, $1e +	call DelayFrames +	dec b +	jr nz, .asm_7046e +	ld a, [$c0ef] +	cp $1f +	ld [$c0f0], a +	jr nz, .asm_70495 +	ld a, $ff +	ld [$c0ee], a +	call PlaySound +	ld a, Bank(Func_9876) +	ld [$c0ef], a +.asm_70495 +	ld a, MUSIC_PKMN_HEALED +	ld [$c0ee], a +	call PlaySound +	ld d, $28 +	call Func_704f3 +.asm_704a2 +	ld a, [$c026] +	cp MUSIC_PKMN_HEALED +	jr z, .asm_704a2 +	ld c, $20 +	call DelayFrames +	pop af +	ld [rOBP1], a ; $ff49 +	pop hl +	pop af +	ld [hl], a +	jp UpdateSprites + +PokeCenterFlashingMonitorAndHealBall: ; 704b7 (1c:44b7) +	INCBIN "gfx/pokecenter_ball.2bpp" + +PokeCenterOAMData: ; 704d7 (1c:44d7) +	db $24,$34,$7C,$10 ; heal machine monitor +	db $2B,$30,$7D,$10 ; pokeballs 1-6 +	db $2B,$38,$7D,$30 +	db $30,$30,$7D,$10 +	db $30,$38,$7D,$30 +	db $35,$30,$7D,$10 +	db $35,$38,$7D,$30 + +Func_704f3: ; 704f3 (1c:44f3) +	ld b, $8 +.asm_704f5 +	ld a, [rOBP1] ; $ff49 +	xor d +	ld [rOBP1], a ; $ff49 +	ld c, $a +	call DelayFrames +	dec b +	jr nz, .asm_704f5 +	ret + +Func_70503: ; 70503 (1c:4503) +	ld a, [de] +	inc de +	ld [hli], a +	ld a, [de] +	inc de +	ld [hli], a +	ld a, [de] +	inc de +	ld [hli], a +	ld a, [de] +	inc de +	ld [hli], a +	ret diff --git a/engine/overworld/hidden_items.asm b/engine/overworld/hidden_items.asm new file mode 100755 index 00000000..db6bf1cd --- /dev/null +++ b/engine/overworld/hidden_items.asm @@ -0,0 +1,168 @@ +HiddenItems: ; 76688 (1d:6688) +	ld hl, HiddenItemCoords +	call Func_76857 +	ld [$cd41], a +	ld hl, $d6f0 +	ld a, [$cd41] +	ld c, a +	ld b, $2 +	ld a, $10 +	call Predef +	ld a, c +	and a +	ret nz +	call EnableAutoTextBoxDrawing +	ld a, $1 +	ld [$cc3c], a +	ld a, [$cd3d] ; item ID +	ld [$d11e], a +	call GetItemName +	ld a, $24 +	jp PrintPredefTextID + +INCLUDE "data/hidden_item_coords.asm" + +FoundHiddenItemText: ; 7675b (1d:675b) +; XXX where is the pointer to this? +	TX_FAR _FoundHiddenItemText +	db $8 +	ld a, [$cd3d] ; item ID +	ld b, a +	ld c, 1 +	call GiveItem +	jr nc, .BagFull +	ld hl, $d6f0 +	ld a, [$cd41] +	ld c, a +	ld b, $1 +	ld a, $10 +	call Predef +	ld a, (SFX_02_3b - SFX_Headers_02) / 3 +	call PlaySoundWaitForCurrent ; play sound +	call WaitForSoundToFinish ; wait for sound to finish playing +	jp TextScriptEnd +.BagFull +	call WaitForTextScrollButtonPress ; wait for button press +	xor a +	ld [$cc3c], a +	ld hl, HiddenItemBagFullText +	call PrintText +	jp TextScriptEnd + +HiddenItemBagFullText: ; 76794 (1d:6794) +	TX_FAR _HiddenItemBagFullText +	db "@" + +HiddenCoins: ; 76799 (1d:6799) +	ld b, COIN_CASE +	ld a, $1c +	call Predef +	ld a, b +	and a +	ret z +	ld hl, HiddenCoinCoords +	call Func_76857 +	ld [$cd41], a +	ld hl, $d6fe +	ld a, [$cd41] +	ld c, a +	ld b, $2 +	ld a, $10 +	call Predef +	ld a, c +	and a +	ret nz +	xor a +	ld [$ff9f], a +	ld [$ffa0], a +	ld [$ffa1], a +	ld a, [$cd3d] +	sub COIN +	cp 10 +	jr z, .bcd10 +	cp 20 +	jr z, .bcd20 +	cp 40 +	jr z, .bcd20 +	jr .bcd100 +.bcd10 +	ld a, $10 +	ld [$ffa1], a +	jr .bcddone +.bcd20 +	ld a, $20 +	ld [$ffa1], a +	jr .bcddone +.bcd40 ; due to a typo, this is never used +	ld a, $40 +	ld [$ffa1], a +	jr .bcddone +.bcd100 +	ld a, $1 +	ld [$ffa0], a +.bcddone +	ld de, $d5a5 +	ld hl, $ffa1 +	ld c, $2 +	ld a, $b +	call Predef +	ld hl, $d6fe +	ld a, [$cd41] +	ld c, a +	ld b, $1 +	ld a, $10 +	call Predef +	call EnableAutoTextBoxDrawing +	ld a, [wPlayerCoins] +	cp $99 +	jr nz, .RoomInCoinCase +	ld a, [wPlayerCoins + 1] +	cp $99 +	jr nz, .RoomInCoinCase +	ld a, $2c +	jr .done +.RoomInCoinCase +	ld a, $2b +.done +	jp PrintPredefTextID + +INCLUDE "data/hidden_coins.asm" + +FoundHiddenCoinsText: ; 76847 (1d:6847) +	TX_FAR _FoundHiddenCoinsText +	db $10,"@" + +DroppedHiddenCoinsText: ; 7684d (1d:684d) +	TX_FAR _FoundHiddenCoins2Text +	db $10 +	TX_FAR _DroppedHiddenCoinsText +	db "@" + +Func_76857: ; 76857 (1d:6857) +	ld a, [$cd40] +	ld d, a +	ld a, [$cd41] +	ld e, a +	ld a, [W_CURMAP] +	ld b, a +	ld c, $ff +.loop +	inc c +	ld a, [hli] +	cp $ff ; end of the list? +	ret z  ; if so, we're done here +	cp b +	jr nz, .asm_76877 ; 0x7686b $a +	ld a, [hli] +	cp d +	jr nz, .asm_76878 ; 0x7686f $7 +	ld a, [hli] +	cp e +	jr nz, .loop +	ld a, c +	ret +.asm_76877 +	inc hl +.asm_76878 +	inc hl +	jr .loop diff --git a/engine/overworld/hidden_objects.asm b/engine/overworld/hidden_objects.asm new file mode 100755 index 00000000..e4777a84 --- /dev/null +++ b/engine/overworld/hidden_objects.asm @@ -0,0 +1,129 @@ +Func_46981: ; 46981 (11:6981) +	xor a +	ld [$d71e], a +	ld a, [$d72d] +	bit 4, a +	ret nz +	call ArePlayerCoordsInArray +	ret nc +	ld a, [wWhichTrade] ; $cd3d +	ld [$d71e], a +	ld hl, $d72d +	set 4, [hl] +	ld hl, $d732 +	set 4, [hl] +	ret + +Func_469a0: ; 469a0 (11:69a0) +	ld hl, $ffeb +	xor a +	ld [hli], a +	ld [hli], a +	ld [hli], a +	ld [hl], a +	ld de, $0 +	ld hl, HiddenObjectMaps ; $6a40 +.asm_469ae +	ld a, [hli] +	ld b, a +	cp $ff +	jr z, .asm_469fc +	ld a, [W_CURMAP] ; $d35e +	cp b +	jr z, .asm_469be +	inc de +	inc de +	jr .asm_469ae +.asm_469be +	ld hl, HiddenObjectPointers ; $6a96 +	add hl, de +	ld a, [hli] +	ld h, [hl] +	ld l, a +	push hl +	ld hl, wWhichTrade ; $cd3d +	xor a +	ld [hli], a +	ld [hli], a +	ld [hl], a +	pop hl +.asm_469ce +	ld a, [hli] +	cp $ff +	jr z, .asm_469fc +	ld [$cd40], a +	ld b, a +	ld a, [hli] +	ld [$cd41], a +	ld c, a +	call Func_46a01 +	ld a, [$ffea] +	and a +	jr z, .asm_469f0 +	inc hl +	inc hl +	inc hl +	inc hl +	push hl +	ld hl, $cd3f +	inc [hl] +	pop hl +	jr .asm_469ce +.asm_469f0 +	ld a, [hli] +	ld [wWhichTrade], a ; $cd3d +	ld a, [hli] +	ld [$cd3e], a +	ld a, [hli] +	ld h, [hl] +	ld l, a +	ret +.asm_469fc +	ld a, $ff +	ld [$ffee], a +	ret + +Func_46a01: ; 46a01 (11:6a01) +	ld a, [$c109] +	cp $4 +	jr z, .asm_46a16 +	cp $8 +	jr z, .asm_46a25 +	cp $c +	jr z, .asm_46a2b +	ld a, [W_YCOORD] ; $d361 +	inc a +	jr .asm_46a1a +.asm_46a16 +	ld a, [W_YCOORD] ; $d361 +	dec a +.asm_46a1a +	cp b +	jr nz, .asm_46a3b +	ld a, [W_XCOORD] ; $d362 +	cp c +	jr nz, .asm_46a3b +	jr .asm_46a38 +.asm_46a25 +	ld a, [W_XCOORD] ; $d362 +	dec a +	jr .asm_46a2f +.asm_46a2b +	ld a, [W_XCOORD] ; $d362 +	inc a +.asm_46a2f +	cp c +	jr nz, .asm_46a3b +	ld a, [W_YCOORD] ; $d361 +	cp b +	jr nz, .asm_46a3b +.asm_46a38 +	xor a +	jr .asm_46a3d +.asm_46a3b +	ld a, $ff +.asm_46a3d +	ld [$ffea], a +	ret + +INCLUDE "data/hidden_objects.asm" diff --git a/engine/overworld/ledges.asm b/engine/overworld/ledges.asm new file mode 100755 index 00000000..d2f248cd --- /dev/null +++ b/engine/overworld/ledges.asm @@ -0,0 +1,87 @@ +HandleLedges: ; 1a672 (6:6672) +	ld a, [$d736] +	bit 6, a +	ret nz +	ld a, [W_CURMAPTILESET] ; $d367 +	and a ; OVERWORLD +	ret nz +	ld a, $35 +	call Predef ; indirect jump to Func_c586 (c586 (3:4586)) +	ld a, [$c109] +	ld b, a +	FuncCoord 8, 9 ; $c45c +	ld a, [Coord] +	ld c, a +	ld a, [$cfc6] +	ld d, a +	ld hl, LedgeTiles ; $66cf +.asm_1a691 +	ld a, [hli] +	cp $ff +	ret z +	cp b +	jr nz, .asm_1a6a4 +	ld a, [hli] +	cp c +	jr nz, .asm_1a6a5 +	ld a, [hli] +	cp d +	jr nz, .asm_1a6a6 +	ld a, [hl] +	ld e, a +	jr .asm_1a6a9 +.asm_1a6a4 +	inc hl +.asm_1a6a5 +	inc hl +.asm_1a6a6 +	inc hl +	jr .asm_1a691 +.asm_1a6a9 +	ld a, [H_CURRENTPRESSEDBUTTONS] +	and e +	ret z +	ld a, $ff +	ld [wJoypadForbiddenButtonsMask], a +	ld hl, $d736 +	set 6, [hl] +	call Func_3486 +	ld a, e +	ld [$ccd3], a +	ld [$ccd4], a +	ld a, $2 +	ld [$cd38], a +	call LoadHoppingShadowOAM +	ld a, (SFX_02_4e - SFX_Headers_02) / 3 +	call PlaySound +	ret + +	; (player direction) (tile player standing on) (ledge tile) (input required) +LedgeTiles: ; 1a6cf (6:66cf) +	db $00,$2C,$37,$80 +	db $00,$39,$36,$80 +	db $00,$39,$37,$80 +	db $08,$2C,$27,$20 +	db $08,$39,$27,$20 +	db $0C,$2C,$0D,$10 +	db $0C,$2C,$1D,$10 +	db $0C,$39,$0D,$10 +	db $FF + +LoadHoppingShadowOAM: ; 1a6f0 (6:66f0) +	ld hl, $8ff0 +	ld de, LedgeHoppingShadow ; $6708 +	ld bc, (BANK(LedgeHoppingShadow) << 8) + $01 +	call CopyVideoDataDouble +	ld a, $9 +	ld bc, $5448 ; b, c = y, x coordinates of shadow +	ld de, LedgeHoppingShadowOAM ; $6710 +	call WriteOAMBlock +	ret + +LedgeHoppingShadow: ; 1a708 (6:6708) +	INCBIN "gfx/ledge_hopping_shadow.1bpp" + +LedgeHoppingShadowOAM: ; 1a710 (6:6710) +	db $FF,$10,$FF,$20 +	db $FF,$40,$FF,$60 diff --git a/engine/overworld/map_sprites.asm b/engine/overworld/map_sprites.asm new file mode 100755 index 00000000..a734319d --- /dev/null +++ b/engine/overworld/map_sprites.asm @@ -0,0 +1,440 @@ +; Loads tile patterns for map's sprites. +; For outside maps, it loads one of several fixed sets of sprites. +; For inside maps, it loads each sprite picture ID used in the map header. +; This is also called after displaying text because loading +; text tile patterns overwrites half of the sprite tile pattern data. +; Note on notation: +; $C1X* and $C2X* are used to denote $C100-$C1FF and $C200-$C2FF sprite slot +; fields, respectively, within loops. The X is the loop index. +; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y* +; denote fields of the sprite slots interated over in the inner loop. +InitMapSprites: ; 1785b (5:785b) +	call InitOutsideMapSprites +	ret c ; return if the map is an outside map (already handled by above call) +; if the map is an inside map (i.e. mapID >= $25) +	ld hl,wSpriteStateData1 +	ld de,$c20d +; Loop to copy picture ID's from $C1X0 to $C2XD for LoadMapSpriteTilePatterns. +.copyPictureIDLoop +	ld a,[hl] ; $C1X0 (picture ID) +	ld [de],a ; $C2XD +	ld a,$10 +	add e +	ld e,a +	ld a,$10 +	add l +	ld l,a +	jr nz,.copyPictureIDLoop + +; This is used for both inside and outside maps, since it is called by +; InitOutsideMapSprites. +; Loads tile pattern data for sprites into VRAM. +LoadMapSpriteTilePatterns: ; 17871 (5:7871) +	ld a,[W_NUMSPRITES] +	and a ; are there any sprites? +	jr nz,.spritesExist +	ret +.spritesExist +	ld c,a ; c = [W_NUMSPRITES] +	ld b,$10 ; number of sprite slots +	ld hl,$c20d +	xor a +	ld [$ff8e],a ; 4-tile sprite counter +.copyPictureIDLoop ; loop to copy picture ID from $C2XD to $C2XE +	ld a,[hli] ; $C2XD (sprite picture ID) +	ld [hld],a ; $C2XE +	ld a,l +	add a,$10 +	ld l,a +	dec b +	jr nz,.copyPictureIDLoop +	ld hl,$c21e +.loadTilePatternLoop +	ld de,$c21d +; Check if the current picture ID has already had its tile patterns loaded. +; This done by looping through the previous sprite slots and seeing if any of +; their picture ID's match that of the current sprite slot. +.checkIfAlreadyLoadedLoop +	ld a,e +	and a,$f0 +	ld b,a ; b = offset of the wSpriteStateData2 sprite slot being checked against +	ld a,l +	and a,$f0 ; a = offset of current wSpriteStateData2 sprite slot +	cp b ; done checking all previous sprite slots? +	jr z,.notAlreadyLoaded +	ld a,[de] ; picture ID of the wSpriteStateData2 sprite slot being checked against +	cp [hl] ; do the picture ID's match? +	jp z,.alreadyLoaded +	ld a,e +	add a,$10 +	ld e,a +	jr .checkIfAlreadyLoadedLoop +.notAlreadyLoaded +	ld de,$c20e +	ld b,$01 +; loop to find the highest tile pattern VRAM slot (among the first 10 slots) used by a previous sprite slot +; this is done in order to find the first free VRAM slot available +.findNextVRAMSlotLoop +	ld a,e +	add a,$10 +	ld e,a +	ld a,l +	cp e ; reached current slot? +	jr z,.foundNextVRAMSlot +	ld a,[de] ; $C2YE (VRAM slot) +	cp a,11 ; is it one of the first 10 slots? +	jr nc,.findNextVRAMSlotLoop +	cp b ; compare the slot being checked to the current max +	jr c,.findNextVRAMSlotLoop ; if the slot being checked is less than the current max +; if the slot being checked is greater than or equal to the current max +	ld b,a ; store new max VRAM slot +	jr .findNextVRAMSlotLoop +.foundNextVRAMSlot +	inc b ; increment previous max value to get next VRAM tile pattern slot +	ld a,b ; a = next VRAM tile pattern slot +	push af +	ld a,[hl] ; $C2XE (sprite picture ID) +	ld b,a ; b = current sprite picture ID +	cp a,SPRITE_BALL ; is it a 4-tile sprite? +	jr c,.notFourTileSprite +	pop af +	ld a,[$ff8e] ; 4-tile sprite counter +	add a,11 +	jr .storeVRAMSlot +.notFourTileSprite +	pop af +.storeVRAMSlot +	ld [hl],a ; store VRAM slot at $C2XE +	ld [$ff8d],a ; used to determine if it's 4-tile sprite later +	ld a,b ; a = current sprite picture ID +	dec a +	add a +	add a +	push bc +	push hl +	ld hl,SpriteSheetPointerTable +	jr nc,.noCarry +	inc h +.noCarry +	add l +	ld l,a +	jr nc,.noCarry2 +	inc h +.noCarry2 +	push hl +	call ReadSpriteSheetData +	push af +	push de +	push bc +	ld hl,$8000 ; VRAM base address +	ld bc,$c0 ; number of bytes per VRAM slot +	ld a,[$ff8d] +	cp a,11 ; is it a 4-tile sprite? +	jr nc,.fourTileSpriteVRAMAddr +	ld d,a +	dec d +; Equivalent to multiplying $C0 (number of bytes in 12 tiles) times the VRAM +; slot and adding the result to $8000 (the VRAM base address). +.calculateVRAMAddrLoop +	add hl,bc +	dec d +	jr nz,.calculateVRAMAddrLoop +	jr .loadStillTilePattern +.fourTileSpriteVRAMAddr +	ld hl,$87c0 ; address for second 4-tile sprite +	ld a,[$ff8e] ; 4-tile sprite counter +	and a ; is it the first 4-tile sprite? +	jr nz,.loadStillTilePattern +; if it's the first 4-tile sprite +	ld hl,$8780 ; address for first 4-tile sprite +	inc a +	ld [$ff8e],a ; 4-tile sprite counter +.loadStillTilePattern +	pop bc +	pop de +	pop af +	push hl +	push hl +	ld h,d +	ld l,e +	pop de +	ld b,a +	ld a,[$cfc4] +	bit 0,a ; reloading upper half of tile patterns after displaying text? +	jr nz,.skipFirstLoad ; if so, skip loading data into the lower half +	ld a,b +	ld b,0 +	call FarCopyData2 ; load tile pattern data for sprite when standing still +.skipFirstLoad +	pop de +	pop hl +	ld a,[$ff8d] +	cp a,11 ; is it a 4-tile sprite? +	jr nc,.skipSecondLoad ; if so, there is no second block +	push de +	call ReadSpriteSheetData +	push af +	ld a,$c0 +	add e +	ld e,a +	jr nc,.noCarry3 +	inc d +.noCarry3 +	ld a,[$cfc4] +	bit 0,a ; reloading upper half of tile patterns after displaying text? +	jr nz,.loadWhileLCDOn +	pop af +	pop hl +	set 3,h ; add $800 to hl +	push hl +	ld h,d +	ld l,e +	pop de +	call FarCopyData2 ; load tile pattern data for sprite when walking +	jr .skipSecondLoad +; When reloading the upper half of tile patterns after diplaying text, the LCD +; will be on, so CopyVideoData (which writes to VRAM only during V-blank) must +; be used instead of FarCopyData2. +.loadWhileLCDOn +	pop af +	pop hl +	set 3,h ; add $800 to hl +	ld b,a +	swap c +	call CopyVideoData ; load tile pattern data for sprite when walking +.skipSecondLoad +	pop hl +	pop bc +	jr .nextSpriteSlot +.alreadyLoaded ; if the current picture ID has already had its tile patterns loaded +	inc de +	ld a,[de] ; a = VRAM slot for the current picture ID (from $C2YE) +	ld [hl],a ; store VRAM slot in current wSpriteStateData2 sprite slot (at $C2XE) +.nextSpriteSlot +	ld a,l +	add a,$10 +	ld l,a +	dec c +	jp nz,.loadTilePatternLoop +	ld hl,$c20d +	ld b,$10 +; the pictures ID's stored at $C2XD are no longer needed, so zero them +.zeroStoredPictureIDLoop +	xor a +	ld [hl],a ; $C2XD +	ld a,$10 +	add l +	ld l,a +	dec b +	jr nz,.zeroStoredPictureIDLoop +	ret + +; reads data from SpriteSheetPointerTable +; INPUT: +; hl = address of sprite sheet entry +; OUTPUT: +; de = pointer to sprite sheet +; bc = length in bytes +; a = ROM bank +ReadSpriteSheetData: ; 17971 (5:7971) +	ld a,[hli] +	ld e,a +	ld a,[hli] +	ld d,a +	ld a,[hli] +	ld c,a +	xor a +	ld b,a +	ld a,[hli] +	ret + +; Loads sprite set for outside maps (cities and routes) and sets VRAM slots. +; sets carry if the map is a city or route, unsets carry if not +InitOutsideMapSprites: ; 1797b (5:797b) +	ld a,[W_CURMAP] +	cp a,REDS_HOUSE_1F ; is the map a city or a route (map ID less than $25)? +	ret nc ; if not, return +	ld hl,MapSpriteSets +	add l +	ld l,a +	jr nc,.noCarry +	inc h +.noCarry +	ld a,[hl] ; a = spriteSetID +	cp a,$f0 ; does the map have 2 sprite sets? +	call nc,GetSplitMapSpriteSetID ; if so, choose the appropriate one +	ld b,a ; b = spriteSetID +	ld a,[$cfc4] +	bit 0,a ; reloading upper half of tile patterns after displaying text? +	jr nz,.loadSpriteSet ; if so, forcibly reload the sprite set +	ld a,[W_SPRITESETID] +	cp b ; has the sprite set ID changed? +	jr z,.skipLoadingSpriteSet ; if not, don't load it again +.loadSpriteSet +	ld a,b +	ld [W_SPRITESETID],a +	dec a +	ld b,a +	sla a +	ld c,a +	sla a +	sla a +	add c +	add b ; a = (spriteSetID - 1) * 11 +	ld de,SpriteSets +; add a to de to get offset of sprite set +	add e +	ld e,a +	jr nc,.noCarry2 +	inc d +.noCarry2 +	ld hl,$c20d +	ld a,SPRITE_RED +	ld [hl],a +	ld bc,W_SPRITESET +; Load the sprite set into RAM. +; This loop also fills $C2XD (sprite picture ID) where X is from $0 to $A +; with picture ID's. This is done so that LoadMapSpriteTilePatterns will +; load tile patterns for all sprite pictures in the sprite set. +.loadSpriteSetLoop +	ld a,$10 +	add l +	ld l,a +	ld a,[de] ; sprite picture ID from sprite set +	ld [hl],a ; $C2XD (sprite picture ID) +	ld [bc],a +	inc de +	inc bc +	ld a,l +	cp a,$bd ; reached 11th sprite slot? +	jr nz,.loadSpriteSetLoop +	ld b,4 ; 4 remaining sprite slots +.zeroRemainingSlotsLoop ; loop to zero the picture ID's of the remaining sprite slots +	ld a,$10 +	add l +	ld l,a +	xor a +	ld [hl],a ; $C2XD (sprite picture ID) +	dec b +	jr nz,.zeroRemainingSlotsLoop +	ld a,[W_NUMSPRITES] +	push af ; save number of sprites +	ld a,11 ; 11 sprites in sprite set +	ld [W_NUMSPRITES],a +	call LoadMapSpriteTilePatterns +	pop af +	ld [W_NUMSPRITES],a ; restore number of sprites +	ld hl,$c21e +	ld b,$0f +; The VRAM tile pattern slots that LoadMapSpriteTilePatterns set are in the +; order of the map's sprite set, not the order of the actual sprites loaded +; for the current map. So, they are not needed and are zeroed by this loop. +.zeroVRAMSlotsLoop +	xor a +	ld [hl],a ; $C2XE (VRAM slot) +	ld a,$10 +	add l +	ld l,a +	dec b +	jr nz,.zeroVRAMSlotsLoop +.skipLoadingSpriteSet +	ld hl,$c110 +; This loop stores the correct VRAM tile pattern slots according the sprite +; data from the map's header. Since the VRAM tile pattern slots are filled in +; the order of the sprite set, in order to find the VRAM tile pattern slot +; for a sprite slot, the picture ID for the sprite is looked up within the +; sprite set. The index of the picture ID within the sprite set plus one +; (since the Red sprite always has the first VRAM tile pattern slot) is the +; VRAM tile pattern slot. +.storeVRAMSlotsLoop +	ld c,0 +	ld a,[hl] ; $C1X0 (picture ID) (zero if sprite slot is not used) +	and a ; is the sprite slot used? +	jr z,.skipGettingPictureIndex ; if the sprite slot is not used +	ld b,a ; b = picture ID +	ld de,W_SPRITESET +; Loop to find the index of the sprite's picture ID within the sprite set. +.getPictureIndexLoop +	inc c +	ld a,[de] +	inc de +	cp b ; does the picture ID match? +	jr nz,.getPictureIndexLoop +	inc c +.skipGettingPictureIndex +	push hl +	inc h +	ld a,$0e +	add l +	ld l,a +	ld a,c ; a = VRAM slot (zero if sprite slot is not used) +	ld [hl],a ; $C2XE (VRAM slot) +	pop hl +	ld a,$10 +	add l +	ld l,a +	and a +	jr nz,.storeVRAMSlotsLoop +	scf +	ret + +; Chooses the correct sprite set ID depending on the player's position within +; the map for maps with two sprite sets. +GetSplitMapSpriteSetID: ; 17a1a (5:7a1a) +	cp a,$f8 +	jr z,.route20 +	ld hl,SplitMapSpriteSets +	and a,$0f +	dec a +	sla a +	sla a +	add l +	ld l,a +	jr nc,.noCarry +	inc h +.noCarry +	ld a,[hli] ; determines whether the map is split East/West or North/South +	cp a,$01 +	ld a,[hli] ; position of dividing line +	ld b,a +	jr z,.eastWestDivide +.northSouthDivide +	ld a,[W_YCOORD] +	jr .compareCoord +.eastWestDivide +	ld a,[W_XCOORD] +.compareCoord +	cp b +	jr c,.loadSpriteSetID +; if in the East side or South side +	inc hl +.loadSpriteSetID +	ld a,[hl] +	ret +; Uses sprite set $01 for West side and $0A for East side. +; Route 20 is a special case because the two map sections have a more complex +; shape instead of the map simply being split horizontally or vertically. +.route20 +	ld hl,W_XCOORD +	ld a,[hl] +	cp a,$2b +	ld a,$01 +	ret c +	ld a,[hl] +	cp a,$3e +	ld a,$0a +	ret nc +	ld a,[hl] +	cp a,$37 +	ld b,$08 +	jr nc,.next +	ld b,$0d +.next +	ld a,[W_YCOORD] +	cp b +	ld a,$0a +	ret c +	ld a,$01 +	ret + +INCLUDE "data/sprite_sets.asm" diff --git a/engine/overworld/npc_movement.asm b/engine/overworld/npc_movement.asm new file mode 100755 index 00000000..54d7321b --- /dev/null +++ b/engine/overworld/npc_movement.asm @@ -0,0 +1,291 @@ +Func_1a3e0: ; 1a3e0 (6:63e0) +	ld hl, $d730 +	res 1, [hl] +	call HandleDoors +	jr nc, .asm_1a406 +	ld a, $fc +	ld [wJoypadForbiddenButtonsMask], a +	ld hl, $d736 +	set 1, [hl] +	ld a, $1 +	ld [$cd38], a +	ld a, $80 +	ld [$ccd3], a +	xor a +	ld [$c102], a +	call Func_3486 +	ret +.asm_1a406 +	xor a +	ld [$cd3a], a +	ld [$cd38], a +	ld [$ccd3], a +	ld hl, $d736 +	res 0, [hl] +	res 1, [hl] +	ld hl, $d730 +	res 7, [hl] +	ret + +Func_1a41d: ; 1a41d (6:641d) +	ld hl, $d730 +	res 7, [hl] +	ld hl, $d72e +	res 7, [hl] +	ld hl, $d736 +	res 0, [hl] +	res 1, [hl] +	xor a +	ld [$cf17], a +	ld [$cc57], a +	ld [$cf10], a +	ld [$cd3a], a +	ld [$cd38], a +	ld [$ccd3], a +	ret + +PointerTable_1a442: ; 1a442 (6:6442) +	dw Func_1a44c +	dw Func_1a485 +	dw Func_1a4a1 +	dw Func_1a4a6 +	dw Func_1a4f4 + +Func_1a44c: ; 1a44c (6:644c) +	ld a, [W_XCOORD] ; $d362 +	sub $a +	ld [$cca1], a +	jr z, .asm_1a475 +	ld b, $0 +	ld c, a +	ld hl, $cc97 +	ld a, $80 +	call FillMemory +	ld [hl], $ff +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	ld de, $cc97 +	call MoveSprite +	ld a, $1 +	ld [$cf10], a +	jr .asm_1a47a +.asm_1a475 +	ld a, $3 +	ld [$cf10], a +.asm_1a47a +	ld hl, W_FLAGS_D733 +	set 1, [hl] +	ld a, $fc +	ld [wJoypadForbiddenButtonsMask], a +	ret + +Func_1a485: ; 1a485 (6:6485) +	ld a, [$d730] +	bit 0, a +	ret nz +	ld a, [$cca1] +	ld [$cd38], a +	ld [$ff95], a +	ld a, $23 +	call Predef +	call Func_3486 +	ld a, $2 +	ld [$cf10], a +	ret + +Func_1a4a1: ; 1a4a1 (6:64a1) +	ld a, [$cd38] +	and a +	ret nz + +Func_1a4a6: ; 1a4a6 (6:64a6) +	xor a +	ld [$cd3b], a +	ld a, [$cf13] +	swap a +	ld [$cf17], a +	xor a +	ld [$c206], a +	ld hl, $ccd3 +	ld de, RLEList_1a4e9 +	call DecodeRLEList +	dec a +	ld [$cd38], a +	ld hl, $cc97 +	ld de, RLEList_1a4dc +	call DecodeRLEList +	ld hl, $d72e +	res 7, [hl] +	ld hl, $d730 +	set 7, [hl] +	ld a, $4 +	ld [$cf10], a +	ret + +RLEList_1a4dc: ; 1a4dc (6:64dc) +	db $00, $05 +	db $80, $01 +	db $00, $05 +	db $C0, $03 +	db $40, $01 +	db $E0, $01 +	db $FF + +RLEList_1a4e9: ; 1a4e9 (6:64e9) +	db $40, $02 +	db $10, $03 +	db $80, $05 +	db $20, $01 +	db $80, $06 +	db $FF + +Func_1a4f4: ; 1a4f4 (6:64f4) +	ld a, [$cd38] +	and a +	ret nz +	ld a, $0 +	ld [$cc4d], a +	ld a, $11 +	call Predef ; indirect jump to RemoveMissableObject (f1d7 (3:71d7)) +	ld hl, $d730 +	res 7, [hl] +	ld hl, $d72e +	res 7, [hl] +	jp Func_314e + +PointerTable_1a510: ; 1a510 (6:6510) +	dw Func_1a514 +	dw Func_1a56b + +Func_1a514: ; 1a514 (6:6514) +	ld a, Bank(Func_9876) +	ld [$c0ef], a +	ld [$c0f0], a +	ld a, MUSIC_MUSEUM_GUY +	ld [$c0ee], a +	call PlaySound +	ld a, [$cf13] +	swap a +	ld [$cf17], a +	call Func_3486 +	ld hl, $ccd3 +	ld de, RLEList_PewterMuseumPlayer +	call DecodeRLEList +	dec a +	ld [$cd38], a +	xor a +	ld [$d12f], a +	ld a, $4f +	call Predef +	ld hl, $cc97 +	ld de, RLEList_PewterMuseumGuy +	call DecodeRLEList +	ld hl, $d72e +	res 7, [hl] +	ld a, $1 +	ld [$cf10], a +	ret + +RLEList_PewterMuseumPlayer: ; 1a559 (6:6559) +	db $00, $01 +	db $40, $03 +	db $20, $0D +	db $40, $06 +	db $FF + +RLEList_PewterMuseumGuy: ; 1a562 (6:6562) +	db $40, $06 +	db $80, $0D +	db $40, $03 +	db $80, $01 +	db $FF + +Func_1a56b: ; 1a56b (6:656b) +	ld a, [$cd38] +	and a +	ret nz +	ld hl, $d730 +	res 7, [hl] +	ld hl, $d72e +	res 7, [hl] +	jp Func_314e + +PointerTable_1a57d: ; 1a57d (6:657d) +	dw Func_1a581 +	dw Func_1a56b + +Func_1a581: ; 1a581 (6:6581) +	ld a, Bank(Func_9876) +	ld [$c0ef], a +	ld [$c0f0], a +	ld a, MUSIC_MUSEUM_GUY +	ld [$c0ee], a +	call PlaySound +	ld a, [$cf13] +	swap a +	ld [$cf17], a +	xor a +	ld [$c206], a +	ld hl, $ccd3 +	ld de, RLEList_PewterGymPlayer +	call DecodeRLEList +	dec a +	ld [$cd38], a +	ld a, $1 +	ld [$d12f], a +	ld a, $4f +	call Predef +	ld hl, $cc97 +	ld de, RLEList_PewterGymGuy +	call DecodeRLEList +	ld hl, $d72e +	res 7, [hl] +	ld hl, $d730 +	set 7, [hl] +	ld a, $1 +	ld [$cf10], a +	ret + +RLEList_PewterGymPlayer: ; 1a5cd (6:65cd) +	db $00, $01 +	db $10, $02 +	db $80, $05 +	db $20, $0B +	db $40, $05 +	db $20, $0F +	db $FF + +RLEList_PewterGymGuy: ; 1a5da (6:65da) +	db $00, $02 +	db $80, $0F +	db $40, $05 +	db $80, $0B +	db $00, $05 +	db $C0, $03 +	db $FF + +; XXX why would this function want to return on POKEMONTOWER_7? +Func_1a5e7: ; 1a5e7 (6:65e7) +	ld a, [W_CURMAP] ; $d35e +	cp POKEMONTOWER_7 +	ret z +	ld hl, RivalIDs ; $6605 +	ld a, [wEngagedTrainerClass] +	ld b, a +.loop +	ld a, [hli] +	cp $ff +	jr z, .notRival +	cp b +	ret z +	jr .loop +.notRival +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	jp SetSpriteMovementBytesToFF + +RivalIDs: ; 1a605 (6:6605) +	db SONY1 + $c8 +	db SONY2 + $c8 +	db SONY3 + $c8 +	db $ff diff --git a/engine/overworld/oaks_aide.asm b/engine/overworld/oaks_aide.asm new file mode 100755 index 00000000..ca2c6726 --- /dev/null +++ b/engine/overworld/oaks_aide.asm @@ -0,0 +1,71 @@ +OaksAideScript ; 0x59035 +	ld hl, OaksAideHiText +	call PrintText +	call YesNoChoice +	ld a, [$cc26] +	and a +	jr nz, .asm_59086 ; 0x59042 $42 +	ld hl, wPokedexOwned +	ld b, wPokedexOwnedEnd - wPokedexOwned +	call CountSetBits +	ld a, [$d11e] +	ld [$ffdd], a +	ld b, a +	ld a, [$ffdb] +	cp b +	jr z, .asm_59059 ; 0x59055 $2 +	jr nc, .asm_5907c ; 0x59057 $23 +.asm_59059 +	ld hl, OaksAideHereYouGoText +	call PrintText +	ld a, [$ffdc] +	ld b, a +	ld c, 1 +	call GiveItem +	jr nc, .BagFull +	ld hl, OaksAideGotItemText +	call PrintText +	ld a, $1 +	jr .asm_5908e ; 0x59071 $1b +.BagFull +	ld hl, OaksAideNoRoomText +	call PrintText +	xor a +	jr .asm_5908e ; 0x5907a $12 +.asm_5907c +	ld hl, OaksAideUhOhText +	call PrintText +	ld a, $80 +	jr .asm_5908e ; 0x59084 $8 +.asm_59086 +	ld hl, OaksAideComeBackText +	call PrintText +	ld a, $ff +.asm_5908e +	ld [$ffdb], a +	ret + +OaksAideHiText: ; 59091 (16:5091) +	TX_FAR _OaksAideHiText +	db "@" + +OaksAideUhOhText: ; 59096 (16:5096) +	TX_FAR _OaksAideUhOhText +	db "@" + +OaksAideComeBackText: ; 5909b (16:509b) +	TX_FAR _OaksAideComeBackText +	db "@" + +OaksAideHereYouGoText: ; 590a0 (16:50a0) +	TX_FAR _OaksAideHereYouGoText +	db "@" + +OaksAideGotItemText: ; 590a5 (16:50a5) +	TX_FAR _OaksAideGotItemText +	db $0b +	db "@" + +OaksAideNoRoomText: ; 590ab (16:50ab) +	TX_FAR _OaksAideNoRoomText +	db "@" diff --git a/engine/overworld/pewter_guys.asm b/engine/overworld/pewter_guys.asm new file mode 100755 index 00000000..7c5779a2 --- /dev/null +++ b/engine/overworld/pewter_guys.asm @@ -0,0 +1,101 @@ +PewterGuys: ; 37ca1 (d:7ca1) +	ld hl, $ccd3 +	ld a, [$cd38] +	dec a +	ld [$cd38], a +	ld d, 0 +	ld e, a +	add hl, de +	ld d, h +	ld e, l +	ld hl, PointerTable_37ce6 +	ld a, [$d12f] +	add a +	ld b, 0 +	ld c, a +	add hl, bc +	ld a, [hli] +	ld h, [hl] +	ld l, a +	ld a, [W_YCOORD] +	ld b, a +	ld a, [W_XCOORD] +	ld c, a +.asm_37cc7 +	ld a, [hli] +	cp b +	jr nz, .asm_37ce1 +	ld a, [hli] +	cp c +	jr nz, .asm_37ce2 +	ld a, [hli] +	ld h, [hl] +	ld l, a +.asm_37cd2 +	ld a, [hli] +	cp $ff +	ret z +	ld [de], a +	inc de +	ld a, [$cd38] +	inc a +	ld [$cd38], a +	jr .asm_37cd2 +.asm_37ce1 +	inc hl +.asm_37ce2 +	inc hl +	inc hl +	jr .asm_37cc7 + +PointerTable_37ce6: ; 37ce6 (d:7ce6) +	dw PewterMuseumGuyCoords +	dw PewterGymGuyCoords + +; these are the four coordinates of the spaces below, above, to the left and +; to the right of the museum guy, and pointers to different movements for +; the player to make to get positioned before the main movement. +PewterMuseumGuyCoords: ; 37cea (d:7cea) +	db 18, 27 +	dw .down +	db 16, 27 +	dw .up +	db 17, 26 +	dw .left +	db 17, 28 +	dw .right + +.down +	db $40, $40, $ff +.up +	db $10, $20, $ff +.left +	db $40, $10, $ff +.right +	db $40, $20, $ff + +; these are the five coordinates which trigger the gym guy and pointers to +; different movements for the player to make to get positioned before the +; main movement +PewterGymGuyCoords: ; 37d06 (d:7d06) +	db 16, 34 +	dw .one +	db 17, 35 +	dw .two +	db 18, 37 +	dw .three +	db 19, 37 +	dw .four +	db 17, 36 +	dw .five + +.one +	db $20, $80, $80, $10, $ff +.two +	db $20, $80, $10, $20, $ff +.three +	db $20, $20, $20, $00, $00, $00, $00, $00, $00, $00, $00, $ff +.four +	db $20, $20, $40, $20, $ff +.five +	db $20, $80, $20, $00, $00, $00, $00, $00, $00, $00, $00, $ff diff --git a/engine/overworld/player_animations.asm b/engine/overworld/player_animations.asm new file mode 100755 index 00000000..1af178c7 --- /dev/null +++ b/engine/overworld/player_animations.asm @@ -0,0 +1,520 @@ +Func_70510: ; 70510 (1c:4510) +	call Func_706ef +	ld a, $ec +	ld [$c104], a +	call Delay3 +	push hl +	call GBFadeIn2 +	ld hl, W_FLAGS_D733 +	bit 7, [hl] +	res 7, [hl] +	jr nz, .asm_70568 +	ld a, (SFX_02_4c - SFX_Headers_02) / 3 +	call PlaySound +	ld hl, $d732 +	bit 4, [hl] +	res 4, [hl] +	pop hl +	jr nz, .asm_7055e +	call Func_705aa +	ld a, (SFX_02_4f - SFX_Headers_02) / 3 +	call PlaySound +	call Func_70787 +	ld a, b +	and a +	jr nz, .asm_7055b +	ld hl, wWhichTrade ; $cd3d +	xor a +	ld [hli], a +	inc a +	ld [hli], a +	ld a, $8 +	ld [hli], a +	ld [hl], $ff +	ld hl, $cd48 +	call Func_70730 +.asm_70558 +	call Func_2307 +.asm_7055b +	jp Func_70772 +.asm_7055e +	ld c, $32 +	call DelayFrames +	call Func_705aa +	jr .asm_7055b +.asm_70568 +	pop hl +	ld de, BirdSprite ; $4d80 +	ld hl, $8000 +	ld bc, (BANK(BirdSprite) << 8) + $0c +	call CopyVideoData +	call Func_706d7 +	ld a, (SFX_02_50 - SFX_Headers_02) / 3 +	call PlaySound +	ld hl, wWhichTrade ; $cd3d +	xor a +	ld [hli], a +	ld a, $c +	ld [hli], a +	ld [hl], $8 +	ld de, FlyAnimationEnterScreenCoords ; $4592 +	call Func_706ae +	call LoadPlayerSpriteGraphics +	jr .asm_70558 + +FlyAnimationEnterScreenCoords: ; 70592 (1c:4592) +; y, x pairs +; This is the sequence of screen coordinates used by the overworld +; Fly animation when the player is entering a map. +	db $05, $98 +	db $0F, $90 +	db $18, $88 +	db $20, $80 +	db $27, $78 +	db $2D, $70 +	db $32, $68 +	db $36, $60 +	db $39, $58 +	db $3B, $50 +	db $3C, $48 +	db $3C, $40 + +Func_705aa: ; 705aa (1c:45aa) +	ld hl, wWhichTrade ; $cd3d +	ld a, $10 +	ld [hli], a +	ld a, $3c +	ld [hli], a +	call Func_7077f +	ld [hl], a +	jp Func_70755 + +_DoFlyOrTeleportAwayGraphics: ; 705ba (1c:45ba) +	call Func_706ef +	call Func_70787 +	ld a, b +	and a +	jr z, .asm_705ef +	dec a +	jp nz, Func_7067d +.asm_705c8 +	ld a, (SFX_02_4b - SFX_Headers_02) / 3 +	call PlaySound +	ld hl, wWhichTrade ; $cd3d +	ld a, $f0 +	ld [hli], a +	ld a, $ec +	ld [hli], a +	call Func_7077f +	ld [hl], a +	call Func_70755 +	call Func_70787 +	ld a, b +	dec a +	jr z, .asm_705e9 +	ld c, $a +	call DelayFrames +.asm_705e9 +	call GBFadeOut2 +	jp Func_70772 +.asm_705ef +	ld a, $4 +	call StopMusic +	ld a, [$d732] +	bit 6, a +	jr z, .asm_70610 +	ld hl, wWhichTrade ; $cd3d +	ld a, $10 +	ld [hli], a +	ld a, $ff +	ld [hli], a +	xor a +	ld [hli], a +	ld [hl], $a1 +	ld hl, $cd48 +	call Func_70730 +	jr .asm_705c8 +.asm_70610 +	call Func_706d7 +	ld hl, wWhichTrade ; $cd3d +	ld a, $ff +	ld [hli], a +	ld a, $8 +	ld [hli], a +	ld [hl], $c +	call Func_706ae +	ld a, (SFX_02_50 - SFX_Headers_02) / 3 +	call PlaySound +	ld hl, wWhichTrade ; $cd3d +	xor a +	ld [hli], a +	ld a, $c +	ld [hli], a +	ld [hl], $c +	ld de, FlyAnimationScreenCoords1 ; $464f +	call Func_706ae +	ld c, $28 +	call DelayFrames +	ld hl, $cd3e +	ld a, $b +	ld [hli], a +	ld [hl], $8 +	ld de, FlyAnimationScreenCoords2 ; $4667 +	call Func_706ae +	call GBFadeOut2 +	jp Func_70772 + +FlyAnimationScreenCoords1: ; 7064f (1c:464f) +; y, x pairs +; This is the sequence of screen coordinates used by the first part +; of the Fly overworld animation. +	db $3C, $48 +	db $3C, $50 +	db $3B, $58 +	db $3A, $60 +	db $39, $68 +	db $37, $70 +	db $37, $78 +	db $33, $80 +	db $30, $88 +	db $2D, $90 +	db $2A, $98 +	db $27, $A0 + +FlyAnimationScreenCoords2: ; 70667 (1c:4667) +; y, x pairs +; This is the sequence of screen coordinates used by the second part +; of the Fly overworld animation. +	db $1A, $90 +	db $19, $80 +	db $17, $70 +	db $15, $60 +	db $12, $50 +	db $0F, $40 +	db $0C, $30 +	db $09, $20 +	db $05, $10 +	db $00, $00 + +	db $F0, $00 + +Func_7067d: ; 7067d (1c:467d) +	ld a, $ff +	ld [$cfcb], a +	ld a, [$c302] +	ld [$c30a], a +	ld a, [$c306] +	ld [$c30e], a +	ld a, $a0 +	ld [wOAMBuffer], a +	ld [$c304], a +	ld c, $2 +	call DelayFrames +	ld a, $a0 +	ld [$c308], a +	ld [$c30c], a +	call GBFadeOut2 +	ld a, $1 +	ld [$cfcb], a +	jp Func_70772 + +Func_706ae: ; 706ae (1c:46ae) +	ld a, [$cd3f] +	xor $1 +	ld [$cd3f], a +	ld [$c102], a +	call Delay3 +	ld a, [wWhichTrade] ; $cd3d +	cp $ff +	jr z, .asm_706cd +	ld hl, $c104 +	ld a, [de] +	inc de +	ld [hli], a +	inc hl +	ld a, [de] +	inc de +	ld [hl], a +.asm_706cd +	ld a, [$cd3e] +	dec a +	ld [$cd3e], a +	jr nz, Func_706ae +	ret + +Func_706d7: ; 706d7 (1c:46d7) +	ld de, BirdSprite ; $4d80 +	ld hl, $8000 +	ld bc, (BANK(BirdSprite) << 8) + $0c +	call CopyVideoData +	ld de, BirdSprite + $c0 ; $4e40 ; moving amination sprite +	ld hl, $8800 +	ld bc, (BANK(BirdSprite) << 8) + $0c +	jp CopyVideoData + +Func_706ef: ; 706ef (1c:46ef) +	ld a, [$c102] +	ld [$cd50], a +	ld a, [$c104] +	ld [$cd4f], a +	ld hl, PlayerSpinningFacingOrder ; $4713 +	ld de, $cd48 +	ld bc, $4 +	call CopyData +	ld a, [$c102] +	ld hl, $cd48 +.asm_7070d +	cp [hl] +	inc hl +	jr nz, .asm_7070d +	dec hl +	ret + +PlayerSpinningFacingOrder: ; 70713 (1c:4713) +; The order of the direction the player's sprite is facing when teleporting +; away. Creates a spinning effect. +	db $00, $08, $04, $0C ; down, left, up, right + +Func_70717: ; 70717 (1c:4717) +	ld a, [hl] +	ld [$c102], a +	push hl +	ld hl, $cd48 +	ld de, $cd47 +	ld bc, $4 +	call CopyData +	ld a, [$cd47] +	ld [$cd4b], a +	pop hl +	ret + +Func_70730: ; 70730 (1c:4730) +	call Func_70717 +	ld a, [wWhichTrade] ; $cd3d +	ld c, a +	and $3 +	jr nz, .asm_70743 +	ld a, [$cd40] +	cp $ff +	call nz, PlaySound +.asm_70743 +	ld a, [$cd3e] +	add c +	ld [wWhichTrade], a ; $cd3d +	ld c, a +	ld a, [$cd3f] +	cp c +	ret z +	call DelayFrames +	jr Func_70730 + +Func_70755: ; 70755 (1c:4755) +	call Func_70717 +	ld a, [wWhichTrade] ; $cd3d +	ld c, a +	ld a, [$c104] +	add c +	ld [$c104], a +	ld c, a +	ld a, [$cd3e] +	cp c +	ret z +	ld a, [$cd3f] +	ld c, a +	call DelayFrames +	jr Func_70755 + +Func_70772: ; 70772 (1c:4772) +	ld a, [$cd4f] +	ld [$c104], a +	ld a, [$cd50] +	ld [$c102], a +	ret + +Func_7077f: ; 7077f (1c:477f) +	ld a, [$cf1b] +	xor $1 +	inc a +	inc a +	ret + +Func_70787: ; 70787 (1c:4787) +	ld b, 0 +	ld hl, DataTable_707a9 ; $47a9 +	ld a, [W_CURMAPTILESET] ; $d367 +	ld c, a +.asm_70790 +	ld a, [hli] +	cp $ff +	jr z, .asm_707a4 +	cp c +	jr nz, .asm_7079e +	FuncCoord 8, 9 ; $c45c +	ld a, [Coord] +	cp [hl] +	jr z, .asm_707a2 +.asm_7079e +	inc hl +	inc hl +	jr .asm_70790 +.asm_707a2 +	inc hl +	ld b, [hl] +.asm_707a4 +	ld a, b +	ld [$cd5b], a +	ret + +; format: db tileset id, tile id, value to be put in $cd5b +DataTable_707a9: ; 707a9 (1c:47a9) +	db FACILITY, $20, 1 ; warp pad +	db FACILITY, $11, 2 ; hole +	db CAVERN,   $22, 2 ; hole +	db INTERIOR, $55, 1 ; warp pad +	db $FF + +Func_707b6: ; 707b6 (1c:47b6) +	ld c, $a +	call DelayFrames +	ld hl, $d736 +	set 6, [hl] +	ld de, RedSprite ; $4180 +	ld hl, $8000 +	ld bc, (BANK(RedSprite) << 8) + $0c +	call CopyVideoData +	ld a, $4 +	ld hl, RedFishingTiles ; $4866 +	call Func_71771 +	ld a, [$c102] +	ld c, a +	ld b, $0 +	ld hl, FishingRodGfxProperties ; $4856 +	add hl, bc +	ld de, $c39c +	ld bc, $4 +	call CopyData +	ld c, $64 +	call DelayFrames +	ld a, [wWhichTrade] ; $cd3d +	and a +	ld hl, NoNibbleText +	jr z, .asm_70836 +	cp $2 +	ld hl, NothingHereText +	jr z, .asm_70836 +	ld b, $a +.asm_707fe +	ld hl, $c104 +	call Func_70842 +	ld hl, $c39c +	call Func_70842 +	call Delay3 +	dec b +	jr nz, .asm_707fe +	ld a, [$c102] +	cp $4 +	jr nz, .asm_7081c +	ld a, $a0 +	ld [$c39c], a +.asm_7081c +	ld hl, $cd4f +	xor a +	ld [hli], a +	ld [hl], a +	ld a, $4c +	call Predef ; indirect jump to PrintEmotionBubble (17c47 (5:7c47)) +	ld a, [$c102] +	cp $4 +	jr nz, .asm_70833 +	ld a, $44 +	ld [$c39c], a +.asm_70833 +	ld hl, ItsABiteText +.asm_70836 +	call PrintText +	ld hl, $d736 +	res 6, [hl] +	call LoadFontTilePatterns +	ret + +Func_70842: ; 70842 (1c:4842) +	ld a, [hl] +	xor $1 +	ld [hl], a +	ret + +NoNibbleText: ; 70847 (1c:4847) +	TX_FAR _NoNibbleText +	db "@" + +NothingHereText: ; 7084c (1c:484c) +	TX_FAR _NothingHereText +	db "@" + +ItsABiteText: ; 70851 (1c:4851) +	TX_FAR _ItsABiteText +	db "@" + +FishingRodGfxProperties: ; 70856 (1c:4856) +; specicies how the fishing rod should be drawn on the screen +; first byte = screen y coordinate +; second byte = screen x coordinate +; third byte = tile number +; fourth byte = sprite properties +	db $5B, $4C, $FD, $00 ; player facing down +	db $44, $4C, $FD, $00 ; player facing up +	db $50, $40, $FE, $00 ; player facing left +	db $50, $58, $FE, $20 ; player facing right ($20 means "horizontally flip the tile") + +RedFishingTiles: ; 70866 (1c:4866) +	dw RedFishingTilesFront +	db $02, $1E +	dw $8020 + +	dw RedFishingTilesBack +	db $02, $1E +	dw $8060 + +	dw RedFishingTilesSide +	db $02, $1E +	dw $80A0 + +	dw RedFishingRodTiles +	db $03, $1E +	dw $8FD0 + +_HandleMidJump: ; 7087e (1c:487e) +	ld a, [$d714] +	ld c, a +	inc a +	cp $10 +	jr nc, .asm_70895 +	ld [$d714], a +	ld b, $0 +	ld hl, PlayerJumpingYScreenCoords ; $48ba +	add hl, bc +	ld a, [hl] +	ld [$c104], a ; player's sprite y coordinate +	ret +.asm_70895 +	ld a, [wWalkCounter] ; $cfc5 +	cp $0 +	ret nz +	call UpdateSprites +	call Delay3 +	xor a +	ld [H_CURRENTPRESSEDBUTTONS], a +	ld [H_NEWLYPRESSEDBUTTONS], a +	ld [H_NEWLYRELEASEDBUTTONS], a +	ld [$d714], a +	ld hl, $d736 +	res 6, [hl] +	ld hl, $d730 +	res 7, [hl] +	xor a +	ld [wJoypadForbiddenButtonsMask], a +	ret + +PlayerJumpingYScreenCoords: ; 708ba (1c:48ba) +; Sequence of y screen coordinates for player's sprite when jumping over a ledge. +	db $38, $36, $34, $32, $31, $30, $30, $30, $31, $32, $33, $34, $36, $38, $3C, $3C diff --git a/engine/overworld/pokecenter.asm b/engine/overworld/pokecenter.asm new file mode 100755 index 00000000..45599498 --- /dev/null +++ b/engine/overworld/pokecenter.asm @@ -0,0 +1,68 @@ +DisplayPokemonCenterDialogue_: ; 6fe6 (1:6fe6) +	call SaveScreenTilesToBuffer1 ; save screen +	ld hl, PokemonCenterWelcomeText +	call PrintText +	ld hl, $d72e +	bit 2, [hl] +	set 1, [hl] +	set 2, [hl] +	jr nz, .skipShallWeHealYourPokemon +	ld hl, ShallWeHealYourPokemonText +	call PrintText +.skipShallWeHealYourPokemon +	call YesNoChoicePokeCenter ; yes/no menu +	ld a, [wCurrentMenuItem] +	and a +	jr nz, .declinedHealing ; if the player chose No +	call SetLastBlackoutMap +	call LoadScreenTilesFromBuffer1 ; restore screen +	ld hl, NeedYourPokemonText +	call PrintText +	ld a, $18 +	ld [$c112], a ; make the nurse turn to face the machine +	call Delay3 +	PREDEF HealPartyPredef +	callba AnimateHealingMachine ; do the healing machine animation +	xor a +	ld [wMusicHeaderPointer], a +	ld a, [$c0f0] +	ld [$c0ef], a +	ld a, [$d35b] +	ld [$cfca], a +	ld [$c0ee], a +	call PlaySound +	ld hl, PokemonFightingFitText +	call PrintText +	ld a, $14 +	ld [$c112], a ; make the nurse bow +	ld c, a +	call DelayFrames +	jr .done +.declinedHealing +	call LoadScreenTilesFromBuffer1 ; restore screen +.done +	ld hl, PokemonCenterFarewellText +	call PrintText +	jp UpdateSprites ; move sprites + +PokemonCenterWelcomeText: ; 705d (1:705d) +	TX_FAR _PokemonCenterWelcomeText +	db "@" + +ShallWeHealYourPokemonText: ; 7062 (1:7062) +	db $a +	TX_FAR _ShallWeHealYourPokemonText +	db "@" + +NeedYourPokemonText: ; 7068 (1:7068) +	TX_FAR _NeedYourPokemonText +	db "@" + +PokemonFightingFitText: ; 706d (1:706d) +	TX_FAR _PokemonFightingFitText +	db "@" + +PokemonCenterFarewellText: ; 7072 (1:7072) +	db $a +	TX_FAR _PokemonCenterFarewellText +	db "@" diff --git a/engine/overworld/pokemart.asm b/engine/overworld/pokemart.asm new file mode 100755 index 00000000..6e6f5ee2 --- /dev/null +++ b/engine/overworld/pokemart.asm @@ -0,0 +1,256 @@ +DisplayPokemartDialogue_: ; 6c20 (1:6c20) +	ld a,[wListScrollOffset] +	ld [$d07e],a +	call UpdateSprites ; move sprites +	xor a +	ld [$cf0a],a ; flag that is set if something is sold or bought +.loop +	xor a +	ld [wListScrollOffset],a +	ld [wCurrentMenuItem],a +	ld [$cc2f],a +	inc a +	ld [$cf93],a +	ld a,$13 +	ld [$d125],a +	call DisplayTextBoxID ; draw money text box +	ld a,$15 +	ld [$d125],a +	call DisplayTextBoxID ; do buy/sell/quit menu +	ld hl,$d128 ; pointer to this pokemart's inventory +	ld a,[hli] +	ld l,[hl] +	ld h,a ; hl = address of inventory +	ld a,[$d12e] +	cp a,$02 +	jp z,.done +	ld a,[$d12d] ; ID of the chosen menu item +	and a ; buying? +	jp z,.buyMenu +	dec a ; selling? +	jp z,.sellMenu +	dec a ; quitting? +	jp z,.done +.sellMenu +	xor a +	ld [$cf93],a +	ld a,$02 +	ld [$d11b],a +	callab Func_39bd5 +	ld a,[wNumBagItems] +	and a +	jp z,.bagEmpty +	ld hl,PokemonSellingGreetingText +	call PrintText +	call SaveScreenTilesToBuffer1 ; save screen +.sellMenuLoop +	call LoadScreenTilesFromBuffer1 ; restore saved screen +	ld a,$13 +	ld [$d125],a +	call DisplayTextBoxID ; draw money text box +	ld hl,wNumBagItems +	ld a,l +	ld [$cf8b],a +	ld a,h +	ld [$cf8c],a +	xor a +	ld [$cf93],a +	ld [wCurrentMenuItem],a +	ld a,ITEMLISTMENU +	ld [wListMenuID],a +	call DisplayListMenuID +	jp c,.returnToMainPokemartMenu ; if the player closed the menu +.confirmItemSale ; if the player is trying to sell a specific item +	call IsKeyItem ; check if item is unsellable +	ld a,[$d124] +	and a +	jr nz,.unsellableItem +	ld a,[$cf91] +	call IsItemHM +	jr c,.unsellableItem +	ld a,PRICEDITEMLISTMENU +	ld [wListMenuID],a +	ld [$ff8e],a ; halve prices when selling +	call DisplayChooseQuantityMenu +	inc a +	jr z,.sellMenuLoop ; if the player closed the choose quantity menu with the B button +	ld hl,PokemartTellSellPriceText +	ld bc,$0e01 +	call PrintText +	FuncCoord 14,7 +	ld hl,Coord +	ld bc,$080f +	ld a,$14 +	ld [$d125],a +	call DisplayTextBoxID ; yes/no menu +	ld a,[$d12e] +	cp a,$02 +	jr z,.sellMenuLoop ; if the player pressed the B button +	ld a,[$d12d] ; ID of the chosen menu item +	dec a +	jr z,.sellMenuLoop ; if the player chose No +.sellItem +	ld a,[$cf0a] ; flag that is set if something is sold or bought +	and a +	jr nz,.skipSettingFlag1 +	inc a +	ld [$cf0a],a +.skipSettingFlag1 +	call AddAmountSoldToMoney +	ld hl,wNumBagItems +	call RemoveItemFromInventory +	jp .sellMenuLoop +.unsellableItem +	ld hl,PokemartUnsellableItemText +	call PrintText +	jp .returnToMainPokemartMenu +.bagEmpty +	ld hl,PokemartItemBagEmptyText +	call PrintText +	call SaveScreenTilesToBuffer1 ; save screen +	jp .returnToMainPokemartMenu +.buyMenu +	ld a,$01 +	ld [$cf93],a +	ld a,$03 +	ld [$d11b],a +	callab Func_39bd5 +	ld hl,PokemartBuyingGreetingText +	call PrintText +	call SaveScreenTilesToBuffer1 ; save screen +.buyMenuLoop +	call LoadScreenTilesFromBuffer1 ; restore saved screen +	ld a,$13 +	ld [$d125],a +	call DisplayTextBoxID ; draw money text box +	ld hl,$cf7b +	ld a,l +	ld [$cf8b],a +	ld a,h +	ld [$cf8c],a +	xor a +	ld [wCurrentMenuItem],a +	inc a +	ld [$cf93],a +	inc a ; a = 2 (PRICEDITEMLISTMENU) +	ld [wListMenuID],a +	call DisplayListMenuID +	jr c,.returnToMainPokemartMenu ; if the player closed the menu +	ld a,$63 +	ld [$cf97],a +	xor a +	ld [$ff8e],a +	call DisplayChooseQuantityMenu +	inc a +	jr z,.buyMenuLoop ; if the player closed the choose quantity menu with the B button +	ld a,[$cf91] ; item ID +	ld [$d11e],a ; store item ID for GetItemName +	call GetItemName +	call CopyStringToCF4B ; copy name to $cf4b +	ld hl,PokemartTellBuyPriceText +	call PrintText +	FuncCoord 14,7 +	ld hl,Coord +	ld bc,$080f +	ld a,$14 +	ld [$d125],a +	call DisplayTextBoxID ; yes/no menu +	ld a,[$d12e] +	cp a,$02 +	jp z,.buyMenuLoop ; if the player pressed the B button +	ld a,[$d12d] ; ID of the chosen menu item +	dec a +	jr z,.buyMenuLoop ; if the player chose No +.buyItem +	call .isThereEnoughMoney +	jr c,.notEnoughMoney +	ld hl,wNumBagItems +	call AddItemToInventory +	jr nc,.bagFull +	call SubtractAmountPaidFromMoney +	ld a,[$cf0a] ; flag that is set if something is sold or bought +	and a +	jr nz,.skipSettingFlag2 +	ld a,$01 +	ld [$cf0a],a +.skipSettingFlag2 +	ld a,(SFX_02_5a - SFX_Headers_02) / 3 +	call PlaySoundWaitForCurrent ; play sound +	call WaitForSoundToFinish ; wait until sound is done playing +	ld hl,PokemartBoughtItemText +	call PrintText +	jp .buyMenuLoop +.returnToMainPokemartMenu +	call LoadScreenTilesFromBuffer1 ; restore save screen +	ld a,$13 +	ld [$d125],a +	call DisplayTextBoxID ; draw money text box +	ld hl,PokemartAnythingElseText +	call PrintText +	jp .loop +.isThereEnoughMoney +	ld de,wPlayerMoney +	ld hl,$ff9f ; item price +	ld c,3 ; length of money in bytes +	jp StringCmp +.notEnoughMoney +	ld hl,PokemartNotEnoughMoneyText +	call PrintText +	jr .returnToMainPokemartMenu +.bagFull +	ld hl,PokemartItemBagFullText +	call PrintText +	jr .returnToMainPokemartMenu +.done +	ld hl,PokemartThankYouText +	call PrintText +	ld a,$01 +	ld [$cfcb],a +	call UpdateSprites ; move sprites +	ld a,[$d07e] +	ld [wListScrollOffset],a +	ret + +PokemartBuyingGreetingText: ; 6e0c (1:6e0c) +	TX_FAR _PokemartBuyingGreetingText +	db "@" + +PokemartTellBuyPriceText: ; 6e11 (1:6e11) +	TX_FAR _PokemartTellBuyPriceText +	db "@" + +PokemartBoughtItemText: ; 6e16 (1:6e16) +	TX_FAR _PokemartBoughtItemText +	db "@" + +PokemartNotEnoughMoneyText: ; 6e1b (1:6e1b) +	TX_FAR _PokemartNotEnoughMoneyText +	db "@" + +PokemartItemBagFullText: ; 6e20 (1:6e20) +	TX_FAR _PokemartItemBagFullText +	db "@" + +PokemonSellingGreetingText: ; 6e25 (1:6e25) +	TX_FAR _PokemonSellingGreetingText +	db "@" + +PokemartTellSellPriceText: ; 6e2a (1:6e2a) +	TX_FAR _PokemartTellSellPriceText +	db "@" + +PokemartItemBagEmptyText: ; 6e2f (1:6e2f) +	TX_FAR _PokemartItemBagEmptyText +	db "@" + +PokemartUnsellableItemText: ; 6e34 (1:6e34) +	TX_FAR _PokemartUnsellableItemText +	db "@" + +PokemartThankYouText: ; 6e39 (1:6e39) +	TX_FAR _PokemartThankYouText +	db "@" + +PokemartAnythingElseText: ; 6e3e (1:6e3e) +	TX_FAR _PokemartAnythingElseText +	db "@" diff --git a/engine/overworld/saffron_guards.asm b/engine/overworld/saffron_guards.asm new file mode 100755 index 00000000..8e584a2d --- /dev/null +++ b/engine/overworld/saffron_guards.asm @@ -0,0 +1,18 @@ +RemoveGuardDrink: ; 5a59f (16:659f) +	ld hl, GuardDrinksList +.drinkLoop +	ld a, [hli] +	ld [$ffdb], a +	and a +	ret z +	push hl +	ld b, a +	call IsItemInBag +	pop hl +	jr z, .drinkLoop +	ld b, BANK(RemoveItemByID) +	ld hl, RemoveItemByID +	jp Bankswitch + +GuardDrinksList: ; 5a5b7 (16:65b7) +	db FRESH_WATER, SODA_POP, LEMONADE, $00 diff --git a/engine/overworld/ssanne.asm b/engine/overworld/ssanne.asm new file mode 100755 index 00000000..e8060810 --- /dev/null +++ b/engine/overworld/ssanne.asm @@ -0,0 +1,88 @@ +Func_79f54: ; 79f54 (1e:5f54) +	ld a, $1 +	ld [$cd50], a +	ld a, [$cfcb] +	push af +	ld a, $ff +	ld [$cfcb], a +	ld a, $e4 +	ld [rOBP1], a ; $ff49 +	call LoadSmokeTileFourTimes +	callba asm_f055 +	ld c, $8 +.asm_79f73 +	push bc +	call Func_79f92 +	ld bc, .asm_79f7e +	push bc +	ld c, $4 +	jp [hl] +.asm_79f7e +	ld a, [rOBP1] ; $ff49 +	xor $64 +	ld [rOBP1], a ; $ff49 +	call Delay3 +	pop bc +	dec c +	jr nz, .asm_79f73 +	pop af +	ld [$cfcb], a +	jp LoadPlayerSpriteGraphics + +Func_79f92: ; 79f92 (1e:5f92) +	ld a, [$c109] +	ld hl, PointerTable_79fb0 ; $5fb0 +	ld c, a +	ld b, $0 +	add hl, bc +	ld a, [hli] +	ld [$d08a], a +	ld a, [hli] +	ld e, a +	ld a, [hli] +	ld h, [hl] +	ld l, a +	push hl +	ld hl, $c390 +	ld d, $0 +	add hl, de +	ld e, l +	ld d, h +	pop hl +	ret + +PointerTable_79fb0: ; 79fb0 (1e:5fb0) +	db $FF,$00 +	dw Func_79350 + +	db $01,$00 +	dw Func_79350 + +	db $01,$01 +	dw Func_79337 + +	db $FF,$01 +	dw Func_79337 + +LoadSmokeTileFourTimes: ; 79fc0 (1e:5fc0) +	ld hl, $8fc0 +	ld c, $4 +.loop +	push bc +	push hl +	call LoadSmokeTile +	pop hl +	ld bc, $10 +	add hl, bc +	pop bc +	dec c +	jr nz, .loop +	ret + +LoadSmokeTile: ; 79fd4 (1e:5fd4) +	ld de, SSAnneSmokePuffTile ; $5fdd +	ld bc, (BANK(SSAnneSmokePuffTile) << 8) + $01 +	jp CopyVideoData + +SSAnneSmokePuffTile: ; 79fdd (1e:5fdd) +	INCBIN "gfx/ss_anne_smoke_puff.2bpp" diff --git a/engine/overworld/trainers.asm b/engine/overworld/trainers.asm new file mode 100755 index 00000000..8968332a --- /dev/null +++ b/engine/overworld/trainers.asm @@ -0,0 +1,347 @@ +Func_567f9: ; 567f9 (15:67f9) +	ld hl, wSpriteStateData1 +	ld de, $4 +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	call Func_56903 +	ld a, [hli] +	ld [$ffeb], a +	inc hl +	ld a, [hl] +	ld [$ffec], a +	ld de, $fe +	add hl, de +	ld a, [hli] +	ld [$ffed], a +	ld a, [hl] +	ld [$ffee], a +	ret + +Func_56819: ; 56819 (15:6819) +	ld hl, wSpriteStateData1 +	ld de, $0004 +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	call Func_56903 +	ld a, [hli] +	ld [$d130], a +	inc hl +	ld a, [hl] +	ld [$d131], a +	ld de, $00fe +	add hl, de +	ld a, [hli] +	ld [$d132], a +	ld a, [hl] +	ld [$d133], a +	ret + +Func_5683d: ; 5683d (15:683d) +	ld hl, wSpriteStateData1 +	ld de, $4 +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	call Func_56903 +	ld a, [$ffeb] +	ld [hli], a +	inc hl +	ld a, [$ffec] +	ld [hl], a +	ld de, $fe +	add hl, de +	ld a, [$ffed] +	ld [hli], a +	ld a, [$ffee] +	ld [hl], a +	ret + +Func_5685d: ; 5685d (15:685d) +	ld hl, wSpriteStateData1 +	ld de, $0004 +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	call Func_56903 +	ld a, [$d130] +	ld [hli], a +	inc hl +	ld a, [$d131] +	ld [hl], a +	ld de, $00fe +	add hl, de +	ld a, [$d132] +	ld [hli], a +	ld a, [$d133] +	ld [hl], a +	ret + +TrainerWalkUpToPlayer: ; 56881 (15:6881) +	ld a, [$cf13] +	swap a +	ld [wTrainerSpriteOffset], a ; $cd3d +	call ReadTrainerScreenPosition +	ld a, [wTrainerFacingDirection] +	and a +	jr z, .facingDown +	cp $4 +	jr z, .facingUp +	cp $8 +	jr z, .facingLeft +	jr .facingRight +.facingDown +	ld a, [wTrainerScreenY] +	ld b, a +	ld a, $3c           ; (fixed) player screen Y pos +	call CalcDifference +	cp $10              ; trainer is right above player +	ret z +	swap a +	dec a +	ld c, a             ; bc = steps yet to go to reach player +	xor a +	ld b, a           ; a = direction to go to +	jr .writeWalkScript +.facingUp +	ld a, [wTrainerScreenY] +	ld b, a +	ld a, $3c           ; (fixed) player screen Y pos +	call CalcDifference +	cp $10              ; trainer is right below player +	ret z +	swap a +	dec a +	ld c, a             ; bc = steps yet to go to reach player +	ld b, $0 +	ld a, $40           ; a = direction to go to +	jr .writeWalkScript +.facingRight +	ld a, [wTrainerScreenX] +	ld b, a +	ld a, $40           ; (fixed) player screen X pos +	call CalcDifference +	cp $10              ; trainer is directly left of player +	ret z +	swap a +	dec a +	ld c, a             ; bc = steps yet to go to reach player +	ld b, $0 +	ld a, $c0           ; a = direction to go to +	jr .writeWalkScript +.facingLeft +	ld a, [$cd41] +	ld b, a +	ld a, $40           ; (fixed) player screen X pos +	call CalcDifference +	cp $10              ; trainer is directly right of player +	ret z +	swap a +	dec a +	ld c, a             ; bc = steps yet to go to reach player +	ld b, $0 +	ld a, $80           ; a = direction to go to +.writeWalkScript +	ld hl, $cc97 +	ld de, $cc97 +	call FillMemory     ; write the necessary steps to reach player +	ld [hl], $ff        ; write end of list sentinel +	ld a, [$cf13] +	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c +	jp MoveSprite_ + +Func_56903: ; 56903 (15:6903) +	push de +	add hl, de +	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c +	swap a +	ld d, $0 +	ld e, a +	add hl, de +	pop de +	ret + +; tests if this trainer is in the right position to engage the player and do so if she is. +CheckEngagePlayer: ; 5690f (15:690f) +	push hl +	push de +	ld a, [wTrainerSpriteOffset] ; $cd3d +	add $2 +	ld d, $0 +	ld e, a +	ld hl, wSpriteStateData1 +	add hl, de +	ld a, [hl]             ; c1x2: sprite image index +	sub $ff +	jr nz, .spriteOnScreen ; test if sprite is on screen +	jp .noEngage +.spriteOnScreen +	ld a, [wTrainerSpriteOffset] ; $cd3d +	add $9 +	ld d, $0 +	ld e, a +	ld hl, wSpriteStateData1 +	add hl, de +	ld a, [hl]             ; c1x9: facing direction +	ld [$cd3f], a +	call ReadTrainerScreenPosition +	ld a, [$cd40]          ; sprite screen Y pos +	ld b, a +	ld a, $3c +	cp b +	jr z, .linedUpY +	ld a, [$cd41]          ; sprite screen X pos +	ld b, a +	ld a, $40 +	cp b +	jr z, .linedUpX +	xor a +	jp .noEngage +.linedUpY +	ld a, [$cd41]        ; sprite screen X pos +	ld b, a +	ld a, $40            ; (fixed) player X position +	call CalcDifference  ; calc distance +	jr z, .noEngage      ; exact same position as player +	call CheckSpriteCanSeePlayer +	jr c, .engage +	xor a +	jr .noEngage +.linedUpX +	ld a, [$cd40]        ; sprite screen Y pos +	ld b, a +	ld a, $3c            ; (fixed) player Y position +	call CalcDifference  ; calc distance +	jr z, .noEngage      ; exact same position as player +	call CheckSpriteCanSeePlayer +	jr c, .engage +	xor a +	jp .noEngage +.engage +	call CheckPlayerIsInFrontOfSprite +	ld a, [wTrainerSpriteOffset] ; $cd3d +	and a +	jr z, .noEngage +	ld hl, wFlags_0xcd60 +	set 0, [hl] +	call EngageMapTrainer +	ld a, $ff +.noEngage: ; 56988 (15:6988) +	ld [wTrainerSpriteOffset], a ; $cd3d +	pop de +	pop hl +	ret + +; reads trainer's Y position to $cd40 and X position to $cd41 +ReadTrainerScreenPosition: ; 5698e (15:698e) +	ld a, [wTrainerSpriteOffset] ; $cd3d +	add $4 +	ld d, $0 +	ld e, a +	ld hl, wSpriteStateData1 +	add hl, de +	ld a, [hl] +	ld [$cd40], a +	ld a, [wTrainerSpriteOffset] ; $cd3d +	add $6 +	ld d, $0 +	ld e, a +	ld hl, wSpriteStateData1 +	add hl, de +	ld a, [hl] +	ld [$cd41], a +	ret + +; checks if the sprite is properly lined up with the player with respect to the direction it's looking. Also checks the distance between player and sprite +; note that this does not necessarily mean the sprite is seeing the player, he could be behind it's back +; a: distance player to sprite +CheckSpriteCanSeePlayer: ; 569af (15:69af) +	ld b, a +	ld a, [wTrainerEngageDistance]  ; sprite line of sight (engage distance) +	cp b +	jr nc, .checkIfLinedUp +	jr .notInLine         ; player too far away +.checkIfLinedUp +	ld a, [$cd3f]         ; sprite facing direction +	cp $0                 ; down +	jr z, .checkXCoord +	cp $4                 ; up +	jr z, .checkXCoord +	cp $8                 ; left +	jr z, .checkYCoord +	cp $c                 ; right +	jr z, .checkYCoord +	jr .notInLine +.checkXCoord +	ld a, [$cd41]         ; sprite screen X position +	ld b, a +	cp $40 +	jr z, .inLine +	jr .notInLine +.checkYCoord +	ld a, [$cd40]         ; sprite screen Y position +	ld b, a +	cp $3c +	jr nz, .notInLine +.inLine +	scf +	ret +.notInLine +	and a +	ret + +; tests if the player is in front of the sprite (rather than behind it) +CheckPlayerIsInFrontOfSprite: ; 569e3 (15:69e3) +	ld a, [W_CURMAP] ; $d35e +	cp POWER_PLANT +	jp z, .engage       ; XXX not sure why bypass this for power plant (maybe to get voltorb fake items to work?) +	ld a, [wTrainerSpriteOffset] ; $cd3d +	add $4 +	ld d, $0 +	ld e, a +	ld hl, wSpriteStateData1 +	add hl, de +	ld a, [hl]          ; c1x4 (sprite screen Y pos) +	cp $fc +	jr nz, .notOnTopmostTile ; special case if sprite is on topmost tile (Y = $fc (-4)), make it come down a block +	ld a, $c +.notOnTopmostTile +	ld [$cd40], a +	ld a, [wTrainerSpriteOffset] ; $cd3d +	add $6 +	ld d, $0 +	ld e, a +	ld hl, wSpriteStateData1 +	add hl, de +	ld a, [hl]          ; c1x6 (sprite screen X pos) +	ld [$cd41], a +	ld a, [$cd3f]       ; facing direction +	cp $0 +	jr nz, .notFacingDown +	ld a, [$cd40]       ; sprite screen Y pos +	cp $3c +	jr c, .engage       ; sprite above player +	jr .noEngage        ; sprite below player +.notFacingDown +	cp $4 +	jr nz, .notFacingUp +	ld a, [$cd40]       ; sprite screen Y pos +	cp $3c +	jr nc, .engage      ; sprite below player +	jr .noEngage        ; sprite above player +.notFacingUp +	cp $8 +	jr nz, .notFacingLeft +	ld a, [$cd41]       ; sprite screen X pos +	cp $40 +	jr nc, .engage      ; sprite right of player +	jr .noEngage        ; sprite left of player +.notFacingLeft +	ld a, [$cd41]       ; sprite screen X pos +	cp $40 +	jr nc, .noEngage    ; sprite right of player +.engage +	ld a, $ff +	jr .done +.noEngage +	xor a +.done +	ld [wTrainerSpriteOffset], a ; $cd3d +	ret | 
