diff options
Diffstat (limited to 'engine/trainer_gear.asm')
-rw-r--r-- | engine/trainer_gear.asm | 726 |
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 |