Add CMake

This commit is contained in:
heinrich5991 2018-10-01 10:49:19 +02:00
parent c45aa9927c
commit ee2afdac33
47 changed files with 2323 additions and 512 deletions

17
.gitignore vendored
View file

@ -8,6 +8,7 @@ src/game/generated
SDL.dll SDL.dll
freetype.dll freetype.dll
autoexec.cfg autoexec.cfg
Info.plist
crapnet* crapnet*
dilate* dilate*
@ -20,3 +21,19 @@ teeworlds*
teeworlds_srv* teeworlds_srv*
tileset_border* tileset_border*
versionsrv* versionsrv*
# CMake
data
!/data
src
!/src
*.ninja
.ninja*
CMakeCache.txt
CMakeFiles/
CPackConfig.cmake
CPackSourceConfig.cmake
Makefile
cmake_install.cmake
install_manifest.txt

1243
CMakeLists.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -169,6 +169,7 @@ function build(settings)
-- set some platform specific settings -- set some platform specific settings
settings.cc.includes:Add("src") settings.cc.includes:Add("src")
settings.cc.includes:Add("src/engine/external/wavpack")
if family == "unix" then if family == "unix" then
if platform == "macosx" 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) -- build tools (TODO: fix this so we don't get double _d_d stuff)
tools_src = Collect("src/tools/*.cpp", "src/tools/*.c") tools_src = Collect("src/tools/*.cpp", "src/tools/*.c")
client_osxlaunch = {}
server_osxlaunch = {} server_osxlaunch = {}
if platform == "macosx" then if platform == "macosx" then
client_osxlaunch = Compile(client_settings, "src/osxlaunch/client.m")
server_osxlaunch = Compile(launcher_settings, "src/osxlaunch/server.m") server_osxlaunch = Compile(launcher_settings, "src/osxlaunch/server.m")
end end
@ -268,7 +267,7 @@ function build(settings)
-- build client, server, version server and master server -- build client, server, version server and master server
client_exe = Link(client_settings, "teeworlds", game_shared, game_client, client_exe = Link(client_settings, "teeworlds", game_shared, game_client,
engine, client, game_editor, md5, zlib, pnglite, wavpack, 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, server_exe = Link(server_settings, "teeworlds_srv", engine, server,
game_shared, game_server, md5, zlib, server_link_other) game_shared, game_server, md5, zlib, server_link_other)

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

38
cmake/FindSDL.cmake Normal file
View file

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

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

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

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>org.DDNetClient.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

@ -39,9 +39,9 @@ FreeType = {
elseif option.use_winlib > 0 then elseif option.use_winlib > 0 then
if option.use_winlib == 32 then if option.use_winlib == 32 then
settings.link.libpath:Add(FreeType.basepath .. "/lib32") settings.link.libpath:Add(FreeType.basepath .. "/windows/lib32")
else else
settings.link.libpath:Add(FreeType.basepath .. "/lib64") 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

@ -51,9 +51,9 @@ SDL = {
if option.use_winlib > 0 then if 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 .. "/lib32") settings.link.libpath:Add(SDL.basepath .. "/windows/lib32")
else else
settings.link.libpath:Add(SDL.basepath .. "/lib64") settings.link.libpath:Add(SDL.basepath .. "/windows/lib64")
end end
settings.link.libs:Add("SDL") settings.link.libs:Add("SDL")
settings.link.libs:Add("SDLmain") settings.link.libs:Add("SDLmain")

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

106
scripts/dmg.py Normal file
View file

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

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

@ -303,6 +303,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);

View file

@ -219,6 +219,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

@ -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>
@ -67,6 +68,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)
{ {
@ -328,11 +331,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
int CSound::LoadWV(const char *pFilename) int CSound::LoadWV(const char *pFilename)
{ {
CSample *pSample; CSample *pSample;
@ -351,8 +386,8 @@ int CSound::LoadWV(const char *pFilename)
if(!m_pStorage) if(!m_pStorage)
return -1; return -1;
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);
return -1; return -1;
@ -363,7 +398,17 @@ int CSound::LoadWV(const char *pFilename)
return -1; return -1;
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);
@ -419,8 +464,8 @@ int 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);
@ -527,7 +572,4 @@ void CSound::StopAll()
lock_unlock(m_SoundLock); lock_unlock(m_SoundLock);
} }
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 int LoadWV(const char *pFilename); virtual int LoadWV(const char *pFilename);

View file

@ -2,8 +2,8 @@
/* If you are missing that file, acquire a complete release at teeworlds.com. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef GAME_VERSION_H #ifndef GAME_VERSION_H
#define GAME_VERSION_H #define GAME_VERSION_H
#include "generated/nethash.cpp" #include <game/generated/nethash.cpp>
#define GAME_VERSION "0.6.5" #define GAME_VERSION "0.6.5"
#define GAME_NETVERSION "0.6 " GAME_NETVERSION_HASH #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 #endif

View file

@ -1,373 +0,0 @@
/* 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;
}

1
src/osxlaunch/client.m Symbolic link
View file

@ -0,0 +1 @@
client.mm

373
src/osxlaunch/client.mm Normal file
View file

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

View file

@ -1,112 +0,0 @@
#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;
}

1
src/osxlaunch/server.m Symbolic link
View file

@ -0,0 +1 @@
server.mm

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