seems to be working
This commit is contained in:
commit
98a655d315
8 changed files with 594 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.cache
|
||||
build
|
||||
.zed
|
||||
.clang-format
|
||||
.DS_Store
|
||||
13
CmakeLists.txt
Normal file
13
CmakeLists.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(minesweeper_sdl)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(EXECUTABLE_NAME bin)
|
||||
|
||||
file(GLOB SOURCES "src/*.c")
|
||||
add_executable(${EXECUTABLE_NAME} ${SOURCES})
|
||||
target_include_directories(${EXECUTABLE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
find_package(SDL3 REQUIRED COMPONENTS SDL3)
|
||||
target_link_libraries(${EXECUTABLE_NAME} SDL3::SDL3)
|
||||
9
README.md
Normal file
9
README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
A simple minesweeper game I made, 'cause train rides to school are boring.
|
||||
|
||||
Requires cmake and SDL3 to compile.
|
||||
|
||||
Compile, and run with:
|
||||
|
||||
```bash
|
||||
cmake -B build/ && cmake --build build/ && ./build/bin
|
||||
```
|
||||
36
include/board.h
Normal file
36
include/board.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} Vector2;
|
||||
Vector2 random_vector2(Vector2 bounds);
|
||||
// returns size of the output, doesn't check if the output will fit
|
||||
int get_neighbours(Vector2 input, Vector2 bounds, Vector2* output);
|
||||
|
||||
typedef struct {
|
||||
bool has_mine;
|
||||
bool has_flag;
|
||||
bool is_revealed;
|
||||
// -1 means it hasn't been calculated
|
||||
char revealed_value;
|
||||
} Cell;
|
||||
Cell new_cell();
|
||||
// returns true if there isn't a mine, cells with flags can't be revealed
|
||||
|
||||
typedef struct {
|
||||
// x, y
|
||||
Cell** cells;
|
||||
Vector2 bounds;
|
||||
Vector2 hover;
|
||||
bool game_over;
|
||||
bool game_started;
|
||||
} Board;
|
||||
Board generate_board(Vector2 bounds, int mine_count);
|
||||
Cell* get_cell(Board* board, Vector2* position);
|
||||
void shift_board(Board* board, Vector2* direction);
|
||||
void destroy_board(Board);
|
||||
void right_click(Board*);
|
||||
void left_click(Board*);
|
||||
12
include/graphics.h
Normal file
12
include/graphics.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
#include "board.h"
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
void draw_circle(SDL_Renderer* target, Vector2 position, int radius);
|
||||
void draw_grid(SDL_Renderer* target, Vector2 size);
|
||||
void draw_mines(SDL_Renderer* target, Board board);
|
||||
void draw_flags(SDL_Renderer* target, Board board);
|
||||
void draw_hover(SDL_Renderer* targer, Board board);
|
||||
void draw_revealed(SDL_Renderer* target, Board board);
|
||||
void draw_numbers(SDL_Renderer* target, Board* board);
|
||||
Vector2 get_resolution(SDL_Renderer* renderer, Vector2 size);
|
||||
226
src/board.c
Normal file
226
src/board.c
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
#include "board.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
Vector2 random_vector2(Vector2 bounds)
|
||||
{
|
||||
Vector2 output = { -1, -1 };
|
||||
output.x = SDL_rand(bounds.x);
|
||||
output.y = SDL_rand(bounds.y);
|
||||
return output;
|
||||
}
|
||||
|
||||
int get_neighbours(Vector2 input, Vector2 bounds, Vector2* output)
|
||||
{
|
||||
int length = 0;
|
||||
Vector2 tmp = { -1, -1 };
|
||||
if (input.x > 0 && input.y > 0) {
|
||||
tmp.x = input.x - 1;
|
||||
tmp.y = input.y - 1;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.x > 0 && input.y < bounds.y - 1) {
|
||||
tmp.x = input.x - 1;
|
||||
tmp.y = input.y + 1;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.x > 0) {
|
||||
tmp.x = input.x - 1;
|
||||
tmp.y = input.y;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.x < bounds.x - 1 && input.y > 0) {
|
||||
tmp.x = input.x + 1;
|
||||
tmp.y = input.y - 1;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.x < bounds.x - 1 && input.y < bounds.y - 1) {
|
||||
tmp.x = input.x + 1;
|
||||
tmp.y = input.y + 1;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.x < bounds.x - 1) {
|
||||
tmp.x = input.x + 1;
|
||||
tmp.y = input.y;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.y > 0) {
|
||||
tmp.x = input.x;
|
||||
tmp.y = input.y - 1;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
if (input.y < bounds.y - 1) {
|
||||
tmp.x = input.x;
|
||||
tmp.y = input.y + 1;
|
||||
output[length] = tmp;
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
Cell new_cell()
|
||||
{
|
||||
Cell output;
|
||||
output.has_mine = false;
|
||||
output.has_flag = false;
|
||||
output.is_revealed = false;
|
||||
output.revealed_value = -1;
|
||||
return output;
|
||||
}
|
||||
|
||||
char cell_value(Board* board, Vector2 position)
|
||||
{
|
||||
char out = 0;
|
||||
Vector2 neighbours[8];
|
||||
if (get_cell(board, &position)->has_mine) {
|
||||
return -1;
|
||||
}
|
||||
int n = get_neighbours(position, board->bounds, neighbours);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (get_cell(board, &neighbours[i])->has_mine) {
|
||||
out++;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Vector2 find_empty_cell(Board* board)
|
||||
{
|
||||
for (int i = 1; i < board->bounds.x - 1; i++) {
|
||||
for (int j = 1; j < board->bounds.y - 1; j++) {
|
||||
Vector2 position = { i, j };
|
||||
if (cell_value(board, position) == 0) {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector2 out = { -1, -1 };
|
||||
return out;
|
||||
}
|
||||
Board generate_board(Vector2 bounds, int mine_count)
|
||||
{
|
||||
Cell** cells = malloc(sizeof(Cell*) * bounds.x);
|
||||
for (int i = 0; i < bounds.x; i++) {
|
||||
cells[i] = malloc(sizeof(Cell) * bounds.y);
|
||||
for (int j = 0; j < bounds.y; j++) {
|
||||
cells[i][j] = new_cell();
|
||||
}
|
||||
}
|
||||
Board output = { cells, bounds };
|
||||
output.hover.x = -1;
|
||||
output.hover.y = -1;
|
||||
output.game_over = false;
|
||||
output.game_started = false;
|
||||
while (mine_count > 0) {
|
||||
const Vector2 mine_position = random_vector2(bounds);
|
||||
if (cells[mine_position.x][mine_position.y].has_mine) {
|
||||
continue;
|
||||
}
|
||||
mine_count--;
|
||||
cells[mine_position.x][mine_position.y].has_mine = true;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
Cell* get_cell(Board* board, Vector2* position)
|
||||
{
|
||||
return &board->cells[position->x][position->y];
|
||||
}
|
||||
|
||||
void destroy_board(Board board)
|
||||
{
|
||||
for (int i = 0; i < board.bounds.x; i++) {
|
||||
free(board.cells[i]);
|
||||
}
|
||||
free(board.cells);
|
||||
}
|
||||
|
||||
void reveal_cell(Board* board, Vector2* position)
|
||||
{
|
||||
Cell* cell = get_cell(board, position);
|
||||
if (cell->is_revealed == true) {
|
||||
return;
|
||||
}
|
||||
cell->is_revealed = true;
|
||||
cell->revealed_value = cell_value(board, *position);
|
||||
|
||||
if (cell->revealed_value != 0) {
|
||||
return;
|
||||
}
|
||||
Vector2 neighbours[8];
|
||||
int n = get_neighbours(*position, board->bounds, neighbours);
|
||||
for (int i = 0; i < n; i++) {
|
||||
Cell* neighbour = get_cell(board, &neighbours[i]);
|
||||
if (neighbour->has_mine) {
|
||||
continue;
|
||||
}
|
||||
reveal_cell(board, &neighbours[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void right_click(Board* board)
|
||||
{
|
||||
board->cells[board->hover.x][board->hover.y].has_flag
|
||||
= !board->cells[board->hover.x][board->hover.y].has_flag;
|
||||
}
|
||||
|
||||
void left_click(Board* board)
|
||||
{
|
||||
if (board->cells[board->hover.x][board->hover.y].has_flag) {
|
||||
return;
|
||||
}
|
||||
if (!board->game_started) {
|
||||
board->game_started = true;
|
||||
if (cell_value(board, board->hover) == 0) {
|
||||
reveal_cell(board, &board->hover);
|
||||
return;
|
||||
}
|
||||
Vector2 anchor_position = find_empty_cell(board);
|
||||
anchor_position.x = board->hover.x - anchor_position.x;
|
||||
anchor_position.y = board->hover.y - anchor_position.y;
|
||||
shift_board(board, &anchor_position);
|
||||
reveal_cell(board, &board->hover);
|
||||
return;
|
||||
}
|
||||
if (board->cells[board->hover.x][board->hover.y].has_mine) {
|
||||
board->game_over = true;
|
||||
return;
|
||||
}
|
||||
reveal_cell(board, &board->hover);
|
||||
}
|
||||
|
||||
Vector2 sub_modulo(Vector2 a, Vector2 b, Vector2 bounds)
|
||||
{
|
||||
Vector2 out = {
|
||||
(bounds.x + a.x - b.x) % bounds.x,
|
||||
(bounds.y + a.y - b.y) % bounds.y
|
||||
};
|
||||
return out;
|
||||
}
|
||||
|
||||
void shift_board(Board* board, Vector2* direction)
|
||||
{
|
||||
Cell** new_board = malloc(sizeof(Cell*) * board->bounds.x);
|
||||
for (int i = 0; i < board->bounds.x; i++) {
|
||||
new_board[i] = malloc(sizeof(Cell) * board->bounds.y);
|
||||
for (int j = 0; j < board->bounds.y; j++) {
|
||||
Vector2 position = { i, j };
|
||||
position = sub_modulo(position, *direction, board->bounds);
|
||||
new_board[i][j] = *get_cell(board, &position);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < board->bounds.x; i++) {
|
||||
for (int j = 0; j < board->bounds.y; j++) {
|
||||
board->cells[i][j] = new_board[i][j];
|
||||
}
|
||||
free(new_board[i]);
|
||||
}
|
||||
free(new_board);
|
||||
}
|
||||
178
src/graphics.c
Normal file
178
src/graphics.c
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#include "graphics.h"
|
||||
#include "board.h"
|
||||
|
||||
const SDL_Color light_green = { 170, 215, 81, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color dark_green = { 162, 209, 73, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color light_yellow = { 229, 194, 159, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color dark_yellow = { 215, 184, 153, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color hover_dark_green = { 185, 221, 119, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color black = { 0, 0, 0, SDL_ALPHA_OPAQUE };
|
||||
const SDL_Color red = { 255, 0, 0, SDL_ALPHA_OPAQUE };
|
||||
|
||||
void set_color(SDL_Renderer* target, SDL_Color color)
|
||||
{
|
||||
SDL_SetRenderDrawColor(target, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void draw_circle(SDL_Renderer* target, Vector2 position, int radius)
|
||||
{
|
||||
int x = radius;
|
||||
int y = 0;
|
||||
int radius_error = 1 - x;
|
||||
|
||||
while (x >= y) {
|
||||
for (int i = position.x - x; i < position.x + x; i++) {
|
||||
SDL_RenderPoint(target, i, position.y + y);
|
||||
SDL_RenderPoint(target, i, position.y - y);
|
||||
}
|
||||
for (int i = position.x - y; i < position.x + y; i++) {
|
||||
SDL_RenderPoint(target, i, position.y + x);
|
||||
SDL_RenderPoint(target, i, position.y - x);
|
||||
}
|
||||
y++;
|
||||
if (radius_error < 0) {
|
||||
radius_error += 2 * y + 1;
|
||||
} else {
|
||||
x--;
|
||||
radius_error += 2 * (y - x + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 get_resolution(SDL_Renderer* renderer, Vector2 size)
|
||||
{
|
||||
SDL_Rect viewport;
|
||||
Vector2 resolution;
|
||||
bool darker_color = false;
|
||||
SDL_GetRenderViewport(renderer, &viewport);
|
||||
resolution.x = viewport.w / size.x;
|
||||
resolution.y = viewport.h / size.y;
|
||||
return resolution;
|
||||
}
|
||||
|
||||
void draw_grid(SDL_Renderer* target, Vector2 size)
|
||||
{
|
||||
Vector2 resolution = get_resolution(target, size);
|
||||
bool darker_color = false;
|
||||
for (int i = 0; i < size.x; i++) {
|
||||
for (int j = 0; j < size.y; j++) {
|
||||
SDL_FRect rectangle;
|
||||
rectangle.x = resolution.x * i;
|
||||
rectangle.y = resolution.y * j;
|
||||
rectangle.w = resolution.x;
|
||||
rectangle.h = resolution.y;
|
||||
if (darker_color) {
|
||||
set_color(target, dark_green);
|
||||
} else {
|
||||
set_color(target, light_green);
|
||||
}
|
||||
SDL_RenderFillRect(target, &rectangle);
|
||||
darker_color = !darker_color;
|
||||
}
|
||||
darker_color = !darker_color;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_mines(SDL_Renderer* target, Board board)
|
||||
{
|
||||
set_color(target, black);
|
||||
Vector2 resolution = get_resolution(target, board.bounds);
|
||||
int radius = resolution.x / 4;
|
||||
for (int i = 0; i < board.bounds.x; i++) {
|
||||
// SDL_Log("i: %d", i);
|
||||
for (int j = 0; j < board.bounds.y; j++) {
|
||||
// SDL_Log("j: %d", j);
|
||||
if (!board.cells[i][j].has_mine) {
|
||||
continue;
|
||||
}
|
||||
Vector2 position = {
|
||||
resolution.x * i + resolution.x / 2,
|
||||
resolution.y * j + resolution.y / 2
|
||||
};
|
||||
draw_circle(target, position, radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_flags(SDL_Renderer* target, Board board)
|
||||
{
|
||||
set_color(target, red);
|
||||
Vector2 resolution = get_resolution(target, board.bounds);
|
||||
int radius = resolution.x / 4;
|
||||
for (int i = 0; i < board.bounds.x; i++) {
|
||||
// SDL_Log("i: %d", i);
|
||||
for (int j = 0; j < board.bounds.y; j++) {
|
||||
// SDL_Log("j: %d", j);
|
||||
if (!board.cells[i][j].has_flag) {
|
||||
continue;
|
||||
}
|
||||
Vector2 position = {
|
||||
resolution.x * i + resolution.x / 2,
|
||||
resolution.y * j + resolution.y / 2
|
||||
};
|
||||
draw_circle(target, position, radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_hover(SDL_Renderer* target, Board board)
|
||||
{
|
||||
Vector2 resolution = get_resolution(target, board.bounds);
|
||||
set_color(target, hover_dark_green);
|
||||
SDL_FRect rectangle;
|
||||
rectangle.x = resolution.x * board.hover.x;
|
||||
rectangle.y = resolution.y * board.hover.y;
|
||||
rectangle.w = resolution.x;
|
||||
rectangle.h = resolution.y;
|
||||
SDL_RenderFillRect(target, &rectangle);
|
||||
}
|
||||
|
||||
void draw_revealed(SDL_Renderer* target, Board board)
|
||||
{
|
||||
set_color(target, red);
|
||||
Vector2 resolution = get_resolution(target, board.bounds);
|
||||
int radius = resolution.x / 4;
|
||||
bool darker_color = true;
|
||||
for (int i = 0; i < board.bounds.x; i++) {
|
||||
// SDL_Log("i: %d", i);
|
||||
for (int j = 0; j < board.bounds.y; j++) {
|
||||
// SDL_Log("j: %d", j);
|
||||
darker_color = !darker_color;
|
||||
if (!board.cells[i][j].is_revealed) {
|
||||
continue;
|
||||
}
|
||||
SDL_FRect rectangle;
|
||||
rectangle.x = resolution.x * i;
|
||||
rectangle.y = resolution.y * j;
|
||||
rectangle.w = resolution.x;
|
||||
rectangle.h = resolution.y;
|
||||
if (darker_color) {
|
||||
set_color(target, dark_yellow);
|
||||
} else {
|
||||
set_color(target, light_yellow);
|
||||
}
|
||||
SDL_RenderFillRect(target, &rectangle);
|
||||
}
|
||||
darker_color = !darker_color;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_numbers(SDL_Renderer* target, Board* board)
|
||||
{
|
||||
set_color(target, black);
|
||||
Vector2 resolution = get_resolution(target, board->bounds);
|
||||
int radius = resolution.x / 4;
|
||||
for (int i = 0; i < board->bounds.x; i++) {
|
||||
for (int j = 0; j < board->bounds.y; j++) {
|
||||
Vector2 position = { i, j };
|
||||
char text[2] = { get_cell(board, &position)->revealed_value, '\0' };
|
||||
if (text[0] < 1) {
|
||||
continue;
|
||||
}
|
||||
text[0] += '0';
|
||||
int x = resolution.x * i + resolution.x / 2;
|
||||
int y = resolution.y * j + resolution.y / 2;
|
||||
SDL_RenderDebugText(target, x, y, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
115
src/main.c
Normal file
115
src/main.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include "board.h"
|
||||
#include "graphics.h"
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
const int GRID_WIDTH = 18;
|
||||
const int GRID_HEIGHT = 14;
|
||||
const int CELL_RESOLUTION = 30;
|
||||
const Vector2 BOARD_SIZE = { 18, 14 };
|
||||
const int MINE_COUNT = 40;
|
||||
|
||||
static SDL_Window* window = NULL;
|
||||
static SDL_Renderer* renderer = NULL;
|
||||
static Board board;
|
||||
static Vector2 resolution = { -1, -1 };
|
||||
static bool debug_draw_mines = false;
|
||||
|
||||
SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[])
|
||||
{
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_CreateWindowAndRenderer("minesweeper", GRID_WIDTH * CELL_RESOLUTION, GRID_HEIGHT * CELL_RESOLUTION, 0, &window, &renderer);
|
||||
|
||||
SDL_Log("created renderer");
|
||||
SDL_Rect vp;
|
||||
bool status = SDL_GetRenderViewport(renderer, &vp);
|
||||
if (status)
|
||||
SDL_Log("x: %d, y: %d", vp.w, vp.h);
|
||||
else
|
||||
SDL_Log("couldn't get vp");
|
||||
|
||||
Vector2 grid_bounds = { GRID_WIDTH, GRID_HEIGHT };
|
||||
SDL_Log("generating board");
|
||||
board = generate_board(grid_bounds, MINE_COUNT);
|
||||
SDL_Log("generated board");
|
||||
|
||||
resolution = get_resolution(renderer, board.bounds);
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
return SDL_APP_SUCCESS;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
board.hover.x = event->motion.x / resolution.x;
|
||||
board.hover.y = event->motion.y / resolution.y;
|
||||
// SDL_Log("%d %d", mouse_position.x, mouse_position.y);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
if (event->button.button == 3) {
|
||||
right_click(&board);
|
||||
} else if (event->button.button == 1) {
|
||||
left_click(&board);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
if (event->key.key == SDLK_H) {
|
||||
// debug_draw_mines = !debug_draw_mines;
|
||||
}
|
||||
if (event->key.key == SDLK_UP) {
|
||||
Vector2 position = { 0, -1 };
|
||||
shift_board(&board, &position);
|
||||
}
|
||||
if (event->key.key == SDLK_DOWN) {
|
||||
Vector2 position = { 0, 1 };
|
||||
shift_board(&board, &position);
|
||||
}
|
||||
if (event->key.key == SDLK_LEFT) {
|
||||
Vector2 position = { -1, 0 };
|
||||
shift_board(&board, &position);
|
||||
}
|
||||
if (event->key.key == SDLK_RIGHT) {
|
||||
Vector2 position = { 1, 0 };
|
||||
shift_board(&board, &position);
|
||||
}
|
||||
if (event->key.key == SDLK_R) {
|
||||
destroy_board(board);
|
||||
Vector2 grid_bounds = { GRID_WIDTH, GRID_HEIGHT };
|
||||
board = generate_board(grid_bounds, MINE_COUNT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void* appstate)
|
||||
{
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
draw_grid(renderer, BOARD_SIZE);
|
||||
draw_hover(renderer, board);
|
||||
draw_revealed(renderer, board);
|
||||
draw_flags(renderer, board);
|
||||
if (board.game_over || debug_draw_mines) {
|
||||
draw_mines(renderer, board);
|
||||
}
|
||||
draw_numbers(renderer, &board);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void* appstate, SDL_AppResult result)
|
||||
{
|
||||
destroy_board(board);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue