; overworld.asm

DIR_UP equ $01
DIR_DOWN equ $02
DIR_LEFT equ $03
DIR_RIGHT equ $04

include "engine/overworld/maps.asm"
include "engine/overworld/sprites.asm"
    
M_OverworldInit:

    	;jp GameOver

    xor a
    ld [wUpdateSpritesEnabled], a
    ld [wMisTileAnimCounter], a

    ldh [$FFAE], a ; cam height    
    ldh [$FFAF], a ; cam height

    inc a
    ldh [$FFD7], a ; hTilesetType
    
    ld a, $90    ;SCREEN_HEIGHT_PIXELS
    ldh [$FFB0], a ; hWY

    ld a, $98
    ldh [$FFBD], a    ; H_AUTOBGTRANSFERDEST+1

    ld a, $01
    ld [wPlayerDir], a

    ;ld a, $0A
   ; ld [wPlayerXTile], a
    ;ld a, $0E
    ;ld [wPlayerYTile], a

    ld a, 200
    ld hl, wDebbieScreenX
    ld [hli], a
    ld [hl], a

    
    	;ld a, 01
    call DMAHijackingApply

    xor a
    call M_LoadMap

    

    

    ; fall through (probably)

M_OverworldLoop:

    call Joypad

    ; get input
    ld a, [wPlayerFlags]
    bit 0, a
    jp nz, .walkPlayer
    		;call JoypadLowSensitivity
    		;call Joypad
    ldh a, [$FFF5]    ;[$FFB4] ;hJoy5
    and %11110000 ; dont care about start, select, or b
    and a
    jp z, .noInput
    bit 7, a
    jr nz, .downPressed
    bit 6, a
    jr nz, .upPressed
    bit 5, a
    jr nz, .leftPressed
    	;bit 4, a
    jr .rightPressed	;nz, .rightPressed
    	;jr .noInput
    
.upPressed
    ld a, DIR_UP
    ld [wPlayerDir], a
    ld bc, $00FF
    jr .walkVertical
.downPressed
    ld a, DIR_DOWN
    ld [wPlayerDir], a
    ld bc, $0001
    jr .walkVertical
.leftPressed
    ld a, DIR_LEFT
    ld [wPlayerDir], a
    ld bc, $FF00
    jr .walkHorizontal
.rightPressed
    ld a, DIR_RIGHT
    ld [wPlayerDir], a
    ld bc, $0100

.walkHorizontal
    ld a, [wPlayerXTile]
    add b
    ld h, a
    ld a, [wPlayerYTile]
    add c
    ld l, a
ld a, [wPlayerDir]
    cp DIR_RIGHT
    jr nz, .facingEast
    inc h
.facingEast
    	;add hl, bc		; darn 16 bit math

    call CheckCollForTile
    jp c, .bonk

    dec l
    call CheckCollForTile
    jp c, .bonk
    jr .walkRejoin

.walkVertical
    ld a, [wPlayerXTile]
    add b
    ld h, a
    ld a, [wPlayerYTile]
    add c
    ld l, a
    ld a, [wPlayerDir]
    cp DIR_UP
    jr nz, .facingDown
    dec l
.facingDown
    	;add hl, bc		; darn 16 bit math

    call CheckCollForTile
    jp c, .bonk

    inc h
    call CheckCollForTile
    jp c, .bonk
    



.walkRejoin
    

    ld a, [wPlayerFlags]
    set 0, a
    ld [wPlayerFlags], a





    ; draw map row or column
    ld a, [wPlayerDir]
    cp $03
    jr nc, .redrawEW
.redrawNS
    	;ld a, [wCameraYTile]
    	;bit 0, a
    	;jr nz, .noRedraw

    ld a, [wCameraXTile]
    ld d, a
    or a
    rra
    ld b, a	; b = wCameraXTile/2

    ld a, [wCameraYTile]
    
    ld e, a
    
    ld a, [wPlayerDir]
    dec a
    jr z, .redrawNorth
    
.redrawSouth
    ld a, e
    add $12
    jp .redrawHoriz

.redrawNorth
    ld a, e
    sub $01
    
.redrawHoriz
    res 0, a
    ld e, a
    or a
    rra
    ld c, a	; c = (wCameraYTile/2)+9
    call RedrawRow
    jp .doneInput
   
.redrawEW 
    	;ld a, [wCameraXTile]
    	;bit 0, a
    	;jr nz, .noRedraw

    ld a, [wCameraYTile]
    	;dec a
    ld e, a
    or a
    rra
    ld c, a	; b = wCameraXTile/2

    ld a, [wCameraXTile]
    ld d, a

    ld a, [wPlayerDir]
    cp 3
    jr z, .redrawWest
    
.redrawEast
    ld a, d
    add $14
    jp .redrawVert

.redrawWest
    ld a, d
    sub $01
    
.redrawVert
    res 0, a
    ld d, a
    or a
    rra
    ld b, a	; c = (wCameraYTile/2)+9
    call RedrawCol

.noRedraw
    jr .doneInput






.bonk
    ld a, [wPlayerFlags]
    bit 2, a
    jr nz, .doneInput
    set 2, a
    ld [wPlayerFlags], a
    ld a, SFX_COLLISION
    call PlaySound
    jr .doneInput
    
.noInput
   
    ld a, [wPlayerFlags]
    res 2, a
    ld [wPlayerFlags], a
    	;xor a
    ld a, [wPlayerAnimTileCount]
    set 0, a
    ld [wPlayerAnimTileCount], a

.doneInput

    ; update voam (every frame?)
    	;ld a, [wPlayerYTile]
    	;ld [wOAMBuffer], a
    	;ld a, [wPlayerXTile]
    	;ld [wOAMBuffer+1], a

    
    call M_UpdateSprites

    ; warps

    ld a, [wPlayerFlags]
    bit 0, a
    jr nz, .skipEvent
    call DoEvents
    call DoWarps
    call DoSigns
.skipEvent

    ld a, [wMisTileAnimCounter]
    inc a
    ld [wMisTileAnimCounter], a
    srl a
    jr c, .skipTileAnim
    srl a
    jr c, .skipTileAnim
    srl a
    jr c, .skipTileAnim
    srl a
    jr c, .skipTileAnim
    and %00000111
    ld c,a
    ld b,0
    ld hl, FlameFrames
    add bc
    ld a,[hl]
    ld l,a
    ld h,0
    add hl,hl
    add hl,hl
    add hl,hl
    add hl,hl
    add hl,hl
    ld bc, FlameAnimGfx
    add bc

    ld bc, 32
    ld de, wMisTileAnimBuffer
    ld a,3
    call CopyDataFromSRAX
    
    ;ldh a, [$BA] ; hAutoBGTransferEnabled
    ;push af
    ;xor a ; disable auto-transfer while copying
    ;ldh [$BA], a ; hAutoBGTransferEnabled

    ;ld b,h
    ;ld c,l
    ld bc, wMisTileAnimBuffer
    ld hl,$FFC6 ;hVBlankCopySize
    ld a,2
    ld [hli],a
    ld a,c
    ld [hli],a
    ld a,b
    ld [hli],a
    ld bc, $8A50
    ld a,c
    ld [hli],a
    ld a,b
    ld [hl],a

.skipTileAnim

    ;push hl
    call DelayFrame
    ;pop hl

    ;pop af
    ;ldh [$BA], a ; hAutoBGTransferEnabled
    
    ;ld bc, 32
    ;ld de, $8A50
    ;ld a,3
    ;call CopyDataFromSRAX

    
    jp M_OverworldLoop

.walkPlayer ; a = wPlayerDir
    ld a, [wPlayerSubPos]
    cp 7
    jr z, .walkDone
    inc a
    ld [wPlayerSubPos], a
    jp .doneInput

.walkDone
    ld a, [wPlayerDir]
    dec a
    jr z, .finUp
    dec a
    jr z, .finDown
    dec a
    jr z, .finLeft
.finRight
    ld a, [wPlayerXTile]
    inc a
    ld [wPlayerXTile], a
    jr .walkDoneDone
.finUp
    ld a, [wPlayerYTile]
    dec a
    ld [wPlayerYTile], a
    jr .walkDoneDone
.finDown
    ld a, [wPlayerYTile]
    inc a
    ld [wPlayerYTile], a
    jr .walkDoneDone
.finLeft
    ld a, [wPlayerXTile]
    dec a
    ld [wPlayerXTile], a
.walkDoneDone
    ld a, [wPlayerAnimTileCount]
    inc a
    ld [wPlayerAnimTileCount], a
    xor a
    ld [wPlayerSubPos], a
    ld a, [wPlayerFlags]
    and %11111110
    ld [wPlayerFlags], a
    jp .doneInput

M_UpdateSprites:
    call CalcCamPos
    
    xor a
    ld hl, wDrawSpriteInd
    ld [hli], a		; index

    call CalcPlayerPos

    ld a, b		; pos
    ld [hli], a
    ld a, c
    ld [hli], a

    ld a, $22		; size
    ld [hli], a

    call CalcPlayerFrame

    ld [hli], a		; graphic
    ld a, [wPlayerFlags]
    ld [hl], a		; flags
    
    call DrawSprite_M	; call DrawSprite_M
			; ret

    ld a, $04
    ld hl, wDrawSpriteInd
    ld [hli], a		; index
    ld a, [wDebbieScreenX]		; pos
    ld [hli], a
    ld a, [wDebbieScreenY]
    ld [hli], a

    ld a, $23		; size
    ld [hli], a

    ld a, $18
    ld [hli], a
    ld a, [wDebbieFlags]
    ld [hl], a
    jp DrawSprite_M
    
    
    
MultBy8:
    push bc
    ld c, 7
MultByC_PopBC
    ld b, a
.loop
    add b
    dec c
    jr nz, .loop
    pop bc
    ret
MultBy6:
    push bc
    ld c, 5
    jr MultByC_PopBC
MultBy4:
    push bc
    ld c, 3
    jr MultByC_PopBC
    
CalcPlayerFrame:
    ld a, [wPlayerFlags]
    res 1, a
    ld [wPlayerFlags], a
    ld a, [wPlayerDir]
    dec a
    jr z, .up
    dec a
    jr z, .down
    dec a
    jr z, .left
    ld a, [wPlayerFlags]
    set 1, a
    ld [wPlayerFlags], a
.left
    ld a, 8
    jr .walkCheck
.up
    ld a, 4
    jr .walkCheck
.down
    xor a

.walkCheck
    ld b, a
    ld a, [wPlayerFlags]
    bit 0, a
    jr z, .notWalking
    ld a, [wPlayerAnimTileCount]
    bit 0, a
    jr z, .notWalking
    ld a, b
    add a, $0C
    ld b, a
    ld a, [wPlayerDir]
    cp 3
    jr nc, .notWalking
    ld a, [wPlayerAnimTileCount]
    bit 1, a
    jr z, .notWalking
    ld a, [wPlayerFlags]
    set 1, a
    ld [wPlayerFlags], a
.notWalking
    ld a, b
    ret

; b - max camera tile along axis
; d - player tile along axis
;nvm   ;;;;;; e - player offset along axis
; returns in de
CalcCamAxis:

    ld a, [wPlayerSubPos]
    ld e, a

    ld a, d
    sub $0A
    jr c, .zeroAxis
    ld d, a
    ld a, b
    cp d
    jr c, .maxAxis
    jr .doneGrid
.zeroAxis
    lb de, $00, $00
    xor a
    ret
.maxAxis
    ld d, a
    ld e, $00
    ret
.doneGrid
    ld a, [wPlayerDir]
    bit 0, a
    jr nz, .walkLowOffs

.walkHighOffs
    ld a, b
    cp d
    jr z, .zeroOffs
    ret		;jr .noWalk

.walkLowOffs
    xor a
    sub e
    ld e, a

    ld a, d
    or a
    ret nz	;jr nz, .noWalk

.zeroOffs
    ld e, 0
    ret


CalcCamX:
    ld a, [wPlayerXTile]
    ld d, a
    
    ld a, [wMisMapWidth]	; map width
    or a
    rla
    sub 20
    ld b, a

    call CalcCamAxis

    ld a, d
    ld [wCameraXTile], a
    ld a, e
    ld [wCameraXOff], a
    
    jr ApplyCamPos

CalcCamY:
    ld a, [wPlayerYTile]
    ld d, a
    
    ld a, [wMisMapHeight]	; map height
    or a
    rla
    sub $12
    ld b, a

    call CalcCamAxis

    ld a, d
    ld [wCameraYTile], a
    ld a, e
    ld [wCameraYOff], a
    
    jr ApplyCamPos

CalcCamPos:
    ld a, [wPlayerDir]
    cp $03
    jr c, CalcCamY
    jr CalcCamX

ApplyCamPos:
    ld a, [wCameraXTile]
    call MultBy8
    ld b, a
    ld a, [wCameraXOff]
    add b
    ldh [$FFAE], a	; hscx

    ld a, [wCameraYTile]
    call MultBy8
    ld b, a
    ld a, [wCameraYOff]
    add b
    ldh [$FFAF], a	; hscy
    ret

CalcPlayerPos:

    ld a, [wCameraXTile]
    ld b, a

    ld a, [wPlayerXTile]
    sub b
    call MultBy8
    ld b, a

    ld a, [wCameraXOff]
    ld d, a
    ld a, b
    sub d
    ld b, a

    ld a, [wCameraYTile]
    ld c, a

    ld a, [wPlayerYTile]
    sub c
    call MultBy8
    ld c, a

    ld a, [wCameraYOff]
    ld d, a
    ld a, c
    sub d
    ld c, a
    
    ld a, [wPlayerSubPos]
    ld d, a
    ld a, [wPlayerFlags]
    bit 0, a
    jr z, .noWalk
    ld a, [wPlayerDir]
    dec a
    jr z, .walkUpOffs
    dec a
    jr z, .walkDownOffs
    dec a
    jr z, .walkLeftOffs
.walkRightOffs
    ld a, b
    add d
    ld b, a
    jr .noWalk
.walkUpOffs
    ld a, c
    sub d
    ld c, a
    jr .noWalk
.walkDownOffs
    ld a, c
    add d
    ld c, a
    jr .noWalk
.walkLeftOffs
    ld a, b
    sub d
    ld b, a
.noWalk
    ret

CompareCoordsToPlayer:
;    ld a, [wPlayerFlags]
;    bit 0, a
;    jr nz, .fail
;    ld a, [hli]    ; a = warp x
;    cp $FF
;    jr z, .xPass
;    ld b, a
;    ld a, [wPlayerXTile]
;    cp b
;    jr nz, .fail
;.xPass
;    ld a, [hl]
;    cp $FF
;    jr z, .pass
;    ld b, a
;    ld a, [wPlayerYTile]
;    cp b
;    jr nz, .fail
;.pass
;    scf
;    ret
;.fail
;    or a
;    ret

    ld a, [wPlayerXTile]
    ld b, a
    ld a, [wPlayerYTile]
    ld c, a
    	; fall through to comparecoordstobc

CompareCoordsToBC:
    ld a, [hli]
    cp $FF
    jr z, .xPass
    cp b
    jr nz, .fail
.xPass
    ld a, [hl]
    cp $FF
    jr z, .pass
    cp c
    jr nz, .fail
.pass
    scf
    ret
.fail
    or a
    ret

DoEvents:
    ld hl, wMisEventDataPtr
    ld a, [hli]
    ld h, [hl]
    ld l, a
    
    ld a, [hli]    ; a = num events
    or a
    ret z          ; return if no events
    ld d, a

.eventLoop
    call CompareCoordsToPlayer
    jr c, .doEvent

.nextEvent
    ld bc, $0003
    add hl, bc
    dec d
    jr nz, .eventLoop
    ret
.doEvent
    inc hl
    ld a, [hli]
    ld h, [hl]
    ld l, a
    jp hl
    
DoWarps:
    ld hl, wMisWarpDataPtr
    ld a, [hli]
    ld h, [hl]
    ld l, a
    
    ld a, [hli]    ; a = num warps
    or a
    ret z          ; return if no warps
    ld d, a

.warpLoop
    call CompareCoordsToPlayer
    jr c, .warp

.nextWarp
    ;ld bc, $0002
    ;add hl, bc

    inc hl
    inc hl

    dec d
    jr nz, .warpLoop
    ret

.warp
    inc hl
    ld a, [hli]
    ld d, a
    ; ld a, [hli]
    ; ld b, a
    ; ld c, [hl]
    	;jp WarpToMap    ; fall through instead

; warp to map d at coordinates bc
WarpToMap:
    ; push bc
    push de
    ld a, SFX_GO_OUTSIDE
    call PlaySound
    call GBFadeOutToBlack
    pop de
    ; pop bc
    ; ld a, b
    ; ld [wPlayerXTile], a
    ; ld a, c
    ; ld [wPlayerYTile], a
    ld a, d
    cp $FF
    jp z, GameOver
    call M_LoadMap
    call M_UpdateSprites
    jp GBFadeInFromBlack

DoSigns:
    ldh a, [$FFB3]	;[$FFF5]    ;[$FFB4] ;hJoy5
    and %00000001 ; a
    ret z

    ld a, [wPlayerXTile]
    ld b, a
    ld a, [wPlayerYTile]
    ld c, a
    lb de, 2, -2

    ld a, [wPlayerDir]
    dec a
    jr z, .lookUp
    dec a
    jr z, .lookDown
    dec a
    jr z, .lookLeft
.lookRight
    ;ld a, d
    ;add b
    ;ld b, a

    inc b
    inc b
    jr .checkForSign
    
.lookUp
    ;ld a, e
    ;ld c, a

    dec c
    dec c
    jr .checkForSign

.lookDown
    ;ld a, d
    ;add c
    ;ld c, a

    inc c
    inc c
    jr .checkForSign

.lookLeft
    ;ld a, e
    ;add b
    ;ld b, a

    dec b
    dec b

.checkForSign

    ld hl, wMisSignDataPtr
    ld a, [hli]
    ld h, [hl]
    ld l, a
    
    ld a, [hli]    ; a = num signs
    or a
    ret z          ; return if no signs
    ld d, a

.signLoop
    call CompareCoordsToBC
    jr c, .doSign
.nextSign
    push bc
    ld bc, $0003
    add hl, bc
    pop bc
    dec d
    jr nz, .signLoop
    ret

.doSign
    inc hl
    ld a, [hli]
    ld h, [hl]
    ld l, a
    call PrintTextVWF

    
    ret


FlameFrames:
    db $00, $01, $02, $03, $02, $01, $00, $00

; 0 - 32
; 1 - 11
; 2 - 10
; 3 - 11
; 2 - 11
; 1 - 10
; 0 - 32
; ...
    

    