aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jetris.ino144
-rw-r--r--drawing.h3
-rw-r--r--drawing.ino59
-rw-r--r--sprites.h2
4 files changed, 184 insertions, 24 deletions
diff --git a/Jetris.ino b/Jetris.ino
index fb0c7e8..1d03b00 100644
--- a/Jetris.ino
+++ b/Jetris.ino
@@ -1,6 +1,14 @@
#include "drawing.h"
#include "sprites.h"
+#define LEFT_PIN 2
+#define RIGHT_PIN 4
+#define DROP_PIN 11
+#define ROTATE_PIN 10
+#define CLICK_TIME 200
+
+#define RENDER_TO_SERIAL 0
+
void setup() {
Serial.begin(115200);
Serial.println("Starting \n\n");
@@ -9,13 +17,13 @@ void setup() {
randomSeed( analogRead(0) );
/* Init pins */
- pinMode(cs, OUTPUT);
- pinMode(clk, OUTPUT);
- pinMode(dataIn, OUTPUT);
- pinMode(leftPin, INPUT_PULLUP);
- pinMode(rightPin, INPUT_PULLUP);
- pinMode(dropPin, INPUT_PULLUP);
- pinMode(rotatePin, INPUT_PULLUP);
+ pinMode(CS, OUTPUT);
+ pinMode(CLK, OUTPUT);
+ pinMode(DATA_IN, OUTPUT);
+ pinMode(LEFT_PIN, INPUT_PULLUP);
+ pinMode(RIGHT_PIN, INPUT_PULLUP);
+ pinMode(DROP_PIN, INPUT_PULLUP);
+ pinMode(ROTATE_PIN, INPUT_PULLUP);
initDisplays(0);
initDisplays(1);
@@ -51,12 +59,14 @@ void gameLoop() {
if( millis() - loop_time < 500)
return;
- /* Move the block */
+ /* Move the cur_block */
if( checkCollision(0, 1) ){
- drawSprite(buttonLayer, xPos, yPos, cur_block);
+ drawSprite(buttonLayer, x_pos, y_pos, cur_block);
- /* Handle the rows, from the top */
+ /* Handle the rows, from the button */
handleFullRows(0);
+
+ initBlock();
renderAll();
}else {
/* Free to move (one down)*/
@@ -67,9 +77,9 @@ void gameLoop() {
}
void initBlock() {
- xPos = yPos = 0;
+ x_pos = y_pos = 0;
- block = blocks[ random(7) ];
+ cur_block = blocks[ random(7) ];
}
void moveBlock(int x_move, int y_move) {
@@ -77,6 +87,116 @@ void moveBlock(int x_move, int y_move) {
y_pos += y_move;
/* Redraw ball */
+ clearBuffer(topLayer);
+
+ drawSprite(topLayer, x_pos, y_pos, cur_block);
+
+ renderAll();
+}
+
+/* Returns 1 if there is collision in specified direction */
+int checkCollision(int xMove, int yMove) {
+ /* New position */
+ int xNew = x_pos + xMove;
+ int yNew = y_pos + yMove;
+
+ for( int i = 0; i < cur_block->height; i++ ) {
+ if( (cur_block->buff[i] >> xNew) & buttonLayer[i + yNew] )
+ return 1;
+ }
+ /* Check if border is hit */
+ if( xNew + cur_block->width > 8 || xNew < 0 || yNew + cur_block->height > 16 )
+ return 1;
+ return 0;
+}
+
+int rotateBlock() {
+ /* Switch to next cur_block if it exists */
+ if( cur_block->rotateNext ) {
+ cur_block = cur_block->rotateNext;
+ }
+
+ /* Render new cur_block(by abusing move block) */
+ moveBlock(0, 0);
+}
+
+void dropBlock() {
+ /* Move down until it hits something */
+ while( !checkCollision(0, 1) ) {
+ moveBlock(0, 1);
+
+ /* Add delay to make falling effect */
+ delay(5);
+ }
+
+ /* Move to cur_block to the backlayer */
+ drawSprite(buttonLayer, x_pos, y_pos, cur_block);
+}
+
+/* Check and delete full rows(starting at `start`) */
+void handleFullRows(int start) {
+ int i = start;
+ while(i < 16) {
+ /* If row is full */
+ if( buttonLayer[15 - i] == 0xFF) {
+ /* Drop all layers ontop */
+ for( int j = i; j < 16; j++ ){
+ buttonLayer[15 - j] = buttonLayer[14 - j];
+ }
+ } else {
+ i++;
+ }
+ }
+}
+
+/* Draw first 8 bytes on first desplay and second 8 on last */
+void renderAll() {
+#if RENDER_TO_SERIAL == 1
+ renderToSerial();
+ return;
+#endif
+
+ render(0, 0);
+ render(1, 8);
+}
+
+/*
+ * Input Handling
+ */
+unsigned long leftLast, rightLast, dropLast, rotateLast;
+
+void handleButtons() {
+ /* Read from switches */
+ int leftState = !digitalRead(LEFT_PIN);
+ int rightState = !digitalRead(RIGHT_PIN);
+ int dropState = !digitalRead(DROP_PIN);
+ int rotateState = !digitalRead(ROTATE_PIN);
+
+ /* Check if last click is over 100 ms */
+ if( leftState && millis() - leftLast > CLICK_TIME ) {
+ leftLast = millis();
+
+ /* Move left */
+ if( !checkCollision(1, 0) )
+ moveBlock(1, 0);
+ }
+
+ /* Repeat for others buttons */
+ if( rightState && millis() - rightLast > CLICK_TIME ) {
+ rightLast = millis();
+ if( !checkCollision(-1, 0) )
+ moveBlock(-1, 0);
+ }
+
+ if( dropState && millis() - dropLast > CLICK_TIME + 100 ){
+ dropLast = millis();
+ dropBlock();
+ }
+
+ if( rotateState && millis() - rotateLast > CLICK_TIME + 100 ){
+ rotateLast = millis();
+ rotateBlock();
+ }
}
diff --git a/drawing.h b/drawing.h
index 9089d9b..24a033a 100644
--- a/drawing.h
+++ b/drawing.h
@@ -18,7 +18,8 @@ void drawSprite(uint8_t layer[], uint8_t x, uint8_t y, struct Sprite* sprite);
void clearBuffer(uint8_t layer[] );
/* Screen interface commands */
-void render(uint8_t screenBuffer[], unsigned int where);
+void render(int display, unsigned int where);
+void renderToSerial();
void initDisplays(int display);
#endif
diff --git a/drawing.ino b/drawing.ino
index b326c7f..7269f08 100644
--- a/drawing.ino
+++ b/drawing.ino
@@ -31,7 +31,7 @@ void clearBuffer(uint8_t layer[] ) {
* device: Which screen
* where: It render the next 8 bytes from this index
*/
-void render(int device, uint8_t screenBuffer[], unsigned int where) {
+void render(int display, unsigned int where) {
static uint8_t onScreen[BUFF_HEIGHT];
static unsigned long reRenderLast;
@@ -44,13 +44,13 @@ void render(int device, uint8_t screenBuffer[], unsigned int where) {
/* Will draw 8 lines from /where/. */
for(i = where; i < (where + 8); i++) {
- toWrite = screenbuffer[i];
+ toWrite = topLayer[i] | buttonLayer[i];
/* Check if whats on screen is the same */
if(onScreen[i] == toWrite && !reRender)
continue;
- writeCommand(device, maxDIGIT_0 + i - where, toWrite);
+ writeCommand(display, maxDIGIT_0 + i - where, toWrite);
/* Keep track of whats on screen */
onScreen[i] = toWrite;
@@ -61,8 +61,37 @@ void render(int device, uint8_t screenBuffer[], unsigned int where) {
}
+/* Renders all 16 bytes to screen */
+void renderToSerial() {
+ /* Send terminal clear characters(https://stackoverflow.com/questions/10105666/clearing-the-terminal-screen) */
+ Serial.write(27);
+ Serial.print("[2J");
+ Serial.write(27);
+ Serial.print("[H");
+
+ /* For every line */
+ for( int i = 0; i < 16; i++ ) {
+ uint8_t toWrite = topLayer[i] | buttonLayer[i];
+
+ /* For every bit in line */
+ for( int bit = 0; bit < 8; bit++)
+ Serial.print( ( toWrite & ( 1 << 7 - bit ) ) > 0 );
+
+ Serial.println();
+
+ }
+}
+
/* Write a register to specified display */
static void writeCommand(int display, uint8_t addr, uint8_t data) {
+ Serial.print("Writing byte ");
+ Serial.print(data);
+ Serial.print(" to addr ");
+ Serial.print(addr);
+ Serial.print(" on display ");
+ Serial.println(display);
+
+
/* Chip select low */
digitalWrite(CS, LOW);
@@ -73,7 +102,7 @@ static void writeCommand(int display, uint8_t addr, uint8_t data) {
/* If the device is number two, the commands should be shiftet through
* Each MAX, holds 16 bits(2 bytes) */
- serialPad(curDisplay * 2);
+ serialPad(display * 2);
digitalWrite(CS, HIGH);
@@ -84,14 +113,24 @@ static void writeCommand(int display, uint8_t addr, uint8_t data) {
/* Init specified display */
void initDisplays(int display) {
-
+ /* Clear all registers */
+ for( int i = 0; i < 0x0F; i++)
+ writeCommand(display, i, 0);
+
+ /* Turn on(1 is shutdown disable) */
+ writeCommand(display, maxSHUTDOWN_INV, 1);
+
+ /* Darker please */
+ writeCommand(display, maxINTENSITY, 0x00);
+
+ /* Activate all lines */
+ writeCommand(display, maxSCAN_LIMIT, 0x07);
}
-/* Send x amount of empty bytes, recursively(for fun)*/
+/* Send x amount of empty bytes */
static void serialPad(int count) {
- shiftOut(DATA_IN, CLK, MSBFIRST, 0);
-
- if ( count )
- serialPad(count-1);
+ for( int i = 0; i < count; i++ ) {
+ shiftOut(DATA_IN, CLK, MSBFIRST, 0);
+ }
}
diff --git a/sprites.h b/sprites.h
index a951167..9cf0f1b 100644
--- a/sprites.h
+++ b/sprites.h
@@ -184,7 +184,7 @@ struct Sprite lBlockL = {
0b01000000,
0b01000000,
0b00000000,
- }, 3, 2, NULL
+ }, 2, 3, NULL
};
struct Sprite *blocks[] = { &iBlock, &oBlock, &tBlock, &sBlock, &zBlock, &jBlock, &lBlock };