summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorheinrich5991 <heinrich5991@gmail.com>2018-10-01 10:49:19 +0200
committerheinrich5991 <heinrich5991@gmail.com>2018-10-12 22:09:24 +0200
commitee2afdac33f43d96a457bcf692a817489d6f896e (patch)
treee667c07c78265eb91265449173cef521852360ab
parentc45aa9927ca7c546bf3d70d525d5515f12134925 (diff)
Add CMake
-rw-r--r--.gitignore17
-rw-r--r--CMakeLists.txt1243
-rw-r--r--bam.lua5
-rw-r--r--cmake/FindFreetype.cmake37
-rw-r--r--cmake/FindPnglite.cmake46
-rw-r--r--cmake/FindSDL.cmake38
-rw-r--r--cmake/FindWavpack.cmake52
-rw-r--r--cmake/FindZLIB.cmake50
-rw-r--r--cmake/toolchains/darwin.toolchain11
-rw-r--r--cmake/toolchains/mingw32.toolchain10
-rw-r--r--cmake/toolchains/mingw64.toolchain10
-rw-r--r--other/bundle/client/Info.plist.in24
-rw-r--r--other/bundle/client/PkgInfo1
-rw-r--r--other/bundle/server/Info.plist.in20
-rw-r--r--other/bundle/server/PkgInfo1
-rw-r--r--other/freetype/freetype.lua4
-rw-r--r--other/freetype/windows/lib32/freetype.dll (renamed from other/freetype/lib32/freetype.dll)bin451072 -> 451072 bytes
-rw-r--r--other/freetype/windows/lib32/freetype.lib (renamed from other/freetype/lib32/freetype.lib)bin59196 -> 59196 bytes
-rw-r--r--other/freetype/windows/lib64/freetype.dll (renamed from other/freetype/lib64/freetype.dll)bin570368 -> 570368 bytes
-rw-r--r--other/freetype/windows/lib64/freetype.lib (renamed from other/freetype/lib64/freetype.lib)bin57870 -> 57870 bytes
-rw-r--r--other/icons/teeworlds.icns (renamed from other/icons/Teeworlds.icns)bin77819 -> 77819 bytes
-rw-r--r--other/icons/teeworlds.ico (renamed from other/icons/Teeworlds.ico)bin107390 -> 107390 bytes
-rw-r--r--other/icons/teeworlds.rc1
-rw-r--r--other/icons/teeworlds_srv.icns (renamed from other/icons/Teeworlds_srv.icns)bin74618 -> 74618 bytes
-rw-r--r--other/icons/teeworlds_srv.ico (renamed from other/icons/Teeworlds_srv.ico)bin105572 -> 105572 bytes
-rw-r--r--other/icons/teeworlds_srv.rc1
-rw-r--r--other/icons/teeworlds_srv_cl.rc2
-rw-r--r--other/icons/teeworlds_srv_gcc.rc2
-rw-r--r--other/sdl/sdl.lua4
-rw-r--r--other/sdl/windows/lib32/SDL.dll (renamed from other/sdl/lib32/SDL.dll)bin303616 -> 303616 bytes
-rw-r--r--other/sdl/windows/lib32/SDL.lib (renamed from other/sdl/lib32/SDL.lib)bin42522 -> 42522 bytes
-rw-r--r--other/sdl/windows/lib32/SDLmain.lib (renamed from other/sdl/lib32/SDLmain.lib)bin8214 -> 8214 bytes
-rw-r--r--other/sdl/windows/lib64/SDL.dll (renamed from other/sdl/lib64/SDL.dll)bin306688 -> 306688 bytes
-rw-r--r--other/sdl/windows/lib64/SDL.lib (renamed from other/sdl/lib64/SDL.lib)bin41512 -> 41512 bytes
-rw-r--r--other/sdl/windows/lib64/SDLmain.lib (renamed from other/sdl/lib64/SDLmain.lib)bin11176 -> 11176 bytes
-rw-r--r--scripts/darwin_change_dylib.py63
-rw-r--r--scripts/dmg.py106
-rw-r--r--scripts/git_revision.py21
-rw-r--r--src/base/system.c5
-rw-r--r--src/base/system.h15
-rw-r--r--src/engine/client/sound.cpp66
-rw-r--r--src/engine/client/sound.h4
-rw-r--r--src/game/version.h4
l---------[-rw-r--r--]src/osxlaunch/client.m374
-rw-r--r--src/osxlaunch/client.mm373
l---------[-rw-r--r--]src/osxlaunch/server.m113
-rw-r--r--src/osxlaunch/server.mm112
47 files changed, 2323 insertions, 512 deletions
diff --git a/.gitignore b/.gitignore
index edbb7eab8..c0916ca03 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ src/game/generated
SDL.dll
freetype.dll
autoexec.cfg
+Info.plist
crapnet*
dilate*
@@ -20,3 +21,19 @@ teeworlds*
teeworlds_srv*
tileset_border*
versionsrv*
+
+# CMake
+data
+!/data
+src
+!/src
+
+*.ninja
+.ninja*
+CMakeCache.txt
+CMakeFiles/
+CPackConfig.cmake
+CPackSourceConfig.cmake
+Makefile
+cmake_install.cmake
+install_manifest.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000..7a8fb99e0
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,1243 @@
+cmake_minimum_required(VERSION 2.8)
+
+file(STRINGS src/game/version.h VERSION_LINE
+ LIMIT_COUNT 1
+ REGEX GAME_RELEASE_VERSION
+)
+
+if(VERSION_LINE MATCHES "\"([0-9]+)\\.([0-9]+)\\.([0-9]+)\"")
+ set(VERSION_MAJOR ${CMAKE_MATCH_1})
+ set(VERSION_MINOR ${CMAKE_MATCH_2})
+ set(VERSION_PATCH ${CMAKE_MATCH_3})
+elseif(VERSION_LINE MATCHES "\"([0-9]+)\\.([0-9]+)\"")
+ set(VERSION_MAJOR ${CMAKE_MATCH_1})
+ set(VERSION_MINOR ${CMAKE_MATCH_2})
+ set(VERSION_PATCH "0")
+else()
+ message(FATAL_ERROR "Couldn't parse version from src/game/version.h")
+endif()
+
+if(POLICY CMP0048)
+ cmake_policy(SET CMP0048 NEW)
+ if(VERSION_PATCH STREQUAL "0")
+ project(teeworlds VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
+ else()
+ project(teeworlds VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+ endif()
+else()
+ project(teeworlds)
+ set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR})
+ set(PROJECT_VERSION_MINOR ${VERSION_MINOR})
+ set(PROJECT_VERSION_PATCH ${VERSION_PATCH})
+ if(VERSION_PATCH STREQUAL "0")
+ set(PROJECT_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
+ else()
+ set(PROJECT_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+ endif()
+endif()
+
+set(ORIGINAL_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+set(ORIGINAL_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
+set(ORIGINAL_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+set(OWN_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
+set(CMAKE_MODULE_PATH ${OWN_CMAKE_MODULE_PATH})
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(TARGET_BITS "64")
+elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set(TARGET_BITS "32")
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set(TARGET_OS "windows")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(TARGET_OS "linux")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ set(TARGET_OS "mac")
+endif()
+
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+include(CheckSymbolExists)
+
+check_symbol_exists(__i386 "" TARGET_ARCH_X86_i386)
+if(TARGET_ARCH_X86_i386)
+ set(TARGET_ARCH x86)
+else()
+ set(TARGET_ARCH)
+endif()
+
+set(AUTO_DEPENDENCIES_DEFAULT OFF)
+if(TARGET_OS STREQUAL "windows")
+ set(AUTO_DEPENDENCIES_DEFAULT ON)
+endif()
+
+option(CLIENT "Compile client" ON)
+option(PREFER_BUNDLED_LIBS "Prefer bundled libraries over system libraries" ${AUTO_DEPENDENCIES_DEFAULT})
+option(DEV "Don't generate stuff necessary for packaging" OFF)
+
+# Set the default build type to Release
+if(NOT(CMAKE_BUILD_TYPE))
+ if(DEV)
+ set(CMAKE_BUILD_TYPE Release)
+ else()
+ set(CMAKE_BUILD_TYPE Debug)
+ endif()
+endif()
+
+set(DBG $<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>)
+
+set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
+ src/game/version.h
+)
+
+set(SERVER_EXECUTABLE teeworlds_srv CACHE STRING "Name of the built server executable")
+set(CLIENT_EXECUTABLE teeworlds CACHE STRING "Name of the build client executable")
+
+########################################################################
+# Compiler flags
+########################################################################
+
+function(add_c_compiler_flag_if_supported VARIABLE FLAG)
+ if(ARGC GREATER 2)
+ set(CHECKED_FLAG "${ARGV2}")
+ else()
+ set(CHECKED_FLAG "${FLAG}")
+ endif()
+ string(REGEX REPLACE "[^A-Za-z0-9]" "_" CONFIG_VARIABLE "FLAG_SUPPORTED${CHECKED_FLAG}")
+ check_c_compiler_flag("${CHECKED_FLAG}" ${CONFIG_VARIABLE})
+ if(${CONFIG_VARIABLE})
+ if(${VARIABLE})
+ set("${VARIABLE}" "${${VARIABLE}};${FLAG}" PARENT_SCOPE)
+ else()
+ set("${VARIABLE}" "${FLAG}" PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+if(NOT MSVC)
+ # Protect the stack pointer.
+ # -fstack-protector-all doesn't work on MinGW.
+ add_c_compiler_flag_if_supported(OUR_FLAGS -fstack-protector-all)
+
+ # Inaccurate floating point numbers cause problems on mingw-w64-gcc when
+ # compiling for x86, might cause problems elsewhere. So don't store floats
+ # in registers but keep them at higher accuracy.
+
+ if(TARGET_ARCH STREQUAL "x86")
+ add_c_compiler_flag_if_supported(OUR_FLAGS -ffloat-store)
+ endif()
+
+ if(TARGET_OS STREQUAL "mac")
+ add_c_compiler_flag_if_supported(OUR_FLAGS -stdlib=libc++)
+ add_c_compiler_flag_if_supported(OUR_FLAGS -mmacosx-version-min=10.7)
+ endif()
+
+ add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wall)
+ if(CMAKE_VERSION VERSION_GREATER 3.3 OR CMAKE_VERSION VERSION_EQUAL 3.3)
+ add_c_compiler_flag_if_supported(OUR_FLAGS_OWN
+ $<$<COMPILE_LANGUAGE:C>:-Wdeclaration-after-statement>
+ -Wdeclaration-after-statement
+ )
+ endif()
+ add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wextra)
+ add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-unused-parameter)
+ add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-missing-field-initializers)
+ add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wformat=2) # Warn about format strings.
+ add_c_compiler_flag_if_supported(OUR_FLAGS_DEP -Wno-implicit-function-declaration)
+endif()
+
+if(NOT MSVC)
+ check_c_compiler_flag("-O2;-Wp,-Werror;-D_FORTIFY_SOURCE=2" DEFINE_FORTIFY_SOURCE) # Some distributions define _FORTIFY_SOURCE by themselves.
+endif()
+
+########################################################################
+# COMMON FUNCTIONS
+########################################################################
+
+function(set_glob VAR GLOBBING DIRECTORY) # ...
+ file(${GLOBBING} GLOB_RESULT "${DIRECTORY}/*.c" "${DIRECTORY}/*.cpp" "${DIRECTORY}/*.h")
+ list(SORT GLOB_RESULT)
+ set(FILES)
+ foreach(file ${ARGN})
+ list(APPEND FILES "${PROJECT_SOURCE_DIR}/${DIRECTORY}/${file}")
+ endforeach()
+
+ if(NOT FILES STREQUAL GLOB_RESULT)
+ message(AUTHOR_WARNING "${VAR} does not contain every file from directory ${DIRECTORY}")
+ set(LIST_BUT_NOT_GLOB)
+ if(POLICY CMP0057)
+ cmake_policy(SET CMP0057 NEW)
+ foreach(file ${FILES})
+ if(NOT file IN_LIST GLOB_RESULT)
+ list(APPEND LIST_BUT_NOT_GLOB ${file})
+ endif()
+ endforeach()
+ if(LIST_BUT_NOT_GLOB)
+ message(AUTHOR_WARNING "Entries only present in ${VAR}: ${LIST_BUT_NOT_GLOB}")
+ endif()
+ set(GLOB_BUT_NOT_LIST)
+ foreach(file ${GLOB_RESULT})
+ if(NOT file IN_LIST FILES)
+ list(APPEND GLOB_BUT_NOT_LIST ${file})
+ endif()
+ endforeach()
+ if(GLOB_BUT_NOT_LIST)
+ message(AUTHOR_WARNING "Entries only present in ${DIRECTORY}: ${GLOB_BUT_NOT_LIST}")
+ endif()
+ endif()
+ endif()
+
+ set(${VAR} ${FILES} PARENT_SCOPE)
+endfunction()
+
+########################################################################
+# INITIALIZE TARGET LISTS
+########################################################################
+
+set(TARGETS_OWN)
+set(TARGETS_DEP)
+
+set(TARGETS_LINK) # Targets with a linking stage.
+
+########################################################################
+# DEPENDENCIES
+########################################################################
+
+function(set_extra_dirs_lib VARIABLE NAME)
+ set("PATHS_${VARIABLE}_LIBDIR" PARENT_SCOPE)
+ set("HINTS_${VARIABLE}_LIBDIR" PARENT_SCOPE)
+ if(PREFER_BUNDLED_LIBS)
+ set(TYPE HINTS)
+ else()
+ set(TYPE PATHS)
+ endif()
+ if(TARGET_BITS AND TARGET_OS)
+ set(DIR "other/${NAME}/${TARGET_OS}/lib${TARGET_BITS}")
+ set("${TYPE}_${VARIABLE}_LIBDIR" "${DIR}" PARENT_SCOPE)
+ set("EXTRA_${VARIABLE}_LIBDIR" "${DIR}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(set_extra_dirs_include VARIABLE NAME LIBRARY)
+ set("PATHS_${VARIABLE}_INCLUDEDIR" PARENT_SCOPE)
+ set("HINTS_${VARIABLE}_INCLUDEDIR" PARENT_SCOPE)
+ is_bundled(IS_BUNDLED "${LIBRARY}")
+ if(IS_BUNDLED)
+ set("HINTS_${VARIABLE}_INCLUDEDIR" "other/${NAME}/include" "other/${NAME}/include/${TARGET_OS}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+if(CMAKE_CROSSCOMPILING)
+ set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH NO_CMAKE_SYSTEM_PATH)
+else()
+ set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH)
+endif()
+
+function(is_bundled VARIABLE PATH)
+ if(PATH)
+ string(FIND "${PATH}" "${PROJECT_SOURCE_DIR}" LOCAL_PATH_POS)
+ if(LOCAL_PATH_POS EQUAL 0 AND TARGET_BITS AND TARGET_OS)
+ set("${VARIABLE}" ON PARENT_SCOPE)
+ else()
+ set("${VARIABLE}" OFF PARENT_SCOPE)
+ endif()
+ else()
+ set("${VARIABLE}" OFF PARENT_SCOPE)
+ endif()
+endfunction()
+
+if(NOT CMAKE_CROSSCOMPILING)
+ # Check for PkgConfig once so all the other `find_package` calls can do it
+ # quietly.
+ find_package(PkgConfig)
+endif()
+find_package(ZLIB)
+find_package(Freetype)
+find_package(Git)
+find_package(Pnglite)
+find_package(PythonInterp)
+find_package(SDL)
+find_package(Threads)
+find_package(Wavpack)
+
+
+if(TARGET_OS AND TARGET_OS STREQUAL "mac")
+ find_program(DMG dmg)
+ find_program(HFSPLUS hfsplus)
+ find_program(NEWFS_HFS newfs_hfs)
+ if(DMG AND HFSPLUS AND NEWFS_HFS)
+ set(DMGTOOLS_FOUND ON)
+ else()
+ set(DMGTOOLS_FOUND OFF)
+ endif()
+
+ find_program(HDIUTIL hdiutil)
+endif()
+
+message(STATUS "******** Teeworlds ********")
+message(STATUS "Target OS: ${TARGET_OS} ${TARGET_BITS}bit")
+message(STATUS "Compiler: ${CMAKE_CXX_COMPILER}")
+message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
+
+message(STATUS "Dependencies:")
+function(show_dependency_status OUTPUT_NAME NAME)
+ if(${NAME}_FOUND)
+ if(${NAME}_BUNDLED)
+ message(STATUS " * ${OUTPUT_NAME} not found (using bundled version)")
+ else()
+ message(STATUS " * ${OUTPUT_NAME} found")
+ endif()
+ else()
+ message(STATUS " * ${OUTPUT_NAME} not found")
+ endif()
+endfunction()
+
+if(TARGET_OS AND TARGET_OS STREQUAL "mac")
+ show_dependency_status("Dmg tools" DMGTOOLS)
+endif()
+show_dependency_status("Freetype" FREETYPE)
+if(TARGET_OS AND TARGET_OS STREQUAL "mac")
+ show_dependency_status("Hdiutil" HDIUTIL)
+endif()
+show_dependency_status("Pnglite" PNGLITE)
+show_dependency_status("PythonInterp" PYTHONINTERP)
+show_dependency_status("SDL" SDL)
+show_dependency_status("Wavpack" WAVPACK)
+show_dependency_status("Zlib" ZLIB)
+
+if(NOT(PYTHONINTERP_FOUND))
+ message(SEND_ERROR "You must install Python to compile Teeworlds")
+endif()
+
+if(CLIENT AND NOT(FREETYPE_FOUND))
+ message(SEND_ERROR "You must install Freetype to compile the Teeworlds client")
+endif()
+if(CLIENT AND NOT(SDL_FOUND))
+ message(SEND_ERROR "You must install SDL to compile the Teeworlds client")
+endif()
+
+if(TARGET_OS STREQUAL "windows")
+ set(PLATFORM_CLIENT)
+ set(PLATFORM_CLIENT_LIBS opengl32 glu32 winmm)
+ set(PLATFORM_LIBS ws2_32) # Windows sockets
+elseif(TARGET_OS STREQUAL "mac")
+ find_library(CARBON Carbon)
+ find_library(COCOA Cocoa)
+ find_library(OPENGL OpenGL)
+ set(PLATFORM_CLIENT
+ src/osxlaunch/client.h
+ src/osxlaunch/client.m
+ )
+ set(PLATFORM_CLIENT_LIBS ${COCOA} ${OPENGL})
+ set(PLATFORM_LIBS ${CARBON})
+else()
+ set(PLATFORM_CLIENT)
+ set(PLATFORM_CLIENT_LIBS GL GLU X11)
+ if(TARGET_OS STREQUAL "linux")
+ set(PLATFORM_LIBS rt) # clock_gettime for glibc < 2.17
+ else()
+ set(PLATFORM_LIBS)
+ endif()
+endif()
+
+########################################################################
+# DEPENDENCY COMPILATION
+########################################################################
+
+set_glob(DEP_MD5_SRC GLOB src/engine/external/md5 md5.c md5.h)
+add_library(md5 EXCLUDE_FROM_ALL OBJECT ${DEP_MD5_SRC})
+
+list(APPEND TARGETS_DEP md5)
+set(DEP_MD5 $<TARGET_OBJECTS:md5>)
+
+########################################################################
+# COPY DATA AND DLLS
+########################################################################
+
+file(COPY data DESTINATION .)
+set(COPY_FILES
+ ${FREETYPE_COPY_FILES}
+ ${SDL_COPY_FILES}
+)
+file(COPY ${COPY_FILES} DESTINATION .)
+
+########################################################################
+# CODE GENERATION
+########################################################################
+
+function(chash output_file)
+ add_custom_command(OUTPUT ${output_file}
+ COMMAND ${PYTHON_EXECUTABLE} scripts/cmd5.py ${ARGN}
+ > "${PROJECT_BINARY_DIR}/${output_file}"
+ DEPENDS scripts/cmd5.py ${ARGN}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ )
+endfunction()
+
+function(generate_source output_file script_parameter)
+ add_custom_command(OUTPUT ${output_file}
+ COMMAND ${PYTHON_EXECUTABLE} datasrc/compile.py ${script_parameter}
+ > "${PROJECT_BINARY_DIR}/${output_file}"
+ DEPENDS
+ datasrc/compile.py
+ datasrc/content.py
+ datasrc/datatypes.py
+ datasrc/network.py
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ )
+endfunction()
+
+file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/src/game/generated/")
+if(GIT_FOUND)
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
+ ERROR_QUIET
+ OUTPUT_VARIABLE PROJECT_GIT_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE PROJECT_GIT_DIR_ERROR
+ )
+ if(NOT PROJECT_GIT_DIR_ERROR)
+ set(GIT_REVISION_EXTRA_DEPS
+ ${PROJECT_GIT_DIR}/index
+ ${PROJECT_GIT_DIR}/logs/HEAD
+ )
+ endif()
+endif()
+add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src/game/generated/git_revision.cpp
+ COMMAND ${PYTHON_EXECUTABLE}
+ scripts/git_revision.py
+ > ${PROJECT_BINARY_DIR}/src/game/generated/git_revision.cpp
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ DEPENDS
+ ${GIT_REVISION_EXTRA_DEPS}
+ scripts/git_revision.py
+)
+chash("src/game/generated/nethash.cpp"
+ "src/engine/shared/protocol.h"
+ "${PROJECT_BINARY_DIR}/src/game/generated/protocol.h"
+ "src/game/tuning.h"
+ "src/game/gamecore.cpp"
+)
+generate_source("src/game/generated/client_data.cpp" "client_content_source")
+generate_source("src/game/generated/client_data.h" "client_content_header")
+generate_source("src/game/generated/protocol.cpp" "network_source")
+generate_source("src/game/generated/protocol.h" "network_header")
+generate_source("src/game/generated/server_data.cpp" "server_content_source")
+generate_source("src/game/generated/server_data.h" "server_content_header")
+
+
+########################################################################
+# SHARED
+########################################################################
+
+# Sources
+set_glob(BASE GLOB_RECURSE src/base
+ detect.h
+ math.h
+ system.c
+ system.h
+ tl/algorithm.h
+ tl/allocator.h
+ tl/array.h
+ tl/base.h
+ tl/range.h
+ tl/sorted_array.h
+ tl/string.h
+ tl/threading.h
+ vmath.h
+)
+set_glob(ENGINE_INTERFACE GLOB src/engine
+ client.h
+ config.h
+ console.h
+ demo.h
+ editor.h
+ engine.h
+ friends.h
+ graphics.h
+ input.h
+ kernel.h
+ keys.h
+ map.h
+ masterserver.h
+ message.h
+ server.h
+ serverbrowser.h
+ sound.h
+ storage.h
+ textrender.h
+)
+set_glob(ENGINE_SHARED GLOB src/engine/shared
+ compression.cpp
+ compression.h
+ config.cpp
+ config.h
+ config_variables.h
+ console.cpp
+ console.h
+ datafile.cpp
+ datafile.h
+ demo.cpp
+ demo.h
+ econ.cpp
+ econ.h
+ engine.cpp
+ filecollection.cpp
+ filecollection.h
+ huffman.cpp
+ huffman.h
+ jobs.cpp
+ jobs.h
+ kernel.cpp
+ linereader.cpp
+ linereader.h
+ map.cpp
+ mapchecker.cpp
+ mapchecker.h
+ masterserver.cpp
+ memheap.cpp
+ memheap.h
+ message.h
+ netban.cpp
+ netban.h
+ network.cpp
+ network.h
+ network_client.cpp
+ network_conn.cpp
+ network_console.cpp
+ network_console_conn.cpp
+ network_server.cpp
+ packer.cpp
+ packer.h
+ protocol.h
+ ringbuffer.cpp
+ ringbuffer.h
+ snapshot.cpp
+ snapshot.h
+ storage.cpp
+)
+set(ENGINE_GENERATED_SHARED src/game/generated/protocol.cpp src/game/generated/protocol.h)
+set_glob(GAME_SHARED GLOB src/game
+ collision.cpp
+ collision.h
+ gamecore.cpp
+ gamecore.h
+ layers.cpp
+ layers.h
+ localization.cpp
+ localization.h
+ mapitems.h
+ tuning.h
+ variables.h
+ version.h
+ voting.h
+)
+set(GAME_GENERATED_SHARED
+ src/game/generated/git_revision.cpp
+ src/game/generated/nethash.cpp
+ src/game/generated/protocol.h
+)
+
+set(DEPS ${DEP_MD5} ${ZLIB_DEP})
+
+# Libraries
+set(LIBS ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES} ${PLATFORM_LIBS})
+
+# Targets
+add_library(engine-shared EXCLUDE_FROM_ALL OBJECT ${ENGINE_INTERFACE} ${ENGINE_SHARED} ${ENGINE_GENERATED_SHARED} ${BASE})
+add_library(game-shared EXCLUDE_FROM_ALL OBJECT ${GAME_SHARED} ${GAME_GENERATED_SHARED})
+list(APPEND TARGETS_OWN engine-shared game-shared)
+
+
+########################################################################
+# CLIENT
+########################################################################
+
+if(CLIENT)
+ # Sources
+ set_glob(ENGINE_CLIENT GLOB src/engine/client
+ backend_sdl.cpp
+ backend_sdl.h
+ client.cpp
+ client.h
+ friends.cpp
+ friends.h
+ graphics.cpp
+ graphics.h
+ graphics_threaded.cpp
+ graphics_threaded.h
+ input.cpp
+ input.h
+ keynames.h
+ serverbrowser.cpp
+ serverbrowser.h
+ sound.cpp
+ sound.h
+ text.cpp
+ )
+ set_glob(GAME_CLIENT GLOB_RECURSE src/game/client
+ animstate.cpp
+ animstate.h
+ component.h
+ components/binds.cpp
+ components/binds.h
+ components/broadcast.cpp
+ components/broadcast.h
+ components/camera.cpp
+ components/camera.h
+ components/chat.cpp
+ components/chat.h
+ components/console.cpp
+ components/console.h
+ components/controls.cpp
+ components/controls.h
+ components/countryflags.cpp
+ components/countryflags.h
+ components/damageind.cpp
+ components/damageind.h
+ components/debughud.cpp
+ components/debughud.h
+ components/effects.cpp
+ components/effects.h
+ components/emoticon.cpp
+ components/emoticon.h
+ components/flow.cpp
+ components/flow.h
+ components/hud.cpp
+ components/hud.h
+ components/items.cpp
+ components/items.h
+ components/killmessages.cpp
+ components/killmessages.h
+ components/mapimages.cpp
+ components/mapimages.h
+ components/maplayers.cpp
+ components/maplayers.h
+ components/menus.cpp
+ components/menus.h
+ components/menus_browser.cpp
+ components/menus_demo.cpp
+ components/menus_ingame.cpp
+ components/menus_settings.cpp
+ components/motd.cpp
+ components/motd.h
+ components/nameplates.cpp
+ components/nameplates.h
+ components/particles.cpp
+ components/particles.h
+ components/players.cpp
+ components/players.h
+ components/scoreboard.cpp
+ components/scoreboard.h
+ components/skins.cpp
+ components/skins.h
+ components/sounds.cpp
+ components/sounds.h
+ components/spectator.cpp
+ components/spectator.h
+ components/voting.cpp
+ components/voting.h
+ gameclient.cpp
+ gameclient.h
+ lineinput.cpp
+ lineinput.h
+ render.cpp
+ render.h
+ render_map.cpp
+ ui.cpp
+ ui.h
+ )
+ set_glob(GAME_EDITOR GLOB src/game/editor
+ auto_map.cpp
+ auto_map.h
+ editor.cpp
+ editor.h
+ io.cpp
+ layer_game.cpp
+ layer_quads.cpp
+ layer_tiles.cpp
+ popups.cpp
+ )
+ set(GAME_GENERATED_CLIENT
+ src/game/generated/client_data.cpp
+ src/game/generated/client_data.h
+ )
+ set(CLIENT_SRC ${ENGINE_CLIENT} ${PLATFORM_CLIENT} ${GAME_CLIENT} ${GAME_EDITOR} ${GAME_GENERATED_CLIENT})
+
+ set(DEPS_CLIENT ${DEPS} ${PNGLITE_DEP} ${WAVPACK_DEP})
+
+ # Libraries
+ set(LIBS_CLIENT
+ ${LIBS}
+ ${FREETYPE_LIBRARIES}
+ ${PNGLITE_LIBRARIES}
+ ${SDL_LIBRARIES}
+ ${WAVPACK_LIBRARIES}
+ ${PLATFORM_CLIENT_LIBS}
+ )
+
+ if(TARGET_OS STREQUAL "windows")
+ set(CLIENT_ICON "other/icons/${CLIENT_EXECUTABLE}.rc")
+ else()
+ set(CLIENT_ICON)
+ endif()
+
+ # Target
+ set(TARGET_CLIENT ${CLIENT_EXECUTABLE})
+ add_executable(${TARGET_CLIENT}
+ ${CLIENT_SRC}
+ ${CLIENT_ICON}
+ ${CLIENT_MANIFEST}
+ ${DEPS_CLIENT}
+ $<TARGET_OBJECTS:engine-shared>
+ $<TARGET_OBJECTS:game-shared>
+ )
+ target_link_libraries(${TARGET_CLIENT} ${LIBS_CLIENT})
+
+ target_include_directories(${TARGET_CLIENT} PRIVATE
+ ${FREETYPE_INCLUDE_DIRS}
+ ${PNGLITE_INCLUDE_DIRS}
+ ${SDL_INCLUDE_DIRS}
+ ${WAVPACK_INCLUDE_DIRS}
+ )
+
+ set(PARAMS "${WAVPACK_INCLUDE_DIRS};${WAVPACK_INCLUDE_DIRS}")
+ if(NOT(WAVPACK_OPEN_FILE_INPUT_EX_PARAMS STREQUAL PARAMS))
+ unset(WAVPACK_OPEN_FILE_INPUT_EX CACHE)
+ endif()
+ set(WAVPACK_OPEN_FILE_INPUT_EX_PARAMS "${PARAMS}" CACHE INTERNAL "")
+
+ set(CMAKE_REQUIRED_INCLUDES ${ORIGINAL_CMAKE_REQUIRED_INCLUDES} ${WAVPACK_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_LIBRARIES ${ORIGINAL_CMAKE_REQUIRED_LIBRARIES} ${WAVPACK_LIBRARIES})
+ check_symbol_exists(WavpackOpenFileInputEx wavpack.h WAVPACK_OPEN_FILE_INPUT_EX)
+ set(CMAKE_REQUIRED_INCLUDES ${ORIGINAL_CMAKE_REQUIRED_INCLUDES})
+ set(CMAKE_REQUIRED_LIBRARIES ${ORIGINAL_CMAKE_REQUIRED_LIBRARIES})
+
+ if(WAVPACK_OPEN_FILE_INPUT_EX)
+ target_compile_definitions(${TARGET_CLIENT} PRIVATE CONF_WAVPACK_OPEN_FILE_INPUT_EX)
+ endif()
+
+ list(APPEND TARGETS_OWN ${TARGET_CLIENT})
+ list(APPEND TARGETS_LINK ${TARGET_CLIENT})
+endif()
+
+
+########################################################################
+# SERVER
+########################################################################
+
+# Sources
+set_glob(ENGINE_SERVER GLOB src/engine/server
+ register.cpp
+ register.h
+ server.cpp
+ server.h
+)
+set_glob(GAME_SERVER GLOB_RECURSE src/game/server
+ entities/character.cpp
+ entities/character.h
+ entities/flag.cpp
+ entities/flag.h
+ entities/laser.cpp
+ entities/laser.h
+ entities/pickup.cpp
+ entities/pickup.h
+ entities/projectile.cpp
+ entities/projectile.h
+ entity.cpp
+ entity.h
+ eventhandler.cpp
+ eventhandler.h
+ gamecontext.cpp
+ gamecontext.h
+ gamecontroller.cpp
+ gamecontroller.h
+ gamemodes/ctf.cpp
+ gamemodes/ctf.h
+ gamemodes/dm.cpp
+ gamemodes/dm.h
+ gamemodes/mod.cpp
+ gamemodes/mod.h
+ gamemodes/tdm.cpp
+ gamemodes/tdm.h
+ gameworld.cpp
+ gameworld.h
+ player.cpp
+ player.h
+)
+set(GAME_GENERATED_SERVER
+ "src/game/generated/server_data.cpp"
+ "src/game/generated/server_data.h"
+)
+set(SERVER_SRC ${ENGINE_SERVER} ${GAME_SERVER} ${GAME_GENERATED_SERVER})
+if(TARGET_OS STREQUAL "windows")
+ set(SERVER_ICON "other/icons/${SERVER_EXECUTABLE}.rc")
+else()
+ set(SERVER_ICON)
+endif()
+
+# Libraries
+set(LIBS_SERVER ${LIBS})
+
+# Target
+set(TARGET_SERVER ${SERVER_EXECUTABLE})
+add_executable(${TARGET_SERVER}
+ ${DEPS}
+ ${SERVER_SRC}
+ ${SERVER_ICON}
+ $<TARGET_OBJECTS:engine-shared>
+ $<TARGET_OBJECTS:game-shared>
+)
+target_link_libraries(${TARGET_SERVER} ${LIBS_SERVER})
+list(APPEND TARGETS_OWN ${TARGET_SERVER})
+list(APPEND TARGETS_LINK ${TARGET_SERVER})
+
+if(TARGET_OS AND TARGET_OS STREQUAL "mac")
+ set(SERVER_LAUNCHER_SRC src/osxlaunch/server.mm)
+ set(TARGET_SERVER_LAUNCHER ${TARGET_SERVER}-Launcher)
+ add_executable(${TARGET_SERVER_LAUNCHER} ${SERVER_LAUNCHER_SRC})
+ target_link_libraries(${TARGET_SERVER_LAUNCHER} ${COCOA})
+ list(APPEND TARGETS_OWN ${TARGET_SERVER_LAUNCHER})
+ list(APPEND TARGETS_LINK ${TARGET_SERVER_LAUNCHER})
+endif()
+
+########################################################################
+# VARIOUS TARGETS
+########################################################################
+
+set_glob(MASTERSRV_SRC GLOB src/mastersrv mastersrv.cpp mastersrv.h)
+set_glob(VERSIONSRV_SRC GLOB src/versionsrv mapversions.h versionsrv.cpp versionsrv.h)
+
+set(TARGET_MASTERSRV mastersrv)
+set(TARGET_VERSIONSRV versionsrv)
+
+add_executable(${TARGET_MASTERSRV} EXCLUDE_FROM_ALL ${MASTERSRV_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
+add_executable(${TARGET_VERSIONSRV} EXCLUDE_FROM_ALL ${VERSIONSRV_SRC} $<TARGET_OBJECTS:engine-shared> ${DEPS})
+
+target_link_libraries(${TARGET_MASTERSRV} ${LIBS})
+target_link_libraries(${TARGET_VERSIONSRV} ${LIBS})
+
+list(APPEND TARGETS_OWN ${TARGET_MASTERSRV} ${TARGET_VERSIONSRV})
+list(APPEND TARGETS_LINK ${TARGET_MASTERSRV} ${TARGET_VERSIONSRV})
+
+set(TARGETS_TOOLS)
+set_glob(TOOLS GLOB src/tools
+ crapnet.cpp
+ dilate.cpp
+ fake_server.cpp
+ map_resave.cpp
+ map_version.cpp
+ packetgen.cpp
+ tileset_borderadd.cpp
+ tileset_borderfix.cpp
+ tileset_borderrem.cpp
+ tileset_borderset.cpp
+)
+foreach(ABS_T ${TOOLS})
+ file(RELATIVE_PATH T "${PROJECT_SOURCE_DIR}/src/tools/" ${ABS_T})
+ if(T MATCHES "\\.cpp$")
+ string(REGEX REPLACE "\\.cpp$" "" TOOL "${T}")
+ set(TOOL_DEPS ${DEPS})
+ set(TOOL_LIBS ${LIBS})
+ if(TOOL MATCHES "^(tileset_.*|dilate|map_extract|map_replace_image)$")
+ list(APPEND TOOL_DEPS ${PNGLITE_DEP})
+ list(APPEND TOOL_LIBS ${PNGLITE_LIBRARIES})
+ list(APPEND TOOL_INCLUDE_DIRS ${PNGLITE_INCLUDE_DIRS})
+ endif()
+ set(EXCLUDE_FROM_ALL)
+ add_executable(${TOOL} EXCLUDE_FROM_ALL
+ ${TOOL_DEPS}
+ src/tools/${TOOL}.cpp
+ ${EXTRA_TOOL_SRC}
+ $<TARGET_OBJECTS:engine-shared>
+ )
+ target_include_directories(${TOOL} PRIVATE ${TOOL_INCLUDE_DIRS})
+ target_link_libraries(${TOOL} ${TOOL_LIBS})
+ list(APPEND TARGETS_TOOLS ${TOOL})
+ endif()
+endforeach()
+
+list(APPEND TARGETS_OWN ${TARGETS_TOOLS})
+list(APPEND TARGETS_LINK ${TARGETS_TOOLS})
+
+add_custom_target(tools DEPENDS ${TARGETS_TOOLS})
+add_custom_target(everything DEPENDS ${TARGETS_OWN})
+
+########################################################################
+# INSTALLATION
+########################################################################
+
+function(escape_regex VAR STRING)
+ string(REGEX REPLACE "([][^$.+*?|()\\\\])" "\\\\\\1" ESCAPED "${STRING}")
+ set(${VAR} ${ESCAPED} PARENT_SCOPE)
+endfunction()
+
+function(escape_backslashes VAR STRING)
+ string(REGEX REPLACE "\\\\" "\\\\\\\\" ESCAPED "${STRING}")
+ set(${VAR} ${ESCAPED} PARENT_SCOPE)
+endfunction()
+
+function(max_length VAR)
+ set(MAX_LENGTH 0)
+ foreach(str ${ARGN})
+ string(LENGTH ${str} LENGTH)
+ if(LENGTH GREATER MAX_LENGTH)
+ set(MAX_LENGTH ${LENGTH})
+ endif()
+ endforeach()
+ set(${VAR} ${MAX_LENGTH} PARENT_SCOPE)
+endfunction()
+
+# Tries to generate a list of regex that matches everything except the given
+# parameters.
+function(regex_inverted VAR)
+ max_length(MAX_LENGTH ${ARGN})
+ math(EXPR UPPER_BOUND "${MAX_LENGTH}-1")
+
+ set(REMAINING ${ARGN})
+ set(RESULT)
+
+ foreach(i RANGE ${UPPER_BOUND})
+ set(TEMP ${REMAINING})
+ set(REMAINING)
+ foreach(str ${TEMP})
+ string(LENGTH ${str} LENGTH)
+ if(i LESS LENGTH)
+ list(APPEND REMAINING ${str})
+ endif()
+ endforeach()
+
+ set(ADDITIONAL)
+ foreach(outer ${REMAINING})
+ string(SUBSTRING ${outer} 0 ${i} OUTER_PREFIX)
+ set(CHARS "")
+ foreach(inner ${REMAINING})
+ string(SUBSTRING ${inner} 0 ${i} INNER_PREFIX)
+ if(OUTER_PREFIX STREQUAL INNER_PREFIX)
+ string(SUBSTRING ${inner} ${i} 1 INNER_NEXT)
+ set(CHARS "${CHARS}${INNER_NEXT}")
+ endif()
+ endforeach()
+ escape_regex(OUTER_PREFIX_ESCAPED "${OUTER_PREFIX}")
+
+ list(APPEND ADDITIONAL "${OUTER_PREFIX_ESCAPED}([^${CHARS}]|$)")
+ endforeach()
+ list(REMOVE_DUPLICATES ADDITIONAL)
+ list(APPEND RESULT ${ADDITIONAL})
+ endforeach()
+ set(${VAR} ${RESULT} PARENT_SCOPE)
+endfunction()
+
+set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
+set(CPACK_GENERATOR TGZ TXZ)
+set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
+set(CPACK_STRIP_FILES TRUE)
+set(CPACK_COMPONENTS_ALL portable)
+set(CPACK_SOURCE_GENERATOR ZIP TGZ TBZ2 TXZ)
+set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
+set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
+if(VERSION_PATCH STREQUAL "0")
+ set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR})
+else()
+ set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH})
+endif()
+set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME})
+
+if(TARGET_OS AND TARGET_BITS)
+ if(TARGET_OS STREQUAL "windows")
+ set(CPACK_SYSTEM_NAME "win${TARGET_BITS}")
+ set(CPACK_GENERATOR ZIP)
+ elseif(TARGET_OS STREQUAL "linux")
+ # Assuming Intel here.
+ if(TARGET_BITS EQUAL 32)
+ set(CPACK_SYSTEM_NAME "linux_x86")
+ elseif(TARGET_BITS EQUAL 64)
+ set(CPACK_SYSTEM_NAME "linux_x86_64")
+ endif()
+ elseif(TARGET_OS STREQUAL "mac")
+ set(CPACK_SYSTEM_NAME "osx")
+ set(CPACK_GENERATOR DMG)
+ endif()
+endif()
+
+set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME})
+set(CPACK_ARCHIVE_PORTABLE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
+set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src)
+set(CPACK_SOURCE_FILES
+ CMakeLists.txt
+ bam.lua
+ cmake/
+ configure.lua
+ data/
+ datasrc/
+ docs/
+ license.txt
+ objs/
+ other/
+ readme.txt
+ scripts/
+ src/
+ storage.cfg
+)
+set(CPACK_SOURCE_IGNORE_FILES
+ "\\\\.o$"
+ "\\\\.pyc$"
+ "/\\\\.git"
+ "/__pycache__/"
+)
+
+regex_inverted(CPACK_SOURCE_FILES_INVERTED ${CPACK_SOURCE_FILES})
+escape_regex(PROJECT_SOURCE_DIR_ESCAPED ${PROJECT_SOURCE_DIR})
+
+foreach(str ${CPACK_SOURCE_FILES_INVERTED})
+ escape_backslashes(STR_ESCAPED "${PROJECT_SOURCE_DIR_ESCAPED}/${str}")
+ list(APPEND CPACK_SOURCE_IGNORE_FILES "${STR_ESCAPED}")
+endforeach()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME ${PROJECT_NAME})
+
+set(CPACK_TARGETS
+ ${TARGET_CLIENT}
+ ${TARGET_SERVER}
+)
+set(CPACK_DIRS data)
+set(CPACK_FILES
+ license.txt
+ storage.cfg
+ ${COPY_FILES}
+)
+if(TARGET_OS STREQUAL "windows")
+ list(APPEND CPACK_FILES other/config_directory.bat)
+endif()
+
+if(NOT DEV)
+ install(DIRECTORY data DESTINATION share/${PROJECT_NAME} COMPONENT data)
+ install(TARGETS ${TARGET_CLIENT} DESTINATION bin COMPONENT client)
+ install(TARGETS ${TARGET_SERVER} DESTINATION bin COMPONENT server)
+endif()
+
+if(DEV)
+ # Don't generate CPack targets.
+elseif(CMAKE_VERSION VERSION_LESS 3.6 OR CMAKE_VERSION VERSION_EQUAL 3.6)
+ message(WARNING "Cannot create CPack targets, CMake version too old. Use CMake 3.6 or newer.")
+else()
+ set(EXTRA_ARGS DESTINATION ${CPACK_PACKAGE_FILE_NAME} COMPONENT portable EXCLUDE_FROM_ALL)
+ install(TARGETS ${CPACK_TARGETS} ${EXTRA_ARGS})
+ install(DIRECTORY ${CPACK_DIRS} ${EXTRA_ARGS})
+ install(FILES ${CPACK_FILES} ${EXTRA_ARGS})
+endif()
+
+set(PACKAGE_TARGETS)
+
+if(CLIENT AND (DMGTOOLS_FOUND OR HDIUTIL))
+ file(MAKE_DIRECTORY bundle/client/)
+ file(MAKE_DIRECTORY bundle/server/)
+ configure_file(other/bundle/client/Info.plist.in bundle/client/Info.plist)
+ configure_file(other/bundle/server/Info.plist.in bundle/server/Info.plist)
+
+ if(HDIUTIL)
+ set(DMG_PARAMS --hdiutil ${HDIUTIL})
+ elseif(DMGTOOLS_FOUND)
+ set(DMG_PARAMS --dmgtools ${DMG} ${HFSPLUS} ${NEWFS_HFS})
+ endif()
+ set(DMG_TMPDIR pack_${CPACK_PACKAGE_FILE_NAME}_dmg)
+ set(DMG_MKDIRS
+ ${TARGET_CLIENT}.app
+ ${TARGET_CLIENT}.app/Contents
+ ${TARGET_CLIENT}.app/Contents/Frameworks
+ ${TARGET_CLIENT}.app/Contents/MacOS
+ ${TARGET_CLIENT}.app/Contents/Resources
+ ${TARGET_SERVER}.app
+ ${TARGET_SERVER}.app/Contents
+ ${TARGET_SERVER}.app/Contents/MacOS
+ ${TARGET_SERVER}.app/Contents/Resources
+ ${TARGET_SERVER}.app/Contents/Resources/data
+ ${TARGET_SERVER}.app/Contents/Resources/data/mapres
+ )
+ set(DMG_MKDIR_COMMANDS)
+ foreach(dir ${DMG_MKDIRS})
+ list(APPEND DMG_MKDIR_COMMANDS COMMAND ${CMAKE_COMMAND} -E make_directory ${DMG_TMPDIR}/${dir})
+ endforeach()
+ add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.dmg
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${DMG_TMPDIR}
+ ${DMG_MKDIR_COMMANDS}
+
+ # CLIENT
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_CLIENT}.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/
+ COMMAND ${CMAKE_COMMAND} -E copy bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET_CLIENT}> ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/other/sdl/mac/lib64/SDL.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL.framework
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/
+ COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/darwin_change_dylib.py change --tools ${CMAKE_INSTALL_NAME_TOOL} ${CMAKE_OTOOL} ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} SDL @executable_path/../Frameworks/SDL.framework/SDL
+ COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/darwin_change_dylib.py change --tools ${CMAKE_INSTALL_NAME_TOOL} ${CMAKE_OTOOL} ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} libfreetype @executable_path/../Frameworks/libfreetype.6.dylib
+
+ # SERVER
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/
+ COMMAND ${CMAKE_COMMAND} -E copy bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET_SERVER}> $<TARGET_FILE:${TARGET_SERVER_LAUNCHER}> ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/
+
+ # DMG
+ COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR}
+
+ DEPENDS
+ ${TARGET_CLIENT}
+ ${TARGET_SERVER_LAUNCHER}
+ ${TARGET_SERVER}
+ ${PROJECT_BINARY_DIR}/bundle/client/Info.plist
+ ${PROJECT_BINARY_DIR}/bundle/server/Info.plist
+ data
+ other/bundle/client/PkgInfo
+ other/bundle/server/PkgInfo
+ other/icons/${TARGET_CLIENT}.icns
+ other/icons/${TARGET_SERVER}.icns
+ scripts/dmg.py
+ )
+ add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg)
+ list(APPEND PACKAGE_TARGETS package_dmg)
+endif()
+
+foreach(ext zip tar.gz tar.xz)
+ set(TAR_MODE c)
+ set(TAR_EXTRA_ARGS)
+ string(REPLACE . _ EXT_SLUG ${ext})
+
+ set(TMPDIR pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG}/${CPACK_PACKAGE_FILE_NAME})
+
+ set(COPY_FILE_COMMANDS)
+ set(COPY_DIR_COMMANDS)
+ set(COPY_TARGET_COMMANDS)
+ set(STRIP_TARGET_COMMANDS)
+ foreach(file ${CPACK_FILES})
+ list(APPEND COPY_FILE_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/${file} ${TMPDIR}/)
+ endforeach()
+ foreach(dir ${CPACK_DIRS})
+ list(APPEND COPY_DIR_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${TMPDIR}/${dir})
+ endforeach()
+ foreach(target ${CPACK_TARGETS})
+ list(APPEND COPY_TARGET_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${target}> ${TMPDIR}/)
+ endforeach()
+
+ if(ext STREQUAL zip)
+ set(TAR_EXTRA_ARGS --format=zip)
+ elseif(ext STREQUAL tar.gz)
+ set(TAR_MODE cz)
+ elseif(ext STREQUAL tar.xz)
+ set(TAR_MODE cJ)
+ endif()
+ add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext}
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${TMPDIR}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${TMPDIR}
+ ${COPY_FILE_COMMANDS}
+ ${COPY_DIR_COMMANDS}
+ ${COPY_TARGET_COMMANDS}
+ ${STRIP_TARGET_COMMANDS}
+ COMMAND ${CMAKE_COMMAND} -E chdir pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG} ${CMAKE_COMMAND} -E tar ${TAR_MODE} ../${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/
+ DEPENDS ${CPACK_TARGETS}
+ )
+ add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext})
+ list(APPEND PACKAGE_TARGETS package_${EXT_SLUG})
+endforeach()
+
+set(PACKAGE_DEFAULT tar_xz)
+if(TARGET_OS STREQUAL "windows")
+ set(PACKAGE_DEFAULT zip)
+elseif(TARGET_OS STREQUAL "mac")
+ set(PACKAGE_DEFAULT dmg)
+endif()
+add_custom_target(package_default DEPENDS package_${PACKAGE_DEFAULT})
+
+add_custom_target(package_all DEPENDS ${PACKAGE_TARGETS})
+
+# Unset these variables, they might do something in the future of CPack.
+unset(CPACK_SOURCE_FILES)
+unset(CPACK_SOURCE_FILES_INVERTED)
+unset(CPACK_TARGETS)
+unset(CPACK_DIRS)
+unset(CPACK_FILES)
+
+include(CPack)
+
+########################################################################
+# COMPILER-SPECIFICS
+########################################################################
+
+# In the future (CMake 3.8.0+), use source_group(TREE ...)
+macro(source_group_tree dir)
+ file(GLOB ents RELATIVE ${PROJECT_SOURCE_DIR}/${dir} ${PROJECT_SOURCE_DIR}/${dir}/*)
+ foreach(ent ${ents})
+ if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${dir}/${ent})
+ source_group_tree(${dir}/${ent})
+ else()
+ string(REPLACE "/" "\\" group ${dir})
+ source_group(${group} FILES ${PROJECT_SOURCE_DIR}/${dir}/${ent})
+ endif()
+ endforeach()
+endmacro()
+source_group_tree(src)
+
+set(TARGETS ${TARGETS_OWN} ${TARGETS_DEP})
+
+foreach(target ${TARGETS})
+ if(MSVC)
+ target_compile_options(${target} PRIVATE $<$<NOT:${DBG}>:/MT> $<${DBG}:/MTd>) # Use static CRT
+ target_compile_options(${target} PRIVATE /MP) # Use multiple cores
+ target_compile_options(${target} PRIVATE /EHsc) # Only catch C++ exceptions with catch.
+ target_compile_options(${target} PRIVATE /GS) # Protect the stack pointer.
+ target_compile_options(${target} PRIVATE /wd4996) # Use of non-_s functions.
+ endif()
+ if(OUR_FLAGS)
+ target_compile_options(${target} PRIVATE ${OUR_FLAGS})
+ endif()
+ if(DEFINE_FORTIFY_SOURCE)
+ target_compile_definitions(${target} PRIVATE $<$<NOT:$<CONFIG:Debug>>:_FORTIFY_SOURCE=2>) # Detect some buffer overflows.
+ endif()
+endforeach()
+
+foreach(target ${TARGETS_LINK})
+ if(MSVC)
+ set_property(TARGET ${target} APPEND PROPERTY LINK_FLAGS /SAFESEH:NO) # Disable SafeSEH because the shipped libraries don't support it (would cause error LNK2026 otherwise).
+ endif()
+ if(TARGET_OS STREQUAL "mac")
+ target_link_libraries(${target} -stdlib=libc++)
+ target_link_libraries(${target} -mmacosx-version-min=10.7)
+ endif()
+ if((MINGW OR TARGET_OS STREQUAL "linux") AND PREFER_BUNDLED_LIBS)
+ # Statically link the standard libraries with on MinGW/Linux so we don't
+ # have to ship them as DLLs.
+ target_link_libraries(${target} -static-libgcc)
+ target_link_libraries(${target} -static-libstdc++)
+ if(MINGW)
+ # Link pthread library statically instead of dynamically.
+ # Solution from https://stackoverflow.com/a/28001261.
+ target_link_libraries(${target} -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic)
+ endif()
+ endif()
+endforeach()
+
+foreach(target ${TARGETS_OWN})
+ if(MSVC)
+ target_compile_options(${target} PRIVATE /wd4244) # Possible loss of data (float -> int, int -> float, etc.).
+ target_compile_options(${target} PRIVATE /wd4267) # Possible loss of data (size_t - int on win64).
+ target_compile_options(${target} PRIVATE /wd4800) # Implicit conversion of int to bool.
+ endif()
+ if(OUR_FLAGS_OWN)
+ target_compile_options(${target} PRIVATE ${OUR_FLAGS_OWN})
+ endif()
+ target_include_directories(${target} PRIVATE ${PROJECT_BINARY_DIR}/src)
+ target_include_directories(${target} PRIVATE src)
+ target_compile_definitions(${target} PRIVATE $<$<CONFIG:Debug>:CONF_DEBUG>)
+ target_include_directories(${target} PRIVATE ${CURL_INCLUDE_DIRS})
+ target_include_directories(${target} PRIVATE ${ZLIB_INCLUDE_DIRS})
+endforeach()
+
+foreach(target ${TARGETS_DEP})
+ if(MSVC)
+ target_compile_options(${target} PRIVATE /W0)
+ endif()
+ if(OUR_FLAGS_DEP)
+ target_compile_options(${target} PRIVATE ${OUR_FLAGS_DEP})
+ endif()
+endforeach()
diff --git a/bam.lua b/bam.lua
index f8b178077..214b9fccf 100644
--- a/bam.lua
+++ b/bam.lua
@@ -169,6 +169,7 @@ function build(settings)
-- set some platform specific settings
settings.cc.includes:Add("src")
+ settings.cc.includes:Add("src/engine/external/wavpack")
if family == "unix" then
if platform == "macosx" then
@@ -252,10 +253,8 @@ function build(settings)
-- build tools (TODO: fix this so we don't get double _d_d stuff)
tools_src = Collect("src/tools/*.cpp", "src/tools/*.c")
- client_osxlaunch = {}
server_osxlaunch = {}
if platform == "macosx" then
- client_osxlaunch = Compile(client_settings, "src/osxlaunch/client.m")
server_osxlaunch = Compile(launcher_settings, "src/osxlaunch/server.m")
end
@@ -268,7 +267,7 @@ function build(settings)
-- build client, server, version server and master server
client_exe = Link(client_settings, "teeworlds", game_shared, game_client,
engine, client, game_editor, md5, zlib, pnglite, wavpack,
- client_link_other, client_osxlaunch)
+ client_link_other)
server_exe = Link(server_settings, "teeworlds_srv", engine, server,
game_shared, game_server, md5, zlib, server_link_other)
diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake
new file mode 100644
index 000000000..347b68442
--- /dev/null
+++ b/cmake/FindFreetype.cmake
@@ -0,0 +1,37 @@
+if(NOT CMAKE_CROSSCOMPILING)
+ find_package(PkgConfig QUIET)
+ pkg_check_modules(PC_FREETYPE freetype2)
+endif()
+
+set_extra_dirs_lib(FREETYPE freetype)
+find_library(FREETYPE_LIBRARY
+ NAMES freetype freetype.6
+ HINTS ${HINTS_FREETYPE_LIBDIR} ${PC_FREETYPE_LIBDIR} ${PC_FREETYPE_LIBRARY_DIRS}
+ PATHS ${PATHS_FREETYPE_LIBDIR}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+)
+set_extra_dirs_include(FREETYPE freetype "${FREETYPE_LIBRARY}")
+find_path(FREETYPE_INCLUDEDIR
+ NAMES config/ftheader.h freetype/config/ftheader.h
+ PATH_SUFFIXES freetype2
+ HINTS ${HINTS_FREETYPE_INCLUDEDIR} ${PC_FREETYPE_INCLUDEDIR} ${PC_FREETYPE_INCLUDE_DIRS}
+ PATHS ${PATHS_FREETYPE_INCLUDEDIR}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Freetype DEFAULT_MSG FREETYPE_LIBRARY FREETYPE_INCLUDEDIR)
+
+mark_as_advanced(FREETYPE_LIBRARY FREETYPE_INCLUDEDIR)
+
+if(FREETYPE_FOUND)
+ set(FREETYPE_LIBRARIES ${FREETYPE_LIBRARY})
+ set(FREETYPE_INCLUDE_DIRS ${FREETYPE_INCLUDEDIR})
+
+ is_bundled(FREETYPE_BUNDLED "${FREETYPE_LIBRARY}")
+ if(FREETYPE_BUNDLED AND TARGET_OS STREQUAL "windows")
+ set(FREETYPE_COPY_FILES "${EXTRA_FREETYPE_LIBDIR}/freetype.dll")
+ else()
+ set(FREETYPE_COPY_FILES)
+ endif()
+endif()
diff --git a/cmake/FindPnglite.cmake b/cmake/FindPnglite.cmake
new file mode 100644
index 000000000..b011a5011
--- /dev/null
+++ b/cmake/FindPnglite.cmake
@@ -0,0 +1,46 @@
+if(NOT PREFER_BUNDLED_LIBS)
+ if(NOT CMAKE_CROSSCOMPILING)
+ find_package(PkgConfig QUIET)
+ pkg_check_modules(PC_PNGLITE pnglite)
+ endif()
+
+ find_library(PNGLITE_LIBRARY
+ NAMES pnglite
+ HINTS ${PC_PNGLITE_LIBDIR} ${PC_PNGLITE_LIBRARY_DIRS}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+ )
+ find_path(PNGLITE_INCLUDEDIR
+ NAMES pnglite.h
+ HINTS ${PC_PNGLITE_INCLUDEDIR} ${PC_PNGLITE_INCLUDE_DIRS}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+ )
+
+ mark_as_advanced(PNGLITE_LIBRARY PNGLITE_INCLUDEDIR)
+
+ if(PNGLITE_LIBRARY AND PNGLITE_INCLUDEDIR)
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Pnglite DEFAULT_MSG PNGLITE_LIBRARY PNGLITE_INCLUDEDIR)
+
+ set(PNGLITE_LIBRARIES ${PNGLITE_LIBRARY})
+ set(PNGLITE_INCLUDE_DIRS ${PNGLITE_INCLUDEDIR})
+ set(PNGLITE_BUNDLED OFF)
+ endif()
+endif()
+
+if(NOT PNGLITE_FOUND)
+ set(PNGLITE_SRC_DIR src/engine/external/pnglite)
+ set_glob(PNGLITE_SRC GLOB ${PNGLITE_SRC_DIR} pnglite.c pnglite.h)
+ add_library(pnglite EXCLUDE_FROM_ALL OBJECT ${PNGLITE_SRC})
+ list(APPEND TARGETS_DEP pnglite)
+
+ set(PNGLITE_INCLUDEDIR ${PNGLITE_SRC_DIR})
+ target_include_directories(pnglite PRIVATE ${ZLIB_INCLUDE_DIRS})
+
+ set(PNGLITE_DEP $<TARGET_OBJECTS:pnglite>)
+ set(PNGLITE_INCLUDE_DIRS ${PNGLITE_INCLUDEDIR})
+ set(PNGLITE_LIBRARIES)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Pnglite DEFAULT_MSG PNGLITE_INCLUDEDIR)
+ set(PNGLITE_BUNDLED ON)
+endif()
diff --git a/cmake/FindSDL.cmake b/cmake/FindSDL.cmake
new file mode 100644
index 000000000..137567501
--- /dev/null
+++ b/cmake/FindSDL.cmake
@@ -0,0 +1,38 @@
+if(NOT CMAKE_CROSSCOMPILING)
+ find_package(PkgConfig QUIET)
+ pkg_check_modules(PC_SDL sdl)
+endif()
+
+set_extra_dirs_lib(SDL sdl)
+find_library(SDL_LIBRARY
+ NAMES SDL
+ HINTS ${HINTS_SDL_LIBDIR} ${PC_SDL_LIBDIR} ${PC_SDL_LIBRARY_DIRS}
+ PATHS ${PATHS_SDL_LIBDIR}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+)
+set(CMAKE_FIND_FRAMEWORK FIRST)
+set_extra_dirs_include(SDL sdl "${SDL_LIBRARY}")
+# Looking for 'SDL.h' directly might accidentally find a SDL 2 instead of SDL
+# installation. Look for a header file only present in SDL instead.
+find_path(SDL_INCLUDEDIR SDL_active.h
+ PATH_SUFFIXES SDL
+ HINTS ${HINTS_SDL_INCLUDEDIR} ${PC_SDL_INCLUDEDIR} ${PC_SDL_INCLUDE_DIRS}
+ PATHS ${PATHS_SDL_INCLUDEDIR}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SDL DEFAULT_MSG SDL_LIBRARY SDL_INCLUDEDIR)
+
+mark_as_advanced(SDL_LIBRARY SDL_INCLUDEDIR)
+
+if(SDL_FOUND)
+ set(SDL_LIBRARIES ${SDL_LIBRARY})
+ set(SDL_INCLUDE_DIRS ${SDL_INCLUDEDIR})
+
+ is_bundled(SDL_BUNDLED "${SDL_LIBRARY}")
+ if(SDL_BUNDLED AND TARGET_OS STREQUAL "windows")
+ set(SDL_COPY_FILES "${EXTRA_SDL_LIBDIR}/SDL.dll")
+ else()
+ set(SDL_COPY_FILES)
+ endif()
+endif()
diff --git a/cmake/FindWavpack.cmake b/cmake/FindWavpack.cmake
new file mode 100644
index 000000000..086902ca7
--- /dev/null
+++ b/cmake/FindWavpack.cmake
@@ -0,0 +1,52 @@
+if(NOT PREFER_BUNDLED_LIBS)
+ if(NOT CMAKE_CROSSCOMPILING)
+ find_package(PkgConfig QUIET)
+ pkg_check_modules(PC_WAVPACK wavpack)
+ endif()
+
+ find_library(WAVPACK_LIBRARY
+ NAMES wavpack
+ HINTS ${PC_WAVPACK_LIBDIR} ${PC_WAVPACK_LIBRARY_DIRS}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+ )
+ find_path(WAVPACK_INCLUDEDIR
+ NAMES wavpack.h
+ PATH_SUFFIXES wavpack
+ HINTS ${PC_WAVPACK_INCLUDEDIR} ${PC_WAVPACK_INCLUDE_DIRS}
+ ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
+ )
+
+ mark_as_advanced(WAVPACK_LIBRARY WAVPACK_INCLUDEDIR)
+
+ if(WAVPACK_LIBRARY AND WAVPACK_INCLUDEDIR)
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Wavpack DEFAULT_MSG WAVPACK_LIBRARY WAVPACK_INCLUDEDIR)
+
+ set(WAVPACK_LIBRARIES ${WAVPACK_LIBRARY})
+ set(WAVPACK_INCLUDE_DIRS ${WAVPACK_INCLUDEDIR})
+ set(WAVPACK_BUNDLED OFF)
+ endif()
+endif()
+
+if(NOT WAVPACK_FOUND)
+ set(WAVPACK_SRC_DIR src/engine/external/wavpack)
+ set_glob(WAVPACK_SRC GLOB ${WAVPACK_SRC_DIR}
+ bits.c
+ float.c
+ metadata.c
+ unpack.c
+ wavpack.h
+ words.c
+ wputils.c
+ )
+ add_library(wavpack EXCLUDE_FROM_ALL OBJECT ${WAVPACK_SRC})
+ set(WAVPACK_DEP $<TARGET_OBJECTS:wavpack>)
+ set(WAVPACK_INCLUDEDIR ${WAVPACK_SRC_DIR})
+ set(WAVPACK_INCLUDE_DIRS ${WAVPACK_INCLUDEDIR})
+
+ list(APPEND TARGETS_DEP wavpack)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Wavpack DEFAULT_MSG WAVPACK_INCLUDEDIR)
+ set(WAVPACK_BUNDLED ON)
+endif()
diff --git a/cmake/FindZLIB.cmake b/cmake/FindZLIB.cmake
new file mode 100644
index 000000000..5c51bd8ba
--- /dev/null
+++ b/cmake/FindZLIB.cmake
@@ -0,0 +1,50 @@
+if(NOT PREFER_BUNDLED_LIBS)
+ set(CMAKE_MODULE_PATH ${ORIGINAL_CMAKE_MODULE_PATH})
+ find_package(ZLIB)
+ set(CMAKE_MODULE_PATH ${OWN_CMAKE_MODULE_PATH})
+ if(ZLIB_FOUND)
+ set(ZLIB_BUNDLED OFF)
+ set(ZLIB_DEP)
+ endif()
+endif()
+
+if(NOT ZLIB_FOUND)
+ set(ZLIB_BUNDLED ON)
+ set(ZLIB_SRC_DIR src/engine/external/zlib)
+ set_glob(ZLIB_SRC GLOB ${ZLIB_SRC_DIR}
+ adler32.c
+ compress.c
+ crc32.c
+ crc32.h
+ deflate.c
+ deflate.h
+ gzguts.h
+ infback.c
+ inffast.c
+ inffast.h
+ inffixed.h
+ inflate.c
+ inflate.h
+ inftrees.c
+ inftrees.h
+ trees.c
+ trees.h
+ uncompr.c
+ zconf.h
+ zlib.h
+ zutil.c
+ zutil.h
+ )
+ add_library(zlib EXCLUDE_FROM_ALL OBJECT ${ZLIB_SRC})
+ set(ZLIB_INCLUDEDIR ${ZLIB_SRC_DIR})
+ target_include_directories(zlib PRIVATE ${ZLIB_INCLUDEDIR})
+
+ set(ZLIB_DEP $<TARGET_OBJECTS:zlib>)
+ set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDEDIR})
+ set(ZLIB_LIBRARIES)
+
+ list(APPEND TARGETS_DEP zlib)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(ZLIB DEFAULT_MSG ZLIB_INCLUDEDIR)
+endif()
diff --git a/cmake/toolchains/darwin.toolchain b/cmake/toolchains/darwin.toolchain
new file mode 100644
index 000000000..6d1d6eb3e
--- /dev/null
+++ b/cmake/toolchains/darwin.toolchain
@@ -0,0 +1,11 @@
+set(CMAKE_SYSTEM_NAME Darwin)
+
+set(CMAKE_C_COMPILER o64-clang)
+set(CMAKE_CXX_COMPILER o64-clang++)
+set(CMAKE_INSTALL_NAME_TOOL x86_64-apple-darwin15-install_name_tool)
+set(CMAKE_OTOOL x86_64-apple-darwin15-otool)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/cmake/toolchains/mingw32.toolchain b/cmake/toolchains/mingw32.toolchain
new file mode 100644
index 000000000..c4c065b7e
--- /dev/null
+++ b/cmake/toolchains/mingw32.toolchain
@@ -0,0 +1,10 @@
+set(CMAKE_SYSTEM_NAME Windows)
+
+set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
+set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/cmake/toolchains/mingw64.toolchain b/cmake/toolchains/mingw64.toolchain
new file mode 100644
index 000000000..bec41e944
--- /dev/null
+++ b/cmake/toolchains/mingw64.toolchain
@@ -0,0 +1,10 @@
+set(CMAKE_SYSTEM_NAME Windows)
+
+set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
+set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/other/bundle/client/Info.plist.in b/other/bundle/client/Info.plist.in
new file mode 100644
index 000000000..3346bf5e6
--- /dev/null
+++ b/other/bundle/client/Info.plist.in
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${TARGET_CLIENT}</string>
+ <key>CFBundleIconFile</key>
+ <string>${TARGET_CLIENT}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${PROJECT_VERSION}</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.DDNetClient.app</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
+ </dict>
+</plist>
diff --git a/other/bundle/client/PkgInfo b/other/bundle/client/PkgInfo
new file mode 100644
index 000000000..6f749b0f3
--- /dev/null
+++ b/other/bundle/client/PkgInfo
@@ -0,0 +1 @@
+APPL????
diff --git a/other/bundle/server/Info.plist.in b/other/bundle/server/Info.plist.in
new file mode 100644
index 000000000..6cdd38f0d
--- /dev/null
+++ b/other/bundle/server/Info.plist.in
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${TARGET_SERVER_LAUNCHER}</string>
+ <key>CFBundleIconFile</key>
+ <string>${TARGET_SERVER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${PROJECT_VERSION}</string>
+ </dict>
+</plist>
diff --git a/other/bundle/server/PkgInfo b/other/bundle/server/PkgInfo
new file mode 100644
index 000000000..6f749b0f3
--- /dev/null
+++ b/other/bundle/server/PkgInfo
@@ -0,0 +1 @@
+APPL????
diff --git a/other/freetype/freetype.lua b/other/freetype/freetype.lua
index 9d484afbd..9df4de40a 100644
--- a/other/freetype/freetype.lua
+++ b/other/freetype/freetype.lua
@@ -39,9 +39,9 @@ FreeType = {
elseif option.use_winlib > 0 then
if option.use_winlib == 32 then
- settings.link.libpath:Add(FreeType.basepath .. "/lib32")
+ settings.link.libpath:Add(FreeType.basepath .. "/windows/lib32")
else
- settings.link.libpath:Add(FreeType.basepath .. "/lib64")
+ settings.link.libpath:Add(FreeType.basepath .. "/windows/lib64")
end
settings.link.libs:Add("freetype")
end
diff --git a/other/freetype/lib32/freetype.dll b/other/freetype/windows/lib32/freetype.dll
index e98c734ca..e98c734ca 100644
--- a/other/freetype/lib32/freetype.dll
+++ b/other/freetype/windows/lib32/freetype.dll
Binary files differ
diff --git a/other/freetype/lib32/freetype.lib b/other/freetype/windows/lib32/freetype.lib
index e7664732c..e7664732c 100644
--- a/other/freetype/lib32/freetype.lib
+++ b/other/freetype/windows/lib32/freetype.lib
Binary files differ
diff --git a/other/freetype/lib64/freetype.dll b/other/freetype/windows/lib64/freetype.dll
index 17af6b183..17af6b183 100644
--- a/other/freetype/lib64/freetype.dll
+++ b/other/freetype/windows/lib64/freetype.dll
Binary files differ
diff --git a/other/freetype/lib64/freetype.lib b/other/freetype/windows/lib64/freetype.lib
index 1bdf9fda2..1bdf9fda2 100644
--- a/other/freetype/lib64/freetype.lib
+++ b/other/freetype/windows/lib64/freetype.lib
Binary files differ
diff --git a/other/icons/Teeworlds.icns b/other/icons/teeworlds.icns
index 22be3422e..22be3422e 100644
--- a/other/icons/Teeworlds.icns
+++ b/other/icons/teeworlds.icns
Binary files differ
diff --git a/other/icons/Teeworlds.ico b/other/icons/teeworlds.ico
index 3ddec5c3d..3ddec5c3d 100644
--- a/other/icons/Teeworlds.ico
+++ b/other/icons/teeworlds.ico
Binary files differ
diff --git a/other/icons/teeworlds.rc b/other/icons/teeworlds.rc
new file mode 100644
index 000000000..aa5dcb44f
--- /dev/null
+++ b/other/icons/teeworlds.rc
@@ -0,0 +1 @@
+ID ICON "teeworlds.ico"
diff --git a/other/icons/Teeworlds_srv.icns b/other/icons/teeworlds_srv.icns
index 44a847ebb..44a847ebb 100644
--- a/other/icons/Teeworlds_srv.icns
+++ b/other/icons/teeworlds_srv.icns
Binary files differ
diff --git a/other/icons/Teeworlds_srv.ico b/other/icons/teeworlds_srv.ico
index bde79f6a6..bde79f6a6 100644
--- a/other/icons/Teeworlds_srv.ico
+++ b/other/icons/teeworlds_srv.ico
Binary files differ
diff --git a/other/icons/teeworlds_srv.rc b/other/icons/teeworlds_srv.rc
new file mode 100644
index 000000000..44287bb51
--- /dev/null
+++ b/other/icons/teeworlds_srv.rc
@@ -0,0 +1 @@
+ID ICON "teeworlds_srv.ico"
diff --git a/other/icons/teeworlds_srv_cl.rc b/other/icons/teeworlds_srv_cl.rc
index f7b046d92..8e18b64ce 100644
--- a/other/icons/teeworlds_srv_cl.rc
+++ b/other/icons/teeworlds_srv_cl.rc
@@ -1 +1 @@
-50h ICON "Teeworlds_srv.ico"
+50h ICON "teeworlds_srv.ico"
diff --git a/other/icons/teeworlds_srv_gcc.rc b/other/icons/teeworlds_srv_gcc.rc
index 3b7c78a56..44287bb51 100644
--- a/other/icons/teeworlds_srv_gcc.rc
+++ b/other/icons/teeworlds_srv_gcc.rc
@@ -1 +1 @@
-ID ICON "Teeworlds_srv.ico"
+ID ICON "teeworlds_srv.ico"
diff --git a/other/sdl/sdl.lua b/other/sdl/sdl.lua
index 9bf75ea81..5b69901d2 100644
--- a/other/sdl/sdl.lua
+++ b/other/sdl/sdl.lua
@@ -51,9 +51,9 @@ SDL = {
if option.use_winlib > 0 then
settings.cc.includes:Add(SDL.basepath .. "/include")
if option.use_winlib == 32 then
- settings.link.libpath:Add(SDL.basepath .. "/lib32")
+ settings.link.libpath:Add(SDL.basepath .. "/windows/lib32")
else
- settings.link.libpath:Add(SDL.basepath .. "/lib64")
+ settings.link.libpath:Add(SDL.basepath .. "/windows/lib64")
end
settings.link.libs:Add("SDL")
settings.link.libs:Add("SDLmain")
diff --git a/other/sdl/lib32/SDL.dll b/other/sdl/windows/lib32/SDL.dll
index 69fd61ecb..69fd61ecb 100644
--- a/other/sdl/lib32/SDL.dll
+++ b/other/sdl/windows/lib32/SDL.dll
Binary files differ
diff --git a/other/sdl/lib32/SDL.lib b/other/sdl/windows/lib32/SDL.lib
index 22d50ba18..22d50ba18 100644
--- a/other/sdl/lib32/SDL.lib
+++ b/other/sdl/windows/lib32/SDL.lib
Binary files differ
diff --git a/other/sdl/lib32/SDLmain.lib b/other/sdl/windows/lib32/SDLmain.lib
index a891ca55f..a891ca55f 100644
--- a/other/sdl/lib32/SDLmain.lib
+++ b/other/sdl/windows/lib32/SDLmain.lib
Binary files differ
diff --git a/other/sdl/lib64/SDL.dll b/other/sdl/windows/lib64/SDL.dll
index dee47e810..dee47e810 100644
--- a/other/sdl/lib64/SDL.dll
+++ b/other/sdl/windows/lib64/SDL.dll
Binary files differ
diff --git a/other/sdl/lib64/SDL.lib b/other/sdl/windows/lib64/SDL.lib
index bfabad761..bfabad761 100644
--- a/other/sdl/lib64/SDL.lib
+++ b/other/sdl/windows/lib64/SDL.lib
Binary files differ
diff --git a/other/sdl/lib64/SDLmain.lib b/other/sdl/windows/lib64/SDLmain.lib
index c4ac06f34..c4ac06f34 100644
--- a/other/sdl/lib64/SDLmain.lib
+++ b/other/sdl/windows/lib64/SDLmain.lib
Binary files differ
diff --git a/scripts/darwin_change_dylib.py b/scripts/darwin_change_dylib.py
new file mode 100644
index 000000000..6f3922572
--- /dev/null
+++ b/scripts/darwin_change_dylib.py
@@ -0,0 +1,63 @@
+from collections import namedtuple
+import os
+import re
+import shlex
+import subprocess
+
+Config = namedtuple('Config', 'install_name_tool otool verbose')
+
+def dylib_regex(name):
+ return re.compile(r'\S*{}\S*'.format(re.escape(name)))
+
+class ChangeDylib:
+ def __init__(self, config):
+ self.config = config
+ def _check_call(self, process_args, *args, **kwargs):
+ if self.config.verbose >= 1:
+ print("EXECUTING {}".format(" ".join(shlex.quote(x) for x in process_args)))
+ if not (self.config.verbose >= 2 and "stdout" not in kwargs):
+ kwargs["stdout"] = open(os.devnull, 'wb')
+ return subprocess.check_call(process_args, *args, **kwargs)
+ def _check_output(self, process_args, *args, **kwargs):
+ if self.config.verbose >= 1:
+ print("EXECUTING {} FOR OUTPUT".format(" ".join(shlex.quote(x) for x in process_args)))
+ return subprocess.check_output(process_args, *args, **kwargs)
+ def _install_name_tool(self, *args):
+ return self._check_call((self.config.install_name_tool,) + args)
+ def _otool(self, *args):
+ return self._check_output((self.config.otool,) + args)
+
+ def change(self, filename, from_, to):
+ lines = self._otool("-L", filename).decode().splitlines()
+ regex = dylib_regex(from_)
+ matches = sum([regex.findall(l) for l in lines], [])
+ if len(matches) != 1:
+ if matches:
+ raise ValueError("More than one match found for {}: {}".format(from_, matches))
+ else:
+ raise ValueError("No matches found for {}".format(from_))
+ actual_from = matches[0]
+ self._install_name_tool("-change", actual_from, to, filename)
+
+def main():
+ import argparse
+ p = argparse.ArgumentParser(description="Manipulate shared library dependencies for macOS")
+
+ subcommands = p.add_subparsers(help="Subcommand", dest='command', metavar="COMMAND")
+ subcommands.required = True
+
+ change = subcommands.add_parser("change", help="Change a shared library dependency to a given value")
+ change.add_argument('-v', '--verbose', action='count', help="Verbose output")
+ change.add_argument('--tools', nargs=2, help="Paths to the install_name_tool and otool", default=("install_name_tool", "otool"))
+ change.add_argument('filename', metavar="FILE", help="Filename of the executable to manipulate")
+ change.add_argument('from_', metavar="FROM", help="Fuzzily matched library name to change")
+ change.add_argument('to', metavar="TO", help="Exact name that the library dependency should be changed to")
+ args = p.parse_args()
+
+ verbose = args.verbose or 0
+ install_name_tool, otool = args.tools
+ dylib = ChangeDylib(Config(install_name_tool, otool, verbose))
+ dylib.change(filename=args.filename, from_=args.from_, to=args.to)
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/dmg.py b/scripts/dmg.py
new file mode 100644
index 000000000..8f2d4cfc1
--- /dev/null
+++ b/scripts/dmg.py
@@ -0,0 +1,106 @@
+from collections import namedtuple
+import os
+import shlex
+import subprocess
+import tempfile
+
+ConfigDmgtools = namedtuple('Config', 'dmg hfsplus newfs_hfs verbose')
+ConfigHdiutil = namedtuple('Config', 'hdiutil verbose')
+
+def chunks(l, n):
+ """
+ Yield successive n-sized chunks from l.
+
+ From https://stackoverflow.com/a/312464.
+ """
+ for i in range(0, len(l), n):
+ yield l[i:i + n]
+
+class Dmg:
+ def __init__(self, config):
+ self.config = config
+
+ def _check_call(self, process_args, *args, **kwargs):
+ if self.config.verbose >= 1:
+ print("EXECUTING {}".format(" ".join(shlex.quote(x) for x in process_args)))
+ if not (self.config.verbose >= 2 and "stdout" not in kwargs):
+ kwargs["stdout"] = open(os.devnull, 'wb')
+ subprocess.check_call(process_args, *args, **kwargs)
+
+class Dmgtools(Dmg):
+ def _mkfs_hfs(self, *args):
+ self._check_call((self.config.newfs_hfs,) + args)
+ def _hfs(self, *args):
+ self._check_call((self.config.hfsplus,) + args)
+ def _dmg(self, *args):
+ self._check_call((self.config.dmg,) + args)
+
+ def _create_hfs(self, hfs, volume_name, size):
+ if self.config.verbose >= 1:
+ print("TRUNCATING {} to {} bytes".format(hfs, size))
+ with open(hfs, 'wb') as f:
+ f.truncate(size)
+ self._mkfs_hfs('-v', volume_name, hfs)
+
+ def _symlink(self, hfs, target, link_name):
+ self._hfs(hfs, 'symlink', link_name, target)
+
+ def _add(self, hfs, directory):
+ self._hfs(hfs, 'addall', directory)
+
+ def _finish(self, hfs, dmg):
+ self._dmg('build', hfs, dmg)
+
+ def create(self, dmg, volume_name, directory, symlinks):
+ input_size = sum(os.stat(os.path.join(path, f)).st_size for path, dirs, files in os.walk(directory) for f in files)
+ output_size = max(input_size * 2, 1024**2)
+ hfs = tempfile.mktemp(prefix=dmg + '.', suffix='.hfs')
+ self._create_hfs(hfs, volume_name, output_size)
+ self._add(hfs, directory)
+ for target, link_name in symlinks:
+ self._symlink(hfs, target, link_name)
+ self._finish(hfs, dmg)
+ if self.config.verbose >= 1:
+ print("REMOVING {}".format(hfs))
+ os.remove(hfs)
+
+class Hdiutil(Dmg):
+ def _hdiutil(self, *args):
+ self._check_call((self.config.hdiutil,) + args)
+
+ def create(self, dmg, volume_name, directory, symlinks):
+ if symlinks:
+ raise NotImplementedError("symlinks are not yet implemented")
+ self._hdiutil('create', '-volname', volume_name, '-srcdir', directory, dmg)
+
+def main():
+ import argparse
+ p = argparse.ArgumentParser(description="Manipulate dmg archives")
+
+ subcommands = p.add_subparsers(help="Subcommand", dest='command', metavar="COMMAND")
+ subcommands.required = True
+
+ create = subcommands.add_parser("create", help="Create a dmg archive from files or directories")
+ create.add_argument('-v', '--verbose', action='count', help="Verbose output")
+ createx = create.add_mutually_exclusive_group(required=True)
+ createx.add_argument('--dmgtools', nargs=3, help="Paths to the dmg and hfsplus executable (https://github.com/mozilla/libdmg-hfsplus) and the newfs_hfs executable (http://pkgs.fedoraproject.org/repo/pkgs/hfsplus-tools/diskdev_cmds-540.1.linux3.tar.gz/0435afc389b919027b69616ad1b05709/diskdev_cmds-540.1.linux3.tar.gz)")
+ createx.add_argument('--hdiutil', help="Path to the hdiutil (only exists for macOS at time of writing)")
+ create.add_argument('output', metavar="OUTPUT", help="Filename of the output dmg archive")
+ create.add_argument('volume_name', metavar="VOLUME_NAME", help="Name of the dmg archive")
+ create.add_argument('directory', metavar="DIR", help="Directory to create the archive from")
+ create.add_argument('--symlink', metavar="SYMLINK", nargs=2, action="append", help="Symlink the first argument under the second name")
+ args = p.parse_args()
+
+ verbose = args.verbose or 0
+ symlinks = args.symlink or []
+ if args.dmgtools:
+ dmg, hfsplus, newfs_hfs = args.dmgtools
+ dmg = Dmgtools(ConfigDmgtools(dmg=dmg, hfsplus=hfsplus, newfs_hfs=newfs_hfs, verbose=verbose))
+ elif args.hdiutil:
+ dmg = Hdiutil(ConfigHdiutil(hdiutil=args.hdiutil, verbose=verbose))
+ else:
+ raise RuntimeError("unreachable")
+ dmg.create(volume_name=args.volume_name, directory=args.directory, dmg=args.output, symlinks=symlinks)
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/git_revision.py b/scripts/git_revision.py
new file mode 100644
index 000000000..ae1186c42
--- /dev/null
+++ b/scripts/git_revision.py
@@ -0,0 +1,21 @@
+import errno
+import subprocess
+try:
+ from subprocess import DEVNULL
+except ImportError:
+ import os
+ DEVNULL = open(os.devnull, 'wb')
+try:
+ FileNotFoundError
+except NameError:
+ FileNotFoundError = OSError
+try:
+ git_hash = subprocess.check_output(["git", "rev-parse", "--short=16", "HEAD"], stderr=DEVNULL).decode().strip()
+ definition = '"{}"'.format(git_hash)
+except FileNotFoundError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ definition = "0"
+except subprocess.CalledProcessError:
+ definition = "0";
+print("const char *GIT_SHORTREV_HASH = {};".format(definition))
diff --git a/src/base/system.c b/src/base/system.c
index c5765e68a..a6d214717 100644
--- a/src/base/system.c
+++ b/src/base/system.c
@@ -303,6 +303,11 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size)
return fread(buffer, 1, size, (FILE*)io);
}
+unsigned io_unread_byte(IOHANDLE io, unsigned char byte)
+{
+ return ungetc(byte, (FILE*)io) == EOF;
+}
+
unsigned io_skip(IOHANDLE io, int size)
{
fseek((FILE*)io, size, SEEK_CUR);
diff --git a/src/base/system.h b/src/base/system.h
index fef36f0b6..c1178e7b0 100644
--- a/src/base/system.h
+++ b/src/base/system.h
@@ -220,6 +220,21 @@ IOHANDLE io_open(const char *filename, int flags);
unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
/*
+ Function: io_unread_byte
+ "Unreads" a single byte, making it available for future read
+ operations.
+
+ Parameters:
+ io - Handle to the file to unread the byte from.
+ byte - Byte to unread.
+
+ Returns:
+ Returns 0 on success and 1 on failure.
+
+*/
+unsigned io_unread_byte(IOHANDLE io, unsigned char byte);
+
+/*
Function: io_skip
Skips data in a file.
diff --git a/src/engine/client/sound.cpp b/src/engine/client/sound.cpp
index 4c64422e8..7f6275836 100644
--- a/src/engine/client/sound.cpp
+++ b/src/engine/client/sound.cpp
@@ -12,8 +12,9 @@
#include "sound.h"
-extern "C" { // wavpack
- #include <engine/external/wavpack/wavpack.h>
+extern "C"
+{
+ #include <wavpack.h>
}
#include <math.h>
@@ -67,6 +68,8 @@ static int m_NextVoice = 0;
static int *m_pMixBuffer = 0; // buffer only used by the thread callback function
static unsigned m_MaxFrames = 0;
+static IOHANDLE s_File;
+
// TODO: there should be a faster way todo this
static short Int2Short(int i)
{
@@ -328,11 +331,43 @@ void CSound::RateConvert(int SampleID)
pSample->m_NumFrames = NumFrames;
}
-int CSound::ReadData(void *pBuffer, int Size)
+static int ReadDataOld(void *pBuffer, int Size)
+{
+ return io_read(s_File, pBuffer, Size);
+}
+
+#if defined(CONF_WAVPACK_OPEN_FILE_INPUT_EX)
+static int ReadData(void *pId, void *pBuffer, int Size)
+{
+ (void)pId;
+ return ReadDataOld(pBuffer, Size);
+}
+
+static int ReturnFalse(void *pId)
+{
+ (void)pId;
+ return 0;
+}
+
+static unsigned int GetPos(void *pId)
+{
+ (void)pId;
+ return io_tell(s_File);
+}
+
+static unsigned int GetLength(void *pId)
{
- return io_read(ms_File, pBuffer, Size);
+ (void)pId;
+ return io_length(s_File);
}
+static int PushBackByte(void *pId, int Char)
+{
+ (void)pId;
+ return io_unread_byte(s_File, Char);
+}
+#endif
+
int CSound::LoadWV(const char *pFilename)
{
CSample *pSample;
@@ -351,8 +386,8 @@ int CSound::LoadWV(const char *pFilename)
if(!m_pStorage)
return -1;
- ms_File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
- if(!ms_File)
+ s_File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
+ if(!s_File)
{
dbg_msg("sound/wv", "failed to open file. filename='%s'", pFilename);
return -1;
@@ -363,7 +398,17 @@ int CSound::LoadWV(const char *pFilename)
return -1;
pSample = &m_aSamples[SampleID];
- pContext = WavpackOpenFileInput(ReadData, aError);
+#if defined(CONF_WAVPACK_OPEN_FILE_INPUT_EX)
+ WavpackStreamReader Callback = {0};
+ Callback.can_seek = ReturnFalse;
+ Callback.get_length = GetLength;
+ Callback.get_pos = GetPos;
+ Callback.push_back_byte = PushBackByte;
+ Callback.read_bytes = ReadData;
+ pContext = WavpackOpenFileInputEx(&Callback, (void *)1, 0, aError, 0, 0);
+#else
+ pContext = WavpackOpenFileInput(ReadDataOld, aError);
+#endif
if (pContext)
{
int m_aSamples = WavpackGetNumSamples(pContext);
@@ -419,8 +464,8 @@ int CSound::LoadWV(const char *pFilename)
dbg_msg("sound/wv", "failed to open %s: %s", pFilename, aError);
}
- io_close(ms_File);
- ms_File = NULL;
+ io_close(s_File);
+ s_File = NULL;
if(g_Config.m_Debug)
dbg_msg("sound/wv", "loaded %s", pFilename);
@@ -527,7 +572,4 @@ void CSound::StopAll()
lock_unlock(m_SoundLock);
}
-IOHANDLE CSound::ms_File = 0;
-
IEngineSound *CreateEngineSound() { return new CSound; }
-
diff --git a/src/engine/client/sound.h b/src/engine/client/sound.h
index 8112427c3..576f6497b 100644
--- a/src/engine/client/sound.h
+++ b/src/engine/client/sound.h
@@ -21,10 +21,6 @@ public:
static void RateConvert(int SampleID);
- // TODO: Refactor: clean this mess up
- static IOHANDLE ms_File;
- static int ReadData(void *pBuffer, int Size);
-
virtual bool IsSoundEnabled() { return m_SoundEnabled != 0; }
virtual int LoadWV(const char *pFilename);
diff --git a/src/game/version.h b/src/game/version.h
index 17010c1b0..bc174a24d 100644
--- a/src/game/version.h
+++ b/src/game/version.h
@@ -2,8 +2,8 @@
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef GAME_VERSION_H
#define GAME_VERSION_H
-#include "generated/nethash.cpp"
+#include <game/generated/nethash.cpp>
#define GAME_VERSION "0.6.5"
#define GAME_NETVERSION "0.6 " GAME_NETVERSION_HASH
-static const char GAME_RELEASE_VERSION[8] = {'0', '.', '6', '.', '5', 0};
+static const char GAME_RELEASE_VERSION[8] = "0.6.5";
#endif
diff --git a/src/osxlaunch/client.m b/src/osxlaunch/client.m
index 6de919e2a..c224081fa 100644..120000
--- a/src/osxlaunch/client.m
+++ b/src/osxlaunch/client.m
@@ -1,373 +1 @@
-/* SDLMain.m - main entry point for our Cocoa-ized SDL app
- Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
- Non-NIB-Code & other changes: Max Horn <max@quendi.de>
-
- Feel free to customize this file to suit your needs
-*/
-
-#import <SDL.h>
-#import "client.h"
-#import <sys/param.h> /* for MAXPATHLEN */
-#import <unistd.h>
-
-/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
- but the method still is there and works. To avoid warnings, we declare
- it ourselves here. */
-@interface NSApplication(SDL_Missing_Methods)
-- (void)setAppleMenu:(NSMenu *)menu;
-@end
-
-/* Use this flag to determine whether we use SDLMain.nib or not */
-#define SDL_USE_NIB_FILE 0
-
-/* Use this flag to determine whether we use CPS (docking) or not */
-#define SDL_USE_CPS 1
-#ifdef SDL_USE_CPS
-/* Portions of CPS.h */
-typedef struct CPSProcessSerNum
-{
- UInt32 lo;
- UInt32 hi;
-} CPSProcessSerNum;
-
-extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
-extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
-
-#endif /* SDL_USE_CPS */
-
-static int gArgc;
-static char **gArgv;
-static BOOL gFinderLaunch;
-static BOOL gCalledAppMainline = FALSE;
-
-static NSString *getApplicationName(void)
-{
- NSDictionary *dict;
- NSString *appName = 0;
-
- /* Determine the application name */
- dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
- if (dict)
- appName = [dict objectForKey: @"CFBundleName"];
-
- if (![appName length])
- appName = [[NSProcessInfo processInfo] processName];
-
- return appName;
-}
-
-#if SDL_USE_NIB_FILE
-/* A helper category for NSString */
-@interface NSString (ReplaceSubString)
-- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
-@end
-#endif
-
-@interface SDLApplication : NSApplication
-@end
-
-@implementation SDLApplication
-/* Invoked from the Quit menu item */
-- (void)terminate:(id)sender
-{
- /* Post a SDL_QUIT event */
- SDL_Event event;
- event.type = SDL_QUIT;
- SDL_PushEvent(&event);
-}
-@end
-
-/* The main class of the application, the application's delegate */
-@implementation SDLMain
-
-/* Set the working directory to the .app's parent directory */
-- (void) setupWorkingDirectory:(BOOL)shouldChdir
-{
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- [[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcePath];
-}
-
-#if SDL_USE_NIB_FILE
-
-/* Fix menu to contain the real app name instead of "SDL App" */
-- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
-{
- NSRange aRange;
- NSEnumerator *enumerator;
- NSMenuItem *menuItem;
-
- aRange = [[aMenu title] rangeOfString:@"SDL App"];
- if (aRange.length != 0)
- [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
-
- enumerator = [[aMenu itemArray] objectEnumerator];
- while ((menuItem = [enumerator nextObject]))
- {
- aRange = [[menuItem title] rangeOfString:@"SDL App"];
- if (aRange.length != 0)
- [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
- if ([menuItem hasSubmenu])
- [self fixMenu:[menuItem submenu] withAppName:appName];
- }
- [ aMenu sizeToFit ];
-}
-
-#else
-
-static void setApplicationMenu(void)
-{
- /* warning: this code is very odd */
- NSMenu *appleMenu;
- NSMenuItem *menuItem;
- NSString *title;
- NSString *appName;
-
- appName = getApplicationName();
- appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
- /* Add menu items */
- title = [@"About " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Hide " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
-
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
-
- [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Quit " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
-
- /* Put menu into the menubar */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:appleMenu];
- [[NSApp mainMenu] addItem:menuItem];
-
- /* Tell the application object that this is now the application menu */
- [NSApp setAppleMenu:appleMenu];
-
- /* Finally give up our references to the objects */
- [appleMenu release];
- [menuItem release];
-}
-
-/* Create a window menu */
-static void setupWindowMenu(void)
-{
- NSMenu *windowMenu;
- NSMenuItem *windowMenuItem;
- NSMenuItem *menuItem;
-
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- /* "Minimize" item */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
- [windowMenu addItem:menuItem];
- [menuItem release];
-
- /* Put menu into the menubar */
- windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
- [windowMenuItem setSubmenu:windowMenu];
- [[NSApp mainMenu] addItem:windowMenuItem];
-
- /* Tell the application object that this is now the window menu */
- [NSApp setWindowsMenu:windowMenu];
-
- /* Finally give up our references to the objects */
- [windowMenu release];
- [windowMenuItem release];
-}
-
-/* Replacement for NSApplicationMain */
-static void CustomApplicationMain (int argc, char **argv)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- SDLMain *sdlMain;
-
- /* Ensure the application object is initialised */
- [SDLApplication sharedApplication];
-
-#ifdef SDL_USE_CPS
- {
- CPSProcessSerNum PSN;
- /* Tell the dock about us */
- if (!CPSGetCurrentProcess(&PSN))
- if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
- if (!CPSSetFrontProcess(&PSN))
- [SDLApplication sharedApplication];
- }
-#endif /* SDL_USE_CPS */
-
- /* Set up the menubar */
- [NSApp setMainMenu:[[NSMenu alloc] init]];
- setApplicationMenu();
- setupWindowMenu();
-
- /* Create SDLMain and make it the app delegate */
- sdlMain = [[SDLMain alloc] init];
- [NSApp setDelegate:sdlMain];
-
- /* Start the main event loop */
- [NSApp run];
-
- [sdlMain release];
- [pool release];
-}
-
-#endif
-
-
-/*
- * Catch document open requests...this lets us notice files when the app
- * was launched by double-clicking a document, or when a document was
- * dragged/dropped on the app's icon. You need to have a
- * CFBundleDocumentsType section in your Info.plist to get this message,
- * apparently.
- *
- * Files are added to gArgv, so to the app, they'll look like command line
- * arguments. Previously, apps launched from the finder had nothing but
- * an argv[0].
- *
- * This message may be received multiple times to open several docs on launch.
- *
- * This message is ignored once the app's mainline has been called.
- */
-- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
-{
- const char *temparg;
- size_t arglen;
- char *arg;
- char **newargv;
-
- if (!gFinderLaunch) /* MacOS is passing command line args. */
- return FALSE;
-
- if (gCalledAppMainline) /* app has started, ignore this document. */
- return FALSE;
-
- temparg = [filename UTF8String];
- arglen = SDL_strlen(temparg) + 1;
- arg = (char *) SDL_malloc(arglen);
- if (arg == NULL)
- return FALSE;
-
- newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
- if (newargv == NULL)
- {
- SDL_free(arg);
- return FALSE;
- }
- gArgv = newargv;
-
- SDL_strlcpy(arg, temparg, arglen);
- gArgv[gArgc++] = arg;
- gArgv[gArgc] = NULL;
- return TRUE;
-}
-
-
-/* Called when the internal event loop has just started running */
-- (void) applicationDidFinishLaunching: (NSNotification *) note
-{
- int status;
-
- /* Set the working directory to the .app's parent directory */
- [self setupWorkingDirectory:gFinderLaunch];
-
-#if SDL_USE_NIB_FILE
- /* Set the main menu to contain the real app name instead of "SDL App" */
- [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
-#endif
-
- /* Hand off to main application code */
- gCalledAppMainline = TRUE;
- status = SDL_main (gArgc, gArgv);
-
- /* We're done, thank you for playing */
- exit(status);
-}
-@end
-
-
-@implementation NSString (ReplaceSubString)
-
-- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
-{
- unsigned int bufferSize;
- unsigned int selfLen = [self length];
- unsigned int aStringLen = [aString length];
- unichar *buffer;
- NSRange localRange;
- NSString *result;
-
- bufferSize = selfLen + aStringLen - aRange.length;
- buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
-
- /* Get first part into buffer */
- localRange.location = 0;
- localRange.length = aRange.location;
- [self getCharacters:buffer range:localRange];
-
- /* Get middle part into buffer */
- localRange.location = 0;
- localRange.length = aStringLen;
- [aString getCharacters:(buffer+aRange.location) range:localRange];
-
- /* Get last part into buffer */
- localRange.location = aRange.location + aRange.length;
- localRange.length = selfLen - localRange.location;
- [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
-
- /* Build output string */
- result = [NSString stringWithCharacters:buffer length:bufferSize];
-
- NSDeallocateMemoryPages(buffer, bufferSize);
-
- return result;
-}
-
-@end
-
-#ifdef main
-#undef main
-#endif
-
-
-/* Main entry point to executable - should *not* be SDL_main! */
-int main (int argc, char **argv)
-{
- /* Copy the arguments into a global variable */
- /* This is passed if we are launched by double-clicking */
- if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
- gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
- gArgv[0] = argv[0];
- gArgv[1] = NULL;
- gArgc = 1;
- gFinderLaunch = YES;
- } else {
- int i;
- gArgc = argc;
- gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
- for (i = 0; i <= argc; i++)
- gArgv[i] = argv[i];
- gFinderLaunch = NO;
- }
-
-#if SDL_USE_NIB_FILE
- [SDLApplication poseAsClass:[NSApplication class]];
- NSApplicationMain (argc, argv);
-#else
- CustomApplicationMain (argc, argv);
-#endif
-
- return 0;
-}
-
+client.mm \ No newline at end of file
diff --git a/src/osxlaunch/client.mm b/src/osxlaunch/client.mm
new file mode 100644
index 000000000..6de919e2a
--- /dev/null
+++ b/src/osxlaunch/client.mm
@@ -0,0 +1,373 @@
+/* SDLMain.m - main entry point for our Cocoa-ized SDL app
+ Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+ Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+ Feel free to customize this file to suit your needs
+*/
+
+#import <SDL.h>
+#import "client.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
+ but the method still is there and works. To avoid warnings, we declare
+ it ourselves here. */
+@interface NSApplication(SDL_Missing_Methods)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+
+/* Use this flag to determine whether we use SDLMain.nib or not */
+#define SDL_USE_NIB_FILE 0
+
+/* Use this flag to determine whether we use CPS (docking) or not */
+#define SDL_USE_CPS 1
+#ifdef SDL_USE_CPS
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+{
+ UInt32 lo;
+ UInt32 hi;
+} CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+#endif /* SDL_USE_CPS */
+
+static int gArgc;
+static char **gArgv;
+static BOOL gFinderLaunch;
+static BOOL gCalledAppMainline = FALSE;
+
+static NSString *getApplicationName(void)
+{
+ NSDictionary *dict;
+ NSString *appName = 0;
+
+ /* Determine the application name */
+ dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
+ if (dict)
+ appName = [dict objectForKey: @"CFBundleName"];
+
+ if (![appName length])
+ appName = [[NSProcessInfo processInfo] processName];
+
+ return appName;
+}
+
+#if SDL_USE_NIB_FILE
+/* A helper category for NSString */
+@interface NSString (ReplaceSubString)
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
+@end
+#endif
+
+@interface SDLApplication : NSApplication
+@end
+
+@implementation SDLApplication
+/* Invoked from the Quit menu item */
+- (void)terminate:(id)sender
+{
+ /* Post a SDL_QUIT event */
+ SDL_Event event;
+ event.type = SDL_QUIT;
+ SDL_PushEvent(&event);
+}
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+ NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
+ [[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcePath];
+}
+
+#if SDL_USE_NIB_FILE
+
+/* Fix menu to contain the real app name instead of "SDL App" */
+- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
+{
+ NSRange aRange;
+ NSEnumerator *enumerator;
+ NSMenuItem *menuItem;
+
+ aRange = [[aMenu title] rangeOfString:@"SDL App"];
+ if (aRange.length != 0)
+ [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
+
+ enumerator = [[aMenu itemArray] objectEnumerator];
+ while ((menuItem = [enumerator nextObject]))
+ {
+ aRange = [[menuItem title] rangeOfString:@"SDL App"];
+ if (aRange.length != 0)
+ [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
+ if ([menuItem hasSubmenu])
+ [self fixMenu:[menuItem submenu] withAppName:appName];
+ }
+ [ aMenu sizeToFit ];
+}
+
+#else
+
+static void setApplicationMenu(void)
+{
+ /* warning: this code is very odd */
+ NSMenu *appleMenu;
+ NSMenuItem *menuItem;
+ NSString *title;
+ NSString *appName;
+
+ appName = getApplicationName();
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
+
+ /* Add menu items */
+ title = [@"About " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Hide " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+
+ [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Quit " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+
+ /* Finally give up our references to the objects */
+ [appleMenu release];
+ [menuItem release];
+}
+
+/* Create a window menu */
+static void setupWindowMenu(void)
+{
+ NSMenu *windowMenu;
+ NSMenuItem *windowMenuItem;
+ NSMenuItem *menuItem;
+
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ /* "Minimize" item */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ [windowMenu addItem:menuItem];
+ [menuItem release];
+
+ /* Put menu into the menubar */
+ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+ [windowMenuItem setSubmenu:windowMenu];
+ [[NSApp mainMenu] addItem:windowMenuItem];
+
+ /* Tell the application object that this is now the window menu */
+ [NSApp setWindowsMenu:windowMenu];
+
+ /* Finally give up our references to the objects */
+ [windowMenu release];
+ [windowMenuItem release];
+}
+
+/* Replacement for NSApplicationMain */
+static void CustomApplicationMain (int argc, char **argv)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ SDLMain *sdlMain;
+
+ /* Ensure the application object is initialised */
+ [SDLApplication sharedApplication];
+
+#ifdef SDL_USE_CPS
+ {
+ CPSProcessSerNum PSN;
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN))
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [SDLApplication sharedApplication];
+ }
+#endif /* SDL_USE_CPS */
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+ setApplicationMenu();
+ setupWindowMenu();
+
+ /* Create SDLMain and make it the app delegate */
+ sdlMain = [[SDLMain alloc] init];
+ [NSApp setDelegate:sdlMain];
+
+ /* Start the main event loop */
+ [NSApp run];
+
+ [sdlMain release];
+ [pool release];
+}
+
+#endif
+
+
+/*
+ * Catch document open requests...this lets us notice files when the app
+ * was launched by double-clicking a document, or when a document was
+ * dragged/dropped on the app's icon. You need to have a
+ * CFBundleDocumentsType section in your Info.plist to get this message,
+ * apparently.
+ *
+ * Files are added to gArgv, so to the app, they'll look like command line
+ * arguments. Previously, apps launched from the finder had nothing but
+ * an argv[0].
+ *
+ * This message may be received multiple times to open several docs on launch.
+ *
+ * This message is ignored once the app's mainline has been called.
+ */
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ const char *temparg;
+ size_t arglen;
+ char *arg;
+ char **newargv;
+
+ if (!gFinderLaunch) /* MacOS is passing command line args. */
+ return FALSE;
+
+ if (gCalledAppMainline) /* app has started, ignore this document. */
+ return FALSE;
+
+ temparg = [filename UTF8String];
+ arglen = SDL_strlen(temparg) + 1;
+ arg = (char *) SDL_malloc(arglen);
+ if (arg == NULL)
+ return FALSE;
+
+ newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
+ if (newargv == NULL)
+ {
+ SDL_free(arg);
+ return FALSE;
+ }
+ gArgv = newargv;
+
+ SDL_strlcpy(arg, temparg, arglen);
+ gArgv[gArgc++] = arg;
+ gArgv[gArgc] = NULL;
+ return TRUE;
+}
+
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+ int status;
+
+ /* Set the working directory to the .app's parent directory */
+ [self setupWorkingDirectory:gFinderLaunch];
+
+#if SDL_USE_NIB_FILE
+ /* Set the main menu to contain the real app name instead of "SDL App" */
+ [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
+#endif
+
+ /* Hand off to main application code */
+ gCalledAppMainline = TRUE;
+ status = SDL_main (gArgc, gArgv);
+
+ /* We're done, thank you for playing */
+ exit(status);
+}
+@end
+
+
+@implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+ unsigned int bufferSize;
+ unsigned int selfLen = [self length];
+ unsigned int aStringLen = [aString length];
+ unichar *buffer;
+ NSRange localRange;
+ NSString *result;
+
+ bufferSize = selfLen + aStringLen - aRange.length;
+ buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+
+ /* Get first part into buffer */
+ localRange.location = 0;
+ localRange.length = aRange.location;
+ [self getCharacters:buffer range:localRange];
+
+ /* Get middle part into buffer */
+ localRange.location = 0;
+ localRange.length = aStringLen;
+ [aString getCharacters:(buffer+aRange.location) range:localRange];
+
+ /* Get last part into buffer */
+ localRange.location = aRange.location + aRange.length;
+ localRange.length = selfLen - localRange.location;
+ [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+
+ /* Build output string */
+ result = [NSString stringWithCharacters:buffer length:bufferSize];
+
+ NSDeallocateMemoryPages(buffer, bufferSize);
+
+ return result;
+}
+
+@end
+
+#ifdef main
+#undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+ /* Copy the arguments into a global variable */
+ /* This is passed if we are launched by double-clicking */
+ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+ gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
+ gArgv[0] = argv[0];
+ gArgv[1] = NULL;
+ gArgc = 1;
+ gFinderLaunch = YES;
+ } else {
+ int i;
+ gArgc = argc;
+ gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
+ for (i = 0; i <= argc; i++)
+ gArgv[i] = argv[i];
+ gFinderLaunch = NO;
+ }
+
+#if SDL_USE_NIB_FILE
+ [SDLApplication poseAsClass:[NSApplication class]];
+ NSApplicationMain (argc, argv);
+#else
+ CustomApplicationMain (argc, argv);
+#endif
+
+ return 0;
+}
+
diff --git a/src/osxlaunch/server.m b/src/osxlaunch/server.m
index 5ae32c6fa..9ff19d9b5 100644..120000
--- a/src/osxlaunch/server.m
+++ b/src/osxlaunch/server.m
@@ -1,112 +1 @@
-#import <Cocoa/Cocoa.h>
-
-@interface ServerView : NSTextView
-{
- NSTask *task;
- NSFileHandle *file;
-}
-- (void)listenTo: (NSTask*)t;
-@end
-
-@implementation ServerView
-- (void)listenTo: (NSTask*)t;
-{
- NSPipe *pipe;
- task = t;
- pipe = [NSPipe pipe];
- [task setStandardOutput: pipe];
- file = [pipe fileHandleForReading];
-
- [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(outputNotification:) name: NSFileHandleReadCompletionNotification object: file];
-
- [file readInBackgroundAndNotify];
-}
-
-- (void) outputNotification: (NSNotification *) notification
-{
- NSData *data = [[[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] retain];
- NSString *string = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
- NSAttributedString *attrstr = [[NSAttributedString alloc] initWithString: string];
-
- [[self textStorage] appendAttributedString: attrstr];
- int length = [[self textStorage] length];
- NSRange range = NSMakeRange(length, 0);
- [self scrollRangeToVisible: range];
-
- [attrstr release];
- [string release];
- [file readInBackgroundAndNotify];
-}
-
--(void)windowWillClose:(NSNotification *)notification
-{
- [task terminate];
- [NSApp terminate:self];
-}
-@end
-
-void runServer()
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSApp = [NSApplication sharedApplication];
- NSBundle* mainBundle = [NSBundle mainBundle];
- NSTask *task;
- task = [[NSTask alloc] init];
- [task setCurrentDirectoryPath: [mainBundle resourcePath]];
-
- // get a server config
- NSOpenPanel* openDlg = [NSOpenPanel openPanel];
- [openDlg setCanChooseFiles:YES];
-
- if([openDlg runModalForDirectory:nil file:nil] != NSOKButton)
- return;
-
- NSArray* filenames = [openDlg filenames];
- if([filenames count] != 1)
- return;
-
- NSString* filename = [filenames objectAtIndex: 0];
- NSArray* arguments = [NSArray arrayWithObjects: @"-f", filename, nil];
-
- // run server
- NSWindow *window;
- ServerView *view;
- NSRect graphicsRect;
-
- graphicsRect = NSMakeRect(100.0, 1000.0, 600.0, 400.0);
-
- window = [[NSWindow alloc]
- initWithContentRect: graphicsRect
- styleMask: NSTitledWindowMask
- | NSClosableWindowMask
- | NSMiniaturizableWindowMask
- backing: NSBackingStoreBuffered
- defer: NO];
-
- [window setTitle: @"Teeworlds Server"];
-
- view = [[[ServerView alloc] initWithFrame: graphicsRect] autorelease];
- [view setEditable: NO];
- [view setRulerVisible: YES];
-
- [window setContentView: view];
- [window setDelegate: view];
- [window makeKeyAndOrderFront: nil];
-
- [view listenTo: task];
- [task setLaunchPath: [mainBundle pathForAuxiliaryExecutable: @"teeworlds_srv"]];
- [task setArguments: arguments];
- [task launch];
- [NSApp run];
- [task terminate];
-
- [NSApp release];
- [pool release];
-}
-
-int main (int argc, char **argv)
-{
- runServer();
-
- return 0;
-}
+server.mm \ No newline at end of file
diff --git a/src/osxlaunch/server.mm b/src/osxlaunch/server.mm
new file mode 100644
index 000000000..5ad2d4eda
--- /dev/null
+++ b/src/osxlaunch/server.mm
@@ -0,0 +1,112 @@
+#import <Cocoa/Cocoa.h>
+
+@interface ServerView : NSTextView
+{
+ NSTask *task;
+ NSFileHandle *file;
+}
+- (void)listenTo: (NSTask*)t;
+@end
+
+@implementation ServerView
+- (void)listenTo: (NSTask*)t;
+{
+ NSPipe *pipe;
+ task = t;
+ pipe = [NSPipe pipe];
+ [task setStandardOutput: pipe];
+ file = [pipe fileHandleForReading];
+
+ [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(outputNotification:) name: NSFileHandleReadCompletionNotification object: file];
+
+ [file readInBackgroundAndNotify];
+}
+
+- (void) outputNotification: (NSNotification *) notification
+{
+ NSData *data = [[[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] retain];
+ NSString *string = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
+ NSAttributedString *attrstr = [[NSAttributedString alloc] initWithString: string];
+
+ [[self textStorage] appendAttributedString: attrstr];
+ int length = [[self textStorage] length];
+ NSRange range = NSMakeRange(length, 0);
+ [self scrollRangeToVisible: range];
+
+ [attrstr release];
+ [string release];
+ [file readInBackgroundAndNotify];
+}
+
+-(void)windowWillClose:(NSNotification *)notification
+{
+ [task terminate];
+ [NSApp terminate:self];
+}
+@end
+
+void runServer()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSApp = [NSApplication sharedApplication];
+ NSBundle* mainBundle = [NSBundle mainBundle];
+ NSTask *task;
+ task = [[NSTask alloc] init];
+ [task setCurrentDirectoryPath: [mainBundle resourcePath]];
+
+ // get a server config
+ NSOpenPanel* openDlg = [NSOpenPanel openPanel];
+ [openDlg setCanChooseFiles:YES];
+
+ if([openDlg runModalForDirectory:nil file:nil] != NSOKButton)
+ return;
+
+ NSArray* filenames = [openDlg filenames];
+ if([filenames count] != 1)
+ return;
+
+ NSString* filename = [filenames objectAtIndex: 0];
+ NSArray* arguments = [NSArray arrayWithObjects: @"-f", filename, nil];
+
+ // run server
+ NSWindow *window;
+ ServerView *view;
+ NSRect graphicsRect;
+
+ graphicsRect = NSMakeRect(100.0, 1000.0, 600.0, 400.0);
+
+ window = [[NSWindow alloc]
+ initWithContentRect: graphicsRect
+ styleMask: NSTitledWindowMask
+ | NSClosableWindowMask
+ | NSMiniaturizableWindowMask
+ backing: NSBackingStoreBuffered
+ defer: NO];
+
+ [window setTitle: @"Teeworlds Server"];
+
+ view = [[[ServerView alloc] initWithFrame: graphicsRect] autorelease];
+ [view setEditable: NO];
+ [view setRulerVisible: YES];
+
+ [window setContentView: view];
+ [window setDelegate: (id<NSWindowDelegate>)view];
+ [window makeKeyAndOrderFront: nil];
+
+ [view listenTo: task];
+ [task setLaunchPath: [mainBundle pathForAuxiliaryExecutable: @"teeworlds_srv"]];
+ [task setArguments: arguments];
+ [task launch];
+ [NSApp run];
+ [task terminate];
+
+ [NSApp release];
+ [pool release];
+}
+
+int main (int argc, char **argv)
+{
+ runServer();
+
+ return 0;
+}