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,10 +38,10 @@ _Repeat for every avaible actions._
The settings file has the following format:
- 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 last selected width of the board, stored with 1 byte
- The last selected height of the board, stored with 1 byte
- The uniformity mode (0 for default distribution, 1 for uniformous distribution, 2 for custom distribution), stored with 1 byte
- If custom distribution is set, store the proportion of each size (15x1 byte total)
- Every selected pieces, using 1 byte for the type of selection (once again converted from an Enum) and 1 byte for the actual value
- Every selected pieces, using 1 byte for the type of selection (once again converted from an Enum) and 1 byte for the actual value

View File

@@ -5,7 +5,6 @@
#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 MAXIMUM_PIECES_SIZE = 15; // the maximum size of available pieces
/**

View File

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

View File

@@ -7,7 +7,7 @@
#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),
game(this->settings->getMenu().startGame(this->settings->getGamemode()))
{

View File

@@ -13,7 +13,7 @@ class InGameAppMenu : public AppMenu {
bool paused;
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();

View File

@@ -1,20 +1,21 @@
#include "MainAppMenu.h"
#include "AppMenu.h"
#include "InGameAppMenu.h"
#include <stack>
#include <memory>
#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) {
}
void MainAppMenu::computeFrame() {
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)) {
this->menuStack->pop();

View File

@@ -9,7 +9,7 @@
class MainAppMenu : public AppMenu {
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();

View File

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

View File

@@ -11,8 +11,8 @@
class GraphApp {
private:
std::shared_ptr<Settings> settings;
std::shared_ptr<std::stack<AppMenu>> menuStack;
std::shared_ptr<sf::RenderWindow> window;
std::shared_ptr<MenuStack> menuStack;
std::shared_ptr<sf::RenderWindow> renderWindow;
public:
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 <map>
#include <vector>
#include <set>
#include <SFML/Graphics.hpp>
using sfKey = sf::Keyboard::Key;
static const int NUMBER_OF_KEYBINDS = 5;
static const int CUSTOMIZABLE_KEYBINDS = NUMBER_OF_KEYBINDS - 1;
class Keybinds {
private:
std::map<Action, std::vector<sfKey>> keybinds;
std::map<Action, std::set<sfKey>> keybinds;
int layoutNumber;
public:
Keybinds();
Keybinds(int layoutNumber);
void loadKeybindsFromFile();
@@ -24,7 +28,7 @@ class Keybinds {
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 {
CONVEX,
HOLELESS,
OTHERS,
ALL,
SINGLE
CONVEX_PIECES,
HOLELESS_PIECES,
OTHER_PIECES,
ALL_PIECES,
SINGLE_PIECE
};
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) {
return PiecesType(SINGLE + size - 1);
return PiecesType(SINGLE_PIECE + size - 1);
}

View File

@@ -4,31 +4,99 @@
#include "Keybinds.h"
#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 int WINDOW_SIZE_MULTIPLIERS[] = {4, 6, 9, 14, 20};
static const int WINDOW_SIZE_LAST_MODE = (sizeof(WINDOW_SIZE_MULTIPLIERS) / sizeof(int)) - 1;
Settings::Settings() {
for (int i = 1; i <= 15; i++) {
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; 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();
}
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
this->menu.getPiecesList().unselectAll();
this->menu.getPiecesList().selectAllPieces(4);
this->windowSizeMode = 2;
// selected pieces
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 {
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
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() {
@@ -89,14 +157,14 @@ void Settings::confirmSelectedPieces() {
if (size == 0) {
switch (type) {
case CONVEX : {this->menu.getPiecesList().selectConvexPieces(value); break;}
case HOLELESS : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
case OTHERS : {this->menu.getPiecesList().selectOtherPieces(value); break;}
case ALL : {this->menu.getPiecesList().selectAllPieces(value); break;}
case CONVEX_PIECES : {this->menu.getPiecesList().selectConvexPieces(value); break;}
case HOLELESS_PIECES : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
case OTHER_PIECES : {this->menu.getPiecesList().selectOtherPieces(value); break;}
case ALL_PIECES : {this->menu.getPiecesList().selectAllPieces(value); break;}
}
}
else {
if (size > 15) return;
if (size > MAXIMUM_PIECES_SIZE) return;
this->menu.getPiecesList().selectPiece(size, value);
}

View File

@@ -7,6 +7,11 @@
#include <SFML/Graphics.hpp>
#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 {
private:

View File

@@ -1,12 +1,18 @@
#include "GraphApp.h"
#include "../Pieces/PiecesFiles.h"
#include <fstream>
void resetConfigFiles();
void resetSettingsFile();
void resetKeybindFile(int layout);
int main() {
std::srand(std::time(NULL));
// dev version
// keep only for dev
PiecesFiles pf;
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
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();
GraphApp UI;
@@ -41,7 +47,38 @@ void resetConfigFiles() {
}
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) {
@@ -100,17 +137,17 @@ void resetKeybindFile(int layout) {
keybinds.insert({HOLD, sfKey::Z});
}
char contentChar;
char byte;
for (Action action : ACTION_LIST_IN_ORDER) {
contentChar = action;
layoutFile.write(&contentChar, 1);
byte = action;
layoutFile.write(&byte, 1);
if (keybinds.contains(action)) {
contentChar = (int) keybinds.at(action);
layoutFile.write(&contentChar, 1);
byte = (int) keybinds.at(action);
layoutFile.write(&byte, 1);
}
contentChar = 0xFF;
layoutFile.write(&contentChar, 1);
byte = 0xFF;
layoutFile.write(&byte, 1);
}
}