Compare commits
1 Commits
main
...
quit-bugfi
Author | SHA1 | Date | |
---|---|---|---|
80a9d4d8ec |
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@ 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 -lSDL2
|
LDFLAGS := -lncursesw
|
||||||
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
Normal file
72
Makefile.win
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# 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)
|
163
src/main.cpp
163
src/main.cpp
@ -4,10 +4,9 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <ncurses.h>
|
#include <ncursesw/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>
|
||||||
@ -21,8 +20,6 @@ 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();
|
||||||
@ -47,11 +44,10 @@ 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);
|
|
||||||
refresh();
|
refresh();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -164,115 +160,8 @@ 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:
|
||||||
@ -365,7 +254,6 @@ void startGame(Board &board)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (isPaused)
|
if (isPaused)
|
||||||
continue;
|
continue;
|
||||||
@ -394,9 +282,7 @@ 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();
|
||||||
@ -426,9 +312,7 @@ 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();
|
||||||
@ -438,49 +322,16 @@ 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