diff --git a/compiler/examples/cube3d-c64-float.p8 b/compiler/examples/cube3d-c64-float.p8 index 450c4fd67..4f378bb9c 100644 --- a/compiler/examples/cube3d-c64-float.p8 +++ b/compiler/examples/cube3d-c64-float.p8 @@ -20,7 +20,8 @@ float time=0.0 while(true) { rotate_vertices(time) - c64.CLEARSCR() + c64scr.clear_screenchars(32) + c64scr.print("\uf1203d cube! (using floating point)") draw_edges() time+=0.2 } diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index a321bc392..837474f61 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -3,156 +3,6 @@ ~ main { - 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() { - - - label1: - label2: - Y-- - if_mi goto label1 - if_mi goto label1 else goto label2 - - 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) - } - } - - ; @todo integer / integer should usually result in a FLOAT, not INT. the // operator is for integer division! - - 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/examples/whizzine.p8 b/compiler/examples/wizzine.p8 similarity index 95% rename from compiler/examples/whizzine.p8 rename to compiler/examples/wizzine.p8 index dd8d36b15..9d95a8700 100644 --- a/compiler/examples/whizzine.p8 +++ b/compiler/examples/wizzine.p8 @@ -64,8 +64,8 @@ sub irq() { ubyte i=14 nextsprite: ; @todo should be a for loop from 14 to 0 step -2 but this causes a value out of range error at the moment - word x = (sin8(angle*2-i*8) as word)+190 ; @todo will/should be using shifts for faster multiplication - byte y = cos8(angle*3-i*8) // 2 ; @todo will/should be using shifts for faster multiplication + word x = (sin8(angle*2-i*8) as word)+190 ; @todo will/should be using shifts for faster multiplication and division + byte y = cos8(angle*3-i*8) // 2 ; @todo will/should be using shifts for faster multiplication and division @(SP0X+i) = lsb(x) @(SP0Y+i) = y+150 as ubyte diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index 0145fc1ff..a4e0ba20f 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -33,6 +33,7 @@ enum class DataType { ARRAY_F; fun assignableTo(targetType: DataType) = + // what types are assignable to others without loss of precision? when(this) { UBYTE -> targetType == UBYTE || targetType == UWORD || targetType == FLOAT BYTE -> targetType == BYTE || targetType == WORD || targetType == FLOAT diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 4bdc0c00e..fb6ac7ac1 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -1034,8 +1034,11 @@ private class StatementTranslator(private val prog: IntermediateProgram, } } else { // only regular (non-register) arguments + // "assign" the arguments to the locally scoped parameter variables for this subroutine + // (subroutine arguments are not passed via the stack!) for (arg in arguments.zip(subroutine.parameters)) { translate(arg.first) + convertType(arg.first.resultingDatatype(namespace, heap)!!, arg.second.type) // convert types of arguments to required parameter type val opcode = opcodePopvar(arg.second.type) prog.instr(opcode, callLabel = subroutine.scopedname + "." + arg.second.name) } @@ -1354,6 +1357,7 @@ private class StatementTranslator(private val prog: IntermediateProgram, val targetDt = assignTarget.determineDatatype(namespace, heap, stmt) if(valueDt!=targetDt) { // convert value to target datatype if possible + // @todo use convertType()???? when(targetDt) { DataType.UBYTE, DataType.BYTE -> if(valueDt!=DataType.BYTE && valueDt!=DataType.UBYTE)