diff --git a/CMakeLists.txt b/CMakeLists.txt index 125a07b45..07edf8773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,121 +1,156 @@ -cmake_minimum_required (VERSION 2.6) -project(keeper) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# set default cxxflags -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++1y -Wno-sign-compare -Wno-unused-variable -Wno-shift-count-overflow -ftemplate-depth=512 -DUSE_STEAMWORKS -I /home/michal/keeperrl/extern/steamworks/public") -# clang specific cflags -if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-tautological-constant-out-of-range-compare -Wno-mismatched-tags") -endif() +cmake_minimum_required(VERSION 3.14) -set(STDAFX_H "${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h") -set(STDAFX_H_GCH "${CMAKE_CURRENT_BINARY_DIR}/stdagx.h.gch") +set(BUILD_SHARED_LIBS off) +set(BUILD_STATIC_LIBS on) +set(BUILD_CURL_EXE off) +set(BUILD_LIBCURL_DOCS off) -# set debug cxxflags -set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wimplicit-fallthrough -Wno-unused-function") -#if ((${CMAKE_BUILD_TYPE} MATCHES "Debug") AND (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")) -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld -L ${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/redistributable_bin/linux64/ -L /usr/local/lib -lsteam_api -Wl,-rpath=. -Wl,--gdb-index") - #endif() +project(KeeperRL) -# additional cmake modules directory -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED on) -# find required libraries -find_package(SDL2 REQUIRED) -find_package(SDL2_image REQUIRED) -find_package(OpenGL REQUIRED) -if(APPLE) - # assume built-in pthreads on MacOS - set(CMAKE_THREAD_LIBS_INIT "-lpthread") - set(CMAKE_HAVE_THREADS_LIBRARY 1) - set(CMAKE_USE_WIN32_THREADS_INIT 0) - set(CMAKE_USE_PTHREADS_INIT 1) - set(THREADS_PREFER_PTHREAD_FLAG ON) +option(ENABLE_STEAMWORKS "Enable steamworks integration" ON) +option(BUILD_ALSOFT "Build OpenAL-soft from source instead of using regular OpenAL" OFF) + +add_compile_options("$<$:/utf-8>") + +if(ENABLE_STEAMWORKS) + add_library(steamworks SHARED IMPORTED) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set_target_properties(steamworks PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/redistributable_bin/win64/steam_api64.dll") + set_target_properties(steamworks PROPERTIES IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/redistributable_bin/win64/steam_api64.lib") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/redistributable_bin/win64/steam_api64.dll" TYPE BIN) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set_target_properties(steamworks PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/redistributable_bin/linux64/libsteam_api.so") + endif() + target_include_directories(steamworks INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/public") +endif() + +include(FetchContent) + +set(OGG_LIBRARY ogg) +set(OGG_INCLUDE_DIR "dummy") + +if(BUILD_ALSOFT) + FetchContent_Declare(ALSOFT GIT_REPOSITORY https://github.com/kcat/openal-soft GIT_TAG 1.23.1) + set(ALSOFT_DECL ALSOFT) + set(OPENAL_LIBRARY OpenAL) + unset(OPENAL_INCLUDE_DIR CACHE) else() - find_package(Threads REQUIRED) + find_package(OpenAL REQUIRED) endif() -find_package(CURL REQUIRED) -find_package(ZLIB REQUIRED) -find_package(OpenAL REQUIRED) -find_package(Vorbis REQUIRED) -find_package(Ogg REQUIRED) -find_package(VorbisFile REQUIRED) -find_package(THEORA REQUIRED) + +FetchContent_Declare(SDL2 GIT_REPOSITORY https://github.com/libsdl-org/SDL GIT_TAG release-2.30.1 EXCLUDE_FROM_ALL) +FetchContent_Declare(SDL2_image GIT_REPOSITORY https://github.com/libsdl-org/SDL_image GIT_TAG release-2.8.2 EXCLUDE_FROM_ALL) +FetchContent_Declare(CURL GIT_REPOSITORY https://github.com/curl/curl GIT_TAG curl-8_6_0 EXCLUDE_FROM_ALL) +FetchContent_Declare(ZLIB GIT_REPOSITORY https://github.com/madler/zlib GIT_TAG v1.3.1 EXCLUDE_FROM_ALL) +FetchContent_Declare(OGG GIT_REPOSITORY https://github.com/xiph/ogg GIT_TAG v1.3.5 EXCLUDE_FROM_ALL) +FetchContent_Declare(VORBIS GIT_REPOSITORY https://github.com/xiph/vorbis GIT_TAG v1.3.7 EXCLUDE_FROM_ALL) +FetchContent_Declare(THEORA GIT_REPOSITORY https://github.com/xiph/theora GIT_TAG v1.2.0alpha1 EXCLUDE_FROM_ALL) +FetchContent_MakeAvailable(SDL2 SDL2_image CURL ZLIB OGG VORBIS THEORA ${ALSOFT_DECL}) + +find_package(OpenGL REQUIRED) + +add_library( + theoradec + "${theora_SOURCE_DIR}/lib/apiwrapper.c" + "${theora_SOURCE_DIR}/lib/bitpack.c" "${theora_SOURCE_DIR}/lib/dequant.c" + "${theora_SOURCE_DIR}/lib/fragment.c" "${theora_SOURCE_DIR}/lib/idct.c" + "${theora_SOURCE_DIR}/lib/info.c" "${theora_SOURCE_DIR}/lib/internal.c" + "${theora_SOURCE_DIR}/lib/state.c" "${theora_SOURCE_DIR}/lib/quant.c" + "${theora_SOURCE_DIR}/lib/decapiwrapper.c" "${theora_SOURCE_DIR}/lib/decinfo.c" + "${theora_SOURCE_DIR}/lib/decode.c" "${theora_SOURCE_DIR}/lib/huffdec.c" +) +target_link_libraries(theoradec PRIVATE ogg) +target_include_directories(theoradec PUBLIC ${theora_SOURCE_DIR}/include) # generate version.h -file(GLOB GENERATE_VERSION_SH "gen_version.sh") set(KEEPER_VERSION_H "${CMAKE_CURRENT_SOURCE_DIR}/version.h") -add_custom_command( - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/ - COMMAND ${GENERATE_VERSION_SH} - DEPENDS ${GENERATE_VERSION_SH} - OUTPUT ${KEEPER_VERSION_H} - COMMENT "Generating version.h" +string(TIMESTAMP BUILD_DATE "%Y-%m-%d") +execute_process(COMMAND git describe --abbrev=4 --dirty --always OUTPUT_VARIABLE GIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE) +configure_file( + ${KEEPER_VERSION_H}.in + ${KEEPER_VERSION_H} + @ONLY ) -# check member serialization -# the stamp file is not actually generated, but it doesn't seem to matter -file(GLOB CHECK_SERIAL_SH "check_serial.sh") -set(CHECK_SERIAL_STAMP "${CMAKE_CURRENT_SOURCE_DIR}/check_serial.stamp") -add_custom_command( - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/ - COMMAND bash ${CHECK_SERIAL_SH} - DEPENDS ${CHECK_SERIAL_SH} - OUTPUT ${CHECK_SERIAL_STAMP} - COMMENT "Checking serialization" +file(GLOB KEEPER_SOURCES "*.cpp" "extern/*.cpp") +add_executable( + keeper + ${KEEPER_SOURCES} + ${KEEPER_VERSION_H} ) - -# rules to create `keeper` binary -file(GLOB SOURCES "*.cpp" "extern/*.cpp") -add_executable(keeper ${SOURCES} ${KEEPER_VERSION_H} ${CHECK_SERIAL_STAMP}) target_include_directories(keeper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(keeper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/extern) -target_include_directories(keeper PRIVATE ${SDL2_INCLUDE_DIRS}) -target_link_libraries(keeper PRIVATE - ${SDL2_LIBRARIES} - ${SDL2_IMAGE_LIBRARY} - ${OPENGL_gl_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${CURL_LIBRARIES} - ${ZLIB_LIBRARIES} +target_include_directories(keeper PRIVATE ${sdl2_image_SOURCE_DIR}/include ${theora_SOURCE_DIR}/include ${OPENAL_INCLUDE_DIR}) +target_link_libraries( + keeper + PRIVATE + SDL2-static + SDL2main + SDL2_image + libcurl_static + zlibstatic + ogg + vorbis + vorbisfile + theoradec + OpenGL::GL ${OPENAL_LIBRARY} - ${VORBIS_LIBRARIES} - ${OGG_LIBRARIES} - ${THEORA_dec_LIBRARY} - ${VorbisFile_LIBRARIES} - ) - -# set up definitions -if ((${CMAKE_BUILD_TYPE} MATCHES "Release")) - target_compile_definitions(keeper PRIVATE RELEASE=1) -else() -# generate stdafx.h.gch for debug build -# workaround to unquote the cxxflags -set(CXX_FLAGS_LIST ${CMAKE_CXX_FLAGS}) -separate_arguments(CXX_FLAGS_LIST) -add_custom_command( - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/ - COMMAND ${CMAKE_CXX_COMPILER} ${CXX_FLAGS_LIST} -x c++-header ${STDAFX_H} -MMD -o ${STDAFX_H_GCH} - DEPENDS ${STDAFX_H} - OUTPUT ${STDAFX_H_GCH} - COMMENT "Generating ${STDAFX_H_GCH}" ) -if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include-pch ${STDAFX_H_GCH}") -endif() -target_sources(keeper PRIVATE ${STDAFX_H_GCH}) -endif() +target_precompile_headers(keeper PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h") +if(ENABLE_STEAMWORKS) + target_link_libraries(keeper PRIVATE steamworks) + target_compile_definitions(keeper PRIVATE USE_STEAMWORKS) -if(ENABLE_LOCAL_USER_DIR) - target_compile_definitions(keeper PRIVATE ENABLE_LOCAL_USER_DIR=1) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + add_custom_command( + TARGET keeper + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${CMAKE_CURRENT_SOURCE_DIR}/extern/steamworks/redistributable_bin/win64/steam_api64.dll" + "$" + ) + endif() endif() -if(SANITIZE) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") -endif() -if(PROF) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + target_compile_definitions(keeper PRIVATE WINDOWS $<$:_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING>) + target_compile_options(keeper PRIVATE $<$:/w>) + target_link_libraries(keeper PRIVATE dbghelp) + target_sources(keeper PRIVATE keeper.rc) + + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set_source_files_properties( + content_factory.cpp + player_control.cpp + gui_builder.cpp + pretty_printing.cpp + task.cpp + PROPERTIES + COMPILE_FLAGS /bigobj + ) + else() + set_source_files_properties( + content_factory.cpp + player_control.cpp + gui_builder.cpp + pretty_printing.cpp + task.cpp + PROPERTIES + COMPILE_FLAGS -Wa,-mbig-obj + ) + endif() endif() -if(EASY_PROFILER) - target_compile_definitions(keeper PRIVATE EASY_PROFILER=1) - target_link_libraries(keeper PRIVATE libeasy_profiler) + +if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDbgInfo") + target_compile_definitions(keeper PRIVATE RELEASE=1) endif() + + + + +install( + TARGETS keeper + RUNTIME +) diff --git a/audio_device.cpp b/audio_device.cpp index ade2e0185..04312424f 100644 --- a/audio_device.cpp +++ b/audio_device.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" -#include -#include +#include +#include #include diff --git a/cmake/FindTHEORA.cmake b/cmake/FindTHEORA.cmake index 2a5d1f43d..a7f0dc260 100644 --- a/cmake/FindTHEORA.cmake +++ b/cmake/FindTHEORA.cmake @@ -38,7 +38,7 @@ mark_as_advanced(THEORA_dec_LIBRARY) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(THEORA - REQUIRED_VARS THEORA_LIBRARY THEORA_enc_LIBRARY THEORA_dec_LIBRARY THEORA_INCLUDE_DIR) + REQUIRED_VARS THEORA_dec_LIBRARY THEORA_INCLUDE_DIR) if (THEORA_FOUND) set(THEORA_LIBRARIES "${THEORA_LIBRARY}" "${THEORA_enc_LIBRARY}" "${THEORA_dec_LIBRARY}") diff --git a/collective.h b/collective.h index e009c7cdc..bd1325662 100644 --- a/collective.h +++ b/collective.h @@ -50,7 +50,7 @@ class CollectiveWarnings; class Immigration; class PositionMatching; class MinionActivities; -class ResourceInfo; +struct ResourceInfo; class StoragePositions; class Furnace; class Dancing; diff --git a/collective_config.cpp b/collective_config.cpp index 95d3d3e2c..da0b67cbe 100644 --- a/collective_config.cpp +++ b/collective_config.cpp @@ -95,7 +95,7 @@ void CollectiveConfig::addBedRequirementToImmigrants(vector& immi [&](const auto&) {} )); if (!hasBed) { - info.addRequirement(AttractionInfo(1, factory->furniture.getBedFurniture(*bedType)[0])); + info.addRequirement(AttractionInfo(1, AttractionType(factory->furniture.getBedFurniture(*bedType)[0]))); } } } diff --git a/content_factory.h b/content_factory.h index 4c8b7e1ee..de00bcc07 100644 --- a/content_factory.h +++ b/content_factory.h @@ -32,12 +32,12 @@ class KeyVerifier; class BuildInfo; -class ExternalEnemy; -class ResourceDistribution; -class EnemyInfo; +struct ExternalEnemy; +struct ResourceDistribution; +struct EnemyInfo; class ImmigrantInfo; -class ZLevelInfo; -class BuildingInfo; +struct ZLevelInfo; +struct BuildingInfo; struct LayoutGenerator; struct TileGasInfo; struct PromotionInfo; diff --git a/creature.cpp b/creature.cpp index 96ba91578..047a6162d 100644 --- a/creature.cpp +++ b/creature.cpp @@ -3056,7 +3056,7 @@ bool Creature::addButcheringEvent(const string& villageName) { #define CASE(VAR, ELEM, TYPE, ...) \ case std::remove_reference::type::TYPE##Tag: {\ - auto ELEM = event.getReferenceMaybe::type::TYPE>();\ + auto ELEM = event.getReferenceMaybe::type::E##TYPE>();\ __VA_ARGS__\ break;\ } diff --git a/directory_path.cpp b/directory_path.cpp index 32d8d26e9..6933a47d6 100644 --- a/directory_path.cpp +++ b/directory_path.cpp @@ -1,10 +1,15 @@ #include "stdafx.h" #include "directory_path.h" #include "file_path.h" -#include -#include -#include -#include "dirent.h" +#ifndef _MSC_VER +# include +# include +# include +# include "dirent.h" +#else +# define WIN32_LEAN_AND_MEAN +# include +#endif DirectoryPath::DirectoryPath(string p) : path(std::move(p)) { } @@ -17,6 +22,7 @@ DirectoryPath DirectoryPath::subdirectory(const std::string& s) const { return DirectoryPath(path + "/" + s); } +#ifndef _MSC_VER static bool isDirectory(const string& path) { struct stat path_stat; if (stat(path.c_str(), &path_stat)) @@ -24,6 +30,15 @@ static bool isDirectory(const string& path) { else return S_ISDIR(path_stat.st_mode); } +#else +static bool isDirectory(const string& path) { + auto attribs = GetFileAttributesA(path.c_str()); + if(attribs == INVALID_FILE_ATTRIBUTES) + return false; + else + return attribs & FILE_ATTRIBUTE_DIRECTORY; +} +#endif bool DirectoryPath::exists() const { return isDirectory(getPath()); @@ -31,7 +46,9 @@ bool DirectoryPath::exists() const { void DirectoryPath::createIfDoesntExist() const { if (!exists()) { -#ifndef WINDOWS +#ifdef _MSC_VER + USER_CHECK(CreateDirectoryA(path.data(), nullptr)); +#elif !defined(WINDOWS) USER_CHECK(!mkdir(path.data(), 0750)) << "Unable to create directory \"" + path + "\": " + strerror(errno); #else USER_CHECK(!mkdir(path.data())) << "Unable to create directory \"" + path + "\": " + strerror(errno); @@ -45,19 +62,32 @@ void DirectoryPath::removeRecursively() const { remove(file.getPath()); for (auto subdir : getSubDirs()) subdirectory(subdir).removeRecursively(); - rmdir(getPath()); + #ifdef _MSC_VER + RemoveDirectoryA(getPath()); + #else + rmdir(getPath()); + #endif } } static bool isRegularFile(const string& path) { +#ifndef _MSC_VER struct stat path_stat; if (stat(path.c_str(), &path_stat)) return false; else return S_ISREG(path_stat.st_mode); +#else + auto attribs = GetFileAttributesA(path.c_str()); + if(attribs == INVALID_FILE_ATTRIBUTES) + return false; + else + return !(attribs & FILE_ATTRIBUTE_DIRECTORY); +#endif } vector DirectoryPath::getFiles() const { +#ifndef _MSC_VER vector ret; if (DIR* dir = opendir(path.data())) { while (dirent* ent = readdir(dir)) @@ -66,9 +96,30 @@ vector DirectoryPath::getFiles() const { closedir(dir); } return ret; +#else + vector res; + + auto searchStr = path + "\\*"; + WIN32_FIND_DATA findData; + auto findHandle = FindFirstFileA(searchStr.c_str(), &findData); + if(findHandle != INVALID_HANDLE_VALUE) { + if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + res.push_back(FilePath(*this, findData.cFileName)); + + while(FindNextFileA(findHandle, &findData)) { + if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + res.push_back(FilePath(*this, findData.cFileName)); + } + + FindClose(findHandle); + } + + return res; +#endif } vector DirectoryPath::getSubDirs() const { +#ifndef _MSC_VER vector ret; if (DIR* dir = opendir(path.data())) { while (dirent* ent = readdir(dir)) @@ -77,6 +128,26 @@ vector DirectoryPath::getSubDirs() const { closedir(dir); } return ret; +#else + vector res; + + auto searchStr = path + "\\*"; + WIN32_FIND_DATA findData; + auto findHandle = FindFirstFileA(searchStr.c_str(), &findData); + if(findHandle != INVALID_HANDLE_VALUE) { + if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && strcmp(findData.cFileName, "..") != 0 && strcmp(findData.cFileName, ".") != 0) + res.push_back(findData.cFileName); + + while(FindNextFileA(findHandle, &findData)) { + if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && strcmp(findData.cFileName, "..") != 0 && strcmp(findData.cFileName, ".") != 0) + res.push_back(findData.cFileName); + } + + FindClose(findHandle); + } + + return res; +#endif } const char* DirectoryPath::getPath() const { @@ -107,10 +178,18 @@ string getAbsolute(const char* path) { } DirectoryPath DirectoryPath::current() { +#ifndef _MSC_VER char buffer[2048]; char* name = getcwd(buffer, sizeof(buffer) - 1); CHECK(name && "getcwd error"); return DirectoryPath(name); +#else + auto cwdLen = GetCurrentDirectoryA(0, nullptr); + std::vector cwd; + cwd.resize(cwdLen); + GetCurrentDirectoryA(cwdLen, cwd.data()); + return DirectoryPath(cwd.data()); +#endif } optional DirectoryPath::copyRecursively(DirectoryPath to) { diff --git a/extern/iomanip.h b/extern/iomanip.h index dd7815c80..d3d8bb66d 100644 --- a/extern/iomanip.h +++ b/extern/iomanip.h @@ -2,7 +2,7 @@ #include -#ifdef _LIBCPP_VERSION +#if defined(_LIBCPP_VERSION) || defined(_MSC_VER) #include #else diff --git a/extern/variant.hpp b/extern/variant.hpp index 746acaac8..bc907e4de 100644 --- a/extern/variant.hpp +++ b/extern/variant.hpp @@ -43,6 +43,7 @@ #if defined(__has_include) && !defined(STX_NO_STD_VARIANT) # if __has_include() && (__cplusplus > 201402) + #include namespace STX_NAMESPACE_NAME { using std::variant; using std::visit; diff --git a/file_path.cpp b/file_path.cpp index fb094fbc4..d681f3bc4 100644 --- a/file_path.cpp +++ b/file_path.cpp @@ -2,8 +2,14 @@ #include "file_path.h" #include "debug.h" #include "util.h" -#include -#include + +#ifndef _MSC_VER +# include +# include +#else +# define WIN32_LEAN_AND_MEAN +# include +#endif FilePath FilePath::fromFullPath(const std::string& path) { return FilePath(split(path, {'/'}).back(), path); @@ -28,7 +34,13 @@ time_t FilePath::getModificationTime() const { } bool FilePath::exists() const { -#ifdef WINDOWS +#ifdef _MSC_VER + auto attribs = GetFileAttributesA(fullPath.c_str()); + if(attribs == INVALID_FILE_ATTRIBUTES) + return false; + else + return (attribs & FILE_ATTRIBUTE_DIRECTORY) == 0; +#elif defined(WINDOWS) struct _stat buf; _stat(fullPath.c_str(), &buf); return S_ISREG(buf.st_mode); diff --git a/file_sharing.cpp b/file_sharing.cpp index 4b5d12c4b..b8a951603 100644 --- a/file_sharing.cpp +++ b/file_sharing.cpp @@ -395,7 +395,7 @@ static string firstLines(string text, int max_lines = 3) { } } } - while (text.back() == '\n') + while (!text.empty() && text.back() == '\n') text.pop_back(); return text; } diff --git a/fx_base.h b/fx_base.h index fb8875172..011185bd5 100644 --- a/fx_base.h +++ b/fx_base.h @@ -30,7 +30,7 @@ template using vector = std::vector; #if defined(PARANOID_CHECKS) && !defined(NDEBUG) #define PASSERT CHECK #else -#define PASSERT(...) +#define PASSERT(...) CHECK(true) #endif #endif diff --git a/fx_factory.cpp b/fx_factory.cpp index 06b7d4a7c..749d81720 100644 --- a/fx_factory.cpp +++ b/fx_factory.cpp @@ -619,7 +619,7 @@ static void addMagicMissileEffect(FXManager& mgr) { pdef.textureName = TextureName::MISSILE_CORE; SubSystemDef ssdef(pdef, edef, 0.0f, 0.1f); - ssdef.emitFunc = [](AnimationContext& ctx, EmissionState& em, Particle& pinst) { + ssdef.emitFunc = [=](AnimationContext& ctx, EmissionState& em, Particle& pinst) { em.direction = ctx.ps.targetDirAngle; em.directionSpread = 0.0f; em.strength = ctx.ps.targetTileDist * 24.0f / flightTime; diff --git a/fx_math.h b/fx_math.h index cf4aab705..989b5c734 100644 --- a/fx_math.h +++ b/fx_math.h @@ -29,9 +29,16 @@ inline float degToRad(float v) { return v * (2.0f * fconstant::pi / 360.0f); } inline float radToDeg(float v) { return v * (360.0 / (2.0 * fconstant::pi)); } inline std::pair sincos(float radians) { +#ifndef WINDOWS std::pair out; ::sincosf(radians, &out.first, &out.second); return out; +#else + std::pair out; + out.first = std::sin(radians); + out.second = std::cos(radians); + return out; +#endif } // Return angle in range (0; 2 * PI) diff --git a/gen_variant.h b/gen_variant.h index 758ca0a72..fc7968d7a 100644 --- a/gen_variant.h +++ b/gen_variant.h @@ -115,7 +115,7 @@ struct VARIANT_NAME { VARIANT_TYPES_LIST #undef X #define X(Type, Index) \ - using Type = Type; + using E##Type = Type; VARIANT_TYPES_LIST #undef X }; diff --git a/gen_variant_serialize_pretty.h b/gen_variant_serialize_pretty.h index 5496e14a7..fa9f24dc6 100644 --- a/gen_variant_serialize_pretty.h +++ b/gen_variant_serialize_pretty.h @@ -9,7 +9,8 @@ void serialize(PrettyInputArchive& ar1, VARIANT_NAME& v) { v.index = Index; \ new(&v.elem##Index) Type;\ ar1(v.elem##Index); \ - } else + return; \ + } VARIANT_TYPES_LIST #undef X #ifdef DEFAULT_ELEM @@ -19,7 +20,8 @@ void serialize(PrettyInputArchive& ar1, VARIANT_NAME& v) { new(&v.elem##Index) Type;\ ar1.seek(bookmark);\ ar1(v.elem##Index); \ - } else + return; \ + } VARIANT_TYPES_LIST #undef X ar1.error("Bad default elem"); diff --git a/gui_builder.cpp b/gui_builder.cpp index 00940a3b8..341820839 100644 --- a/gui_builder.cpp +++ b/gui_builder.cpp @@ -1775,7 +1775,7 @@ SGuiElem GuiBuilder::drawSpellsList(const vector& spells, GenericId c list.addElem(line.buildHorizontalList()); auto ret = list.buildVerticalList(); if (active) { - auto getNextSpell = [spells](int curIndex, int inc) -> optional { + auto getNextSpell = [spells, spellsPerRow](int curIndex, int inc) -> optional { int module = abs(inc) == 1 ? spells.size() : (spells.size() + spellsPerRow - 1) / spellsPerRow * spellsPerRow; for (int i : All(spells)) { int index = (curIndex + (i + 1) * inc + module) % module; @@ -4385,7 +4385,7 @@ SGuiElem GuiBuilder::drawMinionPage(const PlayerInfo& minion, const optional& queue, View:: SGuiElem GuiBuilder::drawCampaignMenu(SyncQueue& queue, View::CampaignOptions campaignOptions, View::CampaignMenuState& menuState) { if (menuState.index == CampaignMenuElems::None{} && hasController()) - menuState.index = CampaignMenuElems::Help{}; + menuState.index = CampaignMenuElems::CampaignMenuIndexVariant(CampaignMenuElems::Help{}); const auto& campaign = campaignOptions.campaign; auto& retiredGames = campaignOptions.retired; auto lines = WL(getListBuilder, getStandardLineHeight()); diff --git a/indexed_vector.h b/indexed_vector.h index b802f76e1..1c9deaa35 100644 --- a/indexed_vector.h +++ b/indexed_vector.h @@ -11,6 +11,9 @@ class IndexedVector { indexes.emplace(elems[i]->getUniqueId(), i); } + IndexedVector(const IndexedVector&) = default; + IndexedVector& operator=(const IndexedVector&) = default; + IndexedVector(IndexedVector&&) = default; IndexedVector& operator = (IndexedVector&&) = default; diff --git a/item.h b/item.h index e1050ec88..345a418e7 100644 --- a/item.h +++ b/item.h @@ -29,7 +29,7 @@ class Attack; class Fire; class Effect; struct CorpseInfo; -class WeaponInfo; +struct WeaponInfo; struct ItemUpgradeInfo; class ItemPrefix; class ItemType; diff --git a/item_attributes.h b/item_attributes.h index c9e0aab01..8ca9d7532 100644 --- a/item_attributes.h +++ b/item_attributes.h @@ -107,6 +107,6 @@ class ItemAttributes { string SERIAL(equipWarning) = "This item may potentially hurt your minion. Continue?"; }; -static_assert(std::is_nothrow_move_constructible::value, "T should be noexcept MoveConstructible"); +// static_assert(std::is_nothrow_move_constructible::value, "T should be noexcept MoveConstructible"); CEREAL_CLASS_VERSION(ItemAttributes, 1) diff --git a/item_type.cpp b/item_type.cpp index e08672db9..dc600452a 100644 --- a/item_type.cpp +++ b/item_type.cpp @@ -598,7 +598,7 @@ SItemAttributes ItemTypes::FireScroll::getAttributes(const ContentFactory*) cons i.price = 15; i.burnTime = 10; i.uses = 1; - i.effect = Effect(EffectType::Chain{}); + i.effect = Effect(EffectType::EChain{}); i.effectDescription = false; i.applyPredicate = CreaturePredicate(CreaturePredicates::Not{CreaturePredicate(LastingEffect::BLIND)}); i.storageIds = {StorageId("equipment")}; diff --git a/level_maker.h b/level_maker.h index a0abfe0f6..8c545450b 100644 --- a/level_maker.h +++ b/level_maker.h @@ -31,7 +31,7 @@ class LevelGenException { }; class FilePath; -class CreatureList; +struct CreatureList; class TribeId; class ContentFactory;; struct BiomeInfo; diff --git a/main.cpp b/main.cpp index c6f2278af..1272b9b30 100644 --- a/main.cpp +++ b/main.cpp @@ -313,8 +313,8 @@ static int keeperMain(po::parser& commandLineFlags) { #else AppConfig appConfig(dataPath.file("appconfig-dev.txt")); #endif + steamInput = make_unique(); #ifdef USE_STEAMWORKS - steamInput = make_unique(); optional steamClient; if (appConfig.get("steamworks") > 0) { if (steam::initAPI()) { diff --git a/main_loop.h b/main_loop.h index 065c656de..4a0666b28 100644 --- a/main_loop.h +++ b/main_loop.h @@ -19,7 +19,7 @@ class SokobanInput; struct CampaignSetup; class ModelBuilder; class ItemType; -class CreatureList; +struct CreatureList; class GameConfig; class AvatarInfo; class NameGenerator; @@ -32,7 +32,7 @@ struct ModDetails; class TribeId; struct RetiredModelInfo; class Unlocks; -class SteamAchievements; +struct SteamAchievements; class MainLoop { public: diff --git a/map_layouts.h b/map_layouts.h index b0677030b..abe369167 100644 --- a/map_layouts.h +++ b/map_layouts.h @@ -33,4 +33,4 @@ class MapLayouts { map> SERIAL(layouts); }; -static_assert(std::is_nothrow_move_constructible::value, "T should be noexcept MoveConstructible"); +// static_assert(std::is_nothrow_move_constructible::value, "T should be noexcept MoveConstructible"); diff --git a/miniunz.cpp b/miniunz.cpp index f640e8414..7fea09a23 100644 --- a/miniunz.cpp +++ b/miniunz.cpp @@ -3,6 +3,8 @@ Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant + + * Modified for compatibility with keeperrl on windows * */ @@ -16,25 +18,24 @@ #include //#ifdef unix +#ifndef WIN32 # include # include -/*#else +#else # include # include -#endif*/ +#endif #include "unzip.h" -#undef WIN32 - #define CASESENSITIVITY (0) #define WRITEBUFFERSIZE (8192) #define MAXFILENAME (256) -#ifdef WIN32 -#define USEWIN32IOAPI -#include "iowin32.h" -#endif +// #ifdef WIN32 +// #define USEWIN32IOAPI +// #include "iowin32.h" +// #endif #include "util.h" /* @@ -57,7 +58,7 @@ void change_file_date( uLong dosdate, tm_unz tmu_date) { -#ifdef WIN32 +#if 0 // defined(WIN32) HANDLE hFile; FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; @@ -96,7 +97,7 @@ void change_file_date( optional mymkdir( const char* dirname) { -#ifndef WINDOWS +#ifndef WIN32 if (mkdir (dirname,0775) != 0) #else if (mkdir (dirname) != 0) diff --git a/model_builder.h b/model_builder.h index 83d3de3a7..29528f98e 100644 --- a/model_builder.h +++ b/model_builder.h @@ -17,7 +17,7 @@ class ExternalEnemies; struct EnemyEvent; class Tutorial; class FilePath; -class CreatureList; +struct CreatureList; class GameConfig; class ContentFactory; struct LevelConnection; diff --git a/my_containers.h b/my_containers.h index af9e3371a..f531979fe 100644 --- a/my_containers.h +++ b/my_containers.h @@ -51,7 +51,7 @@ class vector { } void push_back(T t) { -#ifndef RELEASE // due to compile errors on older clang +#if !defined(RELEASE) && !defined(_MSC_VER) // due to compile errors on older clang static_assert(std::is_nothrow_move_constructible::value, "T should be noexcept MoveConstructible"); #endif impl.push_back(std::move(t)); @@ -419,19 +419,19 @@ class vector { friend class Iterator; auto begin() const { - return const_iterator(&*impl.begin(), this); + return const_iterator(impl.data(), this); } auto end() const { - return const_iterator(&*impl.end(), this); + return const_iterator(impl.data() + impl.size(), this); } auto begin() { - return iterator(&*impl.begin(), this); + return iterator(impl.data(), this); } auto end() { - return iterator(&*impl.end(), this); + return iterator(impl.data() + impl.size(), this); } std::vector impl; diff --git a/opengl.cpp b/opengl.cpp index c9216e2d8..9da38c762 100644 --- a/opengl.cpp +++ b/opengl.cpp @@ -181,7 +181,7 @@ void glQuad(float x, float y, float ex, float ey) { SDL::glEnd(); } -#ifdef WINDOWS +#if defined(WINDOWS) void *winLoadFunction(const char *name) { auto ret = SDL::SDL_GL_GetProcAddress(name); //USER_CHECK(!!ret) << "Unable to load OpenGL function: " << name << ". Please update your video card driver."; @@ -208,7 +208,7 @@ namespace SDL { #endif bool isOpenglFeatureAvailable(OpenglFeature feature) { -#ifdef WINDOWS +#if defined(WINDOWS) #define ON_WINDOWS(check) check #else #define ON_WINDOWS(check) @@ -228,7 +228,7 @@ bool isOpenglFeatureAvailable(OpenglFeature feature) { } void initializeGLExtensions() { -#ifdef WINDOWS +#if defined(WINDOWS) #define LOAD(func) SDL::func = (decltype(SDL::func))winLoadFunction(#func); LOAD(glBindFramebuffer); LOAD(glDeleteFramebuffers); @@ -237,6 +237,8 @@ void initializeGLExtensions() { LOAD(glFramebufferTexture2D); LOAD(glDrawBuffers); LOAD(glBlendFuncSeparate); + LOAD(glDebugMessageCallback); + LOAD(glDebugMessageControl); #undef LOAD #endif } diff --git a/opengl.h b/opengl.h index 4c7ca8f2d..fca3291e2 100644 --- a/opengl.h +++ b/opengl.h @@ -24,7 +24,7 @@ void initializeGLExtensions(); enum class OpenglFeature { FRAMEBUFFER, SEPARATE_BLEND_FUNC, DEBUG }; bool isOpenglFeatureAvailable(OpenglFeature); -#ifdef WINDOWS +#if defined(WINDOWS) namespace SDL { #define EXT_ENTRY __stdcall diff --git a/player_control.h b/player_control.h index 61d16b424..94cc13b8a 100644 --- a/player_control.h +++ b/player_control.h @@ -50,7 +50,7 @@ class Tutorial; struct BuildInfo; class MoveInfo; class UnknownLocations; -class AttackTrigger; +struct AttackTrigger; class ImmigrantInfo; struct WorkshopOptionInfo; struct FurnaceOptionInfo; diff --git a/pretty_archive.cpp b/pretty_archive.cpp index 93ff000a3..37ab4f4da 100644 --- a/pretty_archive.cpp +++ b/pretty_archive.cpp @@ -28,7 +28,7 @@ static bool contains(const vector& a, const string& substring, int i } static void eatWhitespace(const vector& s, int& index) { - while (index < s.size() && isspace(s[index].c)) + while (index < s.size() && isspace((unsigned char)s[index].c)) ++index; } @@ -107,9 +107,9 @@ void eatArgument(const vector& s, int& index) { optional scanWord(const vector& s, int& index) { string ret; int origIndex = index; - while (index < s.size() && isspace(s[index].c)) + while (index < s.size() && isspace((unsigned char)s[index].c)) ++index; - while (index < s.size() && (isalnum(s[index].c) || s[index].c == '_')) + while (index < s.size() && (isalnum((unsigned char)s[index].c) || s[index].c == '_')) ret += s[index++].c; if (ret.empty()) { index = origIndex; diff --git a/renderer.cpp b/renderer.cpp index d7407aa68..c9d36537d 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -14,7 +14,7 @@ If not, see http://www.gnu.org/licenses/ . */ #include "stdafx.h" -#include "dirent.h" +// #include "dirent.h" #include "extern/lodepng.h" #include "renderer.h" diff --git a/scripted_ui.cpp b/scripted_ui.cpp index 5cb9ebe6a..c4dfe9f18 100644 --- a/scripted_ui.cpp +++ b/scripted_ui.cpp @@ -374,9 +374,10 @@ struct Container : ScriptedUIInterface { vector getError(const string& s) const { static map errors; + static ScriptedUIData defUiData; if (!errors.count(s)) errors[s] = ScriptedUI{make_unique