From cc5898d0108d95b11a96ed43f59d06a8d41c01c6 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 14 Feb 2019 02:23:59 +0100 Subject: [PATCH] more tetriz work --- compiler/res/version.txt | 2 +- examples/looplabelproblem.p8 | 18 +++ examples/tehtriz.p8 | 292 +++++++++++++++++++++++++++++++---- examples/test.p8 | 11 ++ 4 files changed, 296 insertions(+), 27 deletions(-) create mode 100644 examples/looplabelproblem.p8 diff --git a/compiler/res/version.txt b/compiler/res/version.txt index 4450960a9..ed1985f2a 100644 --- a/compiler/res/version.txt +++ b/compiler/res/version.txt @@ -1 +1 @@ -1.2 (beta) +1.3 (beta) diff --git a/examples/looplabelproblem.p8 b/examples/looplabelproblem.p8 new file mode 100644 index 000000000..6c87657e4 --- /dev/null +++ b/examples/looplabelproblem.p8 @@ -0,0 +1,18 @@ + +~ main { + + sub start() { + + if A>10 { + A=44 + while true { + ;derp + } + } else { + + gameover: + goto gameover + } + } + +} diff --git a/examples/tehtriz.p8 b/examples/tehtriz.p8 index 585527391..23c782f64 100644 --- a/examples/tehtriz.p8 +++ b/examples/tehtriz.p8 @@ -4,42 +4,148 @@ const ubyte boardOffsetY = 3 const ubyte boardWidth = 10 const ubyte boardHeight = 20 + const ubyte startXpos = boardOffsetX + 3 + const ubyte startYpos = boardOffsetY - 2 - ; 3x3, rotating around their center square: + ubyte[4] blockI = [4, 5, 6, 7] ; note: special rotation ubyte[4] blockJ = [0, 4, 5, 6] ubyte[4] blockL = [2, 4, 5, 6] + ubyte[4] blockO = [1, 2, 5, 6] ; note: no rotation ubyte[4] blockS = [1, 2, 4, 5] ubyte[4] blockT = [1, 4, 5, 6] ubyte[4] blockZ = [0, 1, 5, 6] - ;4x4, rotating around center: - ubyte[4] blockI = [4, 5, 6, 7] - ubyte[4] blockO = [1, 2, 5, 6] ; block colors I, J, L, O, S, T, Z: cyan, blue, orange, yellow, green, purple, red ubyte[7] blockColors = [3, 6, 8, 7, 5, 4, 2] - ubyte[7] blockSizes = [4, 3, 3, 4, 3, 3, 3] ; needed for proper rotation? (or just use block num?) - ubyte[16] currentBlock - ubyte currentBlockSize ; 3 or 4 - ubyte currentBlockNum + ubyte lines = 0 + ubyte score = 0 + ubyte xpos = startXpos + ubyte ypos = startYpos + ubyte nextBlock = rnd() % 7 sub start() { + @(650) = 128 ; set all keys to repeat drawBoard() + spawnNextBlock() - for ubyte b in 7 to 0 step -1 { - newCurrentBlock(b) - drawBlock(3, 2+b*3, 102) ; 102 = stipple - drawBlock(boardOffsetX+3, 1+b*3, 160) ; 160 = block, 32 = erase (space) +waitkey: + if c64.TIME_LO==30 { + c64.TIME_LO = 0 + if blocklogic.canMoveDown(xpos, ypos) { + drawBlock(xpos, ypos, 32) + ypos++ ; descend + drawBlock(xpos, ypos, 160) + } else { + ; block can't move further down! + ; check if the game area is full, if not, spawn the next block at the top. + if blocklogic.isGameOver() { + c64scr.PLOT(7, 7) + c64.CHROUT('U') + c64scr.print("────────────────────────") + c64.CHROUT('I') + c64scr.PLOT(7, 8) + c64scr.print("│*** g a m e o v e r ***│") + c64scr.PLOT(7, 9) + c64.CHROUT('J') + c64scr.print("────────────────────────") + c64.CHROUT('K') + } else { + spawnNextBlock() + } + } } - while(true) { - ; loop + ubyte key=c64.GETIN() + if_z goto waitkey + + if key>='1' and key<='7' { + ; select block type + drawBlock(xpos, ypos, 32) + newCurrentBlock(key-'1') + drawBlock(xpos, ypos, 160) } + else if key==157 or key==',' { + if blocklogic.canMoveLeft(xpos, ypos) { + drawBlock(xpos, ypos, 32) + xpos-- ; move left + drawBlock(xpos, ypos, 160) + } + } + else if key==29 or key=='.' { + if blocklogic.canMoveRight(xpos, ypos) { + drawBlock(xpos, ypos, 32) + xpos++ ; move right + drawBlock(xpos, ypos, 160) + } + } + else if key==17 or key=='m' { + if blocklogic.canMoveDown(xpos, ypos) { + drawBlock(xpos, ypos, 32) + ypos++ ; descend + drawBlock(xpos, ypos, 160) + } + } + else if key==145 or key==' ' { + ; drop down immediately + drawBlock(xpos, ypos, 32) + ypos = boardOffsetY+boardHeight-4 + drawBlock(xpos, ypos, 160) + } + else if key=='z' { + ; rotate CCW + drawBlock(xpos, ypos, 32) + blocklogic.rotateCCW() + drawBlock(xpos, ypos, 160) + } + else if key=='x' { + ; rotate CW + drawBlock(xpos, ypos, 32) + blocklogic.rotateCW() + drawBlock(xpos, ypos, 160) + } + goto waitkey + + } + + sub spawnNextBlock() { + c64.TIME_LO = 0 + newCurrentBlock(nextBlock) + nextBlock = rnd() % 7 + drawNextBlock() + xpos = startXpos + ypos = startYpos + drawBlock(xpos, ypos, 160) } sub drawBoard() { + c64.COLOR = 7 c64scr.PLOT(1,1) + c64scr.print("irmen's") + c64scr.PLOT(1,2) c64scr.print("teh▁triz") + c64.COLOR = 5 + c64scr.PLOT(28,3) + c64scr.print("next:") + c64scr.PLOT(28,10) + c64scr.print("lines:") + c64scr.PLOT(28,14) + c64scr.print("score:") + c64.COLOR = 12 + c64scr.PLOT(28,19) + c64scr.print("controls:") + c64.COLOR = 11 + c64scr.PLOT(27,20) + c64scr.print("z/x rotate") + c64scr.PLOT(27,21) + c64scr.print(",/. move") + c64scr.PLOT(27,22) + c64scr.print("spc drop") + c64scr.PLOT(27,23) + c64scr.print(" m descend") + + c64scr.setcc(boardOffsetX-1, boardOffsetY-1, 108, 12) + c64scr.setcc(boardOffsetX+boardWidth, boardOffsetY-1, 123, 12) c64scr.setcc(boardOffsetX-1, boardOffsetY+boardHeight, 124, 12) c64scr.setcc(boardOffsetX+boardWidth, boardOffsetY+boardHeight, 126, 12) ubyte i @@ -49,52 +155,186 @@ c64scr.setcc(boardOffsetX-1, i, 89, 11) c64scr.setcc(boardOffsetX+boardWidth, i, 84, 11) } + + for ubyte b in 7 to 0 step -1 { + newCurrentBlock(b) + drawBlock(3, 3+b*3, 102) ; 102 = stipple + } + drawScore() } + sub drawScore() { + c64.COLOR=1 + c64scr.PLOT(30,11) + c64scr.print_ub(lines) + c64scr.PLOT(30,15) + c64scr.print_uw(score) + } + + sub drawNextBlock() { + for ubyte x in 31 to 28 step -1 { + c64scr.setcc(x, 5, ' ', 0) + c64scr.setcc(x, 6, ' ', 0) + } + + ; reuse the normal block draw routine (because we can't manipulate array pointers yet) + ubyte prev = blocklogic.currentBlockNum + newCurrentBlock(nextBlock) + drawBlock(28, 5, 160) + newCurrentBlock(prev) + } sub newCurrentBlock(ubyte block) { - memset(currentBlock, len(currentBlock), 0) - currentBlockNum = block - currentBlockSize = blockSizes[block] + memset(blocklogic.currentBlock, len(blocklogic.currentBlock), 0) + blocklogic.currentBlockNum = block ; @todo would be nice to have an explicit pointer type to reference the array, and code the loop only once... ubyte blockCol = blockColors[block] ubyte i if block==0 { ; I for i in blockI - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } else if block==1 { ; J for i in blockJ - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } else if block==2 { ; L for i in blockL - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } - else if block==3 { ; O + else if block==3 { ; O for i in blockO - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } else if block==4 { ; S for i in blockS - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } else if block==5 { ; T for i in blockT - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } else if block==6 { ; Z for i in blockZ - currentBlock[i] = blockCol + blocklogic.currentBlock[i] = blockCol } } sub drawBlock(ubyte x, ubyte y, ubyte character) { for ubyte i in 15 to 0 step -1 { - ubyte c=currentBlock[i] + ubyte c=blocklogic.currentBlock[i] if c c64scr.setcc((i&3)+x, (i/4)+y, character, c) } } } + + +~ blocklogic { + + ubyte currentBlockNum + ubyte[16] currentBlock + ubyte[16] rotated + + sub rotateCW() { + ; rotates the current block clockwise. + if canRotateCW() { + if currentBlockNum==0 + rotateIblock() ; block 'I' has special rotation + else if currentBlockNum!=3 { + ; rotate all other blocks (except 3, the square) around their center square + rotated[0] = currentBlock[8] + rotated[1] = currentBlock[4] + rotated[2] = currentBlock[0] + rotated[4] = currentBlock[9] + rotated[6] = currentBlock[1] + rotated[8] = currentBlock[10] + rotated[9] = currentBlock[6] + rotated[10] = currentBlock[2] + + currentBlock[0] = rotated[0] + currentBlock[1] = rotated[1] + currentBlock[2] = rotated[2] + currentBlock[4] = rotated[4] + currentBlock[6] = rotated[6] + currentBlock[8] = rotated[8] + currentBlock[9] = rotated[9] + currentBlock[10] = rotated[10] + } + } + } + + sub rotateCCW() { + ; rotates the current block counterclockwise. + if canRotateCCW() { + if currentBlockNum==0 + rotateIblock() ; block 'I' has special rotation + else if currentBlockNum!=3 { + ; rotate all other blocks (except 3, the square) around their center square + rotated[0] = currentBlock[2] + rotated[1] = currentBlock[6] + rotated[2] = currentBlock[10] + rotated[4] = currentBlock[1] + rotated[6] = currentBlock[9] + rotated[8] = currentBlock[0] + rotated[9] = currentBlock[4] + rotated[10] = currentBlock[8] + + currentBlock[0] = rotated[0] + currentBlock[1] = rotated[1] + currentBlock[2] = rotated[2] + currentBlock[4] = rotated[4] + currentBlock[6] = rotated[6] + currentBlock[8] = rotated[8] + currentBlock[9] = rotated[9] + currentBlock[10] = rotated[10] + } + } + } + + sub rotateIblock() { + ; the I-block only has 2 rotational states. + if currentBlock[2]==0 { + ; it's horizontal, make it vertical again + currentBlock[2] = currentBlock[4] + currentBlock[10] = currentBlock[4] + currentBlock[14] = currentBlock[4] + currentBlock[4] = 0 + currentBlock[5] = 0 + currentBlock[7] = 0 + } else { + ; it's vertical, make it horizontal again + currentBlock[4] = currentBlock[2] + currentBlock[5] = currentBlock[2] + currentBlock[7] = currentBlock[2] + currentBlock[2] = 0 + currentBlock[10] = 0 + currentBlock[14] = 0 + } + } + + sub canRotateCW() -> ubyte { + return true ; TODO determine + } + + sub canRotateCCW() -> ubyte { + return true ; TODO determine + } + + sub canMoveLeft(ubyte xpos, ubyte ypos) -> ubyte { + return xpos>main.boardOffsetX ; TODO deal with actual block collision + } + + sub canMoveRight(ubyte xpos, ubyte ypos) -> ubyte { + return xpos ubyte { + return ypos ubyte { + return false ; TODO determine fail state + } +} diff --git a/examples/test.p8 b/examples/test.p8 index 4b9d541ae..103fd11f0 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,6 +3,17 @@ ~ main { + ; @todo test memset/memcopy (there's a bug in memcopy?) + + + ubyte x = rnd82() % 6 ; @todo fix compiler crash + always 0??? + drawNext(rnd() & 7) ; @todo missing asm pattern + + + ubyte[7] blockColors = [3, 6, 8, 7, 5, 4, 2] + drawNext(n % len(blockColors)) ; @todo why is len a word here? + + ; mul_word_3 sub start() {