summaryrefslogtreecommitdiff
path: root/engine/trainer_gear.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/trainer_gear.asm')
-rw-r--r--engine/trainer_gear.asm726
1 files changed, 726 insertions, 0 deletions
diff --git a/engine/trainer_gear.asm b/engine/trainer_gear.asm
new file mode 100644
index 0000000..32e3a91
--- /dev/null
+++ b/engine/trainer_gear.asm
@@ -0,0 +1,726 @@
+INCLUDE "constants.asm"
+
+SECTION "engine/trainer_gear.asm@OpenTrainerGear", ROMX
+
+TRAINERGEAR_GFX_VERTICAL_PIPE EQU $00
+TRAINERGEAR_GFX_POINTER EQU $7c
+
+TRAINERGEAR_GFX_BORDER_TOPLEFT EQU $01
+TRAINERGEAR_GFX_BORDER_TOPRIGHT EQU $02
+TRAINERGEAR_GFX_BORDER_BOTTOMLEFT EQU $03
+TRAINERGEAR_GFX_BORDER_BOTTOMRIGHT EQU $04
+TRAINERGEAR_GFX_BORDER_TOP EQU $05
+TRAINERGEAR_GFX_BORDER_BOTTOM EQU $06
+TRAINERGEAR_GFX_BORDER_RIGHT EQU $07
+TRAINERGEAR_GFX_BORDER_LEFT EQU $08
+
+TRAINERGEAR_GFX_GRAYTILE EQU $0e
+TRAINERGEAR_GFX_BLANKTILE EQU $7f
+
+TRAINERGEAR_GFX_MAP_ICON EQU $10
+TRAINERGEAR_GFX_RADIO_ICON EQU $14
+TRAINERGEAR_GFX_PHONE_ICON EQU $18
+
+TRAINERGEAR_GFX_TUNE_BUTTON EQU $60
+TRAINERGEAR_GFX_TUNE_TEXT EQU $64
+TRAINERGEAR_GFX_RADIO_TOPHALF EQU $66
+TRAINERGEAR_GFX_RADIO_BOTTOMHALF EQU $67
+
+; Trainer Gear cards
+ const_def
+ const TRAINERGEARCARD_MAP
+ const TRAINERGEARCARD_RADIO
+ const TRAINERGEARCARD_PHONE
+NUM_TRAINERGEAR_CARDS EQU const_value
+
+; TrainerGear_Jumptable.Jumptable indices
+ const_def
+ const TRAINERGEARSTATE_INIT
+ const TRAINERGEARSTATE_JOYPAD
+ const TRAINERGEARSTATE_MAPINIT
+ const TRAINERGEARSTATE_MAPJOYPAD
+ const TRAINERGEARSTATE_RADIOINIT
+ const TRAINERGEARSTATE_RADIOJOYPAD
+ const TRAINERGEARSTATE_PHONEINIT
+ const TRAINERGEARSTATE_PHONEJOYPAD
+TRAINERGEAR_END_LOOP_F EQU 7
+
+; TrainerGear_RadioJumptable.Jumptable indices
+ const_def
+ const TRAINERGEAR_RADIOSTATE_WAITINPUT_1
+ const TRAINERGEAR_RADIOSTATE_ADVANCEDIAL
+ const TRAINERGEAR_RADIOSTATE_WAITINPUT_2
+ const TRAINERGEAR_RADIOSTATE_TURNBACKDIAL
+
+OpenTrainerGear:
+ ld hl, wce5f
+ ld a, [hl]
+ push af
+ set 4, [hl]
+ ldh a, [hMapAnims]
+ push af
+ xor a
+ ldh [hMapAnims], a
+ ldh a, [hJoypadSum]
+ push af
+
+ ld a, [wVramState]
+ push af
+ xor a
+ ld [wVramState], a
+ call TrainerGear_Init
+ call DelayFrame
+.loop
+ call TrainerGear_Loop
+ jr nc, .loop
+ pop af
+ ld [wVramState], a
+
+ pop af
+ ldh [hJoypadSum], a
+ pop af
+ ldh [hMapAnims], a
+ pop af
+ ld [wce5f], a
+ call ClearJoypad
+ ret
+
+TrainerGear_Init:
+ call ClearBGPalettes
+ call DisableLCD
+ call ClearSprites
+ ld b, SGB_TRAINER_GEAR
+ call GetSGBLayout
+
+ ld hl, TrainerGearGFX
+ ld de, vChars2
+ ld bc, $20 tiles
+ ld a, BANK(TrainerGearGFX)
+ call FarCopyData
+
+ call TrainerGear_InitTilemap
+ call TrainerGear_PlaceIcons
+
+ xor a
+ ldh [hSCY], a
+ ldh [hSCX], a
+ ld [wJumptableIndex], a
+ ld [wTrainerGearPointerPosition], a
+ ld a, $ff
+ ld [wTrainerGearCard], a
+ ld a, 7
+ ldh [hWX], a
+ ld a, 8
+ call UpdateSoundNTimes
+
+ ld a, LCDC_DEFAULT
+ ldh [rLCDC], a
+ call WaitBGMap
+ call SetPalettes
+ ld a, %11100000
+ ldh [rOBP1], a
+ ret
+
+TrainerGear_InitTilemap:
+ ld hl, wTileMap
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, TRAINERGEAR_GFX_BLANKTILE
+ call ByteFill
+ ld de, wTileMap
+ ld hl, TrainerGearTilemap
+ ld bc, TrainerGearTilemap.End - TrainerGearTilemap
+ call CopyBytes
+ ret
+
+TrainerGearTilemap:
+INCBIN "gfx/trainer_gear/trainer_gear.tilemap"
+.End:
+
+TrainerGear_PlaceIcons:
+ coord hl, 1, 0
+ ld a, TRAINERGEAR_GFX_MAP_ICON
+ call .PlaceIcon
+
+ coord hl, 4, 0
+ ld a, TRAINERGEAR_GFX_RADIO_ICON
+ call .PlaceIcon
+
+ coord hl, 7, 0
+ ld a, TRAINERGEAR_GFX_PHONE_ICON
+ call .PlaceIcon
+ ret
+
+.PlaceIcon:
+ ld [hli], a
+ inc a
+ ld [hld], a
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ inc a
+ ld [hli], a
+ inc a
+ ld [hld], a
+ ret
+
+TrainerGear_Loop:
+ call UpdateTime
+ call GetJoypadDebounced
+ ld a, [wJumptableIndex]
+ bit TRAINERGEAR_END_LOOP_F, a
+ jr nz, .done
+ call TrainerGear_Jumptable
+ callba EffectObjectJumpNoDelay
+ call TrainerGear_UpdateTime
+ call DelayFrame
+ and a
+ ret
+.done
+ callab InitEffectObject
+ call ClearSprites
+ xor a
+ ldh [hSCX], a
+ ldh [hSCY], a
+ scf
+ ret
+
+TrainerGear_UpdateTime:
+ coord hl, 11, 1
+ ld a, TRAINERGEAR_GFX_BLANKTILE
+ ld [hli], a
+ ld [hl], a
+
+ ld de, hRTCHours
+ coord hl, 11, 1
+ lb bc, 1, 2
+ call PrintNumber
+ inc hl
+
+ ld de, hRTCMinutes
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNumber
+ inc hl
+
+ ld de, hRTCSeconds
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNumber
+ ret
+
+TrainerGear_Jumptable:
+ jumptable .Jumptable, wJumptableIndex
+
+.Jumptable:
+ dw TrainerGear_InitPointerSprite
+ dw TrainerGear_Joypad
+ dw TrainerGear_Map
+ dw TrainerGear_MapJoypad
+ dw TrainerGear_Radio
+ dw TrainerGear_RadioJoypad
+ dw TrainerGear_Phone
+ dw TrainerGear_PhoneJoypad
+
+TrainerGear_Next:
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+TrainerGear_InitPointerSprite:
+ callab InitEffectObject
+ ld de, PointerGFX
+ ld hl, vChars0 tile TRAINERGEAR_GFX_POINTER
+ lb bc, BANK(PointerGFX), 4
+ call Request2bpp
+ ld a, SPRITE_ANIM_DICT_29
+ ld hl, wSpriteAnimDict
+ ld [hli], a
+ ld [hl], TRAINERGEAR_GFX_POINTER
+ depixel 4, 3, 4, 4
+ ld a, SPRITE_ANIM_INDEX_TRAINERGEAR_POINTER
+ call InitSpriteAnimStruct
+ call TrainerGear_Next
+ ret
+
+TrainerGear_Joypad:
+ ld hl, hJoySum
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .exit
+ ld a, [hl]
+ and A_BUTTON
+ ret z
+ call TrainerGear_DetermineView
+ ret
+.exit
+ ld hl, wJumptableIndex
+ set TRAINERGEAR_END_LOOP_F, [hl]
+ ret
+
+TrainerGear_DetermineView:
+; don't attempt to reload the view if we're already in it
+ ld a, [wTrainerGearPointerPosition]
+ ld hl, wTrainerGearCard
+ cp [hl]
+ ret z
+
+; load a new view by jumping to its init routine
+ ld [wTrainerGearCard], a
+ maskbits NUM_TRAINERGEAR_CARDS
+ ld e, a
+ ld d, 0
+ ld hl, .Views
+ add hl, de
+ ld a, [hl]
+ ld [wJumptableIndex], a
+ ret
+
+.Views:
+ db TRAINERGEARSTATE_MAPINIT
+ db TRAINERGEARSTATE_RADIOINIT
+ db TRAINERGEARSTATE_PHONEINIT
+ db TRAINERGEARSTATE_MAPINIT ; unused
+
+TrainerGear_Map:
+ call TrainerGear_Next
+ call TrainerGear_ClearView
+ call WaitForAutoBgMapTransfer
+ ld b, SGB_PACKPALS
+ call GetSGBLayout
+ ld de, TownMapGFX
+ ld hl, vTilesetEnd
+ lb bc, BANK(TownMapGFX), ((TownMapGFX.End - TownMapGFX) / LEN_2BPP_TILE - 1)
+ call Request2bpp
+ coord hl, 0, 3
+ call DecompTownMapTilemap
+ call WaitBGMap
+ call PlaceGoldInMap
+ ld hl, SPRITEANIMSTRUCT_YCOORD
+ add hl, bc
+ ld a, [hl]
+ add 3 * TILE_WIDTH ; shift sprite down past the Trainer Gear UI
+ ld [hl], a
+ ret
+
+TrainerGear_MapJoypad:
+ ld hl, hJoyDown
+ ld a, [hl]
+ and B_BUTTON
+ ret z
+ xor a
+ ld [wJumptableIndex], a
+ ret
+
+TrainerGear_Radio:
+ call TrainerGear_Next
+ call TrainerGear_ClearView
+ call WaitForAutoBgMapTransfer
+ ld b, SGB_TRAINER_CARD
+ call GetSGBLayout
+
+ ld de, RadioGFX
+ ld hl, vChars2 tile TRAINERGEAR_GFX_TUNE_BUTTON
+ lb bc, BANK(RadioGFX), 9
+ call Request2bpp
+ ld de, VerticalPipeGFX
+ ld hl, vChars0
+ lb bc, BANK(VerticalPipeGFX), 1
+ call Request2bpp
+
+ coord hl, 0, 3
+ ld bc, SCREEN_WIDTH * 9
+ ld a, TRAINERGEAR_GFX_GRAYTILE
+ call ByteFill
+
+ coord hl, 1, 8
+ lb bc, 4, 18
+ call TrainerGear_DrawBox
+ coord hl, 4, 3
+ lb bc, 6, 14
+ call TrainerGear_DrawBox
+ ld a, TRAINERGEAR_GFX_BORDER_TOP
+ coord hl, 0, 11
+ ld [hl], a
+ coord hl, 19, 11
+ ld [hl], a
+
+ coord hl, 2, 5
+ ld a, TRAINERGEAR_GFX_TUNE_BUTTON
+ ld [hli], a
+ inc a
+ ld [hld], a
+ inc a
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld [hli], a
+ inc a
+ ld [hld], a
+ coord hl, 2, 4
+ ld a, TRAINERGEAR_GFX_TUNE_TEXT
+ ld [hli], a
+ inc a
+ ld [hl], a
+
+ coord hl, 5, 5
+ ld bc, 12
+ ld a, TRAINERGEAR_GFX_RADIO_TOPHALF
+ call ByteFill
+ coord hl, 5, 6
+ ld bc, 12
+ ld a, TRAINERGEAR_GFX_RADIO_BOTTOMHALF
+ call ByteFill
+
+ ld hl, TrainerGear_RadioText
+ call PrintText
+
+ call WaitBGMap
+
+ depixel 9, 4, 4, 3
+ ld a, SPRITE_ANIM_INDEX_TRAINERGEAR_POINTER
+ call InitSpriteAnimStruct
+ ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID
+ add hl, bc
+ ld [hl], 0
+ ld hl, SPRITEANIMSTRUCT_TILE_ID
+ add hl, bc
+ ld [hl], TRAINERGEAR_GFX_POINTER
+ depixel 8, 6
+ ld a, SPRITE_ANIM_INDEX_RADIO_TUNING_KNOB
+ call InitSpriteAnimStruct
+ ld hl, SPRITEANIMSTRUCT_TILE_ID
+ add hl, bc
+ ld [hl], TRAINERGEAR_GFX_VERTICAL_PIPE
+ xor a
+ ld [wTrainerGearRadioIndex], a
+ ret
+
+TrainerGear_RadioJoypad:
+ ld hl, hJoyDown
+ ld a, [hl]
+ and B_BUTTON
+ ret z
+ xor a
+ ld [wJumptableIndex], a
+ ret
+
+TrainerGear_RadioJumptable:
+ ld hl, wTrainerGearRadioIndex
+ ld e, [hl]
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.Jumptable:
+ dw .WaitInput
+ dw .AdvanceDial
+ dw .WaitInput
+ dw .TurnBackDial
+
+.WaitInput:
+ ld hl, hJoyDown
+ ld a, [hl]
+ and A_BUTTON
+ ret z
+ ld hl, wTrainerGearRadioIndex
+ inc [hl]
+ ret
+
+.AdvanceDial:
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .advance_save_pos
+ call .GetRadioEvents
+ jr c, .advance_wait_input
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .reached_end
+
+.advance_save_pos
+ ld hl, -$40
+ jr .SaveCursorPosition
+
+.reached_end
+ ld a, TRAINERGEAR_RADIOSTATE_TURNBACKDIAL
+ ld [wTrainerGearRadioIndex], a
+ ret
+
+.advance_wait_input
+ call .advance_save_pos
+ xor a ; TRAINERGEAR_RADIOSTATE_WAITINPUT_1
+ ld [wTrainerGearRadioIndex], a
+ ret
+
+.TurnBackDial:
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr nz, .turnback_save_pos
+ call .GetRadioEvents
+ jr c, .turnback_wait_input
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld a, [hl]
+ cp $60
+ jr z, .reached_beginning
+.turnback_save_pos
+ ld hl, $40
+ jr .SaveCursorPosition
+.reached_beginning
+ ld a, TRAINERGEAR_RADIOSTATE_ADVANCEDIAL
+ ld [wTrainerGearRadioIndex], a
+ ret
+.turnback_wait_input
+ call .turnback_save_pos
+ ld a, TRAINERGEAR_RADIOSTATE_WAITINPUT_2
+ ld [wTrainerGearRadioIndex], a
+ ret
+
+.SaveCursorPosition:
+ push hl
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld d, [hl]
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld e, [hl]
+ pop hl
+ add hl, de
+ ld e, l
+ ld d, h
+ ld hl, SPRITEANIMSTRUCT_0C
+ add hl, bc
+ ld [hl], e
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld [hl], d
+ ret
+
+.GetRadioEvents:
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ push bc
+ ld c, [hl]
+ ld a, [wMapGroup]
+ ld e, a
+ ld d, 0
+ ld hl, TrainerGear_RadioAreas
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.find_matches
+; Finds an event corresponding to the radio cursor's X offset
+ ld a, [hl]
+ and a
+ jr z, .no_match
+ cp c
+ jr z, .found
+ ld de, 6
+ add hl, de
+ jr .find_matches
+
+.no_match
+; No associated event found, quit the routine
+ pop bc
+ and a
+ ret
+
+.found
+; Execute associated event with a parameter stored in e
+; Returns carry upon exiting event
+ ld de, .AfterEvent
+ push de
+ inc hl
+ ld e, [hl]
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.AfterEvent:
+ pop bc
+ scf
+ ret
+
+TrainerGear_RadioAreas:
+; one set of radio stations per map group
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+ dw TrainerGear_RadioStations_Music
+
+radio_station: MACRO
+ ; \1 = "frequency" (tuning knob's X position)
+ ; \2 = parameter (loaded onto E)
+ ; \3 = subroutine to call
+ ; \4 = unused
+ db \1, \2
+ dw \3, \4
+ENDM
+
+TrainerGear_RadioStations_Music:
+; list of radio stations associated with the map group
+ radio_station $10, MUSIC_ROUTE_1, .PlayMusic, .PlayMusic
+ radio_station $20, MUSIC_TRAINER_BATTLE, .PlayMusic, .PlayMusic
+ radio_station $40, MUSIC_VIRIDIAN_CITY, .PlayMusic, .PlayMusic
+ radio_station $48, MUSIC_BICYCLE, .PlayMusic, .PlayMusic
+ db 0 ; list terminator
+
+.PlayMusic:
+ ld d, 0
+ call PlayMusic
+ ret
+
+TrainerGear_Phone:
+ call TrainerGear_Next
+ call TrainerGear_ClearView
+ call WaitForAutoBgMapTransfer
+ ld b, SGB_TRAINER_GEAR
+ call GetSGBLayout
+ call LoadFontExtra
+ ld de, .OutOfRangeText
+ coord hl, 7, 7
+ call PlaceString
+ ld hl, .DarnText
+ call PrintText
+ call WaitBGMap
+ ret
+
+.OutOfRangeText:
+ db "けんがい@"
+
+.DarnText:
+ text "ちぇっ⋯⋯⋯⋯"
+ done
+
+TrainerGear_PhoneJoypad:
+ ld hl, hJoyDown
+ ld a, [hl]
+ and B_BUTTON
+ ret z
+ xor a
+ ld [wJumptableIndex], a
+ ret
+
+TrainerGear_ClearView:
+ callab InitEffectObject
+ call ClearSprites
+ call WaitForAutoBgMapTransfer
+ coord hl, 0, 3
+ ld bc, SCREEN_WIDTH * 15
+ ld a, TRAINERGEAR_GFX_BLANKTILE
+ call ByteFill
+ call WaitBGMap
+ call WaitBGMap
+ ret
+
+; called from sprite animation routine
+
+AnimateTrainerGearModeIndicatorPointer::
+ ld hl, wTrainerGearPointerPosition
+ ld de, hJoySum
+ ld a, [de]
+ and D_LEFT
+ jr nz, .move_left
+ ld a, [de]
+ and D_RIGHT
+ jr nz, .move_right
+ jr .update_position
+.move_left
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ jr .update_position
+.move_right
+ ld a, [hl]
+ cp NUM_TRAINERGEAR_CARDS - 1
+ ret nc
+ inc [hl]
+.update_position
+ ld e, [hl]
+ ld d, 0
+ ld hl, .CursorPositions
+ add hl, de
+ ld a, [hl]
+ ld hl, SPRITEANIMSTRUCT_XOFFSET
+ add hl, bc
+ ld [hl], a
+ ret
+
+.CursorPositions:
+ db $00, $18, $30, $00
+
+TrainerGear_DrawBox:
+ dec c
+ dec c
+ dec b
+ dec b
+ ld de, SCREEN_WIDTH
+ push bc
+ push hl
+ ld a, TRAINERGEAR_GFX_BORDER_TOPLEFT
+ ld [hli], a
+ ld a, TRAINERGEAR_GFX_BORDER_TOP
+.draw_separator
+ ld [hli], a
+ dec c
+ jr nz, .draw_separator
+ ld a, TRAINERGEAR_GFX_BORDER_TOPRIGHT
+ ld [hl], a
+ pop hl
+ pop bc
+ add hl, de
+.draw_row
+ push bc
+ push hl
+ ld a, TRAINERGEAR_GFX_BORDER_LEFT
+ ld [hli], a
+ ld a, TRAINERGEAR_GFX_BLANKTILE
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ld a, TRAINERGEAR_GFX_BORDER_RIGHT
+ ld [hli], a
+ pop hl
+ add hl, de
+ pop bc
+ dec b
+ jr nz, .draw_row
+ ld a, TRAINERGEAR_GFX_BORDER_BOTTOMLEFT
+ ld [hli], a
+ ld a, TRAINERGEAR_GFX_BORDER_BOTTOM
+.draw_bottom
+ ld [hli], a
+ dec c
+ jr nz, .draw_bottom
+ ld a, TRAINERGEAR_GFX_BORDER_BOTTOMRIGHT
+ ld [hli], a
+ ret
+
+SECTION "engine/trainer_gear.asm@TrainerGear_RadioText", ROMX
+
+TrainerGear_RadioText:
+ text "エーボタンで チューニング!"
+ done