mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Add CMake
This commit is contained in:
parent
c45aa9927c
commit
ee2afdac33
17
.gitignore
vendored
17
.gitignore
vendored
|
@ -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
|
||||
|
|
1243
CMakeLists.txt
Normal file
1243
CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load diff
5
bam.lua
5
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)
|
||||
|
|
37
cmake/FindFreetype.cmake
Normal file
37
cmake/FindFreetype.cmake
Normal 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
46
cmake/FindPnglite.cmake
Normal 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
38
cmake/FindSDL.cmake
Normal 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
52
cmake/FindWavpack.cmake
Normal 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
50
cmake/FindZLIB.cmake
Normal 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()
|
11
cmake/toolchains/darwin.toolchain
Normal file
11
cmake/toolchains/darwin.toolchain
Normal 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)
|
10
cmake/toolchains/mingw32.toolchain
Normal file
10
cmake/toolchains/mingw32.toolchain
Normal 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)
|
10
cmake/toolchains/mingw64.toolchain
Normal file
10
cmake/toolchains/mingw64.toolchain
Normal 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)
|
24
other/bundle/client/Info.plist.in
Normal file
24
other/bundle/client/Info.plist.in
Normal 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>
|
1
other/bundle/client/PkgInfo
Normal file
1
other/bundle/client/PkgInfo
Normal file
|
@ -0,0 +1 @@
|
|||
APPL????
|
20
other/bundle/server/Info.plist.in
Normal file
20
other/bundle/server/Info.plist.in
Normal 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>
|
1
other/bundle/server/PkgInfo
Normal file
1
other/bundle/server/PkgInfo
Normal file
|
@ -0,0 +1 @@
|
|||
APPL????
|
|
@ -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
|
||||
|
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
1
other/icons/teeworlds.rc
Normal file
1
other/icons/teeworlds.rc
Normal file
|
@ -0,0 +1 @@
|
|||
ID ICON "teeworlds.ico"
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
1
other/icons/teeworlds_srv.rc
Normal file
1
other/icons/teeworlds_srv.rc
Normal file
|
@ -0,0 +1 @@
|
|||
ID ICON "teeworlds_srv.ico"
|
|
@ -1 +1 @@
|
|||
50h ICON "Teeworlds_srv.ico"
|
||||
50h ICON "teeworlds_srv.ico"
|
||||
|
|
|
@ -1 +1 @@
|
|||
ID ICON "Teeworlds_srv.ico"
|
||||
ID ICON "teeworlds_srv.ico"
|
||||
|
|
|
@ -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")
|
||||
|
|
63
scripts/darwin_change_dylib.py
Normal file
63
scripts/darwin_change_dylib.py
Normal 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
106
scripts/dmg.py
Normal 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
21
scripts/git_revision.py
Normal 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))
|
|
@ -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);
|
||||
|
|
|
@ -219,6 +219,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.
|
||||
|
|
|
@ -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(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)
|
||||
{
|
||||
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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
1
src/osxlaunch/client.m
Symbolic link
|
@ -0,0 +1 @@
|
|||
client.mm
|
373
src/osxlaunch/client.mm
Normal file
373
src/osxlaunch/client.mm
Normal 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;
|
||||
}
|
||||
|
|
@ -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
1
src/osxlaunch/server.m
Symbolic link
|
@ -0,0 +1 @@
|
|||
server.mm
|
112
src/osxlaunch/server.mm
Normal file
112
src/osxlaunch/server.mm
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue