1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

Merge branch 'develop' of https://github.com/vcmi/vcmi into RMG

This commit is contained in:
DjWarmonger 2014-07-15 12:27:59 +02:00
commit 173111955e
73 changed files with 2839 additions and 810 deletions

62
.travis.yml Normal file
View File

@ -0,0 +1,62 @@
language: cpp
before_install:
#new boost
- sudo add-apt-repository --yes ppa:boost-latest/ppa
#new GCC
- sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
#new Clang
- sudo add-apt-repository --yes ppa:h-rayflood/llvm
#new SDL2
- sudo add-apt-repository --yes ppa:zoogie/sdl2-snapshots
#new Qt
- sudo add-apt-repository --yes ppa:beineri/opt-qt531
#new FFmpeg
- sudo add-apt-repository --yes ppa:djcj/vlc-stable
- sudo apt-get update -qq
- sudo apt-get install -qq $SUPPORT
- sudo apt-get install -qq $PACKAGE
- sudo apt-get install -qq cmake yasm libboost1.55-all-dev zlib1g-dev
- sudo apt-get install -qq libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
- sudo apt-get install -qq libavformat-dev libswscale-dev
- sudo apt-get install -qq qt53declarative
#setup compiler
- source /opt/qt53/bin/qt53-env.sh
- export CC=${REAL_CC} CXX=${REAL_CXX}
before_script:
- mkdir build
- cd build
- cmake ..
script:
- make
env:
- ignore=this
matrix:
exclude:
- env: ignore=this
include:
- compiler: clang
env: REAL_CC=clang-3.2 REAL_CXX=clang++-3.2 PACKAGE=clang-3.2 SUPPORT=g++-4.8
- compiler: clang
env: REAL_CC=clang-3.3 REAL_CXX=clang++-3.3 PACKAGE=clang-3.3 SUPPORT=g++-4.8
- compiler: clang
env: REAL_CC=clang-3.4 REAL_CXX=clang++-3.4 PACKAGE=clang-3.4 SUPPORT=g++-4.8
- compiler: gcc
env: REAL_CC=gcc-4.7 REAL_CXX=g++-4.7 PACKAGE=g++-4.7 SUPPORT=
- compiler: gcc
env: REAL_CC=gcc-4.8 REAL_CXX=g++-4.8 PACKAGE=g++-4.8 SUPPORT=
notifications:
email:
recipients:
- vcmi.fail@mixaill.tk
- saven.ivan@gmail.com
on_success: change
on_failure: always

View File

@ -6,7 +6,8 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../BattleAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
@ -15,7 +16,31 @@
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../BattleAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../BattleAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../BattleAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />

View File

@ -16,6 +16,6 @@ set_target_properties(BattleAI PROPERTIES ${PCH_PROPERTIES})
cotire(BattleAI)
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS BattleAI DESTINATION ${AI_LIB_DIR})
install(TARGETS BattleAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
endif()

View File

@ -12,5 +12,5 @@ add_library(EmptyAI SHARED ${emptyAI_SRCS})
target_link_libraries(EmptyAI vcmi)
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS EmptyAI DESTINATION ${AI_LIB_DIR})
install(TARGETS EmptyAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
endif()

View File

@ -6,7 +6,8 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../EmptyAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
@ -15,7 +16,32 @@
<Add option="-ggdb" />
</Compiler>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../EmptyAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O3" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../EmptyAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-ggdb" />
</Compiler>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../EmptyAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />

View File

@ -50,4 +50,6 @@ add_library(FuzzyLite_lib STATIC ${FuzzyLite_lib_SRCS})
# all symobls from FuzzyLite exposed to public. This triggers errors
# when library is checked by analizers for issues
# Correct solution is either make FuzzyLite symbols hidden or turn lib into dynamic
SET_TARGET_PROPERTIES(FuzzyLite_lib PROPERTIES COMPILE_FLAGS "-fPIC")
if(NOT WIN32)
SET_TARGET_PROPERTIES(FuzzyLite_lib PROPERTIES COMPILE_FLAGS "-fPIC")
endif()

View File

@ -1,130 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="FuzzyLite" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin\Debug\FuzzyLite" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj\Debug\" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin\Release\FuzzyLite" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj\Release\" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wextra" />
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add option="-Wpointer-arith" />
<Add option="-Wno-switch" />
<Add option="-Wno-sign-compare" />
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-overloaded-virtual" />
</Compiler>
<Unit filename="AreaCentroidAlgorithm.cpp" />
<Unit filename="AreaCentroidAlgorithm.h" />
<Unit filename="CompoundTerm.cpp" />
<Unit filename="CompoundTerm.h" />
<Unit filename="DescriptiveAntecedent.cpp" />
<Unit filename="DescriptiveAntecedent.h" />
<Unit filename="DiscreteTerm.cpp" />
<Unit filename="DiscreteTerm.h" />
<Unit filename="FunctionTerm.cpp" />
<Unit filename="FunctionTerm.h" />
<Unit filename="FuzzyAnd.cpp" />
<Unit filename="FuzzyAnd.h" />
<Unit filename="FuzzyAntecedent.cpp" />
<Unit filename="FuzzyAntecedent.h" />
<Unit filename="FuzzyConsequent.cpp" />
<Unit filename="FuzzyConsequent.h" />
<Unit filename="FuzzyDefuzzifier.cpp" />
<Unit filename="FuzzyDefuzzifier.h" />
<Unit filename="FuzzyEngine.cpp" />
<Unit filename="FuzzyEngine.h" />
<Unit filename="FuzzyException.cpp" />
<Unit filename="FuzzyException.h" />
<Unit filename="FuzzyExceptions.cpp" />
<Unit filename="FuzzyExceptions.h" />
<Unit filename="FuzzyLite.h" />
<Unit filename="FuzzyModulation.cpp" />
<Unit filename="FuzzyModulation.h" />
<Unit filename="FuzzyOperation.cpp" />
<Unit filename="FuzzyOperation.h" />
<Unit filename="FuzzyOperator.cpp" />
<Unit filename="FuzzyOperator.h" />
<Unit filename="FuzzyOr.cpp" />
<Unit filename="FuzzyOr.h" />
<Unit filename="FuzzyRule.cpp" />
<Unit filename="FuzzyRule.h" />
<Unit filename="Hedge.cpp" />
<Unit filename="Hedge.h" />
<Unit filename="HedgeSet.cpp" />
<Unit filename="HedgeSet.h" />
<Unit filename="InfixToPostfix.cpp" />
<Unit filename="InfixToPostfix.h" />
<Unit filename="InputLVar.cpp" />
<Unit filename="InputLVar.h" />
<Unit filename="LinguisticTerm.cpp" />
<Unit filename="LinguisticTerm.h" />
<Unit filename="LinguisticVariable.cpp" />
<Unit filename="LinguisticVariable.h" />
<Unit filename="MamdaniConsequent.cpp" />
<Unit filename="MamdaniConsequent.h" />
<Unit filename="MamdaniRule.cpp" />
<Unit filename="MamdaniRule.h" />
<Unit filename="OutputLVar.cpp" />
<Unit filename="OutputLVar.h" />
<Unit filename="RectangularTerm.cpp" />
<Unit filename="RectangularTerm.h" />
<Unit filename="RuleBlock.cpp" />
<Unit filename="RuleBlock.h" />
<Unit filename="ShoulderTerm.cpp" />
<Unit filename="ShoulderTerm.h" />
<Unit filename="SingletonTerm.cpp" />
<Unit filename="SingletonTerm.h" />
<Unit filename="StrOp.cpp" />
<Unit filename="StrOp.h" />
<Unit filename="TakagiSugenoConsequent.cpp" />
<Unit filename="TakagiSugenoConsequent.h" />
<Unit filename="TakagiSugenoRule.cpp" />
<Unit filename="TakagiSugenoRule.h" />
<Unit filename="TakagiSugenoTerm.cpp" />
<Unit filename="TakagiSugenoTerm.h" />
<Unit filename="TrapezoidalTerm.cpp" />
<Unit filename="TrapezoidalTerm.h" />
<Unit filename="TriangularTerm.cpp" />
<Unit filename="TriangularTerm.h" />
<Unit filename="defs.h" />
<Unit filename="flScalar.h" />
<Unit filename="main.cpp" />
<Unit filename="test.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="FuzzyLite" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="bin/Debug/FuzzyLite" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj/Debug/" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="bin/Release/FuzzyLite" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj/Release/" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="bin/Debug/FuzzyLite" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj/Debug/" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="bin/Release/FuzzyLite" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj/Release/" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wextra" />
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add option="-Wpointer-arith" />
<Add option="-Wno-switch" />
<Add option="-Wno-sign-compare" />
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-overloaded-virtual" />
</Compiler>
<Unit filename="AreaCentroidAlgorithm.cpp" />
<Unit filename="AreaCentroidAlgorithm.h" />
<Unit filename="CompoundTerm.cpp" />
<Unit filename="CompoundTerm.h" />
<Unit filename="DescriptiveAntecedent.cpp" />
<Unit filename="DescriptiveAntecedent.h" />
<Unit filename="DiscreteTerm.cpp" />
<Unit filename="DiscreteTerm.h" />
<Unit filename="FunctionTerm.cpp" />
<Unit filename="FunctionTerm.h" />
<Unit filename="FuzzyAnd.cpp" />
<Unit filename="FuzzyAnd.h" />
<Unit filename="FuzzyAntecedent.cpp" />
<Unit filename="FuzzyAntecedent.h" />
<Unit filename="FuzzyConsequent.cpp" />
<Unit filename="FuzzyConsequent.h" />
<Unit filename="FuzzyDefuzzifier.cpp" />
<Unit filename="FuzzyDefuzzifier.h" />
<Unit filename="FuzzyEngine.cpp" />
<Unit filename="FuzzyEngine.h" />
<Unit filename="FuzzyException.cpp" />
<Unit filename="FuzzyException.h" />
<Unit filename="FuzzyExceptions.cpp" />
<Unit filename="FuzzyExceptions.h" />
<Unit filename="FuzzyLite.h" />
<Unit filename="FuzzyModulation.cpp" />
<Unit filename="FuzzyModulation.h" />
<Unit filename="FuzzyOperation.cpp" />
<Unit filename="FuzzyOperation.h" />
<Unit filename="FuzzyOperator.cpp" />
<Unit filename="FuzzyOperator.h" />
<Unit filename="FuzzyOr.cpp" />
<Unit filename="FuzzyOr.h" />
<Unit filename="FuzzyRule.cpp" />
<Unit filename="FuzzyRule.h" />
<Unit filename="Hedge.cpp" />
<Unit filename="Hedge.h" />
<Unit filename="HedgeSet.cpp" />
<Unit filename="HedgeSet.h" />
<Unit filename="InfixToPostfix.cpp" />
<Unit filename="InfixToPostfix.h" />
<Unit filename="InputLVar.cpp" />
<Unit filename="InputLVar.h" />
<Unit filename="LinguisticTerm.cpp" />
<Unit filename="LinguisticTerm.h" />
<Unit filename="LinguisticVariable.cpp" />
<Unit filename="LinguisticVariable.h" />
<Unit filename="MamdaniConsequent.cpp" />
<Unit filename="MamdaniConsequent.h" />
<Unit filename="MamdaniRule.cpp" />
<Unit filename="MamdaniRule.h" />
<Unit filename="OutputLVar.cpp" />
<Unit filename="OutputLVar.h" />
<Unit filename="RectangularTerm.cpp" />
<Unit filename="RectangularTerm.h" />
<Unit filename="RuleBlock.cpp" />
<Unit filename="RuleBlock.h" />
<Unit filename="ShoulderTerm.cpp" />
<Unit filename="ShoulderTerm.h" />
<Unit filename="SingletonTerm.cpp" />
<Unit filename="SingletonTerm.h" />
<Unit filename="StrOp.cpp" />
<Unit filename="StrOp.h" />
<Unit filename="TakagiSugenoConsequent.cpp" />
<Unit filename="TakagiSugenoConsequent.h" />
<Unit filename="TakagiSugenoRule.cpp" />
<Unit filename="TakagiSugenoRule.h" />
<Unit filename="TakagiSugenoTerm.cpp" />
<Unit filename="TakagiSugenoTerm.h" />
<Unit filename="TrapezoidalTerm.cpp" />
<Unit filename="TrapezoidalTerm.h" />
<Unit filename="TriangularTerm.cpp" />
<Unit filename="TriangularTerm.h" />
<Unit filename="defs.h" />
<Unit filename="flScalar.h" />
<Unit filename="main.cpp" />
<Unit filename="test.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -16,6 +16,6 @@ set_target_properties(StupidAI PROPERTIES ${PCH_PROPERTIES})
cotire(StupidAI)
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS StupidAI DESTINATION ${AI_LIB_DIR})
install(TARGETS StupidAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
endif()

View File

@ -6,7 +6,8 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../StupidAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
@ -15,7 +16,32 @@
<Add option="-ggdb" />
</Compiler>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../StupidAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O3" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../StupidAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-ggdb" />
</Compiler>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../StupidAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />

View File

@ -19,5 +19,5 @@ set_target_properties(VCAI PROPERTIES ${PCH_PROPERTIES})
cotire(VCAI)
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS VCAI DESTINATION ${AI_LIB_DIR})
install(TARGETS VCAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
endif()

View File

@ -6,7 +6,8 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
@ -18,7 +19,36 @@
<Add directory="../FuzzyLite/bin/Debug" />
</Linker>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O3" />
</Compiler>
<Linker>
<Add option="-s" />
<Add directory="../FuzzyLite/bin/Release" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
<Linker>
<Add directory="../FuzzyLite/bin/Debug" />
</Linker>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCAI" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />

View File

@ -9,7 +9,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_HOME_DIRECTORY}/cmake_modules)
# enable Release mode but only if it was not set
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
# VCMI version
@ -22,6 +22,7 @@ option(ENABLE_EDITOR "Enable compilation of map editor" OFF)
option(ENABLE_LAUNCHER "Enable compilation of launcher" ON)
option(ENABLE_TEST "Enable compilation of unit tests" OFF)
option(ENABLE_PCH "Enable compilation using precompiled headers" ON)
option(ENABLE_SDL2 "Use SDL2 for compilation instead of SDL 1.2" ON)
############################################
# Building section #
@ -53,12 +54,72 @@ if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=256")
endif()
if (WIN32)
add_definitions(-DBOOST_THREAD_USE_LIB)
add_definitions(-D_WIN32_WINNT=0x0501)
set(SYSTEM_LIBS ${SYSTEM_LIBS} ole32 oleaut32 ws2_32 mswsock)
#check for iconv (may be needed for boost.locale)
include(CheckLibraryExists)
check_library_exists(iconv libiconv_open "" ICONV_FOUND)
if(ICONV_FOUND)
set(SYSTEM_LIBS ${SYSTEM_LIBS} iconv)
endif()
#delete lib prefix for dlls
set(CMAKE_SHARED_LIBRARY_PREFIX "")
if(MINGW)
get_filename_component(MINGW_BIN_PATH ${CMAKE_CXX_COMPILER} PATH )
#copy libwinpthread-*.dll, libgcc_s_*.dll and libstdc++-*.dll to VCMI location
set(dep_files ${dep_files} "${MINGW_BIN_PATH}/libwinpthread-*.dll")
set(dep_files ${dep_files} "${MINGW_BIN_PATH}/libgcc_s_*.dll")
set(dep_files ${dep_files} "${MINGW_BIN_PATH}/libstdc++-*.dll")
endif()
endif()
if(APPLE)
set(SYSTEM_LIBS ${SYSTEM_LIBS} libiconv.dylib)
endif()
if(NOT WIN32)
INCLUDE(CheckLibraryExists)
#check if some platform-specific libraries are needed for linking
CHECK_LIBRARY_EXISTS(rt shm_open "" HAVE_RT_LIB)
if(HAVE_RT_LIB)
set(SYSTEM_LIBS ${SYSTEM_LIBS} rt)
endif()
CHECK_LIBRARY_EXISTS(dl dlopen "" HAVE_DL_LIB)
if(HAVE_DL_LIB)
set(SYSTEM_LIBS ${SYSTEM_LIBS} dl)
endif()
endif()
set(FFmpeg_FIND_COMPONENTS AVFORMAT SWSCALE)
find_package(Boost 1.48.0 COMPONENTS program_options filesystem system thread locale REQUIRED)
find_package(SDL REQUIRED)
find_package(SDL_image REQUIRED)
find_package(SDL_mixer REQUIRED)
find_package(SDL_ttf REQUIRED)
find_package(ZLIB REQUIRED)
find_package(FFmpeg REQUIRED)
if (ENABLE_SDL2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_mixer REQUIRED)
find_package(SDL2_ttf REQUIRED)
set(SDL_INCLUDE_DIR "${SDL2_INCLUDE_DIR}")
set(SDL_LIBRARY "${SDL2_LIBRARY}")
set(SDLTTF_LIBRARY "${SDL2_TTF_LIBRARY}")
set(SDLIMAGE_LIBRARY "${SDL2_IMAGE_LIBRARY}")
set(SDLMIXER_LIBRARY "${SDL2_MIXER_LIBRARY}")
else()
find_package(SDL REQUIRED)
find_package(SDL_image REQUIRED)
find_package(SDL_mixer REQUIRED)
find_package(SDL_ttf REQUIRED)
endif()
include(cotire)
if (ENABLE_EDITOR OR ENABLE_LAUNCHER)
@ -71,38 +132,16 @@ if (ENABLE_LAUNCHER)
endif()
if(ENABLE_TEST)
# find_package overwrites BOOST_* variables which are already set, so all components have to be
# included again
find_package(Boost 1.48.0 COMPONENTS program_options filesystem system thread locale unit_test_framework REQUIRED)
endif()
if(APPLE)
set(Boost_LIBRARIES ${Boost_LIBRARIES} libiconv.dylib) # Our prebuilt boost_locale for OS X depends on iconv
endif()
if(NOT WIN32)
set(FFmpeg_FIND_COMPONENTS AVFORMAT SWSCALE)
find_package(FFmpeg REQUIRED)
INCLUDE(CheckLibraryExists)
#check if some platform-specific libraries are needed for linking
CHECK_LIBRARY_EXISTS(rt shm_open "" HAVE_RT_LIB)
if(HAVE_RT_LIB)
set(RT_LIB -lrt)
endif()
CHECK_LIBRARY_EXISTS(dl dlopen "" HAVE_DL_LIB)
if(HAVE_DL_LIB)
set(DL_LIB -ldl)
endif()
# find_package overwrites BOOST_* variables which are already set, so all components have to be included again
find_package(Boost 1.48.0 COMPONENTS program_options filesystem system thread locale unit_test_framework REQUIRED)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR NOT WIN32) #so far all *nix compilers support such parameters
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CLANG_SPECIFIC_FLAGS "-Wno-mismatched-tags")
set(CLANG_SPECIFIC_FLAGS "-Wno-mismatched-tags -Wno-unknown-warning-option")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wextra -Wpointer-arith -Wno-switch -Wno-sign-compare -Wno-unused-parameter -Wuninitialized -Wno-overloaded-virtual ${CLANG_SPECIFIC_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wextra -Wpointer-arith -Wno-strict-aliasing -Wno-switch -Wno-sign-compare -Wno-unused-local-typedefs -Wno-unused-parameter -Wuninitialized -Wno-overloaded-virtual -Wno-type-limits ${CLANG_SPECIFIC_FLAGS}")
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
@ -111,9 +150,9 @@ if(CMAKE_COMPILER_IS_GNUCXX OR NOT WIN32) #so far all *nix compilers support suc
endif()
if(WIN32) # on Win everything goes into H3 root directory
set(BIN_DIR "" CACHE STRING "Where to install binaries")
set(LIB_DIR "" CACHE STRING "Where to install main library")
set(DATA_DIR "" CACHE STRING "Where to install data files")
set(BIN_DIR "." CACHE STRING "Where to install binaries")
set(LIB_DIR "." CACHE STRING "Where to install main library")
set(DATA_DIR "." CACHE STRING "Where to install data files")
elseif(APPLE)
# includes lib path which determines where to install shared libraries (either /lib or /lib64)
include(GNUInstallDirs)
@ -126,7 +165,7 @@ else()
include(GNUInstallDirs)
if (NOT BIN_DIR)
set(BIN_DIR "bin" CACHE STRING "Where to install binaries")
set(BIN_DIR "bin" CACHE STRING "Where to install binaries")
endif()
if (NOT LIB_DIR)
set(LIB_DIR "${CMAKE_INSTALL_LIBDIR}/vcmi" CACHE STRING "Where to install main library")
@ -155,7 +194,7 @@ SET(PCH_PROPERTIES
)
if (ENABLE_ERM)
add_subdirectory(scripting/erm)
add_subdirectory(scripting/erm)
endif()
add_subdirectory(lib)
add_subdirectory(client)
@ -193,9 +232,28 @@ if (NOT APPLE)
endif()
if(WIN32)
#TODO: install any additional dll's. This version (may be broken) will copy all dll's including H3 ones
#FILE(GLOB dll_files "${CMAKE_BINARY_DIR}/*.dll")
#INSTALL(FILES ${dll_files} DESTINATION ${BIN_DIR})
file(GLOB dep_files
${dep_files}
"${CMAKE_FIND_ROOT_PATH}/bin/*.dll")
if (ENABLE_EDITOR OR ENABLE_LAUNCHER)
get_target_property(QtCore_location Qt5::Core LOCATION)
get_filename_component(Qtbin_folder ${QtCore_location} PATH)
file(GLOB dep_files
${dep_files}
${Qtbin_folder}/Qt5Core.dll
${Qtbin_folder}/Qt5Gui.dll
${Qtbin_folder}/Qt5Widgets.dll
${Qtbin_folder}/icu*.dll)
endif()
if (ENABLE_LAUNCHER)
file(GLOB dep_files
${dep_files}
${Qtbin_folder}/Qt5Network.dll)
endif()
install(FILES ${dep_files} DESTINATION ${BIN_DIR})
elseif(APPLE)
else()
#install icons and desktop file on Linux

View File

@ -100,6 +100,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <boost/functional/hash.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/optional.hpp>
@ -116,6 +117,10 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
#include <android/log.h>
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
/* ---------------------------------------------------------------------------- */
/* Usings */
/* ---------------------------------------------------------------------------- */

View File

@ -177,7 +177,7 @@ CHeroList::CEmptyHeroItem::CEmptyHeroItem()
auto mana = new CAnimImage("IMANA", 0, 0, move->pos.w + img->pos.w + 2, 1 );
pos.w = mana->pos.w + mana->pos.x - pos.x;
pos.h = std::max(std::max<ui16>(move->pos.h + 1, mana->pos.h + 1), img->pos.h);
pos.h = std::max(std::max<SDLX_Size>(move->pos.h + 1, mana->pos.h + 1), img->pos.h);
}
CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero):
@ -190,7 +190,7 @@ CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero):
mana = new CAnimImage("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1 );
pos.w = mana->pos.w + mana->pos.x - pos.x;
pos.h = std::max(std::max<ui16>(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h);
pos.h = std::max(std::max<SDLX_Size>(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h);
update();
}

View File

@ -294,7 +294,7 @@ void CResDataBar::clickRight(tribool down, bool previousState)
CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist)
{
bg = BitmapHandler::loadBitmap(defname);
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos = genRect(bg->h, bg->w, pos.x+x, pos.y+y);
@ -313,7 +313,7 @@ CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int
CResDataBar::CResDataBar()
{
bg = BitmapHandler::loadBitmap(ADVOPT.resdatabarG);
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos = genRect(bg->h,bg->w,ADVOPT.resdatabarX,ADVOPT.resdatabarY);
@ -723,9 +723,8 @@ void CAdvMapInt::show(SDL_Surface * to)
if((animValHitCount % (4/scrollSpeed)) == 0
&& (
(GH.topInt() == this)
|| SDL_GetKeyState(nullptr)[SDLK_LCTRL]
|| SDL_GetKeyState(nullptr)[SDLK_RCTRL]
)
|| isCtrlKeyDown()
)
)
{
if( (scrollingDir & LEFT) && (position.x>-CGI->mh->frameW) )
@ -921,8 +920,12 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
//numpad arrow
if(CGuiHandler::isArrowKey(SDLKey(k)))
k = CGuiHandler::arrowToNum(SDLKey(k));
#ifdef VCMI_SDL1
k -= SDLK_KP0 + 1;
#else
k -= SDLK_KP_1;
#endif // VCMI_SDL1
if(k < 0 || k > 8)
return;
@ -1041,7 +1044,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
{
//adventure map scrolling with mouse
if(!SDL_GetKeyState(nullptr)[SDLK_LCTRL] && isActive())
if(!isCtrlKeyDown() && isActive())
{
if(sEvent.x<15)
{

View File

@ -157,7 +157,7 @@ CDefFile::CDefFile(std::string Name):
palette[i].r = data[it++];
palette[i].g = data[it++];
palette[i].b = data[it++];
palette[i].unused = 255;
CSDL_Ext::colorSetAlpha(palette[i],255);
}
if (type == 71 || type == 64)//Buttons/buildings don't have shadows\semi-transparency
memset(palette, 0, sizeof(SDL_Color)*2);
@ -356,7 +356,6 @@ void SDLImageLoader::init(Point SpriteSize, Point Margins, Point FullSize, SDL_C
//Prepare surface
SDL_SetColors(image->surf, pal, 0, 256);
SDL_LockSurface(image->surf);
lineStart = position = (ui8*)image->surf->pixels;
}
@ -444,8 +443,14 @@ inline ui8 CompImageLoader::typeOf(ui8 color)
{
if (color == 0)
return 0;
#ifdef VCMI_SDL1
if (image->palette[color].unused != 255)
return 1;
#else
if (image->palette[color].a != 255)
return 1;
#endif // 0
return 2;
}
@ -622,6 +627,7 @@ SDLImage::SDLImage(std::string filename, bool compressed):
{
SDL_Surface *temp = surf;
// add RLE flag
#ifdef VCMI_SDL1
if (surf->format->palette)
{
const SDL_Color &c = temp->format->palette->colors[0];
@ -630,6 +636,13 @@ SDLImage::SDLImage(std::string filename, bool compressed):
}
else
SDL_SetColorKey(temp, SDL_RLEACCEL, 0);
#else
if (surf->format->palette)
{
CSDL_Ext::setColorKey(temp,temp->format->palette->colors[0]);
}
SDL_SetSurfaceRLE(temp, SDL_RLEACCEL);
#endif
// convert surface to enable RLE
surf = SDL_ConvertSurface(temp, temp->format, temp->flags);
@ -797,13 +810,21 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha)
for (size_t i=0; i<size; i++)
{
SDL_Color col = palette[*(data++)];
#ifdef VCMI_SDL1
col.unused = (ui32)col.unused*alpha/255;
#else
col.a = (ui32)col.a*alpha/255;
#endif // 0
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
}
return;
}
#ifdef VCMI_SDL1
if (palette[color].unused == 255)
#else
if (palette[color].a == 255)
#endif // 0
{
//Put row of RGB data
for (size_t i=0; i<size; i++)
@ -820,6 +841,7 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha)
//RLE-d sequence
else
{
#ifdef VCMI_SDL1
if (alpha != 255 && palette[type].unused !=0)//Per-surface alpha is set
{
SDL_Color col = palette[type];
@ -827,9 +849,22 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha)
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
return;
}
}
switch (palette[type].unused)
#else
if (alpha != 255 && palette[type].a !=0)//Per-surface alpha is set
{
SDL_Color col = palette[type];
col.a = (int)col.a*(255-alpha)/255;
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
return;
}
switch (palette[type].a)
#endif // 0
{
case 0:
{
@ -870,10 +905,7 @@ void CompImage::playerColored(PlayerColor player)
for(int i=0; i<32; ++i)
{
palette[224+i].r = pal[i].r;
palette[224+i].g = pal[i].g;
palette[224+i].b = pal[i].b;
palette[224+i].unused = pal[i].unused;
CSDL_Ext::colorAssign(palette[224+i],pal[i]);
}
}

View File

@ -70,7 +70,7 @@ SDL_Surface * BitmapHandler::loadH3PCX(ui8 * pcx, size_t size)
tp.r = pcx[it++];
tp.g = pcx[it++];
tp.b = pcx[it++];
tp.unused = SDL_ALPHA_OPAQUE;
CSDL_Ext::colorSetAlpha(tp,SDL_ALPHA_OPAQUE);
ret->format->palette->colors[i] = tp;
}
}
@ -121,8 +121,7 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
{
if(ret->format->BytesPerPixel == 1 && setKey)
{
const SDL_Color &c = ret->format->palette->colors[0];
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format, c.r, c.g, c.b));
CSDL_Ext::setColorKey(ret,ret->format->palette->colors[0]);
}
}
else
@ -142,8 +141,8 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
if (ret->format->palette)
{
//set correct value for alpha\unused channel
for (int i=0; i< ret->format->palette->ncolors; i++)
ret->format->palette->colors[i].unused = 255;
for (int i=0; i < ret->format->palette->ncolors; i++)
CSDL_Ext::colorSetAlpha(ret->format->palette->colors[i],SDL_ALPHA_OPAQUE);
}
}
else
@ -154,23 +153,17 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
}
}
// When modifyin anything here please check two use cases:
// When modifying anything here please check two use cases:
// 1) Vampire mansion in Necropolis (not 1st color is transparent)
// 2) Battle background when fighting on grass/dirt, topmost sky part (NO transparent color)
// 3) New objects that may use 24-bit images for icons (e.g. witchking arts)
auto colorID = SDL_MapRGB(ret->format, 0, 255, 255);
if (ret->format->palette)
{
auto & color = ret->format->palette->colors[colorID];
// set color key only if exactly such color was found
if (color.r == 0 && color.g == 255 && color.b == 255)
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, colorID);
CSDL_Ext::setDefaultColorKeyPresize(ret);
}
else // always set
{
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, colorID);
CSDL_Ext::setDefaultColorKey(ret);
}
return ret;
}

View File

@ -5,7 +5,7 @@
#include "../lib/filesystem/Filesystem.h"
#include "../lib/VCMI_Lib.h"
#include "CBitmapHandler.h"
#include "gui/SDL_Extensions.h"
/*
* CDefHandler.cpp, part of VCMI engine
*
@ -67,7 +67,7 @@ void CDefHandler::openFromMemory(ui8 *table, const std::string & name)
palette[it].r = de.palette[it].R;
palette[it].g = de.palette[it].G;
palette[it].b = de.palette[it].B;
palette[it].unused = 255;
CSDL_Ext::colorSetAlpha(palette[it],SDL_ALPHA_OPAQUE);
}
// The SDefEntryBlock starts just after the SDefEntry
@ -169,19 +169,35 @@ SDL_Surface * CDefHandler::getSprite (int SIndex, const ui8 * FDef, const SDL_Co
add=0;
ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, 0, 0, 0, 0);
if(nullptr == ret)
{
logGlobal->errorStream() << __FUNCTION__ <<": Unable to create surface";
logGlobal->errorStream() << FullWidth << "X" << FullHeight;
logGlobal->errorStream() << SDL_GetError();
throw std::runtime_error("Unable to create surface");
}
BaseOffset += sizeof(SSpriteDef);
int BaseOffsetor = BaseOffset;
#ifdef VCMI_SDL1
for(int i=0; i<256; ++i)
{
{
SDL_Color pr;
pr.r = palette[i].r;
pr.g = palette[i].g;
pr.b = palette[i].b;
pr.unused = palette[i].unused;
(*(ret->format->palette->colors+i))=pr;
(*(ret->format->palette->colors+i))=pr;
}
#else
if(SDL_SetPaletteColors(ret->format->palette,palette,0,256) != 0)
{
throw std::runtime_error("Unable to set palette");
}
#endif
int ftcp=0;
@ -347,8 +363,14 @@ SDL_Surface * CDefHandler::getSprite (int SIndex, const ui8 * FDef, const SDL_Co
}
SDL_Color ttcol = ret->format->palette->colors[0];
Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
#ifdef VCMI_SDL1
Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
#else
Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.a);
SDL_SetColorKey(ret, SDL_TRUE, keycol);
#endif // 0
return ret;
}

View File

@ -66,11 +66,21 @@ std::string NAME_AFFIX = "client";
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
CGuiHandler GH;
static CClient *client=nullptr;
#ifndef VCMI_SDL1
int preferredDriverIndex = -1;
SDL_Window * mainWindow = nullptr;
SDL_Renderer * mainRenderer = nullptr;
SDL_Texture * screenTexture = nullptr;
#endif // VCMI_SDL1
extern boost::thread_specific_ptr<bool> inGuiThread;
SDL_Surface *screen = nullptr, //main screen surface
*screen2 = nullptr,//and hlp surface (used to store not-active interfaces layer)
*screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed
static boost::thread *mainGUIThread;
std::queue<SDL_Event> events;
boost::mutex eventsM;
@ -84,7 +94,7 @@ void processCommand(const std::string &message);
static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo=true);
void dispose();
void playIntro();
static void listenForEvents();
static void mainLoop();
//void requestChangingResolution();
void startGame(StartInfo * options, CConnection *serv = nullptr);
void endGame();
@ -127,28 +137,16 @@ void startGameFromFile(const std::string &fname)
void init()
{
CStopWatch tmh, pomtime;
logGlobal->infoStream() << "\tInitializing minors: " << pomtime.getDiff();
//initializing audio
// Note: because of interface button range, volume can only be a
// multiple of 11, from 0 to 99.
CCS->soundh = new CSoundHandler;
CCS->soundh->init();
CCS->soundh->setVolume(settings["general"]["sound"].Float());
CCS->musich = new CMusicHandler;
CCS->musich->init();
CCS->musich->setVolume(settings["general"]["music"].Float());
logGlobal->infoStream()<<"\tInitializing sound: "<<pomtime.getDiff();
logGlobal->infoStream()<<"Initializing screen and sound handling: "<<tmh.getDiff();
loadDLLClasses();
const_cast<CGameInfo*>(CGI)->setFromLib();
logGlobal->infoStream()<<"Initializing VCMI_Lib: "<<tmh.getDiff();
pomtime.getDiff();
if(!gNoGUI)
{
pomtime.getDiff();
CCS->curh = new CCursorHandler;
graphics = new Graphics(); // should be before curh->init()
@ -158,7 +156,7 @@ void init()
pomtime.getDiff();
graphics->loadHeroAnims();
logGlobal->infoStream()<<"\tMain graphics: "<<tmh.getDiff();
logGlobal->infoStream()<<"\tMain graphics: "<<pomtime.getDiff();
logGlobal->infoStream()<<"Initializing game graphics: "<<tmh.getDiff();
CMessage::init();
@ -257,10 +255,11 @@ int main(int argc, char** argv)
gNoGUI = true;
vm.insert(std::pair<std::string, po::variable_value>("onlyAI", po::variable_value()));
}
#ifdef VCMI_SDL1
//Set environment vars to make window centered. Sometimes work, sometimes not. :/
putenv((char*)"SDL_VIDEO_WINDOW_POS");
putenv((char*)"SDL_VIDEO_CENTERED=1");
#endif
// Have effect on X11 system only (Linux).
// For whatever reason in fullscreen mode SDL takes "raw" mouse input from DGA X11 extension
@ -335,22 +334,50 @@ int main(int argc, char** argv)
if(!gNoGUI)
{
#ifdef VCMI_SDL1
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO))
#else
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO|SDL_INIT_NOPARACHUTE))
#endif
{
logGlobal->errorStream()<<"Something was wrong: "<< SDL_GetError();
exit(-1);
}
GH.mainFPSmng->init(); //(!)init here AFTER SDL_Init() while using SDL for FPS management
atexit(SDL_Quit);
#ifndef VCMI_SDL1
int driversCount = SDL_GetNumRenderDrivers();
std::string preferredDriverName = video["driver"].String();
logGlobal->infoStream() << "Found " << driversCount << " render drivers";
for(int it = 0; it < driversCount; it++)
{
SDL_RendererInfo info;
SDL_GetRenderDriverInfo(it,&info);
std::string driverName(info.name);
logGlobal->infoStream() << "\t" << driverName;
if(!preferredDriverName.empty() && driverName == preferredDriverName)
{
preferredDriverIndex = it;
logGlobal->infoStream() << "\t\twill select this";
}
}
#endif // VCMI_SDL1
setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
logGlobal->infoStream() <<"\tInitializing screen: "<<pomtime.getDiff();
}
CCS = new CClientState;
CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler etc.)
// Initialize video
#if DISABLE_VIDEO
#ifdef DISABLE_VIDEO
CCS->videoh = new CEmptyVideoPlayer;
#else
if (!gNoGUI && !vm.count("disable-video"))
@ -361,13 +388,26 @@ int main(int argc, char** argv)
logGlobal->infoStream()<<"\tInitializing video: "<<pomtime.getDiff();
#if defined(__ANDROID__)
//on Android threaded init is broken
#define VCMI_NO_THREADED_LOAD
#endif // defined
//initializing audio
// Note: because of interface button range, volume can only be a
// multiple of 11, from 0 to 99.
CCS->soundh = new CSoundHandler;
CCS->soundh->init();
CCS->soundh->setVolume(settings["general"]["sound"].Float());
CCS->musich = new CMusicHandler;
CCS->musich->init();
CCS->musich->setVolume(settings["general"]["music"].Float());
logGlobal->infoStream()<<"Initializing screen and sound handling: "<<pomtime.getDiff();
#ifndef __ANDROID__
#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(init);
#else
// on Android threaded init is broken
#else
init();
#endif
@ -379,7 +419,7 @@ int main(int argc, char** argv)
}
CSDL_Ext::update(screen);
#ifndef __ANDROID__
#ifndef VCMI_NO_THREADED_LOAD
loading.join();
#endif
logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();
@ -418,8 +458,7 @@ int main(int argc, char** argv)
if(!gNoGUI)
{
mainGUIThread = new boost::thread(&CGuiHandler::run, &GH);
listenForEvents();
mainLoop();
}
else
{
@ -761,9 +800,176 @@ void dispose()
CMessage::dispose();
}
static bool checkVideoMode(int monitorIndex, int w, int h, int& bpp, bool fullscreen)
{
#ifndef VCMI_SDL1
SDL_DisplayMode mode;
const int modeCount = SDL_GetNumDisplayModes(monitorIndex);
for (int i = 0; i < modeCount; i++) {
SDL_GetDisplayMode(0, i, &mode);
if (!mode.w || !mode.h || (w >= mode.w && h >= mode.h)) {
return true;
}
}
return false;
#else
bpp = SDL_VideoModeOK(w, h, bpp, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0));
return !(bpp==0);
#endif // VCMI_SDL1
}
#ifndef VCMI_SDL1
static bool recreateWindow(int w, int h, int bpp, bool fullscreen)
{
// VCMI will only work with 2 or 4 bytes per pixel
vstd::amax(bpp, 16);
vstd::amin(bpp, 32);
if(bpp>16)
bpp = 32;
int suggestedBpp = bpp;
if(!checkVideoMode(0,w,h,suggestedBpp,fullscreen))
{
logGlobal->errorStream() << "Error: SDL says that " << w << "x" << h << " resolution is not available!";
return false;
}
bool bufOnScreen = (screenBuf == screen);
screenBuf = nullptr; //it`s a link - just nullify
if(nullptr != screen2)
{
SDL_FreeSurface(screen2);
screen2 = nullptr;
}
if(nullptr != screen)
{
SDL_FreeSurface(screen);
screen = nullptr;
}
if(nullptr != screenTexture)
{
SDL_DestroyTexture(screenTexture);
screenTexture = nullptr;
}
if(nullptr != mainRenderer)
{
SDL_DestroyRenderer(mainRenderer);
mainRenderer = nullptr;
}
if(nullptr != mainWindow)
{
SDL_DestroyWindow(mainWindow);
mainWindow = nullptr;
}
if(fullscreen)
{
//in full-screen mode always use desktop resolution
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
}
else
{
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, w, h, 0);
}
if(nullptr == mainWindow)
{
throw std::runtime_error("Unable to create window\n");
}
//create first available renderer if preferred not set. Use no flags, so HW accelerated will be preferred but SW renderer also will possible
mainRenderer = SDL_CreateRenderer(mainWindow,preferredDriverIndex,0);
if(nullptr == mainRenderer)
{
throw std::runtime_error("Unable to create renderer\n");
}
SDL_RendererInfo info;
SDL_GetRendererInfo(mainRenderer,&info);
logGlobal->infoStream() << "Created renderer " << info.name;
SDL_RenderSetLogicalSize(mainRenderer, w, h);
SDL_RenderSetViewport(mainRenderer, nullptr);
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
int bmask = 0xff000000;
int gmask = 0x00ff0000;
int rmask = 0x0000ff00;
int amask = 0x000000ff;
#else
int bmask = 0x000000ff;
int gmask = 0x0000ff00;
int rmask = 0x00ff0000;
int amask = 0xFF000000;
#endif
screen = SDL_CreateRGBSurface(0,w,h,bpp,rmask,gmask,bmask,amask);
if(nullptr == screen)
{
logGlobal->errorStream() << "Unable to create surface";
logGlobal->errorStream() << w << " "<< h << " "<< bpp;
logGlobal->errorStream() << SDL_GetError();
throw std::runtime_error("Unable to create surface");
}
//No blending for screen itself. Required for proper cursor rendering.
SDL_SetSurfaceBlendMode(screen, SDL_BLENDMODE_NONE);
screenTexture = SDL_CreateTexture(mainRenderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
w, h);
if(nullptr == screenTexture)
{
logGlobal->errorStream() << "Unable to create screen texture";
logGlobal->errorStream() << SDL_GetError();
throw std::runtime_error("Unable to create screen texture");
}
screen2 = CSDL_Ext::copySurface(screen);
if(nullptr == screen2)
{
throw std::runtime_error("Unable to copy surface\n");
}
screenBuf = bufOnScreen ? screen : screen2;
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 0);
SDL_RenderClear(mainRenderer);
SDL_RenderPresent(mainRenderer);
return true;
}
#endif
//used only once during initialization
static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo)
{
#ifdef VCMI_SDL1
// VCMI will only work with 2, 3 or 4 bytes per pixel
vstd::amax(bpp, 16);
vstd::amin(bpp, 32);
@ -831,7 +1037,15 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
//TODO: centering game window on other platforms (or does the environment do their job correctly there?)
screenBuf = bufOnScreen ? screen : screen2;
//setResolution = true;
//setResolution = true;
#else
if(!recreateWindow(w,h,bpp,fullscreen))
{
throw std::runtime_error("Requested screen resolution is not available\n");
}
#endif // VCMI_SDL1
}
static void fullScreenChanged()
@ -841,8 +1055,9 @@ static void fullScreenChanged()
Settings full = settings.write["video"]["fullscreen"];
const bool toFullscreen = full->Bool();
int bitsPerPixel = screen->format->BitsPerPixel;
auto bitsPerPixel = screen->format->BitsPerPixel;
#ifdef VCMI_SDL1
bitsPerPixel = SDL_VideoModeOK(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(toFullscreen?SDL_FULLSCREEN:0));
if(bitsPerPixel == 0)
{
@ -853,82 +1068,113 @@ static void fullScreenChanged()
bool bufOnScreen = (screenBuf == screen);
screen = SDL_SetVideoMode(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(toFullscreen?SDL_FULLSCREEN:0));
screenBuf = bufOnScreen ? screen : screen2;
#else
auto w = screen->w;
auto h = screen->h;
if(!recreateWindow(w,h,bitsPerPixel,toFullscreen))
{
//will return false and report error if video mode is not supported
return;
}
#endif
GH.totalRedraw();
}
static void listenForEvents()
static void handleEvent(SDL_Event & ev)
{
if((ev.type==SDL_QUIT) ||(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
{
handleQuit();
return;
}
#ifdef VCMI_SDL1
//FIXME: this should work even in pregame
else if(LOCPLINT && ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
#else
else if(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
#endif // VCMI_SDL1
{
Settings full = settings.write["video"]["fullscreen"];
full->Bool() = !full->Bool();
return;
}
else if(ev.type == SDL_USEREVENT)
{
switch(ev.user.code)
{
case RETURN_TO_MAIN_MENU:
{
endGame();
GH.curInt = CGPreGame::create();;
GH.defActionsDef = 63;
}
break;
case STOP_CLIENT:
client->endGame(false);
break;
case RESTART_GAME:
{
StartInfo si = *client->getStartInfo(true);
endGame();
startGame(&si);
}
break;
case PREPARE_RESTART_CAMPAIGN:
{
auto si = reinterpret_cast<StartInfo *>(ev.user.data1);
endGame();
startGame(si);
}
break;
case RETURN_TO_MENU_LOAD:
endGame();
CGPreGame::create();
GH.defActionsDef = 63;
CGP->update();
CGP->menu->switchToTab(vstd::find_pos(CGP->menu->menuNameToEntry, "load"));
GH.curInt = CGP;
break;
case FULLSCREEN_TOGGLED:
fullScreenChanged();
break;
default:
logGlobal->errorStream() << "Unknown user event. Code " << ev.user.code;
break;
}
return;
}
{
boost::unique_lock<boost::mutex> lock(eventsM);
events.push(ev);
}
}
static void mainLoop()
{
SettingsListener resChanged = settings.listen["video"]["fullscreen"];
resChanged([](const JsonNode &newState){ CGuiHandler::pushSDLEvent(SDL_USEREVENT, FULLSCREEN_TOGGLED); });
inGuiThread.reset(new bool(true));
GH.mainFPSmng->init();
while(1) //main SDL events loop
{
SDL_Event ev;
while(1 == SDL_PollEvent(&ev))
{
handleEvent(ev);
}
GH.renderFrame();
int ret = SDL_WaitEvent(&ev);
if (ret == 0 || (ev.type==SDL_QUIT) ||
(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
{
handleQuit();
continue;
}
else if(LOCPLINT && ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
{
Settings full = settings.write["video"]["fullscreen"];
full->Bool() = !full->Bool();
continue;
}
else if(ev.type == SDL_USEREVENT)
{
switch(ev.user.code)
{
case RETURN_TO_MAIN_MENU:
{
endGame();
GH.curInt = CGPreGame::create();;
GH.defActionsDef = 63;
}
break;
case STOP_CLIENT:
client->endGame(false);
break;
case RESTART_GAME:
{
StartInfo si = *client->getStartInfo(true);
endGame();
startGame(&si);
}
break;
case PREPARE_RESTART_CAMPAIGN:
{
auto si = reinterpret_cast<StartInfo *>(ev.user.data1);
endGame();
startGame(si);
}
break;
case RETURN_TO_MENU_LOAD:
endGame();
CGPreGame::create();
GH.defActionsDef = 63;
CGP->update();
CGP->menu->switchToTab(vstd::find_pos(CGP->menu->menuNameToEntry, "load"));
GH.curInt = CGP;
break;
case FULLSCREEN_TOGGLED:
fullScreenChanged();
break;
default:
logGlobal->errorStream() << "Error: unknown user event. Code " << ev.user.code;
assert(0);
}
continue;
}
{
boost::unique_lock<boost::mutex> lock(eventsM);
events.push(ev);
}
}
}
@ -978,15 +1224,9 @@ void handleQuit()
{
auto quitApplication = []()
{
if(client) client->endGame();
if(client)
endGame();
if(mainGUIThread)
{
GH.terminate = true;
if(mainGUIThread->get_id() != boost::this_thread::get_id()) mainGUIThread->join();
delete mainGUIThread;
mainGUIThread = nullptr;
}
delete console;
console = nullptr;
boost::this_thread::sleep(boost::posix_time::milliseconds(750));

View File

@ -1,9 +1,20 @@
#pragma once
#ifndef VCMI_SDL1
#include <SDL_render.h>
extern SDL_Texture * screenTexture;
extern SDL_Window * mainWindow;
extern SDL_Renderer * mainRenderer;
#endif // VCMI_SDL2
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
extern bool gNoGUI; //if true there is no client window and game is silently played between AIs
void handleQuit();
void handleQuit();

View File

@ -7,107 +7,105 @@ include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR} ${FFMPEG_INCLUDE_D
set(client_SRCS
StdInc.cpp
../CCallback.cpp
../CCallback.cpp
battle/CBattleInterface.cpp
battle/CBattleAnimations.cpp
battle/CBattleInterfaceClasses.cpp
battle/CCreatureAnimation.cpp
battle/CBattleAnimations.cpp
battle/CBattleInterfaceClasses.cpp
battle/CCreatureAnimation.cpp
gui/CGuiHandler.cpp
gui/CIntObject.cpp
gui/CIntObjectClasses.cpp
gui/Fonts.cpp
gui/Geometries.cpp
gui/CCursorHandler.cpp
gui/SDL_Extensions.cpp
gui/CGuiHandler.cpp
gui/CIntObject.cpp
gui/CIntObjectClasses.cpp
gui/Fonts.cpp
gui/Geometries.cpp
gui/CCursorHandler.cpp
gui/SDL_Extensions.cpp
CPreGame.cpp
Client.cpp
CPlayerInterface.cpp
CMT.cpp
GUIClasses.cpp
AdventureMapClasses.cpp
CAdvmapInterface.cpp
CAnimation.cpp
CBitmapHandler.cpp
CCastleInterface.cpp
CCreatureWindow.cpp
CDefHandler.cpp
CGameInfo.cpp
CHeroWindow.cpp
CKingdomInterface.cpp
CMessage.cpp
CMusicHandler.cpp
CSpellWindow.cpp
CVideoHandler.cpp
CQuestLog.cpp
Graphics.cpp
mapHandler.cpp
NetPacksClient.cpp
AdventureMapClasses.cpp
CAdvmapInterface.cpp
CAnimation.cpp
CBitmapHandler.cpp
CCastleInterface.cpp
CCreatureWindow.cpp
CDefHandler.cpp
CGameInfo.cpp
CHeroWindow.cpp
CKingdomInterface.cpp
CMessage.cpp
CMusicHandler.cpp
CSpellWindow.cpp
CVideoHandler.cpp
CQuestLog.cpp
Graphics.cpp
mapHandler.cpp
NetPacksClient.cpp
)
set(client_HEADERS
gui/SDL_Pixels.h
)
if(APPLE)
# OS X specific includes
include_directories(${SPARKLE_INCLUDE_DIR})
if(WIN32)
add_executable(vcmiclient WIN32 ${client_SRCS} ${client_HEADERS})
elseif(APPLE)
# OS X specific includes
include_directories(${SPARKLE_INCLUDE_DIR})
# OS X specific source files
set(client_SRCS ${client_SRCS} SDLMain.m OSX.mm Info.plist vcmi.icns ../osx/vcmi_dsa_public.pem)
# OS X specific source files
set(client_SRCS ${client_SRCS} SDLMain.m OSX.mm Info.plist vcmi.icns ../osx/vcmi_dsa_public.pem)
add_executable(vcmiclient MACOSX_BUNDLE ${client_SRCS} ${client_HEADERS})
# OS X specific libraries
target_link_libraries(vcmiclient ${SPARKLE_FRAMEWORK})
# OS X specific libraries
target_link_libraries(vcmiclient ${SPARKLE_FRAMEWORK})
# Because server and AI libs would be copies to bundle they need to be built before client
add_dependencies(vcmiclient vcmiserver VCAI EmptyAI StupidAI BattleAI minizip)
# Because server and AI libs would be copies to bundle they need to be built before client
add_dependencies(vcmiclient vcmiserver VCAI EmptyAI StupidAI BattleAI minizip)
# Custom Info.plist
set_target_properties(vcmiclient PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
# Custom Info.plist
set_target_properties(vcmiclient PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
# Copy icon file and public key for Sparkle
set_source_files_properties(vcmi.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set_source_files_properties(../osx/vcmi_dsa_public.pem PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# Copy icon file and public key for Sparkle
set_source_files_properties(vcmi.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set_source_files_properties(../osx/vcmi_dsa_public.pem PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set_target_properties(vcmiclient PROPERTIES XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks @executable_path/")
set_target_properties(vcmiclient PROPERTIES XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks @executable_path/")
# Copy server executable, libs and game data to bundle
set(BUNDLE_PATH ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/vcmiclient.app/Contents)
set(MakeVCMIBundle
# Copy all needed binaries
mkdir -p ${BUNDLE_PATH}/MacOS/AI &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/vcmiserver ${BUNDLE_PATH}/MacOS/vcmiserver &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libvcmi.dylib ${BUNDLE_PATH}/MacOS/libvcmi.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libminizip.dylib ${BUNDLE_PATH}/MacOS/libminizip.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libVCAI.dylib ${BUNDLE_PATH}/MacOS/AI/libVCAI.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libStupidAI.dylib ${BUNDLE_PATH}/MacOS/AI/libStupidAI.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libEmptyAI.dylib ${BUNDLE_PATH}/MacOS/AI/libEmptyAI.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libBattleAI.dylib ${BUNDLE_PATH}/MacOS/AI/libBattleAI.dylib &&
cp -r ${CMAKE_HOME_DIRECTORY}/osx/vcmibuilder.app ${BUNDLE_PATH}/MacOS/vcmibuilder.app &&
# Copy server executable, libs and game data to bundle
set(BUNDLE_PATH ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/vcmiclient.app/Contents)
set(MakeVCMIBundle
# Copy all needed binaries
mkdir -p ${BUNDLE_PATH}/MacOS/AI &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/vcmiserver ${BUNDLE_PATH}/MacOS/vcmiserver &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libvcmi.dylib ${BUNDLE_PATH}/MacOS/libvcmi.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libminizip.dylib ${BUNDLE_PATH}/MacOS/libminizip.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libVCAI.dylib ${BUNDLE_PATH}/MacOS/AI/libVCAI.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libStupidAI.dylib ${BUNDLE_PATH}/MacOS/AI/libStupidAI.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libEmptyAI.dylib ${BUNDLE_PATH}/MacOS/AI/libEmptyAI.dylib &&
cp ${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)/libBattleAI.dylib ${BUNDLE_PATH}/MacOS/AI/libBattleAI.dylib &&
cp -r ${CMAKE_HOME_DIRECTORY}/osx/vcmibuilder.app ${BUNDLE_PATH}/MacOS/vcmibuilder.app &&
# Copy frameworks
cp -r ${CMAKE_HOME_DIRECTORY}/${CMAKE_FRAMEWORK_PATH} ${BUNDLE_PATH}/Frameworks/ &&
# Copy frameworks
cp -r ${CMAKE_HOME_DIRECTORY}/${CMAKE_FRAMEWORK_PATH} ${BUNDLE_PATH}/Frameworks/ &&
# Copy vcmi data
mkdir -p ${BUNDLE_PATH}/Data &&
mkdir -p ${BUNDLE_PATH}/Data/Mods &&
mkdir -p ${BUNDLE_PATH}/Data/launcher &&
cp -r ${CMAKE_HOME_DIRECTORY}/config/ ${BUNDLE_PATH}/Data/config/ &&
cp -r ${CMAKE_HOME_DIRECTORY}/Mods/vcmi/ ${BUNDLE_PATH}/Data/Mods/vcmi/ &&
cp -r ${CMAKE_HOME_DIRECTORY}/Mods/WoG/ ${BUNDLE_PATH}/Data/Mods/WoG/ &&
cp -r ${CMAKE_HOME_DIRECTORY}/launcher/icons/ ${BUNDLE_PATH}/Data/launcher/icons/)
add_custom_command(TARGET vcmiclient POST_BUILD COMMAND ${MakeVCMIBundle})
# Copy vcmi data
mkdir -p ${BUNDLE_PATH}/Data &&
mkdir -p ${BUNDLE_PATH}/Data/Mods &&
mkdir -p ${BUNDLE_PATH}/Data/launcher &&
cp -r ${CMAKE_HOME_DIRECTORY}/config/ ${BUNDLE_PATH}/Data/config/ &&
cp -r ${CMAKE_HOME_DIRECTORY}/Mods/vcmi/ ${BUNDLE_PATH}/Data/Mods/vcmi/ &&
cp -r ${CMAKE_HOME_DIRECTORY}/Mods/WoG/ ${BUNDLE_PATH}/Data/Mods/WoG/ &&
cp -r ${CMAKE_HOME_DIRECTORY}/launcher/icons/ ${BUNDLE_PATH}/Data/launcher/icons/)
add_custom_command(TARGET vcmiclient POST_BUILD COMMAND ${MakeVCMIBundle})
else()
add_executable(vcmiclient ${client_SRCS} ${client_HEADERS})
add_executable(vcmiclient ${client_SRCS})
endif()
target_link_libraries(vcmiclient vcmi ${Boost_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLTTF_LIBRARY} ${ZLIB_LIBRARIES} ${FFMPEG_LIBRARIES} ${RT_LIB} ${DL_LIB})
if(WIN32)
set_target_properties(vcmiclient PROPERTIES OUTPUT_NAME VCMI_client)
endif()
target_link_libraries(vcmiclient vcmi ${Boost_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLTTF_LIBRARY} ${ZLIB_LIBRARIES} ${FFMPEG_LIBRARIES} ${SYSTEM_LIBS})
set_target_properties(vcmiclient PROPERTIES ${PCH_PROPERTIES})
cotire(vcmiclient)

View File

@ -91,7 +91,7 @@ void CMessage::init()
delete bluePieces;
}
background = BitmapHandler::loadBitmap("DIBOXBCK.BMP");
SDL_SetColorKey(background,SDL_SRCCOLORKEY,SDL_MapRGB(background->format,0,255,255));
CSDL_Ext::setDefaultColorKey(background);
}
ok = CDefHandler::giveDef("IOKAY.DEF");
cancel = CDefHandler::giveDef("ICANCEL.DEF");
@ -134,7 +134,7 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWi
boost::algorithm::trim_right_if(text,boost::algorithm::is_any_of(std::string(" ")));
// each interation generates one output line
// each iteration generates one output line
while (text.length())
{
ui32 lineWidth = 0; //in characters or given char metric

View File

@ -481,6 +481,8 @@ void MusicEntry::load(std::string musicURI)
data = CResourceHandler::get()->load(ResourceID(musicURI, EResType::MUSIC))->readAll();
musicFile = SDL_RWFromConstMem(data.first.get(), data.second);
#ifdef VCMI_SDL1
music = Mix_LoadMUS_RW(musicFile);
if(!music)
@ -491,10 +493,19 @@ void MusicEntry::load(std::string musicURI)
return;
}
#ifdef _WIN32
//The assertion will fail if old MSVC libraries pack .dll is used
assert(Mix_GetMusicType(music) != MUS_MP3);
#endif
#else
music = Mix_LoadMUS_RW(musicFile, SDL_FALSE);
if(!music)
{
SDL_FreeRW(musicFile);
musicFile = nullptr;
logGlobal->warnStream() << "Warning: Cannot open " << currentName << ": " << Mix_GetError();
return;
}
#endif // 0
}
bool MusicEntry::play()

View File

@ -116,6 +116,10 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
firstCall = 1; //if loading will be overwritten in serialize
autosaveCount = 0;
isAutoFightOn = false;
duringMovement = false;
ignoreEvents = false;
locked = false;
}
CPlayerInterface::~CPlayerInterface()
@ -313,8 +317,16 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
movementPxStep(details, i, hp, hero);
adventureInt->updateScreen = true;
adventureInt->show(screen);
CSDL_Ext::update(screen);
GH.mainFPSmng->framerateDelay(); //for animation purposes
{
//evil returns here ...
//todo: get rid of it
logGlobal->traceStream() << "before [un]locks in " << __FUNCTION__;
auto unlockPim = vstd::makeUnlockGuard(*pim); //let frame to be rendered
GH.mainFPSmng->framerateDelay(); //for animation purposes
logGlobal->traceStream() << "after [un]locks in " << __FUNCTION__;
}
//CSDL_Ext::update(screen);
} //for(int i=1; i<32; i+=4)
//main moving done
@ -1257,19 +1269,20 @@ void CPlayerInterface::loadGame( CISer<CLoadFile> &h, const int version )
firstCall = -1;
}
bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
void CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
{
logGlobal->traceStream() << __FUNCTION__;
if(!LOCPLINT->makingTurn)
return false;
return;
if (!h)
return false; //can't find hero
return; //can't find hero
//It shouldn't be possible to move hero with open dialog (or dialog waiting in bg)
if(showingDialog->get() || !dialogs.empty())
return false;
return;
duringMovement = true;
if (adventureInt && adventureInt->isHeroSleeping(h))
{
adventureInt->sleepWake.clickLeft(true, false);
@ -1278,103 +1291,20 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
//adventureInt->fsleepWake();
//but no authentic button click/sound ;-)
}
boost::thread moveHeroTask(boost::bind(&CPlayerInterface::doMoveHero,this,h,path));
int i = 1;
bool result = false; //TODO why not set to true anywhere?
{
//evil...
logGlobal->traceStream() << "before [un]locks in " << __FUNCTION__;
auto unlockEvents = vstd::makeUnlockGuard(eventsM);
auto unlockGs = vstd::makeUnlockSharedGuard(cb->getGsMutex()); //GS mutex is above PIM because CClient::run thread first locks PIM and then GS -> so this way we avoid deadlocks
auto unlockPim = vstd::makeUnlockGuard(*pim);
logGlobal->traceStream() << "after [un]locks in " << __FUNCTION__;
//TODO the above combination works... but it should all be atomic (unlock all three or none)
{
path.convert(0);
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
stillMoveHero.data = CONTINUE_MOVE;
ETerrainType currentTerrain = ETerrainType::BORDER; // not init yet
ETerrainType newTerrain;
int sh = -1;
const TerrainTile * curTile = cb->getTile(CGHeroInstance::convertPosition(h->pos, false));
for(i=path.nodes.size()-1; i>0 && (stillMoveHero.data == CONTINUE_MOVE || curTile->blocked); i--)
{
//changing z coordinate means we're moving through subterranean gate -> it's done automatically upon the visit, so we don't have to request that move here
if(path.nodes[i-1].coord.z != path.nodes[i].coord.z)
continue;
//stop sending move requests if the next node can't be reached at the current turn (hero exhausted his move points)
if(path.nodes[i-1].turns)
{
stillMoveHero.data = STOP_MOVE;
break;
}
// Start a new sound for the hero movement or let the existing one carry on.
#if 0
// TODO
if (hero is flying && sh == -1)
sh = CCS->soundh->playSound(soundBase::horseFlying, -1);
#endif
{
newTerrain = cb->getTile(CGHeroInstance::convertPosition(path.nodes[i].coord, false))->terType;
if (newTerrain != currentTerrain)
{
CCS->soundh->stopSound(sh);
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[newTerrain], -1);
currentTerrain = newTerrain;
}
}
stillMoveHero.data = WAITING_MOVE;
int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
bool guarded = CGI->mh->map->isInTheMap(cb->getGuardingCreaturePosition(endpos - int3(1, 0, 0)));
logGlobal->traceStream() << "Requesting hero movement to " << endpos;
cb->moveHero(h,endpos);
while(stillMoveHero.data != STOP_MOVE && stillMoveHero.data != CONTINUE_MOVE)
stillMoveHero.cond.wait(un);
logGlobal->traceStream() << "Resuming " << __FUNCTION__;
if (guarded || showingDialog->get() == true) // Abort movement if a guard was fought or there is a dialog to display (Mantis #1136)
break;
}
CCS->soundh->stopSound(sh);
}
//Update cursor so icon can change if needed when it reappears; doesn;'t apply if a dialog box pops up at the end of the movement
if(!showingDialog->get())
GH.fakeMouseMove();
//RAII unlocks
}
if (adventureInt)
{
// (i == 0) means hero went through all the path
adventureInt->updateMoveHero(h, (i != 0));
adventureInt->updateNextHero(h);
}
return result;
}
bool CPlayerInterface::shiftPressed() const
{
return SDL_GetKeyState(nullptr)[SDLK_LSHIFT] || SDL_GetKeyState(nullptr)[SDLK_RSHIFT];
return isShiftKeyDown();
}
bool CPlayerInterface::altPressed() const
{
return SDL_GetKeyState(nullptr)[SDLK_LALT] || SDL_GetKeyState(nullptr)[SDLK_RALT];
return isAltKeyDown();
}
void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID)
@ -1569,8 +1499,16 @@ void CPlayerInterface::centerView (int3 pos, int focusTime)
if(focusTime)
{
GH.totalRedraw();
#ifdef VCMI_SDL1
CSDL_Ext::update(screen);
SDL_Delay(focusTime);
#else
{
auto unlockPim = vstd::makeUnlockGuard(*pim);
IgnoreEvents ignore(*this);
SDL_Delay(focusTime);
}
#endif
}
}
@ -1586,36 +1524,16 @@ void CPlayerInterface::objectRemoved( const CGObjectInstance *obj )
bool CPlayerInterface::ctrlPressed() const
{
return SDL_GetKeyState(nullptr)[SDLK_LCTRL] || SDL_GetKeyState(nullptr)[SDLK_RCTRL];
return isCtrlKeyDown();
}
void CPlayerInterface::update()
{
// Updating GUI requires locking pim mutex (that protects screen and GUI state).
// When ending the game, the pim mutex might be hold bo other thread,
// that will notify us about the ending game by setting terminate_cond flag.
bool acquiredTheLockOnPim = false; //for tracking whether pim mutex locking succeeded
while(!terminate_cond.get() && !(acquiredTheLockOnPim = pim->try_lock())) //try acquiring long until it succeeds or we are told to terminate
boost::this_thread::sleep(boost::posix_time::milliseconds(15));
if(!acquiredTheLockOnPim)
if (!locked)
{
// We broke the while loop above and not because of mutex, so we must be terminating.
assert(terminate_cond.get());
logGlobal->errorStream() << "Non synchronized update of PlayerInterface";
return;
}
// If we are here, pim mutex has been successfully locked - let's store it in a safe RAII lock.
boost::unique_lock<boost::recursive_mutex> un(*pim, boost::adopt_lock);
// While mutexes were locked away we may be have stopped being the active interface
if(LOCPLINT != this)
return;
// Make sure that gamestate won't change when GUI objects may obtain its parts on event processing or drawing request
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
//if there are any waiting dialogs, show them
if((howManyPeople <= 1 || makingTurn) && !dialogs.empty() && !showingDialog->get())
{
@ -1641,11 +1559,38 @@ void CPlayerInterface::update()
if (settings["general"]["showfps"].Bool())
GH.drawFPSCounter();
}
// draw the mouse cursor and update the screen
CCS->curh->drawWithScreenRestore();
CSDL_Ext::update(screen);
CCS->curh->drawRestored();
void CPlayerInterface::runLocked(std::function<void(IUpdateable * )> functor)
{
// Updating GUI requires locking pim mutex (that protects screen and GUI state).
// When ending the game, the pim mutex might be hold by other thread,
// that will notify us about the ending game by setting terminate_cond flag.
bool acquiredTheLockOnPim = false; //for tracking whether pim mutex locking succeeded
while(!terminate_cond.get() && !(acquiredTheLockOnPim = pim->try_lock())) //try acquiring long until it succeeds or we are told to terminate
boost::this_thread::sleep(boost::posix_time::milliseconds(15));
if(!acquiredTheLockOnPim)
{
// We broke the while loop above and not because of mutex, so we must be terminating.
assert(terminate_cond.get());
return;
}
// If we are here, pim mutex has been successfully locked - let's store it in a safe RAII lock.
boost::unique_lock<boost::recursive_mutex> un(*pim, boost::adopt_lock);
// While mutexes were locked away we may be have stopped being the active interface
if(LOCPLINT != this)
return;
// Make sure that gamestate won't change when GUI objects may obtain its parts on event processing or drawing request
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
locked = true;
functor(this);
locked = false;
}
int CPlayerInterface::getLastIndex( std::string namePrefix)
@ -2608,3 +2553,104 @@ CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
spellbookLastPageBattle = spellbokLastPageAdvmap = 0;
spellbookLastTabBattle = spellbookLastTabAdvmap = 4;
}
bool CPlayerInterface::capturedAllEvents()
{
if(duringMovement)
{
//just inform that we are capturing events. they will be processed by heroMoved() in client thread.
return true;
}
if(ignoreEvents)
{
boost::unique_lock<boost::mutex> un(eventsM);
while(!events.empty())
{
events.pop();
}
return true;
}
return false;
}
void CPlayerInterface::doMoveHero(const CGHeroInstance* h, CGPath path)
{
int i = 1;
{
path.convert(0);
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
stillMoveHero.data = CONTINUE_MOVE;
ETerrainType currentTerrain = ETerrainType::BORDER; // not init yet
ETerrainType newTerrain;
int sh = -1;
const TerrainTile * curTile = cb->getTile(CGHeroInstance::convertPosition(h->pos, false));
for(i=path.nodes.size()-1; i>0 && (stillMoveHero.data == CONTINUE_MOVE || curTile->blocked); i--)
{
//changing z coordinate means we're moving through subterranean gate -> it's done automatically upon the visit, so we don't have to request that move here
if(path.nodes[i-1].coord.z != path.nodes[i].coord.z)
continue;
//stop sending move requests if the next node can't be reached at the current turn (hero exhausted his move points)
if(path.nodes[i-1].turns)
{
stillMoveHero.data = STOP_MOVE;
break;
}
// Start a new sound for the hero movement or let the existing one carry on.
#if 0
// TODO
if (hero is flying && sh == -1)
sh = CCS->soundh->playSound(soundBase::horseFlying, -1);
#endif
{
newTerrain = cb->getTile(CGHeroInstance::convertPosition(path.nodes[i].coord, false))->terType;
if (newTerrain != currentTerrain)
{
CCS->soundh->stopSound(sh);
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[newTerrain], -1);
currentTerrain = newTerrain;
}
}
stillMoveHero.data = WAITING_MOVE;
int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
bool guarded = CGI->mh->map->isInTheMap(cb->getGuardingCreaturePosition(endpos - int3(1, 0, 0)));
logGlobal->traceStream() << "Requesting hero movement to " << endpos;
cb->moveHero(h,endpos);
while(stillMoveHero.data != STOP_MOVE && stillMoveHero.data != CONTINUE_MOVE)
stillMoveHero.cond.wait(un);
logGlobal->traceStream() << "Resuming " << __FUNCTION__;
if (guarded || showingDialog->get() == true) // Abort movement if a guard was fought or there is a dialog to display (Mantis #1136)
break;
}
CCS->soundh->stopSound(sh);
}
//Update cursor so icon can change if needed when it reappears; doesn;'t apply if a dialog box pops up at the end of the movement
if(!showingDialog->get())
GH.fakeMouseMove();
//todo: this should be in main thread
if (adventureInt)
{
// (i == 0) means hero went through all the path
adventureInt->updateMoveHero(h, (i != 0));
adventureInt->updateNextHero(h);
}
duringMovement = false;
}

View File

@ -83,7 +83,7 @@ enum
};
/// Central class for managing user interface logic
class CPlayerInterface : public CGameInterface, public IUpdateable
class CPlayerInterface : public CGameInterface, public ILockedUpdatable
{
public:
bool observerInDuelMode;
@ -129,7 +129,8 @@ public:
}
} spellbookSettings;
void update();
void update() override;
void runLocked(std::function<void(IUpdateable * )> functor) override;
void initializeHeroTownList();
int getLastIndex(std::string namePrefix);
@ -239,7 +240,7 @@ public:
void showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps = false, const std::vector<CComponent*> & components = std::vector<CComponent*>()); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close
void stopMovement();
bool moveHero(const CGHeroInstance *h, CGPath path);
void moveHero(const CGHeroInstance *h, CGPath path);
void initMovement(const TryMoveHero &details, const CGHeroInstance * ho, const int3 &hp );//initializing objects and performing first step of move
void movementPxStep( const TryMoveHero &details, int i, const int3 &hp, const CGHeroInstance * ho );//performing step of movement
void finishMovement( const TryMoveHero &details, const int3 &hp, const CGHeroInstance * ho ); //finish movement
@ -254,14 +255,44 @@ public:
void sendCustomEvent(int code);
void proposeLoadingGame();
///returns true if all events are processed internally
bool capturedAllEvents();
CPlayerInterface(PlayerColor Player);//c-tor
~CPlayerInterface();//d-tor
static CondSh<bool> terminate_cond; // confirm termination
//////////////////////////////////////////////////////////////////////////
private:
template <typename Handler> void serializeTempl(Handler &h, const int version);
private:
struct IgnoreEvents
{
CPlayerInterface & owner;
IgnoreEvents(CPlayerInterface & Owner):owner(Owner)
{
owner.ignoreEvents = true;
};
~IgnoreEvents()
{
owner.ignoreEvents = false;
};
};
bool duringMovement;
bool ignoreEvents;
bool locked;
void doMoveHero(const CGHeroInstance *h, CGPath path);
};
extern CPlayerInterface * LOCPLINT;

View File

@ -536,11 +536,12 @@ void CGPreGame::update()
if (settings["general"]["showfps"].Bool())
GH.drawFPSCounter();
}
// draw the mouse cursor and update the screen
CCS->curh->drawWithScreenRestore();
CSDL_Ext::update(screen);
CCS->curh->drawRestored();
void CGPreGame::runLocked(std::function<void(IUpdateable * )> cb)
{
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
cb(this);
}
void CGPreGame::openCampaignScreen(std::string name)
@ -1897,7 +1898,7 @@ CChatBox::CChatBox(const Rect &rect)
{
OBJ_CONSTRUCTION;
pos += rect;
addUsedEvents(KEYBOARD);
addUsedEvents(KEYBOARD | TEXTINPUT);
captureAllKeys = true;
const int height = graphics->fonts[FONT_SMALL]->getLineHeight();
@ -4193,7 +4194,7 @@ CPrologEpilogVideo::CPrologEpilogVideo( CCampaignScenario::SScenarioPrologEpilog
void CPrologEpilogVideo::show( SDL_Surface * to )
{
CSDL_Ext::fillRect(to, &pos, 0); // fill screen with black
CSDL_Ext::fillRectBlack(to, &pos);
//BUG: some videos are 800x600 in size while some are 800x400
//VCMI should center them in the middle of the screen. Possible but needs modification
//of video player API which I'd like to avoid until we'll get rid of Windows-specific player

View File

@ -589,7 +589,7 @@ private:
};
/// Handles background screen, loads graphics for victory/loss condition and random town or hero selection
class CGPreGame : public CIntObject, public IUpdateable
class CGPreGame : public CIntObject, public ILockedUpdatable
{
void loadGraphics();
void disposeGraphics();
@ -602,7 +602,8 @@ public:
CDefHandler *victory, *loss;
~CGPreGame();
void update();
void update() override;
void runLocked(std::function<void(IUpdateable * )> cb) override;
void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER);
void openCampaignScreen(std::string name);

View File

@ -9,6 +9,7 @@
extern CGuiHandler GH; //global gui handler
#ifndef DISABLE_VIDEO
//reads events and returns true on key down
static bool keyDown()
{
@ -20,6 +21,7 @@ static bool keyDown()
}
return false;
}
#endif
#if defined(_WIN32) && (_MSC_VER < 1800 || !defined(USE_FFMPEG))
@ -29,12 +31,12 @@ void checkForError(bool throwing = true)
if(!error)
return;
logGlobal->errorStream() << "Error " << error << " encountered!";
logGlobal->errorStream() << "Error " << error << " encountered!";
std::string msg;
char* pTemp = nullptr;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, error, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, nullptr );
logGlobal->errorStream() << "Error: " << pTemp;
logGlobal->errorStream() << "Error: " << pTemp;
msg = pTemp;
LocalFree( pTemp );
pTemp = nullptr;
@ -60,7 +62,7 @@ void DLLHandler::Instantiate(const char *filename)
dll = LoadLibraryA(filename);
if(!dll)
{
logGlobal->errorStream() << "Failed loading " << filename;
logGlobal->errorStream() << "Failed loading " << filename;
checkForError(true);
}
}
@ -71,13 +73,13 @@ void *DLLHandler::FindAddress(const char *symbol)
if(!dll)
{
logGlobal->errorStream() << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!";
logGlobal->errorStream() << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!";
return nullptr;
}
ret = (void*) GetProcAddress(dll,symbol);
if(!ret)
{
logGlobal->errorStream() << "Failed to find " << symbol << " in " << name;
logGlobal->errorStream() << "Failed to find " << symbol << " in " << name;
checkForError();
}
return ret;
@ -89,7 +91,7 @@ DLLHandler::~DLLHandler()
{
if(!FreeLibrary(dll))
{
logGlobal->errorStream() << "Failed to free " << name;
logGlobal->errorStream() << "Failed to free " << name;
checkForError();
}
}
@ -136,21 +138,21 @@ bool CBIKHandler::open(std::string name)
if(hBinkFile == INVALID_HANDLE_VALUE)
{
logGlobal->errorStream() << "BIK handler: failed to open " << name;
logGlobal->errorStream() << "BIK handler: failed to open " << name;
goto checkErrorAndClean;
}
//GCC wants scope of waveout to don`t cross labels/swith/goto
{
void *waveout = GetProcAddress(dll,"_BinkOpenWaveOut@4");
{
void *waveout = (void *)GetProcAddress(dll,"_BinkOpenWaveOut@4");
if(waveout)
binkSetSoundSystem(waveout,nullptr);
}
}
hBink = binkOpen(hBinkFile, 0x8a800000);
if(!hBink)
{
logGlobal->errorStream() << "bink failed to open " << name;
logGlobal->errorStream() << "bink failed to open " << name;
goto checkErrorAndClean;
}
@ -300,7 +302,7 @@ bool CSmackPlayer::open( std::string name )
data = ptrSmackOpen( (void*)name.c_str(), flags[1], -1);
if (!data)
{
logGlobal->errorStream() << "Smack cannot open " << name;
logGlobal->errorStream() << "Smack cannot open " << name;
checkForError();
throw std::runtime_error("SMACK failed opening video");
}
@ -434,7 +436,7 @@ bool CVideoPlayer::open(std::string name)
catch(std::exception &e)
{
current = nullptr;
logGlobal->warnStream() << "Failed to open video file " << name << ": " << e.what();
logGlobal->warnStream() << "Failed to open video file " << name << ": " << e.what();
}
return false;
@ -444,7 +446,7 @@ void CVideoPlayer::close()
{
if(!current)
{
logGlobal->warnStream() << "Closing no opened player...?";
logGlobal->warnStream() << "Closing no opened player...?";
return;
}
@ -452,7 +454,7 @@ void CVideoPlayer::close()
current = nullptr;
if(!DeleteFileA(fname.c_str()))
{
logGlobal->errorStream() << "Cannot remove temporarily extracted video file: " << fname;
logGlobal->errorStream() << "Cannot remove temporarily extracted video file: " << fname;
checkForError(false);
}
fname.clear();
@ -603,7 +605,11 @@ CVideoPlayer::CVideoPlayer()
frame = nullptr;
codec = nullptr;
sws = nullptr;
#ifdef VCMI_SDL1
overlay = nullptr;
#else
texture = nullptr;
#endif
dest = nullptr;
context = nullptr;
@ -633,7 +639,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
if (!CResourceHandler::get()->existsResource(resource))
{
logGlobal->errorStream() << "Error: video " << resource.getName() << " was not found";
logGlobal->errorStream() << "Error: video " << resource.getName() << " was not found";
return false;
}
@ -706,8 +712,13 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
// Allocate a place to put our YUV image on that screen
if (useOverlay)
{
#ifdef VCMI_SDL1
overlay = SDL_CreateYUVOverlay(codecContext->width, codecContext->height,
SDL_YV12_OVERLAY, screen);
#else
texture = SDL_CreateTexture( mainRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STATIC, codecContext->width, codecContext->height);
#endif
}
else
{
@ -716,13 +727,18 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
destRect.w = codecContext->width;
destRect.h = codecContext->height;
}
#ifdef VCMI_SDL1
if (overlay == nullptr && dest == nullptr)
return false;
// Convert the image into YUV format that SDL uses
if (overlay)
{
#else
if (texture == nullptr && dest == nullptr)
return false;
if (texture)
#endif
{ // Convert the image into YUV format that SDL uses
sws = sws_getContext(codecContext->width, codecContext->height,
codecContext->pix_fmt, codecContext->width, codecContext->height,
PIX_FMT_YUV420P, SWS_BICUBIC, nullptr, nullptr, nullptr);
@ -810,6 +826,7 @@ bool CVideoPlayer::nextFrame()
{
AVPicture pict;
#ifdef VCMI_SDL1
if (overlay) {
SDL_LockYUVOverlay(overlay);
@ -825,6 +842,18 @@ bool CVideoPlayer::nextFrame()
0, codecContext->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(overlay);
#else
if (texture) {
avpicture_alloc(&pict, AV_PIX_FMT_YUV420P, codecContext->width, codecContext->height);
sws_scale(sws, frame->data, frame->linesize,
0, codecContext->height, pict.data, pict.linesize);
SDL_UpdateYUVTexture(texture, NULL, pict.data[0], pict.linesize[0],
pict.data[1], pict.linesize[1],
pict.data[2], pict.linesize[2]);
avpicture_free(&pict);
#endif
}
else
{
@ -900,11 +929,21 @@ void CVideoPlayer::close()
sws = nullptr;
}
#ifdef VCMI_SDL1
if (overlay)
{
SDL_FreeYUVOverlay(overlay);
overlay = nullptr;
}
#else
if (texture)
{
SDL_DestroyTexture(texture);
texture = nullptr;
}
#endif
if (dest)
{
@ -958,7 +997,13 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
if(stopOnKey && keyDown())
return false;
#ifdef VCMI_SDL1
SDL_DisplayYUVOverlay(overlay, &pos);
#else
SDL_RenderCopy(mainRenderer, texture, NULL, NULL);
SDL_RenderPresent(mainRenderer);
#endif
// Wait 3 frames
GH.mainFPSmng->framerateDelay();

View File

@ -221,7 +221,7 @@ public:
#include <SDL.h>
#include <SDL_video.h>
#if SDL_VERSION_ATLEAST(1,3,0)
#if SDL_VERSION_ATLEAST(1,3,0) && !SDL_VERSION_ATLEAST(2,0,0)
#include <SDL_compat.h>
#endif
@ -242,7 +242,12 @@ class CVideoPlayer : public IMainVideoPlayer
AVIOContext * context;
// Destination. Either overlay or dest.
SDL_Overlay *overlay;
#ifdef VCMI_SDL1
SDL_Overlay * overlay;
#else
SDL_Texture *texture;
#endif
SDL_Surface *dest;
SDL_Rect destRect; // valid when dest is used
SDL_Rect pos; // destination on screen

View File

@ -1799,7 +1799,7 @@ void CMinorResDataBar::showAll(SDL_Surface * to)
CMinorResDataBar::CMinorResDataBar()
{
bg = BitmapHandler::loadBitmap("KRESBAR.bmp");
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos.x = 7;
pos.y = 575;
@ -3946,8 +3946,8 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
{
if(enteredText.size() > 1)
{
enteredText.resize(enteredText.size()-1);
enteredText[enteredText.size()-1] = '_';
Unicode::trimRight(enteredText,2);
enteredText += '_';
refreshEnteredText();
}
break;
@ -3989,6 +3989,7 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
}
default:
{
#ifdef VCMI_SDL1
if(enteredText.size() > 0 && enteredText.size() < conf.go()->ac.inputLineLength)
{
if( key.keysym.unicode < 0x80 && key.keysym.unicode > 0 )
@ -3998,13 +3999,37 @@ void CInGameConsole::keyPressed (const SDL_KeyboardEvent & key)
refreshEnteredText();
}
}
#endif // VCMI_SDL1
break;
}
}
}
#ifndef VCMI_SDL1
void CInGameConsole::textInputed(const SDL_TextInputEvent & event)
{
if(!captureAllKeys || enteredText.size() == 0)
return;
enteredText.resize(enteredText.size()-1);
enteredText += event.text;
enteredText += "_";
refreshEnteredText();
}
void CInGameConsole::textEdited(const SDL_TextEditingEvent & event)
{
//do nothing here
}
#endif // VCMI_SDL1
void CInGameConsole::startEnteringText()
{
CSDL_Ext::startTextInput(&pos);
enteredText = "_";
if(GH.topInt() == adventureInt)
{
@ -4022,6 +4047,8 @@ void CInGameConsole::startEnteringText()
void CInGameConsole::endEnteringText(bool printEnteredText)
{
CSDL_Ext::stopTextInput();
prevEntDisp = -1;
if(printEnteredText)
{
@ -4060,7 +4087,11 @@ void CInGameConsole::refreshEnteredText()
CInGameConsole::CInGameConsole() : prevEntDisp(-1), defaultTimeout(10000), maxDisplayedTexts(10)
{
#ifdef VCMI_SDL1
addUsedEvents(KEYBOARD);
#else
addUsedEvents(KEYBOARD | TEXTINPUT);
#endif
}
CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits ):
@ -5341,6 +5372,9 @@ CPuzzleWindow::CPuzzleWindow(const int3 &GrailPos, double discoveredRatio):
piecesToRemove.push_back(piece);
piece->needRefresh = true;
piece->recActions = piece->recActions & ~SHOWALL;
#ifndef VCMI_SDL1
SDL_SetSurfaceBlendMode(piece->bg,SDL_BLENDMODE_BLEND);
#endif // VCMI_SDL1
}
}
}

View File

@ -834,6 +834,11 @@ public:
void print(const std::string &txt);
void keyPressed (const SDL_KeyboardEvent & key); //call-in
#ifndef VCMI_SDL1
void textInputed(const SDL_TextInputEvent & event) override;
void textEdited(const SDL_TextEditingEvent & event) override;
#endif // VCMI_SDL1
void startEnteringText();
void endEnteringText(bool printEnteredText);
void refreshEnteredText();

View File

@ -60,7 +60,7 @@ void Graphics::loadPaletteAndColors()
col.r = pals[startPoint++];
col.g = pals[startPoint++];
col.b = pals[startPoint++];
col.unused = 255;
CSDL_Ext::colorSetAlpha(col,SDL_ALPHA_OPAQUE);
startPoint++;
playerColorPalette[i] = col;
}
@ -75,20 +75,26 @@ void Graphics::loadPaletteAndColors()
neutralColorPalette[i].r = reader.readUInt8();
neutralColorPalette[i].g = reader.readUInt8();
neutralColorPalette[i].b = reader.readUInt8();
neutralColorPalette[i].unused = reader.readUInt8();
neutralColorPalette[i].unused = !neutralColorPalette[i].unused;
CSDL_Ext::colorSetAlpha(neutralColorPalette[i], !reader.readUInt8());
}
//colors initialization
int3 kolory[] = {int3(0xff,0,0),int3(0x31,0x52,0xff),int3(0x9c,0x73,0x52),int3(0x42,0x94,0x29),
int3(0xff,0x84,0x0),int3(0x8c,0x29,0xa5),int3(0x09,0x9c,0xa5),int3(0xc6,0x7b,0x8c)};
SDL_Color colors[] = {
{0xff,0, 0, SDL_ALPHA_OPAQUE},
{0x31,0x52,0xff,SDL_ALPHA_OPAQUE},
{0x9c,0x73,0x52,SDL_ALPHA_OPAQUE},
{0x42,0x94,0x29,SDL_ALPHA_OPAQUE},
{0xff,0x84,0, SDL_ALPHA_OPAQUE},
{0x8c,0x29,0xa5,SDL_ALPHA_OPAQUE},
{0x09,0x9c,0xa5,SDL_ALPHA_OPAQUE},
{0xc6,0x7b,0x8c,SDL_ALPHA_OPAQUE}};
for(int i=0;i<8;i++)
{
playerColors[i].r = kolory[i].x;
playerColors[i].g = kolory[i].y;
playerColors[i].b = kolory[i].z;
playerColors[i].unused = 255;
playerColors[i] = colors[i];
}
neutralColor->r = 0x84; neutralColor->g = 0x84; neutralColor->b = 0x84; neutralColor->unused = 255;//gray
neutralColor->r = 0x84; neutralColor->g = 0x84; neutralColor->b = 0x84; //gray
CSDL_Ext::colorSetAlpha(*neutralColor,SDL_ALPHA_OPAQUE);
}
void Graphics::initializeBattleGraphics()
@ -119,6 +125,7 @@ void Graphics::initializeBattleGraphics()
}
Graphics::Graphics()
{
#if 0
std::vector<Task> tasks; //preparing list of graphics to load
tasks += boost::bind(&Graphics::loadFonts,this);
tasks += boost::bind(&Graphics::loadPaletteAndColors,this);
@ -131,6 +138,16 @@ Graphics::Graphics()
CThreadHelper th(&tasks,std::max((ui32)1,boost::thread::hardware_concurrency()));
th.run();
#else
loadFonts();
loadPaletteAndColors();
loadHeroFlags();
initializeBattleGraphics();
loadErmuToPicture();
initializeImageLists();
resources32 = CDefHandler::giveDefEss("RESOURCE.DEF");
heroMoveArrows = CDefHandler::giveDefEss("ADAG.DEF");
#endif
for(auto & elem : heroMoveArrows->ourImages)
{
@ -242,9 +259,10 @@ void Graphics::loadHeroFlagsDetail(std::pair<std::vector<CDefEssential *> Graphi
}
for(auto & curImg : curImgs)
{
SDL_SetColorKey(curImg.bitmap, SDL_SRCCOLORKEY,
SDL_MapRGB(curImg.bitmap->format, 0, 255, 255)
);
CSDL_Ext::setDefaultColorKey(curImg.bitmap);
#ifndef VCMI_SDL1
SDL_SetSurfaceBlendMode(curImg.bitmap,SDL_BLENDMODE_NONE);
#endif
}
}
}
@ -266,12 +284,19 @@ void Graphics::loadHeroFlags()
pr[3].first = &Graphics::flags4;
pr[3].second+=("AF00.DEF"),("AF01.DEF"),("AF02.DEF"),("AF03.DEF"),("AF04.DEF"),
("AF05.DEF"),("AF06.DEF"),("AF07.DEF");
#if 0
boost::thread_group grupa;
for(int g=3; g>=0; --g)
{
grupa.create_thread(boost::bind(&Graphics::loadHeroFlagsDetail, this, boost::ref(pr[g]), true));
}
grupa.join_all();
#else
for(auto p: pr)
{
loadHeroFlagsDetail(p,true);
}
#endif
logGlobal->infoStream() << "Loading and transforming heroes' flags: "<<th.getDiff();
}

View File

@ -165,6 +165,11 @@ void SetMovePoints::applyCl( CClient *cl )
void FoWChange::applyCl( CClient *cl )
{
for(auto &i : cl->playerint)
{
if(cl->getPlayerRelations(i.first, player) == PlayerRelations::SAME_PLAYER && waitForDialogs && LOCPLINT == i.second.get())
{
LOCPLINT->waitWhileDialog();
}
if(cl->getPlayerRelations(i.first, player) != PlayerRelations::ENEMIES)
{
if(mode)
@ -172,7 +177,7 @@ void FoWChange::applyCl( CClient *cl )
else
i.second->tileHidden(tiles);
}
}
cl->invalidatePaths();
}

View File

@ -2,6 +2,8 @@
#include "../Global.h"
#include "gui/SDL_Compat.h"
// This header should be treated as a pre compiled header file(PCH) in the compiler building settings.
// Here you can add specific libraries and macros which are specific to this project.
// Here you can add specific libraries and macros which are specific to this project.

View File

@ -6,18 +6,28 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCMI_client" prefix_auto="1" extension_auto="1" />
<Option working_dir="../" />
<Option object_output="../obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-Og" />
<Add option="-g" />
<Add directory="$(#sdl2.include)" />
</Compiler>
<Linker>
<Add option="-lSDL2.dll" />
<Add option="-lSDL2_image.dll" />
<Add option="-lSDL2_mixer.dll" />
<Add option="-lSDL2_ttf.dll" />
<Add directory="$(#sdl2.lib)" />
</Linker>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCMI_client" prefix_auto="1" extension_auto="1" />
<Option working_dir="../" />
<Option object_output="../obj/Release/" />
@ -26,9 +36,56 @@
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#sdl2.include)" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-lSDL2.dll" />
<Add option="-lSDL2_image.dll" />
<Add option="-lSDL2_mixer.dll" />
<Add option="-lSDL2_ttf.dll" />
<Add directory="$(#sdl2.lib)" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCMI_client" prefix_auto="1" extension_auto="1" />
<Option working_dir="../" />
<Option object_output="../obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-Og" />
<Add option="-g" />
<Add directory="$(#sdl.include)" />
</Compiler>
<Linker>
<Add option="-lSDL" />
<Add option="-lSDL_image" />
<Add option="-lSDL_mixer" />
<Add option="-lSDL_ttf" />
<Add directory="$(#sdl.lib)" />
</Linker>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCMI_client" prefix_auto="1" extension_auto="1" />
<Option working_dir="../" />
<Option object_output="../obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#sdl.include)" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="-lSDL" />
<Add option="-lSDL_image" />
<Add option="-lSDL_mixer" />
<Add option="-lSDL_ttf" />
<Add directory="$(#sdl.lib)" />
</Linker>
</Target>
</Build>
@ -45,7 +102,6 @@
<Add option="-DBOOST_THREAD_USE_LIB" />
<Add option="-D_WIN32_WINNT=0x0501" />
<Add directory="$(#boost.include)" />
<Add directory="$(#sdl.include)" />
<Add directory="../include" />
<Add directory="../client" />
</Compiler>
@ -58,13 +114,8 @@
<Add option="-lboost_system$(#boost.libsuffix)" />
<Add option="-lboost_thread$(#boost.libsuffix)" />
<Add option="-lboost_chrono$(#boost.libsuffix)" />
<Add option="-lSDL" />
<Add option="-lSDL_image" />
<Add option="-lSDL_mixer" />
<Add option="-lSDL_ttf" />
<Add option="-lVCMI_lib" />
<Add directory="$(#boost.lib32)" />
<Add directory="$(#sdl.lib)" />
<Add directory="../" />
</Linker>
<Unit filename="../CCallback.cpp" />
@ -139,6 +190,7 @@
<Unit filename="gui/Fonts.h" />
<Unit filename="gui/Geometries.cpp" />
<Unit filename="gui/Geometries.h" />
<Unit filename="gui/SDL_Compat.h" />
<Unit filename="gui/SDL_Extensions.cpp" />
<Unit filename="gui/SDL_Extensions.h" />
<Unit filename="gui/SDL_Pixels.h" />

View File

@ -234,6 +234,7 @@
<ClInclude Include="FontBase.h" />
<ClInclude Include="Graphics.h" />
<ClInclude Include="GUIClasses.h" />
<ClInclude Include="gui\SDL_Compat.h" />
<ClInclude Include="mapHandler.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="StdInc.h" />

View File

@ -126,6 +126,7 @@
<ClInclude Include="gui\SDL_Pixels.h">
<Filter>gui</Filter>
</ClInclude>
<ClInclude Include="gui\SDL_Compat.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="VCMI_client.rc" />

View File

@ -363,8 +363,8 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
{
idToObstacle[ID] = CDefHandler::giveDef(elem->getInfo().defName);
for(auto & _n : idToObstacle[ID]->ourImages)
{
SDL_SetColorKey(_n.bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(_n.bitmap->format,0,255,255));
{
CSDL_Ext::setDefaultColorKey(_n.bitmap);
}
}
else if(elem->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)

View File

@ -178,7 +178,7 @@ CCreatureAnimation::CCreatureAnimation(std::string name, TSpeedController contro
elem.r = reader.readUInt8();
elem.g = reader.readUInt8();
elem.b = reader.readUInt8();
elem.unused = 0;
CSDL_Ext::colorSetAlpha(elem,0);
}
for (int i=0; i<totalBlocks; i++)
@ -267,7 +267,11 @@ static SDL_Color genShadow(ui8 alpha)
static SDL_Color genBorderColor(ui8 alpha, const SDL_Color & base)
{
#ifdef VCMI_SDL1
return CSDL_Ext::makeColor(base.r, base.g, base.b, ui8(base.unused * alpha / 256));
#else
return CSDL_Ext::makeColor(base.r, base.g, base.b, ui8(base.a * alpha / 256));
#endif
}
static ui8 mixChannels(ui8 c1, ui8 c2, ui8 a1, ui8 a2)
@ -277,12 +281,22 @@ static ui8 mixChannels(ui8 c1, ui8 c2, ui8 a1, ui8 a2)
static SDL_Color addColors(const SDL_Color & base, const SDL_Color & over)
{
#ifdef VCMI_SDL1
return CSDL_Ext::makeColor(
mixChannels(over.r, base.r, over.unused, base.unused),
mixChannels(over.g, base.g, over.unused, base.unused),
mixChannels(over.b, base.b, over.unused, base.unused),
ui8(over.unused + base.unused * (255 - over.unused) / 256)
);
mixChannels(over.r, base.r, over.unused, base.unused),
mixChannels(over.g, base.g, over.unused, base.unused),
mixChannels(over.b, base.b, over.unused, base.unused),
ui8(over.unused + base.unused * (255 - over.unused) / 256)
);
#else
return CSDL_Ext::makeColor(
mixChannels(over.r, base.r, over.a, base.a),
mixChannels(over.g, base.g, over.a, base.a),
mixChannels(over.b, base.b, over.a, base.a),
ui8(over.a + base.a * (255 - over.a) / 256)
);
#endif // VCMI_SDL1
}
std::array<SDL_Color, 8> CCreatureAnimation::genSpecialPalette()
@ -413,7 +427,11 @@ inline void CCreatureAnimation::putPixel(ui8 * dest, const SDL_Color & color, si
if (index < 8)
{
const SDL_Color & pal = special[index];
#ifdef VCMI_SDL1
ColorPutter<bpp, 0>::PutColor(dest, pal.r, pal.g, pal.b, pal.unused);
#else
ColorPutter<bpp, 0>::PutColor(dest, pal.r, pal.g, pal.b, pal.a);
#endif // 0
}
else
{

View File

@ -25,6 +25,10 @@ void CCursorHandler::initCursor()
currentCursor = nullptr;
help = CSDL_Ext::newSurface(40,40);
#ifndef VCMI_SDL1
//No blending. Ensure, that we are copying pixels during "screen restore draw"
SDL_SetSurfaceBlendMode(help,SDL_BLENDMODE_NONE);
#endif // VCMI_SDL1
SDL_ShowCursor(SDL_DISABLE);
changeGraphic(ECursor::ADVENTURE, 0);
@ -223,6 +227,14 @@ void CCursorHandler::centerCursor()
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
}
void CCursorHandler::render()
{
drawWithScreenRestore();
CSDL_Ext::update(screen);
drawRestored();
}
CCursorHandler::~CCursorHandler()
{
if(help)

View File

@ -32,6 +32,13 @@ class CCursorHandler
CAnimImage * dndObject; //if set, overrides currentCursor
bool showing;
/// Draw cursor preserving original image below cursor
void drawWithScreenRestore();
/// Restore original image below cursor
void drawRestored();
/// Simple draw cursor
void draw(SDL_Surface *to);
public:
/// position of cursor
int xpos, ypos;
@ -53,13 +60,8 @@ public:
* cursor. CursorHandler takes ownership of object
*/
void dragAndDropCursor (CAnimImage * image);
/// Draw cursor preserving original image below cursor
void drawWithScreenRestore();
/// Restore original image below cursor
void drawRestored();
/// Simple draw cursor
void draw(SDL_Surface *to);
void render();
void shiftPos( int &x, int &y );
void hide() { showing=0; };

View File

@ -1,13 +1,14 @@
#include "StdInc.h"
#include "CGuiHandler.h"
#include "SDL_Extensions.h"
#include "CIntObject.h"
#include "../CGameInfo.h"
#include "CCursorHandler.h"
#include "../../lib/CThreadHelper.h"
#include "../../lib/CConfigHandler.h"
#include "../CMT.h"
#include "../CPlayerInterface.h"
extern std::queue<SDL_Event> events;
extern boost::mutex eventsM;
@ -60,6 +61,10 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
processList(CIntObject::TIME,activityFlag,&timeinterested,cb);
processList(CIntObject::WHEEL,activityFlag,&wheelInterested,cb);
processList(CIntObject::DOUBLECLICK,activityFlag,&doubleClickInterested,cb);
#ifndef VCMI_SDL1
processList(CIntObject::TEXTINPUT,activityFlag,&textInterested,cb);
#endif // VCMI_SDL1
}
void CGuiHandler::handleElementActivate(CIntObject * elem, ui16 activityFlag)
@ -164,20 +169,16 @@ void CGuiHandler::updateTime()
void CGuiHandler::handleEvents()
{
while(true)
//player interface may want special event handling
if(nullptr != LOCPLINT && LOCPLINT->capturedAllEvents())
return;
boost::unique_lock<boost::mutex> lock(eventsM);
while(!events.empty())
{
SDL_Event ev;
boost::unique_lock<boost::mutex> lock(eventsM);
if(events.empty())
{
return;
}
else
{
ev = events.front();
events.pop();
}
handleEvent(&ev);
SDL_Event ev = events.front();
events.pop();
this->handleEvent(&ev);
}
}
@ -194,6 +195,9 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
if(key.keysym.sym == SDLK_KP_ENTER)
{
key.keysym.sym = (SDLKey)SDLK_RETURN;
#ifndef VCMI_SDL1
key.keysym.scancode = SDL_SCANCODE_RETURN;
#endif // VCMI_SDL1
}
bool keysCaptured = false;
@ -264,6 +268,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
}
}
}
#ifdef VCMI_SDL1 //SDL1x only events
else if(sEvent->button.button == SDL_BUTTON_WHEELDOWN || sEvent->button.button == SDL_BUTTON_WHEELUP)
{
std::list<CIntObject*> hlp = wheelInterested;
@ -273,7 +278,34 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
(*i)->wheelScrolled(sEvent->button.button == SDL_BUTTON_WHEELDOWN, isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y));
}
}
#endif
}
#ifndef VCMI_SDL1 //SDL2x only events
else if (sEvent->type == SDL_MOUSEWHEEL)
{
std::list<CIntObject*> hlp = wheelInterested;
for(auto i=hlp.begin(); i != hlp.end() && current; i++)
{
if(!vstd::contains(wheelInterested,*i)) continue;
(*i)->wheelScrolled(sEvent->wheel.y < 0, isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y));
}
}
else if(sEvent->type == SDL_TEXTINPUT)
{
for(auto it : textInterested)
{
it->textInputed(sEvent->text);
}
}
else if(sEvent->type == SDL_TEXTEDITING)
{
for(auto it : textInterested)
{
it->textEdited(sEvent->edit);
}
}
//todo: muiltitouch
#endif // VCMI_SDL1
else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_LEFT))
{
std::list<CIntObject*> hlp = lclickable;
@ -360,8 +392,11 @@ void CGuiHandler::handleMoveInterested( const SDL_MouseMotionEvent & motion )
void CGuiHandler::fakeMouseMove()
{
SDL_Event evnt;
#ifdef VCMI_SDL1
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0};
#else
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0, 0, 0};
#endif
int x, y;
sme.state = SDL_GetMouseState(&x, &y);
sme.x = x;
@ -372,37 +407,38 @@ void CGuiHandler::fakeMouseMove()
handleMouseMotion(&evnt);
}
void CGuiHandler::run()
void CGuiHandler::renderFrame()
{
setThreadName("CGuiHandler::run");
inGuiThread.reset(new bool(true));
try
auto doUpdate = [](IUpdateable * target)
{
if(settings["video"]["fullscreen"].Bool())
CCS->curh->centerCursor();
if(nullptr != target)
target -> update();
// draw the mouse cursor and update the screen
CCS->curh->render();
mainFPSmng->init(); // resets internal clock, needed for FPS manager
while(!terminate)
{
if(curInt)
curInt->update(); // calls a update and drawing process of the loaded game interface object at the moment
#ifndef VCMI_SDL1
if(0 != SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr))
logGlobal->errorStream() << __FUNCTION__ << " SDL_RenderCopy " << SDL_GetError();
mainFPSmng->framerateDelay(); // holds a constant FPS
}
}
catch(const std::exception & e)
{
logGlobal->errorStream() << "Error: " << e.what();
exit(EXIT_FAILURE);
}
SDL_RenderPresent(mainRenderer);
#endif
};
if(curInt)
curInt->runLocked(doUpdate);
else
doUpdate(nullptr);
mainFPSmng->framerateDelay(); // holds a constant FPS
}
CGuiHandler::CGuiHandler()
:lastClick(-500, -500)
{
curInt = nullptr;
current = nullptr;
terminate = false;
statusbar = nullptr;
// Creates the FPS manager and sets the framerate to 48 which is doubled the value of the original Heroes 3 FPS rate
@ -432,6 +468,7 @@ void CGuiHandler::drawFPSCounter()
SDLKey CGuiHandler::arrowToNum( SDLKey key )
{
#ifdef VCMI_SDL1
switch(key)
{
case SDLK_DOWN:
@ -443,23 +480,51 @@ SDLKey CGuiHandler::arrowToNum( SDLKey key )
case SDLK_RIGHT:
return SDLK_KP6;
default:
assert(0);
}
throw std::runtime_error("Wrong key!");
throw std::runtime_error("Wrong key!");assert(0);
}
#else
switch(key)
{
case SDLK_DOWN:
return SDLK_KP_2;
case SDLK_UP:
return SDLK_KP_8;
case SDLK_LEFT:
return SDLK_KP_4;
case SDLK_RIGHT:
return SDLK_KP_6;
default:
throw std::runtime_error("Wrong key!");
}
#endif // 0
}
SDLKey CGuiHandler::numToDigit( SDLKey key )
{
#ifdef VCMI_SDL1
if(key >= SDLK_KP0 && key <= SDLK_KP9)
return SDLKey(key - SDLK_KP0 + SDLK_0);
#endif // 0
#define REMOVE_KP(keyName) case SDLK_KP_ ## keyName : return SDLK_ ## keyName;
switch(key)
{
#ifndef VCMI_SDL1
REMOVE_KP(0)
REMOVE_KP(1)
REMOVE_KP(2)
REMOVE_KP(3)
REMOVE_KP(4)
REMOVE_KP(5)
REMOVE_KP(6)
REMOVE_KP(7)
REMOVE_KP(8)
REMOVE_KP(9)
#endif // VCMI_SDL1
REMOVE_KP(PERIOD)
REMOVE_KP(MINUS)
REMOVE_KP(PLUS)
REMOVE_KP(EQUALS)
REMOVE_KP(MINUS)
REMOVE_KP(PLUS)
REMOVE_KP(EQUALS)
case SDLK_KP_MULTIPLY:
return SDLK_ASTERISK;
@ -475,15 +540,22 @@ SDLKey CGuiHandler::numToDigit( SDLKey key )
bool CGuiHandler::isNumKey( SDLKey key, bool number )
{
#ifdef VCMI_SDL1
if(number)
return key >= SDLK_KP0 && key <= SDLK_KP9;
else
return key >= SDLK_KP0 && key <= SDLK_KP_EQUALS;
#else
if(number)
return key >= SDLK_KP_1 && key <= SDLK_KP_0;
else
return (key >= SDLK_KP_1 && key <= SDLK_KP_0) || key == SDLK_KP_MINUS || key == SDLK_KP_PLUS || key == SDLK_KP_EQUALS;
#endif // 0
}
bool CGuiHandler::isArrowKey( SDLKey key )
{
return key >= SDLK_UP && key <= SDLK_LEFT;
return key == SDLK_UP || key == SDLK_DOWN || key == SDLK_LEFT || key == SDLK_RIGHT;
}
bool CGuiHandler::amIGuiThread()

View File

@ -2,11 +2,13 @@
#include "../../lib/CStopWatch.h"
#include "Geometries.h"
#include "SDL_Extensions.h"
class CFramerateManager;
class CGStatusBar;
class CIntObject;
class IUpdateable;
class ILockedUpdatable;
class IShowActivatable;
class IShowable;
@ -57,6 +59,9 @@ private:
timeinterested,
wheelInterested,
doubleClickInterested;
#ifndef VCMI_SDL1
CIntObjectList textInterested;
#endif // VCMI_SDL1
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
public:
@ -68,15 +73,15 @@ public:
std::vector<IShowable*> objsToBlit;
SDL_Event * current; //current event - can be set to nullptr to stop handling event
IUpdateable *curInt;
ILockedUpdatable *curInt;
Point lastClick;
unsigned lastClickTime;
bool terminate;
CGuiHandler();
~CGuiHandler();
void run(); // holds the main loop for the whole program after initialization and manages the update/rendering system
void renderFrame();
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering

View File

@ -4,6 +4,12 @@
#include "SDL_Extensions.h"
#include "../CMessage.h"
void ILockedUpdatable::runLocked(std::function<void(IUpdateable*)> cb)
{
boost::unique_lock<boost::recursive_mutex> lock(updateGuard);
cb(this);
}
CIntObject::CIntObject(int used_, Point pos_):
parent_m(nullptr),
active_m(0),

View File

@ -1,13 +1,3 @@
#pragma once
#include <SDL_events.h>
#include "Geometries.h"
#include "../Graphics.h"
struct SDL_Surface;
class CPicture;
class CGuiHandler;
/*
* CIntObject.h, part of VCMI engine
*
@ -17,6 +7,16 @@ class CGuiHandler;
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include <SDL_events.h>
#include "Geometries.h"
#include "../Graphics.h"
struct SDL_Surface;
class CPicture;
class CGuiHandler;
using boost::logic::tribool;
@ -36,6 +36,14 @@ public:
virtual ~IUpdateable(){}; //d-tor
};
class ILockedUpdatable: protected IUpdateable
{
boost::recursive_mutex updateGuard;
public:
virtual void runLocked(std::function<void(IUpdateable * )> cb);
virtual ~ILockedUpdatable(){}; //d-tor
};
// Defines a show method
class IShowable
{
@ -123,6 +131,11 @@ public:
bool captureAllKeys; //if true, only this object should get info about pressed keys
virtual void keyPressed(const SDL_KeyboardEvent & key){}
virtual bool captureThisEvent(const SDL_KeyboardEvent & key); //allows refining captureAllKeys against specific events (eg. don't capture ENTER)
#ifndef VCMI_SDL1
virtual void textInputed(const SDL_TextInputEvent & event){};
virtual void textEdited(const SDL_TextEditingEvent & event){};
#endif // VCMI_SDL1
//mouse movement handling
bool strongInterest; //if true - report all mouse movements, if not - only when hovered
@ -138,7 +151,7 @@ public:
//double click
virtual void onDoubleClick(){}
enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64, WHEEL=128, DOUBLECLICK=256, ALL=0xffff};
enum {LCLICK=1, RCLICK=2, HOVER=4, MOVE=8, KEYBOARD=16, TIME=32, GENERAL=64, WHEEL=128, DOUBLECLICK=256, TEXTINPUT=512, ALL=0xffff};
const ui16 & active;
void addUsedEvents(ui16 newActions);
void removeUsedEvents(ui16 newActions);

View File

@ -18,6 +18,7 @@
#include "../GUIClasses.h"
#include "CGuiHandler.h"
#include "../CAdvmapInterface.h"
#include "../../lib/CGeneralTextHandler.h" //for Unicode related stuff
CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free )
{
@ -128,13 +129,17 @@ void CPicture::convertToScreenBPP()
{
SDL_Surface *hlp = bg;
bg = SDL_ConvertSurface(hlp,screen->format,0);
SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
CSDL_Ext::setDefaultColorKey(bg);
SDL_FreeSurface(hlp);
}
void CPicture::setAlpha(int value)
{
SDL_SetAlpha(bg, SDL_SRCALPHA, value);
{
#ifdef VCMI_SDL1
SDL_SetAlpha(bg, SDL_SRCALPHA, value);
#else
SDL_SetSurfaceAlphaMod(bg,value);
#endif // 0
}
void CPicture::scaleTo(Point size)
@ -285,7 +290,7 @@ void CButtonBase::block(bool on)
CAdventureMapButton::CAdventureMapButton ()
{
hoverable = actOnDown = borderEnabled = soundDisabled = false;
borderColor.unused = 1; // represents a transparent color, used for HighlightableButton
CSDL_Ext::colorSetAlpha(borderColor,1);// represents a transparent color, used for HighlightableButton
addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD);
}
@ -404,7 +409,7 @@ void CAdventureMapButton::init(const CFunctionList<void()> &Callback, const std:
addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD);
callback = Callback;
hoverable = actOnDown = borderEnabled = soundDisabled = false;
borderColor.unused = 1; // represents a transparent color, used for HighlightableButton
CSDL_Ext::colorSetAlpha(borderColor,1);// represents a transparent color, used for HighlightableButton
hoverTexts = Name;
helpBox=HelpBox;
@ -452,9 +457,14 @@ void CAdventureMapButton::setPlayerColor(PlayerColor player)
void CAdventureMapButton::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
#ifdef VCMI_SDL1
if (borderEnabled && borderColor.unused == 0)
CSDL_Ext::drawBorder(to, pos.x-1, pos.y-1, pos.w+2, pos.h+2, int3(borderColor.r, borderColor.g, borderColor.b));
CSDL_Ext::drawBorder(to, pos.x-1, pos.y-1, pos.w+2, pos.h+2, int3(borderColor.r, borderColor.g, borderColor.b));
#else
if (borderEnabled && borderColor.a == 0)
CSDL_Ext::drawBorder(to, pos.x-1, pos.y-1, pos.w+2, pos.h+2, int3(borderColor.r, borderColor.g, borderColor.b));
#endif // 0
}
void CHighlightableButton::select(bool on)
@ -840,7 +850,7 @@ void CSlider::setAmount( int to )
void CSlider::showAll(SDL_Surface * to)
{
CSDL_Ext::fillRect(to, &pos, 0);
CSDL_Ext::fillRectBlack(to, &pos);
CIntObject::showAll(to);
}
@ -1536,7 +1546,7 @@ CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(co
pos.w = Pos.w;
captureAllKeys = true;
bg = nullptr;
addUsedEvents(LCLICK | KEYBOARD);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus();
}
@ -1548,7 +1558,7 @@ CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::strin
captureAllKeys = true;
OBJ_CONSTRUCTION;
bg = new CPicture(bgName, bgOffset.x, bgOffset.y);
addUsedEvents(LCLICK | KEYBOARD);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus();
}
@ -1567,13 +1577,24 @@ CTextInput::CTextInput(const Rect &Pos, SDL_Surface *srf)
pos.w = bg->pos.w;
pos.h = bg->pos.h;
bg->pos = pos;
addUsedEvents(LCLICK | KEYBOARD);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus();
}
void CTextInput::focusGot()
{
CSDL_Ext::startTextInput(&pos);
}
void CTextInput::focusLost()
{
CSDL_Ext::stopTextInput();
}
std::string CTextInput::visibleText()
{
return focus ? text + "_" : text;
return focus ? text + newText + "_" : text;
}
void CTextInput::clickLeft( tribool down, bool previousState )
@ -1584,6 +1605,7 @@ void CTextInput::clickLeft( tribool down, bool previousState )
void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
{
if(!focus || key.state != SDL_PRESSED)
return;
@ -1594,29 +1616,46 @@ void CTextInput::keyPressed( const SDL_KeyboardEvent & key )
return;
}
bool redrawNeeded = false;
#ifdef VCMI_SDL1
std::string oldText = text;
#endif // 0
switch(key.keysym.sym)
{
case SDLK_DELETE: // have index > ' ' so it won't be filtered out by default section
return;
case SDLK_BACKSPACE:
if(!text.empty())
text.resize(text.size()-1);
if(!newText.empty())
{
Unicode::trimRight(newText);
redrawNeeded = true;
}
else if(!text.empty())
{
Unicode::trimRight(text);
redrawNeeded = true;
}
break;
default:
#ifdef VCMI_SDL1
if (key.keysym.unicode < ' ')
return;
else
{
text += key.keysym.unicode; //TODO 16-/>8
redrawNeeded = true;
}
#endif // 0
break;
}
#ifdef VCMI_SDL1
filters(text, oldText);
if (text != oldText)
#endif // 0
if (redrawNeeded)
{
redraw();
cb(text);
}
}
}
void CTextInput::setText( const std::string &nText, bool callCb )
@ -1630,14 +1669,49 @@ bool CTextInput::captureThisEvent(const SDL_KeyboardEvent & key)
{
if(key.keysym.sym == SDLK_RETURN || key.keysym.sym == SDLK_KP_ENTER)
return false;
#ifdef VCMI_SDL1
//this should allow all non-printable keys to go through (for example arrows)
if (key.keysym.unicode < ' ')
return false;
return true;
#else
return false;
#endif
}
#ifndef VCMI_SDL1
void CTextInput::textInputed(const SDL_TextInputEvent & event)
{
if(!focus)
return;
std::string oldText = text;
text += event.text;
filters(text,oldText);
if (text != oldText)
{
redraw();
cb(text);
}
newText = "";
}
void CTextInput::textEdited(const SDL_TextEditingEvent & event)
{
if(!focus)
return;
newText = event.text;
redraw();
cb(text+newText);
}
#endif
void CTextInput::filenameFilter(std::string & text, const std::string &)
{
static const std::string forbiddenChars = "<>:\"/\\|?*\r\n"; //if we are entering a filename, some special characters won't be allowed
@ -1690,7 +1764,10 @@ CFocusable::CFocusable()
CFocusable::~CFocusable()
{
if(inputWithFocus == this)
{
focusLost();
inputWithFocus = nullptr;
}
focusables -= this;
}
@ -1699,12 +1776,14 @@ void CFocusable::giveFocus()
if(inputWithFocus)
{
inputWithFocus->focus = false;
inputWithFocus->focusLost();
inputWithFocus->redraw();
}
focus = true;
inputWithFocus = this;
redraw();
focusGot();
redraw();
}
void CFocusable::moveFocus()

View File

@ -217,7 +217,7 @@ public:
void wheelScrolled(bool down, bool in);
void clickLeft(tribool down, bool previousState);
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void showAll(SDL_Surface * to);
void showAll(SDL_Surface * to);
CSlider(int x, int y, int totalw, std::function<void(int)> Moved, int Capacity, int Amount,
int Value=0, bool Horizontal=true, int style = 0); //style 0 - brown, 1 - blue
@ -436,6 +436,9 @@ public:
/// UIElement which can get input focus
class CFocusable : public virtual CIntObject
{
protected:
virtual void focusGot(){};
virtual void focusLost(){};
public:
bool focus; //only one focusable control can have focus at one moment
@ -451,9 +454,12 @@ public:
/// Text input box where players can enter text
class CTextInput : public CLabel, public CFocusable
{
std::string newText;
protected:
std::string visibleText() override;
void focusGot() override;
void focusLost() override;
public:
CFunctionList<void(const std::string &)> cb;
CFunctionList<void(std::string &, const std::string &)> filters;
@ -466,6 +472,13 @@ public:
void clickLeft(tribool down, bool previousState) override;
void keyPressed(const SDL_KeyboardEvent & key) override;
bool captureThisEvent(const SDL_KeyboardEvent & key) override;
#ifndef VCMI_SDL1
void textInputed(const SDL_TextInputEvent & event) override;
void textEdited(const SDL_TextEditingEvent & event) override;
#endif // VCMI_SDL1
//Filter that will block all characters not allowed in filenames
static void filenameFilter(std::string &text, const std::string & oldText);

37
client/gui/SDL_Compat.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
/*
* SDL_Compat.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
*
*/
#include <SDL_version.h>
#if (SDL_MAJOR_VERSION == 2)
#define VCMI_SDL2
#include <SDL_keycode.h>
typedef int SDLX_Coord;
typedef int SDLX_Size;
typedef SDL_Keycode SDLKey;
#define SDL_SRCCOLORKEY SDL_TRUE
#define SDL_FULLSCREEN SDL_WINDOW_FULLSCREEN
#elif (SDL_MAJOR_VERSION == 1)
#define VCMI_SDL1
//SDL 1.x
typedef Sint16 SDLX_Coord;
typedef Uint16 SDLX_Size;
#else
#error "unknown or unsupported SDL version"
#endif

View File

@ -7,11 +7,28 @@
#include "../CMessage.h"
#include "../CDefHandler.h"
#include "../Graphics.h"
#include "../CMT.h"
const SDL_Color Colors::YELLOW = { 229, 215, 123, 0 };
const SDL_Color Colors::WHITE = { 255, 243, 222, 0 };
const SDL_Color Colors::METALLIC_GOLD = { 173, 142, 66, 0 };
const SDL_Color Colors::GREEN = { 0, 255, 0, 0 };
const SDL_Color Colors::DEFAULT_KEY_COLOR = {0, 255, 255, 0};
#if (SDL_MAJOR_VERSION == 2)
void SDL_UpdateRect(SDL_Surface *surface, int x, int y, int w, int h)
{
Rect rect(x,y,w,h);
if(0 !=SDL_UpdateTexture(screenTexture, &rect, surface->pixels, surface->pitch))
logGlobal->errorStream() << __FUNCTION__ << "SDL_UpdateTexture " << SDL_GetError();
SDL_RenderClear(mainRenderer);
if(0 != SDL_RenderCopy(mainRenderer, screenTexture, NULL, NULL))
logGlobal->errorStream() << __FUNCTION__ << "SDL_RenderCopy " << SDL_GetError();
SDL_RenderPresent(mainRenderer);
}
#endif // VCMI_SDL1
SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
{
@ -444,7 +461,11 @@ int CSDL_Ext::blit8bppAlphaTo24bppT(const SDL_Surface * src, const SDL_Rect * sr
for(int x = w; x; x--)
{
const SDL_Color &tbc = colors[*color++]; //color to blit
#ifdef VCMI_SDL1
ColorPutter<bpp, +1>::PutColorAlphaSwitch(p, tbc.r, tbc.g, tbc.b, tbc.unused);
#else
ColorPutter<bpp, +1>::PutColorAlphaSwitch(p, tbc.r, tbc.g, tbc.b, tbc.a);
#endif // 0
}
}
SDL_UnlockSurface(dst);
@ -469,7 +490,11 @@ int CSDL_Ext::blit8bppAlphaTo24bpp(const SDL_Surface * src, const SDL_Rect * src
Uint32 CSDL_Ext::colorToUint32(const SDL_Color * color)
{
Uint32 ret = 0;
#ifdef VCMI_SDL1
ret+=color->unused;
#else
ret+=color->a;
#endif // 0
ret<<=8; //*=256
ret+=color->b;
ret<<=8; //*=256
@ -481,8 +506,15 @@ Uint32 CSDL_Ext::colorToUint32(const SDL_Color * color)
void CSDL_Ext::update(SDL_Surface * what)
{
#ifdef VCMI_SDL1
if(what)
SDL_UpdateRect(what, 0, 0, what->w, what->h);
SDL_UpdateRect(what, 0, 0, what->w, what->h);
#else
if(!what)
return;
if(0 !=SDL_UpdateTexture(screenTexture, nullptr, what->pixels, what->pitch))
logGlobal->errorStream() << __FUNCTION__ << "SDL_UpdateTexture " << SDL_GetError();
#endif // VCMI_SDL1
}
void CSDL_Ext::drawBorder(SDL_Surface * sur, int x, int y, int w, int h, const int3 &color)
{
@ -601,14 +633,22 @@ bool CSDL_Ext::isTransparent( SDL_Surface * srf, int x, int y )
return true;
SDL_Color color;
#ifdef VCMI_SDL1
SDL_GetRGBA(SDL_GetPixel(srf, x, y), srf->format, &color.r, &color.g, &color.b, &color.unused);
#else
SDL_GetRGBA(SDL_GetPixel(srf, x, y), srf->format, &color.r, &color.g, &color.b, &color.a);
#endif // 0
// color is considered transparent here if
// a) image has aplha: less than 50% transparency
// b) no alpha: color is cyan
if (srf->format->Amask)
#ifdef VCMI_SDL1
return color.unused < 128; // almost transparent
#else
return color.a < 128; // almost transparent
#endif // 0
else
return (color.r == 0 && color.g == 255 && color.b == 255);
}
@ -915,6 +955,12 @@ void CSDL_Ext::fillRect( SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color )
SDL_FillRect(dst, &newRect, color);
}
void CSDL_Ext::fillRectBlack( SDL_Surface *dst, SDL_Rect *dstrect)
{
const Uint32 black = SDL_MapRGB(dst->format,0,0,0);
fillRect(dst,dstrect,black);
}
void CSDL_Ext::fillTexture(SDL_Surface *dst, SDL_Surface * src)
{
SDL_Rect srcRect;
@ -941,6 +987,59 @@ SDL_Color CSDL_Ext::makeColor(ui8 r, ui8 g, ui8 b, ui8 a)
return ret;
}
void CSDL_Ext::startTextInput(SDL_Rect * where)
{
#ifndef VCMI_SDL1
if (SDL_IsTextInputActive() == SDL_FALSE)
{
SDL_StartTextInput();
}
SDL_SetTextInputRect(where);
#endif
}
void CSDL_Ext::stopTextInput()
{
#ifndef VCMI_SDL1
if (SDL_IsTextInputActive() == SDL_TRUE)
{
SDL_StopTextInput();
}
#endif
}
STRONG_INLINE static uint32_t mapColor(SDL_Surface * surface, SDL_Color color)
{
#ifdef VCMI_SDL1
return SDL_MapRGB(surface->format, color.r, color.g, color.b);
#else
return SDL_MapRGBA(surface->format, color.r, color.g, color.b, color.a);
#endif
}
void CSDL_Ext::setColorKey(SDL_Surface * surface, SDL_Color color)
{
uint32_t key = mapColor(surface,color);
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, key);
}
void CSDL_Ext::setDefaultColorKey(SDL_Surface * surface)
{
setColorKey(surface, Colors::DEFAULT_KEY_COLOR);
}
void CSDL_Ext::setDefaultColorKeyPresize(SDL_Surface * surface)
{
uint32_t key = mapColor(surface,Colors::DEFAULT_KEY_COLOR);
auto & color = surface->format->palette->colors[key];
// set color key only if exactly such color was found
if (color.r == Colors::DEFAULT_KEY_COLOR.r && color.g == Colors::DEFAULT_KEY_COLOR.g && color.b == Colors::DEFAULT_KEY_COLOR.b)
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, key);
}
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<2>(int, int);
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<3>(int, int);
template SDL_Surface * CSDL_Ext::createSurfaceWithBpp<4>(int, int);

View File

@ -1,11 +1,3 @@
#pragma once
#include <SDL_video.h>
#include <SDL_ttf.h>
#include "../../lib/int3.h"
#include "../Graphics.h"
#include "Geometries.h"
/*
* SDL_Extensions.h, part of VCMI engine
*
@ -15,6 +7,20 @@
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include <SDL_version.h>
#ifndef VCMI_SDL1
#include <SDL_render.h>
#endif
#include <SDL_video.h>
#include <SDL_ttf.h>
#include "../../lib/int3.h"
#include "../Graphics.h"
#include "Geometries.h"
//A macro to force inlining some of our functions. Compiler (at least MSVC) is not so smart here-> without that displaying is MUCH slower
#ifdef _MSC_VER
@ -29,6 +35,75 @@
#define SDL_GetKeyState SDL_GetKeyboardState
#endif
//SDL2 support
#if (SDL_MAJOR_VERSION == 2)
extern SDL_Window * mainWindow;
extern SDL_Renderer * mainRenderer;
extern SDL_Texture * screenTexture;
inline void SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors)
{
SDL_SetPaletteColors(surface->format->palette,colors,firstcolor,ncolors);
}
inline void SDL_WarpMouse(int x, int y)
{
SDL_WarpMouseInWindow(mainWindow,x,y);
}
void SDL_UpdateRect(SDL_Surface *surface, int x, int y, int w, int h);
#endif
inline bool isCtrlKeyDown()
{
#ifdef VCMI_SDL1
return SDL_GetKeyState(nullptr)[SDLK_LCTRL] || SDL_GetKeyState(nullptr)[SDLK_RCTRL];
#else
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LCTRL] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RCTRL];
#endif
}
inline bool isAltKeyDown()
{
#ifdef VCMI_SDL1
return SDL_GetKeyState(nullptr)[SDLK_LALT] || SDL_GetKeyState(nullptr)[SDLK_RALT];
#else
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LALT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RALT];
#endif
}
inline bool isShiftKeyDown()
{
#ifdef VCMI_SDL1
return SDL_GetKeyState(nullptr)[SDLK_LSHIFT] || SDL_GetKeyState(nullptr)[SDLK_RSHIFT];
#else
return SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_LSHIFT] || SDL_GetKeyboardState(nullptr)[SDL_SCANCODE_RSHIFT];
#endif
}
namespace CSDL_Ext
{
STRONG_INLINE void colorSetAlpha(SDL_Color & color, Uint8 alpha)
{
#ifdef VCMI_SDL1
color.unused = alpha;
#else
color.a = alpha;
#endif
}
//todo: should this better be assignment operator?
STRONG_INLINE void colorAssign(SDL_Color & dest, const SDL_Color & source)
{
dest.r = source.r;
dest.g = source.g;
dest.b = source.b;
#ifdef VCMI_SDL1
dest.unused = source.unused;
#else
dest.a = source.a;
#endif
}
}
struct Rect;
extern SDL_Surface * screen, *screen2, *screenBuf;
@ -53,6 +128,9 @@ public:
/** green color used for in-game console */
static const SDL_Color GREEN;
/** default key color for all 8 & 24 bit graphics */
static const SDL_Color DEFAULT_KEY_COLOR;
};
//MSVC gives an error when calling abs with ui64 -> we add template that will match calls with unsigned arg and return it
@ -130,6 +208,7 @@ namespace CSDL_Ext
void blitSurface(SDL_Surface * src, SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect);
void fillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
void fillRectBlack(SDL_Surface * dst, SDL_Rect * dstrect);
//fill dest image with source texture.
void fillTexture(SDL_Surface *dst, SDL_Surface * sourceTexture);
@ -188,4 +267,13 @@ namespace CSDL_Ext
template<int bpp>
void applyEffectBpp( SDL_Surface * surf, const SDL_Rect * rect, int mode );
void applyEffect(SDL_Surface * surf, const SDL_Rect * rect, int mode); //mode: 0 - sepia, 1 - grayscale
void startTextInput(SDL_Rect * where);
void stopTextInput();
void setColorKey(SDL_Surface * surface, SDL_Color color);
///set key-color to 0,255,255
void setDefaultColorKey(SDL_Surface * surface);
///set key-color to 0,255,255 only if it exactly mapped
void setDefaultColorKeyPresize(SDL_Surface * surface);
}

View File

@ -133,7 +133,11 @@ struct ColorPutter<2, incrementPtr>
template<int bpp, int incrementPtr>
STRONG_INLINE void ColorPutter<bpp, incrementPtr>::PutColorAlpha(Uint8 *&ptr, const SDL_Color & Color)
{
#ifdef VCMI_SDL1
PutColor(ptr, Color.r, Color.g, Color.b, Color.unused);
#else
PutColor(ptr, Color.r, Color.g, Color.b, Color.a);
#endif
}
template<int bpp, int incrementPtr>
@ -262,7 +266,11 @@ STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColor(Uint8 *&ptr, const Uin
template <int incrementPtr>
STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColorAlpha(Uint8 *&ptr, const SDL_Color & Color)
{
#ifdef VCMI_SDL1
PutColor(ptr, Color.r, Color.g, Color.b, Color.unused);
#else
PutColor(ptr, Color.r, Color.g, Color.b, Color.a);
#endif
}
template <int incrementPtr>
@ -285,4 +293,4 @@ STRONG_INLINE void ColorPutter<2, incrementPtr>::PutColorRow(Uint8 *&ptr, const
if(incrementPtr == 1)
ptr += 2;
}
}
}

View File

@ -80,6 +80,69 @@ static bool objectBlitOrderSorter(const std::pair<const CGObjectInstance*,SDL_Re
return CMapHandler::compareObjectBlitOrder(a.first, b.first);
}
struct NeighborTilesInfo
{
bool d7, //789
d8, //456
d9, //123
d4,
d5,
d6,
d1,
d2,
d3;
NeighborTilesInfo(const int3 & pos, const int3 & sizes, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap)
{
auto getTile = [&](int dx, int dy)->bool
{
if ( dx + pos.x < 0 || dx + pos.x >= sizes.x
|| dy + pos.y < 0 || dy + pos.y >= sizes.y)
return false;
return visibilityMap[dx+pos.x][dy+pos.y][pos.z];
};
d7 = getTile(-1, -1); //789
d8 = getTile( 0, -1); //456
d9 = getTile(+1, -1); //123
d4 = getTile(-1, 0);
d5 = visibilityMap[pos.x][pos.y][pos.z];
d6 = getTile(+1, 0);
d1 = getTile(-1, +1);
d2 = getTile( 0, +1);
d3 = getTile(+1, +1);
}
bool areAllHidden() const
{
return !(d1 || d2 || d3 || d4 || d5 || d6 || d7 || d8 || d8 );
}
int getBitmapID() const
{
//NOTE: some images have unused in VCMI pair (same blockmap but a bit different look)
// 0-1, 2-3, 4-5, 11-13, 12-14
static const int visBitmaps[256] = {
-1, 34, 4, 4, 22, 23, 4, 4, 36, 36, 38, 38, 47, 47, 38, 38, //16
3, 25, 12, 12, 3, 25, 12, 12, 9, 9, 6, 6, 9, 9, 6, 6, //32
35, 39, 48, 48, 41, 43, 48, 48, 36, 36, 38, 38, 47, 47, 38, 38, //48
26, 49, 28, 28, 26, 49, 28, 28, 9, 9, 6, 6, 9, 9, 6, 6, //64
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //80
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, //96
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //112
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, //128
15, 17, 30, 30, 16, 19, 30, 30, 46, 46, 40, 40, 32, 32, 40, 40, //144
2, 25, 12, 12, 2, 25, 12, 12, 9, 9, 6, 6, 9, 9, 6, 6, //160
18, 42, 31, 31, 20, 21, 31, 31, 46, 46, 40, 40, 32, 32, 40, 40, //176
26, 49, 28, 28, 26, 49, 28, 28, 9, 9, 6, 6, 9, 9, 6, 6, //192
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //208
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, //224
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //240
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10 //256
};
return visBitmaps[d1 + d2 * 2 + d3 * 4 + d4 * 8 + d6 * 16 + d7 * 32 + d8 * 64 + d9 * 128]; // >=0 -> partial hide, <0 - full hide
}
};
void CMapHandler::prepareFOWDefs()
{
graphics->FoWfullHide = CDefHandler::giveDef("TSHRC.DEF");
@ -434,6 +497,15 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
// Skip tile if not in map
if (pos.y < 0 || pos.y >= sizes.y)
continue;
//we should not render fully hidden tiles
if(!puzzleMode)
{
const NeighborTilesInfo info(pos,sizes,*visibilityMap);
if(info.areAllHidden())
continue;
}
const TerrainTile2 & tile = ttiles[pos.x][pos.y][pos.z];
const TerrainTile &tinfo = map->getTile(int3(pos.x, pos.y, pos.z));
@ -492,7 +564,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
if(obj->ID != Obj::HERO && !obj->coveringAt(top_tile.x + bx, top_tile.y + by))
continue;
static const int notBlittedInPuzzleMode[] = {124};
static const int notBlittedInPuzzleMode[] = {Obj::HOLE};
//don't print flaggable objects in puzzle mode
if(puzzleMode && (obj->isVisitable() || std::find(notBlittedInPuzzleMode, notBlittedInPuzzleMode+1, obj->ID) != notBlittedInPuzzleMode+1)) //?
@ -766,52 +838,13 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
std::pair<SDL_Surface *, bool> CMapHandler::getVisBitmap( const int3 & pos, const std::vector< std::vector< std::vector<ui8> > > & visibilityMap ) const
{
//NOTE: some images have unused in VCMI pair (same blockmap but a bit different look)
// 0-1, 2-3, 4-5, 11-13, 12-14
static const int visBitmaps[256] = {
-1, 34, 4, 4, 22, 23, 4, 4, 36, 36, 38, 38, 47, 47, 38, 38, //16
3, 25, 12, 12, 3, 25, 12, 12, 9, 9, 6, 6, 9, 9, 6, 6, //32
35, 39, 48, 48, 41, 43, 48, 48, 36, 36, 38, 38, 47, 47, 38, 38, //48
26, 49, 28, 28, 26, 49, 28, 28, 9, 9, 6, 6, 9, 9, 6, 6, //64
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //80
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, //96
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //112
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, //128
15, 17, 30, 30, 16, 19, 30, 30, 46, 46, 40, 40, 32, 32, 40, 40, //144
2, 25, 12, 12, 2, 25, 12, 12, 9, 9, 6, 6, 9, 9, 6, 6, //160
18, 42, 31, 31, 20, 21, 31, 31, 46, 46, 40, 40, 32, 32, 40, 40, //176
26, 49, 28, 28, 26, 49, 28, 28, 9, 9, 6, 6, 9, 9, 6, 6, //192
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //208
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10, //224
0, 45, 29, 29, 24, 33, 29, 29, 37, 37, 7, 7, 50, 50, 7, 7, //240
13, 27, 44, 44, 13, 27, 44, 44, 8, 8, 10, 10, 8, 8, 10, 10 //256
};
const NeighborTilesInfo info(pos,sizes,visibilityMap);
auto getTile = [&](int dx, int dy)->bool
{
if ( dx + pos.x < 0 || dx + pos.x >= sizes.x
|| dy + pos.y < 0 || dy + pos.y >= sizes.y)
return false;
return visibilityMap[dx+pos.x][dy+pos.y][pos.z];
};
//is tile visible. arrangement: (like num keyboard)
bool d7 = getTile(-1, -1), //789
d8 = getTile( 0, -1), //456
d9 = getTile(+1, -1), //123
d4 = getTile(-1, 0),
d6 = getTile(+1, 0),
d1 = getTile(-1, +1),
d2 = getTile( 0, +1),
d3 = getTile(+1, +1);
int retBitmapID = visBitmaps[d1 + d2 * 2 + d3 * 4 + d4 * 8 + d6 * 16 + d7 * 32 + d8 * 64 + d9 * 128]; // >=0 -> partial hide, <0 - full hide
int retBitmapID = info.getBitmapID();// >=0 -> partial hide, <0 - full hide
if (retBitmapID < 0)
{
retBitmapID = - hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden
}
if (retBitmapID >= 0)
{

View File

@ -1,27 +0,0 @@
The following files are derived from the Thermite project
(http://www.thermite3d.org) and are covered under the license below.
FindMYGUI.cmake, FindOGRE.cmake, FindOIS.cmake, FindBullet.cmake
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,216 @@
#.rst:
# FindSDL2
# --------
#
# Locate SDL2 library
#
# This module defines
#
# ::
#
# SDL2_LIBRARY, the name of the library to link against
# SDL2_FOUND, if false, do not try to link to SDL
# SDL2_INCLUDE_DIR, where to find SDL.h
# SDL2_VERSION_STRING, human-readable string containing the version of SDL
#
#
#
# This module responds to the flag:
#
# ::
#
# SDL2_BUILDING_LIBRARY
# If this is defined, then no SDL2_main will be linked in because
# only applications need main().
# Otherwise, it is assumed you are building an application and this
# module will attempt to locate and set the proper link flags
# as part of the returned SDL2_LIBRARY variable.
#
#
#
# Don't forget to include SDLmain.h and SDLmain.m your project for the
# OS X framework based version. (Other versions link to -lSDL2main which
# this module will try to find on your behalf.) Also for OS X, this
# module will automatically add the -framework Cocoa on your behalf.
#
#
#
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your
# configuration and no SDL2_LIBRARY, it means CMake did not find your SDL
# library (SDL2.dll, libSDL2.so, SDL.framework, etc). Set
# SDL2_LIBRARY_TEMP to point to your SDL library, and configure again.
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this
# value as appropriate. These values are used to generate the final
# SDL2_LIBRARY variable, but when these values are unset, SDL2_LIBRARY
# does not get created.
#
#
#
# $SDL2DIR is an environment variable that would correspond to the
# ./configure --prefix=$SDL2DIR used in building SDL. l.e.galup 9-20-02
#
# Modified by Eric Wing. Added code to assist with automated building
# by using environmental variables and providing a more
# controlled/consistent search behavior. Added new modifications to
# recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
# Also corrected the header search path to follow "proper" SDL
# guidelines. Added a search for SDLmain which is needed by some
# platforms. Added a search for threads which is needed by some
# platforms. Added needed compile switches for MinGW.
#
# On OSX, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of SDL2_LIBRARY to
# override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
#
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
# Copyright 2012 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file kitware license.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if (NOT WIN32)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_SDL2 sdl2)
set(SDL2_VERSION_STRING ${_SDL2_VERSION})
endif ()
endif ()
find_path(SDL2_INCLUDE_DIR
SDL.h
HINTS
${_SDL2_INCLUDEDIR}
ENV SDL2DIR
PATH_SUFFIXES
SDL2
include/SDL2
include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_LIBRARY_TEMP
NAMES
SDL2
HINTS
${_SDL2_LIBDIR}
ENV SDL2DIR
PATH_SUFFIXES
lib
${VC_LIB_PATH_SUFFIX}
)
if(NOT SDL2_BUILDING_LIBRARY)
if(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
# Non-OS X framework versions expect you to also dynamically link to
# SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms
# seem to provide SDLmain for compatibility even though they don't
# necessarily need it.
find_library(SDL2MAIN_LIBRARY
NAMES
SDL2main
HINTS
ENV SDL2DIR
PATH_SUFFIXES
lib
${VC_LIB_PATH_SUFFIX}
PATHS
/sw
/opt/local
/opt/csw
/opt
)
endif()
endif()
# SDL may require threads on your system.
# The Apple build may not need an explicit flag because one of the
# frameworks may already provide it.
# But for non-OSX systems, I will use the CMake Threads package.
if(NOT APPLE)
find_package(Threads)
endif()
# MinGW needs an additional library, mwindows
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL -lmwindows
# (Actually on second look, I think it only needs one of the m* libraries.)
if(MINGW)
set(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
endif()
if(SDL2_LIBRARY_TEMP)
# For SDLmain
if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY)
list(FIND SDL2_LIBRARY_TEMP "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX)
if(_SDL2_MAIN_INDEX EQUAL -1)
set(SDL2_LIBRARY_TEMP "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARY_TEMP})
endif()
unset(_SDL2_MAIN_INDEX)
endif()
# For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
# CMake doesn't display the -framework Cocoa string in the UI even
# though it actually is there if I modify a pre-used variable.
# I think it has something to do with the CACHE STRING.
# So I use a temporary variable until the end so I can set the
# "real" variable in one-shot.
if(APPLE)
set(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
endif()
# For threads, as mentioned Apple doesn't need this.
# In fact, there seems to be a problem if I used the Threads package
# and try using this line, so I'm just skipping it entirely for OS X.
if(NOT APPLE)
set(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
endif()
# For MinGW library
if(MINGW)
set(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
endif()
# Set the final string here so the GUI reflects the final state.
set(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found")
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
set(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
endif()
if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h" AND NOT SDL2_VERSION_STRING)
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH})
unset(SDL2_VERSION_MAJOR_LINE)
unset(SDL2_VERSION_MINOR_LINE)
unset(SDL2_VERSION_PATCH_LINE)
unset(SDL2_VERSION_MAJOR)
unset(SDL2_VERSION_MINOR)
unset(SDL2_VERSION_PATCH)
endif()
set(SDL2_LIBRARIES ${SDL2_LIBRARY})
set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
VERSION_VAR SDL2_VERSION_STRING)

View File

@ -0,0 +1,100 @@
#.rst:
# FindSDL2_image
# --------------
#
# Locate SDL2_image library
#
# This module defines:
#
# ::
#
# SDL2_IMAGE_LIBRARIES, the name of the library to link against
# SDL2_IMAGE_INCLUDE_DIRS, where to find the headers
# SDL2_IMAGE_FOUND, if false, do not try to link against
# SDL2_IMAGE_VERSION_STRING - human-readable string containing the version of SDL2_image
#
# $SDL2DIR is an environment variable that would correspond to the
# ./configure --prefix=$SDL2DIR used in building SDL.
#
# Created by Eric Wing. This was influenced by the FindSDL2.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
# Copyright 2012 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file kitware license.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if (NOT WIN32)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_SDL2_IMAGE SDL2_image)
set(SDL2_IMAGE_VERSION_STRING ${_SDL2_IMAGE_VERSION})
endif ()
endif ()
find_path(SDL2_IMAGE_INCLUDE_DIR
SDL_image.h
HINTS
${_SDL2_IMAGE_INCLUDEDIR}
ENV SDL2IMAGEDIR
ENV SDL2DIR
PATH_SUFFIXES
SDL2
include/SDL2
include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_IMAGE_LIBRARY
NAMES
SDL2_image
HINTS
${_SDL2_IMAGE_LIBDIR}
ENV SDL2IMAGEDIR
ENV SDL2DIR
PATH_SUFFIXES
lib
${VC_LIB_PATH_SUFFIX}
)
if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" AND NOT SDL2_IMAGE_VERSION_STRING)
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}")
set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH})
unset(SDL2_IMAGE_VERSION_MAJOR_LINE)
unset(SDL2_IMAGE_VERSION_MINOR_LINE)
unset(SDL2_IMAGE_VERSION_PATCH_LINE)
unset(SDL2_IMAGE_VERSION_MAJOR)
unset(SDL2_IMAGE_VERSION_MINOR)
unset(SDL2_IMAGE_VERSION_PATCH)
endif()
set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY})
set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image
REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS
VERSION_VAR SDL2_IMAGE_VERSION_STRING)
mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)

View File

@ -0,0 +1,101 @@
#.rst:
# FindSDL2_mixer
# --------------
#
# Locate SDL2_mixer library
#
# This module defines:
#
# ::
#
# SDL2_MIXER_LIBRARIES, the name of the library to link against
# SDL2_MIXER_INCLUDE_DIRS, where to find the headers
# SDL2_MIXER_FOUND, if false, do not try to link against
# SDL2_MIXER_VERSION_STRING - human-readable string containing the version of SDL_mixer
#
# $SDL2DIR is an environment variable that would correspond to the
# ./configure --prefix=$SDL2DIR used in building SDL.
#
# Created by Eric Wing. This was influenced by the FindSDL2.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
# Copyright 2012 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file kitware license.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if (NOT WIN32)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_SDL2_MIXER SDL2_mixer)
set(SDL2_MIXER_STRING ${_SDL2_MIXER_VERSION})
endif ()
endif ()
find_path(SDL2_MIXER_INCLUDE_DIR
SDL_mixer.h
HINTS
${_SDL2_MIXER_INCLUDEDIR}
ENV SDL2MIXERDIR
ENV SDL2DIR
PATH_SUFFIXES
SDL2
include/SDL2
include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_MIXER_LIBRARY
NAMES
SDL2_mixer
HINTS
${_SDL2_MIXER_LIBDIR}
ENV SDL2MIXERDIR
ENV SDL2DIR
PATH_SUFFIXES
lib
${VC_LIB_PATH_SUFFIX}
)
if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" AND NOT SDL2_MIXER_STRING)
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH})
unset(SDL2_MIXER_VERSION_MAJOR_LINE)
unset(SDL2_MIXER_VERSION_MINOR_LINE)
unset(SDL2_MIXER_VERSION_PATCH_LINE)
unset(SDL2_MIXER_VERSION_MAJOR)
unset(SDL2_MIXER_VERSION_MINOR)
unset(SDL2_MIXER_VERSION_PATCH)
endif()
set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY})
set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer
REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS
VERSION_VAR SDL2_MIXER_VERSION_STRING)
mark_as_advanced(SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR)

View File

@ -0,0 +1,100 @@
#.rst:
# FindSDL2_ttf
# ------------
#
# Locate SDL2_ttf library
#
# This module defines:
#
# ::
#
# SDL2_TTF_LIBRARIES, the name of the library to link against
# SDL2_TTF_INCLUDE_DIRS, where to find the headers
# SDL2_TTF_FOUND, if false, do not try to link against
# SDL2_TTF_VERSION_STRING - human-readable string containing the version of SDL2_ttf
#
# $SDL2DIR is an environment variable that would correspond to the
# ./configure --prefix=$SDL2DIR used in building SDL.
#
# Created by Eric Wing. This was influenced by the FindSDL2.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
# Copyright 2012 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file kitware license.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if (NOT WIN32)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(_SDL2_TTF SDL2_ttf)
set(SDL2_TTF_VERSION_STRING ${_SDL2_TTF_VERSION})
endif ()
endif ()
find_path(SDL2_TTF_INCLUDE_DIR
SDL_ttf.h
HINTS
${_SDL2_TTF_INCLUDEDIR}
ENV SDL2TTFDIR
ENV SDL2DIR
PATH_SUFFIXES
SDL2
include/SDL2
include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_TTF_LIBRARY
NAMES
SDL2_ttf
HINTS
${_SDL2_TTF_LIBDIR}
ENV SDL2TTFDIR
ENV SDL2DIR
PATH_SUFFIXES
lib
${VC_LIB_PATH_SUFFIX}
)
if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" AND NOT SDL2_TTF_VERSION_STRING)
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH})
unset(SDL2_TTF_VERSION_MAJOR_LINE)
unset(SDL2_TTF_VERSION_MINOR_LINE)
unset(SDL2_TTF_VERSION_PATCH_LINE)
unset(SDL2_TTF_VERSION_MAJOR)
unset(SDL2_TTF_VERSION_MINOR)
unset(SDL2_TTF_VERSION_PATCH)
endif()
set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY})
set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf
REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS
VERSION_VAR SDL2_TTF_VERSION_STRING)
mark_as_advanced(SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR)

View File

@ -0,0 +1,57 @@
CMake - Cross Platform Makefile Generator
Copyright 2000-2014 Kitware, Inc.
Copyright 2000-2011 Insight Software Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the names of Kitware, Inc., the Insight Software Consortium,
nor the names of their contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
The above copyright and license notice applies to distributions of
CMake in source and binary form. Some source files contain additional
notices of original copyright by their contributors; see each source
for details. Third-party software packages supplied with CMake under
compatible licenses provide their own copyright notices documented in
corresponding subdirectories.
------------------------------------------------------------------------------
CMake was initially developed by Kitware with the following sponsorship:
* National Library of Medicine at the National Institutes of Health
as part of the Insight Segmentation and Registration Toolkit (ITK).
* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
Visualization Initiative.
* National Alliance for Medical Image Computing (NAMIC) is funded by the
National Institutes of Health through the NIH Roadmap for Medical Research,
Grant U54 EB005149.
* Kitware, Inc.

View File

@ -49,7 +49,7 @@
"type" : "object",
"additionalProperties" : false,
"default": {},
"required" : [ "screenRes", "bitsPerPixel", "fullscreen", "spellbookAnimation" ],
"required" : [ "screenRes", "bitsPerPixel", "fullscreen", "spellbookAnimation","driver"],
"properties" : {
"screenRes" : {
"type" : "object",
@ -63,7 +63,7 @@
},
"bitsPerPixel" : {
"type" : "number",
"default" : 24
"default" : 32
},
"fullscreen" : {
"type" : "boolean",
@ -73,6 +73,11 @@
"type" : "boolean",
"default" : true
},
"driver":{
"type" : "string",
"default" : "opengl",
"description" : "preferred graphics backend driver name for SDL2"
}
}
},
"adventure" : {

2
debian/rules vendored
View File

@ -5,7 +5,7 @@
# override disabled by default rpath - we need to find libvcmi.so with it:
override_dh_auto_configure:
dh_auto_configure -- -DCMAKE_SKIP_RPATH=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBIN_DIR=games
dh_auto_configure -- -DCMAKE_SKIP_RPATH=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_SDL2=OFF -DBIN_DIR=games
.PHONY: override_dh_strip
override_dh_strip:
dh_strip --dbg-package=vcmi-dbg

View File

@ -51,7 +51,12 @@ set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ${CMAKE_CXX_FLAGS}")
qt5_wrap_ui(launcher_UI_HEADERS ${launcher_FORMS})
add_executable(vcmilauncher ${launcher_SRCS} ${launcher_UI_HEADERS})
if(WIN32)
add_executable(vcmilauncher WIN32 ${launcher_SRCS} ${launcher_UI_HEADERS})
set_target_properties(vcmilauncher PROPERTIES OUTPUT_NAME VCMI_launcher)
else()
add_executable(vcmilauncher ${launcher_SRCS} ${launcher_UI_HEADERS})
endif()
# The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore
target_link_libraries(vcmilauncher vcmi ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES})
@ -61,7 +66,7 @@ target_link_libraries(vcmilauncher vcmi ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIB
#cotire(vcmilauncher)
if (NOT APPLE) # Already inside bundle
install(TARGETS vcmilauncher DESTINATION ${BIN_DIR})
install(TARGETS vcmilauncher DESTINATION ${BIN_DIR})
# copy whole directory but .svn control files
install(DIRECTORY icons DESTINATION ${DATA_DIR}/launcher PATTERN ".svn" EXCLUDE)
endif()

View File

@ -19,7 +19,7 @@
*
*/
size_t Unicode::getCharacterSize(ui8 firstByte)
size_t Unicode::getCharacterSize(char firstByte)
{
// length of utf-8 character can be determined from 1st byte by counting number of highest bits set to 1:
// 0xxxxxxx -> 1 - ASCII chars
@ -27,14 +27,14 @@ size_t Unicode::getCharacterSize(ui8 firstByte)
// 11110xxx -> 4 - last allowed in current standard
// 1111110x -> 6 - last allowed in original standard
if (firstByte < 0x80)
if ((ui8)firstByte < 0x80)
return 1; // ASCII
size_t ret = 0;
for (size_t i=0; i<8; i++)
{
if ((firstByte & (0x80 >> i)) != 0)
if (((ui8)firstByte & (0x80 >> i)) != 0)
ret++;
else
break;
@ -42,12 +42,15 @@ size_t Unicode::getCharacterSize(ui8 firstByte)
return ret;
}
bool Unicode::isValidCharacter(const ui8 *character, size_t maxSize)
bool Unicode::isValidCharacter(const char * character, size_t maxSize)
{
// can't be first byte in UTF8
if ((ui8)character[0] >= 0x80 && (ui8)character[0] < 0xC0)
return false;
// first character must follow rules checked in getCharacterSize
size_t size = getCharacterSize(character[0]);
size_t size = getCharacterSize((ui8)character[0]);
if (character[0] > 0xF4)
if ((ui8)character[0] > 0xF4)
return false; // above maximum allowed in standard (UTF codepoints are capped at 0x0010FFFF)
if (size > maxSize)
@ -56,7 +59,7 @@ bool Unicode::isValidCharacter(const ui8 *character, size_t maxSize)
// remaining characters must have highest bit set to 1
for (size_t i = 1; i < size; i++)
{
if ((character[i] & 0x80) == 0)
if (((ui8)character[i] & 0x80) == 0)
return false;
}
return true;
@ -82,7 +85,7 @@ bool Unicode::isValidString(const std::string & text)
{
for (size_t i=0; i<text.size(); i += getCharacterSize(text[i]))
{
if (!isValidCharacter(reinterpret_cast<const ui8*>(text.data() + i), text.size() - i))
if (!isValidCharacter(text.data() + i, text.size() - i))
return false;
}
return true;
@ -92,7 +95,7 @@ bool Unicode::isValidString(const char * data, size_t size)
{
for (size_t i=0; i<size; i += getCharacterSize(data[i]))
{
if (!isValidCharacter(reinterpret_cast<const ui8*>(data + i), size - i))
if (!isValidCharacter(data + i, size - i))
return false;
}
return true;
@ -123,6 +126,35 @@ std::string Unicode::fromUnicode(const std::string &text, const std::string &enc
return boost::locale::conv::from_utf<char>(text, encoding);
}
void Unicode::trimRight(std::string & text, const size_t amount/* =1 */)
{
if(text.empty())
return;
//todo: more efficient algorithm
for(int i = 0; i< amount; i++){
auto b = text.begin();
auto e = text.end();
size_t lastLen = 0;
size_t len = 0;
while (b != e) {
lastLen = len;
size_t n = getCharacterSize(*b);
if(!isValidCharacter(&(*b),e-b))
{
logGlobal->errorStream() << "Invalid UTF8 sequence";
break;//invalid sequence will be trimmed
}
len += n;
b += n;
}
text.resize(lastLen);
}
}
//Helper for string -> float conversion
class LocaleWithComma: public std::numpunct<char>
{

View File

@ -16,11 +16,11 @@
namespace Unicode
{
/// evaluates size of UTF-8 character
size_t DLL_LINKAGE getCharacterSize(ui8 firstByte);
size_t DLL_LINKAGE getCharacterSize(char firstByte);
/// test if character is a valid UTF-8 symbol
/// maxSize - maximum number of bytes this symbol may consist from ( = remainer of string)
bool DLL_LINKAGE isValidCharacter(const ui8 *character, size_t maxSize);
bool DLL_LINKAGE isValidCharacter(const char * character, size_t maxSize);
/// test if text contains ASCII-string (no need for unicode conversion)
bool DLL_LINKAGE isValidASCII(const std::string & text);
@ -38,6 +38,9 @@ namespace Unicode
/// NOTE: usage of these functions should be avoided if possible
std::string DLL_LINKAGE fromUnicode(const std::string & text);
std::string DLL_LINKAGE fromUnicode(const std::string & text, const std::string & encoding);
///delete (amount) UTF characters from right
DLL_LINKAGE void trimRight(std::string & text, const size_t amount = 1);
};
class CInputStream;

View File

@ -95,7 +95,7 @@ set(lib_SRCS
registerTypes/TypesClientPacks2.cpp
registerTypes/TypesMapObjects1.cpp
registerTypes/TypesMapObjects2.cpp
registerTypes/TypesMapObjects3.cpp
registerTypes/TypesMapObjects3.cpp
registerTypes/TypesPregamePacks.cpp
registerTypes/TypesServerPacks.cpp
)
@ -132,11 +132,16 @@ set(lib_HEADERS
add_library(vcmi SHARED ${lib_SRCS} ${lib_HEADERS})
set_target_properties(vcmi PROPERTIES XCODE_ATTRIBUTE_LD_DYLIB_INSTALL_NAME "@rpath/libvcmi.dylib")
target_link_libraries(vcmi minizip ${Boost_LIBRARIES} ${SDL_LIBRARY} ${ZLIB_LIBRARIES} ${RT_LIB} ${DL_LIB})
set_target_properties(vcmi PROPERTIES COMPILE_DEFINITIONS "VCMI_DLL=1")
target_link_libraries(vcmi minizip ${Boost_LIBRARIES} ${SDL_LIBRARY} ${ZLIB_LIBRARIES} ${SYSTEM_LIBS})
if(WIN32)
set_target_properties(vcmi PROPERTIES OUTPUT_NAME VCMI_lib)
endif()
set_target_properties(vcmi PROPERTIES ${PCH_PROPERTIES})
cotire(vcmi)
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS vcmi DESTINATION ${LIB_DIR})
install(TARGETS vcmi RUNTIME DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${LIB_DIR})
endif()

View File

@ -305,16 +305,17 @@ struct SetMovePoints : public CPackForClient //111
struct FoWChange : public CPackForClient //112
{
FoWChange(){type = 112;};
FoWChange(){type = 112;waitForDialogs = false;};
void applyCl(CClient *cl);
DLL_LINKAGE void applyGs(CGameState *gs);
std::unordered_set<int3, struct ShashInt3 > tiles;
PlayerColor player;
ui8 mode; //mode==0 - hide, mode==1 - reveal
bool waitForDialogs;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tiles & player & mode;
h & tiles & player & mode & waitForDialogs;
}
};

View File

@ -263,8 +263,7 @@ DLL_LINKAGE void GiveBonus::applyGs( CGameState *gs )
if(!bdescr.message.size()
&& bonus.source == Bonus::OBJECT
&& (bonus.type == Bonus::LUCK || bonus.type == Bonus::MORALE)
&& gs->map->objects[bonus.sid]->ID == Obj::EVENT) //it's morale/luck bonus from an event without description
&& (bonus.type == Bonus::LUCK || bonus.type == Bonus::MORALE))
{
descr = VLC->generaltexth->arraytxt[bonus.val > 0 ? 110 : 109]; //+/-%d Temporary until next battle"
}

View File

@ -7,7 +7,7 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCMI_lib" prefix_auto="0" extension_auto="1" />
<Option object_output="../obj/Debug/Lib" />
@ -19,9 +19,13 @@
<Compiler>
<Add option="-Og" />
<Add option="-g" />
<Add directory="$(#sdl2.include)" />
</Compiler>
<Linker>
<Add directory="$(#sdl2.lib)" />
</Linker>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCMI_lib" prefix_auto="0" extension_auto="1" />
<Option object_output="../obj/Release/Lib" />
@ -31,9 +35,46 @@
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#sdl2.include)" />
</Compiler>
<Linker>
<Add option="-s" />
<Add directory="$(#sdl2.lib)" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCMI_lib" prefix_auto="0" extension_auto="1" />
<Option object_output="../obj/Debug/Lib" />
<Option type="3" />
<Option compiler="gcc" />
<Option host_application="D:/projects/vcmi/engine/VCMI_client.exe" />
<Option run_host_application_in_terminal="1" />
<Option createStaticLib="1" />
<Compiler>
<Add option="-Og" />
<Add option="-g" />
<Add directory="$(#sdl.include)" />
</Compiler>
<Linker>
<Add directory="$(#sdl.lib)" />
</Linker>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCMI_lib" prefix_auto="0" extension_auto="1" />
<Option object_output="../obj/Release/Lib" />
<Option type="3" />
<Option compiler="gcc" />
<Option createStaticLib="1" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#sdl.include)" />
</Compiler>
<Linker>
<Add option="-s" />
<Add directory="$(#sdl.lib)" />
</Linker>
</Target>
</Build>
@ -50,14 +91,14 @@
<Add option="-DVCMI_DLL" />
<Add option="-DBOOST_THREAD_USE_LIB" />
<Add option="-D_WIN32_WINNT=0x0501" />
<Add directory="$(#zlib.include)" />
<Add directory="$(#boost.include)" />
<Add directory="$(#sdl.include)" />
<Add directory="../include" />
<Add directory="../lib" />
</Compiler>
<Linker>
<Add option="-lws2_32" />
<Add option="-lzlib" />
<Add option="-lz" />
<Add option="-lminizip" />
<Add option="-lboost_filesystem$(#boost.libsuffix)" />
<Add option="-lboost_system$(#boost.libsuffix)" />
@ -65,7 +106,7 @@
<Add option="-lboost_chrono$(#boost.libsuffix)" />
<Add option="-lboost_locale$(#boost.libsuffix)" />
<Add directory="$(#boost.lib32)" />
<Add directory="$(#sdl.lib)" />
<Add directory="$(#zlib.lib)" />
<Add directory="../" />
</Linker>
<Unit filename="AI_Base.h" />

View File

@ -1327,6 +1327,7 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const
FoWChange fw;
fw.player = h->tempOwner;
fw.mode = 1;
fw.waitForDialogs = true;
for(auto it : eyelist[subID])
{

View File

@ -16,5 +16,5 @@ set_target_properties(minizip PROPERTIES XCODE_ATTRIBUTE_LD_DYLIB_INSTALL_NAME "
target_link_libraries(minizip ${ZLIB_LIBRARIES})
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS minizip DESTINATION ${LIB_DIR})
install(TARGETS minizip RUNTIME DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${LIB_DIR})
endif()

View File

@ -6,7 +6,7 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../../minizip" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
@ -19,7 +19,37 @@
<Add option="-DBUILD_DLL" />
</Compiler>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../../minizip" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />
<Option compiler="gcc" />
<Option createStaticLib="1" />
<Compiler>
<Add option="-O2" />
<Add option="-Wall" />
<Add option="-DBUILD_DLL" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../../minizip" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="3" />
<Option compiler="gcc" />
<Option createStaticLib="1" />
<Compiler>
<Add option="-Wall" />
<Add option="-g" />
<Add option="-DBUILD_DLL" />
</Compiler>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../../minizip" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="3" />
@ -36,11 +66,11 @@
</Target>
</Build>
<Compiler>
<Add directory="$(#sdl.include)" />
<Add directory="$(#zlib.include)" />
</Compiler>
<Linker>
<Add option="-lzlib" />
<Add directory="$(#sdl.lib)" />
<Add option="-lz" />
<Add directory="$(#zlib.lib)" />
</Linker>
<Unit filename="ioapi.c">
<Option compilerVar="CC" />

View File

@ -6,25 +6,25 @@ include_directories(${Boost_INCLUDE_DIRS})
set(server_SRCS
StdInc.cpp
CGameHandler.cpp
CVCMIServer.cpp
CQuery.cpp
NetPacksServer.cpp
CGameHandler.cpp
CVCMIServer.cpp
CQuery.cpp
NetPacksServer.cpp
)
if(WIN32)
add_executable(vcmiserver WIN32 ${server_SRCS})
else()
add_executable(vcmiserver ${server_SRCS})
endif()
add_executable(vcmiserver ${server_SRCS})
target_link_libraries(vcmiserver vcmi ${Boost_LIBRARIES} ${RT_LIB} ${DL_LIB})
target_link_libraries(vcmiserver vcmi ${Boost_LIBRARIES} ${SYSTEM_LIBS})
if(WIN32)
set_target_properties(vcmiserver PROPERTIES OUTPUT_NAME VCMI_server)
endif()
set_target_properties(vcmiserver PROPERTIES ${PCH_PROPERTIES})
set_target_properties(vcmiserver PROPERTIES XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks @executable_path/")
cotire(vcmiserver)
if (NOT APPLE) # Already inside vcmiclient bundle
install(TARGETS vcmiserver DESTINATION ${BIN_DIR})
install(TARGETS vcmiserver DESTINATION ${BIN_DIR})
endif()

View File

@ -6,25 +6,59 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCMI_server" prefix_auto="1" extension_auto="1" />
<Option object_output="../obj/Debug/Server" />
<Option type="1" />
<Option compiler="gcc" />
<Option use_console_runner="0" />
<Compiler>
<Add option="-ggdb" />
<Add option="-Og" />
<Add option="-ggdb" />
<Add directory="$(#sdl2.include)" />
</Compiler>
</Target>
<Target title="Release">
<Target title="Release-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../VCMI_server" prefix_auto="1" extension_auto="1" />
<Option object_output="../obj/Release/Server" />
<Option type="1" />
<Option compiler="gcc" />
<Option use_console_runner="0" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#sdl2.include)" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCMI_server" prefix_auto="1" extension_auto="1" />
<Option object_output="../obj/Debug/Server" />
<Option type="1" />
<Option compiler="gcc" />
<Option use_console_runner="0" />
<Compiler>
<Add option="-Og" />
<Add option="-ggdb" />
<Add directory="$(#sdl.include)" />
</Compiler>
</Target>
<Target title="Release-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../VCMI_server" prefix_auto="1" extension_auto="1" />
<Option object_output="../obj/Release/Server" />
<Option type="1" />
<Option compiler="gcc" />
<Option use_console_runner="0" />
<Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-O2" />
<Add directory="$(#sdl.include)" />
</Compiler>
<Linker>
<Add option="-s" />
@ -42,8 +76,8 @@
<Add option="-Wno-overloaded-virtual" />
<Add option="-D_WIN32_WINNT=0x0501" />
<Add option="-DBOOST_THREAD_USE_LIB" />
<Add directory="$(#zlib.include)" />
<Add directory="$(#boost.include)" />
<Add directory="$(#sdl.include)" />
<Add directory="../include" />
</Compiler>
<Linker>

View File

@ -6,7 +6,20 @@
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Target title="Debug-win32-SDL2">
<Option platforms="Windows;" />
<Option output="../Test" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-march=athlon-xp" />
<Add option="-Wextra" />
<Add option="-g" />
</Compiler>
</Target>
<Target title="Debug-win32-SDL1">
<Option platforms="Windows;" />
<Option output="../Test" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />