2020-06-24 11:05:49 +08:00
|
|
|
#include <ncurses.h>
|
2020-07-05 20:47:00 +08:00
|
|
|
#include <stdlib.h>
|
2020-06-24 09:51:30 +08:00
|
|
|
#include "game.h"
|
|
|
|
#include "grid.h"
|
|
|
|
#include "vect.h"
|
2020-07-04 07:26:34 +08:00
|
|
|
#include "log.h"
|
2020-06-24 09:51:30 +08:00
|
|
|
|
2020-06-24 11:05:49 +08:00
|
|
|
static Grid* grid = 0;
|
2020-06-24 09:51:30 +08:00
|
|
|
|
|
|
|
static bool running = true;
|
2020-06-24 21:27:24 +08:00
|
|
|
static bool stepping_mode = false;
|
2020-06-24 09:51:30 +08:00
|
|
|
static bool do_step = true;
|
2020-06-24 11:05:49 +08:00
|
|
|
static Vect2i cursor;
|
2020-06-24 09:51:30 +08:00
|
|
|
|
2020-06-24 21:27:24 +08:00
|
|
|
// declaration of locally used
|
|
|
|
static void toggleStepMode();
|
|
|
|
|
|
|
|
static void toggleCell();
|
|
|
|
|
2020-07-05 20:47:00 +08:00
|
|
|
int min (int a, int b);
|
|
|
|
|
|
|
|
int max (int a, int b);
|
|
|
|
|
2020-06-24 09:51:30 +08:00
|
|
|
void initGame()
|
|
|
|
{
|
2020-06-27 08:18:06 +08:00
|
|
|
// init
|
|
|
|
initscr();
|
|
|
|
raw();
|
|
|
|
noecho();
|
|
|
|
// Colors
|
|
|
|
// allows for transparancy when color values in init_pair(); are set to -1 or, no pair specified
|
|
|
|
// e.g init_pair(1, COLOR_WHITE, -1) would be transparent background but white text
|
|
|
|
use_default_colors();
|
|
|
|
start_color();
|
|
|
|
// cell
|
|
|
|
init_pair(1, COLOR_BLUE, COLOR_WHITE);
|
|
|
|
// text
|
|
|
|
init_pair(2, COLOR_YELLOW, -1);
|
|
|
|
// cursor
|
|
|
|
init_pair(3, COLOR_RED, COLOR_RED);
|
|
|
|
// doesn't wait for user to input.
|
|
|
|
// timeout(100) waits for 100ms for input.
|
|
|
|
timeout(0);
|
|
|
|
curs_set(FALSE);
|
|
|
|
|
2020-06-24 11:05:49 +08:00
|
|
|
int width = 0;
|
|
|
|
int height = 0;
|
|
|
|
// stdscr is screen created by initscr()
|
|
|
|
getmaxyx(stdscr, height, width);
|
2020-06-24 21:27:24 +08:00
|
|
|
|
|
|
|
grid = initGrid(width, height);
|
2020-06-27 08:18:06 +08:00
|
|
|
//randomizeGrid(grid);
|
2020-06-24 11:05:49 +08:00
|
|
|
cursor.x = width/2; cursor.y = height/2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateGame()
|
|
|
|
{
|
|
|
|
if (!grid) return;
|
2020-06-24 21:27:24 +08:00
|
|
|
if (do_step) {
|
|
|
|
updateGrid(grid);
|
|
|
|
if (stepping_mode) do_step = false;
|
|
|
|
}
|
2020-06-24 11:05:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void drawGame()
|
|
|
|
{
|
|
|
|
if (!grid) return;
|
|
|
|
drawGrid(grid);
|
2020-06-24 09:51:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isRunning() { return running; }
|
|
|
|
|
2020-06-24 21:27:24 +08:00
|
|
|
|
2020-06-24 09:51:30 +08:00
|
|
|
void handleInput(char ch)
|
|
|
|
{
|
|
|
|
switch (ch) {
|
2020-06-24 11:05:49 +08:00
|
|
|
case 'q':
|
|
|
|
running = false;
|
|
|
|
break;
|
|
|
|
case ' ':
|
2020-06-24 21:27:24 +08:00
|
|
|
toggleStepMode();
|
2020-06-24 11:05:49 +08:00
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
moveVect2i(&cursor, -1, 0);
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
moveVect2i(&cursor, 0, 1);
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
moveVect2i(&cursor, 0, -1);
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
moveVect2i(&cursor, 1, 0);
|
|
|
|
break;
|
2020-06-27 08:18:06 +08:00
|
|
|
case 'r':
|
|
|
|
randomizeGrid(grid);
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
clearGrid(grid);
|
|
|
|
break;
|
2020-06-24 21:27:24 +08:00
|
|
|
case '\n':
|
|
|
|
do_step = true;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
toggleCell();
|
2020-06-24 11:05:49 +08:00
|
|
|
break;
|
2020-07-06 07:59:39 +08:00
|
|
|
case 'e':
|
|
|
|
loadGame("test.txt");
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
saveGame("test.txt");
|
|
|
|
break;
|
2020-06-24 21:27:24 +08:00
|
|
|
default:
|
|
|
|
if (ch != -1) do_step = true;
|
2020-06-24 09:51:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 21:27:24 +08:00
|
|
|
void drawLastPressed(char ch)
|
2020-06-24 11:05:49 +08:00
|
|
|
{
|
|
|
|
static char lastc = ' ';
|
|
|
|
if (ch != -1) lastc = ch;
|
|
|
|
attron(COLOR_PAIR(2));
|
|
|
|
mvprintw(0, 0, "Last Pressed: %c", lastc);
|
|
|
|
attroff(COLOR_PAIR(2));
|
|
|
|
}
|
|
|
|
|
2020-06-24 21:27:24 +08:00
|
|
|
void drawCurPos()
|
2020-06-24 09:51:30 +08:00
|
|
|
{
|
|
|
|
attron(COLOR_PAIR(2));
|
|
|
|
mvprintw(1, 0, "curpos: %i, %i", cursor.x, cursor.y);
|
2020-06-24 21:27:24 +08:00
|
|
|
attroff(COLOR_PAIR(2));
|
2020-06-24 09:51:30 +08:00
|
|
|
attron(COLOR_PAIR(3));
|
|
|
|
mvaddch(cursor.y, cursor.x, ' ');
|
|
|
|
attroff(COLOR_PAIR(3));
|
|
|
|
}
|
|
|
|
|
2020-07-04 07:26:34 +08:00
|
|
|
void saveGame(char* name)
|
|
|
|
{
|
2020-07-05 20:47:00 +08:00
|
|
|
FILE* file = NULL;
|
|
|
|
file = fopen(name, "w");
|
2020-07-07 05:28:47 +08:00
|
|
|
if (!file) {
|
|
|
|
logLine("Failed to write file.");
|
|
|
|
return;
|
2020-07-04 07:26:34 +08:00
|
|
|
}
|
2020-07-07 05:28:47 +08:00
|
|
|
|
|
|
|
unsigned int dimensions[2] = {grid->width, grid->size};
|
|
|
|
fwrite(dimensions, sizeof(dimensions), 1, file);
|
|
|
|
fwrite(grid->state, sizeof(bool), grid->size, file);
|
|
|
|
|
|
|
|
fclose(file);
|
2020-07-04 07:26:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void loadGame(char* name)
|
|
|
|
{
|
2020-07-05 20:47:00 +08:00
|
|
|
FILE* file = NULL;
|
|
|
|
file = fopen(name, "r");
|
2020-07-07 05:28:47 +08:00
|
|
|
if (!file) {
|
|
|
|
logLine("Failed to load file.");
|
|
|
|
return;
|
|
|
|
}
|
2020-07-05 20:47:00 +08:00
|
|
|
|
|
|
|
if (!grid) initGame();
|
|
|
|
else clearGrid(grid);
|
|
|
|
|
2020-07-07 05:28:47 +08:00
|
|
|
unsigned int width, height, size;
|
2020-07-05 20:47:00 +08:00
|
|
|
bool* pixels;
|
2020-07-06 07:59:39 +08:00
|
|
|
|
2020-07-07 05:28:47 +08:00
|
|
|
fread(&width, sizeof(unsigned int), 1, file);
|
|
|
|
fread(&size, sizeof(unsigned int), 1, file);
|
|
|
|
height = size/width;
|
|
|
|
pixels = (bool*)malloc(sizeof(bool)*size);
|
|
|
|
fread(pixels, sizeof(bool), size, file);
|
2020-07-05 20:47:00 +08:00
|
|
|
|
2020-07-07 05:28:47 +08:00
|
|
|
|
2020-07-05 20:47:00 +08:00
|
|
|
unsigned int grid_width, grid_height;
|
|
|
|
getDimensions(grid, &grid_width, &grid_height);
|
|
|
|
for (int y =0; y < min(grid_height, height); y++) {
|
|
|
|
for (int x =0; x < min(grid_width, width); x++) {
|
2020-07-06 07:59:39 +08:00
|
|
|
int index = y * width + x;
|
|
|
|
setPixel(grid, x, y, pixels[index]);
|
2020-07-05 20:47:00 +08:00
|
|
|
}
|
|
|
|
}
|
2020-07-06 07:59:39 +08:00
|
|
|
free(pixels);
|
2020-07-05 20:47:00 +08:00
|
|
|
|
|
|
|
fclose(file);
|
2020-07-04 07:26:34 +08:00
|
|
|
}
|
|
|
|
|
2020-06-24 09:51:30 +08:00
|
|
|
void endGame()
|
|
|
|
{
|
2020-06-24 21:27:24 +08:00
|
|
|
// free stuff
|
2020-06-27 08:18:06 +08:00
|
|
|
endwin();
|
|
|
|
destroyGrid(grid);
|
2020-06-24 21:27:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// locally used
|
|
|
|
static void toggleStepMode()
|
|
|
|
{
|
|
|
|
stepping_mode ^= 1;
|
|
|
|
do_step = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void toggleCell()
|
|
|
|
{
|
|
|
|
if (!grid) return;
|
|
|
|
bool cell = getPixel(grid, cursor.x, cursor.y);
|
|
|
|
if (cell) setPixel(grid, cursor.x, cursor.y, 0);
|
|
|
|
else setPixel(grid, cursor.x, cursor.y, 1);
|
|
|
|
|
2020-06-24 09:51:30 +08:00
|
|
|
}
|
2020-07-05 20:47:00 +08:00
|
|
|
|
|
|
|
int min(int a, int b)
|
|
|
|
{
|
|
|
|
if (a <= b) return a;
|
|
|
|
else return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
int max(int a, int b)
|
|
|
|
{
|
|
|
|
if (a >= b) return a;
|
|
|
|
else return b;
|
|
|
|
}
|