
.include "fb32x32.inc"

.include "globals.inc"

; observations:
; man in jump to man on ground ratio 1:3
; arm change with jump start
; jump first arms later

lossoman_mem   := $e400    ; must be page aligned
sintab_mem     := $e500    ; must be page aligned
armbit         := $10

.segment "PADATA"

theman1:
.incbin "gfx/theman1.bin"
theman2:
.incbin "gfx/theman2.bin"

.assert <* = 0, error, "not page aligned"

.segment "DATA"

text_deadline:
   .byte "LOSSO & XAYAX ^ DEADLINE",0
text_kaleido:
   .byte "THIS CAUSED A TRAFFIC JAM ON 5TH AVE IN 1976",0
text_kefrens:
   .byte "HEARD THIS ONE? A MAN WALKS INTO SOME BARS...",0

xayaxtext:
   .byte "XAYAX",0

in2025text:
   .byte "2025",0

myschedule_intro:
   .word $0000, lossoman_init
   .word $0001, lossoman_default
   .word $01ff, lossoman_cheer
   .word $0200, lossoman_default
   .word $021f, lossoman_jump
   .word $0220, lossoman_default
   .word $027f, lossoman_jumparms
   .word $0280, lossoman_default
   .word $02ff, love_deadline_setup
   .word $0300, love_deadline_scroll
   .word $043f, lossoman_stompdown
   .word $0440, lossoman_default
   .word $04ff, schedulenext

myschedule_kefrens:
   .word $0000, speechbubble_kefrens
   .word $0010, speechbubble_scroll
   .word $00ff, schedulenext

myschedule_kaleido:
   .word $0000, speechbubble_kaleido
   .word $0010, speechbubble_scroll
   .word $00ff, schedulenext

myschedule_rotate:
   .word $0000, rotate_init
   .word $0001, rotate_run
   .word $0080, rotate_run2
   .word $00ff, schedulenext


.segment "CODE"

lossoman_intro:
   lda   #<myschedule_intro
   ldx   #>myschedule_intro
   jmp   subschedule

lossoman_kefrens:
   lda   #<myschedule_kefrens
   ldx   #>myschedule_kefrens
   jmp   subschedule

lossoman_kaleido:
   lda   #<myschedule_kaleido
   ldx   #>myschedule_kaleido
   jmp   subschedule

lossoman_rotate:
   lda   #<myschedule_rotate
   ldx   #>myschedule_rotate
   jmp   subschedule


lossoman_cheer:
   lda   #$60
   .byte $2c
lossoman_stompdown:
   lda   #$a0  ; %10100000
   .byte $2c
lossoman_nomove:
   lda   #$00  ; %00000000
   .byte $2c
lossoman_jump:
   lda   #$80  ; %10000000
   .byte $2c
lossoman_arms:
   lda   #$40  ; %01000000
   .byte $2c
lossoman_jumparms:
   lda   #$c0  ; %11000000
   sta   lossoman_mode
   rts

lossoman_init:
   lda   #$00
   jsr   music             ; music starts with lossoman

   lda   #$80              ; enable music playback in NMI
   tsb   features

   lda   #$10              ; buildup
   sta   lossoman_mode
   ; slip through

lossoman_default:
   jsr   lossoman_draw
   sta   FB32X32_COPY
   rts

lossoman_prepare:
   jsr   lossoman_draw
   sta   FB32X32_COPYN
   rts

lossoman_draw:
   lda   lossoman_mode
   and   #$20              ; stompdown
   beq   @ninelines
   ; calculate number of blue lines
   lda   frmcnt
   lsr
   lsr
   lsr
   lsr
   and   #$0f
   eor   #$0f
   cmp   #$09
   bcc   @nofix
@ninelines:
   lda   #$09
@nofix:
   tay                     ; Y = number of blue lines
   bne   :+
   iny                     ; keep at least one line
:

   ; step 1: green blue background
   jsr   greenblue
;   int   PRHEX8

   sta   tmp8
   bit   lossoman_mode
   bpl   :+

   lda   frmcnt
   and   #$06
   eor   #$06
   cmp   #$01              ; carry is set for everything except last frame
   lda   tmp8
   .byte $24               ; ship sec
:
   sec
   sbc   #$10              ; start pos of man = start of blue - $10 (-1 if jump)
   sta   @manfromtop+1

   ; lossoman partial?
   lda   lossoman_mode
   and   #$10
   beq   @full

   lda   frmcnt+1
   lsr
   lda   frmcnt+0
   ror
   lsr
   lsr
   lsr
   and   #$1f
   eor   #$1f
   sec
   sbc   #$08
   bcc   @full
   cmp   #$10
   bcc   @part
   lda   #$10
   .byte $2c
@full:
   lda   #$00
@part:
   sta   tmp8

   lda   lossoman_mode
   cmp   #$60
   beq   @botharms
   ; lossoman moves arms?
   bit   lossoman_mode
   bvc   @noarms
   lda   frmcnt
   and   #$08
   beq   :+
   lda   #$80
   .byte $2c
:
   lda   #$40
   .byte $2c
@noarms:
   lda   #$00
   .byte $2c
@botharms:
   lda   #$c0
   ora   tmp8
   ; step 2: calculate the lossoman
   jsr   theman

   ; step 3: display the man
   stz   FB32X32_SRC+0
   lda   #>lossoman_mem
   sta   FB32X32_SRC+1

   lda   #$08
   sta   FB32X32_DEST_X
@manfromtop:
   lda   #$00
   sta   FB32X32_DEST_Y

   lda   #$0f              ; copy square 16x16 pixels
   sta   FB32X32_WIDTH
   sta   FB32X32_HEIGHT
   sta   FB32X32_STEP

   stz   FB32X32_TCOL
   lda   #$01
   rts

greenblue:
   ; IN:
   ; Y: number of blue lines from bottom
   ; OUT:
   ; A: startline of blue
   ldx   #$3f
:
   lda   #$a4
   sta   TMPBUFFER+$00,x
   lda   #$07
   sta   TMPBUFFER+$40,x
   dex
   bpl   :-

   lda   #>TMPBUFFER
   stz   FB32X32_SRC+0     ; green color
   sta   FB32X32_SRC+1

   lda   #$1f
   sta   FB32X32_WIDTH
   tya
   eor   #$ff
   sec
   adc   #$1f
   sta   FB32X32_HEIGHT
   stz   FB32X32_STEP

   stz   FB32X32_DEST_X
   stz   FB32X32_DEST_Y

   stz   FB32X32_COPYN

   inc
   cmp   #$20
   bcs   @skipblue

   ; FB32X32_DEST_X = $00
   ; FB32X32_WIDTH  = $1f
   ; FB32X32_STEP   = $00
   sta   FB32X32_DEST_Y
   dey
   sty   FB32X32_HEIGHT

   ldx   #$40              ; blue color
   stx   FB32X32_SRC+0

   stz   FB32X32_COPYN

@skipblue:
   rts

theman:
   ; clean up rotate parameters, A,Y arguments see below
   ldx   #$0f
:
   stz   rotable,x
   dex
   bpl   :-

themanrotate:
   ; IN:
   ; A: $80 left arm up, $40 right arm up, $10-$01 number of lines hidden
   ; X is not usable, see above
   ; OUT:
   ; lossoman_mem: graphics data 16x16
   sta   tmp8
   ; clear out tmp buffer
   ldx   #$00
:
   stz   TMPBUFFER,x
   inx
   bne   :-

   and   #$10
   bne   @done

   lda   #<theman1
   sta   vector1+0
   sta   vector2+0
   lda   #>theman1
   sta   vector1+1
   sta   vector2+1

   ; select arm to show
   bit   tmp8              ; lda only sets negative, not overflow
   bpl   :+
   inc   vector1+1         ; inc does not change overflow
:
   bvc   :+
   inc   vector2+1
:
   lda   tmp8
   and   #$0f
   eor   #$0f
   sta   tmp8

   ldy   #$00
@armsloop:
   tya
   and   #$08
   bne   :+
   lda   (vector1),y
   .byte $2c
:
   lda   (vector2),y
   sta   TMPBUFFER,y
   iny
   tya
   and   #$0f
   bne   @armsloop         ; make sure a full line is copied

   dec   tmp8
   bpl   @armsloop

@done:
   ; now compress / rotate
   lda   #>lossoman_mem
   jmp   imgcompress

love_deadline_setup:
   lda   #$07
   ldx   #$00
:
   sta   FRAMEBUFFER+$300,x
   dex
   bne   :-

   lda   #<text_deadline
   ldx   #>text_deadline
   ; A/X: start address of text
   jsr   scroll_settext

   lda   #$03              ; colortext
   ldx   #$07              ; colorbackground
   ldy   #$01              ; colorshadow
   jsr   scroll_setcolors

   lda   #<(FRAMEBUFFER+$300)
   ldx   #>(FRAMEBUFFER+$300)
   ldy   #$20
   jmp   scroll_setfb

love_deadline_scroll:
   jsr   scroll_update
   jsr   lossoman_prepare

   lda   #>(FRAMEBUFFER+$300)
   stz   FB32X32_SRC+0
   sta   FB32X32_SRC+1

   stz   FB32X32_DEST_X
   lda   #$18
   sta   FB32X32_DEST_Y

   lda   #$1f
   sta   FB32X32_WIDTH
   sta   FB32X32_STEP
   lda   #$07
   sta   FB32X32_HEIGHT
   stz   FB32X32_COPY
   rts

speechbubble_kefrens:
   lda   #<text_kefrens
   ldx   #>text_kefrens
   bra   speechbubble_setup
speechbubble_kaleido:
   lda   #<text_kaleido
   ldx   #>text_kaleido
speechbubble_setup:
   ; A/X: start address of text
   jsr   scroll_settext

   lda   #FB32X32_CMAP_RGBI2222
   sta   FB32X32_COLMAP

   lda   #$03              ; colortext
   ldx   #$a4              ; colorbackground
   ldy   #$01              ; colorshadow
   jsr   scroll_setcolors

   lda   #<(FRAMEBUFFER+$200)
   ldx   #>(FRAMEBUFFER+$200)
   ldy   #$18
   jsr   scroll_setfb

   ldy   #$04
   jsr   greenblue

   lda   #$a4
   ldx   #$00
:
   sta   FRAMEBUFFER+$000,x
   sta   FRAMEBUFFER+$100,x
   sta   FRAMEBUFFER+$200,x
   inx
   bne   :-
:
   lda   #$01
   sta   FRAMEBUFFER+$041,x
   sta   FRAMEBUFFER+$05e,x
   txa
   clc
   adc   #$20
   tax
   cmp   #$e0
   bcc   :-

   lda   #$01
   ldx   #$1a
:
   sta   FRAMEBUFFER+$002,x
   sta   FRAMEBUFFER+$142,x
   dex
   bne   :-

   sta   FRAMEBUFFER+$022
   sta   FRAMEBUFFER+$122
   sta   FRAMEBUFFER+$03d
   sta   FRAMEBUFFER+$13d
   sta   FRAMEBUFFER+$165
   sta   FRAMEBUFFER+$185
   sta   FRAMEBUFFER+$1a5
   sta   FRAMEBUFFER+$1c6
   sta   FRAMEBUFFER+$1c7

   lda   #>FRAMEBUFFER
   stz   FB32X32_SRC+0
   sta   FB32X32_SRC+1

   stz   FB32X32_DEST_X
   stz   FB32X32_DEST_Y

   lda   #$1f
   sta   FB32X32_WIDTH
   sta   FB32X32_STEP
   lda   #$0e
   sta   FB32X32_HEIGHT
   stz   FB32X32_COPYN

   lda   #$00
   jsr   theman
   stz   FB32X32_SRC+0
   lda   #>lossoman_mem
   sta   FB32X32_SRC+1

   lda   #$08
   sta   FB32X32_DEST_X
   lda   #$0c
   sta   FB32X32_DEST_Y

   lda   #$0f
   sta   FB32X32_WIDTH
   sta   FB32X32_HEIGHT
   sta   FB32X32_STEP

   stz   FB32X32_TCOL
   lda   #$01
   sta   FB32X32_COPY

   rts

speechbubble_scroll:
   jsr   scroll_update

   lda   #>(FRAMEBUFFER+$200)
   stz   FB32X32_SRC+0
   sta   FB32X32_SRC+1

   lda   #$04
   sta   FB32X32_DEST_X
   lda   #$02
   sta   FB32X32_DEST_Y

   lda   #$17
   sta   FB32X32_WIDTH
   sta   FB32X32_STEP
   lda   #$07
   sta   FB32X32_HEIGHT
   stz   FB32X32_COPY
   rts


lossoman_generate:
   ldx   #$00
:
   lda   theman1,x
   sta   lossoman_mem,x
   inx
   bne   :-
   rts


rotate_init:
   lda   #$10
   ldx   #>sintab_mem
   int   GENSINE

   lda   #<FRAMEBUFFER
   ldx   #>FRAMEBUFFER
   ldy   #$01
   int   FB32X32

   lda   #<(FRAMEBUFFER+$002)
   ldx   #>(FRAMEBUFFER+$002)
   ldy   #$c0
   jsr   text_setfb
   lda   #<xayaxtext
   ldx   #>xayaxtext
   jsr   text_draw

   lda   #<(FRAMEBUFFER+$328)
   ldx   #>(FRAMEBUFFER+$328)
   ldy   #$c0
   jsr   text_setfb
   lda   #<in2025text
   ldx   #>in2025text
   jsr   text_draw

   jmp   showfb

rotate_run:
   lda   frmcnt+0
   asl
   asl
   asl
   ;asl
   tax
   lda   sintab_mem,x
   and   #$f0
   eor   #$f0
   ldx   #$0f
:
   sta   rotable,x
   dex
   bpl   :-
   bra   rotate_exec

rotate_run2:
   ldx   #$00
:
   lda   rotable+$1,x
   sta   rotable+$0,x
   inx
   cpx   #$0f
   bcc   :-

   lda   frmcnt+0
   asl
   ;asl
   ;asl
   ;asl
   tax
   lda   sintab_mem,x
   and   #$f0
   eor   #$f0
   sta   rotable+$f
   ; fall through

rotate_exec:

   lda   #$00
   jsr   themanrotate

   lda   #>lossoman_mem
   stz   FB32X32_SRC+0
   sta   FB32X32_SRC+1

   lda   #$08
   sta   FB32X32_DEST_X
   sta   FB32X32_DEST_Y

   lda   #$0f
   sta   FB32X32_WIDTH
   sta   FB32X32_HEIGHT
   sta   FB32X32_STEP

   stz   FB32X32_COPY
   rts
