mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-08-07 22:25:13 +00:00
369 lines
6.3 KiB
NASM
369 lines
6.3 KiB
NASM
// 2D rotattion of 8 sprites
|
|
.pc = $801 "Basic"
|
|
:BasicUpstart(main)
|
|
.pc = $80d "Program"
|
|
.label SPRITES_XPOS = $d000
|
|
.label SPRITES_YPOS = $d001
|
|
.label SPRITES_XMSB = $d010
|
|
.label RASTER = $d012
|
|
.label SPRITES_ENABLE = $d015
|
|
.label BORDERCOL = $d020
|
|
.label SPRITES_COLS = $d027
|
|
.const GREEN = 5
|
|
.const LIGHT_BLUE = $e
|
|
.label SCREEN = $400
|
|
// Sine and Cosine tables
|
|
// Angles: $00=0, $80=PI,$100=2*PI
|
|
// Sine/Cosine: signed fixed [-$7f,$7f]
|
|
.label COS = $2000
|
|
// A single sprite
|
|
.label SPRITE = $3000
|
|
.label SIN = COS+$40
|
|
// sin(x) = cos(x+PI/2)
|
|
main: {
|
|
sei
|
|
jsr init
|
|
jsr anim
|
|
rts
|
|
}
|
|
anim: {
|
|
.label _4 = 7
|
|
.label _6 = 9
|
|
.label _9 = 5
|
|
.label _10 = 5
|
|
.label _11 = 5
|
|
.label _12 = 5
|
|
.label x = $b
|
|
.label y = $c
|
|
.label xr = 7
|
|
.label yr = 9
|
|
.label xpos = 5
|
|
.label sprite_msb = 4
|
|
.label i = 3
|
|
.label angle = 2
|
|
lda #0
|
|
sta angle
|
|
b4:
|
|
lda RASTER
|
|
cmp #$ff
|
|
bne b4
|
|
inc BORDERCOL
|
|
lda #0
|
|
sta sprite_msb
|
|
sta i
|
|
b7:
|
|
ldy i
|
|
lda xs,y
|
|
sta x
|
|
// signed fixed[7.0]
|
|
lda ys,y
|
|
sta y
|
|
ldy angle
|
|
lda COS,y
|
|
jsr mulf8u_prepare
|
|
ldy x
|
|
jsr mulf8s_prepared
|
|
lda mulf8s_prepared.return
|
|
sta _4
|
|
lda mulf8s_prepared.return+1
|
|
sta _4+1
|
|
asl xr
|
|
rol xr+1
|
|
ldy y
|
|
jsr mulf8s_prepared
|
|
lda mulf8s_prepared.return
|
|
sta _6
|
|
lda mulf8s_prepared.return+1
|
|
sta _6+1
|
|
asl yr
|
|
rol yr+1
|
|
ldy angle
|
|
lda SIN,y
|
|
jsr mulf8u_prepare
|
|
ldy y
|
|
jsr mulf8s_prepared
|
|
asl _10
|
|
rol _10+1
|
|
lda xr
|
|
sec
|
|
sbc _10
|
|
sta xr
|
|
lda xr+1
|
|
sbc _10+1
|
|
sta xr+1
|
|
ldy x
|
|
jsr mulf8s_prepared
|
|
asl _12
|
|
rol _12+1
|
|
// signed fixed[8.8]
|
|
lda yr
|
|
clc
|
|
adc _12
|
|
sta yr
|
|
lda yr+1
|
|
adc _12+1
|
|
sta yr+1
|
|
lda xr+1
|
|
sta xpos
|
|
ora #$7f
|
|
bmi !+
|
|
lda #0
|
|
!:
|
|
sta xpos+1
|
|
lda xpos
|
|
clc
|
|
adc #$18+$95
|
|
sta xpos
|
|
lda xpos+1
|
|
adc #0
|
|
sta xpos+1
|
|
lsr sprite_msb
|
|
cmp #0
|
|
beq b8
|
|
lda #$80
|
|
ora sprite_msb
|
|
sta sprite_msb
|
|
b8:
|
|
lda yr+1
|
|
clc
|
|
adc #$59+$33
|
|
tay
|
|
lda i
|
|
asl
|
|
tax
|
|
lda xpos
|
|
sta SPRITES_XPOS,x
|
|
tya
|
|
sta SPRITES_YPOS,x
|
|
inc i
|
|
lda i
|
|
cmp #8
|
|
beq !b7+
|
|
jmp b7
|
|
!b7:
|
|
lda sprite_msb
|
|
sta SPRITES_XMSB
|
|
inc angle
|
|
lda #LIGHT_BLUE
|
|
sta BORDERCOL
|
|
jmp b4
|
|
}
|
|
// Calculate fast multiply with a prepared unsigned byte to a word result
|
|
// The prepared number is set by calling mulf8s_prepare(byte a)
|
|
mulf8s_prepared: {
|
|
.label memA = $fd
|
|
.label m = 5
|
|
.label return = 5
|
|
jsr mulf8u_prepared
|
|
lda memA
|
|
cmp #0
|
|
bpl b1
|
|
lda m+1
|
|
sty $ff
|
|
sec
|
|
sbc $ff
|
|
sta m+1
|
|
b1:
|
|
cpy #0
|
|
bpl b2
|
|
lda m+1
|
|
sec
|
|
sbc memA
|
|
sta m+1
|
|
b2:
|
|
rts
|
|
}
|
|
// Calculate fast multiply with a prepared unsigned byte to a word result
|
|
// The prepared number is set by calling mulf8u_prepare(byte a)
|
|
mulf8u_prepared: {
|
|
.label resL = $fe
|
|
.label memB = $ff
|
|
.label return = 5
|
|
sty memB
|
|
ldx memB
|
|
sec
|
|
sm1:
|
|
lda mulf_sqr1_lo,x
|
|
sm2:
|
|
sbc mulf_sqr2_lo,x
|
|
sta resL
|
|
sm3:
|
|
lda mulf_sqr1_hi,x
|
|
sm4:
|
|
sbc mulf_sqr2_hi,x
|
|
sta memB
|
|
lda resL
|
|
sta return
|
|
lda memB
|
|
sta return+1
|
|
rts
|
|
}
|
|
// Prepare for fast multiply with an unsigned byte to a word result
|
|
mulf8u_prepare: {
|
|
.label memA = $fd
|
|
sta memA
|
|
sta mulf8u_prepared.sm1+1
|
|
sta mulf8u_prepared.sm3+1
|
|
eor #$ff
|
|
sta mulf8u_prepared.sm2+1
|
|
sta mulf8u_prepared.sm4+1
|
|
rts
|
|
}
|
|
init: {
|
|
.label sprites_ptr = SCREEN+$3f8
|
|
jsr mulf_init
|
|
lda #$ff
|
|
sta SPRITES_ENABLE
|
|
ldx #0
|
|
b1:
|
|
lda #$ff&SPRITE/$40
|
|
sta sprites_ptr,x
|
|
lda #GREEN
|
|
sta SPRITES_COLS,x
|
|
inx
|
|
cpx #8
|
|
bne b1
|
|
rts
|
|
}
|
|
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
|
mulf_init: {
|
|
.label sqr1_hi = 7
|
|
.label sqr = 9
|
|
.label sqr1_lo = 5
|
|
.label x_2 = 2
|
|
.label sqr2_hi = 7
|
|
.label sqr2_lo = 5
|
|
.label dir = 2
|
|
lda #0
|
|
sta x_2
|
|
lda #<mulf_sqr1_hi+1
|
|
sta sqr1_hi
|
|
lda #>mulf_sqr1_hi+1
|
|
sta sqr1_hi+1
|
|
lda #<mulf_sqr1_lo+1
|
|
sta sqr1_lo
|
|
lda #>mulf_sqr1_lo+1
|
|
sta sqr1_lo+1
|
|
lda #<0
|
|
sta sqr
|
|
sta sqr+1
|
|
tax
|
|
b1:
|
|
inx
|
|
txa
|
|
and #1
|
|
cmp #0
|
|
bne b2
|
|
inc x_2
|
|
inc sqr
|
|
bne !+
|
|
inc sqr+1
|
|
!:
|
|
b2:
|
|
lda sqr
|
|
ldy #0
|
|
sta (sqr1_lo),y
|
|
lda sqr+1
|
|
sta (sqr1_hi),y
|
|
inc sqr1_hi
|
|
bne !+
|
|
inc sqr1_hi+1
|
|
!:
|
|
lda x_2
|
|
clc
|
|
adc sqr
|
|
sta sqr
|
|
lda #0
|
|
adc sqr+1
|
|
sta sqr+1
|
|
inc sqr1_lo
|
|
bne !+
|
|
inc sqr1_lo+1
|
|
!:
|
|
lda sqr1_lo+1
|
|
cmp #>mulf_sqr1_lo+$200
|
|
bne b1
|
|
lda sqr1_lo
|
|
cmp #<mulf_sqr1_lo+$200
|
|
bne b1
|
|
lda #$ff
|
|
sta dir
|
|
lda #<mulf_sqr2_hi
|
|
sta sqr2_hi
|
|
lda #>mulf_sqr2_hi
|
|
sta sqr2_hi+1
|
|
lda #<mulf_sqr2_lo
|
|
sta sqr2_lo
|
|
lda #>mulf_sqr2_lo
|
|
sta sqr2_lo+1
|
|
ldx #-1
|
|
b3:
|
|
lda mulf_sqr1_lo,x
|
|
ldy #0
|
|
sta (sqr2_lo),y
|
|
lda mulf_sqr1_hi,x
|
|
sta (sqr2_hi),y
|
|
inc sqr2_hi
|
|
bne !+
|
|
inc sqr2_hi+1
|
|
!:
|
|
txa
|
|
clc
|
|
adc dir
|
|
tax
|
|
cpx #0
|
|
bne b4
|
|
lda #1
|
|
sta dir
|
|
b4:
|
|
inc sqr2_lo
|
|
bne !+
|
|
inc sqr2_lo+1
|
|
!:
|
|
lda sqr2_lo+1
|
|
cmp #>mulf_sqr2_lo+$1ff
|
|
bne b3
|
|
lda sqr2_lo
|
|
cmp #<mulf_sqr2_lo+$1ff
|
|
bne b3
|
|
// Set the very last value g(511) = f(256)
|
|
lda mulf_sqr1_lo+$100
|
|
sta mulf_sqr2_lo+$1ff
|
|
lda mulf_sqr1_hi+$100
|
|
sta mulf_sqr2_hi+$1ff
|
|
rts
|
|
}
|
|
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
|
|
// <f(x) = <(( x * x )/4)
|
|
.align $100
|
|
mulf_sqr1_lo: .fill $200, 0
|
|
// >f(x) = >(( x * x )/4)
|
|
.align $100
|
|
mulf_sqr1_hi: .fill $200, 0
|
|
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
|
|
.align $100
|
|
mulf_sqr2_lo: .fill $200, 0
|
|
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
|
|
.align $100
|
|
mulf_sqr2_hi: .fill $200, 0
|
|
// Positions to rotate
|
|
xs: .byte -$46, -$46, -$46, 0, 0, $46, $46, $46
|
|
ys: .byte -$46, 0, $46, -$46, $46, -$46, 0, $46
|
|
.pc = COS "COS"
|
|
{
|
|
.var min = -$7fff
|
|
.var max = $7fff
|
|
.var ampl = max-min;
|
|
.for(var i=0;i<$140;i++) {
|
|
.var rad = i*2*PI/256;
|
|
.byte >round(min+(ampl/2)+(ampl/2)*cos(rad))
|
|
}
|
|
}
|
|
|
|
.pc = SPRITE "SPRITE"
|
|
.var pic = LoadPicture("balloon.png", List().add($000000, $ffffff))
|
|
.for (var y=0; y<21; y++)
|
|
.for (var x=0;x<3; x++)
|
|
.byte pic.getSinglecolorByte(x,y)
|
|
|