; 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:
    xor a
    ld [wUpdateSpritesEnabled], a

    ldh [$FFAE], a ; cam height    
    ldh [$FFAF], a ; cam height
    
    ld a, $90    ;SCREEN_HEIGHT_PIXELS
    ldh [$FFB0], a ; hWY

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

    call M_LoadMap

    ld a, $01
    ld [wPlayerDir], a

    ld a, $0A
    ld [wPlayerXTile], a
    ld a, $0F
    ld [wPlayerYTile], a

    ; fall through (probably)

M_OverworldLoop:

    ;ld a, [wPlayerYTile]
    ;cp 4
    ;jp nc, .noEvent
    ;
    ;ld hl, Txt_DebbieIntro
    ;call PrintTextVWF
    ;call YesNo
    ;jr nc, .choseNo
    ;ld hl, Txt_DebbieIntro2
    ;call PrintTextVWF
    ;jp .noEvent
;.choseNo
    ;jp SoftReset

;.noEvent

    ; get input
    ld a, [wPlayerFlags]
    bit 0, a
    jp nz, .walkPlayer
    call JoypadLowSensitivity
    ld a, [$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 .startWalk
.downPressed
    ld a, DIR_DOWN
    ld [wPlayerDir], a
    ld bc, $0001
    jr .startWalk
.leftPressed
    ld a, DIR_LEFT
    ld [wPlayerDir], a
    ld bc, $FF00
    jr .startWalk
.rightPressed
    ld a, DIR_RIGHT
    ld [wPlayerDir], a
    ld bc, $0100
.startWalk

    ;dec c

    ld a, [wPlayerXTile]
    add b
    ld h, a
    ld a, [wPlayerYTile]
    add c
    ld l, a

    	;add hl, bc		; darn 16 bit math

    call CheckCollForTile
    jp c, .bonk

    inc h
    call CheckCollForTile
    jp c, .bonk
    

    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, [wCameraYTile]
    ld d, a
    ld a, [wPlayerDir]
    dec a
    jr z, .redrawNorth
.redrawSouth
    ld a, d
    add $12
    call .redrawNSRejoin
    add 9    ; todo: conditionally
    jp .redrawHoriz
.redrawNorth
    ld a, d
    sub $04
    call .redrawNSRejoin
    sub 2
    jp .redrawHoriz
.redrawNSRejoin

    
    
    
    
		;.redrawDownYLoop
		;    add hl, bc
		;    dec a
		;    jr nz, .redrawDownYLoop
    
    
    ld a, [wCameraXTile]
    ld c, a
    add hl, bc
    
    

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

.redrawHoriz
    ld c, a	; c = (wCameraYTile/2)+9
   
.redrawEW 
.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 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 DelayFrame
    
    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


    
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


CalcCamX:
    ld a, [wPlayerXTile]
    sub $0A
    jr c, .zeroX
    ld [wCameraXTile], a
    ld b, a
    ld a, [$D367]	; map width
    sub 10
    cp b
    jr c, .maxX
    jr .doneCalcX
.zeroX
    xor a
    ld [wCameraXTile], a
    ld a, [wPlayerDir]
    cp $03
    jr nc, .skipOffs	; skips y calc?
    jr .doneCalcX
.maxX
    ld [wCameraXTile], a
    jr .skipOffs
.doneCalcX

    


    ld a, [wPlayerSubPos]
    ld d, a
    ld a, [wPlayerDir]
    cp 3
    jr z, .walkLeftOffs
.walkRightOffs
    ld a, [wCameraXTile]
    ld b, a
    ld a, [$D367]
    sub 10
    cp b
    jr z, .zeroOffs
    
    ld a, d
    ld [wCameraXOff], a
    jr .noWalk
.walkLeftOffs
    ld a, [wCameraXTile]
    or a
    jr z, .zeroOffs
    xor a
    sub d
    ld [wCameraXOff], a
    jr .noWalk


.zeroOffs
    xor a
    ld [wCameraXOff], a
.skipOffs
.noWalk
    jp ApplyCamPos

CalcCamY:
    ld a, [wPlayerYTile]
    sub $0A
    jr c, .zeroY
    ld [wCameraYTile], a
    ld b, a
    ld a, [$D368]	; map height
    sub 7
    cp b
    jr c, .maxY
    jr .doneY
.zeroY
    xor a
    ld [wCameraYTile], a
    ld a, [wPlayerDir]
    cp $03
    jr c, .skipOffs
    jr .doneY
.maxY
    ld [wCameraYTile], a
    jr .skipOffs
.doneY

    ld a, [wPlayerSubPos]
    ld d, a
    ld a, [wPlayerDir]
    dec a
    jr z, .walkUpOffs
.walkDownOffs
    ld a, [wCameraYTile]
    ld b, a
    ld a, [$D368]
    sub 7
    cp b
    jr z, .zeroOffs

    ld a, d
    ld [wCameraYOff], a
    jr .noWalk
.walkUpOffs
    ld a, [wCameraYTile]
    or a
    jr z, .zeroOffs
    xor a
    sub d
    ld [wCameraYOff], a
    jr .noWalk

.zeroOffs
    xor a
    ld [wCameraYOff], a
.skipOffs
.noWalk
    jp ApplyCamPos

CalcCamPos:
    ld a, [wPlayerDir]
    cp $03
    jp c, CalcCamY
    jp 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


    