Added the minesweeper game.

This commit is contained in:
That_One_Nerd 2024-09-10 10:13:02 -04:00
commit 813fcd2cb5
23 changed files with 1135 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Python cache files.
*/__pycache__/
# Build files.
*/bin/
*/obj/
convimg.out
# Other stuff.
.DS_Store

3
Minesweeper/.clangd Normal file
View File

@ -0,0 +1,3 @@
CompileFlags: # Add the include folder.
Add:
- "--include-directory=C:\\Users\\kyley\\Desktop\\Coding\\TiCalculatorModding\\Libraries\\CE_C-C++_Toolchain_11.0\\include"

7
Minesweeper/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
obj/
bin/
src/gfx/*.c
src/gfx/*.h
src/gfx/*.8xv
.DS_Store
convimg.out

View File

@ -0,0 +1,45 @@
import sys
INPUT_R = 8
INPUT_G = 8
INPUT_B = 8
OUTPUT_R = 5
OUTPUT_G = 6
OUTPUT_B = 5
def convert(color_in: int) -> int:
global INPUT_R, INPUT_G, INPUT_B
global OUTPUT_R, OUTPUT_G, OUTPUT_B
in_r_max = 2 ** INPUT_R - 1
in_g_max = 2 ** INPUT_G - 1
in_b_max = 2 ** INPUT_B - 1
out_r_max = 2 ** OUTPUT_R - 1
out_g_max = 2 ** OUTPUT_G - 1
out_b_max = 2 ** OUTPUT_B - 1
in_b = color_in & in_b_max
in_g = (color_in >> INPUT_B) & in_g_max
in_r = (color_in >> INPUT_B + INPUT_G) & in_r_max
r_float = in_r / float(in_r_max)
g_float = in_g / float(in_g_max)
b_float = in_b / float(in_b_max)
out_r = int(r_float * out_r_max)
out_g = int(g_float * out_g_max)
out_b = int(b_float * out_b_max)
color_out = out_b + (out_g << OUTPUT_B) + (out_r << (OUTPUT_B + OUTPUT_G))
return color_out
if len(sys.argv) < 2:
print("Requires color argument.")
elif len(sys.argv) > 2:
print("Too many arguments!")
else:
input_col = int(sys.argv[1], 16)
output_col = convert(input_col)
print(hex(output_col))

94
Minesweeper/colorconv.py Normal file
View File

@ -0,0 +1,94 @@
import math
import sys
def print_usage():
print("Usage: colorconv.py <from> <to> <color_from>")
print("")
print(" <from>: The color format to convert from.")
print(" <to>: The color format to convert to.")
print(" <color_from>: The color to convert the format of.")
print("")
print(" Color formats are formatted as their individual channels.")
print(" Ex.")
print(" r8g8b8")
print(" r5g6b5")
print("")
print(" Color data is represented as a number. Must be hexadecimal.")
print(" The output is a single color value in hexadecimal.")
def total_format_bytes(format: tuple[int, int, int]):
bits = sum(format)
return math.ceil(bits / 8)
def determine_format(format: str) -> tuple[int, int, int]:
r_ind: int = format.index("r")
g_ind: int = format.index("g")
b_ind: int = format.index("b")
r_sub: str = format[(r_ind + 1):g_ind]
g_sub: str = format[(g_ind + 1):b_ind]
b_sub: str = format[(b_ind + 1):]
r_val = int(r_sub)
g_val = int(g_sub)
b_val = int(b_sub)
return (r_val, g_val, b_val)
def convert_color(format_in: tuple[int, int, int], format_out: tuple[int, int, int], color_in):
in_r_max = 2 ** format_in[0] - 1
in_g_max = 2 ** format_in[1] - 1
in_b_max = 2 ** format_in[2] - 1
out_r_max = 2 ** format_out[0] - 1
out_g_max = 2 ** format_out[1] - 1
out_b_max = 2 ** format_out[2] - 1
in_r: int
in_g: int
in_b: int
if isinstance(color_in, int):
in_b = color_in & in_b_max
in_g = (color_in >> format_in[2]) & in_g_max
in_r = (color_in >> (format_in[2] + format_in[1])) & in_r_max
else:
in_r = color_in[0]
in_g = color_in[1]
in_b = color_in[2]
r_float = in_r / float(in_r_max)
g_float = in_g / float(in_g_max)
b_float = in_b / float(in_b_max)
out_r = int(r_float * out_r_max)
out_g = int(g_float * out_g_max)
out_b = int(b_float * out_b_max)
color_out = out_b + (out_g << format_out[2]) + (out_r << (format_out[2] + format_out[1]))
return color_out
def main(argv: list[str]):
argc: int = len(argv)
if argc < 4:
print_usage()
return
elif argc > 4:
print("Too many arguments!\n")
print_usage()
return
# The first argument is this file. Happens when calling python.exe.
format_in_str: str = argv[1]
format_out_str: str = argv[2]
color_str: str = argv[3]
format_in: tuple[int, int, int] = determine_format(format_in_str)
format_out: tuple[int, int, int] = determine_format(format_out_str)
color = int(color_str, 16)
result: int = convert_color(format_in, format_out, color)
formatter: str = "0x{:0" + str(total_format_bytes(format_out) * 2) + "X}"
print(formatter.format(result))
if __name__ == "__main__": main(sys.argv)

BIN
Minesweeper/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

56
Minesweeper/imageconv.py Normal file
View File

@ -0,0 +1,56 @@
from colorconv import determine_format, convert_color, total_format_bytes
import sys
from PIL import Image
def print_usage():
print("Usage: colorconv.py <to> <image>")
print("")
print(" <to>: The color format to convert to.")
print(" <image>: The color to convert the format of.")
print("")
print(" Color formats are formatted as their individual channels.")
print(" Ex.")
print(" r8g8b8")
print(" r5g6b5")
print("")
print(" Image data is represented as a path to an image file.")
print(" The output is printed code that represents the sprite.")
def convert_image(format_out: tuple[int, int, int], image: Image.Image) -> str:
output = "{\n"
counter = 0
size = image.size[0] * image.size[1]
pixels = image.getdata()
formatter: str = "0x{:0" + str(total_format_bytes(format_out) * 2) + "X}"
for y in range(image.size[1]):
output += " "
for x in range(image.size[0]):
num = convert_color([8, 8, 8], format_out, pixels[y * image.size[0] + x])
output += formatter.format(num)
if counter < size - 1: output += ", "
counter += 1
output += "\n"
output += "}"
return output
def main(argv: list[str]):
argc: int = len(argv)
if argc < 3:
print_usage()
return
elif argc > 3:
print("Too many arguments!\n")
print_usage()
return
# The first argument is this file. Happens when calling python.exe.
format_out_str: str = argv[1]
image_path: str = argv[2]
format_out: tuple[int, int, int] = determine_format(format_out_str)
image = Image.open(image_path).convert("RGB")
result = convert_image(format_out, image)
print(result)
if __name__ == "__main__": main(sys.argv)

16
Minesweeper/makefile Normal file
View File

@ -0,0 +1,16 @@
# ----------------------------
# Makefile Options
# ----------------------------
NAME = MINESWEE
ICON = icon.png
DESCRIPTION = "Minesweeper by Kyle Gilbert"
COMPRESSED = NO
ARCHIVED = NO
CFLAGS = -Wall -Wextra -Oz
CXXFLAGS = -Wall -Wextra -Oz
# ----------------------------
include $(shell cedev-config --makefile)

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

BIN
Minesweeper/sprites/one.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

BIN
Minesweeper/sprites/six.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

BIN
Minesweeper/sprites/two.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

66
Minesweeper/src/libext.h Normal file
View File

@ -0,0 +1,66 @@
#include <string.h>
template<typename T>
class vector
{
private:
int _size;
T* ptr;
public:
vector()
{
_size = 0;
ptr = new T[0];
}
~vector()
{
delete[] ptr;
}
const T& at(int index) const
{
return ptr[index];
}
T& at(int index)
{
return ptr[index];
}
void add(T item)
{
T* new_ptr = new T[_size + 1];
memcpy(new_ptr, ptr, _size * sizeof(T));
new_ptr[_size] = item;
delete[] ptr;
ptr = new_ptr;
_size++;
}
void remove_at(int index)
{
T* new_ptr = new T[_size - 1];
memcpy(new_ptr, ptr, index * sizeof(T)); // Before
memcpy(new_ptr + index, ptr + index + 1, (_size - index) * sizeof(T)); // After
delete[] ptr;
ptr = new_ptr;
_size--;
}
int size() const
{
return _size;
}
const T& operator[](int index) const
{
return ptr[index];
}
T& operator[](int index)
{
return ptr[index];
}
};

648
Minesweeper/src/main.cpp Normal file
View File

@ -0,0 +1,648 @@
#pragma region Boilerplate
#pragma region Disregard
// Removes some errors. Weird.
typedef int int24_t;
typedef unsigned int uint24_t;
#pragma endregion
#include <sys/lcd.h>
#include <sys/rtc.h>
#include <ti/getcsc.h>
#include <ti/getkey.h>
#include <ti/screen.h>
#include <ti/ui.h>
#include <ti/vars.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#pragma endregion
#include "libext.h"
#include "sprites.h"
// Useful macros.
#define VRAM_START ((uint16_t*)0xD40000)
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define HEADER_SIZE 30
#define VRAM_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT)
#define GET_TILE_INDEX(c, r) ((r) * game.columns + (c))
#define GET_TILE_AT(c, r) (tiles[(r) * game.columns + (c)])
enum DirectionType : uint8_t
{
DIR_UP,
DIR_LEFT,
DIR_RIGHT,
DIR_DOWN
};
struct GameInfo
{
uint8_t columns = 16; // Width
uint8_t rows = 12; // Height
uint16_t mines = 48;
};
struct ScreenInfo
{
int8_t scroll_x = 0;
int8_t scroll_y = 0;
int8_t selection_x = 0;
int8_t selection_y = 0;
};
enum TileFlags : uint8_t
{
TILE_NO_FLAGS = 0x00,
TILE_IS_MINE = 0x01,
TILE_REVEALED = 0x02,
TILE_FLAGGED = 0x04
};
struct TileInfo
{
TileFlags flags = TILE_NO_FLAGS;
uint8_t mines_around = 0;
};
GameInfo game;
ScreenInfo screen;
TileInfo* tiles = nullptr;
int tile_count;
bool lost = false, won = false;
int remaining_tiles;
void initialize()
{
game = GameInfo();
screen = ScreenInfo();
srand(rtc_Time());
}
void setup_tiles()
{
if (tiles != nullptr) delete[] tiles;
tile_count = game.columns * game.rows;
tiles = new TileInfo[tile_count];
if (game.mines >= tile_count) game.mines = tile_count;
remaining_tiles = tile_count - game.mines;
// Randomize mine positions.
for (int i = 0; i < game.mines; i++)
{
_choose_pos:
int mine_pos = rand() % tile_count;
// Using = instead of & and | because we're setting up for the first time.
TileInfo& tile = tiles[mine_pos];
if (tile.flags & TILE_IS_MINE) goto _choose_pos; // Mine already there, try again.
tile.flags = TILE_IS_MINE;
}
// Another loop. Calculate the amount of mines around each tile.
for (int r = 0; r < game.columns; r++)
{
for (int c = 0; c < game.rows; c++)
{
TileInfo& tile = GET_TILE_AT(r, c);
if (tile.flags & TILE_IS_MINE) continue; // This is a mine, we know what that means.
int adjacent_rows[8] =
{
r - 1,
r - 1,
r,
r + 1,
r + 1,
r + 1,
r,
r - 1
};
int adjacent_columns[8] =
{
c,
c + 1,
c + 1,
c + 1,
c,
c - 1,
c - 1,
c - 1
};
for (int i = 0; i < 8; i++)
{
int ind_row = adjacent_rows[i],
ind_column = adjacent_columns[i];
if (ind_row < 0 || ind_row >= game.columns ||
ind_column < 0 || ind_column >= game.rows) continue; // Tile is hugging the side, ignore this one.
TileInfo& adjTile = GET_TILE_AT(ind_row, ind_column);
if (adjTile.flags & TILE_IS_MINE) tile.mines_around++; // Mine around here.
}
}
}
}
// Colors and Formatting
constexpr uint16_t background_color = 0xB5D6; // #BDBDBD
constexpr uint16_t tile_shadow_color = 0x7BEF;
constexpr uint16_t tile_highlight_color = 0xFFFF;
constexpr uint8_t tile_size = 20;
constexpr uint8_t tile_3d_effect_size = 3;
constexpr uint8_t arrow_size = 14;
constexpr uint8_t arrow_distance = 10;
constexpr uint16_t arrow_color = 0x000;
constexpr uint16_t selection_color = 0xF800;
constexpr uint16_t win_selection_color = 0x07E0;
constexpr uint16_t selection_width = 3;
void draw_sprite(int row, int column, uint16_t* sprite, int sprite_width, int sprite_height)
{
uint16_t pos_x = row + screen.scroll_x,
pos_y = column + screen.scroll_y;
int pix_x = pos_x * tile_size,
pix_y = pos_y * tile_size;
if (pix_x < 0 || pix_x >= SCREEN_WIDTH ||
pix_y < 0 || pix_y >= SCREEN_HEIGHT) return; // Sprite is off-screen.
// Find middle of tile and offset by sprite size.
pix_x += (tile_size - sprite_width) / 2;
pix_y += (tile_size - sprite_height) / 2;
uint16_t* vram = VRAM_START + pix_y * SCREEN_WIDTH + pix_x;
for (int y = 0; y < sprite_height; y++)
{
for (int x = 0; x < sprite_width; x++)
{
memcpy(vram, sprite, sprite_width * sizeof(uint16_t));
}
vram += SCREEN_WIDTH;
sprite += sprite_width;
}
}
void render_background()
{
// Can't use memset!
// The upper byte gets replaced by the lower one.
// Draw sequential lines to make things faster.
uint16_t* vram = VRAM_START;
for (int x = 0; x < SCREEN_WIDTH; x++) vram[x] = background_color;
for (int y = 1; y < SCREEN_HEIGHT; y++)
{
memcpy(vram + SCREEN_WIDTH, vram, SCREEN_WIDTH * sizeof(uint16_t));
vram += SCREEN_WIDTH;
}
}
void render_tile_3d_effect(int row, int column)
{
uint16_t pos_x = row + screen.scroll_x,
pos_y = column + screen.scroll_y;
int pix_x = pos_x * tile_size,
pix_y = pos_y * tile_size;
// First render the highlight with two rectangles.
uint16_t* vram = VRAM_START + pix_y * SCREEN_WIDTH + pix_x + tile_3d_effect_size;
for (int x = 0; x < tile_size - tile_3d_effect_size; x++) vram[x] = tile_highlight_color;
// Copy line for horizontal part.
for (int y = 0; y < tile_3d_effect_size - 1; y++)
{
memcpy(vram + SCREEN_WIDTH, vram, (tile_size - tile_3d_effect_size) * sizeof(uint16_t));
vram += SCREEN_WIDTH;
}
// Copy line for vertical part.
uint16_t* vram_side = vram + (tile_size - tile_3d_effect_size * 2);
for (int y = 0; y < tile_size - tile_3d_effect_size * 2; y++)
{
memcpy(vram_side + SCREEN_WIDTH, vram_side, tile_3d_effect_size * sizeof(uint16_t));
vram_side += SCREEN_WIDTH;
}
// Now render the shadow with two rectangles.
vram = VRAM_START + (pix_y + tile_size - tile_3d_effect_size) * SCREEN_WIDTH + pix_x + tile_3d_effect_size - 3;
for (int x = 0; x < tile_size - 3; x++) vram[x] = tile_shadow_color;
// Copy line for horizontal part.
for (int y = 0; y < tile_3d_effect_size - 1; y++)
{
memcpy(vram + SCREEN_WIDTH, vram, tile_size * sizeof(uint16_t));
vram += SCREEN_WIDTH;
}
// Copy line for vertical part.
vram_side = vram - (tile_3d_effect_size - 1) * SCREEN_WIDTH;
for (int y = 0; y < tile_size - tile_3d_effect_size * 2; y++)
{
memcpy(vram_side - SCREEN_WIDTH, vram_side, tile_3d_effect_size * sizeof(uint16_t));
vram_side -= SCREEN_WIDTH;
}
}
void render_tile_selection(int row, int column, uint16_t color)
{
uint16_t pos_x = row + screen.scroll_x,
pos_y = column + screen.scroll_y;
int pix_x = pos_x * tile_size,
pix_y = pos_y * tile_size;
if (pix_x < 0 || pix_x >= SCREEN_WIDTH ||
pix_y < 0 || pix_y >= SCREEN_HEIGHT) return; // Selection is off-screen.
// Render selection with three rectangles.
uint16_t* vram = VRAM_START + pix_y * SCREEN_WIDTH + pix_x;
for (int x = 0; x < tile_size; x++) vram[x] = color;
// Copy line for top part.
for (int y = 1; y < selection_width; y++)
{
memcpy(vram + SCREEN_WIDTH, vram, tile_size * sizeof(uint16_t));
vram += SCREEN_WIDTH;
}
// Copy line for left part.
uint16_t* vram_side = vram + SCREEN_WIDTH;
for (int y = 0; y < tile_size - selection_width * 2; y++)
{
memcpy(vram_side, vram, selection_width * sizeof(uint16_t));
vram_side += SCREEN_WIDTH;
}
// Copy line for right part.
vram_side = vram + SCREEN_WIDTH + (tile_size - selection_width);
for (int y = 0; y < tile_size - selection_width * 2; y++)
{
memcpy(vram_side, vram, selection_width * sizeof(uint16_t));
vram_side += SCREEN_WIDTH;
}
// Copy line for bottom part.
uint16_t* new_vram = vram + SCREEN_WIDTH * (tile_size - selection_width * 2 + 1);
for (int y = 0; y < selection_width; y++)
{
memcpy(new_vram, vram, tile_size * sizeof(uint16_t));
new_vram += SCREEN_WIDTH;
}
}
void render_tile(int row, int column)
{
constexpr int tiles_visible_x = SCREEN_WIDTH / tile_size,
tiles_visible_y = SCREEN_HEIGHT / tile_size;
const TileInfo& tile = GET_TILE_AT(row, column);
int16_t pos_x = row + screen.scroll_x,
pos_y = column + screen.scroll_y;
if (pos_x < 0 || pos_x >= tiles_visible_x ||
pos_y < 0 || pos_y >= tiles_visible_y) return; // Off screen.
// No need to render the tile background because it's
// just the regular background.
if (tile.flags & TILE_REVEALED)
{
if (tile.flags & TILE_IS_MINE)
{
// Uh oh.
draw_sprite(row, column, (uint16_t*)sprite_mine, 14, 14);
}
else if (tile.mines_around > 0)
{
// Draw number icon.
uint16_t* sprite;
switch (tile.mines_around)
{
case 1:
sprite = (uint16_t*)sprite_one;
break;
case 2:
sprite = (uint16_t*)sprite_two;
break;
case 3:
sprite = (uint16_t*)sprite_three;
break;
case 4:
sprite = (uint16_t*)sprite_four;
break;
case 5:
sprite = (uint16_t*)sprite_five;
break;
case 6:
sprite = (uint16_t*)sprite_six;
break;
case 7:
sprite = (uint16_t*)sprite_seven;
break;
case 8:
sprite = (uint16_t*)sprite_eight;
break;
}
draw_sprite(row, column, sprite, 14, 14);
}
}
else
{
render_tile_3d_effect(row, column);
if (tile.flags & TILE_FLAGGED)
{
draw_sprite(row, column, (uint16_t*)sprite_flag, 12, 12);
}
}
// If we lost, show all the mines.
if (lost && (tile.flags & TILE_IS_MINE))
{
draw_sprite(row, column, (uint16_t*)sprite_mine, 14, 14);
}
}
void render_arrow(DirectionType dir)
{
uint16_t* vram = VRAM_START;
switch (dir)
{
case DIR_UP:
vram += SCREEN_WIDTH / 2 + arrow_distance * SCREEN_WIDTH;
for (int y = 1; y <= arrow_size; y++)
{
vram += y % 2 == 1 ? SCREEN_WIDTH - 1 : SCREEN_WIDTH;
for (int x = 0; x < 2 * ceil(y / 2.0); x++) vram[x] = arrow_color;
}
break;
case DIR_LEFT:
vram += SCREEN_WIDTH * SCREEN_HEIGHT / 2 + arrow_distance;
for (int x = 1; x <= arrow_size; x++)
{
vram += x % 2 == 1 ? -SCREEN_WIDTH + 1 : 1;
for (int y = 0; y < 2 * ceil(x / 2.0); y++) vram[SCREEN_WIDTH * y] = arrow_color;
}
break;
case DIR_RIGHT:
vram += SCREEN_WIDTH * SCREEN_HEIGHT / 2 + (SCREEN_WIDTH - arrow_distance);
for (int x = 1; x <= arrow_size; x++)
{
vram -= x % 2 == 1 ? SCREEN_WIDTH + 1 : 1;
for (int y = 0; y < 2 * ceil(x / 2.0); y++) vram[SCREEN_WIDTH * y] = arrow_color;
}
break;
case DIR_DOWN:
vram += SCREEN_WIDTH / 2 + (SCREEN_HEIGHT - arrow_distance) * SCREEN_WIDTH;
for (int y = 1; y <= arrow_size; y++)
{
vram -= y % 2 == 1 ? SCREEN_WIDTH + 1 : SCREEN_WIDTH;
for (int x = 0; x < 2 * ceil(y / 2.0); x++) vram[x] = arrow_color;
}
break;
default: return;
}
}
void full_render()
{
constexpr int tiles_visible_x = SCREEN_WIDTH / tile_size,
tiles_visible_y = SCREEN_HEIGHT / tile_size;
render_background();
for (int r = 0; r < game.columns; r++)
{
for (int c = 0; c < game.rows; c++)
{
render_tile(r, c);
}
}
render_tile_selection(screen.selection_x, screen.selection_y, selection_color);
int min_tile_visible_x = -screen.scroll_x,
max_tile_visible_x = tiles_visible_x - screen.scroll_x;
int min_tile_visible_y = -screen.scroll_y,
max_tile_visible_y = tiles_visible_y - screen.scroll_y;
if (min_tile_visible_y > 0) render_arrow(DIR_UP);
if (min_tile_visible_x > 0) render_arrow(DIR_LEFT);
if (max_tile_visible_x < game.columns) render_arrow(DIR_RIGHT);
if (max_tile_visible_y < game.rows) render_arrow(DIR_DOWN);
}
bool check_completion()
{
return remaining_tiles == 0;
}
void reveal_tile(int row, int column)
{
// We have a vector of tile pointers. we loop until every tile in the vector
// is revealed. if it's revealed, remove it, otherwise add its neighbors and repeat.
// This is double its possible size because I don't want to use additional memory for
// storing the row and column for the tile.
TileInfo& tile = GET_TILE_AT(row, column);
if (tile.flags & TILE_IS_MINE)
{
if (tile.flags & TILE_FLAGGED) return; // Clicked on a mine, but it was flagged already. Don't show.
// Otherwise, licked on a mine, we have lost.
lost = true;
return;
}
if (tile.flags & TILE_REVEALED) return; // Already revealed.
vector<int> tile_rows = vector<int>(),
tile_columns = vector<int>();
tile_rows.add(row);
tile_columns.add(column);
while (tile_rows.size() > 0)
{
int active_row = tile_rows.at(0),
active_column = tile_columns.at(0);
TileInfo& active = GET_TILE_AT(active_row, active_column);
if ((active.flags & TILE_REVEALED) ||
(active.flags & TILE_FLAGGED))
{
// Already revealed or flagged and can't reveal, remove.
tile_rows.remove_at(0);
tile_columns.remove_at(0);
continue;
}
else if (active.flags & TILE_IS_MINE)
{
// Mine, so just reveal.
active.flags = (TileFlags)(active.flags | TILE_REVEALED);
tile_rows.remove_at(0);
tile_columns.remove_at(0);
continue;
}
// Get neighbors and add them here too.
// If this current tile is a zero tile, reveal all tiles around it.
// Otherwise, only reveal zero tiles nearby, don't reveal other
// non-zero tiles.
int adjacent_rows[8] =
{
active_row - 1,
active_row - 1,
active_row,
active_row + 1,
active_row + 1,
active_row + 1,
active_row,
active_row - 1
};
int adjacent_columns[8] =
{
active_column,
active_column + 1,
active_column + 1,
active_column + 1,
active_column,
active_column - 1,
active_column - 1,
active_column - 1,
};
for (int i = 0; i < 8; i++)
{
int ind_row = adjacent_rows[i],
ind_column = adjacent_columns[i];
if (ind_row < 0 || ind_row >= game.columns ||
ind_column < 0 || ind_column >= game.rows) continue; // Tile is hugging the side, ignore this one.
TileInfo& adjTile = GET_TILE_AT(ind_row, ind_column);
if (adjTile.flags & TILE_IS_MINE) continue; // Tile is mine, ignore.
if (adjTile.flags & TILE_REVEALED) continue; // Already revealed, ignore.
if (active.mines_around > 0 && adjTile.mines_around > 0) continue; // Non-zero tile can't reveal other non-zero tiles, ignore.
tile_rows.add(ind_row);
tile_columns.add(ind_column);
}
active.flags = (TileFlags)(active.flags | TILE_REVEALED);
tile_rows.remove_at(0);
tile_columns.remove_at(0);
remaining_tiles--;
}
}
void flag_tile(int row, int column)
{
TileInfo& tile = GET_TILE_AT(row, column);
if (tile.flags & TILE_REVEALED) return; // Already revealed, ignore.
tile.flags = (TileFlags)(tile.flags ^ TILE_FLAGGED);
}
void display_win()
{
// Highlight mines in green.
for (int r = 0; r < game.columns; r++)
{
for (int c = 0; c < game.rows; c++)
{
TileInfo& tile = GET_TILE_AT(r, c);
if (!(tile.flags & TILE_IS_MINE)) continue; // Ignore non-mines.
render_tile_selection(r, c, win_selection_color);
}
}
}
int main()
{
// TODO: only full render once. check for empty space and fill that when scrolling.
// TODO: replace the check for out-of-bounds cells with a more optimized for loop.
// this should probably be for 2.0, not this one.
// Initialize
initialize();
setup_tiles();
while (true)
{
full_render();
if (check_completion() || won)
{
won = true;
display_win();
}
_getkey:
uint16_t key = os_GetKey();
switch (key)
{
case k_Up:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.scroll_y++;
break;
case k_Down:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.scroll_y--;
break;
case k_Right:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.scroll_x--;
break;
case k_Left:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.scroll_x++;
break;
case k_4:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.selection_x--;
if (screen.selection_x < 0) screen.selection_x = 0;
break;
case k_6:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.selection_x++;
if (screen.selection_x >= game.columns) screen.selection_x = game.columns - 1;
break;
case k_8:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.selection_y--;
if (screen.selection_y < 0) screen.selection_y = 0;
break;
case k_2:
if (lost || won) goto _getkey; // Lost, can't do anything.
screen.selection_y++;
if (screen.selection_y >= game.rows) screen.selection_y = game.rows - 1;
break;
case k_Enter:
if (lost || won) goto _getkey; // Lost, can't do anything.
reveal_tile(screen.selection_x, screen.selection_y);
break;
case k_DecPnt:
if (lost || won) goto _getkey; // Lost, can't do anything.
flag_tile(screen.selection_x, screen.selection_y);
break;
case k_Clear: return 0; // End.
default: goto _getkey; // Don't re-render if we press the wrong key.
}
}
}

162
Minesweeper/src/sprites.cpp Normal file
View File

@ -0,0 +1,162 @@
#include "sprites.h"
const uint16_t sprite_flag[144] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF800, 0xF800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xF800, 0xF800, 0xF800, 0xF800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xF800, 0xF800, 0xF800, 0xF800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF800, 0xF800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_mine[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_one[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_two[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_three[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_four[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x000F, 0x000F, 0x000F, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_five[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_six[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0x03EF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_seven[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x0000, 0x0000, 0x0000, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};
const uint16_t sprite_eight[196] = {
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0x7BEF, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6,
0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6, 0xB5D6
};

14
Minesweeper/src/sprites.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
extern const uint16_t sprite_flag[144]; // This one is 12x12!
extern const uint16_t sprite_mine[196];
extern const uint16_t sprite_one[196];
extern const uint16_t sprite_two[196];
extern const uint16_t sprite_three[196];
extern const uint16_t sprite_four[196];
extern const uint16_t sprite_five[196];
extern const uint16_t sprite_six[196];
extern const uint16_t sprite_seven[196];
extern const uint16_t sprite_eight[196];

14
README.md Normal file
View File

@ -0,0 +1,14 @@
# Computer Studies Projects
Just a few assignments I made for my 12th grade computer studies class. You get to pick your projects, so these are mine.
I have about 1-2 weeks for each project. Check the Git commits for specific dates or whatever.
## Projects
- Minesweeper/
- I made Minesweeper for the TI-84 calculator. I tried to be somewhat true to the original Windows one.
- 2 is down, 4 is left, 6 is right, 8 is up for your selection. Enter is to mine and the decimal point places a flag. The arrow keys move the board.
- No additional libraries were used, only the built in TI libraries and the [TI CE toolchain](https://github.com/CE-Programming/toolchain).
- Doesn't run great. It uses 16-bit color mode, so the graphics are somewhat slow to render. I attempted to find the way to switch to 4-bit color mode, but I didn't find enough useful info (the best I've found so far is to dissect the GraphX assembly code). Still runs decent though, I've made as many optimizations as I easily could with the renderer, and everything else is fast.
- **WARNING**: This one can't be built without reconfiguring the `.clangd` file to include the path to the toolchain.