From 2c01d53b9dc5872b0ca384bce8a190c5aaa72536 Mon Sep 17 00:00:00 2001 From: Ritchie Cunningham Date: Sat, 27 Sep 2025 00:34:38 +0100 Subject: [PATCH] [Add] Add single-player mode. --- client/CMakeLists.txt | 11 ++++++++++- client/src/main.cpp | 32 ++++++++++++++++++++++++++++++++ client/src/terminal.cpp | 9 ++++----- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 577bfec..b590e4e 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,16 +1,25 @@ file(GLOB_RECURSE CLIENT_SOURCES "src/*.cpp") +# Explicitly list server sources needed for single-player to avoid main() conflict. +set(SERVER_SOURCES + "../server/src/network_manager.cpp" + "../server/src/player.cpp" +) add_executable(bettolac ${CLIENT_SOURCES} + ${SERVER_SOURCES} ) find_package(SDL3 REQUIRED) find_package(GLEW REQUIRED) find_package(OpenGL REQUIRED) find_package(Freetype REQUIRED) +find_package(Threads REQUIRED) target_link_libraries(bettolac PRIVATE bettola SDL3::SDL3 ${GLEW_LIBRARIES} - ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES}) + ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} Threads::Threads) target_include_directories(bettolac PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src + # Add server include dir for single player mode. + ${CMAKE_SOURCE_DIR}/server/src ${GLEW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS}) diff --git a/client/src/main.cpp b/client/src/main.cpp index d616faf..e3f27db 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -4,14 +4,46 @@ #include #include +/* For single player mode. */ +#include +#include +#include +#include +#include "../../server/src/network_manager.h" + #include "terminal.h" #include "gfx/shape_renderer.h" #include "ui/desktop.h" #include "ui/ui_window.h" +void run_server(void) { + try { + NetworkManager server; + server.start(1337); + /* + * Server's start() method is non-blocking, but NetworkManager + * object must be kept alive. We'll just loop forever and let the OS + * clean up the thread when main exits ;) + */ + while(true) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } + } catch(const std::exception& e) { + fprintf(stderr, "Single-player server thread exception: %s\n", e.what()); + } +} + const int SCREEN_WIDTH = 1280; const int SCREEN_HEIGHT = 720; int main(int argc, char** argv) { + if(argc > 1 && std::string(argv[1]) == "-sp") { + fprintf(stdout, "Starting in single-player mode...\n"); + std::thread server_thread(run_server); + server_thread.detach(); + fprintf(stdout, "Waiting for server initialise...\n"); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + /* Init SDL. */ if(!SDL_Init(SDL_INIT_VIDEO)) { printf("SDL could not initialise! SDL_ERROR: %s\n", SDL_GetError()); diff --git a/client/src/terminal.cpp b/client/src/terminal.cpp index bd9d5ce..6f47146 100644 --- a/client/src/terminal.cpp +++ b/client/src/terminal.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "terminal.h" #include "client_network.h" @@ -15,10 +14,10 @@ Terminal::Terminal(void) { _history.push_back("Welcome to Bettola"); _history.push_back("Connecting to server..."); - _network = std::make_unique(); - _should_close = false; - _scroll_offset = 0; - _prompt = ""; + _network = std::make_unique(); + _should_close = false; + _scroll_offset = 0; + _prompt = ""; /* TODO: Move network to main.cpp, or better yet, a dedicatated game state file */ if(_network->connect("127.0.0.1", 1337)) {