aboutsummaryrefslogtreecommitdiff
path: root/Jetris.ino
diff options
context:
space:
mode:
Diffstat (limited to 'Jetris.ino')
-rw-r--r--Jetris.ino335
1 files changed, 37 insertions, 298 deletions
diff --git a/Jetris.ino b/Jetris.ino
index 6c9990b..fb0c7e8 100644
--- a/Jetris.ino
+++ b/Jetris.ino
@@ -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);
- }
}