From 154c142cfbbecba59b54f0ebd270e0a97a278e7a Mon Sep 17 00:00:00 2001 From: Karwler Date: Wed, 22 Apr 2020 17:31:28 +0200 Subject: [PATCH] New rules * add ports * add more piece materials * add button for finishing match * add message for firing over mountains * add more tooltips * add more security checks for loading files * add multiple server logs * add new version notifier * add chat notification * add FPS counter * finish controller support * make late dragon placement optional * change movement and switching rules * change attack and firing rules * change battle/survival check rules * change FF rules * change default tile amounts * change port to service string * fix FF gain --- CMakeLists.txt | 220 +-- README.md | 22 +- android/app/build.gradle | 4 +- android/app/jni/src/Android.mk | 2 +- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3199 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1866 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 8593 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 12986 bytes doc/docs.html | 410 ++++-- doc/rules.html | 175 ++- doc/style.css | 14 +- rsc/data/cursor.png | Bin 0 -> 542 bytes rsc/data/thrones.png | Bin 0 -> 18821 bytes rsc/materials/{regular.mtl => misc.mtl} | 15 - rsc/materials/pieces.mtl | 49 + rsc/materials/tiles.mtl | 30 + .../{crossbowman.obj => crossbowmen.obj} | 0 rsc/objects/{ranger.obj => rangers.obj} | 0 rsc/objects/{spearman.obj => spearmen.obj} | 0 rsc/textures/assault.png | Bin 0 -> 37942 bytes rsc/textures/catapult.png | Bin 0 -> 10282 bytes rsc/textures/conspire.png | Bin 0 -> 35360 bytes rsc/textures/crossbowmen.png | Bin 0 -> 11280 bytes rsc/textures/crosshair.png | Bin 0 -> 369 bytes rsc/textures/deceive.png | Bin 0 -> 39244 bytes rsc/textures/dragon.png | Bin 0 -> 12762 bytes rsc/textures/elephant.png | Bin 0 -> 11882 bytes rsc/textures/forest.png | Bin 0 -> 514314 bytes rsc/textures/fortress.png | Bin 0 -> 339229 bytes rsc/textures/grass.png | Bin 0 -> 10355314 bytes rsc/textures/hasten.png | Bin 0 -> 36079 bytes rsc/textures/lancer.png | Bin 0 -> 8411 bytes rsc/textures/mountain.png | Bin 0 -> 474368 bytes rsc/textures/plains.png | Bin 0 -> 496574 bytes rsc/textures/rangers.png | Bin 0 -> 10165 bytes rsc/textures/rock.png | Bin 0 -> 5040751 bytes rsc/textures/spearmen.png | Bin 0 -> 8710 bytes rsc/textures/throne.png | Bin 0 -> 9409 bytes rsc/textures/title.png | Bin 0 -> 340740 bytes rsc/textures/trebuchet.png | Bin 0 -> 9538 bytes rsc/textures/wall.png | Bin 0 -> 1138646 bytes rsc/textures/warhorse.png | Bin 0 -> 9850 bytes rsc/textures/water.png | Bin 0 -> 513843 bytes src/engine/audioSys.cpp | 30 +- src/engine/audioSys.h | 6 +- src/engine/fileSys.cpp | 396 +++--- src/engine/fileSys.h | 127 +- src/engine/inputSys.cpp | 287 ++-- src/engine/inputSys.h | 42 +- src/engine/scene.cpp | 218 +-- src/engine/scene.h | 76 +- src/engine/windowSys.cpp | 441 +++--- src/engine/windowSys.h | 181 +-- src/engine/world.cpp | 12 +- src/engine/world.h | 30 +- src/oven/oven.cpp | 40 +- src/oven/oven.h | 37 +- src/oven/ovenProg.cpp | 125 +- src/prog/board.cpp | 627 +++++++++ src/prog/board.h | 271 ++++ src/prog/game.cpp | 1056 +++++--------- src/prog/game.h | 335 +---- src/prog/netcp.cpp | 73 +- src/prog/netcp.h | 4 +- src/prog/program.cpp | 783 ++++++++--- src/prog/program.h | 87 +- src/prog/progs.cpp | 1214 ++++++++++------- src/prog/progs.h | 226 +-- src/prog/types.cpp | 111 ++ src/prog/types.h | 261 ++++ src/server/common.h | 5 +- src/server/log.cpp | 76 ++ src/server/log.h | 60 + src/server/server.cpp | 545 ++++---- src/server/server.h | 157 ++- src/server/serverProg.cpp | 246 ++-- src/utils/context.cpp | 38 +- src/utils/context.h | 4 +- src/utils/layouts.cpp | 162 ++- src/utils/layouts.h | 64 +- src/utils/objects.cpp | 359 +++-- src/utils/objects.h | 251 +--- src/utils/text.cpp | 68 +- src/utils/text.h | 190 +-- src/utils/utils.cpp | 67 +- src/utils/utils.h | 161 +-- src/utils/widgets.cpp | 327 ++--- src/utils/widgets.h | 86 +- tools/export.py | 15 +- tools/server.py | 21 + tools/wslim.py | 19 + 92 files changed, 6408 insertions(+), 4550 deletions(-) create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 rsc/data/cursor.png create mode 100644 rsc/data/thrones.png rename rsc/materials/{regular.mtl => misc.mtl} (59%) create mode 100644 rsc/materials/pieces.mtl create mode 100644 rsc/materials/tiles.mtl rename rsc/objects/{crossbowman.obj => crossbowmen.obj} (100%) rename rsc/objects/{ranger.obj => rangers.obj} (100%) rename rsc/objects/{spearman.obj => spearmen.obj} (100%) create mode 100644 rsc/textures/assault.png create mode 100644 rsc/textures/catapult.png create mode 100644 rsc/textures/conspire.png create mode 100644 rsc/textures/crossbowmen.png create mode 100644 rsc/textures/crosshair.png create mode 100644 rsc/textures/deceive.png create mode 100644 rsc/textures/dragon.png create mode 100644 rsc/textures/elephant.png create mode 100644 rsc/textures/forest.png create mode 100644 rsc/textures/fortress.png create mode 100644 rsc/textures/grass.png create mode 100644 rsc/textures/hasten.png create mode 100644 rsc/textures/lancer.png create mode 100644 rsc/textures/mountain.png create mode 100644 rsc/textures/plains.png create mode 100644 rsc/textures/rangers.png create mode 100644 rsc/textures/rock.png create mode 100644 rsc/textures/spearmen.png create mode 100644 rsc/textures/throne.png create mode 100644 rsc/textures/title.png create mode 100644 rsc/textures/trebuchet.png create mode 100644 rsc/textures/wall.png create mode 100644 rsc/textures/warhorse.png create mode 100644 rsc/textures/water.png create mode 100644 src/prog/board.cpp create mode 100644 src/prog/board.h create mode 100644 src/prog/types.cpp create mode 100644 src/prog/types.h create mode 100644 src/server/log.cpp create mode 100644 src/server/log.h create mode 100644 tools/server.py create mode 100644 tools/wslim.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 7738792f..c48161d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ project(Thrones LANGUAGES CXX) if(CMAKE_CONFIGURATION_TYPES) set(CMAKE_CONFIGURATION_TYPES "Debug" "Release") endif() +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) # target names and source/resource files @@ -22,12 +25,14 @@ set(ASSET_DAT "rsc/data/thrones.png") set(ASSET_MTL - "rsc/materials/regular.mtl") + "rsc/materials/misc.mtl" + "rsc/materials/pieces.mtl" + "rsc/materials/tiles.mtl") set(ASSET_OBJ "rsc/objects/breached.obj" "rsc/objects/catapult.obj" - "rsc/objects/crossbowman.obj" + "rsc/objects/crossbowmen.obj" "rsc/objects/dragon.obj" "rsc/objects/elephant.obj" "rsc/objects/fortress.obj" @@ -35,9 +40,9 @@ set(ASSET_OBJ "rsc/objects/lancer.obj" "rsc/objects/outline.obj" "rsc/objects/plane.obj" - "rsc/objects/ranger.obj" + "rsc/objects/rangers.obj" "rsc/objects/screen.obj" - "rsc/objects/spearman.obj" + "rsc/objects/spearmen.obj" "rsc/objects/table.obj" "rsc/objects/throne.obj" "rsc/objects/tile.obj" @@ -54,20 +59,26 @@ set(ASSET_SHD "rsc/shaders/gui.vert") set(ASSET_IMG + "rsc/textures/assault.png" "rsc/textures/catapult.png" - "rsc/textures/crossbowman.png" + #"rsc/textures/city.png" + "rsc/textures/conspire.png" + "rsc/textures/crossbowmen.png" "rsc/textures/crosshair.png" + "rsc/textures/deceive.png" "rsc/textures/dragon.png" "rsc/textures/elephant.png" + #"rsc/textures/farm.png" "rsc/textures/forest.png" "rsc/textures/fortress.png" "rsc/textures/grass.png" + "rsc/textures/hasten.png" "rsc/textures/lancer.png" + "rsc/textures/spearmen.png" "rsc/textures/mountain.png" "rsc/textures/plains.png" - "rsc/textures/ranger.png" + "rsc/textures/rangers.png" "rsc/textures/rock.png" - "rsc/textures/spearman.png" "rsc/textures/throne.png" "rsc/textures/title.png" "rsc/textures/trebuchet.png" @@ -92,6 +103,8 @@ set(THRONES_SRC "src/engine/world.h" "src/oven/oven.cpp" "src/oven/oven.h" + "src/prog/board.cpp" + "src/prog/board.h" "src/prog/game.cpp" "src/prog/game.h" "src/prog/netcp.cpp" @@ -100,6 +113,8 @@ set(THRONES_SRC "src/prog/program.h" "src/prog/progs.cpp" "src/prog/progs.h" + "src/prog/types.cpp" + "src/prog/types.h" "src/server/common.h" "src/server/server.cpp" "src/server/server.h" @@ -115,6 +130,7 @@ set(THRONES_SRC "src/utils/utils.h" "src/utils/widgets.cpp" "src/utils/widgets.h") + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") list(APPEND THRONES_SRC "rsc/thrones.rc") endif() @@ -122,6 +138,8 @@ list(APPEND THRONES_SRC ${ASSET_SHD}) set(SERVER_SRC "src/server/common.h" + "src/server/log.cpp" + "src/server/log.h" "src/server/server.cpp" "src/server/server.h" "src/server/serverProg.cpp" @@ -140,21 +158,16 @@ set(OVEN_SRC # dependencies -if(NOT VER_SDL) - set(VER_SDL "2.0.10") -endif() -if(NOT VER_IMG) - set(VER_IMG "2.0.5") -endif() -if(NOT VER_TTF) - set(VER_TTF "2.0.15") -endif() -if(NOT VER_GLEW) - set(VER_GLEW "2.1.0") -endif() -if(NOT VER_GLM) - set(VER_GLM "0.9.9.7") -endif() +option(EXTERNAL "Save settings externally." OFF) +option(OPENGLES "Build for OpenGL ES. (always on with Emscripten)" OFF) +option(SERVICE "Build server without keyboard input." OFF) + +set(VER_SDL "2.0.12" CACHE STRING "SDL2 version.") +set(VER_IMG "2.0.5" CACHE STRING "SDL2_image version.") +set(VER_TTF "2.0.15" CACHE STRING "SDL2_ttf version.") +set(VER_GLEW "2.1.0" CACHE STRING "GLEW version.") +set(VER_GLM "0.9.9.8" CACHE STRING "glm version.") +set(VER_CURL "7.71.1" CACHE STRING "libcurl version.") set(DIR_LIB "${CMAKE_SOURCE_DIR}/lib") set(DIR_RSC "${CMAKE_SOURCE_DIR}/rsc") @@ -173,11 +186,11 @@ function(downloadLib URL DST LIBDIR) file(DOWNLOAD "${URL}" "${DST}/${FILE}") endif() - if(FILE MATCHES ".zip$") + if(FILE MATCHES "\.zip$") execute_process(COMMAND "${CMAKE_COMMAND}" -E tar xf "${FILE}" WORKING_DIRECTORY "${DST}") - elseif(FILE MATCHES ".tar.gz$") + elseif(FILE MATCHES "\.(tar\.gz|tgz)$") execute_process(COMMAND "${CMAKE_COMMAND}" -E tar xzf "${FILE}" WORKING_DIRECTORY "${DST}") - elseif(FILE MATCHES ".dmg$") + elseif(FILE MATCHES "\.dmg$") execute_process(COMMAND hdiutil attach "${DST}/${FILE}") string(FIND "${FILE}" "-" FID) string(SUBSTRING "${FILE}" 0 ${FID} FNAME) @@ -204,20 +217,21 @@ include_directories("${CMAKE_SOURCE_DIR}/src" "${DIR_LIB}/glm") if(EMSCRIPTEN) file(COPY "${DIR_RSC}/thrones.html" DESTINATION "${CMAKE_BINARY_DIR}") elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + if(MSVC) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(VMACHINE "x64") + else() + set(VMACHINE "x86") + endif() set(DIR_SDL "${DIR_LIB}/SDL2-${VER_SDL}") set(DIR_IMG "${DIR_LIB}/SDL2_image-${VER_IMG}") set(DIR_TTF "${DIR_LIB}/SDL2_ttf-${VER_TTF}") set(DIR_GLEW "${DIR_LIB}/glew-${VER_GLEW}") - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(BIN_SDL "${DIR_SDL}/lib/x64") - set(BIN_IMG "${DIR_IMG}/lib/x64") - set(BIN_TTF "${DIR_TTF}/lib/x64") - else() - set(BIN_SDL "${DIR_SDL}/lib/x86") - set(BIN_IMG "${DIR_IMG}/lib/x86") - set(BIN_TTF "${DIR_TTF}/lib/x86") - endif() + set(DIR_CURL "${DIR_LIB}/curl-${VER_CURL}") + set(BIN_SDL "${DIR_SDL}/lib/${VMACHINE}") + set(BIN_IMG "${DIR_IMG}/lib/${VMACHINE}") + set(BIN_TTF "${DIR_TTF}/lib/${VMACHINE}") + set(BIN_CURL "${DIR_CURL}/builds/libcurl-vc-${VMACHINE}-release-dll-ipv6-sspi-winssl/bin") set(LIB_SDL "${BIN_SDL}") set(LIB_IMG "${BIN_IMG}") set(LIB_TTF "${BIN_TTF}") @@ -226,34 +240,43 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") else() set(LIB_GLEW "${DIR_GLEW}/lib/Release/Win32") endif() + set(LIB_CURL "${DIR_CURL}/builds/libcurl-vc-${VMACHINE}-release-dll-ipv6-sspi-winssl/lib") set(INC_SDL "${DIR_SDL}/include") set(INC_IMG "${DIR_IMG}/include") set(INC_TTF "${DIR_TTF}/include") + set(INC_CURL "${DIR_CURL}/builds/libcurl-vc-${VMACHINE}-release-dll-ipv6-sspi-winssl/include") set(URL_SDL "https://www.libsdl.org/release/SDL2-devel-${VER_SDL}-VC.zip") set(URL_IMG "https://www.libsdl.org/projects/SDL_image/release/SDL2_image-devel-${VER_IMG}-VC.zip") set(URL_TTF "https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-devel-${VER_TTF}-VC.zip") set(URL_GLEW "https://netix.dl.sourceforge.net/project/glew/glew/2.1.0/glew-${VER_GLEW}-win32.zip") + set(URL_CURL "https://curl.haxx.se/download/curl-${VER_CURL}.zip") else() if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(DIR_SDL "${DIR_LIB}/SDL2-${VER_SDL}/x86_64-w64-mingw32") set(DIR_IMG "${DIR_LIB}/SDL2_image-${VER_IMG}/x86_64-w64-mingw32") set(DIR_TTF "${DIR_LIB}/SDL2_ttf-${VER_TTF}/x86_64-w64-mingw32") + set(VMACHINE "win64") else() set(DIR_SDL "${DIR_LIB}/SDL2-${VER_SDL}/i686-w64-mingw32") set(DIR_IMG "${DIR_LIB}/SDL2-image-${VER_IMG}/i686-w64-mingw32") set(DIR_TTF "${DIR_LIB}/SDL2_ttf-${VER_TTF}/i686-w64-mingw32") + set(VMACHINE "win32") endif() set(DIR_GLEW "${DIR_LIB}/glew-${VER_GLEW}") + set(DIR_CURL "${DIR_LIB}/curl-${VER_CURL}-${VMACHINE}-mingw") set(BIN_SDL "${DIR_SDL}/bin") set(BIN_IMG "${DIR_IMG}/bin") set(BIN_TTF "${DIR_TTF}/bin") + set(BIN_CURL "${DIR_CURL}/bin") set(LIB_SDL "${DIR_SDL}/lib") set(LIB_IMG "${DIR_IMG}/lib") set(LIB_TTF "${DIR_TTF}/lib") set(LIB_GLEW "${DIR_GLEW}/lib") + set(LIB_CURL "${DIR_CURL}/lib") set(INC_SDL "${DIR_SDL}/include/SDL2") set(INC_IMG "${DIR_IMG}/include/SDL2") set(INC_TTF "${DIR_TTF}/include/SDL2") + set(INC_CURL "${DIR_CURL}/include") set(URL_SDL "https://www.libsdl.org/release/SDL2-devel-${VER_SDL}-mingw.tar.gz") set(URL_IMG "https://www.libsdl.org/projects/SDL_image/release/SDL2_image-devel-${VER_IMG}-mingw.tar.gz") set(URL_TTF "https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-devel-${VER_TTF}-mingw.tar.gz") @@ -262,14 +285,24 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") else() set(URL_GLEW "http://www.grhmedia.com/glew/glew-${VER_GLEW}-mingw.zip") endif() + set(URL_CURL "https://curl.haxx.se/windows/dl-${VER_CURL}/curl-${VER_CURL}-${VMACHINE}-mingw.zip") endif() + downloadLib("${URL_SDL}" "${DIR_LIB}" "${DIR_SDL}") downloadLib("${URL_IMG}" "${DIR_LIB}" "${DIR_IMG}") downloadLib("${URL_TTF}" "${DIR_LIB}" "${DIR_TTF}") downloadLib("${URL_GLEW}" "${DIR_LIB}" "${DIR_GLEW}") + if(MSVC) + if(NOT EXISTS "${DIR_CURL}") + downloadLib("${URL_CURL}" "${DIR_LIB}" "${DIR_CURL}") + execute_process(COMMAND nmake /f Makefile.vc mode=dll MACHINE=${VMACHINE} WORKING_DIRECTORY "${DIR_CURL}/winbuild") + endif() + else() + downloadLib("${URL_CURL}" "${DIR_LIB}" "${DIR_CURL}") + endif() - link_directories("${LIB_SDL}" "${LIB_IMG}" "${LIB_TTF}" "${LIB_GLEW}") - include_directories("${INC_SDL}" "${INC_IMG}" "${INC_TTF}" "${DIR_GLEW}/include") + link_directories("${LIB_SDL}" "${LIB_IMG}" "${LIB_TTF}" "${LIB_GLEW}" "${LIB_CURL}") + include_directories("${INC_SDL}" "${INC_IMG}" "${INC_TTF}" "${DIR_GLEW}/include" "${INC_CURL}") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") downloadLib("https://www.libsdl.org/release/SDL2-${VER_SDL}.dmg" "${DIR_LIB}" "SDL2.framework") downloadLib("https://www.libsdl.org/projects/SDL_image/release/SDL2_image-${VER_IMG}.dmg" "${DIR_LIB}" "SDL2_image.framework") @@ -279,6 +312,15 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") find_library(LIB_IMG "SDL2_image" HINTS "${DIR_LIB}") find_library(LIB_TTF "SDL2_ttf" HINTS "${DIR_LIB}") find_library(LIB_OPENGL "OpenGL") +elseif(NOT OPENGLES) + set(DIR_GLEW "${DIR_LIB}/glew-${VER_GLEW}") + if(NOT EXISTS "${DIR_GLEW}") + downloadLib("https://sourceforge.net/projects/glew/files/glew/${VER_GLEW}/glew-${VER_GLEW}.tgz" "${DIR_LIB}" "${DIR_GLEW}") + execute_process(COMMAND make glew.lib.static WORKING_DIRECTORY "${DIR_GLEW}") + endif() + + link_directories("${DIR_GLEW}/lib") + include_directories("${DIR_GLEW}/include") endif() set(DIR_PAND "${CMAKE_SOURCE_DIR}/android") @@ -335,56 +377,73 @@ else() add_definitions(-DNDEBUG) endif() -set(CXX_COMMON_WARNINGS "-Wno-implicit-fallthrough -Wno-float-equal -Wno-parentheses -Wno-shadow -Wno-shadow-field -Wno-switch -Wno-switch-enum -Wno-unused-private-field -Wno-unused-result") -if(EMSCRIPTEN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --preload-file ${CMAKE_BINARY_DIR}/data@/ -s TOTAL_MEMORY=536870912 -s WASM=1 -s USE_WEBGL2=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='[\"jpg\",\"png\"]' -s USE_SDL_TTF=2 -lidbfs.js -Wall -Wextra -Wpedantic -Wno-gnu-zero-variadic-macro-arguments -Wno-unused-parameter ${CXX_COMMON_WARNINGS}") - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g4 -s DISABLE_EXCEPTION_CATCHING=0") +if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) + set(CXX_FLG_ANY "-Wall -Wextra -pedantic-errors -Wdouble-promotion -Wformat=2 -Wmissing-declarations -Wold-style-cast -Wshadow -Wunreachable-code -Wno-implicit-fallthrough -Wno-parentheses -Wno-switch") + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CXX_FLG_ANY "${CXX_FLG_ANY} -Wcast-align=strict -Wduplicated-cond") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") - endif() -elseif((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) - set(FLG_ANY "-fno-pie -no-pie -fno-stack-protector ${CXX_COMMON_WARNINGS}") - set(FLG_DEBUG "-g") - set(FLG_RELEASE "-O3 -s -Wno-padded") - if(OPENGLES) - set(FLG_ANY "${FLG_ANY} -Wno-unused-parameter") + set(CXX_FLG_ANY "${CXX_FLG_ANY} -Wcast-align -Wnull-dereference -Wover-aligned -Wshadow-all -Wno-unused-private-field") endif() - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(FLG_ANY "${FLG_ANY} -Wall -Wextra -Wpedantic") - else() - set(FLG_ANY "${FLG_ANY} -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-covered-switch-default -Wno-exit-time-destructors -Wno-global-constructors -Wno-unused-command-line-argument") + if(OPENGLES) + set(CXX_FLG_ANY "${CXX_FLG_ANY} -Wno-unused-parameter") endif() if(ARCH) - set(FLG_ANY "${FLG_ANY} -m${ARCH}") + set(CXX_FLG_ANY "${CXX_FLG_ANY} -m${ARCH}") endif() - if(CMAKE_CONFIGURATION_TYPES) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLG_ANY} ${FLG_DEBUG}") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLG_ANY} ${FLG_RELEASE}") - elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLG_ANY} ${FLG_DEBUG}") + if(EMSCRIPTEN) + set(CXX_FLG_ANY "${CXX_FLG_ANY} --preload-file ${CMAKE_BINARY_DIR}/data@/ -s TOTAL_MEMORY=536870912 -s WASM=1 -s USE_WEBGL2=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='[\"jpg\",\"png\"]' -s USE_SDL_TTF=2 -s FETCH=1 -s DISABLE_EXCEPTION_CATCHING=0 -s DYNAMIC_EXECUTION=1 -lidbfs.js -Wno-gnu-zero-variadic-macro-arguments -Wno-unused-parameter -Wno-unused-variable") + set(FLG_DEBUG "-g4 -s ASSERTIONS=2 -s STACK_OVERFLOW_CHECK=2 -s SAFE_HEAP=1 -s DEMANGLE_SUPPORT=1") + set(FLG_RELEASE "-O3") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLG_ANY} ${FLG_RELEASE}") + set(FLG_DEBUG "-g") + set(FLG_RELEASE "-O3") + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(FLG_RELEASE "${FLG_RELEASE} -s") + endif() endif() +elseif(MSVC) + set(CXX_FLG_ANY "/W4 /wd4100 /wd4201 /wd4244 /wd4458 /wd4706 /wd4805") + set(FLG_DEBUG "/Od /Ob0") + set(FLG_RELEASE "/O2 /Ob2 /Oi /Ot /GL") +endif() + +if(CMAKE_CONFIGURATION_TYPES) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CXX_FLG_ANY} ${FLG_DEBUG}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_FLG_ANY} ${FLG_RELEASE}") +elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLG_ANY} ${FLG_DEBUG}") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLG_ANY} ${FLG_RELEASE}") endif() # main target +if((NOT EMSCRIPTEN) AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")) + find_program(STRIPPER "strip") +endif() + function(setCommonTargetProperties TARGET_NAME OUT_DIR) set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${OUT_DIR}" RUNTIME_OUTPUT_DIRECTORY_DEBUG "${OUT_DIR}" RUNTIME_OUTPUT_DIRECTORY_RELEASE "${OUT_DIR}") - if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") - string(TOLOWER ${TARGET_NAME} TARGET_NAME_LOWER) - set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${TARGET_NAME_LOWER}) + + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(TEXE_NAME ${TARGET_NAME}) + else() + string(TOLOWER ${TARGET_NAME} TEXE_NAME) + set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${TEXE_NAME}) + endif() + + if(STRIPPER) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND "${STRIPPER}" -s "${OUT_DIR}/${TEXE_NAME}") endif() endfunction() add_executable(${PROJECT_NAME} WIN32 ${THRONES_SRC}) -target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17) if(EMSCRIPTEN) setCommonTargetProperties(${PROJECT_NAME} "${CMAKE_BINARY_DIR}") return() @@ -410,22 +469,23 @@ else() target_link_libraries(${PROJECT_NAME} SDL2 SDL2_image SDL2_ttf) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - target_link_libraries(${PROJECT_NAME} glew32s glu32 opengl32 ws2_32) + target_link_libraries(${PROJECT_NAME} glew32s opengl32 libcurl ws2_32) elseif(OPENGLES) - target_link_libraries(${PROJECT_NAME} GLESv2) + target_link_libraries(${PROJECT_NAME} GLESv2 curl) else() - target_link_libraries(${PROJECT_NAME} GLEW GLU GL) + target_link_libraries(${PROJECT_NAME} GLEW GL curl) endif() + add_definitions(-DWEBUTILS) setCommonTargetProperties(${PROJECT_NAME} "${EXE_DIR}") endif() # game data copier targets -function(addDataCopierTarget TARGET_NAME TEXTRA DST OPT_SHD OPT_IMG SINGLE_FILES) +function(addDataCopierTarget TARGET_NAME TEXTRA DST OPT_AUD OPT_SHD OPT_IMG SINGLE_FILES) add_custom_target(${TARGET_NAME} ${TEXTRA} SOURCES ${DATA_SRC} COMMAND "${CMAKE_COMMAND}" -E make_directory "${DST}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${SINGLE_FILES} "${DST}" - COMMAND "${EXE_DIR}/${OVEN_NAME}" -a "${DST}/audio.dat" ${ASSET_WAV} + COMMAND "${EXE_DIR}/${OVEN_NAME}" ${OPT_AUD} "${DST}/audio.dat" ${ASSET_WAV} COMMAND "${EXE_DIR}/${OVEN_NAME}" -m "${DST}/materials.dat" ${ASSET_MTL} COMMAND "${EXE_DIR}/${OVEN_NAME}" -o "${DST}/objects.dat" ${ASSET_OBJ} COMMAND "${EXE_DIR}/${OVEN_NAME}" ${OPT_SHD} "${DST}/shaders.dat" ${ASSET_SHD} @@ -435,28 +495,23 @@ function(addDataCopierTarget TARGET_NAME TEXTRA DST OPT_SHD OPT_IMG SINGLE_FILES endfunction() if(OPENGLES) - addDataCopierTarget(${DATA_NAME} "ALL" "${DATA_DIR}" "-S" "-T" "${ASSET_DAT}") + addDataCopierTarget(${DATA_NAME} "ALL" "${DATA_DIR}" "-A" "-S" "-T" "${ASSET_DAT}") else() - addDataCopierTarget(${DATA_NAME} "ALL" "${DATA_DIR}" "-s" "-t" "${ASSET_DAT}") + addDataCopierTarget(${DATA_NAME} "ALL" "${DATA_DIR}" "-a" "-s" "-t" "${ASSET_DAT}") endif() -addDataCopierTarget(${ADATA_NAME} "" "${DIR_PAND}/app/src/main/assets" "-S" "-T" "rsc/data/romanesque.ttf;rsc/data/merriweather.otf") +addDataCopierTarget(${ADATA_NAME} "" "${DIR_PAND}/app/src/main/assets" "-A" "-S" "-T" "rsc/data/romanesque.ttf;rsc/data/merriweather.otf") # server program target add_executable(${SERVER_NAME} ${SERVER_SRC}) -target_compile_features(${SERVER_NAME} PUBLIC cxx_std_17) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") target_link_libraries(${SERVER_NAME} ws2_32) -elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - target_link_libraries(${SERVER_NAME} "${LIB_SDL}") endif() setCommonTargetProperties(${SERVER_NAME} "${EXE_DIR}") # asset building program target add_executable(${OVEN_NAME} ${OVEN_SRC}) -target_compile_features(${OVEN_NAME} PUBLIC cxx_std_17) - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") target_link_libraries(${OVEN_NAME} "${LIB_SDL}" "${LIB_IMG}") else() @@ -470,14 +525,15 @@ add_custom_command(TARGET ${OVEN_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_LIB}/glm/copying.txt" "${LICN_DIR}/COPYING.glm.txt") if(CMAKE_SYSTEM_NAME STREQUAL "Windows") add_custom_command(TARGET ${OVEN_NAME} POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${BIN_SDL}/SDL2.dll" "${BIN_IMG}/SDL2_image.dll" "${BIN_TTF}/SDL2_ttf.dll" "${BIN_IMG}/libjpeg-9.dll" "${BIN_IMG}/libpng16-16.dll" "${BIN_TTF}/libfreetype-6.dll" "${BIN_TTF}/zlib1.dll" "${EXE_DIR}" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${BIN_SDL}/SDL2.dll" "${BIN_IMG}/SDL2_image.dll" "${BIN_TTF}/SDL2_ttf.dll" "${BIN_IMG}/libjpeg-9.dll" "${BIN_IMG}/libpng16-16.dll" "${BIN_TTF}/libfreetype-6.dll" "${BIN_TTF}/zlib1.dll" "${BIN_CURL}/libcurl.dll" "${EXE_DIR}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_SDL}/COPYING.txt" "${LICN_DIR}/COPYING.SDL.txt" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_IMG}/COPYING.txt" "${LICN_DIR}/COPYING.SDL_image.txt" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_TTF}/COPYING.txt" "${LICN_DIR}/COPYING.SDL_ttf.txt" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_GLEW}/LICENSE.txt" "${LICN_DIR}/LICENSE.glew.txt" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${BIN_IMG}/LICENSE.png.txt" "${LICN_DIR}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${BIN_TTF}/LICENSE.freetype.txt" "${LICN_DIR}" - COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${BIN_TTF}/LICENSE.zlib.txt" "${LICN_DIR}") + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${BIN_TTF}/LICENSE.zlib.txt" "${LICN_DIR}" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_CURL}/COPYING" "${LICN_DIR}/COPYING.curl.txt") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_custom_command(TARGET ${OVEN_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${FRAM_DIR}/${FRAM_SDL}" "${FRAM_DIR}/${FRAM_TTF}" @@ -487,6 +543,10 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_RSC}/Info.plist" "${APP_DIR}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_RSC}/thrones.icns" "${DATA_DIR}") else() + if(NOT OPENGLES) + add_custom_command(TARGET ${OVEN_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_GLEW}/LICENSE.txt" "${LICN_DIR}/LICENSE.glew.txt") + endif() add_custom_command(TARGET ${OVEN_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${DIR_RSC}/thrones.desktop" "${EXE_DIR}") endif() diff --git a/README.md b/README.md index 153c01ff..9fc2c611 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Based on the board game by Chad Anthony Randell. See [RULES](doc/rules.html) or [DOCS](doc/docs.html) for details. ## Build -Used libraries are GLEW, GLM, SDL2, SDL2_image, SDL2_ttf and by extension FreeType, libjpeg, libpng and zlib. The included fonts are Romanesque Serif Regular and Merriweather Regular. +Used libraries are libcurl, GLEW, GLM, SDL2, SDL2_image, SDL2_ttf and by extension FreeType, libjpeg, libpng and zlib. The included fonts are Romanesque Serif Regular and Merriweather Regular. The CMakeLists.txt is written for CMake 3.10.2 with Clang, GCC or MSVC which need to support C++17. CMake variables: @@ -19,11 +19,13 @@ CMake variables: - use OpenGL ES - SERVICE : bool = 0 - server program won't check keyboard input +- VER_CURL : string = 7.71.1 + - libcurl version to download - VER_GLEW : string = 2.1.0 - GLEW version to download -- VER_GLM : string = 0.9.9.7 +- VER_GLM : string = 0.9.9.8 - GLM version to download -- VER_SDL : string = 2.0.10 +- VER_SDL : string = 2.0.12 - SDL version to download - VER_IMG : string = 2.0.5 - SDL_image version to download @@ -34,6 +36,7 @@ CMake variables: The "android" directory can be imported in Android Studio as a project, which builds only the game client. To install the necessary additional files, run CMake with the "-DLIBDROID=1" option. Next the CMake target "assets_android" needs to be built separately, which will create the assets in "android/app/src/main/assets". The requirements for this are as listed for the other systems. +It might be necessary to set the NDK location, which can be done in Android Studio under "File -> Project Structure -> SDK Location -> Android NDK Location". If you're on Windows, make sure that your Git supports symbolic links or check that "android/app/jni/src" contains the files of "src". ### Emscripten @@ -41,8 +44,8 @@ A makefile with a target for the game client can be created with the CMake file, Before building the program, the assets for OpenGL ES need to be built, using the method below and the created "data" directory has to be copied to the directory of the makefile for the Emscripten build. ### Linux -The only supported compilers are Clang and GCC. All dependencies need to be installed manually. -Installing the development packages for the listed libraries should be enough, assuming that all necessary dependencies are installed automatically. +The only supported compilers are Clang and GCC. +GLEW and GLM are downloaded and built while running CMake. SDL2, SDL2_image, SDL2_ttf and libcurl need to be installed manually. To create a menu entry for the game client, you can use the "rsc/thrones.desktop" launcher file. When building the game client on a Raspberry Pi, the CMake option "-DOPENGLES=1" should be set. @@ -50,10 +53,13 @@ When building the game client on a Raspberry Pi, the CMake option "-DOPENGLES=1" All necessary dependencies are downloaded when running CMake. ### Windows -The only supported compilers are MSVC and MinGW. All necessary libraries are downloaded when running CMake. +All necessary libraries are downloaded and built with NMake while running CMake. Because of that you need to run CMake through the developer console or have NMake set up in the Path. +The only supported compiler is MSVC. MinGW might also work, but hasn't been tested yet. ## TODO -- message for not firing over mountains -- the overlays suck +- in emscripten there's an exception thrown somewhere +- homefront +- victory points +- windows server doesn't send rejections properly - shadows aren't working properly on some systems diff --git a/android/app/build.gradle b/android/app/build.gradle index b570ab54..7e6b3ebc 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,13 +7,13 @@ if (buildAsApplication) { } android { - compileSdkVersion 29 + compileSdkVersion 30 defaultConfig { if (buildAsApplication) { applicationId "org.duravia.thrones" } minSdkVersion 19 - targetSdkVersion 29 + targetSdkVersion 30 versionCode 4 versionName "0.5.0" externalNativeBuild { diff --git a/android/app/jni/src/Android.mk b/android/app/jni/src/Android.mk index c67630b2..bfc3ff76 100644 --- a/android/app/jni/src/Android.mk +++ b/android/app/jni/src/Android.mk @@ -4,7 +4,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := main SDL_PATH := ../SDL LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include $(LOCAL_PATH)/../glm -LOCAL_SRC_FILES := engine/audioSys.cpp engine/inputSys.cpp engine/fileSys.cpp engine/scene.cpp engine/windowSys.cpp engine/world.cpp oven/oven.cpp prog/game.cpp prog/netcp.cpp prog/program.cpp prog/progs.cpp server/server.cpp utils/context.cpp utils/layouts.cpp utils/objects.cpp utils/text.cpp utils/utils.cpp utils/widgets.cpp +LOCAL_SRC_FILES := engine/audioSys.cpp engine/inputSys.cpp engine/fileSys.cpp engine/scene.cpp engine/windowSys.cpp engine/world.cpp oven/oven.cpp prog/board.cpp prog/game.cpp prog/netcp.cpp prog/program.cpp prog/progs.cpp prog/types.cpp server/server.cpp utils/context.cpp utils/layouts.cpp utils/objects.cpp utils/text.cpp utils/utils.cpp utils/widgets.cpp LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_ttf LOCAL_LDLIBS := -lGLESv3 -llog include $(BUILD_SHARED_LIBRARY) diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..5119edc56da2ba3944ae50c75620520a847bf1cc GIT binary patch literal 3199 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 Efh;=~jY`WCWg)c* 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 Dw?s|j literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..7131696b9a0ee4bd67ab76227726da21e891f39b GIT binary patch literal 12986 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