2 Commits

Author SHA1 Message Date
9780a36af4 ff 2025-03-22 23:30:52 +01:00
6b16abda6a fichier settings 2025-03-22 22:03:57 +01:00
21 changed files with 251 additions and 53 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -38,7 +38,7 @@ _Repeat for every avaible actions._
The settings file has the following format: The settings file has the following format:
- The number of the chosen keybinds (from 0 to 4), stored with 1 byte - The number of the chosen keybinds (from 0 to 4), stored with 1 byte
- The size multiplier of the window, stored with 1 byte - The window size mode, stored with 1 byte
- The number of the last selected gamemode (converted from an Enum), stored with 1 byte - The number of the last selected gamemode (converted from an Enum), stored with 1 byte
- The last selected width of the board, stored with 1 byte - The last selected width of the board, stored with 1 byte
- The last selected height of the board, stored with 1 byte - The last selected height of the board, stored with 1 byte

View File

@@ -5,7 +5,6 @@
#include "Game.h" #include "Game.h"
static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the app were choosen with this number in mind static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the app were choosen with this number in mind
static const int MAXIMUM_PIECES_SIZE = 15; // the maximum size of available pieces
/** /**

View File

@@ -6,15 +6,18 @@
#include <memory> #include <memory>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
class AppMenu;
using MenuStack = std::stack<std::shared_ptr<AppMenu>>;
class AppMenu { class AppMenu {
protected: protected:
std::shared_ptr<std::stack<AppMenu>> menuStack; std::shared_ptr<MenuStack> menuStack;
std::shared_ptr<Settings> settings; std::shared_ptr<Settings> settings;
std::shared_ptr<sf::RenderWindow> renderWindow; std::shared_ptr<sf::RenderWindow> renderWindow;
public: public:
AppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) : AppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
menuStack(menuStack), menuStack(menuStack),
settings(settings), settings(settings),
renderWindow(renderWindow) renderWindow(renderWindow)

View File

@@ -7,7 +7,7 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
InGameAppMenu::InGameAppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) : InGameAppMenu::InGameAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
AppMenu(menuStack, settings, renderWindow), AppMenu(menuStack, settings, renderWindow),
game(this->settings->getMenu().startGame(this->settings->getGamemode())) game(this->settings->getMenu().startGame(this->settings->getGamemode()))
{ {

View File

@@ -13,7 +13,7 @@ class InGameAppMenu : public AppMenu {
bool paused; bool paused;
public: public:
InGameAppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow); InGameAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow);
void computeFrame(); void computeFrame();

View File

@@ -1,20 +1,21 @@
#include "MainAppMenu.h" #include "MainAppMenu.h"
#include "AppMenu.h" #include "AppMenu.h"
#include "InGameAppMenu.h"
#include <stack> #include <stack>
#include <memory> #include <memory>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
MainAppMenu::MainAppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) : MainAppMenu::MainAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
AppMenu(menuStack, settings, renderWindow) { AppMenu(menuStack, settings, renderWindow) {
} }
void MainAppMenu::computeFrame() { void MainAppMenu::computeFrame() {
if (sf::Keyboard::isKeyPressed(sfKey::Enter)) { if (sf::Keyboard::isKeyPressed(sfKey::Enter)) {
this->menuStack->push(std::make_shared<InGameAppMenu>(this->menuStack, this->settings, this->renderWindow));
} }
else if (sf::Keyboard::isKeyPressed(sfKey::Escape)) { else if (sf::Keyboard::isKeyPressed(sfKey::Escape)) {
this->menuStack->pop(); this->menuStack->pop();

View File

@@ -9,7 +9,7 @@
class MainAppMenu : public AppMenu { class MainAppMenu : public AppMenu {
public: public:
MainAppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow); MainAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow);
void computeFrame(); void computeFrame();

View File

@@ -13,19 +13,19 @@ static const double TIME_BETWEEN_FRAMES = (1000.f / FRAMES_PER_SECOND);
GraphApp::GraphApp() { GraphApp::GraphApp() {
this->settings = std::make_shared<Settings>(); this->settings = std::make_shared<Settings>();
this->menuStack = std::make_shared<std::stack<AppMenu>>(); this->menuStack = std::make_shared<MenuStack>();
this->window = std::make_shared<sf::RenderWindow>(); this->renderWindow = std::make_shared<sf::RenderWindow>();
} }
void GraphApp::run() { void GraphApp::run() {
changeVideoMode(*this->window, this->settings->getVideoMode()); changeVideoMode(*this->renderWindow, this->settings->getVideoMode());
this->menuStack->push(MainAppMenu(this->menuStack, this->settings, this->window)); this->menuStack->push(std::make_shared<MainAppMenu>(this->menuStack, this->settings, this->renderWindow));
bool quit = false; bool quit = false;
double timeAtNextFrame = 0; double timeAtNextFrame = 0;
sf::Clock clock; sf::Clock clock;
while (!quit) { while (!quit) {
while (const std::optional event = this->window->pollEvent()) { while (const std::optional event = this->renderWindow->pollEvent()) {
if (event->is<sf::Event::Closed>()) { if (event->is<sf::Event::Closed>()) {
quit = true; quit = true;
} }
@@ -34,16 +34,16 @@ void GraphApp::run() {
if (!quit) { if (!quit) {
if (clock.getElapsedTime().asMilliseconds() > timeAtNextFrame) { if (clock.getElapsedTime().asMilliseconds() > timeAtNextFrame) {
timeAtNextFrame += TIME_BETWEEN_FRAMES; timeAtNextFrame += TIME_BETWEEN_FRAMES;
this->menuStack->top().computeFrame(); this->menuStack->top()->computeFrame();
if (this->menuStack->empty()) { if (this->menuStack->empty()) {
quit = true; quit = true;
} }
else { else {
this->menuStack->top().drawFrame(); this->menuStack->top()->drawFrame();
} }
} }
} }
} }
window->close(); renderWindow->close();
} }

View File

@@ -11,8 +11,8 @@
class GraphApp { class GraphApp {
private: private:
std::shared_ptr<Settings> settings; std::shared_ptr<Settings> settings;
std::shared_ptr<std::stack<AppMenu>> menuStack; std::shared_ptr<MenuStack> menuStack;
std::shared_ptr<sf::RenderWindow> window; std::shared_ptr<sf::RenderWindow> renderWindow;
public: public:
GraphApp(); GraphApp();

View File

@@ -0,0 +1,81 @@
#include "Keybinds.h"
#include "../Core/Action.h"
#include <map>
#include <set>
#include <fstream>
#include <SFML/Graphics.hpp>
Keybinds::Keybinds(int layoutNumber) :
layoutNumber(layoutNumber) {
for (Action action : ACTION_LIST_IN_ORDER) {
this->keybinds.insert({action, std::set<sfKey>()});
}
this->loadKeybindsFromFile();
}
void Keybinds::loadKeybindsFromFile() {
std::ifstream layoutFile("data/config/keybinds/layout" + std::to_string(this->layoutNumber) + ".bin", std::ios::binary);
for (Action action : ACTION_LIST_IN_ORDER) {
this->keybinds.at(action).clear();
}
char byte;
while (layoutFile.get(&byte, 1)) {
Action action = Action(byte);
do {
layoutFile.get(&byte, 1);
if (byte != 0xFF) {
this->keybinds.at(action).insert(sfKey(byte));
}
} while (byte != 0xFF);
}
}
void Keybinds::saveKeybindsToFile() const {
std::ofstream layoutFile("data/config/keybinds/layout" + std::to_string(this->layoutNumber) + ".bin", std::ios::trunc | std::ios::binary);
char byte;
for (Action action : ACTION_LIST_IN_ORDER) {
byte = action;
layoutFile.write(&byte, 1);
for (sfKey key : this->keybinds.at(action)) {
byte = (int) key;
layoutFile.write(&byte, 1);
}
byte = 0xFF;
layoutFile.write(&byte, 1);
}
}
void Keybinds::addKey(Action action, sfKey key) {
this->keybinds.at(action).insert(key);
}
void Keybinds::clearKeys(Action action) {
this->keybinds.at(action).clear();
}
const std::set<Action> Keybinds::getActions(sfKey key) const {
std::set<Action> actions;
for (const auto& [action, keys] : this->keybinds) {
if (keys.contains(key)) {
actions.insert(action);
}
}
return actions;
}
const std::set<sfKey>& Keybinds::getKeybinds(Action action) const {
return this->keybinds.at(action);
}

View File

@@ -3,18 +3,22 @@
#include "../Core/Action.h" #include "../Core/Action.h"
#include <map> #include <map>
#include <vector> #include <set>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
using sfKey = sf::Keyboard::Key; using sfKey = sf::Keyboard::Key;
static const int NUMBER_OF_KEYBINDS = 5;
static const int CUSTOMIZABLE_KEYBINDS = NUMBER_OF_KEYBINDS - 1;
class Keybinds { class Keybinds {
private: private:
std::map<Action, std::vector<sfKey>> keybinds; std::map<Action, std::set<sfKey>> keybinds;
int layoutNumber;
public: public:
Keybinds(); Keybinds(int layoutNumber);
void loadKeybindsFromFile(); void loadKeybindsFromFile();
@@ -24,7 +28,7 @@ class Keybinds {
void clearKeys(Action action); void clearKeys(Action action);
const std::vector<Action>& getActions(sfKey key) const; const std::set<Action> getActions(sfKey key) const;
const std::vector<sfKey>& getKeybinds(Action action) const; const std::set<sfKey>& getKeybinds(Action action) const;
}; };

View File

@@ -2,20 +2,20 @@
enum PiecesType { enum PiecesType {
CONVEX, CONVEX_PIECES,
HOLELESS, HOLELESS_PIECES,
OTHERS, OTHER_PIECES,
ALL, ALL_PIECES,
SINGLE SINGLE_PIECE
}; };
inline int getSizeOfPieces(PiecesType type) { inline int getSizeOfPieces(PiecesType type) {
if (type < SINGLE) return 0; if (type < SINGLE_PIECE) return 0;
else return (type - SINGLE + 1); else return (type - SINGLE_PIECE + 1);
} }
inline PiecesType createSinglePieceType(int size) { inline PiecesType createSinglePieceType(int size) {
return PiecesType(SINGLE + size - 1); return PiecesType(SINGLE_PIECE + size - 1);
} }

View File

@@ -4,31 +4,99 @@
#include "Keybinds.h" #include "Keybinds.h"
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <fstream>
static const int NUMBER_OF_KEYBINDS = 5;
static const int CUSTOMIZABLE_KEYBINDS = NUMBER_OF_KEYBINDS - 1;
static const sf::Vector2u BASE_WINDOW_SIZE = {80, 50}; static const sf::Vector2u BASE_WINDOW_SIZE = {80, 50};
static const int WINDOW_SIZE_MULTIPLIERS[] = {4, 6, 9, 14, 20}; static const int WINDOW_SIZE_MULTIPLIERS[] = {4, 6, 9, 14, 20};
static const int WINDOW_SIZE_LAST_MODE = (sizeof(WINDOW_SIZE_MULTIPLIERS) / sizeof(int)) - 1; static const int WINDOW_SIZE_LAST_MODE = (sizeof(WINDOW_SIZE_MULTIPLIERS) / sizeof(int)) - 1;
Settings::Settings() { Settings::Settings() {
for (int i = 1; i <= 15; i++) { for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
this->menu.getPiecesList().loadPieces(i); this->menu.getPiecesList().loadPieces(i);
} }
this->keybinds.reserve(NUMBER_OF_KEYBINDS);
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
this->keybinds.emplace_back(i);
}
this->loadSettingsFromFile(); this->loadSettingsFromFile();
} }
void Settings::loadSettingsFromFile() { void Settings::loadSettingsFromFile() {
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
char byte;
// keybind layout
settingsFile.get(&byte, 1);
this->chosenKeybinds = byte;
// window size mode
settingsFile.get(&byte, 1);
this->windowSizeMode = byte;
// gamemode
settingsFile.get(&byte, 1);
this->gamemode = Gamemode(byte);
// board width
settingsFile.get(&byte, 1);
this->menu.setBoardWidth(byte);
// board height
settingsFile.get(&byte, 1);
this->menu.setBoardHeight(byte);
// piece distribution
settingsFile.get(&byte, 1);
//TODO //TODO
this->menu.getPiecesList().unselectAll();
this->menu.getPiecesList().selectAllPieces(4); // selected pieces
this->windowSizeMode = 2; char pieceType;
char pieceValue;
this->selectedPieces.clear();
while (settingsFile.get(&pieceType, 1)) {
settingsFile.get(&pieceValue, 1);
this->selectedPieces.push_back({PiecesType(pieceType), pieceValue});
}
} }
void Settings::saveSettingsToFile() const { void Settings::saveSettingsToFile() const {
std::ofstream settingsFile("data/config/settings.bin", std::ios::trunc | std::ios::binary);
char byte;
// keybind layout
byte = this->chosenKeybinds;
settingsFile.write(&byte, 1);
// window size mode
byte = this->windowSizeMode;
settingsFile.write(&byte, 1);
// gamemode
byte = this->gamemode;
settingsFile.write(&byte, 1);
// board width
byte = this->menu.getBoardWidth();
settingsFile.write(&byte, 1);
// board height
byte = this->menu.getBoardHeight();
settingsFile.write(&byte, 1);
// piece distribution
//TODO //TODO
settingsFile.write(&byte, 1);
// selected pieces
for (const auto& [type, value] : this->selectedPieces) {
byte = type;
settingsFile.write(&byte, 1);
byte = value;
settingsFile.write(&byte, 1);
}
} }
bool Settings::selectNextKeybinds() { bool Settings::selectNextKeybinds() {
@@ -89,14 +157,14 @@ void Settings::confirmSelectedPieces() {
if (size == 0) { if (size == 0) {
switch (type) { switch (type) {
case CONVEX : {this->menu.getPiecesList().selectConvexPieces(value); break;} case CONVEX_PIECES : {this->menu.getPiecesList().selectConvexPieces(value); break;}
case HOLELESS : {this->menu.getPiecesList().selectHolelessPieces(value); break;} case HOLELESS_PIECES : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
case OTHERS : {this->menu.getPiecesList().selectOtherPieces(value); break;} case OTHER_PIECES : {this->menu.getPiecesList().selectOtherPieces(value); break;}
case ALL : {this->menu.getPiecesList().selectAllPieces(value); break;} case ALL_PIECES : {this->menu.getPiecesList().selectAllPieces(value); break;}
} }
} }
else { else {
if (size > 15) return; if (size > MAXIMUM_PIECES_SIZE) return;
this->menu.getPiecesList().selectPiece(size, value); this->menu.getPiecesList().selectPiece(size, value);
} }

View File

@@ -7,6 +7,11 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <vector> #include <vector>
static const int MAXIMUM_BOARD_WIDTH = 40;
static const int MAXIMUM_BOARD_HEIGHT = 40;
static const int MAXIMUM_PIECES_SIZE = 10;
class Settings { class Settings {
private: private:

View File

@@ -1,12 +1,18 @@
#include "GraphApp.h" #include "GraphApp.h"
#include "../Pieces/PiecesFiles.h" #include "../Pieces/PiecesFiles.h"
#include <fstream> #include <fstream>
void resetConfigFiles();
void resetSettingsFile();
void resetKeybindFile(int layout);
int main() { int main() {
std::srand(std::time(NULL)); std::srand(std::time(NULL));
// dev version // keep only for dev
PiecesFiles pf; PiecesFiles pf;
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) { for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) { if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
@@ -23,7 +29,7 @@ int main() {
} }
} }
// release version // before compiling release version
//resetConfigFiles(); //resetConfigFiles();
GraphApp UI; GraphApp UI;
@@ -41,7 +47,38 @@ void resetConfigFiles() {
} }
void resetSettingsFile() { void resetSettingsFile() {
std::ofstream settingsFile("data/config/settings.bin", std::ios::trunc | std::ios::binary);
char byte;
// keybind layout
byte = 0;
settingsFile.write(&byte, 1);
// window size mode
byte = 2;
settingsFile.write(&byte, 1);
// gamemode
byte = SPRINT;
settingsFile.write(&byte, 1);
// board width
byte = 10;
settingsFile.write(&byte, 1);
// board height
byte = 20;
settingsFile.write(&byte, 1);
// piece distribution
byte = 0;
settingsFile.write(&byte, 1);
// selected pieces
byte = ALL_PIECES;
settingsFile.write(&byte, 1);
byte = 4;
settingsFile.write(&byte, 1);
} }
void resetKeybindFile(int layout) { void resetKeybindFile(int layout) {
@@ -100,17 +137,17 @@ void resetKeybindFile(int layout) {
keybinds.insert({HOLD, sfKey::Z}); keybinds.insert({HOLD, sfKey::Z});
} }
char contentChar; char byte;
for (Action action : ACTION_LIST_IN_ORDER) { for (Action action : ACTION_LIST_IN_ORDER) {
contentChar = action; byte = action;
layoutFile.write(&contentChar, 1); layoutFile.write(&byte, 1);
if (keybinds.contains(action)) { if (keybinds.contains(action)) {
contentChar = (int) keybinds.at(action); byte = (int) keybinds.at(action);
layoutFile.write(&contentChar, 1); layoutFile.write(&byte, 1);
} }
contentChar = 0xFF; byte = 0xFF;
layoutFile.write(&contentChar, 1); layoutFile.write(&byte, 1);
} }
} }