2020-09-20 21:49:36 +00:00
|
|
|
%import syslib
|
|
|
|
%import textio
|
2022-04-12 21:58:19 +00:00
|
|
|
%import math
|
2020-11-22 17:17:43 +00:00
|
|
|
%import test_stack
|
2019-01-17 01:25:52 +00:00
|
|
|
|
2020-11-24 23:18:07 +00:00
|
|
|
|
2019-07-29 21:11:13 +00:00
|
|
|
spritedata $2000 {
|
2019-01-17 01:25:52 +00:00
|
|
|
; this memory block contains the sprite data
|
|
|
|
; it must start on an address aligned to 64 bytes.
|
|
|
|
%option force_output ; make sure the data in this block appears in the resulting program
|
|
|
|
|
2019-04-15 23:19:51 +00:00
|
|
|
ubyte[] sprites = [
|
2019-01-17 01:25:52 +00:00
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00111100,%00000000,
|
|
|
|
%00000000,%11111111,%00000000,
|
|
|
|
%00000001,%11111101,%10000000,
|
|
|
|
%00000001,%11111111,%10000000,
|
|
|
|
%00000011,%11111111,%11000000,
|
|
|
|
%00000011,%11111111,%11000000,
|
|
|
|
%00000011,%11111111,%11000000,
|
|
|
|
%00000001,%11111111,%10000000,
|
|
|
|
%00000001,%11111111,%10000000,
|
|
|
|
%00000000,%11111111,%00000000,
|
|
|
|
%00000000,%00111100,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
%00000000,%00111110,%00000000,
|
|
|
|
%00000000,%11111111,%10000000,
|
|
|
|
%00000001,%11111110,%11000000,
|
|
|
|
%00000011,%11111111,%01100000,
|
|
|
|
%00000011,%11111111,%11100000,
|
|
|
|
%00000111,%11111111,%11110000,
|
|
|
|
%00000111,%11111111,%11110000,
|
|
|
|
%00000111,%11111111,%11110000,
|
|
|
|
%00000111,%11111111,%11110000,
|
|
|
|
%00000011,%11111111,%11100000,
|
|
|
|
%00000011,%11111111,%11100000,
|
|
|
|
%00000001,%11111111,%11000000,
|
|
|
|
%00000000,%11111111,%10000000,
|
|
|
|
%00000000,%00111110,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
%00000000,%00000000,%00000000,
|
|
|
|
|
|
|
|
0
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-07-29 21:11:13 +00:00
|
|
|
main {
|
2019-01-17 01:25:52 +00:00
|
|
|
|
|
|
|
const uword width = 255
|
|
|
|
const uword height = 200
|
|
|
|
|
|
|
|
; vertices
|
2020-08-22 17:00:03 +00:00
|
|
|
word[] xcoor = [ -100, -100, -100, -100, 100, 100, 100, 100 ]
|
|
|
|
word[] ycoor = [ -100, -100, 100, 100, -100, -100, 100, 100 ]
|
|
|
|
word[] zcoor = [ -100, 100, -100, 100, -100, 100, -100, 100 ]
|
2019-01-17 01:25:52 +00:00
|
|
|
|
|
|
|
; storage for rotated coordinates
|
|
|
|
word[len(xcoor)] rotatedx
|
|
|
|
word[len(ycoor)] rotatedy
|
|
|
|
word[len(zcoor)] rotatedz
|
|
|
|
|
|
|
|
|
|
|
|
sub start() {
|
|
|
|
|
|
|
|
c64.SPENA = 255 ; enable all sprites
|
|
|
|
|
|
|
|
uword anglex
|
|
|
|
uword angley
|
|
|
|
uword anglez
|
2020-07-25 14:25:02 +00:00
|
|
|
repeat {
|
2023-04-28 21:13:03 +00:00
|
|
|
cbm.TIME_LO=0
|
2019-01-17 01:25:52 +00:00
|
|
|
rotate_vertices(msb(anglex), msb(angley), msb(anglez))
|
|
|
|
position_sprites()
|
|
|
|
anglex-=500
|
|
|
|
angley+=217
|
|
|
|
anglez+=452
|
2020-08-27 16:10:22 +00:00
|
|
|
txt.plot(0,0)
|
|
|
|
txt.print("3d cube! (sprites) ")
|
2023-04-28 21:13:03 +00:00
|
|
|
txt.print_ub(cbm.TIME_LO)
|
2020-08-27 16:10:22 +00:00
|
|
|
txt.print(" jiffies/fr = ")
|
2023-04-28 21:13:03 +00:00
|
|
|
txt.print_ub(60/cbm.TIME_LO)
|
2020-08-27 16:10:22 +00:00
|
|
|
txt.print(" fps")
|
2020-11-22 17:17:43 +00:00
|
|
|
|
|
|
|
; test_stack.test()
|
2019-01-17 01:25:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub rotate_vertices(ubyte ax, ubyte ay, ubyte az) {
|
|
|
|
; rotate around origin (0,0,0)
|
|
|
|
|
|
|
|
; set up the 3d rotation matrix values
|
2022-04-12 21:58:19 +00:00
|
|
|
word wcosa = math.cos8(ax)
|
|
|
|
word wsina = math.sin8(ax)
|
|
|
|
word wcosb = math.cos8(ay)
|
|
|
|
word wsinb = math.sin8(ay)
|
|
|
|
word wcosc = math.cos8(az)
|
|
|
|
word wsinc = math.sin8(az)
|
2019-01-17 01:25:52 +00:00
|
|
|
|
|
|
|
word wcosa_sinb = wcosa*wsinb / 128
|
|
|
|
word wsina_sinb = wsina*wsinb / 128
|
|
|
|
|
|
|
|
word Axx = wcosa*wcosb / 128
|
|
|
|
word Axy = (wcosa_sinb*wsinc - wsina*wcosc) / 128
|
|
|
|
word Axz = (wcosa_sinb*wcosc + wsina*wsinc) / 128
|
|
|
|
word Ayx = wsina*wcosb / 128
|
|
|
|
word Ayy = (wsina_sinb*wsinc + wcosa*wcosc) / 128
|
|
|
|
word Ayz = (wsina_sinb*wcosc - wcosa*wsinc) / 128
|
|
|
|
word Azx = -wsinb
|
|
|
|
word Azy = wcosb*wsinc / 128
|
|
|
|
word Azz = wcosb*wcosc / 128
|
|
|
|
|
2020-09-04 22:17:58 +00:00
|
|
|
ubyte @zp i
|
2019-08-18 01:16:23 +00:00
|
|
|
for i in 0 to len(xcoor)-1 {
|
2019-01-17 01:25:52 +00:00
|
|
|
; don't normalize by dividing by 128, instead keep some precision for perspective calc later
|
|
|
|
rotatedx[i] = (Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i])
|
|
|
|
rotatedy[i] = (Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i])
|
|
|
|
rotatedz[i] = (Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub position_sprites() {
|
|
|
|
|
|
|
|
; set each of the 8 sprites to the correct vertex of the cube
|
2019-01-17 22:05:57 +00:00
|
|
|
|
|
|
|
; first sort vertices to sprite order so the back/front order is correct as well
|
2019-08-17 09:49:30 +00:00
|
|
|
; (simple bubble sort as it's only 8 items to sort)
|
2020-09-04 22:17:58 +00:00
|
|
|
ubyte @zp i
|
|
|
|
ubyte @zp i1
|
2020-03-11 19:47:42 +00:00
|
|
|
for i in 6 downto 0 {
|
2019-08-18 01:16:23 +00:00
|
|
|
for i1 in 0 to i {
|
2019-08-17 23:39:48 +00:00
|
|
|
ubyte i2 = i1+1
|
|
|
|
if(rotatedz[i1] > rotatedz[i2]) {
|
2022-06-06 14:01:11 +00:00
|
|
|
word @zp temp = rotatedx[i1]
|
|
|
|
rotatedx[i1] = rotatedx[i2]
|
|
|
|
rotatedx[i2] = temp
|
|
|
|
temp = rotatedy[i1]
|
|
|
|
rotatedy[i1] = rotatedy[i2]
|
|
|
|
rotatedy[i2] = temp
|
|
|
|
temp = rotatedz[i1]
|
|
|
|
rotatedz[i1] = rotatedz[i2]
|
|
|
|
rotatedz[i2] = temp
|
2019-08-17 23:39:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-01-17 01:25:52 +00:00
|
|
|
|
2019-04-15 23:19:51 +00:00
|
|
|
ubyte[] spritecolors = [1,1,7,15,12,11,9,9]
|
2019-01-18 00:33:54 +00:00
|
|
|
|
2019-08-18 01:16:23 +00:00
|
|
|
for i in 0 to 7 {
|
2020-09-04 22:17:58 +00:00
|
|
|
word @zp zc = rotatedz[i]
|
2019-01-17 01:25:52 +00:00
|
|
|
word persp = 300+zc/256
|
|
|
|
ubyte sx = rotatedx[i] / persp + width/2 as ubyte + 20
|
|
|
|
ubyte sy = rotatedy[i] / persp + height/2 as ubyte + 40
|
|
|
|
|
2020-08-22 19:08:29 +00:00
|
|
|
c64.SPXYW[i] = mkword(sy, sx)
|
2019-01-17 01:25:52 +00:00
|
|
|
|
|
|
|
if(zc < 30*128)
|
|
|
|
c64.SPRPTR[i] = $2000/64 +1 ; large ball
|
|
|
|
else
|
|
|
|
c64.SPRPTR[i] = $2000/64 ; small ball
|
|
|
|
|
2020-10-18 12:05:26 +00:00
|
|
|
c64.SPCOL[i] = spritecolors[(zc>>13) as ubyte + 4] ; further away=darker color
|
2019-01-17 01:25:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|