From f2cddaa21b18e7e84e8de2d391855482206e494e Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 14 Aug 2024 18:36:42 +0300 Subject: [PATCH 01/12] Split vcmiclient in two Similar to vcmiserver (app) and vcmiservercommon (lib), now there is vcmiclient (app) and vcmiclientcommon (lib). --- CMakeLists.txt | 1 + client/CMT.cpp | 390 +---------------------- client/CMT.h | 1 + client/CMakeLists.txt | 126 ++------ client/CPlayerInterface.cpp | 1 - client/ClientCommandManager.cpp | 1 - client/eventsSDL/InputSourceText.cpp | 1 - client/eventsSDL/InputSourceTouch.cpp | 1 - clientapp/CMakeLists.txt | 100 ++++++ clientapp/EntryPoint.cpp | 424 ++++++++++++++++++++++++++ clientapp/StdInc.cpp | 11 + clientapp/StdInc.h | 14 + 12 files changed, 585 insertions(+), 486 deletions(-) create mode 100644 clientapp/CMakeLists.txt create mode 100644 clientapp/EntryPoint.cpp create mode 100644 clientapp/StdInc.cpp create mode 100644 clientapp/StdInc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dcbe5d562..b45403a4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -677,6 +677,7 @@ endif() if (ENABLE_CLIENT) add_subdirectory(client) + add_subdirectory(clientapp) endif() if(ENABLE_SERVER) diff --git a/client/CMT.cpp b/client/CMT.cpp index 3962a1821..7bb0872f9 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -8,42 +8,29 @@ * */ -// CMT.cpp : Defines the entry point for the console application. #include "StdInc.h" #include "CMT.h" #include "CGameInfo.h" #include "mainmenu/CMainMenu.h" -#include "media/CEmptyVideoPlayer.h" #include "media/CMusicHandler.h" #include "media/CSoundHandler.h" #include "media/CVideoHandler.h" #include "gui/CursorHandler.h" -#include "eventsSDL/InputHandler.h" #include "CPlayerInterface.h" #include "gui/CGuiHandler.h" #include "gui/WindowHandler.h" #include "CServerHandler.h" -#include "ClientCommandManager.h" #include "windows/CMessage.h" #include "windows/InfoWindows.h" #include "render/IScreenHandler.h" -#include "render/IRenderHandler.h" #include "render/Graphics.h" -#include "../lib/CConfigHandler.h" #include "../lib/texts/CGeneralTextHandler.h" -#include "../lib/CThreadHelper.h" -#include "../lib/ExceptionsCommon.h" -#include "../lib/VCMIDirs.h" #include "../lib/VCMI_Lib.h" -#include "../lib/filesystem/Filesystem.h" #include "../lib/logging/CBasicLogConfigurator.h" -#include -#include - #include #include @@ -55,378 +42,9 @@ #if __MINGW32__ #undef main #endif - -namespace po = boost::program_options; -namespace po_style = boost::program_options::command_line_style; - -static std::atomic headlessQuit = false; -static std::optional criticalInitializationError; - -#ifndef VCMI_IOS -void processCommand(const std::string &message); -#endif -void playIntro(); -[[noreturn]] static void quitApplication(); -static void mainLoop(); - -static CBasicLogConfigurator *logConfig; - -void init() -{ - CStopWatch tmh; - try - { - loadDLLClasses(); - CGI->setFromLib(); - } - catch (const DataLoadingException & e) - { - criticalInitializationError = e.what(); - return; - } - - logGlobal->info("Initializing VCMI_Lib: %d ms", tmh.getDiff()); - - // Debug code to load all maps on start - //ClientCommandManager commandController; - //commandController.processCommand("convert txt", false); -} - -static void prog_version() -{ - printf("%s\n", GameConstants::VCMI_VERSION.c_str()); - std::cout << VCMIDirs::get().genHelpString(); -} - -static void prog_help(const po::options_description &opts) -{ - auto time = std::time(nullptr); - printf("%s - A Heroes of Might and Magic 3 clone\n", GameConstants::VCMI_VERSION.c_str()); - printf("Copyright (C) 2007-%d VCMI dev team - see AUTHORS file\n", std::localtime(&time)->tm_year + 1900); - printf("This is free software; see the source for copying conditions. There is NO\n"); - printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); - printf("\n"); - std::cout << opts; -} - -#if defined(VCMI_WINDOWS) && !defined(__GNUC__) && defined(VCMI_WITH_DEBUG_CONSOLE) -int wmain(int argc, wchar_t* argv[]) -#elif defined(VCMI_MOBILE) -int SDL_main(int argc, char *argv[]) -#else -int main(int argc, char * argv[]) -#endif -{ -#ifdef VCMI_ANDROID - CAndroidVMHelper::initClassloader(SDL_AndroidGetJNIEnv()); - // boost will crash without this - setenv("LANG", "C", 1); -#endif - -#if !defined(VCMI_MOBILE) - // Correct working dir executable folder (not bundle folder) so we can use executable relative paths - boost::filesystem::current_path(boost::filesystem::system_complete(argv[0]).parent_path()); -#endif - std::cout << "Starting... " << std::endl; - po::options_description opts("Allowed options"); - po::variables_map vm; - - opts.add_options() - ("help,h", "display help and exit") - ("version,v", "display version information and exit") - ("testmap", po::value(), "") - ("testsave", po::value(), "") - ("spectate,s", "enable spectator interface for AI-only games") - ("spectate-ignore-hero", "wont follow heroes on adventure map") - ("spectate-hero-speed", po::value(), "hero movement speed on adventure map") - ("spectate-battle-speed", po::value(), "battle animation speed for spectator") - ("spectate-skip-battle", "skip battles in spectator view") - ("spectate-skip-battle-result", "skip battle result window") - ("onlyAI", "allow one to run without human player, all players will be default AI") - ("headless", "runs without GUI, implies --onlyAI") - ("ai", po::value>(), "AI to be used for the player, can be specified several times for the consecutive players") - ("oneGoodAI", "puts one default AI and the rest will be EmptyAI") - ("autoSkip", "automatically skip turns in GUI") - ("disable-video", "disable video player") - ("nointro,i", "skips intro movies") - ("donotstartserver,d","do not attempt to start server and just connect to it instead server") - ("serverport", po::value(), "override port specified in config file") - ("savefrequency", po::value(), "limit auto save creation to each N days"); - - if(argc > 1) - { - try - { - po::store(po::parse_command_line(argc, argv, opts, po_style::unix_style|po_style::case_insensitive), vm); - } - catch(boost::program_options::error &e) - { - std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl; - } - } - - po::notify(vm); - if(vm.count("help")) - { - prog_help(opts); -#ifdef VCMI_IOS - exit(0); -#else - return 0; -#endif - } - if(vm.count("version")) - { - prog_version(); -#ifdef VCMI_IOS - exit(0); -#else - return 0; -#endif - } - - // Init old logging system and new (temporary) logging system - CStopWatch total; - CStopWatch pomtime; - std::cout.flags(std::ios::unitbuf); -#ifndef VCMI_IOS - console = new CConsoleHandler(); - - auto callbackFunction = [](std::string buffer, bool calledFromIngameConsole) - { - ClientCommandManager commandController; - commandController.processCommand(buffer, calledFromIngameConsole); - }; - - *console->cb = callbackFunction; - console->start(); -#endif - - setThreadNameLoggingOnly("MainGUI"); - const boost::filesystem::path logPath = VCMIDirs::get().userLogsPath() / "VCMI_Client_log.txt"; - logConfig = new CBasicLogConfigurator(logPath, console); - logConfig->configureDefault(); - logGlobal->info("Starting client of '%s'", GameConstants::VCMI_VERSION); - logGlobal->info("Creating console and configuring logger: %d ms", pomtime.getDiff()); - logGlobal->info("The log file will be saved to %s", logPath); - - // Init filesystem and settings - try - { - preinitDLL(::console, false); - } - catch (const DataLoadingException & e) - { - handleFatalError(e.what(), true); - } - - Settings session = settings.write["session"]; - auto setSettingBool = [&](std::string key, std::string arg) { - Settings s = settings.write(vstd::split(key, "/")); - if(vm.count(arg)) - s->Bool() = true; - else if(s->isNull()) - s->Bool() = false; - }; - auto setSettingInteger = [&](std::string key, std::string arg, si64 defaultValue) { - Settings s = settings.write(vstd::split(key, "/")); - if(vm.count(arg)) - s->Integer() = vm[arg].as(); - else if(s->isNull()) - s->Integer() = defaultValue; - }; - - setSettingBool("session/onlyai", "onlyAI"); - if(vm.count("headless")) - { - session["headless"].Bool() = true; - session["onlyai"].Bool() = true; - } - else if(vm.count("spectate")) - { - session["spectate"].Bool() = true; - session["spectate-ignore-hero"].Bool() = vm.count("spectate-ignore-hero"); - session["spectate-skip-battle"].Bool() = vm.count("spectate-skip-battle"); - session["spectate-skip-battle-result"].Bool() = vm.count("spectate-skip-battle-result"); - if(vm.count("spectate-hero-speed")) - session["spectate-hero-speed"].Integer() = vm["spectate-hero-speed"].as(); - if(vm.count("spectate-battle-speed")) - session["spectate-battle-speed"].Float() = vm["spectate-battle-speed"].as(); - } - // Server settings - setSettingBool("session/donotstartserver", "donotstartserver"); - - // Init special testing settings - setSettingInteger("session/serverport", "serverport", 0); - setSettingInteger("general/saveFrequency", "savefrequency", 1); - - // Initialize logging based on settings - logConfig->configure(); - logGlobal->debug("settings = %s", settings.toJsonNode().toString()); - - // Some basic data validation to produce better error messages in cases of incorrect install - auto testFile = [](std::string filename, std::string message) - { - if (!CResourceHandler::get()->existsResource(ResourcePath(filename))) - handleFatalError(message, false); - }; - - testFile("DATA/HELP.TXT", "VCMI requires Heroes III: Shadow of Death or Heroes III: Complete data files to run!"); - testFile("DATA/TENTCOLR.TXT", "Heroes III: Restoration of Erathia (including HD Edition) data files are not supported!"); - testFile("MODS/VCMI/MOD.JSON", "VCMI installation is corrupted! Built-in mod was not found!"); - testFile("DATA/PLAYERS.PAL", "Heroes III data files (Data/H3Bitmap.lod) are incomplete or corruped! Please reinstall them."); - testFile("SPRITES/DEFAULT.DEF", "Heroes III data files (Data/H3Sprite.lod) are incomplete or corruped! Please reinstall them."); - - srand ( (unsigned int)time(nullptr) ); - - if(!settings["session"]["headless"].Bool()) - GH.init(); - - CCS = new CClientState(); - CGI = new CGameInfo(); //contains all global information about game (texts, lodHandlers, map handler etc.) - CSH = new CServerHandler(); - - // Initialize video -#ifdef DISABLE_VIDEO - CCS->videoh = new CEmptyVideoPlayer(); -#else - if (!settings["session"]["headless"].Bool() && !vm.count("disable-video")) - CCS->videoh = new CVideoPlayer(); - else - CCS->videoh = new CEmptyVideoPlayer(); -#endif - - logGlobal->info("\tInitializing video: %d ms", pomtime.getDiff()); - - if(!settings["session"]["headless"].Bool()) - { - //initializing audio - CCS->soundh = new CSoundHandler(); - CCS->soundh->setVolume((ui32)settings["general"]["sound"].Float()); - CCS->musich = new CMusicHandler(); - CCS->musich->setVolume((ui32)settings["general"]["music"].Float()); - logGlobal->info("Initializing screen and sound handling: %d ms", pomtime.getDiff()); - } - -#ifndef VCMI_NO_THREADED_LOAD - //we can properly play intro only in the main thread, so we have to move loading to the separate thread - boost::thread loading([]() - { - setThreadName("initialize"); - init(); - }); -#else - init(); -#endif - - if(!settings["session"]["headless"].Bool()) - { - if(!vm.count("battle") && !vm.count("nointro") && settings["video"]["showIntro"].Bool()) - playIntro(); - GH.screenHandler().clearScreen(); - } - -#ifndef VCMI_NO_THREADED_LOAD - #ifdef VCMI_ANDROID // android loads the data quite slowly so we display native progressbar to prevent having only black screen for few seconds - { - CAndroidVMHelper vmHelper; - vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "showProgress"); - #endif // ANDROID - loading.join(); - #ifdef VCMI_ANDROID - vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "hideProgress"); - } - #endif // ANDROID -#endif // THREADED - - if (criticalInitializationError.has_value()) - { - handleFatalError(criticalInitializationError.value(), false); - } - - if(!settings["session"]["headless"].Bool()) - { - pomtime.getDiff(); - graphics = new Graphics(); // should be before curh - GH.renderHandler().onLibraryLoadingFinished(CGI); - - CCS->curh = new CursorHandler(); - logGlobal->info("Screen handler: %d ms", pomtime.getDiff()); - - CMessage::init(); - logGlobal->info("Message handler: %d ms", pomtime.getDiff()); - - CCS->curh->show(); - } - - logGlobal->info("Initialization of VCMI (together): %d ms", total.getDiff()); - - session["autoSkip"].Bool() = vm.count("autoSkip"); - session["oneGoodAI"].Bool() = vm.count("oneGoodAI"); - session["aiSolo"].Bool() = false; - - if(vm.count("testmap")) - { - session["testmap"].String() = vm["testmap"].as(); - session["onlyai"].Bool() = true; - boost::thread(&CServerHandler::debugStartTest, CSH, session["testmap"].String(), false); - } - else if(vm.count("testsave")) - { - session["testsave"].String() = vm["testsave"].as(); - session["onlyai"].Bool() = true; - boost::thread(&CServerHandler::debugStartTest, CSH, session["testsave"].String(), true); - } - else - { - auto mmenu = CMainMenu::create(); - GH.curInt = mmenu.get(); - } - - std::vector names; - - if(!settings["session"]["headless"].Bool()) - { - mainLoop(); - } - else - { - while(!headlessQuit) - boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); - - boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); - - quitApplication(); - } - - return 0; -} - -//plays intro, ends when intro is over or button has been pressed (handles events) -void playIntro() -{ - if(!CCS->videoh->playIntroVideo(VideoPath::builtin("3DOLOGO.SMK"))) - return; - - if (!CCS->videoh->playIntroVideo(VideoPath::builtin("NWCLOGO.SMK"))) - return; - - CCS->videoh->playIntroVideo(VideoPath::builtin("H3INTRO.SMK")); -} - -static void mainLoop() -{ -#ifndef VCMI_UNIX - // on Linux, name of main thread is also name of our process. Which we don't want to change - setThreadName("MainGUI"); -#endif - - while(1) //main SDL events loop - { - GH.input().fetchEvents(); - GH.renderFrame(); - } -} +extern std::atomic headlessQuit; +extern std::optional criticalInitializationError; +extern CBasicLogConfigurator *logConfig; [[noreturn]] static void quitApplicationImmediately(int error_code) { @@ -442,7 +60,7 @@ static void mainLoop() #endif } -[[noreturn]] static void quitApplication() +[[noreturn]] void quitApplication() { CSH->endNetwork(); diff --git a/client/CMT.h b/client/CMT.h index 1bf25fd73..9bd421dc1 100644 --- a/client/CMT.h +++ b/client/CMT.h @@ -25,3 +25,4 @@ void handleQuit(bool ask = true); /// Notify user about encountered fatal error and terminate the game /// TODO: decide on better location for this method [[noreturn]] void handleFatalError(const std::string & message, bool terminate); +[[noreturn]] void quitApplication(); diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 6ab2a19a6..e752daea6 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,4 +1,4 @@ -set(client_SRCS +set(vcmiclientcommon_SRCS StdInc.cpp ../CCallback.cpp @@ -186,7 +186,7 @@ set(client_SRCS ServerRunner.cpp ) -set(client_HEADERS +set(vcmiclientcommon_HEADERS StdInc.h adventureMap/AdventureMapInterface.h @@ -396,14 +396,14 @@ set(client_HEADERS ) if(APPLE_IOS) - set(client_SRCS ${client_SRCS} + set(vcmiclientcommon_SRCS ${vcmiclientcommon_SRCS} CFocusableHelper.cpp ios/GameChatKeyboardHandler.m ios/main.m ios/startSDL.mm ios/utils.mm ) - set(client_HEADERS ${client_HEADERS} + set(vcmiclientcommon_HEADERS ${vcmiclientcommon_HEADERS} CFocusableHelper.h ios/GameChatKeyboardHandler.h ios/startSDL.h @@ -411,61 +411,51 @@ if(APPLE_IOS) ) endif() -assign_source_group(${client_SRCS} ${client_HEADERS} VCMI_client.rc) +assign_source_group(${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS} VCMI_vcmiclientcommon.rc) if(ANDROID) - add_library(vcmiclient SHARED ${client_SRCS} ${client_HEADERS}) - set_target_properties(vcmiclient PROPERTIES + add_library(vcmiclientcommon SHARED ${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) + set_target_properties(vcmiclientcommon PROPERTIES OUTPUT_NAME "vcmiclient_${ANDROID_ABI}" # required by Qt ) else() - add_executable(vcmiclient ${client_SRCS} ${client_HEADERS}) + add_library(vcmiclientcommon STATIC ${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) endif() if(NOT ENABLE_STATIC_LIBS) - add_dependencies(vcmiclient + add_dependencies(vcmiclientcommon BattleAI EmptyAI StupidAI VCAI ) if(ENABLE_NULLKILLER_AI) - add_dependencies(vcmiclient Nullkiller) + add_dependencies(vcmiclientcommon Nullkiller) endif() endif() if(APPLE_IOS) if(ENABLE_ERM) - add_dependencies(vcmiclient vcmiERM) + add_dependencies(vcmiclientcommon vcmiERM) endif() if(ENABLE_LUA) - add_dependencies(vcmiclient vcmiLua) + add_dependencies(vcmiclientcommon vcmiLua) endif() endif() if(WIN32) - target_sources(vcmiclient PRIVATE "VCMI_client.rc") - set_target_properties(vcmiclient + target_sources(vcmiclientcommon PRIVATE "VCMI_clientcommon.rc") + set_target_properties(vcmiclientcommon PROPERTIES - OUTPUT_NAME "VCMI_client" - PROJECT_LABEL "VCMI_client" + OUTPUT_NAME "VCMI_vcmiclientcommon" + PROJECT_LABEL "VCMI_vcmiclientcommon" ) - set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT vcmiclient) + set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT vcmiclientcommon) if(NOT ENABLE_DEBUG_CONSOLE) - set_target_properties(vcmiclient PROPERTIES WIN32_EXECUTABLE) - target_link_libraries(vcmiclient SDL2::SDL2main) - endif() - target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) - -# TODO: very hacky, find proper solution to copy AI dlls into bin dir - if(MSVC) - add_custom_command(TARGET vcmiclient POST_BUILD - WORKING_DIRECTORY "$" - COMMAND ${CMAKE_COMMAND} -E copy AI/fuzzylite.dll fuzzylite.dll - COMMAND ${CMAKE_COMMAND} -E copy AI/tbb12.dll tbb12.dll - ) + target_link_libraries(vcmiclientcommon SDL2::SDL2main) endif() + target_compile_definitions(vcmiclientcommon PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) elseif(APPLE_IOS) - target_link_libraries(vcmiclient PRIVATE + target_link_libraries(vcmiclientcommon PRIVATE iOS_utils # FFmpeg @@ -478,16 +468,9 @@ elseif(APPLE_IOS) "-framework VideoToolbox" ) - set_target_properties(vcmiclient PROPERTIES - MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/ios/Info.plist" - XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks" - XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "$(CODE_SIGNING_ALLOWED_FOR_APPS)" - XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon - ) - foreach(XCODE_RESOURCE LaunchScreen.storyboard Images.xcassets Settings.bundle vcmi_logo.png) set(XCODE_RESOURCE_PATH ios/${XCODE_RESOURCE}) - target_sources(vcmiclient PRIVATE ${XCODE_RESOURCE_PATH}) + target_sources(vcmiclientcommon PRIVATE ${XCODE_RESOURCE_PATH}) set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) # workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag @@ -495,83 +478,34 @@ elseif(APPLE_IOS) set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX) endif() endforeach() - - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_client_main") endif() -target_link_libraries(vcmiclient PRIVATE vcmiservercommon) +target_link_libraries(vcmiclientcommon PRIVATE vcmiservercommon) if(ENABLE_SINGLE_APP_BUILD AND ENABLE_LAUNCHER) - target_link_libraries(vcmiclient PRIVATE vcmilauncher) + target_link_libraries(vcmiclientcommon PRIVATE vcmilauncher) endif() -target_link_libraries(vcmiclient PRIVATE +target_link_libraries(vcmiclientcommon PUBLIC vcmi SDL2::SDL2 SDL2::Image SDL2::Mixer SDL2::TTF ) if(ffmpeg_LIBRARIES) - target_link_libraries(vcmiclient PRIVATE + target_link_libraries(vcmiclientcommon PRIVATE ${ffmpeg_LIBRARIES} ) else() - target_compile_definitions(vcmiclient PRIVATE DISABLE_VIDEO) + target_compile_definitions(vcmiclientcommon PRIVATE DISABLE_VIDEO) endif() -target_include_directories(vcmiclient PUBLIC +target_include_directories(vcmiclientcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) if (ffmpeg_INCLUDE_DIRS) - target_include_directories(vcmiclient PRIVATE + target_include_directories(vcmiclientcommon PRIVATE ${ffmpeg_INCLUDE_DIRS} ) endif() -vcmi_set_output_dir(vcmiclient "") -enable_pch(vcmiclient) - -if(APPLE_IOS) - vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}") - add_custom_command(TARGET vcmiclient POST_BUILD - COMMAND ios/set_build_version.sh "$" - COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --component "${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}" --config "$" --prefix "$" - COMMAND ios/rpath_remove_symlinks.sh - COMMAND ios/codesign.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - ) - install(TARGETS vcmiclient DESTINATION Payload COMPONENT app) # for ipa generation with cpack -elseif(ANDROID) - find_program(androidDeployQt androiddeployqt - PATHS "${qtBinDir}" - ) - vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}/${LIB_DIR}") - - add_custom_target(android_deploy ALL - COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --config "$" --prefix "${androidQtBuildDir}" - COMMAND "${androidDeployQt}" --input "${CMAKE_BINARY_DIR}/androiddeployqt.json" --output "${androidQtBuildDir}" --android-platform "android-${ANDROID_TARGET_SDK_VERSION}" --verbose $<$>:--release> ${ANDROIDDEPLOYQT_OPTIONS} - COMMAND_EXPAND_LISTS - VERBATIM - COMMENT "Create android package" - ) - add_dependencies(android_deploy vcmiclient) -else() - install(TARGETS vcmiclient DESTINATION ${BIN_DIR}) -endif() - -#install icons and desktop file on Linux -if(NOT WIN32 AND NOT APPLE AND NOT ANDROID) - #FIXME: move to client makefile? - foreach(iconSize 16 22 32 48 64 128 256 512 1024 2048) - install(FILES "icons/vcmiclient.${iconSize}x${iconSize}.png" - DESTINATION "share/icons/hicolor/${iconSize}x${iconSize}/apps" - RENAME vcmiclient.png - ) - endforeach() - - install(FILES icons/vcmiclient.svg - DESTINATION share/icons/hicolor/scalable/apps - RENAME vcmiclient.svg - ) - install(FILES icons/vcmiclient.desktop - DESTINATION share/applications - ) -endif() +vcmi_set_output_dir(vcmiclientcommon "") +enable_pch(vcmiclientcommon) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index d3dc88c9f..1ea64c8e7 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -13,7 +13,6 @@ #include #include "CGameInfo.h" -#include "CMT.h" #include "CServerHandler.h" #include "HeroMovementController.h" #include "PlayerLocalState.h" diff --git a/client/ClientCommandManager.cpp b/client/ClientCommandManager.cpp index 79ef59688..e1d07291e 100644 --- a/client/ClientCommandManager.cpp +++ b/client/ClientCommandManager.cpp @@ -38,7 +38,6 @@ #include "../lib/CHeroHandler.h" #include "../lib/VCMIDirs.h" #include "../lib/logging/VisualLogger.h" -#include "CMT.h" #include "../lib/serializer/Connection.h" #ifdef SCRIPTING_ENABLED diff --git a/client/eventsSDL/InputSourceText.cpp b/client/eventsSDL/InputSourceText.cpp index b1fdfa77d..d33a4e035 100644 --- a/client/eventsSDL/InputSourceText.cpp +++ b/client/eventsSDL/InputSourceText.cpp @@ -11,7 +11,6 @@ #include "StdInc.h" #include "InputSourceText.h" -#include "../CMT.h" #include "../gui/CGuiHandler.h" #include "../gui/EventDispatcher.h" #include "../render/IScreenHandler.h" diff --git a/client/eventsSDL/InputSourceTouch.cpp b/client/eventsSDL/InputSourceTouch.cpp index 992daeb2c..0b5d48954 100644 --- a/client/eventsSDL/InputSourceTouch.cpp +++ b/client/eventsSDL/InputSourceTouch.cpp @@ -14,7 +14,6 @@ #include "InputHandler.h" #include "../../lib/CConfigHandler.h" -#include "../CMT.h" #include "../CGameInfo.h" #include "../gui/CursorHandler.h" #include "../gui/CGuiHandler.h" diff --git a/clientapp/CMakeLists.txt b/clientapp/CMakeLists.txt new file mode 100644 index 000000000..923d7ce09 --- /dev/null +++ b/clientapp/CMakeLists.txt @@ -0,0 +1,100 @@ +set(clientapp_SRCS + StdInc.cpp + EntryPoint.cpp +) + +set(clientapp_HEADERS + StdInc.h +) + +assign_source_group(${clientapp_SRCS} ${clientapp_HEADERS}) +add_executable(vcmiclient ${clientapp_SRCS} ${clientapp_HEADERS}) + +target_link_libraries(vcmiclient PRIVATE vcmiclientcommon) + +target_include_directories(vcmiclient + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} +) + +if(WIN32) + target_sources(vcmiclient PRIVATE "VCMI_client.rc") + set_target_properties(vcmiclient + PROPERTIES + OUTPUT_NAME "VCMI_client" + PROJECT_LABEL "VCMI_client" + ) + set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT vcmiclient) + if(NOT ENABLE_DEBUG_CONSOLE) + set_target_properties(vcmiclient PROPERTIES WIN32_EXECUTABLE) + target_link_libraries(vcmiclient SDL2::SDL2main) + endif() + target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) + +# TODO: very hacky, find proper solution to copy AI dlls into bin dir + if(MSVC) + add_custom_command(TARGET vcmiclient POST_BUILD + WORKING_DIRECTORY "$" + COMMAND ${CMAKE_COMMAND} -E copy AI/fuzzylite.dll fuzzylite.dll + COMMAND ${CMAKE_COMMAND} -E copy AI/tbb12.dll tbb12.dll + ) + endif() +elseif(APPLE_IOS) + set_target_properties(vcmiclient PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/ios/Info.plist" + XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks" + XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "$(CODE_SIGNING_ALLOWED_FOR_APPS)" + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + ) + + set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_vcmiclient_main") +endif() + +vcmi_set_output_dir(vcmiclient "") +enable_pch(vcmiclient) + +if(APPLE_IOS) + vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}") + add_custom_command(TARGET vcmiclient POST_BUILD + COMMAND ios/set_build_version.sh "$" + COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --component "${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}" --config "$" --prefix "$" + COMMAND ios/rpath_remove_symlinks.sh + COMMAND ios/codesign.sh + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + install(TARGETS vcmiclient DESTINATION Payload COMPONENT app) # for ipa generation with cpack +elseif(ANDROID) + find_program(androidDeployQt androiddeployqt + PATHS "${qtBinDir}" + ) + vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}/${LIB_DIR}") + + add_custom_target(android_deploy ALL + COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --config "$" --prefix "${androidQtBuildDir}" + COMMAND "${androidDeployQt}" --input "${CMAKE_BINARY_DIR}/androiddeployqt.json" --output "${androidQtBuildDir}" --android-platform "android-${ANDROID_TARGET_SDK_VERSION}" --verbose $<$>:--release> ${ANDROIDDEPLOYQT_OPTIONS} + COMMAND_EXPAND_LISTS + VERBATIM + COMMENT "Create android package" + ) + add_dependencies(android_deploy vcmiclient) +else() + install(TARGETS vcmiclient DESTINATION ${BIN_DIR}) +endif() + +#install icons and desktop file on Linux +if(NOT WIN32 AND NOT APPLE AND NOT ANDROID) + #FIXME: move to client makefile? + foreach(iconSize 16 22 32 48 64 128 256 512 1024 2048) + install(FILES "icons/vcmiclient.${iconSize}x${iconSize}.png" + DESTINATION "share/icons/hicolor/${iconSize}x${iconSize}/apps" + RENAME vcmiclient.png + ) + endforeach() + + install(FILES icons/vcmiclient.svg + DESTINATION share/icons/hicolor/scalable/apps + RENAME vcmiclient.svg + ) + install(FILES icons/vcmiclient.desktop + DESTINATION share/applications + ) +endif() diff --git a/clientapp/EntryPoint.cpp b/clientapp/EntryPoint.cpp new file mode 100644 index 000000000..7fb42b98c --- /dev/null +++ b/clientapp/EntryPoint.cpp @@ -0,0 +1,424 @@ +/* + * EntryPoint.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +// EntryPoint.cpp : Defines the entry point for the console application. +#include "Global.h" +#include "StdInc.h" + +#include "client/CGameInfo.h" +#include "client/mainmenu/CMainMenu.h" +#include "media/CEmptyVideoPlayer.h" +#include "media/CMusicHandler.h" +#include "media/CSoundHandler.h" +#include "media/CVideoHandler.h" +#include "client/gui/CursorHandler.h" +#include "client/eventsSDL/InputHandler.h" +#include "client/gui/CGuiHandler.h" +#include "client/CServerHandler.h" +#include "client/ClientCommandManager.h" +#include "client/windows/CMessage.h" +#include "client/render/IRenderHandler.h" +#include "client/render/IScreenHandler.h" +#include "client/render/Graphics.h" +#include "client/CMT.h" + +#include "../lib/CThreadHelper.h" +#include "../lib/ExceptionsCommon.h" +#include "../lib/VCMIDirs.h" +#include "../lib/VCMI_Lib.h" +#include "../lib/filesystem/Filesystem.h" + +#include "../lib/logging/CBasicLogConfigurator.h" + +#include +#include + +#include +#include + +#ifdef VCMI_ANDROID +#include "../lib/CAndroidVMHelper.h" +#include +#endif + +#if __MINGW32__ +#undef main +#endif + +namespace po = boost::program_options; +namespace po_style = boost::program_options::command_line_style; + +std::atomic headlessQuit = false; +std::optional criticalInitializationError; + +#ifndef VCMI_IOS +void processCommand(const std::string &message); +#endif +void playIntro(); +static void mainLoop(); + +CBasicLogConfigurator *logConfig; + +void init() +{ + CStopWatch tmh; + try + { + loadDLLClasses(); + CGI->setFromLib(); + } + catch (const DataLoadingException & e) + { + criticalInitializationError = e.what(); + return; + } + + logGlobal->info("Initializing VCMI_Lib: %d ms", tmh.getDiff()); + + // Debug code to load all maps on start + //ClientCommandManager commandController; + //commandController.processCommand("convert txt", false); +} + +static void prog_version() +{ + printf("%s\n", GameConstants::VCMI_VERSION.c_str()); + std::cout << VCMIDirs::get().genHelpString(); +} + +static void prog_help(const po::options_description &opts) +{ + auto time = std::time(nullptr); + printf("%s - A Heroes of Might and Magic 3 clone\n", GameConstants::VCMI_VERSION.c_str()); + printf("Copyright (C) 2007-%d VCMI dev team - see AUTHORS file\n", std::localtime(&time)->tm_year + 1900); + printf("This is free software; see the source for copying conditions. There is NO\n"); + printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + printf("\n"); + std::cout << opts; +} + +#if defined(VCMI_WINDOWS) && !defined(__GNUC__) && defined(VCMI_WITH_DEBUG_CONSOLE) +int wmain(int argc, wchar_t* argv[]) +#elif defined(VCMI_MOBILE) +int SDL_main(int argc, char *argv[]) +#else +int main(int argc, char * argv[]) +#endif +{ +#ifdef VCMI_ANDROID + CAndroidVMHelper::initClassloader(SDL_AndroidGetJNIEnv()); + // boost will crash without this + setenv("LANG", "C", 1); +#endif + +#if !defined(VCMI_MOBILE) + // Correct working dir executable folder (not bundle folder) so we can use executable relative paths + boost::filesystem::current_path(boost::filesystem::system_complete(argv[0]).parent_path()); +#endif + std::cout << "Starting... " << std::endl; + po::options_description opts("Allowed options"); + po::variables_map vm; + + opts.add_options() + ("help,h", "display help and exit") + ("version,v", "display version information and exit") + ("testmap", po::value(), "") + ("testsave", po::value(), "") + ("spectate,s", "enable spectator interface for AI-only games") + ("spectate-ignore-hero", "wont follow heroes on adventure map") + ("spectate-hero-speed", po::value(), "hero movement speed on adventure map") + ("spectate-battle-speed", po::value(), "battle animation speed for spectator") + ("spectate-skip-battle", "skip battles in spectator view") + ("spectate-skip-battle-result", "skip battle result window") + ("onlyAI", "allow one to run without human player, all players will be default AI") + ("headless", "runs without GUI, implies --onlyAI") + ("ai", po::value>(), "AI to be used for the player, can be specified several times for the consecutive players") + ("oneGoodAI", "puts one default AI and the rest will be EmptyAI") + ("autoSkip", "automatically skip turns in GUI") + ("disable-video", "disable video player") + ("nointro,i", "skips intro movies") + ("donotstartserver,d","do not attempt to start server and just connect to it instead server") + ("serverport", po::value(), "override port specified in config file") + ("savefrequency", po::value(), "limit auto save creation to each N days"); + + if(argc > 1) + { + try + { + po::store(po::parse_command_line(argc, argv, opts, po_style::unix_style|po_style::case_insensitive), vm); + } + catch(boost::program_options::error &e) + { + std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl; + } + } + + po::notify(vm); + if(vm.count("help")) + { + prog_help(opts); +#ifdef VCMI_IOS + exit(0); +#else + return 0; +#endif + } + if(vm.count("version")) + { + prog_version(); +#ifdef VCMI_IOS + exit(0); +#else + return 0; +#endif + } + + // Init old logging system and new (temporary) logging system + CStopWatch total; + CStopWatch pomtime; + std::cout.flags(std::ios::unitbuf); +#ifndef VCMI_IOS + console = new CConsoleHandler(); + + auto callbackFunction = [](std::string buffer, bool calledFromIngameConsole) + { + ClientCommandManager commandController; + commandController.processCommand(buffer, calledFromIngameConsole); + }; + + *console->cb = callbackFunction; + console->start(); +#endif + + setThreadNameLoggingOnly("MainGUI"); + const boost::filesystem::path logPath = VCMIDirs::get().userLogsPath() / "VCMI_Client_log.txt"; + logConfig = new CBasicLogConfigurator(logPath, console); + logConfig->configureDefault(); + logGlobal->info("Starting client of '%s'", GameConstants::VCMI_VERSION); + logGlobal->info("Creating console and configuring logger: %d ms", pomtime.getDiff()); + logGlobal->info("The log file will be saved to %s", logPath); + + // Init filesystem and settings + try + { + preinitDLL(::console, false); + } + catch (const DataLoadingException & e) + { + handleFatalError(e.what(), true); + } + + Settings session = settings.write["session"]; + auto setSettingBool = [&](std::string key, std::string arg) { + Settings s = settings.write(vstd::split(key, "/")); + if(vm.count(arg)) + s->Bool() = true; + else if(s->isNull()) + s->Bool() = false; + }; + auto setSettingInteger = [&](std::string key, std::string arg, si64 defaultValue) { + Settings s = settings.write(vstd::split(key, "/")); + if(vm.count(arg)) + s->Integer() = vm[arg].as(); + else if(s->isNull()) + s->Integer() = defaultValue; + }; + + setSettingBool("session/onlyai", "onlyAI"); + if(vm.count("headless")) + { + session["headless"].Bool() = true; + session["onlyai"].Bool() = true; + } + else if(vm.count("spectate")) + { + session["spectate"].Bool() = true; + session["spectate-ignore-hero"].Bool() = vm.count("spectate-ignore-hero"); + session["spectate-skip-battle"].Bool() = vm.count("spectate-skip-battle"); + session["spectate-skip-battle-result"].Bool() = vm.count("spectate-skip-battle-result"); + if(vm.count("spectate-hero-speed")) + session["spectate-hero-speed"].Integer() = vm["spectate-hero-speed"].as(); + if(vm.count("spectate-battle-speed")) + session["spectate-battle-speed"].Float() = vm["spectate-battle-speed"].as(); + } + // Server settings + setSettingBool("session/donotstartserver", "donotstartserver"); + + // Init special testing settings + setSettingInteger("session/serverport", "serverport", 0); + setSettingInteger("general/saveFrequency", "savefrequency", 1); + + // Initialize logging based on settings + logConfig->configure(); + logGlobal->debug("settings = %s", settings.toJsonNode().toString()); + + // Some basic data validation to produce better error messages in cases of incorrect install + auto testFile = [](std::string filename, std::string message) + { + if (!CResourceHandler::get()->existsResource(ResourcePath(filename))) + handleFatalError(message, false); + }; + + testFile("DATA/HELP.TXT", "VCMI requires Heroes III: Shadow of Death or Heroes III: Complete data files to run!"); + testFile("DATA/TENTCOLR.TXT", "Heroes III: Restoration of Erathia (including HD Edition) data files are not supported!"); + testFile("MODS/VCMI/MOD.JSON", "VCMI installation is corrupted! Built-in mod was not found!"); + testFile("DATA/PLAYERS.PAL", "Heroes III data files (Data/H3Bitmap.lod) are incomplete or corruped! Please reinstall them."); + testFile("SPRITES/DEFAULT.DEF", "Heroes III data files (Data/H3Sprite.lod) are incomplete or corruped! Please reinstall them."); + + srand ( (unsigned int)time(nullptr) ); + + if(!settings["session"]["headless"].Bool()) + GH.init(); + + CCS = new CClientState(); + CGI = new CGameInfo(); //contains all global information about game (texts, lodHandlers, map handler etc.) + CSH = new CServerHandler(); + + // Initialize video +#ifdef DISABLE_VIDEO + CCS->videoh = new CEmptyVideoPlayer(); +#else + if (!settings["session"]["headless"].Bool() && !vm.count("disable-video")) + CCS->videoh = new CVideoPlayer(); + else + CCS->videoh = new CEmptyVideoPlayer(); +#endif + + logGlobal->info("\tInitializing video: %d ms", pomtime.getDiff()); + + if(!settings["session"]["headless"].Bool()) + { + //initializing audio + CCS->soundh = new CSoundHandler(); + CCS->soundh->setVolume((ui32)settings["general"]["sound"].Float()); + CCS->musich = new CMusicHandler(); + CCS->musich->setVolume((ui32)settings["general"]["music"].Float()); + logGlobal->info("Initializing screen and sound handling: %d ms", pomtime.getDiff()); + } + +#ifndef VCMI_NO_THREADED_LOAD + //we can properly play intro only in the main thread, so we have to move loading to the separate thread + boost::thread loading([]() + { + setThreadName("initialize"); + init(); + }); +#else + init(); +#endif + + if(!settings["session"]["headless"].Bool()) + { + if(!vm.count("battle") && !vm.count("nointro") && settings["video"]["showIntro"].Bool()) + playIntro(); + GH.screenHandler().clearScreen(); + } + +#ifndef VCMI_NO_THREADED_LOAD + #ifdef VCMI_ANDROID // android loads the data quite slowly so we display native progressbar to prevent having only black screen for few seconds + { + CAndroidVMHelper vmHelper; + vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "showProgress"); + #endif // ANDROID + loading.join(); + #ifdef VCMI_ANDROID + vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "hideProgress"); + } + #endif // ANDROID +#endif // THREADED + + if (criticalInitializationError.has_value()) + { + handleFatalError(criticalInitializationError.value(), false); + } + + if(!settings["session"]["headless"].Bool()) + { + pomtime.getDiff(); + graphics = new Graphics(); // should be before curh + GH.renderHandler().onLibraryLoadingFinished(CGI); + + CCS->curh = new CursorHandler(); + logGlobal->info("Screen handler: %d ms", pomtime.getDiff()); + + CMessage::init(); + logGlobal->info("Message handler: %d ms", pomtime.getDiff()); + + CCS->curh->show(); + } + + logGlobal->info("Initialization of VCMI (together): %d ms", total.getDiff()); + + session["autoSkip"].Bool() = vm.count("autoSkip"); + session["oneGoodAI"].Bool() = vm.count("oneGoodAI"); + session["aiSolo"].Bool() = false; + + if(vm.count("testmap")) + { + session["testmap"].String() = vm["testmap"].as(); + session["onlyai"].Bool() = true; + boost::thread(&CServerHandler::debugStartTest, CSH, session["testmap"].String(), false); + } + else if(vm.count("testsave")) + { + session["testsave"].String() = vm["testsave"].as(); + session["onlyai"].Bool() = true; + boost::thread(&CServerHandler::debugStartTest, CSH, session["testsave"].String(), true); + } + else + { + auto mmenu = CMainMenu::create(); + GH.curInt = mmenu.get(); + } + + std::vector names; + + if(!settings["session"]["headless"].Bool()) + { + mainLoop(); + } + else + { + while(!headlessQuit) + boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); + + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + + quitApplication(); + } + + return 0; +} + +//plays intro, ends when intro is over or button has been pressed (handles events) +void playIntro() +{ + if(!CCS->videoh->playIntroVideo(VideoPath::builtin("3DOLOGO.SMK"))) + return; + + if (!CCS->videoh->playIntroVideo(VideoPath::builtin("NWCLOGO.SMK"))) + return; + + CCS->videoh->playIntroVideo(VideoPath::builtin("H3INTRO.SMK")); +} + +static void mainLoop() +{ +#ifndef VCMI_UNIX + // on Linux, name of main thread is also name of our process. Which we don't want to change + setThreadName("MainGUI"); +#endif + + while(1) //main SDL events loop + { + GH.input().fetchEvents(); + GH.renderFrame(); + } +} diff --git a/clientapp/StdInc.cpp b/clientapp/StdInc.cpp new file mode 100644 index 000000000..277dd9af0 --- /dev/null +++ b/clientapp/StdInc.cpp @@ -0,0 +1,11 @@ +/* + * StdInc.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +// Creates the precompiled header +#include "StdInc.h" diff --git a/clientapp/StdInc.h b/clientapp/StdInc.h new file mode 100644 index 000000000..d03216bdf --- /dev/null +++ b/clientapp/StdInc.h @@ -0,0 +1,14 @@ +/* + * StdInc.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +#include "../Global.h" + +VCMI_LIB_USING_NAMESPACE From bc162f514e97c45e631bda1b15d2db4002be0744 Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 14 Aug 2024 19:26:58 +0300 Subject: [PATCH 02/12] fix invalid file ref --- client/CMakeLists.txt | 3 +-- {client => clientapp}/VCMI_client.rc | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename {client => clientapp}/VCMI_client.rc (100%) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index e752daea6..0208ca71d 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -411,7 +411,7 @@ if(APPLE_IOS) ) endif() -assign_source_group(${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS} VCMI_vcmiclientcommon.rc) +assign_source_group(${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) if(ANDROID) add_library(vcmiclientcommon SHARED ${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) @@ -443,7 +443,6 @@ if(APPLE_IOS) endif() if(WIN32) - target_sources(vcmiclientcommon PRIVATE "VCMI_clientcommon.rc") set_target_properties(vcmiclientcommon PROPERTIES OUTPUT_NAME "VCMI_vcmiclientcommon" diff --git a/client/VCMI_client.rc b/clientapp/VCMI_client.rc similarity index 100% rename from client/VCMI_client.rc rename to clientapp/VCMI_client.rc From 6767f90066e6d960ae911068e21c57754d43e7ea Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 14 Aug 2024 19:55:22 +0300 Subject: [PATCH 03/12] move ios/ folder --- {client => clientapp}/ios/GameChatKeyboardHandler.h | 0 {client => clientapp}/ios/GameChatKeyboardHandler.m | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../AppIcon.appiconset/Icon-App-83.5x83.5@2x.png | Bin .../ios/Images.xcassets/Contents.json | 0 {client => clientapp}/ios/Info.plist | 0 {client => clientapp}/ios/LaunchScreen.storyboard | 0 .../ios/Settings.bundle/Root.plist | 0 .../ios/Settings.bundle/en.lproj/Root.strings | 0 .../ios/Settings.bundle/ru.lproj/Root.strings | 0 {client => clientapp}/ios/main.m | 0 {client => clientapp}/ios/startSDL.h | 0 {client => clientapp}/ios/startSDL.mm | 0 {client => clientapp}/ios/utils.h | 0 {client => clientapp}/ios/utils.mm | 0 {client => clientapp}/ios/vcmi_logo.png | Bin 29 files changed, 0 insertions(+), 0 deletions(-) rename {client => clientapp}/ios/GameChatKeyboardHandler.h (100%) rename {client => clientapp}/ios/GameChatKeyboardHandler.m (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Contents.json (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename {client => clientapp}/ios/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename {client => clientapp}/ios/Images.xcassets/Contents.json (100%) rename {client => clientapp}/ios/Info.plist (100%) rename {client => clientapp}/ios/LaunchScreen.storyboard (100%) rename {client => clientapp}/ios/Settings.bundle/Root.plist (100%) rename {client => clientapp}/ios/Settings.bundle/en.lproj/Root.strings (100%) rename {client => clientapp}/ios/Settings.bundle/ru.lproj/Root.strings (100%) rename {client => clientapp}/ios/main.m (100%) rename {client => clientapp}/ios/startSDL.h (100%) rename {client => clientapp}/ios/startSDL.mm (100%) rename {client => clientapp}/ios/utils.h (100%) rename {client => clientapp}/ios/utils.mm (100%) rename {client => clientapp}/ios/vcmi_logo.png (100%) diff --git a/client/ios/GameChatKeyboardHandler.h b/clientapp/ios/GameChatKeyboardHandler.h similarity index 100% rename from client/ios/GameChatKeyboardHandler.h rename to clientapp/ios/GameChatKeyboardHandler.h diff --git a/client/ios/GameChatKeyboardHandler.m b/clientapp/ios/GameChatKeyboardHandler.m similarity index 100% rename from client/ios/GameChatKeyboardHandler.m rename to clientapp/ios/GameChatKeyboardHandler.m diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Contents.json b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Contents.json rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Contents.json diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from client/ios/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to clientapp/ios/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/client/ios/Images.xcassets/Contents.json b/clientapp/ios/Images.xcassets/Contents.json similarity index 100% rename from client/ios/Images.xcassets/Contents.json rename to clientapp/ios/Images.xcassets/Contents.json diff --git a/client/ios/Info.plist b/clientapp/ios/Info.plist similarity index 100% rename from client/ios/Info.plist rename to clientapp/ios/Info.plist diff --git a/client/ios/LaunchScreen.storyboard b/clientapp/ios/LaunchScreen.storyboard similarity index 100% rename from client/ios/LaunchScreen.storyboard rename to clientapp/ios/LaunchScreen.storyboard diff --git a/client/ios/Settings.bundle/Root.plist b/clientapp/ios/Settings.bundle/Root.plist similarity index 100% rename from client/ios/Settings.bundle/Root.plist rename to clientapp/ios/Settings.bundle/Root.plist diff --git a/client/ios/Settings.bundle/en.lproj/Root.strings b/clientapp/ios/Settings.bundle/en.lproj/Root.strings similarity index 100% rename from client/ios/Settings.bundle/en.lproj/Root.strings rename to clientapp/ios/Settings.bundle/en.lproj/Root.strings diff --git a/client/ios/Settings.bundle/ru.lproj/Root.strings b/clientapp/ios/Settings.bundle/ru.lproj/Root.strings similarity index 100% rename from client/ios/Settings.bundle/ru.lproj/Root.strings rename to clientapp/ios/Settings.bundle/ru.lproj/Root.strings diff --git a/client/ios/main.m b/clientapp/ios/main.m similarity index 100% rename from client/ios/main.m rename to clientapp/ios/main.m diff --git a/client/ios/startSDL.h b/clientapp/ios/startSDL.h similarity index 100% rename from client/ios/startSDL.h rename to clientapp/ios/startSDL.h diff --git a/client/ios/startSDL.mm b/clientapp/ios/startSDL.mm similarity index 100% rename from client/ios/startSDL.mm rename to clientapp/ios/startSDL.mm diff --git a/client/ios/utils.h b/clientapp/ios/utils.h similarity index 100% rename from client/ios/utils.h rename to clientapp/ios/utils.h diff --git a/client/ios/utils.mm b/clientapp/ios/utils.mm similarity index 100% rename from client/ios/utils.mm rename to clientapp/ios/utils.mm diff --git a/client/ios/vcmi_logo.png b/clientapp/ios/vcmi_logo.png similarity index 100% rename from client/ios/vcmi_logo.png rename to clientapp/ios/vcmi_logo.png From 9b655ac43ea7e6a3da6428cd173e7199b54225a7 Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 14 Aug 2024 23:30:19 +0300 Subject: [PATCH 04/12] ios fix attempt --- client/CMakeLists.txt | 30 +++++----------------- {clientapp => client}/ios/utils.h | 0 {clientapp => client}/ios/utils.mm | 0 {client => clientapp}/CFocusableHelper.cpp | 2 +- {client => clientapp}/CFocusableHelper.h | 0 clientapp/CMakeLists.txt | 27 ++++++++++++++++++- 6 files changed, 33 insertions(+), 26 deletions(-) rename {clientapp => client}/ios/utils.h (100%) rename {clientapp => client}/ios/utils.mm (100%) rename {client => clientapp}/CFocusableHelper.cpp (90%) rename {client => clientapp}/CFocusableHelper.h (100%) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0208ca71d..9714c246f 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -396,19 +396,12 @@ set(vcmiclientcommon_HEADERS ) if(APPLE_IOS) - set(vcmiclientcommon_SRCS ${vcmiclientcommon_SRCS} - CFocusableHelper.cpp - ios/GameChatKeyboardHandler.m - ios/main.m - ios/startSDL.mm - ios/utils.mm - ) - set(vcmiclientcommon_HEADERS ${vcmiclientcommon_HEADERS} - CFocusableHelper.h - ios/GameChatKeyboardHandler.h - ios/startSDL.h - ios/utils.h - ) + set(vcmiclientcommon_SRCS ${vcmiclientcommon_SRCS} + ios/utils.mm + ) + set(vcmiclientcommon_HEADERS ${vcmiclientcommon_HEADERS} + ios/utils.h + ) endif() assign_source_group(${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) @@ -466,17 +459,6 @@ elseif(APPLE_IOS) "-framework CoreMedia" "-framework VideoToolbox" ) - - foreach(XCODE_RESOURCE LaunchScreen.storyboard Images.xcassets Settings.bundle vcmi_logo.png) - set(XCODE_RESOURCE_PATH ios/${XCODE_RESOURCE}) - target_sources(vcmiclientcommon PRIVATE ${XCODE_RESOURCE_PATH}) - set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - - # workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag - if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0" AND CMAKE_VERSION VERSION_LESS "3.25.0") - set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX) - endif() - endforeach() endif() target_link_libraries(vcmiclientcommon PRIVATE vcmiservercommon) diff --git a/clientapp/ios/utils.h b/client/ios/utils.h similarity index 100% rename from clientapp/ios/utils.h rename to client/ios/utils.h diff --git a/clientapp/ios/utils.mm b/client/ios/utils.mm similarity index 100% rename from clientapp/ios/utils.mm rename to client/ios/utils.mm diff --git a/client/CFocusableHelper.cpp b/clientapp/CFocusableHelper.cpp similarity index 90% rename from client/CFocusableHelper.cpp rename to clientapp/CFocusableHelper.cpp index ea0297eca..3772694d2 100644 --- a/client/CFocusableHelper.cpp +++ b/clientapp/CFocusableHelper.cpp @@ -9,7 +9,7 @@ */ #include "StdInc.h" #include "CFocusableHelper.h" -#include "widgets/CTextInput.h" +#include "../client/widgets/CTextInput.h" void removeFocusFromActiveInput() { diff --git a/client/CFocusableHelper.h b/clientapp/CFocusableHelper.h similarity index 100% rename from client/CFocusableHelper.h rename to clientapp/CFocusableHelper.h diff --git a/clientapp/CMakeLists.txt b/clientapp/CMakeLists.txt index 923d7ce09..2e9e586cb 100644 --- a/clientapp/CMakeLists.txt +++ b/clientapp/CMakeLists.txt @@ -7,6 +7,20 @@ set(clientapp_HEADERS StdInc.h ) +if(APPLE_IOS) + set(clientapp_SRCS ${clientapp_SRCS} + CFocusableHelper.cpp + ios/GameChatKeyboardHandler.m + ios/main.m + ios/startSDL.mm + ) + set(clientapp_HEADERS ${clientapp_HEADERS} + CFocusableHelper.h + ios/GameChatKeyboardHandler.h + ios/startSDL.h + ) +endif() + assign_source_group(${clientapp_SRCS} ${clientapp_HEADERS}) add_executable(vcmiclient ${clientapp_SRCS} ${clientapp_HEADERS}) @@ -46,7 +60,18 @@ elseif(APPLE_IOS) XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon ) - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_vcmiclient_main") + foreach(XCODE_RESOURCE LaunchScreen.storyboard Images.xcassets Settings.bundle vcmi_logo.png) + set(XCODE_RESOURCE_PATH ios/${XCODE_RESOURCE}) + target_sources(vcmiclient PRIVATE ${XCODE_RESOURCE_PATH}) + set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + # workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0" AND CMAKE_VERSION VERSION_LESS "3.25.0") + set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX) + endif() + endforeach() + + set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_client_main") endif() vcmi_set_output_dir(vcmiclient "") From be58f61c35adb56d66f11c4cc50e73aa461df7f6 Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Thu, 15 Aug 2024 10:19:20 +0300 Subject: [PATCH 05/12] fix indentation --- client/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 9714c246f..09a69f858 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -396,12 +396,12 @@ set(vcmiclientcommon_HEADERS ) if(APPLE_IOS) - set(vcmiclientcommon_SRCS ${vcmiclientcommon_SRCS} - ios/utils.mm - ) - set(vcmiclientcommon_HEADERS ${vcmiclientcommon_HEADERS} - ios/utils.h - ) + set(vcmiclientcommon_SRCS ${vcmiclientcommon_SRCS} + ios/utils.mm + ) + set(vcmiclientcommon_HEADERS ${vcmiclientcommon_HEADERS} + ios/utils.h + ) endif() assign_source_group(${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) From 90931cc3e3934dea916bcce32bec7fe70e613e25 Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Mon, 19 Aug 2024 13:17:38 +0300 Subject: [PATCH 06/12] android deploy fix attempt --- client/CMakeLists.txt | 10 +--------- clientapp/CMakeLists.txt | 10 +++++++++- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 09a69f858..7419370d3 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -405,15 +405,7 @@ if(APPLE_IOS) endif() assign_source_group(${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) - -if(ANDROID) - add_library(vcmiclientcommon SHARED ${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) - set_target_properties(vcmiclientcommon PROPERTIES - OUTPUT_NAME "vcmiclient_${ANDROID_ABI}" # required by Qt - ) -else() - add_library(vcmiclientcommon STATIC ${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) -endif() +add_library(vcmiclientcommon STATIC ${vcmiclientcommon_SRCS} ${vcmiclientcommon_HEADERS}) if(NOT ENABLE_STATIC_LIBS) add_dependencies(vcmiclientcommon diff --git a/clientapp/CMakeLists.txt b/clientapp/CMakeLists.txt index 2e9e586cb..8ed148e3f 100644 --- a/clientapp/CMakeLists.txt +++ b/clientapp/CMakeLists.txt @@ -22,7 +22,15 @@ if(APPLE_IOS) endif() assign_source_group(${clientapp_SRCS} ${clientapp_HEADERS}) -add_executable(vcmiclient ${clientapp_SRCS} ${clientapp_HEADERS}) + +if(ANDROID) + add_library(vcmiclient SHARED ${clientapp_SRCS} ${clientapp_HEADERS}) + set_target_properties(vcmiclient PROPERTIES + OUTPUT_NAME "vcmiclient_${ANDROID_ABI}" # required by Qt + ) +else() + add_executable(vcmiclient ${clientapp_SRCS} ${clientapp_HEADERS}) +endif() target_link_libraries(vcmiclient PRIVATE vcmiclientcommon) From 530c1f2bc1d45c95a8651a7c66f8119b61e1dd5c Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 21 Aug 2024 16:07:30 +0300 Subject: [PATCH 07/12] [SPLIT-CLIENT+DEVELOP] android fix attempt --- client/CMakeLists.txt | 3 --- clientapp/CMakeLists.txt | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 7419370d3..4666d791b 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -454,9 +454,6 @@ elseif(APPLE_IOS) endif() target_link_libraries(vcmiclientcommon PRIVATE vcmiservercommon) -if(ENABLE_SINGLE_APP_BUILD AND ENABLE_LAUNCHER) - target_link_libraries(vcmiclientcommon PRIVATE vcmilauncher) -endif() target_link_libraries(vcmiclientcommon PUBLIC vcmi SDL2::SDL2 SDL2::Image SDL2::Mixer SDL2::TTF diff --git a/clientapp/CMakeLists.txt b/clientapp/CMakeLists.txt index 8ed148e3f..0a83e530e 100644 --- a/clientapp/CMakeLists.txt +++ b/clientapp/CMakeLists.txt @@ -34,6 +34,10 @@ endif() target_link_libraries(vcmiclient PRIVATE vcmiclientcommon) +if(ENABLE_SINGLE_APP_BUILD AND ENABLE_LAUNCHER) + target_link_libraries(vcmiclientcommon PRIVATE vcmilauncher) +endif() + target_include_directories(vcmiclient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) From 81c3151c2c6dde0e56e1951853208b22d004810d Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 21 Aug 2024 16:19:45 +0300 Subject: [PATCH 08/12] TEMP remove unneeded git runs --- .github/workflows/github.yml | 150 +++++++++++++++++------------------ 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index 7d3b02406..dba8b500a 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -19,81 +19,81 @@ jobs: strategy: matrix: include: - - platform: linux-qt6 - os: ubuntu-24.04 - test: 0 - preset: linux-clang-test - - platform: linux - os: ubuntu-24.04 - test: 1 - preset: linux-gcc-test - - platform: linux - os: ubuntu-20.04 - test: 0 - preset: linux-gcc-debug - - platform: mac-intel - os: macos-13 - test: 0 - pack: 1 - pack_type: Release - extension: dmg - preset: macos-conan-ninja-release - conan_profile: macos-intel - conan_options: --options with_apple_system_libs=True - artifact_platform: intel - - platform: mac-arm - os: macos-13 - test: 0 - pack: 1 - pack_type: Release - extension: dmg - preset: macos-arm-conan-ninja-release - conan_profile: macos-arm - conan_options: --options with_apple_system_libs=True - artifact_platform: arm - - platform: ios - os: macos-13 - test: 0 - pack: 1 - pack_type: Release - extension: ipa - preset: ios-release-conan-ccache - conan_profile: ios-arm64 - conan_options: --options with_apple_system_libs=True - - platform: msvc - os: windows-latest - test: 0 - pack: 1 - pack_type: RelWithDebInfo - extension: exe - preset: windows-msvc-release - - platform: mingw - os: ubuntu-22.04 - test: 0 - pack: 1 - pack_type: Release - extension: exe - cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` - cmake_args: -G Ninja - preset: windows-mingw-conan-linux - conan_profile: mingw64-linux.jinja - - platform: mingw-32 - os: ubuntu-22.04 - test: 0 - pack: 1 - pack_type: Release - extension: exe - cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` - cmake_args: -G Ninja - preset: windows-mingw-conan-linux - conan_profile: mingw32-linux.jinja - - platform: android-32 - os: macos-14 - extension: apk - preset: android-conan-ninja-release - conan_profile: android-32 - conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT - artifact_platform: armeabi-v7a + #- platform: linux-qt6 + # os: ubuntu-24.04 + # test: 0 + # preset: linux-clang-test + #- platform: linux + # os: ubuntu-24.04 + # test: 1 + # preset: linux-gcc-test + #- platform: linux + # os: ubuntu-20.04 + # test: 0 + # preset: linux-gcc-debug + #- platform: mac-intel + # os: macos-13 + # test: 0 + # pack: 1 + # pack_type: Release + # extension: dmg + # preset: macos-conan-ninja-release + # conan_profile: macos-intel + # conan_options: --options with_apple_system_libs=True + # artifact_platform: intel + #- platform: mac-arm + # os: macos-13 + # test: 0 + # pack: 1 + # pack_type: Release + # extension: dmg + # preset: macos-arm-conan-ninja-release + # conan_profile: macos-arm + # conan_options: --options with_apple_system_libs=True + # artifact_platform: arm + #- platform: ios + # os: macos-13 + # test: 0 + # pack: 1 + # pack_type: Release + # extension: ipa + # preset: ios-release-conan-ccache + # conan_profile: ios-arm64 + # conan_options: --options with_apple_system_libs=True + #- platform: msvc + # os: windows-latest + # test: 0 + # pack: 1 + # pack_type: RelWithDebInfo + # extension: exe + # preset: windows-msvc-release + #- platform: mingw + # os: ubuntu-22.04 + # test: 0 + # pack: 1 + # pack_type: Release + # extension: exe + # cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` + # cmake_args: -G Ninja + # preset: windows-mingw-conan-linux + # conan_profile: mingw64-linux.jinja + #- platform: mingw-32 + # os: ubuntu-22.04 + # test: 0 + # pack: 1 + # pack_type: Release + # extension: exe + # cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` + # cmake_args: -G Ninja + # preset: windows-mingw-conan-linux + # conan_profile: mingw32-linux.jinja + #- platform: android-32 + # os: macos-14 + # extension: apk + # preset: android-conan-ninja-release + # conan_profile: android-32 + # conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT + # artifact_platform: armeabi-v7a - platform: android-64 os: macos-14 extension: apk From da6bd38a1cec1c6f641177fa326a0daa18187d3f Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 21 Aug 2024 17:21:36 +0300 Subject: [PATCH 09/12] fix typo --- clientapp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientapp/CMakeLists.txt b/clientapp/CMakeLists.txt index 0a83e530e..9c104831c 100644 --- a/clientapp/CMakeLists.txt +++ b/clientapp/CMakeLists.txt @@ -35,7 +35,7 @@ endif() target_link_libraries(vcmiclient PRIVATE vcmiclientcommon) if(ENABLE_SINGLE_APP_BUILD AND ENABLE_LAUNCHER) - target_link_libraries(vcmiclientcommon PRIVATE vcmilauncher) + target_link_libraries(vcmiclient PRIVATE vcmilauncher) endif() target_include_directories(vcmiclient From f500139f8d4d75e309af1c3867cc550f39c949de Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Wed, 21 Aug 2024 17:38:19 +0300 Subject: [PATCH 10/12] re-enable github jobs --- .github/workflows/github.yml | 150 +++++++++++++++++------------------ 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index dba8b500a..7d3b02406 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -19,81 +19,81 @@ jobs: strategy: matrix: include: - #- platform: linux-qt6 - # os: ubuntu-24.04 - # test: 0 - # preset: linux-clang-test - #- platform: linux - # os: ubuntu-24.04 - # test: 1 - # preset: linux-gcc-test - #- platform: linux - # os: ubuntu-20.04 - # test: 0 - # preset: linux-gcc-debug - #- platform: mac-intel - # os: macos-13 - # test: 0 - # pack: 1 - # pack_type: Release - # extension: dmg - # preset: macos-conan-ninja-release - # conan_profile: macos-intel - # conan_options: --options with_apple_system_libs=True - # artifact_platform: intel - #- platform: mac-arm - # os: macos-13 - # test: 0 - # pack: 1 - # pack_type: Release - # extension: dmg - # preset: macos-arm-conan-ninja-release - # conan_profile: macos-arm - # conan_options: --options with_apple_system_libs=True - # artifact_platform: arm - #- platform: ios - # os: macos-13 - # test: 0 - # pack: 1 - # pack_type: Release - # extension: ipa - # preset: ios-release-conan-ccache - # conan_profile: ios-arm64 - # conan_options: --options with_apple_system_libs=True - #- platform: msvc - # os: windows-latest - # test: 0 - # pack: 1 - # pack_type: RelWithDebInfo - # extension: exe - # preset: windows-msvc-release - #- platform: mingw - # os: ubuntu-22.04 - # test: 0 - # pack: 1 - # pack_type: Release - # extension: exe - # cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` - # cmake_args: -G Ninja - # preset: windows-mingw-conan-linux - # conan_profile: mingw64-linux.jinja - #- platform: mingw-32 - # os: ubuntu-22.04 - # test: 0 - # pack: 1 - # pack_type: Release - # extension: exe - # cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` - # cmake_args: -G Ninja - # preset: windows-mingw-conan-linux - # conan_profile: mingw32-linux.jinja - #- platform: android-32 - # os: macos-14 - # extension: apk - # preset: android-conan-ninja-release - # conan_profile: android-32 - # conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT - # artifact_platform: armeabi-v7a + - platform: linux-qt6 + os: ubuntu-24.04 + test: 0 + preset: linux-clang-test + - platform: linux + os: ubuntu-24.04 + test: 1 + preset: linux-gcc-test + - platform: linux + os: ubuntu-20.04 + test: 0 + preset: linux-gcc-debug + - platform: mac-intel + os: macos-13 + test: 0 + pack: 1 + pack_type: Release + extension: dmg + preset: macos-conan-ninja-release + conan_profile: macos-intel + conan_options: --options with_apple_system_libs=True + artifact_platform: intel + - platform: mac-arm + os: macos-13 + test: 0 + pack: 1 + pack_type: Release + extension: dmg + preset: macos-arm-conan-ninja-release + conan_profile: macos-arm + conan_options: --options with_apple_system_libs=True + artifact_platform: arm + - platform: ios + os: macos-13 + test: 0 + pack: 1 + pack_type: Release + extension: ipa + preset: ios-release-conan-ccache + conan_profile: ios-arm64 + conan_options: --options with_apple_system_libs=True + - platform: msvc + os: windows-latest + test: 0 + pack: 1 + pack_type: RelWithDebInfo + extension: exe + preset: windows-msvc-release + - platform: mingw + os: ubuntu-22.04 + test: 0 + pack: 1 + pack_type: Release + extension: exe + cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` + cmake_args: -G Ninja + preset: windows-mingw-conan-linux + conan_profile: mingw64-linux.jinja + - platform: mingw-32 + os: ubuntu-22.04 + test: 0 + pack: 1 + pack_type: Release + extension: exe + cpack_args: -D CPACK_NSIS_EXECUTABLE=`which makensis` + cmake_args: -G Ninja + preset: windows-mingw-conan-linux + conan_profile: mingw32-linux.jinja + - platform: android-32 + os: macos-14 + extension: apk + preset: android-conan-ninja-release + conan_profile: android-32 + conan_options: --conf tools.android:ndk_path=$ANDROID_NDK_ROOT + artifact_platform: armeabi-v7a - platform: android-64 os: macos-14 extension: apk From 20ccc92e6d5905ec1300a29e034526f7707abe60 Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Tue, 27 Aug 2024 03:59:09 +0300 Subject: [PATCH 11/12] move shutdown functions in EntryPoint --- client/CMT.cpp | 159 ------------------------------------- client/CMT.h | 7 +- client/CMakeLists.txt | 1 - clientapp/EntryPoint.cpp | 167 +++++++++++++++++++++++++++++++++------ 4 files changed, 145 insertions(+), 189 deletions(-) delete mode 100644 client/CMT.cpp diff --git a/client/CMT.cpp b/client/CMT.cpp deleted file mode 100644 index 7bb0872f9..000000000 --- a/client/CMT.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * CMT.cpp, part of VCMI engine - * - * Authors: listed in file AUTHORS in main folder - * - * License: GNU General Public License v2.0 or later - * Full text of license available in license.txt file, in main folder - * - */ - -#include "StdInc.h" -#include "CMT.h" - -#include "CGameInfo.h" -#include "mainmenu/CMainMenu.h" -#include "media/CMusicHandler.h" -#include "media/CSoundHandler.h" -#include "media/CVideoHandler.h" -#include "gui/CursorHandler.h" -#include "CPlayerInterface.h" -#include "gui/CGuiHandler.h" -#include "gui/WindowHandler.h" -#include "CServerHandler.h" -#include "windows/CMessage.h" -#include "windows/InfoWindows.h" -#include "render/IScreenHandler.h" -#include "render/Graphics.h" - -#include "../lib/texts/CGeneralTextHandler.h" -#include "../lib/VCMI_Lib.h" - -#include "../lib/logging/CBasicLogConfigurator.h" - -#include -#include - -#ifdef VCMI_ANDROID -#include "../lib/CAndroidVMHelper.h" -#include -#endif - -#if __MINGW32__ -#undef main -#endif -extern std::atomic headlessQuit; -extern std::optional criticalInitializationError; -extern CBasicLogConfigurator *logConfig; - -[[noreturn]] static void quitApplicationImmediately(int error_code) -{ - // Perform quick exit without executing static destructors and let OS cleanup anything that we did not - // We generally don't care about them and this leads to numerous issues, e.g. - // destruction of locked mutexes (fails an assertion), even in third-party libraries (as well as native libs on Android) - // Android - std::quick_exit is available only starting from API level 21 - // Mingw, macOS and iOS - std::quick_exit is unavailable (at least in current version of CI) -#if (defined(__ANDROID_API__) && __ANDROID_API__ < 21) || (defined(__MINGW32__)) || defined(VCMI_APPLE) - ::exit(error_code); -#else - std::quick_exit(error_code); -#endif -} - -[[noreturn]] void quitApplication() -{ - CSH->endNetwork(); - - if(!settings["session"]["headless"].Bool()) - { - if(CSH->client) - CSH->endGameplay(); - - GH.windows().clear(); - } - - vstd::clear_pointer(CSH); - - CMM.reset(); - - if(!settings["session"]["headless"].Bool()) - { - // cleanup, mostly to remove false leaks from analyzer - if(CCS) - { - delete CCS->consoleh; - delete CCS->curh; - delete CCS->videoh; - delete CCS->musich; - delete CCS->soundh; - - vstd::clear_pointer(CCS); - } - CMessage::dispose(); - - vstd::clear_pointer(graphics); - } - - vstd::clear_pointer(VLC); - - // sometimes leads to a hang. TODO: investigate - //vstd::clear_pointer(console);// should be removed after everything else since used by logging - - if(!settings["session"]["headless"].Bool()) - GH.screenHandler().close(); - - if(logConfig != nullptr) - { - logConfig->deconfigure(); - delete logConfig; - logConfig = nullptr; - } - - std::cout << "Ending...\n"; - quitApplicationImmediately(0); -} - -void handleQuit(bool ask) -{ - if(!ask) - { - if(settings["session"]["headless"].Bool()) - { - headlessQuit = true; - } - else - { - quitApplication(); - } - - return; - } - - // FIXME: avoids crash if player attempts to close game while opening is still playing - // use cursor handler as indicator that loading is not done yet - // proper solution would be to abort init thread (or wait for it to finish) - if (!CCS->curh) - { - quitApplicationImmediately(0); - } - - if (LOCPLINT) - LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr); - else - CInfoWindow::showYesNoDialog(CGI->generaltexth->allTexts[69], {}, quitApplication, {}, PlayerColor(1)); -} - -void handleFatalError(const std::string & message, bool terminate) -{ - logGlobal->error("FATAL ERROR ENCOUNTERED, VCMI WILL NOW TERMINATE"); - logGlobal->error("Reason: %s", message); - - std::string messageToShow = "Fatal error! " + message; - - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error!", messageToShow.c_str(), nullptr); - - if (terminate) - throw std::runtime_error(message); - else - quitApplicationImmediately(1); -} diff --git a/client/CMT.h b/client/CMT.h index 9bd421dc1..f2cdc65a3 100644 --- a/client/CMT.h +++ b/client/CMT.h @@ -20,9 +20,6 @@ extern SDL_Surface *screen; // main screen surface extern SDL_Surface *screen2; // and hlp surface (used to store not-active interfaces layer) extern SDL_Surface *screenBuf; // points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed +// defined in clientapp EntryPoint void handleQuit(bool ask = true); - -/// Notify user about encountered fatal error and terminate the game -/// TODO: decide on better location for this method -[[noreturn]] void handleFatalError(const std::string & message, bool terminate); -[[noreturn]] void quitApplication(); +void handleFatalError(const std::string & message, bool terminate); diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ee552f5e5..be6bd26ac 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -177,7 +177,6 @@ set(vcmiclientcommon_SRCS ArtifactsUIController.cpp CGameInfo.cpp - CMT.cpp CPlayerInterface.cpp PlayerLocalState.cpp CServerHandler.cpp diff --git a/clientapp/EntryPoint.cpp b/clientapp/EntryPoint.cpp index 7fb42b98c..e32303f07 100644 --- a/clientapp/EntryPoint.cpp +++ b/clientapp/EntryPoint.cpp @@ -9,33 +9,37 @@ */ // EntryPoint.cpp : Defines the entry point for the console application. -#include "Global.h" -#include "StdInc.h" -#include "client/CGameInfo.h" -#include "client/mainmenu/CMainMenu.h" -#include "media/CEmptyVideoPlayer.h" -#include "media/CMusicHandler.h" -#include "media/CSoundHandler.h" -#include "media/CVideoHandler.h" -#include "client/gui/CursorHandler.h" -#include "client/eventsSDL/InputHandler.h" -#include "client/gui/CGuiHandler.h" -#include "client/CServerHandler.h" -#include "client/ClientCommandManager.h" -#include "client/windows/CMessage.h" -#include "client/render/IRenderHandler.h" -#include "client/render/IScreenHandler.h" -#include "client/render/Graphics.h" -#include "client/CMT.h" +#include "StdInc.h" +#include "../Global.h" + +#include "../client/CGameInfo.h" +#include "../client/ClientCommandManager.h" +#include "../client/CMT.h" +#include "../client/CPlayerInterface.h" +#include "../client/CServerHandler.h" +#include "../client/eventsSDL/InputHandler.h" +#include "../client/gui/CGuiHandler.h" +#include "../client/gui/CursorHandler.h" +#include "../client/gui/WindowHandler.h" +#include "../client/mainmenu/CMainMenu.h" +#include "../client/media/CEmptyVideoPlayer.h" +#include "../client/media/CMusicHandler.h" +#include "../client/media/CSoundHandler.h" +#include "../client/media/CVideoHandler.h" +#include "../client/render/Graphics.h" +#include "../client/render/IRenderHandler.h" +#include "../client/render/IScreenHandler.h" +#include "../client/windows/CMessage.h" +#include "../client/windows/InfoWindows.h" #include "../lib/CThreadHelper.h" #include "../lib/ExceptionsCommon.h" -#include "../lib/VCMIDirs.h" -#include "../lib/VCMI_Lib.h" #include "../lib/filesystem/Filesystem.h" - #include "../lib/logging/CBasicLogConfigurator.h" +#include "../lib/texts/CGeneralTextHandler.h" +#include "../lib/VCMI_Lib.h" +#include "../lib/VCMIDirs.h" #include #include @@ -55,16 +59,17 @@ namespace po = boost::program_options; namespace po_style = boost::program_options::command_line_style; -std::atomic headlessQuit = false; -std::optional criticalInitializationError; +static std::atomic headlessQuit = false; +static std::optional criticalInitializationError; #ifndef VCMI_IOS void processCommand(const std::string &message); #endif void playIntro(); +[[noreturn]] static void quitApplication(); static void mainLoop(); -CBasicLogConfigurator *logConfig; +static CBasicLogConfigurator *logConfig; void init() { @@ -422,3 +427,117 @@ static void mainLoop() GH.renderFrame(); } } + +[[noreturn]] static void quitApplicationImmediately(int error_code) +{ + // Perform quick exit without executing static destructors and let OS cleanup anything that we did not + // We generally don't care about them and this leads to numerous issues, e.g. + // destruction of locked mutexes (fails an assertion), even in third-party libraries (as well as native libs on Android) + // Android - std::quick_exit is available only starting from API level 21 + // Mingw, macOS and iOS - std::quick_exit is unavailable (at least in current version of CI) +#if (defined(__ANDROID_API__) && __ANDROID_API__ < 21) || (defined(__MINGW32__)) || defined(VCMI_APPLE) + ::exit(error_code); +#else + std::quick_exit(error_code); +#endif +} + +[[noreturn]] static void quitApplication() +{ + CSH->endNetwork(); + + if(!settings["session"]["headless"].Bool()) + { + if(CSH->client) + CSH->endGameplay(); + + GH.windows().clear(); + } + + vstd::clear_pointer(CSH); + + CMM.reset(); + + if(!settings["session"]["headless"].Bool()) + { + // cleanup, mostly to remove false leaks from analyzer + if(CCS) + { + delete CCS->consoleh; + delete CCS->curh; + delete CCS->videoh; + delete CCS->musich; + delete CCS->soundh; + + vstd::clear_pointer(CCS); + } + CMessage::dispose(); + + vstd::clear_pointer(graphics); + } + + vstd::clear_pointer(VLC); + + // sometimes leads to a hang. TODO: investigate + //vstd::clear_pointer(console);// should be removed after everything else since used by logging + + if(!settings["session"]["headless"].Bool()) + GH.screenHandler().close(); + + if(logConfig != nullptr) + { + logConfig->deconfigure(); + delete logConfig; + logConfig = nullptr; + } + + std::cout << "Ending...\n"; + quitApplicationImmediately(0); +} + +void handleQuit(bool ask) +{ + if(!ask) + { + if(settings["session"]["headless"].Bool()) + { + headlessQuit = true; + } + else + { + quitApplication(); + } + + return; + } + + // FIXME: avoids crash if player attempts to close game while opening is still playing + // use cursor handler as indicator that loading is not done yet + // proper solution would be to abort init thread (or wait for it to finish) + if (!CCS->curh) + { + quitApplicationImmediately(0); + } + + if (LOCPLINT) + LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr); + else + CInfoWindow::showYesNoDialog(CGI->generaltexth->allTexts[69], {}, quitApplication, {}, PlayerColor(1)); +} + +/// Notify user about encountered fatal error and terminate the game +/// TODO: decide on better location for this method +void handleFatalError(const std::string & message, bool terminate) +{ + logGlobal->error("FATAL ERROR ENCOUNTERED, VCMI WILL NOW TERMINATE"); + logGlobal->error("Reason: %s", message); + + std::string messageToShow = "Fatal error! " + message; + + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error!", messageToShow.c_str(), nullptr); + + if (terminate) + throw std::runtime_error(message); + else + quitApplicationImmediately(1); +} From e502853227c4b0cb88d6d595f96f7afdf2d52740 Mon Sep 17 00:00:00 2001 From: Simeon Manolov Date: Sat, 31 Aug 2024 18:12:00 +0300 Subject: [PATCH 12/12] address code review comments --- client/CMT.h | 6 +- clientapp/CMakeLists.txt | 186 +++++++++++++++++++-------------------- 2 files changed, 97 insertions(+), 95 deletions(-) diff --git a/client/CMT.h b/client/CMT.h index f2cdc65a3..abd6596f5 100644 --- a/client/CMT.h +++ b/client/CMT.h @@ -20,6 +20,8 @@ extern SDL_Surface *screen; // main screen surface extern SDL_Surface *screen2; // and hlp surface (used to store not-active interfaces layer) extern SDL_Surface *screenBuf; // points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed -// defined in clientapp EntryPoint +/// Notify user about encountered fatal error and terminate the game +/// Defined in clientapp EntryPoint +/// TODO: decide on better location for this method +[[noreturn]] void handleFatalError(const std::string & message, bool terminate); void handleQuit(bool ask = true); -void handleFatalError(const std::string & message, bool terminate); diff --git a/clientapp/CMakeLists.txt b/clientapp/CMakeLists.txt index 9c104831c..56d21c1c8 100644 --- a/clientapp/CMakeLists.txt +++ b/clientapp/CMakeLists.txt @@ -1,137 +1,137 @@ set(clientapp_SRCS - StdInc.cpp - EntryPoint.cpp + StdInc.cpp + EntryPoint.cpp ) set(clientapp_HEADERS - StdInc.h + StdInc.h ) if(APPLE_IOS) - set(clientapp_SRCS ${clientapp_SRCS} - CFocusableHelper.cpp - ios/GameChatKeyboardHandler.m - ios/main.m - ios/startSDL.mm - ) - set(clientapp_HEADERS ${clientapp_HEADERS} - CFocusableHelper.h - ios/GameChatKeyboardHandler.h - ios/startSDL.h - ) + set(clientapp_SRCS ${clientapp_SRCS} + CFocusableHelper.cpp + ios/GameChatKeyboardHandler.m + ios/main.m + ios/startSDL.mm + ) + set(clientapp_HEADERS ${clientapp_HEADERS} + CFocusableHelper.h + ios/GameChatKeyboardHandler.h + ios/startSDL.h + ) endif() assign_source_group(${clientapp_SRCS} ${clientapp_HEADERS}) if(ANDROID) - add_library(vcmiclient SHARED ${clientapp_SRCS} ${clientapp_HEADERS}) - set_target_properties(vcmiclient PROPERTIES - OUTPUT_NAME "vcmiclient_${ANDROID_ABI}" # required by Qt - ) + add_library(vcmiclient SHARED ${clientapp_SRCS} ${clientapp_HEADERS}) + set_target_properties(vcmiclient PROPERTIES + OUTPUT_NAME "vcmiclient_${ANDROID_ABI}" # required by Qt + ) else() - add_executable(vcmiclient ${clientapp_SRCS} ${clientapp_HEADERS}) + add_executable(vcmiclient ${clientapp_SRCS} ${clientapp_HEADERS}) endif() target_link_libraries(vcmiclient PRIVATE vcmiclientcommon) if(ENABLE_SINGLE_APP_BUILD AND ENABLE_LAUNCHER) - target_link_libraries(vcmiclient PRIVATE vcmilauncher) + target_link_libraries(vcmiclient PRIVATE vcmilauncher) endif() target_include_directories(vcmiclient - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) if(WIN32) - target_sources(vcmiclient PRIVATE "VCMI_client.rc") - set_target_properties(vcmiclient - PROPERTIES - OUTPUT_NAME "VCMI_client" - PROJECT_LABEL "VCMI_client" - ) - set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT vcmiclient) - if(NOT ENABLE_DEBUG_CONSOLE) - set_target_properties(vcmiclient PROPERTIES WIN32_EXECUTABLE) - target_link_libraries(vcmiclient SDL2::SDL2main) - endif() - target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) + target_sources(vcmiclient PRIVATE "VCMI_client.rc") + set_target_properties(vcmiclient + PROPERTIES + OUTPUT_NAME "VCMI_client" + PROJECT_LABEL "VCMI_client" + ) + set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT vcmiclient) + if(NOT ENABLE_DEBUG_CONSOLE) + set_target_properties(vcmiclient PROPERTIES WIN32_EXECUTABLE) + target_link_libraries(vcmiclient SDL2::SDL2main) + endif() + target_compile_definitions(vcmiclient PRIVATE WINDOWS_IGNORE_PACKING_MISMATCH) -# TODO: very hacky, find proper solution to copy AI dlls into bin dir - if(MSVC) - add_custom_command(TARGET vcmiclient POST_BUILD - WORKING_DIRECTORY "$" - COMMAND ${CMAKE_COMMAND} -E copy AI/fuzzylite.dll fuzzylite.dll - COMMAND ${CMAKE_COMMAND} -E copy AI/tbb12.dll tbb12.dll - ) - endif() + # TODO: very hacky, find proper solution to copy AI dlls into bin dir + if(MSVC) + add_custom_command(TARGET vcmiclient POST_BUILD + WORKING_DIRECTORY "$" + COMMAND ${CMAKE_COMMAND} -E copy AI/fuzzylite.dll fuzzylite.dll + COMMAND ${CMAKE_COMMAND} -E copy AI/tbb12.dll tbb12.dll + ) + endif() elseif(APPLE_IOS) - set_target_properties(vcmiclient PROPERTIES - MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/ios/Info.plist" - XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks" - XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "$(CODE_SIGNING_ALLOWED_FOR_APPS)" - XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon - ) + set_target_properties(vcmiclient PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/ios/Info.plist" + XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks" + XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "$(CODE_SIGNING_ALLOWED_FOR_APPS)" + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + ) - foreach(XCODE_RESOURCE LaunchScreen.storyboard Images.xcassets Settings.bundle vcmi_logo.png) - set(XCODE_RESOURCE_PATH ios/${XCODE_RESOURCE}) - target_sources(vcmiclient PRIVATE ${XCODE_RESOURCE_PATH}) - set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + foreach(XCODE_RESOURCE LaunchScreen.storyboard Images.xcassets Settings.bundle vcmi_logo.png) + set(XCODE_RESOURCE_PATH ios/${XCODE_RESOURCE}) + target_sources(vcmiclient PRIVATE ${XCODE_RESOURCE_PATH}) + set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - # workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag - if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0" AND CMAKE_VERSION VERSION_LESS "3.25.0") - set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX) - endif() - endforeach() + # workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0" AND CMAKE_VERSION VERSION_LESS "3.25.0") + set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX) + endif() + endforeach() - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_client_main") + set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_client_main") endif() vcmi_set_output_dir(vcmiclient "") enable_pch(vcmiclient) if(APPLE_IOS) - vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}") - add_custom_command(TARGET vcmiclient POST_BUILD - COMMAND ios/set_build_version.sh "$" - COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --component "${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}" --config "$" --prefix "$" - COMMAND ios/rpath_remove_symlinks.sh - COMMAND ios/codesign.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - ) - install(TARGETS vcmiclient DESTINATION Payload COMPONENT app) # for ipa generation with cpack + vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}") + add_custom_command(TARGET vcmiclient POST_BUILD + COMMAND ios/set_build_version.sh "$" + COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --component "${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}" --config "$" --prefix "$" + COMMAND ios/rpath_remove_symlinks.sh + COMMAND ios/codesign.sh + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + install(TARGETS vcmiclient DESTINATION Payload COMPONENT app) # for ipa generation with cpack elseif(ANDROID) - find_program(androidDeployQt androiddeployqt - PATHS "${qtBinDir}" - ) - vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}/${LIB_DIR}") + find_program(androidDeployQt androiddeployqt + PATHS "${qtBinDir}" + ) + vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}/${LIB_DIR}") - add_custom_target(android_deploy ALL - COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --config "$" --prefix "${androidQtBuildDir}" - COMMAND "${androidDeployQt}" --input "${CMAKE_BINARY_DIR}/androiddeployqt.json" --output "${androidQtBuildDir}" --android-platform "android-${ANDROID_TARGET_SDK_VERSION}" --verbose $<$>:--release> ${ANDROIDDEPLOYQT_OPTIONS} - COMMAND_EXPAND_LISTS - VERBATIM - COMMENT "Create android package" - ) - add_dependencies(android_deploy vcmiclient) + add_custom_target(android_deploy ALL + COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --config "$" --prefix "${androidQtBuildDir}" + COMMAND "${androidDeployQt}" --input "${CMAKE_BINARY_DIR}/androiddeployqt.json" --output "${androidQtBuildDir}" --android-platform "android-${ANDROID_TARGET_SDK_VERSION}" --verbose $<$>:--release> ${ANDROIDDEPLOYQT_OPTIONS} + COMMAND_EXPAND_LISTS + VERBATIM + COMMENT "Create android package" + ) + add_dependencies(android_deploy vcmiclient) else() - install(TARGETS vcmiclient DESTINATION ${BIN_DIR}) + install(TARGETS vcmiclient DESTINATION ${BIN_DIR}) endif() #install icons and desktop file on Linux if(NOT WIN32 AND NOT APPLE AND NOT ANDROID) - #FIXME: move to client makefile? - foreach(iconSize 16 22 32 48 64 128 256 512 1024 2048) - install(FILES "icons/vcmiclient.${iconSize}x${iconSize}.png" - DESTINATION "share/icons/hicolor/${iconSize}x${iconSize}/apps" - RENAME vcmiclient.png - ) - endforeach() + #FIXME: move to client makefile? + foreach(iconSize 16 22 32 48 64 128 256 512 1024 2048) + install(FILES "icons/vcmiclient.${iconSize}x${iconSize}.png" + DESTINATION "share/icons/hicolor/${iconSize}x${iconSize}/apps" + RENAME vcmiclient.png + ) + endforeach() - install(FILES icons/vcmiclient.svg - DESTINATION share/icons/hicolor/scalable/apps - RENAME vcmiclient.svg - ) - install(FILES icons/vcmiclient.desktop - DESTINATION share/applications - ) + install(FILES icons/vcmiclient.svg + DESTINATION share/icons/hicolor/scalable/apps + RENAME vcmiclient.svg + ) + install(FILES icons/vcmiclient.desktop + DESTINATION share/applications + ) endif()