cube3d and tweaks

This commit is contained in:
Irmen de Jong 2018-10-03 01:11:28 +02:00
parent 4df397d057
commit 4501276217
6 changed files with 157 additions and 87 deletions

142
compiler/examples/cube3d.p8 Normal file
View File

@ -0,0 +1,142 @@
%option enable_floats
~ irq {
word global_time
byte time_changed
sub irq() {
global_time++
time_changed = 1
}
}
~ main {
const word width = 320
const word height = 200
; vertices
float[8] xcoor = [ -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 ]
float[8] ycoor = [ -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0 ]
float[8] zcoor = [ -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ]
; edges (msb=from vertex, lsb=to vertex)
word[12] edges = [$0001, $0103, $0302, $0200, $0405, $0507, $0706, $0604, $0004, $0105, $0206, $0307]
; storage for rotated coordinates
float[len(xcoor)] rotatedx
float[len(ycoor)] rotatedy
float[len(zcoor)] rotatedz
; general index var
byte i
sub start() {
if irq.time_changed {
irq.time_changed = 0
_vm_gfx_clearscr(0)
_vm_gfx_text(14, 5, 5, "Spin to Win !!!")
for i in 0 to width//10 {
_vm_gfx_line(i*2+width//2-width//10, 130, i*10, 199, 6)
}
rotate_vertices(flt(irq.global_time) / 30.0)
draw_edges()
}
goto start
}
sub rotate_vertices(t: float) {
; rotate around origin (0,0,0)
; set up the 3d rotation matrix values
float cosa
float sina
float cosb
float sinb
float cosc
float sinc
float Axx
float Axy
float Axz
float Ayx
float Ayy
float Ayz
float Azx
float Azy
float Azz
cosa = cos(t)
sina = sin(t)
cosb = cos(t*0.33)
sinb = sin(t*0.33)
cosc = cos(t*0.78)
sinc = sin(t*0.78)
Axx = cosa*cosb
Axy = cosa*sinb*sinc - sina*cosc
Axz = cosa*sinb*cosc + sina*sinc
Ayx = sina*cosb
Ayy = sina*sinb*sinc + cosa*cosc
Ayz = sina*sinb*cosc - cosa*sinc
Azx = -sinb
Azy = cosb*sinc
Azz = cosb*cosc
for i in 0 to len(xcoor)-1 {
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 draw_edges() {
word edge
byte e_from
byte e_to
sub toscreenx(x: float, z: float) -> word {
return floor(x/(4.2+z) * height) + width // 2
}
sub toscreeny(y: float, z: float) -> word {
return floor(y/(4.2+z) * height) + height // 2
}
; draw all edges of the object
for edge in edges {
e_from = msb(edge)
e_to = lsb(edge)
_vm_gfx_line(toscreenx(rotatedx[e_from], rotatedz[e_from]), toscreeny(rotatedy[e_from], rotatedz[e_from]),
toscreenx(rotatedx[e_to], rotatedz[e_to]), toscreeny(rotatedy[e_to], rotatedz[e_to]), e_from+e_to)
}
; accentuate the vertices a bit with small boxes
word sx
word sy
byte col
for i in 0 to len(xcoor)-1 {
sx = toscreenx(rotatedx[i], rotatedz[i])
sy = toscreeny(rotatedy[i], rotatedz[i])
col=i+2
_vm_gfx_pixel(sx-1, sy-1, col)
_vm_gfx_pixel(sx, sy-1, col)
_vm_gfx_pixel(sx+1, sy-1, col)
_vm_gfx_pixel(sx-1, sy, col)
_vm_gfx_pixel(sx, sy, col)
_vm_gfx_pixel(sx+1, sy, col)
_vm_gfx_pixel(sx-1, sy+1, col)
_vm_gfx_pixel(sx, sy+1, col)
_vm_gfx_pixel(sx+1, sy+1, col)
_vm_gfx_pixel(sx, sy-2, col)
_vm_gfx_pixel(sx+2, sy, col)
_vm_gfx_pixel(sx, sy+2, col)
_vm_gfx_pixel(sx-2, sy, col)
}
}
}

View File

@ -7,7 +7,7 @@
const word width = 320 // 2
const word height = 256 // 2
const word xoffset = 40
const word yoffset = 20
const word yoffset = 30
word pixelx
byte pixely
float xx
@ -21,7 +21,7 @@
byte ploty
_vm_gfx_clearscr(11)
_vm_gfx_text(5, 5, 7, "Calculating Mandelbrot Fractal...")
_vm_gfx_text(2, 1, 7, "Calculating Mandelbrot Fractal...")
for pixely in yoffset to yoffset+height-1 {
yy = flt((pixely-yoffset))/height/3.6+0.4
@ -46,13 +46,13 @@
}
}
_vm_gfx_text(110, 160, 7, "Finished!")
_vm_gfx_text(11, 21, 7, "Finished!")
}
}
; ---- 60hz irq handling routine------
; ---- some weird testing 60hz irq handling routine------
~ irq {

View File

@ -1,78 +0,0 @@
%option enable_floats
~ irq {
word global_time
byte time_changed
sub irq() {
global_time++
time_changed = 1
}
}
~ main {
const word width = 320
const word height = 200
float[6] xcoor = [-1.0, 1.0, 1.0, 0.5, 0.2, -1.0]
float[6] ycoor = [0.2, 1.0, -1.0, -0.3, -0.6, -1.0]
float[len(xcoor)] rotatedx
float[len(ycoor)] rotatedy
sub start() {
byte i
while(1) {
if irq.time_changed {
irq.time_changed = 0
_vm_gfx_clearscr(0)
_vm_gfx_text(120, 40, 5, "Spin to Win !!!")
for i in 0 to width//10 {
_vm_gfx_line(i*2+100, 100, i*10, 199, 6)
}
rotate_points(flt(irq.global_time) / 30.0)
draw_lines()
}
}
}
sub rotate_points(t: float) {
; rotate around origin (0,0) and zoom a bit
byte i
float zoom
zoom = (0.6 + sin(t*1.4)/2.2)
for i in 0 to len(xcoor)-1 {
rotatedx[i] = xcoor[i] * cos(t) - ycoor[i] * sin(t)
rotatedy[i] = xcoor[i] * sin(t) + ycoor[i] * cos(t)
rotatedx[i] *= zoom
rotatedy[i] *= zoom
}
}
sub draw_lines() {
byte i
sub toscreenx(x: float) -> word {
return floor(x * height/3 + width /2)
}
sub toscreeny(y: float) -> word {
return floor(y * height/3 + height /2)
}
for i in 0 to len(xcoor)-2 {
_vm_gfx_line(toscreenx(rotatedx[i]), toscreeny(rotatedy[i]),
toscreenx(rotatedx[i+1]), toscreeny(rotatedy[i+1]), i+7)
}
_vm_gfx_line(toscreenx(rotatedx[len(xcoor)-1]), toscreeny(rotatedy[len(xcoor)-1]),
toscreenx(rotatedx[0]), toscreeny(rotatedy[0]), 14)
}
}

View File

@ -8,7 +8,7 @@
sub start() {
_vm_gfx_clearscr(0)
_vm_gfx_text(5, 5, 7, "Swirl !!!")
_vm_gfx_text(2, 2, 7, "Swirl !!!")
float x
float y

View File

@ -134,7 +134,7 @@ enum class Syscall(val callNr: Short) {
INPUT_STR(15), // user input a string onto the stack, with max length (truncated) given by value on stack
GFX_PIXEL(16), // plot a pixel at (x,y,color) pushed on stack in that order
GFX_CLEARSCR(17), // clear the screen with color pushed on stack
GFX_TEXT(18), // write text on screen at (x,y,color,text) pushed on stack in that order
GFX_TEXT(18), // write text on screen at cursor position (x,y,color,text) pushed on stack in that order (pixel pos= x*8, y*8)
GFX_LINE(19), // draw line on screen at (x1,y1,x2,y2,color) pushed on stack in that order
FUNC_SIN(66),
@ -514,9 +514,9 @@ class StackVm(private var traceOutputFile: String?) {
Syscall.GFX_TEXT -> {
val textPtr = evalstack.pop()
val color = evalstack.pop()
val (y, x) = evalstack.pop2()
val (cy, cx) = evalstack.pop2()
val text = heap.get(textPtr.heapId)
canvas?.writeText(x.integerValue(), y.integerValue(), text.str!!, color.integerValue())
canvas?.writeText(8*cx.integerValue(), 8*cy.integerValue(), text.str!!, color.integerValue())
}
Syscall.FUNC_RND -> evalstack.push(Value(DataType.BYTE, rnd.nextInt() and 255))
Syscall.FUNC_RNDW -> evalstack.push(Value(DataType.WORD, rnd.nextInt() and 65535))

View File

@ -111,6 +111,13 @@ Usually it is omitted, and the compiler will automatically choose the location (
the previous block in memory).
The address must be >= ``$0200`` (because ``$00``--``$ff`` is the ZP and ``$100``--``$200`` is the cpu stack).
.. sidebar::
Scoped access to symbols / "dotted names"
Every symbol is 'public' and can be accessed from elsewhere given its full "dotted name".
So, accessing a variable ``counter`` defined in subroutine ``worker`` in block ``main``,
can be done from anywhere by using ``main.worker.counter``.
A block is also a *scope* in your program so the symbols in the block don't clash with
symbols of the same name defined elsewhere in the same file or in another file.
You can refer to the symbols in a particular block by using a *dotted name*: ``blockname.symbolname``.
@ -118,7 +125,6 @@ Labels inside a subroutine are appended again to that; ``blockname.subroutinenam
A symbol name that's not a dotted name is searched for in the current scope, if it's not found there,
one scope higher, and so on until it is found.
Every symbol is 'public' and can be accessed from elsewhere given its dotted name.
**The special "ZP" ZeroPage block**