Compare commits
14 Commits
quit-bugfi
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
e9814dea3e | ||
2855b64f03 | |||
9c45259962 | |||
b1256014e3 | |||
b1af7b4f41 | |||
2b0f20d65a | |||
e394d0986e | |||
d8eb655dd7 | |||
b878c2ddb3 | |||
a0e5850e68 | |||
84972ed9bb | |||
08f6ee7161 | |||
f7d2f138ea | |||
1d07cee01a |
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,4 +6,3 @@ lib
|
|||||||
.vscode
|
.vscode
|
||||||
bin
|
bin
|
||||||
build
|
build
|
||||||
Makefile
|
|
@ -9,7 +9,7 @@ DBG_CXXFLAGS := $(CXXFLAGS) -g
|
|||||||
RLS_CXXFLAGS := $(CXXFLAGS) -O2
|
RLS_CXXFLAGS := $(CXXFLAGS) -O2
|
||||||
|
|
||||||
# linker stuff
|
# linker stuff
|
||||||
LDFLAGS := -lncursesw
|
LDFLAGS := -lncursesw -lSDL2
|
||||||
DBG_LDFLAGS := $(LDFLAGS)
|
DBG_LDFLAGS := $(LDFLAGS)
|
||||||
RLS_LDFLAGS := $(LDFLAGS) -s
|
RLS_LDFLAGS := $(LDFLAGS) -s
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ $(shell mkdir -p $(RLS_DIR))
|
|||||||
$(shell mkdir -p $(BUILD_DIR))
|
$(shell mkdir -p $(BUILD_DIR))
|
||||||
|
|
||||||
# phony rules
|
# phony rules
|
||||||
.PHONY := all debug release clean install uninstall
|
.PHONY = all debug release clean install uninstall
|
||||||
|
|
||||||
all: release
|
all: release
|
||||||
|
|
72
Makefile.win
72
Makefile.win
@ -1,72 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 thorium1256
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
# compiler stuff
|
|
||||||
CXX := c++
|
|
||||||
CXXFLAGS := -I include -std=c++11 -Wall -Wextra
|
|
||||||
DBG_CXXFLAGS := $(CXXFLAGS) -g
|
|
||||||
RLS_CXXFLAGS := $(CXXFLAGS) -O2
|
|
||||||
|
|
||||||
# linker stuff
|
|
||||||
LDFLAGS := -L C:\msys64\mingw64\bin -lncursesw6
|
|
||||||
DBG_LDFLAGS := $(LDFLAGS)
|
|
||||||
RLS_STRP_LDFLAGS := $(LDFLAGS) -s
|
|
||||||
|
|
||||||
# directories
|
|
||||||
BUILD_DIR := build
|
|
||||||
SRC_DIR := src
|
|
||||||
BIN_DIR := bin
|
|
||||||
DBG_DIR := $(BIN_DIR)\debug
|
|
||||||
RLS_DIR := $(BIN_DIR)\release
|
|
||||||
LIB_DIR := lib
|
|
||||||
DBG_EXEC := $(DBG_DIR)\debug.exe
|
|
||||||
RLS_STRIPPED_EXEC := $(RLS_DIR)\tuimine.exe
|
|
||||||
|
|
||||||
# sources and objects
|
|
||||||
LIBS := $(wildcard $(LIB_DIR)/*.dll)
|
|
||||||
LIBS_DBG := $(patsubst $(LIB_DIR)/%.dll, $(DBG_DIR)\\%.dll, $(LIBS))
|
|
||||||
LIBS_RLS := $(patsubst $(LIB_DIR)/%.dll, $(RLS_DIR)\\%.dll, $(LIBS))
|
|
||||||
SRCS := $(wildcard $(SRC_DIR)/*.cpp)
|
|
||||||
DBG_OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/debug_%.o,$(SRCS))
|
|
||||||
RLS_OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/release_%.o,$(SRCS))
|
|
||||||
|
|
||||||
$(shell if not exist $(BIN_DIR) mkdir $(BIN_DIR))
|
|
||||||
$(shell if not exist $(DBG_DIR) mkdir $(DBG_DIR))
|
|
||||||
$(shell if not exist $(RLS_DIR) mkdir $(RLS_DIR))
|
|
||||||
$(shell if not exist $(BUILD_DIR) mkdir $(BUILD_DIR))
|
|
||||||
|
|
||||||
# phony rules
|
|
||||||
.PHONY := all debug release clean libraries_debug libraries_release both
|
|
||||||
|
|
||||||
all: release
|
|
||||||
|
|
||||||
debug: $(DBG_EXEC) libraries_debug
|
|
||||||
release: $(RLS_STRIPPED_EXEC) libraries_release
|
|
||||||
both: debug release
|
|
||||||
|
|
||||||
libraries_debug: $(LIBS_DBG)
|
|
||||||
libraries_release: $(LIBS_RLS)
|
|
||||||
|
|
||||||
# linking
|
|
||||||
$(DBG_EXEC): $(DBG_OBJS)
|
|
||||||
$(CXX) -o $@ $^ $(DBG_LDFLAGS)
|
|
||||||
|
|
||||||
$(RLS_STRIPPED_EXEC): $(RLS_OBJS)
|
|
||||||
$(CXX) -o $@ $^ $(RLS_STRP_LDFLAGS)
|
|
||||||
|
|
||||||
# compiling
|
|
||||||
$(BUILD_DIR)/debug_%.o: $(SRC_DIR)/%.cpp
|
|
||||||
$(CXX) -c -o $@ $< $(DBG_CXXFLAGS)
|
|
||||||
|
|
||||||
$(BUILD_DIR)/release_%.o: $(SRC_DIR)/%.cpp
|
|
||||||
$(CXX) -c -o $@ $< $(RLS_CXXFLAGS)
|
|
||||||
|
|
||||||
$(DBG_DIR)\\%.dll: $(LIB_DIR)\\%.dll
|
|
||||||
xcopy $< $(DBG_DIR)\ >nul
|
|
||||||
|
|
||||||
$(RLS_DIR)\\%.dll: $(LIB_DIR)\\%.dll
|
|
||||||
xcopy $< $(RLS_DIR)\ >nul
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rmdir /s /q $(BUILD_DIR) $(DBG_DIR) $(RLS_DIR)
|
|
157
src/main.cpp
157
src/main.cpp
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <ncursesw/ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
#include "Board.h"
|
#include "Board.h"
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -20,6 +21,8 @@ void handleSIGWINCH(int sig)
|
|||||||
|
|
||||||
#define MAX_TIME 60
|
#define MAX_TIME 60
|
||||||
|
|
||||||
|
SDL_GameController *controller;
|
||||||
|
|
||||||
void startGame(Board &board)
|
void startGame(Board &board)
|
||||||
{
|
{
|
||||||
int minesLeft = board.getMineCount();
|
int minesLeft = board.getMineCount();
|
||||||
@ -44,7 +47,8 @@ void startGame(Board &board)
|
|||||||
{
|
{
|
||||||
usleep((1000 / MAX_TIME) * 1000);
|
usleep((1000 / MAX_TIME) * 1000);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if((w.ws_row < boardSize.x + 3 )||( w.ws_col < boardSize.y + 2)) {
|
if ((w.ws_row < boardSize.x + 3) || (w.ws_col < boardSize.y + 2))
|
||||||
|
{
|
||||||
mvprintw(w.ws_col / 2, w.ws_row / 2, "Your terminal is too small:");
|
mvprintw(w.ws_col / 2, w.ws_row / 2, "Your terminal is too small:");
|
||||||
mvprintw(w.ws_col / 2 + 1, w.ws_row / 2, "Current size: %dx%d", w.ws_row, w.ws_col);
|
mvprintw(w.ws_col / 2 + 1, w.ws_row / 2, "Current size: %dx%d", w.ws_row, w.ws_col);
|
||||||
mvprintw(w.ws_col / 2 + 2, w.ws_row / 2, "Min size: %dx%d", boardSize.x + 3, boardSize.y + 2);
|
mvprintw(w.ws_col / 2 + 2, w.ws_row / 2, "Min size: %dx%d", boardSize.x + 3, boardSize.y + 2);
|
||||||
@ -160,8 +164,115 @@ void startGame(Board &board)
|
|||||||
|
|
||||||
c = getch();
|
c = getch();
|
||||||
if (c == ERR)
|
if (c == ERR)
|
||||||
|
{
|
||||||
|
if (controller != nullptr)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
if (event.type == SDL_CONTROLLERBUTTONDOWN)
|
||||||
|
{
|
||||||
|
switch (event.cbutton.button)
|
||||||
|
{
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||||
|
cursorY = (cursorY > 0) ? cursorY - 1 : boardSize.y - 1;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||||
|
cursorY = (cursorY < boardSize.y - 1) ? cursorY + 1 : 0;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||||
|
cursorX = (cursorX > 0) ? cursorX - 1 : boardSize.x - 1;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||||
|
cursorX = (cursorX < boardSize.x - 1) ? cursorX + 1 : 0;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_START:
|
||||||
|
if (isPaused)
|
||||||
|
{
|
||||||
|
pauseTime = difftime(time(NULL), startPauseTime);
|
||||||
|
totalpausetime += pauseTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startPauseTime = time(NULL);
|
||||||
|
}
|
||||||
|
isPaused = !isPaused;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_A:
|
||||||
|
if (!somethingHasBeenDone)
|
||||||
|
{
|
||||||
|
startTime = time(nullptr);
|
||||||
|
somethingHasBeenDone = true;
|
||||||
|
}
|
||||||
|
if (board.getCellStateAt(cursorX, cursorY) == Cell::State::Revealed)
|
||||||
|
{
|
||||||
|
if (!somethingHasBeenDone)
|
||||||
|
{
|
||||||
|
startTime = time(nullptr);
|
||||||
|
somethingHasBeenDone = true;
|
||||||
|
}
|
||||||
|
auto neighbors = board.getNeighborsOf(cursorX, cursorY);
|
||||||
|
int flagCount = 0;
|
||||||
|
for (const Cell &neighbor : neighbors)
|
||||||
|
{
|
||||||
|
if (neighbor.getState() == Cell::State::Flagged)
|
||||||
|
flagCount++;
|
||||||
|
}
|
||||||
|
if (static_cast<int>(board.revealCellAt(cursorX, cursorY).getContent()) > flagCount)
|
||||||
|
break;
|
||||||
|
for (const Cell &neighbor : neighbors)
|
||||||
|
{
|
||||||
|
if (neighbor.getState() == Cell::State::Flagged)
|
||||||
continue;
|
continue;
|
||||||
|
board.revealCellAt(neighbor.getPosition().x, neighbor.getPosition().y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
board.revealCellAt(cursorX, cursorY);
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_B:
|
||||||
|
if (board.getCellStateAt(cursorX, cursorY) == Cell::State::Revealed)
|
||||||
|
break;
|
||||||
|
if (!somethingHasBeenDone)
|
||||||
|
{
|
||||||
|
startTime = time(nullptr);
|
||||||
|
somethingHasBeenDone = true;
|
||||||
|
}
|
||||||
|
if (board.getCellStateAt(cursorX, cursorY) == Cell::State::Flagged)
|
||||||
|
{
|
||||||
|
minesLeft++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minesLeft--;
|
||||||
|
}
|
||||||
|
board.flagCellAt(cursorX, cursorY);
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_MISC1:
|
||||||
|
startTime = time(NULL);
|
||||||
|
minesLeft = board.getMineCount();
|
||||||
|
board.regenerateBoard();
|
||||||
|
somethingHasBeenDone = false;
|
||||||
|
elapsedTime = 0;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_BACK:
|
||||||
|
echo();
|
||||||
|
cbreak();
|
||||||
|
endwin();
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(c == ERR))
|
||||||
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
@ -254,6 +365,7 @@ void startGame(Board &board)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isPaused)
|
if (isPaused)
|
||||||
continue;
|
continue;
|
||||||
@ -282,7 +394,9 @@ void startGame(Board &board)
|
|||||||
{
|
{
|
||||||
Board newBoard(boardSize.x, boardSize.y, board.getMineCount());
|
Board newBoard(boardSize.x, boardSize.y, board.getMineCount());
|
||||||
startGame(newBoard);
|
startGame(newBoard);
|
||||||
} else if(c == 'q') {
|
}
|
||||||
|
else if (c == 'q')
|
||||||
|
{
|
||||||
echo();
|
echo();
|
||||||
cbreak();
|
cbreak();
|
||||||
endwin();
|
endwin();
|
||||||
@ -312,7 +426,9 @@ void startGame(Board &board)
|
|||||||
{
|
{
|
||||||
Board newBoard(boardSize.x, boardSize.y, board.getMineCount());
|
Board newBoard(boardSize.x, boardSize.y, board.getMineCount());
|
||||||
startGame(newBoard);
|
startGame(newBoard);
|
||||||
} else if(c == 'q') {
|
}
|
||||||
|
else if (c == 'q')
|
||||||
|
{
|
||||||
echo();
|
echo();
|
||||||
cbreak();
|
cbreak();
|
||||||
endwin();
|
endwin();
|
||||||
@ -322,16 +438,49 @@ void startGame(Board &board)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_GameController *findController()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < SDL_NumJoysticks(); i++)
|
||||||
|
{
|
||||||
|
if (SDL_IsGameController(i))
|
||||||
|
{
|
||||||
|
return SDL_GameControllerOpen(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
signal(SIGWINCH, handleSIGWINCH);
|
signal(SIGWINCH, handleSIGWINCH);
|
||||||
|
#endif
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
initscr();
|
initscr();
|
||||||
noecho();
|
noecho();
|
||||||
cbreak();
|
cbreak();
|
||||||
keypad(stdscr, TRUE);
|
keypad(stdscr, TRUE);
|
||||||
nodelay(stdscr, TRUE);
|
nodelay(stdscr, TRUE);
|
||||||
|
#ifndef _WIN32
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool controllerSupport;
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_GAMECONTROLLER) < 0)
|
||||||
|
{
|
||||||
|
std::cerr << "SDL failed to initialize GameController API! Controller support will not be available!" << std::endl;
|
||||||
|
controllerSupport = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllerSupport = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
controller = findController();
|
||||||
|
if (controller != nullptr)
|
||||||
|
controllerSupport = false; // no controller for you
|
||||||
|
|
||||||
start_color();
|
start_color();
|
||||||
init_pair(1, COLOR_BLUE, COLOR_BLACK);
|
init_pair(1, COLOR_BLUE, COLOR_BLACK);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user