Merge pull request #1730 from heinrich5991/pr_cmake

Add CMake (and a couple of other fixes)
This commit is contained in:
oy 2019-01-02 19:46:46 +01:00 committed by GitHub
commit f776972a6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 2587 additions and 56 deletions

43
.gitignore vendored
View file

@ -1,10 +1,15 @@
/bam
/.bam /.bam
/config.lua /bam
/build /build
/other/*/lib /config.lua
/objs
/other/*/include /other/*/include
/other/*/lib
/other/*/linux
/other/*/mac
/other/*/windows
__pycache__/ __pycache__/
*.dll
*.pyc *.pyc
*.pyo *.pyo
scripts/work/ scripts/work/
@ -14,3 +19,35 @@ scripts/work/
other/freetype other/freetype
other/sdl other/sdl
_test.exe _test.exe
Info.plist
crapnet*
fake_server*
map_resave*
map_version*
mastersrv*
packetgen*
teeworlds*
teeworlds_srv*
versionsrv*
# CMake
data
generated
.ninja_deps
.ninja_log
CMakeCache.txt
CMakeFiles
CMakeSettings*
CPackConfig.cmake
CPackSourceConfig.cmake
Debug
Makefile
Release
_CPack_Packages/
build.ninja
cmake_install.cmake
install_manifest.txt
pack_*/
rules.ninja

1824
CMakeLists.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -420,6 +420,8 @@ function GenerateSettings(conf, arch, builddir, compiler)
end end
settings.cc.includes:Add("src") settings.cc.includes:Add("src")
settings.cc.includes:Add("src/engine/external/pnglite")
settings.cc.includes:Add("src/engine/external/wavpack")
settings.cc.includes:Add(generated_src_dir) settings.cc.includes:Add(generated_src_dir)
if family == "windows" then if family == "windows" then

37
cmake/FindFreetype.cmake Normal file
View file

@ -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()

46
cmake/FindPnglite.cmake Normal file
View file

@ -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_src(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()

48
cmake/FindSDL2.cmake Normal file
View file

@ -0,0 +1,48 @@
if(NOT PREFER_BUNDLED_LIBS)
set(CMAKE_MODULE_PATH ${ORIGINAL_CMAKE_MODULE_PATH})
find_package(SDL2)
set(CMAKE_MODULE_PATH ${OWN_CMAKE_MODULE_PATH})
if(SDL2_FOUND)
set(SDL2_BUNDLED OFF)
set(SDL2_DEP)
endif()
endif()
if(NOT CMAKE_CROSSCOMPILING)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_SDL2 sdl2)
endif()
set_extra_dirs_lib(SDL2 sdl)
find_library(SDL2_LIBRARY
NAMES SDL2
HINTS ${HINTS_SDL2_LIBDIR} ${PC_SDL2_LIBDIR} ${PC_SDL2_LIBRARY_DIRS}
PATHS ${PATHS_SDL2_LIBDIR}
${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
)
set(CMAKE_FIND_FRAMEWORK FIRST)
set_extra_dirs_include(SDL2 sdl "${SDL2_LIBRARY}")
# Looking for 'SDL.h' directly might accidentally find a SDL 1 instead of SDL 2
# installation. Look for a header file only present in SDL 2 instead.
find_path(SDL2_INCLUDEDIR SDL_assert.h
PATH_SUFFIXES SDL
HINTS ${HINTS_SDL2_INCLUDEDIR} ${PC_SDL2_INCLUDEDIR} ${PC_SDL2_INCLUDE_DIRS}
PATHS ${PATHS_SDL2_INCLUDEDIR}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL2 DEFAULT_MSG SDL2_LIBRARY SDL2_INCLUDEDIR)
mark_as_advanced(SDL2_LIBRARY SDL2_INCLUDEDIR)
if(SDL2_FOUND)
set(SDL2_LIBRARIES ${SDL2_LIBRARY})
set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDEDIR})
is_bundled(SDL2_BUNDLED "${SDL2_LIBRARY}")
if(SDL2_BUNDLED AND TARGET_OS STREQUAL "windows")
set(SDL2_COPY_FILES "${EXTRA_SDL2_LIBDIR}/SDL2.dll")
else()
set(SDL2_COPY_FILES)
endif()
endif()

52
cmake/FindWavpack.cmake Normal file
View file

@ -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_src(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()

50
cmake/FindZLIB.cmake Normal file
View file

@ -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_src(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()

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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>com.teeworlds.app</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

View file

@ -0,0 +1 @@
APPL????

View file

@ -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>

View file

@ -0,0 +1 @@
APPL????

View file

@ -36,9 +36,9 @@ FreeType = {
elseif option.use_winlib > 0 then elseif option.use_winlib > 0 then
settings.cc.includes:Add(FreeType.basepath .. "/include") settings.cc.includes:Add(FreeType.basepath .. "/include")
if option.use_winlib == 32 then if option.use_winlib == 32 then
settings.link.libpath:Add(FreeType.basepath .. "/lib/x86") settings.link.libpath:Add(FreeType.basepath .. "/windows/lib32")
else else
settings.link.libpath:Add(FreeType.basepath .. "/lib/x64") settings.link.libpath:Add(FreeType.basepath .. "/windows/lib64")
end end
settings.link.libs:Add("freetype") settings.link.libs:Add("freetype")
end end

View file

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

1
other/icons/teeworlds.rc Normal file
View file

@ -0,0 +1 @@
ID ICON "teeworlds.ico"

View file

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View file

@ -0,0 +1 @@
ID ICON "teeworlds_srv.ico"

View file

@ -1 +1 @@
50h ICON "Teeworlds_srv.ico" 50h ICON "teeworlds_srv.ico"

View file

@ -1 +1 @@
ID ICON "Teeworlds_srv.ico" ID ICON "teeworlds_srv.ico"

View file

@ -36,9 +36,9 @@ SDL = {
elseif option.use_winlib > 0 then elseif option.use_winlib > 0 then
settings.cc.includes:Add(SDL.basepath .. "/include") settings.cc.includes:Add(SDL.basepath .. "/include")
if option.use_winlib == 32 then if option.use_winlib == 32 then
settings.link.libpath:Add(SDL.basepath .. "/lib/x86") settings.link.libpath:Add(SDL.basepath .. "/windows/lib32")
else else
settings.link.libpath:Add(SDL.basepath .. "/lib/x64") settings.link.libpath:Add(SDL.basepath .. "/windows/lib64")
end end
settings.link.libs:Add("SDL2") settings.link.libs:Add("SDL2")
settings.link.libs:Add("SDL2main") settings.link.libs:Add("SDL2main")

View file

@ -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()

108
scripts/dmg.py Normal file
View file

@ -0,0 +1,108 @@
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")
if os.path.exists(volume_name + '.dmg'):
os.remove(volume_name + '.dmg')
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()

21
scripts/git_revision.py Normal file
View file

@ -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))

View file

@ -334,6 +334,11 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size)
return fread(buffer, 1, size, (FILE*)io); 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) unsigned io_skip(IOHANDLE io, int size)
{ {
fseek((FILE*)io, size, SEEK_CUR); fseek((FILE*)io, size, SEEK_CUR);
@ -1439,6 +1444,10 @@ int fs_storage_path(const char *appname, char *path, int max)
return 0; return 0;
#else #else
char *home = getenv("HOME"); char *home = getenv("HOME");
int i;
char *xdgdatahome = getenv("XDG_DATA_HOME");
char xdgpath[max];
if(!home) if(!home)
return -1; return -1;
@ -1447,10 +1456,6 @@ int fs_storage_path(const char *appname, char *path, int max)
return 0; return 0;
#endif #endif
int i;
char *xdgdatahome = getenv("XDG_DATA_HOME");
char xdgpath[max];
/* old folder location */ /* old folder location */
snprintf(path, max, "%s/.%s", home, appname); snprintf(path, max, "%s/.%s", home, appname);
for(i = strlen(home)+2; path[i]; i++) for(i = strlen(home)+2; path[i]; i++)

View file

@ -212,6 +212,21 @@ IOHANDLE io_open(const char *filename, int flags);
*/ */
unsigned io_read(IOHANDLE io, void *buffer, unsigned size); 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 Function: io_skip
Skips data in a file. Skips data in a file.

View file

@ -138,11 +138,6 @@ public:
end = 0x0; end = 0x0;
} }
plain_range(const plain_range &r)
{
*this = r;
}
plain_range(T *b, T *e) plain_range(T *b, T *e)
{ {
begin = b; begin = b;
@ -184,11 +179,6 @@ public:
plain_range_sorted() plain_range_sorted()
{} {}
plain_range_sorted(const plain_range_sorted &r)
{
*this = r;
}
plain_range_sorted(T *b, T *e) plain_range_sorted(T *b, T *e)
: parent(b, e) : parent(b, e)
{} {}

View file

@ -6,7 +6,8 @@
#include <base/tl/threading.h> #include <base/tl/threading.h>
#include <base/system.h> #include <base/system.h>
#include <engine/external/pnglite/pnglite.h>
#include <pnglite.h>
#include <engine/shared/config.h> #include <engine/shared/config.h>
#include <engine/graphics.h> #include <engine/graphics.h>

View file

@ -12,8 +12,9 @@
#include "sound.h" #include "sound.h"
extern "C" { // wavpack extern "C"
#include <engine/external/wavpack/wavpack.h> {
#include <wavpack.h>
} }
#include <math.h> #include <math.h>
@ -68,6 +69,8 @@ static int m_NextVoice = 0;
static int *m_pMixBuffer = 0; // buffer only used by the thread callback function static int *m_pMixBuffer = 0; // buffer only used by the thread callback function
static unsigned m_MaxFrames = 0; static unsigned m_MaxFrames = 0;
static IOHANDLE s_File;
// TODO: there should be a faster way todo this // TODO: there should be a faster way todo this
static short Int2Short(int i) static short Int2Short(int i)
{ {
@ -327,11 +330,43 @@ void CSound::RateConvert(int SampleID)
pSample->m_NumFrames = NumFrames; pSample->m_NumFrames = NumFrames;
} }
int CSound::ReadData(void *pBuffer, int Size) static int ReadDataOld(void *pBuffer, int Size)
{ {
return io_read(ms_File, pBuffer, 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)
{
(void)pId;
return io_length(s_File);
}
static int PushBackByte(void *pId, int Char)
{
(void)pId;
return io_unread_byte(s_File, Char);
}
#endif
ISound::CSampleHandle CSound::LoadWV(const char *pFilename) ISound::CSampleHandle CSound::LoadWV(const char *pFilename)
{ {
CSample *pSample; CSample *pSample;
@ -351,8 +386,8 @@ ISound::CSampleHandle CSound::LoadWV(const char *pFilename)
return CSampleHandle(); return CSampleHandle();
lock_wait(m_SoundLock); lock_wait(m_SoundLock);
ms_File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL); s_File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
if(!ms_File) if(!s_File)
{ {
dbg_msg("sound/wv", "failed to open file. filename='%s'", pFilename); dbg_msg("sound/wv", "failed to open file. filename='%s'", pFilename);
lock_unlock(m_SoundLock); lock_unlock(m_SoundLock);
@ -362,14 +397,24 @@ ISound::CSampleHandle CSound::LoadWV(const char *pFilename)
SampleID = AllocID(); SampleID = AllocID();
if(SampleID < 0) if(SampleID < 0)
{ {
io_close(ms_File); io_close(s_File);
ms_File = 0; s_File = 0;
lock_unlock(m_SoundLock); lock_unlock(m_SoundLock);
return CSampleHandle(); return CSampleHandle();
} }
pSample = &m_aSamples[SampleID]; 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) if (pContext)
{ {
int m_aSamples = WavpackGetNumSamples(pContext); int m_aSamples = WavpackGetNumSamples(pContext);
@ -387,8 +432,8 @@ ISound::CSampleHandle CSound::LoadWV(const char *pFilename)
if(pSample->m_Channels > 2) if(pSample->m_Channels > 2)
{ {
dbg_msg("sound/wv", "file is not mono or stereo. filename='%s'", pFilename); dbg_msg("sound/wv", "file is not mono or stereo. filename='%s'", pFilename);
io_close(ms_File); io_close(s_File);
ms_File = 0; s_File = 0;
lock_unlock(m_SoundLock); lock_unlock(m_SoundLock);
return CSampleHandle(); return CSampleHandle();
} }
@ -403,8 +448,8 @@ ISound::CSampleHandle CSound::LoadWV(const char *pFilename)
if(BitsPerSample != 16) if(BitsPerSample != 16)
{ {
dbg_msg("sound/wv", "bps is %d, not 16, filname='%s'", BitsPerSample, pFilename); dbg_msg("sound/wv", "bps is %d, not 16, filname='%s'", BitsPerSample, pFilename);
io_close(ms_File); io_close(s_File);
ms_File = 0; s_File = 0;
lock_unlock(m_SoundLock); lock_unlock(m_SoundLock);
return CSampleHandle(); return CSampleHandle();
} }
@ -431,8 +476,8 @@ ISound::CSampleHandle CSound::LoadWV(const char *pFilename)
dbg_msg("sound/wv", "failed to open %s: %s", pFilename, aError); dbg_msg("sound/wv", "failed to open %s: %s", pFilename, aError);
} }
io_close(ms_File); io_close(s_File);
ms_File = NULL; s_File = NULL;
if(g_Config.m_Debug) if(g_Config.m_Debug)
dbg_msg("sound/wv", "loaded %s", pFilename); dbg_msg("sound/wv", "loaded %s", pFilename);
@ -562,7 +607,4 @@ bool CSound::IsPlaying(CSampleHandle SampleID)
return Ret; return Ret;
} }
IOHANDLE CSound::ms_File = 0;
IEngineSound *CreateEngineSound() { return new CSound; } IEngineSound *CreateEngineSound() { return new CSound; }

View file

@ -21,10 +21,6 @@ public:
static void RateConvert(int SampleID); 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 bool IsSoundEnabled() { return m_SoundEnabled != 0; }
virtual CSampleHandle LoadWV(const char *pFilename); virtual CSampleHandle LoadWV(const char *pFilename);

View file

@ -553,7 +553,7 @@ static void StrVariableCommand(IConsole::IResult *pResult, void *pUserData)
int Length = 0; int Length = 0;
while(*pString) while(*pString)
{ {
int Size = str_utf8_encode(Temp, static_cast<const unsigned char>(*pString++)); int Size = str_utf8_encode(Temp, static_cast<unsigned char>(*pString++));
if(Length+Size < pData->m_MaxSize) if(Length+Size < pData->m_MaxSize)
{ {
mem_copy(pData->m_pStr+Length, &Temp, Size); mem_copy(pData->m_pStr+Length, &Temp, Size);

View file

@ -37,9 +37,9 @@ void CMapImages::LoadMapImages(IMap *pMap, class CLayers *pLayers, int MapType)
for(int k = 0; k < pLayers->NumLayers(); k++) for(int k = 0; k < pLayers->NumLayers(); k++)
{ {
const CMapItemLayer * const pLayer = pLayers->GetLayer(k); const CMapItemLayer * const pLayer = pLayers->GetLayer(k);
if(!FoundQuadLayer && pLayer->m_Type == LAYERTYPE_QUADS && ((const CMapItemLayerQuads * const)pLayer)->m_Image == i) if(!FoundQuadLayer && pLayer->m_Type == LAYERTYPE_QUADS && ((const CMapItemLayerQuads *)pLayer)->m_Image == i)
FoundQuadLayer = true; FoundQuadLayer = true;
if(!FoundTileLayer && pLayer->m_Type == LAYERTYPE_TILES && ((const CMapItemLayerTilemap * const)pLayer)->m_Image == i) if(!FoundTileLayer && pLayer->m_Type == LAYERTYPE_TILES && ((const CMapItemLayerTilemap *)pLayer)->m_Image == i)
FoundTileLayer = true; FoundTileLayer = true;
} }
if(FoundTileLayer) if(FoundTileLayer)

View file

@ -524,12 +524,13 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker)
// get paras // get paras
switch(gs_GameMsgList[GameMsgID].m_ParaType) switch(gs_GameMsgList[GameMsgID].m_ParaType)
{ {
case PARA_III: case PARA_I: NumParaI = 1; break;
aParaI[NumParaI++] = pUnpacker->GetInt(); case PARA_II: NumParaI = 2; break;
case PARA_II: case PARA_III: NumParaI = 3; break;
aParaI[NumParaI++] = pUnpacker->GetInt(); }
case PARA_I: for(int i = 0; i < NumParaI; i++)
aParaI[NumParaI++] = pUnpacker->GetInt(); {
aParaI[i] = pUnpacker->GetInt();
} }
// check for unpacking errors // check for unpacking errors

View file

@ -126,6 +126,7 @@ const char *CLocalizationDatabase::FindString(unsigned Hash, unsigned ContextHas
{ {
CString String; CString String;
String.m_Hash = Hash; String.m_Hash = Hash;
String.m_ContextHash = 0; // this is ignored for the search anyway
sorted_array<CString>::range r = ::find_binary(m_Strings.all(), String); sorted_array<CString>::range r = ::find_binary(m_Strings.all(), String);
if(r.empty()) if(r.empty())
return 0; return 0;

View file

@ -648,6 +648,7 @@ void CGameContext::OnClientEnter(int ClientID)
{ {
CNetMsg_De_ClientEnter Msg; CNetMsg_De_ClientEnter Msg;
Msg.m_pName = NewClientInfoMsg.m_pName; Msg.m_pName = NewClientInfoMsg.m_pName;
Msg.m_ClientID = ClientID;
Msg.m_Team = NewClientInfoMsg.m_Team; Msg.m_Team = NewClientInfoMsg.m_Team;
Server()->SendPackMsg(&Msg, MSGFLAG_NOSEND, -1); Server()->SendPackMsg(&Msg, MSGFLAG_NOSEND, -1);
} }

112
src/osxlaunch/server.mm Normal file
View file

@ -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;
}