From d70a67cc9ac043398c1ebddc5400c104caf242fb Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Tue, 27 Apr 2021 22:18:15 +0300 Subject: [PATCH] some fixes (still works badly) --- F1-nolib/Tetris/TETRIS.bin | Bin 18532 -> 19476 bytes F1-nolib/Tetris/debug.h | 35 ++++++++ F1-nolib/Tetris/fonts.c | 4 +- F1-nolib/Tetris/screen.c | 20 +---- F1-nolib/Tetris/snake.c | 7 +- F1-nolib/Tetris/tetris.c | 175 +++++++++++++++++++++++-------------- 6 files changed, 157 insertions(+), 84 deletions(-) create mode 100644 F1-nolib/Tetris/debug.h diff --git a/F1-nolib/Tetris/TETRIS.bin b/F1-nolib/Tetris/TETRIS.bin index 5ba973d657ef86de9e50952108990f1757f55ae3..4c9d506232dcef72c9b8d5c502400a96eb8abd2a 100755 GIT binary patch delta 5765 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 o*4o}OZDA52d|PMx4@Tj}K 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 NGzOq=W+SfrzXRAP+P?q* diff --git a/F1-nolib/Tetris/debug.h b/F1-nolib/Tetris/debug.h new file mode 100644 index 0000000..994b878 --- /dev/null +++ b/F1-nolib/Tetris/debug.h @@ -0,0 +1,35 @@ +/* + * This file is part of the TETRIS project. + * Copyright 2021 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#ifndef DEBUG_H__ +#define DEBUG_H__ + +#ifdef EBUG +#include "usb.h" +#include "proto.h" +#define DBG(x) USB_send(x) +#define DBGU(x) USB_send(u2str(x)) +#define NL() USB_send("\n") +#else // EBUG +#define DBG(x) +#define DBGU(x) +#define NL() +#endif // EBUG + +#endif // DEBUG_H__ + diff --git a/F1-nolib/Tetris/fonts.c b/F1-nolib/Tetris/fonts.c index 6396688..2136cfa 100644 --- a/F1-nolib/Tetris/fonts.c +++ b/F1-nolib/Tetris/fonts.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include "debug.h" #include "fonts.h" /* Bash-script to generate the symbols @@ -304,8 +305,6 @@ done static const afont FONTS[] = { [FONT14] = {font14_table, font14_encoding, FONT14HEIGHT, FONT14BYTES, FONT14BASELINE}, -// [FONTN16] = {fontNumb16_table, fontNumb16_encoding, FONTNUMB16HEIGHT, FONTNUMB16BYTES, FONTNUMB16BASELINE}, -// [FONTN10] = {fontNumb10_table, fontNumb10_encoding, FONTNUMB10HEIGHT, FONTNUMB10BYTES, FONTNUMB10BASELINE}, [FONTN8] = {fontNumb8_table, fontNumb8_encoding, FONTNUMB8HEIGHT, FONTNUMB8BYTES, FONTNUMB8BASELINE}, }; @@ -324,6 +323,7 @@ int choose_font(font_t newfont){ const uint8_t *font_char(uint8_t Char){ uint8_t idx = curfont->enctable[Char]; + //DBG("font_char("); DBGU(Char); DBG(")="); DBGU(idx); NL(); if(!idx) return NULL; // no this character in font return &(curfont->font[idx*(curfont->bytes+1)]); } diff --git a/F1-nolib/Tetris/screen.c b/F1-nolib/Tetris/screen.c index 10481f2..14bf718 100644 --- a/F1-nolib/Tetris/screen.c +++ b/F1-nolib/Tetris/screen.c @@ -18,10 +18,11 @@ #include // memset, memcpy #include +#include "debug.h" #include "fonts.h" #include "hardware.h" #include "screen.h" -//#include "usb.h" + // !!!FOR LITTLE-ENDIAN!!! @@ -106,6 +107,7 @@ uint8_t DrawCharAt(int16_t X, int16_t Y, uint8_t Char){ * @return - text width in pixels */ uint8_t PutStringAt(int16_t X, int16_t Y, const char *str){ + DBG("PutStringAt("); DBGU(X); DBG(", "); DBGU(Y); DBG(", \""); DBG(str); DBG("\"\n"); if(!str) return 0; int16_t Xold = X; while(*str){ @@ -169,22 +171,6 @@ void process_screen(){ } } break; - /*for(int i = 0; i < 32; ++i){ - DrawPix(0,i,0b11111111); - DrawPix(1,i,0b1001010); - DrawPix(2,i,0b00100101); - DrawPix(20,i,0b11100000); - DrawPix(21,i,0b10000000); - DrawPix(22,i,0b00100000); - DrawPix(30,i,0b00011100); - DrawPix(31,i,0b00010000); - DrawPix(32,i,0b00000100); - DrawPix(60,i,0b00000011); - DrawPix(61,i,0b00000010); - DrawPix(62,i,0b00000001); - }*/ - // memset -> halt - //memset(screenbuf, pattern, SCREENBUF_SZ); default: return; } diff --git a/F1-nolib/Tetris/snake.c b/F1-nolib/Tetris/snake.c index b98995b..f3df5cd 100644 --- a/F1-nolib/Tetris/snake.c +++ b/F1-nolib/Tetris/snake.c @@ -34,7 +34,7 @@ // cut - -1 to size #define CUT_COLOR (0b11100000) // chance of CUT appears when drawing food (/1000) -#define CUT_PROMILLE (33) +#define CUT_PROMILLE (80) // score - +10 to score #define SCORE_COLOR (0b00000001) // add this to score after each SCORE_COLOR eating @@ -176,6 +176,11 @@ static int move_snake(){ } // check borders: they could be broken when `balls` activated if(snake[0].x >= SCREEN_WIDTH || snake[0].y >= SCREEN_HEIGHT) return 0; + if(getRand() % 1000 < SCORE_PROMILLE){ // add ++score + point pt = RandCoords(); + if(pt.x && pt.y) + DrawPix(pt.x, pt.y, SCORE_COLOR); + } return 1; } diff --git a/F1-nolib/Tetris/tetris.c b/F1-nolib/Tetris/tetris.c index 951c876..92981f9 100644 --- a/F1-nolib/Tetris/tetris.c +++ b/F1-nolib/Tetris/tetris.c @@ -18,31 +18,31 @@ #include "adcrandom.h" #include "buttons.h" +#include "debug.h" +#include "fonts.h" #include "screen.h" #include "tetris.h" -#include "usb.h" -#include "proto.h" - // backround color #define BACKGROUND_COLOR (COLOR_BLACK) -#define CUP_COLOR (COLOR_LRED) +#define FOREGROUND_COLOR (COLOR_YELLOW) +#define CUP_COLOR (COLOR_CYAN) // height of cup #define CUPHEIGHT (30) #define CUPWIDTH (20) // screen coordinate of x=0 @ cup -#define CUPX0 (1) +#define CUPX0 (7) // screen coordinate of y=0 @ cup (Y grows upside down) #define CUPY0 (0) // coordinates of "NEXT figure" -#define NEXTX0 (30) -#define NEXTY0 (4) +#define NEXTX0 (-5) +#define NEXTY0 (SCREEN_HEIGHT/2-2) #define xmax (CUPWIDTH-1) #define ymax (CUPHEIGHT-1) // min speed -#define MAXSTEPMS (199) +#define MAXSTEPMS (299) // max speed / drop speed #define MINSTEPMS (19) // each NXTSPEEDSCORE of score the speed will be increased @@ -62,41 +62,41 @@ typedef struct{ // L: 00, 01, 02, 10 + 2 = 0x22, 0x23, 0x24, 0x32 static const figure L = { .f = {0x22, 0x23, 0x24, 0x32}, - .color = COLOR_LBLUE + .color = 0b00000001 }; // J: 00, 01, 02, -10 + 2 = 0x22, 0x23, 0x24, 0x12 static const figure J = { .f = {0x22, 0x23, 0x24, 0x12}, - .color = COLOR_BLUE + .color = 0b00000100 }; // O: 00, 01, 10, 11 + 2 = 0x22, 0x23, 0x32, 0x33 static const figure O = { .f = {0x22, 0x23, 0x32, 0x33}, - .color = COLOR_YELLOW + .color = 0b00000101 }; // I: 0-1, 00, 01, 02 + 2 = 0x21, 0x22, 0x23, 0x24 static const figure I = { .f = {0x21, 0x22, 0x23, 0x24}, - .color = COLOR_CYAN + .color = 0b00100000 }; // S: -10, 00, 01, 11 + 2 = 0x12, 0x22, 0x23, 0x33 static const figure S = { .f = {0x12, 0x22, 0x23, 0x33}, - .color = COLOR_LGREEN + .color = 0b00100001 }; -// Z: -11, 01, 00, 10 + 2 = 0x13, 0x23, 0x23, 0x32 +// Z: -11, 01, 00, 10 + 2 = 0x13, 0x23, 0x22, 0x32 static const figure Z = { - .f = {0x13, 0x23, 0x23, 0x32}, - .color = COLOR_GREEN + .f = {0x13, 0x23, 0x22, 0x32}, + .color = 0b00100100 }; // T: -10, 01, 00, 10 + 2 = 0x12, 0x23, 0x22, 0x32 static const figure T = { .f = {0x12, 0x23, 0x22, 0x32}, - .color = COLOR_PURPLE + .color = 0b00100101 }; #define FIGURESNUM (7) @@ -111,34 +111,51 @@ static uint32_t nextSpeedScore = 0; // chk if figure can be put to (x,y); @return 1 if empty static int chkfigure(int x, int y, const figure *F){ - if(x < 0 || x > xmax) return 0; - if(y < 0 || y > ymax) return 0; + DBG("CHKFIG: x="); DBGU(x); DBG(", y="); DBGU(y); DBG(" ... "); + if(x < 0 || x > xmax){ + DBG("x<0 || >xmax\n"); + return 0; + } + if(y < 0 || y > ymax){ + DBG("y<0 || > ymax\n"); + return 0; + } for(int i = 0; i < 4; ++i){ int xn = x + GETX(F->f[i]), yn = y + GETY(F->f[i]); - if(yn > ymax || yn < 0) return 0; - if(xn < 0 || xn > xmax || yn < 0) return 0; // border - if(GetPix(xn ,yn) != BACKGROUND_COLOR) return 0; // occupied + if(yn > ymax){ + DBG("y > ymax\n"); + return 0; + } + if(xn < 0 || xn > xmax){ // border + DBG("x out of borders\n"); + return 0; + } + if(GetPix(CUPX0 + xn, CUPY0 + yn) != BACKGROUND_COLOR){ // occupied + DBG("occupied\n"); + return 0; + } } + DBG("good\n"); return 1; } // clear figure from old location static void clearfigure(int x, int y){ - USB_send("Clear @ "); USB_send(u2str(x)); USB_send(", "); USB_send(u2str(y)); USB_send("\n"); + DBG("Clear @ "); DBGU(x); DBG(", "); DBGU(y); NL(); for(int i = 0; i < 4; ++i){ int xn = x + GETX(curfigure.f[i]), yn = y + GETY(curfigure.f[i]); - if(xn < 0 || xn > xmax || yn < 0 || yn > ymax) continue; // out of cup - DrawPix(xn, yn, BACKGROUND_COLOR); + //if(xn < 0 || xn > xmax || yn < 0 || yn > ymax) continue; // out of cup + DrawPix(CUPX0 + xn, CUPY0 + yn, BACKGROUND_COLOR); } } // put figure into new location static void putfigure(int x, int y, figure *F){ - USB_send("Put @ "); USB_send(u2str(x)); USB_send(", "); USB_send(u2str(y)); USB_send("\n"); + DBG("Put @ "); DBGU(x); DBG(", "); DBGU(y); NL(); for(int i = 0; i < 4; ++i){ int xn = x + GETX(F->f[i]), yn = y + GETY(F->f[i]); - if(xn < 0 || xn > xmax || yn < 0 || yn > ymax) continue; // out of cup - DrawPix(xn, yn, F->color); + //if(xn < 0 || xn > xmax || yn < 0 || yn > ymax) continue; // out of cup + DrawPix(CUPX0 + xn, CUPY0 + yn, F->color); } } @@ -149,10 +166,10 @@ static void rotatefigure(int dir, figure *F){ int x = GETX(F->f[i]), y = GETY(F->f[i]), xn, yn; if(dir > 0){ // CW xn = y; yn = -x; - USB_send("Rotate CW\n"); + DBG("Rotate CW\n"); }else if(dir < 0){ // CCW xn = -y; yn = x; - USB_send("Rotate CCW\n"); + DBG("Rotate CCW\n"); } nF.f[i] = ((xn + 2) << 4) | (yn + 2); } @@ -165,19 +182,20 @@ static int checkandroll(){ for(int y = 0; y < CUPHEIGHT; ++y){ int N = 0; for(int x = 0; x < CUPWIDTH; ++x) - if(GetPix(x, y) != BACKGROUND_COLOR) ++N; + if(GetPix(CUPX0 + x, CUPY0 + y) != BACKGROUND_COLOR) ++N; if(N == 0) upper = y; else if(N == CUPWIDTH){ // full line - roll all upper + DBG("========= Full row! ========= "); DBG("y="); DBGU(y); DBG(", upper="); DBGU(upper); NL(); ++ret; - for(int yy = y; yy <= upper; --yy){ + for(int yy = y; yy > upper; --yy){ uint8_t *ptr = &screenbuf[(yy+CUPY0)*SCREEN_WIDTH + CUPX0]; for(int x = 0; x < CUPWIDTH; ++x, ++ptr) - *ptr = ptr[-CUPWIDTH]; // copy upper row into the current + *ptr = ptr[-SCREEN_WIDTH]; // copy upper row into the current } ++upper; } } - USB_send("Roll="); USB_send(u2str(ret)); USB_send("\n"); + DBG("Roll="); DBGU(ret); NL(); return ret; } @@ -195,11 +213,17 @@ static int getrand(){ // return 0 if cannot move static int mvfig(int *x, int *y, int dx){ register int xx = *x, yy = *y; - int xnew = xx+dx, ynew = yy+1, ret = 1; + DBG("MVFIG: x="); DBGU(*x); DBG(", y="); DBGU(*y); DBG(", dx="); DBGU(dx); NL(); + int ret = 1; clearfigure(xx, yy); - if(chkfigure(xnew, ynew, &curfigure)){ - xx = xnew; yy = ynew; - *x = xx; *y = yy; + // check dx: + if(dx){ + if(chkfigure(xx+dx, yy, &curfigure)){ + xx = xx + dx; *x = xx; + }else ret = 0; + } + if(chkfigure(xx, yy+1, &curfigure)){ + ++yy; *y = yy; }else ret = 0; putfigure(xx, yy, &curfigure); return ret; @@ -208,6 +232,7 @@ static int mvfig(int *x, int *y, int dx){ // dir == -1 - left, 1 - right static void rotfig(int x, int y, int dir){ if(!dir) return; + DBG("Rotate "); DBGU(dir); NL(); figure newF = curfigure; rotatefigure(dir, &newF); clearfigure(x, y); @@ -219,95 +244,117 @@ static void rotfig(int x, int y, int dir){ // draw current & next figures; return 0 if can't static int drawnext(){ + DBG("\n\nDraw next figure\n"); curfigure = nextfigure; clearfigure(NEXTX0, NEXTY0); // clear NEXT nextfigure = *figures[getrand()]; putfigure(NEXTX0, NEXTY0, &nextfigure); - xf = xmax/2; yf = ymax/2; + xf = xmax/2; yf = 1; if(!chkfigure(xf, yf, &curfigure)) return 0; // can't draw next putfigure(xf, yf, &curfigure); + Tlast = Tms; + incSpd = StepMS; return 1; } void tetris_init(){ setBGcolor(BACKGROUND_COLOR); + setFGcolor(FOREGROUND_COLOR); + choose_font(FONT14); ClearScreen(); ScreenON(); - StepMS = MAXSTEPMS; - Tlast = Tms; - incSpd = StepMS; score = 0; nextSpeedScore = NXTSPEEDSCORE; + StepMS = MAXSTEPMS; // draw cup for(int y = 0; y < CUPHEIGHT; ++y){ - DrawPix(CUPX0, CUPY0 + y, CUP_COLOR); + DrawPix(CUPX0-1, CUPY0 + y, CUP_COLOR); DrawPix(CUPX0 + CUPWIDTH, CUPY0 + y, CUP_COLOR); } - for(int x = 0; x < CUPWIDTH; ++x) - DrawPix(CUPX0 + x, CUPY0 + CUPHEIGHT, CUP_COLOR); + for(int x = 0; x < CUPWIDTH + 2; ++x) + DrawPix(CUPX0 - 1 + x, CUPY0 + CUPHEIGHT, CUP_COLOR); nextfigure = *figures[getrand()]; + PutStringAt(CUPX0 + CUPWIDTH + 5, CUPY0 + 5 + curfont->height, "0 "); drawnext(); } // process tetris game; @return 0 if game is over int tetris_process(){ - uint8_t moveX = 0, rot = 0; - keyevent evt; + static int moveX = 0, rot = 0; static uint8_t paused = 0; + keyevent evt; + if(Tms == Tlast) return 1; +#define EVENT(x) ((keystate(x, &evt) && evt == EVT_PRESS) || keyevt(x) == EVT_HOLD) // change moving direction if(keystate(KEY_U, &evt) && (evt == EVT_PRESS || evt == EVT_HOLD)){ // UP - pause if(paused){ - USB_send("Tetris resume\n"); + DBG("----> Tetris resume\n"); paused = 0; }else{ - USB_send("Tetris paused\n"); + DBG("----> Tetris paused\n"); paused = 1; } } - if(keystate(KEY_D, &evt) && evt == EVT_PRESS){ // Down - drop - incSpd = MINSTEPMS; - } - if(keystate(KEY_L, &evt) && evt == EVT_PRESS){ // L - left - moveX = -1; - } - if(keystate(KEY_R, &evt) && evt == EVT_PRESS){ // Right - moveX = 1; - } - if(keystate(KEY_M, &evt) && evt == EVT_PRESS){ // Menu - rotate CCW - rot = -1; - } - if(keystate(KEY_S, &evt) && evt == EVT_PRESS){ // Set - rotate CW - rot = 1; + if(!paused){ + if(keystate(KEY_D, &evt) && evt == EVT_PRESS){ // Down - drop + incSpd = MINSTEPMS; + } + if(EVENT(KEY_L)){ // L - left + moveX = -1; + } + if(EVENT(KEY_R)){ // Right + moveX = 1; + } + if(EVENT(KEY_M)){ // Menu - rotate CCW + rot = 1; + } + if(EVENT(KEY_S)){ // Set - rotate CW + rot = -1; + } } +#undef EVENT clear_events(); if(Tms - Tlast > incSpd){ Tlast = Tms; if(paused) return 1; int xnew = xf, ynew = yf; - if(rot) rotfig(xf, yf, rot); + if(rot){ + rotfig(xf, yf, rot); + rot = 0; + } + DBG("Move down 1px\n"); if(!mvfig(&xnew, &ynew, moveX) && ynew == yf){ // can't move: end of moving? + moveX = 0; int s = checkandroll(); switch(s){ // add score case 1: score += 1; + DBG("One line!\n"); break; case 2: score += 3; + DBG("Two lines!\n"); break; case 3: score += 7; + DBG("Three lines!\n"); break; case 4: score += 15; + DBG("Four lines!\n"); break; default: break; } + PutStringAt(CUPX0 + CUPWIDTH + 5, CUPY0 + 5 + curfont->height, u2str(score)); if(StepMS > MINSTEPMS && score > nextSpeedScore){ // increase speed --StepMS; nextSpeedScore += NXTSPEEDSCORE; } if(!drawnext()) return 0; + }else{ + moveX = 0; + xf = xnew; yf = ynew; } } return 1;