From 3764be49dc1862084cb46b3d4c9968b068d9c65e Mon Sep 17 00:00:00 2001 From: ZERICO2005 <71151164+ZERICO2005@users.noreply.github.com> Date: Thu, 4 Jan 2024 21:10:25 -0700 Subject: [PATCH] v0.81.1 | 2024/01/04 21:00 | Nearest neighbor scaling is now supported on Windows. Fixed a bug with larger board sizes not picking the correct font size on Windows, which lead me to fix more things because (size_t)(uint24_t)(-5) results in different values on the two platforms. Additionally, I refactored the font data into a struct instead of the werid parallel array I had before. Did a few other things such as only registering mouse clicks if the mouse is over a tile, and making the ''Smiley face'' graphic update only when their is an expression change. --- CMakeLists.txt | 2 +- MineSweeper-Patterns.txt | 295 +++++++++++++++++++++++++++++ src-lcd/x86_Common_Def.h | 2 +- src-lcd/x86_Render.c | 86 ++++++--- src/Common_Def.h | 4 +- src/global.c | 6 +- src/mineSweeper.c | 394 +++++++++++++++++++++------------------ src/mineSweeper.h | 3 +- src/prime2D.c | 26 +-- 9 files changed, 587 insertions(+), 231 deletions(-) create mode 100644 MineSweeper-Patterns.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 508ca8b..7dc8ac0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,6 @@ add_executable(${PROJECT_NAME} ${SRC_FILES}) target_include_directories(${PROJECT_NAME} PUBLIC ${SRC_LCD_DIR}) # Compiler Flags Debug(-g -O0) Release(-O3) -set(OPT_FLAG -O3) +set(OPT_FLAG -g -O3) target_compile_options(${PROJECT_NAME} PUBLIC ${OPT_FLAG} -Wall -Wextra -Werror) target_link_libraries(${PROJECT_NAME} PUBLIC SDL2 SDL2main) diff --git a/MineSweeper-Patterns.txt b/MineSweeper-Patterns.txt new file mode 100644 index 0000000..d44b558 --- /dev/null +++ b/MineSweeper-Patterns.txt @@ -0,0 +1,295 @@ +# Classic + +..... +.111. +.1*1. +.111. +..... + +# Knight + +.1.1. +1...1 +..*.. +1...1 +.1.1. + +# Long Orthogonal + +..1.. +..1.. +11*11 +..1.. +..1.. + +# Diagonal + +1...1 +.1.1. +..*.. +.1.1. +1...1 + +# Target + +1...1 +..1.. +.1*1. +..1.. +1...1 + +# Clover + +...1. +1.1.. +.1*1. +..1.1 +.1... + +# Windmill + +.1... +.1.11 +..*.. +11.1. +...1. + +# X-Wing + +..... +11.11 +..*.. +11.11 +..... + +# Tye-Fighter + +..... +.1.1. +11*11 +.1.1. +..... + +# Near Orthogonal + +..... +..1.. +.1*1. +..1.. +..... + +# Doubled Orthogonal + +..... +.121. +.2*2. +.121. +..... + +# Doubled Diagonal + +..... +.212. +.1*1. +.212. +..... + +# Ship Wheel + +1.1.1 +.111. +11*11 +.111. +1.1.1 + +# Hashtag + +.1.1. +11111 +.1*1. +11111 +.1.1. + +# Doubled Target + +..1.. +..2.. +12*21 +..2.. +..1.. + +# Double Center Orthogonal + +..1.. +..2.. +12*21 +..2.. +..1.. + +# Taxicab Distance + +..1.. +.121. +12*21 +.121. +..1.. + +# Ring + +.111. +1...1 +1.*.1 +1...1 +.111. + +# Perimeter + +11111 +1...1 +1.*.1 +1...1 +11111 + +# Corners + +11.11 +1...1 +..*.. +1...1 +11.11 + +# Squared Corners + +11.11 +11.11 +..*.. +11.11 +11.11 + +# Orthogonal Spikes + +..1.. +.111. +11*11 +.111. +..1.. + +# Diagonal Spikes + +1...1 +.111. +.1*1. +.111. +1...1 + +# Plus Sign + +.111. +11.11 +1.*.1 +11.11 +.111. + +# No Corners + +.111. +11111 +11*11 +11111 +.111. + +# Swath + +11111 +11111 +11*11 +11111 +11111 + +# Euclidean + +..1.. +.232. +13*31 +.232. +..1.. + +# Wheel + +.111. +1.1.1 +11*11 +1.1.1 +.111. + +# Sponge + +11111 +1.1.1 +11*11 +1.1.1 +11111 + +# Ninja Star + +.11.. +..1.1 +11*11 +1.1.. +..11. + +# Vortex + +111.1 +..1.1 +11*11 +1.1.. +1.111 + +# Tripled Orthogonal + +..... +.131. +.3*3. +.131. +..... + +# Tripled Diagonal + +..... +.313. +.1*1. +.313. +..... + +# Tripled Center Orthogonal + +..1.. +..3.. +13*31 +..3.. +..1.. + +# Full House Orthogonal + +..... +.232. +.3*3. +.232. +..... + +# Full House Diagonal + +..... +.323. +.2*2. +.323. +..... + +# Full House Center Orthogonal + +..2.. +..3.. +23*32 +..3.. +..2.. \ No newline at end of file diff --git a/src-lcd/x86_Common_Def.h b/src-lcd/x86_Common_Def.h index 26fa4d2..5a6b294 100644 --- a/src-lcd/x86_Common_Def.h +++ b/src-lcd/x86_Common_Def.h @@ -1,5 +1,5 @@ /* -** Author: zerico2005 (2023) +** Author: zerico2005 (2023-2024) ** Project: Super-Sweeper ** License: MIT License ** A copy of the MIT License should be included with diff --git a/src-lcd/x86_Render.c b/src-lcd/x86_Render.c index 9912b26..82ab3f3 100644 --- a/src-lcd/x86_Render.c +++ b/src-lcd/x86_Render.c @@ -1,6 +1,6 @@ /* -** Author: zerico2005 (2023) -** Project: Endless-Super-Sweeper +** Author: zerico2005 (2023-2024) +** Project: Super-Sweeper ** License: MIT License ** A copy of the MIT License should be included with ** this project. If not, see https://opensource.org/license/MIT @@ -125,8 +125,8 @@ SDL_Texture* texture; int32_t x; int32_t y; uint32_t state = SDL_GetMouseState(&x,&y); - x /= scale; - y /= scale; + x = (x * LCD_RESX) / Master.resX; + y = (y * LCD_RESY) / Master.resY; if (posX != NULL) { *posX = x; } if (posY != NULL) { *posY = y; } return state; @@ -368,15 +368,17 @@ void blit16bpp(uint8_t* data) { for (uint32_t x = 0; x < LCD_RESX; x++) { uint32_t c = (uint32_t)((uint16_t*)videoCopy)[z]; c *= 3; - for (uint8_t s = 0; s < scale; s++) { + uint8_t lenX = ((Master.resX * (x + 1)) / LCD_RESX) - ((Master.resX * x) / LCD_RESX); + for (uint8_t s = 0; s < lenX; s++) { data[w] = PreCalc16[c]; w++; data[w] = PreCalc16[c + 1]; w++; data[w] = PreCalc16[c + 2]; w++; } z++; } - w += Master.pitch - (LCD_RESX * scale * 3); - for (uint8_t s = 0; s < scale - 1; s++) { + uint8_t lenY = ((Master.resY * (y + 1)) / LCD_RESY) - ((Master.resY * y) / LCD_RESY); + //w += Master.pitch - (LCD_RESX * lenY * 3); + for (uint8_t s = 0; s < lenY - 1; s++) { memcpy(&data[w],&data[w - Master.pitch],Master.pitch); w += Master.pitch; } @@ -389,15 +391,17 @@ void blit8bpp(uint8_t* data) { for (uint32_t y = 0; y < LCD_RESY; y++) { for (uint32_t x = 0; x < LCD_RESX; x++) { videoCopyArray; - for (uint8_t s = 0; s < scale; s++) { + uint8_t lenX = ((Master.resX * (x + 1)) / LCD_RESX) - ((Master.resX * x) / LCD_RESX); + for (uint8_t s = 0; s < lenX; s++) { data[w] = colorR[c]; w++; data[w] = colorG[c]; w++; data[w] = colorB[c]; w++; } z++; } - w += Master.pitch - (LCD_RESX * scale * 3); - for (uint8_t s = 0; s < scale - 1; s++) { + uint8_t lenY = ((Master.resY * (y + 1)) / LCD_RESY) - ((Master.resY * y) / LCD_RESY); + //w += Master.pitch - (LCD_RESX * lenY * 3); + for (uint8_t s = 0; s < lenY - 1; s++) { memcpy(&data[w],&data[w - Master.pitch],Master.pitch); w += Master.pitch; } @@ -411,7 +415,8 @@ void blit4bpp(uint8_t* data) { for (uint32_t y = 0; y < LCD_RESY; y++) { for (uint32_t x = 0; x < LCD_RESX / PixelsPerByte; x++) { videoCopyArray; - for (uint8_t s = 0; s < scale; s++) { + uint8_t lenX = ((Master.resX * (x + 1)) / LCD_RESX) - ((Master.resX * x) / LCD_RESX); + for (uint8_t s = 0; s < lenX; s++) { data[w] = colorR[c & 0xF]; w++; data[w] = colorG[c & 0xF]; w++; data[w] = colorB[c & 0xF]; w++; @@ -421,8 +426,9 @@ void blit4bpp(uint8_t* data) { } z++; } - w += Master.pitch - (LCD_RESX * scale * 3); - for (uint8_t s = 0; s < scale - 1; s++) { + uint8_t lenY = ((Master.resY * (y + 1)) / LCD_RESY) - ((Master.resY * y) / LCD_RESY); + //w += Master.pitch - (LCD_RESX * lenY * 3); + for (uint8_t s = 0; s < lenY - 1; s++) { memcpy(&data[w],&data[w - Master.pitch],Master.pitch); w += Master.pitch; } @@ -436,7 +442,8 @@ void blit2bpp(uint8_t* data) { for (uint32_t y = 0; y < LCD_RESY; y++) { for (uint32_t x = 0; x < LCD_RESX / PixelsPerByte; x++) { videoCopyArray; - for (uint8_t s = 0; s < scale; s++) { + uint8_t lenX = ((Master.resX * (x + 1)) / LCD_RESX) - ((Master.resX * x) / LCD_RESX); + for (uint8_t s = 0; s < lenX; s++) { data[w] = colorR[c & 0x3]; w++; data[w] = colorG[c & 0x3]; w++; data[w] = colorB[c & 0x3]; w++; @@ -452,8 +459,9 @@ void blit2bpp(uint8_t* data) { } z++; } - w += Master.pitch - (LCD_RESX * scale * 3); - for (uint8_t s = 0; s < scale - 1; s++) { + uint8_t lenY = ((Master.resY * (y + 1)) / LCD_RESY) - ((Master.resY * y) / LCD_RESY); + //w += Master.pitch - (LCD_RESX * lenY * 3); + for (uint8_t s = 0; s < lenY - 1; s++) { memcpy(&data[w],&data[w - Master.pitch],Master.pitch); w += Master.pitch; } @@ -467,7 +475,8 @@ void blit1bpp(uint8_t* data) { for (uint32_t y = 0; y < LCD_RESY; y++) { for (uint32_t x = 0; x < LCD_RESX / PixelsPerByte; x++) { videoCopyArray; - for (uint8_t s = 0; s < scale; s++) { + uint8_t lenX = ((Master.resX * (x + 1)) / LCD_RESX) - ((Master.resX * x) / LCD_RESX); + for (uint8_t s = 0; s < lenX; s++) { for (uint8_t b = 0; b < 8; b++) { data[w] = colorR[(c >> b) & 0x1]; w++; data[w] = colorG[(c >> b) & 0x1]; w++; @@ -476,8 +485,9 @@ void blit1bpp(uint8_t* data) { } z++; } - w += Master.pitch - (LCD_RESX * scale * 3); - for (uint8_t s = 0; s < scale - 1; s++) { + uint8_t lenY = ((Master.resY * (y + 1)) / LCD_RESY) - ((Master.resY * y) / LCD_RESY); + //w += Master.pitch - (LCD_RESX * lenY * 3); + for (uint8_t s = 0; s < lenY - 1; s++) { memcpy(&data[w],&data[w - Master.pitch],Master.pitch); w += Master.pitch; } @@ -618,8 +628,10 @@ void initLCDcontroller() { Master.vram = calloc((size_t)Master.resY * Master.pitch, sizeof(uint8_t)); if (Master.vram == NULL) { printf("\nMaster.vram is NULL"); fflush(stdout); return; } SDL_Init(SDL_INIT_VIDEO); - window = SDL_CreateWindow("Endless-Super-Sweeper", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, LCD_RESX * scale, LCD_RESY * scale,SDL_WINDOW_RESIZABLE); - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + window = SDL_CreateWindow("Super-Sweeper", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, LCD_RESX * scale, LCD_RESY * scale,SDL_WINDOW_RESIZABLE); + SDL_SetWindowMinimumSize(window, RESX_MINIMUM, RESY_MINIMUM); + SDL_SetWindowMaximumSize(window, RESX_MAXIMUM, RESY_MAXIMUM); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB24,SDL_TEXTUREACCESS_STREAMING, LCD_RESX * scale, LCD_RESY * scale); @@ -633,15 +645,29 @@ bool windowResizingCode(uint32_t* resX, uint32_t* resY) { static int32_t rX = 0, rY = 0; SDL_GetWindowSize(window,&x,&y); if ((rX != x || rY != y) && (rX != 0 && rY != 0)) { - if (x < RESX_MINIMUM) { x = RESX_MINIMUM; } - if (y < RESY_MINIMUM) { y = RESY_MINIMUM; } - if (x > RESX_MAXIMUM) { x = RESX_MAXIMUM; } - if (y > RESY_MAXIMUM) { y = RESY_MAXIMUM; } - if (x & 0x3) { x = x & ~0x3; } // Sets resX to a multiple of 4 so I don't have to deal with padded and unpadded image buffers - - scale = MIN(x / LCD_RESX, y / LCD_RESY); - x = LCD_RESX * scale; - y = LCD_RESY * scale; + valueLimit(x,RESX_MINIMUM,RESX_MAXIMUM); + valueLimit(y,RESY_MINIMUM,RESY_MAXIMUM); + + if (x & 0x3) { x = x & ~0x3; } + + // const fp64 MaximumAspectRatio = 1.35; + // fp64 aspectRatio = ((fp64)x / (fp64)LCD_RESX) / ((fp64)y / (fp64)LCD_RESY); + // if (aspectRatio > MaximumAspectRatio) { + // x = (int32_t)(MaximumAspectRatio * ((fp64)y / (fp64)LCD_RESY) * (fp64)LCD_RESX); + // } else if (aspectRatio < 1.0 / MaximumAspectRatio) { + // y = (int32_t)(MaximumAspectRatio * ((fp64)x / (fp64)LCD_RESX) * (fp64)LCD_RESY); + // } + + fp64 scaleVal = MIN((fp64)x / (fp64)LCD_RESX,(fp64)y / (fp64)LCD_RESY); + x = (int32_t)(scaleVal * (fp64)LCD_RESX); + y = (int32_t)(scaleVal * (fp64)LCD_RESY); + + // Sets resX to a multiple of 4 so I don't have to deal with padded and unpadded image buffers + if (x & 0x3) { x = x & ~0x3; } + + // scale = MIN(x / LCD_RESX, y / LCD_RESY); + // x = LCD_RESX * scale; + // y = LCD_RESY * scale; SDL_SetWindowSize(window,x,y); SDL_RenderSetLogicalSize(renderer, x, y); diff --git a/src/Common_Def.h b/src/Common_Def.h index 581e4b9..de0a263 100644 --- a/src/Common_Def.h +++ b/src/Common_Def.h @@ -1,5 +1,5 @@ /* -** Author: zerico2005 (2023) +** Author: zerico2005 (2023-2024) ** Project: Super-Sweeper ** License: MIT License ** A copy of the MIT License should be included with @@ -14,7 +14,7 @@ #define PROGRAM_V_MAJOR 0 #define PROGRAM_V_MINOR 81 -#define PROGRAM_V_PATCH 0 +#define PROGRAM_V_PATCH 1 //#define PLATFORM_TI84CE #define PLATFORM_X86 diff --git a/src/global.c b/src/global.c index 7167fb0..a6c44b7 100644 --- a/src/global.c +++ b/src/global.c @@ -112,7 +112,7 @@ const uint8_t hiddenText[43] = { //SuperSweeper V:X.XX.X ZERICO2005 YYYY/MM/DD (PROGRAM_V_MAJOR),34,((PROGRAM_V_MINOR) / 10),((PROGRAM_V_MINOR) % 10),34,PROGRAM_V_PATCH, /* Version */ 32,89,68,81,72,66,78,2,0,0,5,32, /* Text */ 2,0,2,4,36, /* Year */ - 0,1,36,0,2, /* Month Day */ + 0,1,36,0,4, /* Month Day */ }; const uint8_t hiddenTextLength = 43; @@ -223,10 +223,6 @@ const int8_t order[360] = { 0,2,0,1,0,1,0,-1,0,-1,0,-2, 2,0,1,0,1,0,-1,0,-1,0,-2,0, 1,1,1,-1,-1,1,-1,-1 }; -const uint8_t fontArray[40] = { - 0,0,0,1,1,2,2,2, 6,8,8,8,10,9,11,13, 8,8,10,8,10,11,13,13, 1,2,2,1,2,1,2,3, 1,1,2,1,2,1,2,2 -}; - uint8_t bX[18] = {14,20,24,29,32,34, 34,36,40,47,54,56, 14,24,32,34,40,54}; //Plus 4 uint8_t bY[18] = {14,14,16,19,20,22, 25,28,29,29,29,31, 14,16,20,25,29,29}; //Plus 4 uint24_t bM[18] = {10,18,30,54,72,90, 108,136,180,240,300,3, 10,30,72,108,180,300}; diff --git a/src/mineSweeper.c b/src/mineSweeper.c index 1891dcc..eecfff7 100644 --- a/src/mineSweeper.c +++ b/src/mineSweeper.c @@ -1,5 +1,5 @@ /* -** Author: zerico2005 (2023) +** Author: zerico2005 (2023-2024) ** Project: Super-Sweeper ** License: MIT License ** A copy of the MIT License should be included with @@ -18,6 +18,25 @@ //#include +/* Data */ + struct FontSizeData { + uint8_t fontType; + uint8_t disX; + uint8_t disY; + uint8_t padX; + uint8_t padY; + uint8_t maxX; + uint8_t maxY; + }; typedef struct FontSizeData FontSizeData; + + enum FontSizeList {FontSize_3x5,FontSize_5x5,FontSize_6x8}; + + const FontSizeData fontSizeData[] = { + {FontSize_6x8,13,13,3,2, 24,16},{FontSize_6x8,11,13,2,2, 28,16},{FontSize_6x8,9,11,1,1, 35,19}, + {FontSize_5x5,10,10,2,2, 31,21},{FontSize_5x5,8,8,1,1, 39,27}, + {FontSize_3x5,8,10,2,2, 39,21},{FontSize_3x5,8,8,2,1, 39,27},{FontSize_3x5,6,8,1,1, 52,27} + }; + uint8_t alphaBind() { if (swapAlphaSecondBind == 0) { if ((kb_Data[2] & kb_Alpha)) { @@ -153,75 +172,78 @@ void quake() { } } -void expression(unsigned char e) { //Updates the smiley face +void expression(uint8_t e) { // Updates the smiley face + static uint8_t currentExpression = 0; + static uint32_t currentGame = 0; + if (currentExpression == e) { // If already set to an expression, nothing needs to be updated + if (currentGame == gameStartTime) { // Checks if its a new game + return; + } + } + currentGame = gameStartTime; + currentExpression = e; if (e < 4) { //0-3 gColor = 2; fillRect(156, 12, 7, 3); //y2 = 3 because of chordCheck gColor = 0; - if (e == eHAPPY) { //Happy - horiz(157, 13, 5); - plot(156, 12); - plot(162, 12); - return; - } - if (e == eSAD) { //Sad - horiz(157, 12, 5); - plot(156, 13); - plot(162, 13); - return; - } - if (e == eNULL) { //Null - horiz(156, 13, 7); - return; - } - if (e == eCHORD) { //Chord - gColor = 2; - fillRect(156,12,7,2); - gColor = 0; - fillRect(158,12,3,3); - return; - } + switch (e) { + case eHAPPY: + horiz(157, 13, 5); + plot(156, 12); + plot(162, 12); + return; + case eSAD: + horiz(157, 12, 5); + plot(156, 13); + plot(162, 13); + return; + case eNULL: + horiz(156, 13, 7); + return; + case eCHORD: + gColor = 2; + fillRect(156,12,7,2); + gColor = 0; + fillRect(158,12,3,3); + return; + }; } else if (e < 8) { //4-7 - // gColor = 10; // This is what was causing the odd dark yellow dot - // plot(143,4); //Clears potential sunglasses gColor = 2; fillRect(156, 5, 7, 4); gColor = 0; - if (e == eNORMAL) { //Normal - vert(157, 7, 2); - vert(161, 7, 2); - return; - } - if (e == eSHADES) { //Sunglasses - fillRect(156, 7, 7, 2); - gColor = 2; - plot(159, 8); - gColor = 0; - plot(162, 6); - plot(163, 5); - plot(156, 6); - plot(157, 5); - return; - } - if (e == eXX) { //XX - plot(156,6); - plot(156,8); - plot(157,7); - plot(158,6); - plot(158,8); - - plot(160,6); - plot(160,8); - plot(161,7); - plot(162,6); - plot(162,8); - return; - } - if (e == eSLEEP) { //Sleep - horiz(156, 8, 2); - horiz(161, 8, 2); - return; - } + switch (e) { + case eNORMAL: //Normal + vert(157, 7, 2); + vert(161, 7, 2); + return; + case eSHADES: //Sunglasses + fillRect(156, 7, 7, 2); + gColor = 2; + plot(159, 8); + gColor = 0; + plot(162, 6); + plot(163, 5); + plot(156, 6); + plot(157, 5); + return; + case eXX: //XX + plot(156,6); + plot(156,8); + plot(157,7); + plot(158,6); + plot(158,8); + + plot(160,6); + plot(160,8); + plot(161,7); + plot(162,6); + plot(162,8); + return; + case eSLEEP: //Sleep + horiz(156, 8, 2); + horiz(161, 8, 2); + return; + }; } } @@ -244,6 +266,9 @@ void flash() { //uint8_t x } } +/* +// Legacy Flag Counter Code + void flagDraw(uint8_t symbol, uint24_t xP, uint24_t yP) { gColor = accessMode ? 0 : color[symbol]; symbol <<= 1; @@ -267,8 +292,6 @@ void flagDraw(uint8_t symbol, uint24_t xP, uint24_t yP) { } } -/* -// Legacy Flag Counter Code void flagCount() { gColor = 15; for (int24_t z = 15; z <= 35; z += 10) { //Flag Counter @@ -321,85 +344,87 @@ void flagCount() { //Add a color number mode for nostalga void glyph(int16_t space, uint8_t symbol) { gColor = color[symbol]; if (symbol == gFlag) { - if (~fontSize & 1 || fontSize == 0) { //0,1,3,5 + if (fontSizeData[fontSize].padY == 1 || fontSizeData[fontSize].padX == 1) { gColor = 22; //Changes flag pole color to be more readable } } - if (font == 2) { //6x8 Font - uint8_t* bitImage = (uint8_t*)char6x8 + (symbol * 6); - uint8_t* z = lcd_Ram8 + ((space / marX * disY + posY + padY) * LCD_RESX + (space % marX * disX + posX + padX)); - uint8_t b = 1; - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 6; x++) { - *z = *bitImage & b ? gColor : *z; - bitImage++; - z++; - } - bitImage -= 6; - z += (LCD_RESX - 6); - b <<= 1; - } - - if (symbol == gFlag) { - gColor = flagColor; - fillRect(space % marX * disX + posX + padX, space / marX * disY + posY + padY + 1, 3, 3); - } else if (symbol == gMine) { - //gColor = 7; - z -= (LCD_RESX * 6) - 2; - *z = 7; // 2,2 // White - z += (LCD_RESX - 1); - *z = 7; // 1,3 // White - } - return; - } else if (font == 1) { //5x5 Font - symbol <<= 1; - uint16_t bitImage0 = char5x5[symbol]; - uint16_t bitImage1 = char5x5[symbol + 1]; - // uint24_t z1 = z0 + 960; - uint8_t* z = lcd_Ram8 + ((space / marX * disY + posY + padY) * LCD_RESX + (space % marX * disX + posX + padX)); - for (uint8_t y = 0; y < 5; y++) { - for (uint8_t x = 0; x < 5; x++) { - if (bitImage0 & 1) { - *z = gColor; - } - z += (LCD_RESX * 3); - if (bitImage1 & 1) { - *z = gColor; - } - bitImage0 >>= 1; - bitImage1 >>= 1; - z -= (LCD_RESX * 3) - 1; - } - z += LCD_RESX - 5; - } - if (symbol == 2 * gFlag) { - gColor = flagColor; - fillRect(space % marX * disX + posX + padX, space / marX * disY + posY + padY, 2, 2); - } else if (symbol == 2 * gMine) { - //gColor = 7; - z -= (LCD_RESX * 4) - 1; - *z = 7; // 1,1 // White - } - return; - } - //3x5 Font - uint16_t bitImage = char3x5[symbol]; - uint8_t* z = lcd_Ram8 + ((space / marX * disY + posY + padY) * LCD_RESX + (space % marX * disX + posX + padX)); - for (uint8_t y = 0; y < 5; y++) { - for (uint8_t x = 0; x < 3; x++) { - if (bitImage & 1) { - *z = gColor; - } - bitImage >>= 1; - z++; - } - z += (LCD_RESX - 3); - } - if (symbol == gFlag) { - gColor = flagColor; - fillRect(space % marX * disX + posX + padX, space / marX * disY + posY + padY, 2, 2); - } - return; + switch(font) { + case FontSize_6x8: { + uint8_t* bitImage = (uint8_t*)char6x8 + (symbol * 6); + uint8_t* z = lcd_Ram8 + ((space / marX * disY + posY + padY) * LCD_RESX + (space % marX * disX + posX + padX)); + uint8_t b = 1; + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 6; x++) { + *z = *bitImage & b ? gColor : *z; + bitImage++; + z++; + } + bitImage -= 6; + z += (LCD_RESX - 6); + b <<= 1; + } + + if (symbol == gFlag) { + gColor = flagColor; + fillRect(space % marX * disX + posX + padX, space / marX * disY + posY + padY + 1, 3, 3); + } else if (symbol == gMine) { + //gColor = 7; + z -= (LCD_RESX * 6) - 2; + *z = 7; // 2,2 // White + z += (LCD_RESX - 1); + *z = 7; // 1,3 // White + } + } break; + case FontSize_5x5: { + symbol <<= 1; + uint16_t bitImage0 = char5x5[symbol]; + uint16_t bitImage1 = char5x5[symbol + 1]; + // uint24_t z1 = z0 + 960; + uint8_t* z = lcd_Ram8 + ((space / marX * disY + posY + padY) * LCD_RESX + (space % marX * disX + posX + padX)); + for (uint8_t y = 0; y < 5; y++) { + for (uint8_t x = 0; x < 5; x++) { + if (bitImage0 & 1) { + *z = gColor; + } + z += (LCD_RESX * 3); + if (bitImage1 & 1) { + *z = gColor; + } + bitImage0 >>= 1; + bitImage1 >>= 1; + z -= (LCD_RESX * 3) - 1; + } + z += LCD_RESX - 5; + } + if (symbol == 2 * gFlag) { + gColor = flagColor; + fillRect(space % marX * disX + posX + padX, space / marX * disY + posY + padY, 2, 2); + } else if (symbol == 2 * gMine) { + //gColor = 7; + z -= (LCD_RESX * 4) - 1; + *z = 7; // 1,1 // White + } + } break; + case FontSize_3x5: { + uint16_t bitImage = char3x5[symbol]; + uint8_t* z = lcd_Ram8 + ((space / marX * disY + posY + padY) * LCD_RESX + (space % marX * disX + posX + padX)); + for (uint8_t y = 0; y < 5; y++) { + for (uint8_t x = 0; x < 3; x++) { + if (bitImage & 1) { + *z = gColor; + } + bitImage >>= 1; + z++; + } + z += (LCD_RESX - 3); + } + if (symbol == gFlag) { + gColor = flagColor; + fillRect(space % marX * disX + posX + padX, space / marX * disY + posY + padY, 2, 2); + } + break; + } + }; } void fillTile(int16_t space, int8_t mode) { @@ -714,9 +739,13 @@ void drawGame() { } gColor = (15); //Fill Sqaures - for (int24_t y = 2; y < marY - 2; y++) { - for (int24_t x = 2; x < marX - 2; x++) { - fillRect(x * disX + posX + 1, y * disY + posY + 1, disX - 2, disY - 2); + // printf("\npos(%d,%d) dis(%dx%d)",posX,posY,disX,disY); + // fflush(stdout); + for (int24_t y = borderIndexes; y < marY - borderIndexes; y++) { + for (int24_t x = borderIndexes; x < marX - borderIndexes; x++) { + // printf("\n[%d,%d]: (%d,%d)(%dx%d)",x,y,x * disX + posX + 1,y * disY + posY + 1, disX - 3, disY - 3); + // fflush(stdout); + fillRect(x * disX + posX + 1, y * disY + posY + 1, disX - 3, disY - 3); } } /*for (uint24_t x = 5; x < 55; x += 10) { // Flag Squares @@ -829,20 +858,18 @@ void drawGame() { } -const uint8_t fontList[] = {24,16,6, 28,16,5, 35,19,4, 31,21,2, 39,27,2, 39,21,1, 39,27,0}; -void fontCheck() { //Plus 4 - uint8_t i = 7; - for (uint8_t j = 0; j < 24; j += 3) { - if (fontSize == i && (sizeX > fontList[j] || sizeY > fontList[j + 1])) { - fontSize = fontList[j + 2]; - } - i--; - } - font = fontArray[fontSize]; - disX = fontArray[fontSize + 8]; - disY = fontArray[fontSize + 16]; - padX = fontArray[fontSize + 24]; - padY = fontArray[fontSize + 32]; +void fontCheck() { + for (uint8_t f = fontSize; f < ARRAY_LENGTH(fontSizeData); f++) { + if (sizeX <= fontSizeData[fontSize].maxX && sizeY <= fontSizeData[fontSize].maxY) { + break; + } + fontSize++; + } + font = fontSizeData[fontSize].fontType; + disX = fontSizeData[fontSize].disX; + disY = fontSizeData[fontSize].disY; + padX = fontSizeData[fontSize].padX; + padY = fontSizeData[fontSize].padY; } void resetGame() { @@ -850,7 +877,7 @@ void resetGame() { //1: Board marX = sizeX + 4; marY = sizeY + 4; - fontSize = 7; // Resets font size to the largest available before doing the font check stuff + fontSize = 0; // Resets font size to the largest available before doing the font check stuff fontCheck(); //Fits font to screen size posX = 160 - (disX >> 1) * marX; //Allign game board @@ -1003,24 +1030,19 @@ void autoSolve() { } #ifndef PLATFORM_TI84CE - bool setTileToMousePosition() { + bool setTileToMousePosition() { // Returns false if mouse is out of bounds or disabled if (useMouseInGame == false) { - return false; + return false; // Featured toggled off } static int32_t prevMouseX = -1; static int32_t prevMouseY = -1; int32_t mouseX; int32_t mouseY; getMouseState(&mouseX,&mouseY); - if (prevMouseX == mouseX && prevMouseY == mouseY) { - return false; - } - prevMouseX = mouseX; - prevMouseY = mouseY; int24_t mTileX = (mouseX - posX + 1); int24_t mTileY = (mouseY - posY + 1); if (mTileX % disX == 0 || mTileY % disY == 0) { - return false; + return false; // On the grid but not a tile } mTileX /= disX; mTileY /= disY; @@ -1028,8 +1050,13 @@ void autoSolve() { (mTileX < borderIndexes || mTileX >= marX - borderIndexes) || (mTileY < borderIndexes || mTileY >= marY - borderIndexes) ) { - return false; + return false; // Out of bounds + } + if (prevMouseX == mouseX && prevMouseY == mouseY) { + return true; // No change in mouse cordinates } + prevMouseX = mouseX; + prevMouseY = mouseY; fillTile(tile, tCLEAR); //Clears Tile tile = mTileX + (mTileY * marX); fillTile(tile, tSELECT); //Draws Tile @@ -1075,21 +1102,34 @@ void gameControl() { } #ifndef PLATFORM_TI84CE - setTileToMousePosition(); - uint32_t mouseState = getMouseState(NULL,NULL); - bool alphaClick = mouseState & 0x1; - bool secondClick = mouseState & 0x4; - bool chordClick = mouseState & 0x2; + bool alphaClick = false; + bool secondClick = false; + bool chordClick = false; + if (setTileToMousePosition()) { + uint32_t mouseState = getMouseState(NULL,NULL); + alphaClick = mouseState & 0x1; + secondClick = mouseState & 0x4; + chordClick = mouseState & 0x2; + } #else const bool alphaClick = false; const bool secondClick = false; const bool chordClick = false; #endif - - if (((kb_Data[3] & kb_GraphVar) || chordClick) && cleared != 0 && (keyReady & CHORD)) { - keyReset(cHORD); - autoChord(); - } + + if ((kb_Data[3] & kb_GraphVar) || chordClick) { + expression(eCHORD); + if (cleared != 0 && (keyReady & CHORD)) { + keyReset(cHORD); + autoChord(); + } + } else { + if (win) { + expression(eHAPPY); + } else { + expression(eSAD); + } + } if ((kb_Data[6] & kb_Power) && (cleared != 0) && (keyReady & DEBUG) && autoSolver) { keyReset(dEBUG); diff --git a/src/mineSweeper.h b/src/mineSweeper.h index c1dc452..f03b956 100644 --- a/src/mineSweeper.h +++ b/src/mineSweeper.h @@ -1,5 +1,5 @@ /* -** Author: zerico2005 (2023) +** Author: zerico2005 (2023-2024) ** Project: Super-Sweeper ** License: MIT License ** A copy of the MIT License should be included with @@ -112,7 +112,6 @@ void cursorSetup(); void drawGame(); -extern const uint8_t fontList[]; void fontCheck(); //Plus 4 void resetGame(); diff --git a/src/prime2D.c b/src/prime2D.c index dffa1e7..95d2deb 100644 --- a/src/prime2D.c +++ b/src/prime2D.c @@ -32,7 +32,7 @@ const uint16_t char5x5[56] = { // Integer to print, length, base 2-16 //Auto adjusts for signage void printInt(int24_t in, uint8_t len, uint8_t base, uint24_t xC, uint24_t yC) { - uint8_t* off = lcd_Ram8 + xC + (LCD_RESX * yC); + uint8_t* off = lcd_Ram8 + (int24_t)(xC + (LCD_RESX * yC)); uint8_t* v = off + LCD_RESX; len *= 4; const uint24_t x2 = 5 + len; @@ -58,9 +58,9 @@ const uint16_t char5x5[56] = { uint24_t* negSign = ((LCD_RESX * 3) + 1) + (uint24_t*)off; //Fills three pixels *negSign = (in < 0) ? 460551 : 0; //If Negative uint24_t j = abs(in); - uint24_t pow = 1; + uint24_t powN = 1; for (uint24_t k = 0; k < len; k += 4) { - uint16_t bitImage = num3x5[(j / pow) % base]; + uint16_t bitImage = num3x5[(j / powN) % base]; uint8_t *fill = off + (LCD_RESX + 1) + len - k; for (uint8_t y = 0; y < 5; y++) { for (uint8_t x = 0; x < 3; x++) { @@ -70,13 +70,13 @@ const uint16_t char5x5[56] = { } fill += (LCD_RESX - 3); } - pow *= base; + powN *= base; } } // Integer to print, length, base 2-16 void printUInt(int24_t in, uint8_t len, uint8_t base, uint24_t xC, uint24_t yC) { - uint8_t* off = lcd_Ram8 + xC + (LCD_RESX * yC); //Something about casting off to uint8_t* adds 4 more bytes + uint8_t* off = lcd_Ram8 + (int24_t)(xC + (LCD_RESX * yC)); //Something about casting off to uint8_t* adds 4 more bytes uint8_t* v = off + LCD_RESX; len *= 4; const uint24_t x2 = 1 + len; //Can optomize out "1 + " for a saving of 8 bytes @@ -98,9 +98,9 @@ const uint16_t char5x5[56] = { *v = 0; v++; } - uint24_t pow = 1; + uint24_t powN = 1; for (uint24_t k = 0; k < len; k += 4) { - uint16_t bitImage = num3x5[(in / pow) % base]; + uint16_t bitImage = num3x5[(in / powN) % base]; uint8_t* fill = off + (LCD_RESX - 3) + len - k; for (uint8_t y = 0; y < 5; y++) { for (uint8_t x = 0; x < 3; x++) { @@ -110,25 +110,25 @@ const uint16_t char5x5[56] = { } fill += (LCD_RESX - 3); } - pow *= base; + powN *= base; } } //Primatives void fillRect(uint24_t x1, uint24_t y1, uint24_t x2, uint24_t y2) { //x start, y start, x length, y length - uint8_t* fill = lcd_Ram8 + (x1 + (y1 * LCD_RESX)); + uint8_t* fill = lcd_Ram8 + (int24_t)(x1 + (y1 * LCD_RESX)); for (uint24_t dY = 0; dY < y2; dY++) { memset(fill,gColor,x2); fill += LCD_RESX; } } void horiz(uint24_t x1, uint24_t y, uint24_t x2) { //x start, y postion, x length - uint8_t* fill = lcd_Ram8 + (x1 + (y * LCD_RESX)); + uint8_t* fill = lcd_Ram8 + (int24_t)(x1 + (y * LCD_RESX)); memset(fill,gColor,x2); } void vert(uint24_t x, uint24_t y1, uint24_t y2) { //x postion, y start, y length - uint8_t* z = lcd_Ram8 + x + ((y2 + y1) * LCD_RESX); + uint8_t* z = lcd_Ram8 + (int24_t)(x + ((y2 + y1) * LCD_RESX)); for (uint8_t* fill = lcd_Ram8 + (y1 * LCD_RESX) + x; fill < z; fill += LCD_RESX) { *fill = gColor; } @@ -141,7 +141,7 @@ void fillScreen() { //Fills buffer 0 //Text Engine void text6x8(uint24_t xW, uint24_t yW, uint8_t lexicon) { //x position, y position, letter index uint8_t* bitImage = (uint8_t*)char6x8 + (lexicon * 6); - uint8_t* fill = lcd_Ram8 + (yW * LCD_RESX + xW); + uint8_t* fill = lcd_Ram8 + (int24_t)(yW * LCD_RESX + xW); uint8_t b = 1; for (uint8_t y = 0; y < 8; y++) { for (uint8_t x = 0; x < 6; x++) { @@ -156,7 +156,7 @@ void text6x8(uint24_t xW, uint24_t yW, uint8_t lexicon) { //x position, y positi } void fillText(uint24_t x1, uint24_t y1, uint24_t x2, uint24_t y2) { //x start, y start, x length, y length //fillRect() that does not overwrite text - uint8_t* v = lcd_Ram8 + x1 + (y1 * LCD_RESX); + uint8_t* v = lcd_Ram8 + (int24_t)(x1 + (y1 * LCD_RESX)); const uint24_t jump = LCD_RESX - x2; for (uint24_t dY = 0; dY < y2; dY++) { for (uint24_t dX = 0; dX < x2; dX++) {