From cca94d41bced0ab3ddcfcdb40dad79ee7cb7595d Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 5 Jan 2019 18:34:28 +0100 Subject: [PATCH] cube3d non float --- compiler/examples/cube3d-c64.p8 | 134 ++++++++++------ compiler/examples/test.p8 | 148 +++++++++++++++++- .../src/prog8/compiler/target/c64/AsmGen.kt | 48 +++--- 3 files changed, 254 insertions(+), 76 deletions(-) diff --git a/compiler/examples/cube3d-c64.p8 b/compiler/examples/cube3d-c64.p8 index 6c4f442ff..0039660a9 100644 --- a/compiler/examples/cube3d-c64.p8 +++ b/compiler/examples/cube3d-c64.p8 @@ -5,6 +5,7 @@ const uword width = 40 const uword height = 25 + const float height_f = height ; vertices byte[8] xcoor = [ -50, -50, -50, -50, 50, 50, 50, 50 ] @@ -12,9 +13,9 @@ byte[8] zcoor = [ -50, 50, -50, 50, -50, 50, -50, 50 ] ; storage for rotated coordinates - float[len(xcoor)] rotatedx=0.0 - float[len(ycoor)] rotatedy=0.0 - float[len(zcoor)] rotatedz=-1.0 + word[len(xcoor)] rotatedx=0 + word[len(ycoor)] rotatedy=0 + word[len(zcoor)] rotatedz=-1 sub start() { uword anglex @@ -34,63 +35,108 @@ ; rotate around origin (0,0,0) ; set up the 3d rotation matrix values - float cosa = cos8(ax) as float / 128.0 - float sina = sin8(ax) as float / 128.0 - float cosb = cos8(ay) as float / 128.0 - float sinb = sin8(ay) as float / 128.0 - float cosc = cos8(az) as float / 128.0 - float sinc = sin8(az) as float / 128.0 + word wcosa = cos8(ax) as word + word wsina = sin8(ax) as word + word wcosb = cos8(ay) as word + word wsinb = sin8(ay) as word + word wcosc = cos8(az) as word + word wsinc = sin8(az) as word - float cosa_sinb = cosa*sinb - float sina_sinb = sina*sinb - float Axx = cosa*cosb - float Axy = cosa_sinb*sinc - sina*cosc - float Axz = cosa_sinb*cosc + sina*sinc - float Ayx = sina*cosb - float Ayy = sina_sinb*sinc + cosa*cosc - float Ayz = sina_sinb*cosc - cosa*sinc - float Azx = -sinb - float Azy = cosb*sinc - float Azz = cosb*cosc + word wcosa_sinb = wcosa*wsinb + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) ; / 128 + word wsina_sinb = wsina*wsinb + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) ; / 128 + + float cosa_sinb = wcosa_sinb as float / 128.0 + float sina_sinb = wsina_sinb as float / 128.0 + float Axx = wcosa*wcosb as float / 16384.0 + float Axy = cosa_sinb*(wsinc as float / 128.0) - (wsina*wcosc as float / 16384.0) + float Axz = cosa_sinb*(wcosc as float / 128.0) + (wsina*wsinc as float / 16384.0) + float Ayx = wsina*wcosb as float / 16384.0 + float Ayy = sina_sinb*(wsinc as float / 128.0) + (wcosa*wcosc as float / 16384.0) + float Ayz = sina_sinb*(wcosc as float / 128.0) - (wcosa*wsinc as float / 16384.0) + float Azx = -wsinb as float / 128.0 + float Azy = wcosb*wsinc as float / 16384.0 + float Azz = wcosb*wcosc as float / 16384.0 + + word wAxx = Axx * 128.0 as word + word wAxy = Axy * 128.0 as word + word wAxz = Axz * 128.0 as word + word wAyx = Ayx * 128.0 as word + word wAyy = Ayy * 128.0 as word + word wAyz = Ayz * 128.0 as word + word wAzx = Azx * 128.0 as word + word wAzy = Azy * 128.0 as word + word wAzz = Azz * 128.0 as word for ubyte i in 0 to len(xcoor)-1 { - float xc = xcoor[i] as float - float yc = ycoor[i] as float - float zc = zcoor[i] as float - rotatedx[i] = Axx*xc + Axy*yc + Axz*zc - rotatedy[i] = Ayx*xc + Ayy*yc + Ayz*zc - rotatedz[i] = Azx*xc + Azy*yc + Azz*zc + word xc = xcoor[i] as word + word yc = ycoor[i] as word + word zc = zcoor[i] as word + word zz = wAxx*xc + wAxy*yc + wAxz*zc + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) ; /128 + rotatedx[i] = zz + zz=wAyx*xc + wAyy*yc + wAyz*zc + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) ; /128 + rotatedy[i] = zz + zz = wAzx*xc + wAzy*yc + wAzz*zc + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) ; /128 + rotatedz[i] = zz } } sub draw_edges() { - sub toscreenx(float x, float z) -> byte { - return x/(250.0+z) * (height as float) as byte + width // 2 - } - - sub toscreeny(float y, float z) -> byte { - return y/(250.0+z) * (height as float) as byte + height // 2 - } - ; plot the points of the 3d cube ; first the points on the back, then the points on the front (painter algorithm) for ubyte i in 0 to len(xcoor)-1 { - float rz = rotatedz[i] - if rz >= 0.1 { - ubyte sx = toscreenx(rotatedx[i], rz) as ubyte - ubyte sy = toscreeny(rotatedy[i], rz) as ubyte - c64scr.setchrclr(sx, sy, 46, i+2) + word rz = rotatedz[i] + if rz >= 10 { + float persp = (rz as float + 250.0)/height_f + byte sx = rotatedx[i] as float / persp as byte + width//2 + byte sy = rotatedy[i] as float / persp as byte + height//2 + c64scr.setchrclr(sx as ubyte, sy as ubyte, 46, i+2) } } for ubyte i in 0 to len(xcoor)-1 { - float rz = rotatedz[i] - if rz < 0.1 { - ubyte sx = toscreenx(rotatedx[i], rz) as ubyte - ubyte sy = toscreeny(rotatedy[i], rz) as ubyte - c64scr.setchrclr(sx, sy, 81, i+2) + word rz = rotatedz[i] + if rz < 10 { + float persp = (rz as float + 250.0)/height_f + byte sx = rotatedx[i] as float / persp as byte + width//2 + byte sy = rotatedy[i] as float / persp as byte + height//2 + c64scr.setchrclr(sx as ubyte, sy as ubyte, 81, i+2) } } } diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 9e9191de1..1bc251535 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -1,16 +1,148 @@ %import c64utils +%import c64flt ~ main { - word[1] rotatedx + const uword width = 40 + const uword height = 25 + + ; vertices + byte[8] xcoor = [ -50, -50, -50, -50, 50, 50, 50, 50 ] + byte[8] ycoor = [ -50, -50, 50, 50, -50, -50, 50, 50 ] + byte[8] zcoor = [ -50, 50, -50, 50, -50, 50, -50, 50 ] + + ; storage for rotated coordinates + word[len(xcoor)] rotatedx=0 + word[len(ycoor)] rotatedy=0 + word[len(zcoor)] rotatedz=-1 sub start() { - word xc = 2 -rpt: - word w = 2*xc - rotatedx[0] = w ; @ok! - rotatedx[0] = 2*xc ; @todo wrong code generated? crash! - c64.CHROUT('.') - goto rpt + uword anglex + uword angley + uword anglez + while(true) { + rotate_vertices(msb(anglex), msb(angley), msb(anglez)) + c64.CLEARSCR() + draw_edges() + anglex+=1000 + angley+=333 + anglez+=807 + } + } + + sub rotate_vertices(ubyte ax, ubyte ay, ubyte az) { + ; rotate around origin (0,0,0) + + ; set up the 3d rotation matrix values + word wcosa = cos8(ax) as word + word wsina = sin8(ax) as word + word wcosb = cos8(ay) as word + word wsinb = sin8(ay) as word + word wcosc = cos8(az) as word + word wsinc = sin8(az) as word + + word wcosa_sinb = wcosa*wsinb + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) + lsr(wcosa_sinb) ; / 128 + word wsina_sinb = wsina*wsinb + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) + lsr(wsina_sinb) ; / 128 + + float cosa_sinb = wcosa_sinb as float / 128.0 + float sina_sinb = wsina_sinb as float / 128.0 + float Axx = wcosa*wcosb as float / 16384.0 + float Axy = cosa_sinb*(wsinc as float / 128.0) - (wsina*wcosc as float / 16384.0) + float Axz = cosa_sinb*(wcosc as float / 128.0) + (wsina*wsinc as float / 16384.0) + float Ayx = wsina*wcosb as float / 16384.0 + float Ayy = sina_sinb*(wsinc as float / 128.0) + (wcosa*wcosc as float / 16384.0) + float Ayz = sina_sinb*(wcosc as float / 128.0) - (wcosa*wsinc as float / 16384.0) + float Azx = -wsinb as float / 128.0 + float Azy = wcosb*wsinc as float / 16384.0 + float Azz = wcosb*wcosc as float / 16384.0 + + word wAxx = Axx * 128.0 as word + word wAxy = Axy * 128.0 as word + word wAxz = Axz * 128.0 as word + word wAyx = Ayx * 128.0 as word + word wAyy = Ayy * 128.0 as word + word wAyz = Ayz * 128.0 as word + word wAzx = Azx * 128.0 as word + word wAzy = Azy * 128.0 as word + word wAzz = Azz * 128.0 as word + + for ubyte i in 0 to len(xcoor)-1 { + word xc = xcoor[i] as word + word yc = ycoor[i] as word + word zc = zcoor[i] as word + word zz = wAxx*xc + wAxy*yc + wAxz*zc + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) ; /128 + rotatedx[i] = zz + zz=wAyx*xc + wAyy*yc + wAyz*zc + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) ; /128 + rotatedy[i] = zz + zz = wAzx*xc + wAzy*yc + wAzz*zc + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) + lsr(zz) ; /128 + rotatedz[i] = zz + } + } + + sub draw_edges() { + + sub toscreenx(float x, float z) -> byte { + return x/(250.0+z) * (height as float) as byte + width // 2 + } + + sub toscreeny(float y, float z) -> byte { + return y/(250.0+z) * (height as float) as byte + height // 2 + } + + ; plot the points of the 3d cube + ; first the points on the back, then the points on the front (painter algorithm) + + for ubyte i in 0 to len(xcoor)-1 { + word rz = rotatedz[i] + if rz >= 10 { + ubyte sx = toscreenx(rotatedx[i] as float, rz as float) as ubyte ; @todo crash when not using 'as float' for the param! + ubyte sy = toscreeny(rotatedy[i] as float, rz as float) as ubyte ; @todo crash when not using 'as float' for the param! + c64scr.setchrclr(sx, sy, 46, i+2) + } + } + + for ubyte i in 0 to len(xcoor)-1 { + word rz = rotatedz[i] + if rz < 10 { + ubyte sx = toscreenx(rotatedx[i] as float, rz as float) as ubyte ; @todo crash when not using 'as float' for the param! + ubyte sy = toscreeny(rotatedy[i] as float, rz as float) as ubyte ; @todo crash when not using 'as float' for the param! + c64scr.setchrclr(sx, sy, 81, i+2) + } + } } } diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 457c02f0a..d3c6169d0 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -2309,7 +2309,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.ub2float + jsr c64flt.ub2float """ }, // floatvar = uwordvar @@ -2321,7 +2321,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.uw2float + jsr c64flt.uw2float """ }, // floatvar = bytevar @@ -2337,7 +2337,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.b2float + jsr c64flt.b2float """ }, // floatvar = wordvar @@ -2349,7 +2349,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.w2float + jsr c64flt.w2float """ }, // floatvar = float value @@ -2396,7 +2396,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.b2float + jsr c64flt.b2float """ }, // floatvar = mem ubyte @@ -2406,7 +2406,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.ub2float + jsr c64flt.ub2float """ }, // floatvar = mem word @@ -2418,7 +2418,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.w2float + jsr c64flt.w2float """ }, // floatvar = mem uword @@ -2430,7 +2430,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${segment[2].callLabel} ldy #>${segment[2].callLabel} - jsr prog8_lib.uw2float + jsr c64flt.uw2float """ }, @@ -2442,7 +2442,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${segment[3].callLabel} ldy #>${segment[3].callLabel} - jsr prog8_lib.b2float + jsr c64flt.b2float """ }, // floatvar = ubytearray[index] @@ -2453,7 +2453,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${segment[3].callLabel} ldy #>${segment[3].callLabel} - jsr prog8_lib.ub2float + jsr c64flt.ub2float """ }, // floatvar = wordarray[index] @@ -2466,7 +2466,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sty ${C64Zeropage.SCRATCH_W1+1} lda #<${segment[3].callLabel} ldy #>${segment[3].callLabel} - jsr prog8_lib.w2float + jsr c64flt.w2float """ }, // floatvar = uwordarray[index] @@ -2479,7 +2479,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sty ${C64Zeropage.SCRATCH_W1+1} lda #<${segment[3].callLabel} ldy #>${segment[3].callLabel} - jsr prog8_lib.uw2float + jsr c64flt.uw2float """ }, // floatvar = floatarray[index] @@ -2534,7 +2534,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.ub2float + jsr c64flt.ub2float """ }, // memfloat = uwordvar @@ -2546,7 +2546,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.uw2float + jsr c64flt.uw2float """ }, // memfloat = bytevar @@ -2562,7 +2562,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.b2float + jsr c64flt.b2float """ }, // memfloat = wordvar @@ -2574,7 +2574,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.w2float + jsr c64flt.w2float """ }, // memfloat = mem byte @@ -2584,7 +2584,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.b2float + jsr c64flt.b2float """ }, // memfloat = mem ubyte @@ -2594,7 +2594,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.ub2float + jsr c64flt.ub2float """ }, // memfloat = mem word @@ -2606,7 +2606,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.w2float + jsr c64flt.w2float """ }, // memfloat = mem uword @@ -2618,7 +2618,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_W1+1} lda #<${hexVal(segment[2])} ldy #>${hexVal(segment[2])} - jsr prog8_lib.uw2float + jsr c64flt.uw2float """ }, // memfloat = mem float @@ -2641,7 +2641,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${hexVal(segment[3])} ldy #>${hexVal(segment[3])} - jsr prog8_lib.b2float + jsr c64flt.b2float """ }, // memfloat = ubytearray[index] @@ -2652,7 +2652,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${C64Zeropage.SCRATCH_B1} lda #<${hexVal(segment[3])} ldy #>${hexVal(segment[3])} - jsr prog8_lib.ub2float + jsr c64flt.ub2float """ }, // memfloat = wordarray[index] @@ -2665,7 +2665,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sty ${C64Zeropage.SCRATCH_W1+1} lda #<${hexVal(segment[3])} ldy #>${hexVal(segment[3])} - jsr prog8_lib.w2float + jsr c64flt.w2float """ }, // memfloat = uwordarray[index] @@ -2678,7 +2678,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sty ${C64Zeropage.SCRATCH_W1+1} lda #<${hexVal(segment[3])} ldy #>${hexVal(segment[3])} - jsr prog8_lib.uw2float + jsr c64flt.uw2float """ }, // memfloat = floatarray[index]