From 1823d4c21eb8af79c6ec3ce24c898f9faa40acff Mon Sep 17 00:00:00 2001 From: julian T Date: Sat, 29 Dec 2018 18:05:19 +0100 Subject: Copied all old functions over and it works --- Jetris.ino | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- drawing.h | 3 +- drawing.ino | 59 ++++++++++++++++++++----- sprites.h | 2 +- 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 }; -- cgit v1.2.3