diff options
Diffstat (limited to 'Jetris.ino')
-rw-r--r-- | Jetris.ino | 335 |
1 files changed, 37 insertions, 298 deletions
@@ -1,35 +1,14 @@ -// THings that miss -// Functions that return something -// Make more safety - +#include "drawing.h" #include "sprites.h" -#include "MaxCommands.h" - -#define clk 5 -#define cs 6 -#define dataIn 3 -#define setDisplay(d) (curDisplay = d) -#define leftPin 2 -#define rightPin 4 -#define dropPin 11 -#define rotatePin 10 -#define clickTime 200 - -//Use the drawDot function to draw -uint8_t buttonLayer[16]; -uint8_t topLayer[16]; - -int curDisplay = 0; void setup() { - //Init Serial - Serial.begin(9600); + Serial.begin(115200); + Serial.println("Starting \n\n"); - Serial.println("Starting up \n\n\n"); + /* Prepare the random generator */ + randomSeed( analogRead(0) ); - randomSeed(analogRead(0)); - - //Init pins + /* Init pins */ pinMode(cs, OUTPUT); pinMode(clk, OUTPUT); pinMode(dataIn, OUTPUT); @@ -38,306 +17,66 @@ void setup() { pinMode(dropPin, INPUT_PULLUP); pinMode(rotatePin, INPUT_PULLUP); - //ButtonInterrupt - //attachInterrupt(digitalPinToInterrupt(left), buttonHandle, FALLING); - - //Setup displays - setDisplay(0); - initDisplay(); - - setDisplay(1); - initDisplay(); + initDisplays(0); + initDisplays(1); initSprites(); - - initGame(); + initGame(); } -///////////////////////////// -// GAME LOGIC // -///////////////////////////// +void loop() { + gameLoop(); +} -Sprite *block; -int xPos; -int yPos; +/* + * GAME LOGIC + */ +struct Sprite *cur_block; -long loopTime; +int x_pos, y_pos; void initGame() { initBlock(); } -void loop() { - +void gameLoop() { + + static long loop_time; + handleButtons(); - if(millis() - loopTime < 500) + if( millis() - loop_time < 500) return; - //Move - if(checkCollision(0, 1)) { - drawSprite(buttonLayer, xPos, yPos, block); + /* Move the block */ + if( checkCollision(0, 1) ){ + drawSprite(buttonLayer, xPos, yPos, cur_block); + + /* Handle the rows, from the top */ handleFullRows(0); renderAll(); - initBlock(); - }else{ + }else { + /* Free to move (one down)*/ moveBlock(0, 1); } - loopTime = millis(); - + loop_time = millis(); } -void initBlock(){ - xPos = 0; - yPos = 0; +void initBlock() { + xPos = yPos = 0; - block = blocks[random(7)]; + block = blocks[ random(7) ]; } -void moveBlock(int xMove, int yMove) { - xPos += xMove; - yPos += yMove; - - //Clear screen - drawRegion(topLayer, 0xFF, 0xFFFF, false); +void moveBlock(int x_move, int y_move) { + x_pos += x_move; + y_pos += y_move; - //Draw ball - drawSprite(topLayer, xPos, yPos, block); - - //Render - renderAll(); - -} - -//Checks if input and button layer have bits in common, or if a block hits button. Returns true if collision -int checkCollision(int xMove, int yMove) { - //Newolute position on map - int yNew = yPos + yMove; - int xNew = xPos + xMove; - - for(int i = 0; i < block->height; i++) { - if(( block->buff[i] >> xNew) & buttonLayer[i + yNew]) - return 1; - } - - //Check if out of bounds - if(xNew + block->width > 8 || xNew < 0 || yNew + block->height > 16) - return 1; - - return 0; -} + /* Redraw ball */ -void rotateBlock() { - Serial.println("Rotate"); - - //If next block exist, switch to that - if( block->rotateNext ) { - Serial.println((uint16_t)block); - Serial.println((uint16_t)block->rotateNext); - - block = block->rotateNext; - Serial.println((uint16_t)block); - } - - //And render - moveBlock(0, 0); -} - -void dropBlock() { - //Move down until it hits something - int count = 0; - while( !checkCollision(0, 1) ) { - moveBlock(0, 1); - delay(10); - } - - drawSprite(buttonLayer, xPos, yPos, block); -} - -void renderAll(){ - setDisplay(0); - render(0); - setDisplay(1); - render(8); -} - -void handleFullRows(int start) { - for(int i = start; i < 16; i++ ) { - if(buttonLayer[15 - i] == 0xFF) { - for(int j = i; j < 16; j++) { - buttonLayer[15 - j] = buttonLayer[14 - j]; - } - handleFullRows(i); - return; - } - } -} - -void renderToSerial() { - Serial.write(0x33); Serial.println("[2J"); - for(int i = 0; i < 16; i++) { - for(int b = 0; b < 8; b++) { - Serial.print( ( buttonLayer[i] & ( 1 << 7 - b ) ) > 0 ); - } - Serial.println(); - } -} - -///////////////////////////// -// Control Handling // -///////////////////////////// - -unsigned long leftLast, rightLast, dropLast, rotateLast; - -void handleButtons() { - //Read from switch - int leftState = !digitalRead(leftPin); - int rightState = !digitalRead(rightPin); - int dropState = !digitalRead(dropPin); - int rotateState = !digitalRead(rotatePin); - //Check if last click was over 100 ms ago - if(millis() - leftLast > clickTime && leftState) { - leftLast = millis(); - - //Move - if( !checkCollision(1, 0) ) { - moveBlock(1, 0); - } - } - - if(millis() - rightLast > clickTime && rightState) { - rightLast = millis(); - //Move - if( !checkCollision(-1, 0) ) { - moveBlock(-1, 0); - } - } - - if(millis() - dropLast > clickTime && dropState) { - dropLast = millis(); - - dropBlock(); - } - - if(millis() - rotateLast > clickTime+100 && rotateState) { - rotateLast = millis(); - - rotateBlock(); - } -} - -///////////////////////////// -// Screendrawing routines // -///////////////////////////// - -void initDisplay() { - - //clear all registers - for ( int i = 0; i < 0x0F; i++) { - writeCommand(i, 0); - } - - //Turn it on - writeCommand(maxSHUTDOWN_INV, 1); - - //Darker please - writeCommand(maxINTENSITY, 0x00); - - //Activate all lines - writeCommand(maxSCAN_LIMIT, 0x07); - -} - -//Draw a region, where mask specifies where to draw. -// xMask = 0b00111100, yMask = 0b01111110 will draw a small 4x6 box -void drawSprite(uint8_t layer[], uint8_t x, uint8_t y, Sprite* sprite) { - //Check if in range - if (x + sprite->width - 1 > 7 || y + sprite->height - 1> 15 ) - return; - - for ( int i = y; i < sprite->height + y; i++) { - //Calculate bits - uint8_t row = layer[i]; - row |= sprite->buff[i - y] >> x; - - layer[i] = row; - - } - -} - -void drawRegion(uint8_t layer[], uint8_t xMask, uint16_t yMask, bool state) { - for (int i = 0; i < 16; i++ ) { - //If y index not in mask, go to next - if (! ( yMask & 1 << i ) ) - continue; - - //Flip the bits - uint8_t row = layer[i]; - if ( state ) { - //Write 1 where on the 1's places in xMask - row |= xMask; - } else { - //Write 0. ~ means bitwise NOT - row &= ~( xMask ); - } - layer[i] = row; - } -} - -unsigned long reRenderLast; - -void render(int where) { - - static uint8_t onScreen[16]; - - bool reRender = (millis() - reRenderLast ) > 1000; - - for(int i = where; i < (where + 8); i++ ) { - uint8_t toWrite = buttonLayer[i] | topLayer[i]; - if(onScreen[i] == toWrite && !reRender) - continue; - - writeCommand(maxDIGIT_0 + i - where, buttonLayer[i] | topLayer[i]); - - onScreen[i] = toWrite; - } - - if(reRender) { - reRenderLast = millis(); - } - -} - -void writeCommand(uint8_t addr, uint8_t data) { - uint16_t uint8_tToWrite = addr << 8 | data; - - //Set Chip select low - digitalWrite(cs, LOW); - - //MSBFIRST is a arduino standard, which says that data goes from left to right - - shiftOut(dataIn, clk, MSBFIRST, addr); - shiftOut(dataIn, clk, MSBFIRST, data); - - //To get to other displays padding is added to step through them - serialPad(curDisplay * 2); - - digitalWrite(cs, HIGH); - - //To Clear out other displays more padding is added - serialPad(2 * 2); -} - -void serialPad(int count) { - - for(int i = 0; i < count; i++) { - //Pad with no-ops - shiftOut(dataIn, clk, MSBFIRST, 0); - } } |