diff --git a/.github/workflows/build-prototype.yml b/.github/workflows/build-prototype.yml index ea3a54fea8..f08d458271 100644 --- a/.github/workflows/build-prototype.yml +++ b/.github/workflows/build-prototype.yml @@ -91,3 +91,59 @@ jobs: with: name: ${{ env.LINUX_ARTIFACT_NAME }} path: bin/keeperfx + + build-prototype-macos: + name: "Build Prototype macOS arm64" + runs-on: macos-14 + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Update system + run: | + set -eux + brew update + brew install \ + cmake \ + gcc \ + pkg-config \ + sdl2 \ + sdl2_image \ + sdl2_mixer \ + sdl2_net \ + ffmpeg \ + openal-soft \ + luajit \ + libspng \ + minizip \ + zlib \ + miniupnpc \ + libnatpmp + + - name: Build + run: | + set -eux + GCC_MAJOR=$(brew list --versions gcc | awk '{print $2}' | cut -d. -f1) + BUILD_NUMBER=$(git rev-list --count origin/master) + GITHUB_SHA=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.head.sha) + PACKAGE_SUFFIX=Prototype_$(git rev-parse --short=7 "$GITHUB_SHA") + make BUILD_NUMBER=$BUILD_NUMBER VER_SUFFIX=$PACKAGE_SUFFIX PLATFORM=mac ARCH=arm64 CC=gcc-$GCC_MAJOR CXX=g++-$GCC_MAJOR -f linux.mk + + - name: Bundle app + run: | + set -eux + chmod +x tools/macos_bundle.sh + APP_NAME=KeeperFX.app OUTPUT_DIR=dist BIN_PATH=bin/keeperfx tools/macos_bundle.sh + + - name: Package app + run: | + set -eux + ditto -c -k --keepParent dist/KeeperFX.app dist/KeeperFX.app.zip + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: keeperfx-macos-app + path: dist/KeeperFX.app.zip diff --git a/linux.mk b/linux.mk index 74adfa966f..267e6a7b66 100644 --- a/linux.mk +++ b/linux.mk @@ -9,6 +9,81 @@ STRIP ?= strip ECHO ?= echo MV ?= mv -f +PLATFORM ?= $(shell uname -s) +ARCH ?= $(shell uname -m) + +ifeq ($(PLATFORM),Linux) +PLATFORM := linux +endif +ifeq ($(PLATFORM),Darwin) +PLATFORM := mac +endif +ifeq ($(PLATFORM),macos) +PLATFORM := mac +endif + +ifeq ($(ARCH),amd64) +ARCH := x86_64 +endif +ifeq ($(ARCH),aarch64) +ARCH := arm64 +endif + +DEPS_ASTRONOMY_TAG ?= 20250418 +DEPS_CENTIJSON_TAG ?= 20250418 +DEPS_ENET6_TAG ?= 20260213 +DEPS_ASTRONOMY_REPO ?= https://github.com/cosinekitty/astronomy.git +DEPS_CENTIJSON_REPO ?= https://github.com/mity/centijson.git +DEPS_ENET6_REPO ?= https://github.com/SirLynix/enet6.git +DEPS_ASTRONOMY_REF ?= +DEPS_CENTIJSON_REF ?= +DEPS_ENET6_REF ?= +DEPS_CLONE_DEPTH ?= 1 +DEPS_BUILD_DIR ?= deps/_build +DEPS_SUFFIX ?= +DEPS_DOWNLOAD ?= 1 + +ifeq ($(PLATFORM),linux) +ifeq ($(ARCH),x86_64) +DEPS_SUFFIX ?= lin64 +else +# No prebuilt dependency archive defined for this architecture; disable downloads. +DEPS_DOWNLOAD ?= 0 +endif +endif +ifeq ($(PLATFORM),mac) +DEPS_DOWNLOAD ?= 0 +endif + +ifeq ($(PLATFORM),linux) + ifeq ($(ARCH),x86_64) + ARCH_CFLAGS := -march=x86-64 + else ifeq ($(ARCH),arm64) + ARCH_CFLAGS := -march=armv8-a + else + $(error Unsupported ARCH for linux: $(ARCH)) + endif + ARCH_LDFLAGS := +else ifeq ($(PLATFORM),mac) + ifeq ($(ARCH),x86_64) + ARCH_CFLAGS := -arch x86_64 + else ifeq ($(ARCH),arm64) + ARCH_CFLAGS := -arch arm64 + else + $(error Unsupported ARCH for mac: $(ARCH)) + endif + ARCH_LDFLAGS := $(ARCH_CFLAGS) +else + $(error Unsupported PLATFORM: $(PLATFORM)) +endif + +WARN_NO_FORMAT_TRUNCATION := +ifeq ($(PLATFORM),linux) +WARN_NO_FORMAT_TRUNCATION := -Wno-format-truncation +endif + +CXX_STD ?= -std=c++17 + KFX_SOURCES = \ src/actionpt.c \ src/api.c \ @@ -282,35 +357,63 @@ KFX_INCLUDES = \ -Ideps/centitoml \ -Ideps/astronomy/include \ -Ideps/enet6/include \ + $(shell pkg-config --cflags-only-I sdl2) \ + $(shell pkg-config --cflags-only-I SDL2_image) \ + $(shell pkg-config --cflags-only-I SDL2_mixer) \ + $(shell pkg-config --cflags-only-I SDL2_net) \ + $(shell pkg-config --cflags-only-I libavformat) \ + $(shell pkg-config --cflags-only-I libavcodec) \ + $(shell pkg-config --cflags-only-I libswresample) \ + $(shell pkg-config --cflags-only-I libavutil) \ + $(shell pkg-config --cflags-only-I openal) \ + $(shell pkg-config --cflags-only-I openal-soft) \ + $(shell pkg-config --cflags-only-I spng) \ + $(shell pkg-config --cflags-only-I minizip) \ + $(shell pkg-config --cflags-only-I zlib) \ $(shell pkg-config --cflags-only-I luajit) -KFX_CFLAGS += -g -DDEBUG -DBFDEBUG_LEVEL=0 -O3 -march=x86-64 $(KFX_INCLUDES) -Wall -Wextra -Werror -Wno-unused-parameter -Wno-absolute-value -Wno-unknown-pragmas -Wno-format-truncation -Wno-sign-compare -KFX_CXXFLAGS += -g -DDEBUG -DBFDEBUG_LEVEL=0 -O3 -march=x86-64 $(KFX_INCLUDES) -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unknown-pragmas -Wno-format-truncation -Wno-sign-compare +ifeq ($(PLATFORM),mac) +KFX_INCLUDES += \ + -I/opt/homebrew/opt/openal-soft/include \ + -I/usr/local/opt/openal-soft/include +endif + +KFX_CFLAGS += -g -DDEBUG -DBFDEBUG_LEVEL=0 -O3 $(ARCH_CFLAGS) $(KFX_INCLUDES) -Wall -Wextra -Wno-unused-parameter -Wno-absolute-value -Wno-unknown-pragmas $(WARN_NO_FORMAT_TRUNCATION) -Wno-sign-compare -fsigned-char +KFX_CXXFLAGS += -g -DDEBUG -DBFDEBUG_LEVEL=0 -O3 $(CXX_STD) $(ARCH_CFLAGS) $(KFX_INCLUDES) -Wall -Wextra -Wno-unused-parameter -Wno-unknown-pragmas $(WARN_NO_FORMAT_TRUNCATION) -Wno-sign-compare -fsigned-char KFX_LDFLAGS += \ -g \ -rdynamic \ -Wall -Wextra -Werror \ + $(ARCH_LDFLAGS) \ -Ldeps/astronomy -lastronomy \ -Ldeps/centijson -ljson \ -Ldeps/enet6 -lenet6 \ - $(shell pkg-config --libs-only-l sdl2) \ - $(shell pkg-config --libs-only-l SDL2_mixer) \ - $(shell pkg-config --libs-only-l SDL2_net) \ - $(shell pkg-config --libs-only-l SDL2_image) \ - $(shell pkg-config --libs-only-l libavformat) \ - $(shell pkg-config --libs-only-l libavcodec) \ - $(shell pkg-config --libs-only-l libswresample) \ - $(shell pkg-config --libs-only-l libavutil) \ - $(shell pkg-config --libs-only-l openal) \ - $(shell pkg-config --libs-only-l luajit) \ - $(shell pkg-config --libs-only-l spng) \ - $(shell pkg-config --libs-only-l minizip) \ - $(shell pkg-config --libs-only-l zlib) \ + $(shell pkg-config --libs sdl2) \ + $(shell pkg-config --libs SDL2_mixer) \ + $(shell pkg-config --libs SDL2_net) \ + $(shell pkg-config --libs SDL2_image) \ + $(shell pkg-config --libs libavformat) \ + $(shell pkg-config --libs libavcodec) \ + $(shell pkg-config --libs libswresample) \ + $(shell pkg-config --libs libavutil) \ + $(shell pkg-config --libs openal) \ + $(shell pkg-config --libs openal-soft) \ + $(shell pkg-config --libs luajit) \ + $(shell pkg-config --libs spng) \ + $(shell pkg-config --libs minizip) \ + $(shell pkg-config --libs zlib) \ -lminiupnpc \ -lnatpmp \ -ldl +ifeq ($(PLATFORM),mac) +KFX_LDFLAGS += \ + -L/opt/homebrew/opt/openal-soft/lib \ + -L/usr/local/opt/openal-soft/lib \ + -lopenal +endif + TOML_SOURCES = \ deps/centitoml/toml_api.c @@ -319,7 +422,7 @@ TOML_OBJECTS = $(patsubst deps/centitoml/%.c,obj/centitoml/%.o,$(TOML_SOURCES)) TOML_INCLUDES = \ -Ideps/centijson/include -TOML_CFLAGS += -O3 -march=x86-64 $(TOML_INCLUDES) -Wall -Wextra -Werror -Wno-unused-parameter +TOML_CFLAGS += -O3 $(ARCH_CFLAGS) $(TOML_INCLUDES) -Wall -Wextra -Werror -Wno-unused-parameter ifeq ($(ENABLE_LTO), 1) KFX_CFLAGS += -flto @@ -359,23 +462,102 @@ src/moonphase.c: deps/astronomy/include/astronomy.h deps/centitoml/toml_api.c: deps/centijson/include/json.h deps/centitoml/toml_conv.c: deps/centijson/include/json.h -deps/astronomy-lin64.tar.gz: - curl -Lso $@ "https://github.com/dkfans/kfx-deps/releases/download/20250418/astronomy-lin64.tar.gz" - -deps/astronomy/include/astronomy.h: deps/astronomy-lin64.tar.gz | deps/astronomy - tar xzmf $< -C deps/astronomy - -deps/centijson-lin64.tar.gz: - curl -Lso $@ "https://github.com/dkfans/kfx-deps/releases/download/20250418/centijson-lin64.tar.gz" - -deps/centijson/include/json.h: deps/centijson-lin64.tar.gz | deps/centijson - tar xzmf $< -C deps/centijson +deps/astronomy/include/astronomy.h: | deps/astronomy + @set -eux; \ + if [ -f "$@" ]; then exit 0; fi; \ + if [ "$(DEPS_DOWNLOAD)" = "1" ] && [ -n "$(DEPS_SUFFIX)" ]; then \ + if [ ! -f "deps/astronomy-$(DEPS_SUFFIX).tar.gz" ]; then \ + curl -Lfso "deps/astronomy-$(DEPS_SUFFIX).tar.gz" \ + "https://github.com/dkfans/kfx-deps/releases/download/$(DEPS_ASTRONOMY_TAG)/astronomy-$(DEPS_SUFFIX).tar.gz"; \ + fi; \ + if [ -f "deps/astronomy-$(DEPS_SUFFIX).tar.gz" ]; then \ + tar xzmf "deps/astronomy-$(DEPS_SUFFIX).tar.gz" -C deps/astronomy; \ + exit 0; \ + fi; \ + fi; \ + rm -rf "$(DEPS_BUILD_DIR)/astronomy"; \ + $(MKDIR) "$(DEPS_BUILD_DIR)"; \ + git clone --depth "$(DEPS_CLONE_DEPTH)" "$(DEPS_ASTRONOMY_REPO)" "$(DEPS_BUILD_DIR)/astronomy"; \ + if [ -n "$(DEPS_ASTRONOMY_REF)" ]; then git -C "$(DEPS_BUILD_DIR)/astronomy" checkout "$(DEPS_ASTRONOMY_REF)"; fi; \ + if [ -f "$(DEPS_BUILD_DIR)/astronomy/CMakeLists.txt" ]; then \ + cmake -S "$(DEPS_BUILD_DIR)/astronomy" -B "$(DEPS_BUILD_DIR)/astronomy/build" -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release; \ + cmake --build "$(DEPS_BUILD_DIR)/astronomy/build"; \ + else \ + astro_src=$$(find "$(DEPS_BUILD_DIR)/astronomy" -path "*/source/c/astronomy.c" | head -n 1); \ + if [ -z "$$astro_src" ]; then astro_src=$$(find "$(DEPS_BUILD_DIR)/astronomy" -path "*/source/astronomy.c" | head -n 1); fi; \ + if [ -z "$$astro_src" ]; then astro_src=$$(find "$(DEPS_BUILD_DIR)/astronomy" -path "*/src/astronomy.c" | head -n 1); fi; \ + if [ -z "$$astro_src" ]; then echo "astronomy.c not found"; exit 1; fi; \ + astro_inc=$$(find "$(DEPS_BUILD_DIR)/astronomy" -path "*/source/c/astronomy.h" -exec dirname {} \; | head -n 1); \ + if [ -z "$$astro_inc" ]; then astro_inc=$$(find "$(DEPS_BUILD_DIR)/astronomy" -path "*/source/astronomy.h" -exec dirname {} \; | head -n 1); fi; \ + if [ -z "$$astro_inc" ]; then astro_inc=$$(find "$(DEPS_BUILD_DIR)/astronomy" -path "*/src/astronomy.h" -exec dirname {} \; | head -n 1); fi; \ + if [ -z "$$astro_inc" ]; then echo "astronomy.h not found"; exit 1; fi; \ + $(MKDIR) "$(DEPS_BUILD_DIR)/astronomy/build"; \ + $(CC) -O3 -I"$$astro_inc" -c "$$astro_src" -o "$(DEPS_BUILD_DIR)/astronomy/build/astronomy.o"; \ + ar rcs "$(DEPS_BUILD_DIR)/astronomy/build/libastronomy.a" "$(DEPS_BUILD_DIR)/astronomy/build/astronomy.o"; \ + fi; \ + $(MKDIR) deps/astronomy/include; \ + header_path=$$(find "$(DEPS_BUILD_DIR)/astronomy" -name astronomy.h | head -n 1); \ + lib_path=$$(find "$(DEPS_BUILD_DIR)/astronomy" -name libastronomy.a | head -n 1); \ + if [ -z "$$header_path" ] || [ -z "$$lib_path" ]; then echo "astronomy build output not found"; exit 1; fi; \ + cp "$$header_path" deps/astronomy/include/; \ + cp "$$lib_path" deps/astronomy/libastronomy.a -deps/enet6-lin64.tar.gz: - curl -Lso $@ "https://github.com/dkfans/kfx-deps/releases/download/20260213/enet6-lin64.tar.gz" +deps/centijson/include/json.h: | deps/centijson + @set -eux; \ + if [ -f "$@" ]; then exit 0; fi; \ + if [ "$(DEPS_DOWNLOAD)" = "1" ] && [ -n "$(DEPS_SUFFIX)" ]; then \ + if [ ! -f "deps/centijson-$(DEPS_SUFFIX).tar.gz" ]; then \ + curl -Lfso "deps/centijson-$(DEPS_SUFFIX).tar.gz" \ + "https://github.com/dkfans/kfx-deps/releases/download/$(DEPS_CENTIJSON_TAG)/centijson-$(DEPS_SUFFIX).tar.gz"; \ + fi; \ + if [ -f "deps/centijson-$(DEPS_SUFFIX).tar.gz" ]; then \ + tar xzmf "deps/centijson-$(DEPS_SUFFIX).tar.gz" -C deps/centijson; \ + exit 0; \ + fi; \ + fi; \ + rm -rf "$(DEPS_BUILD_DIR)/centijson"; \ + $(MKDIR) "$(DEPS_BUILD_DIR)"; \ + git clone --depth "$(DEPS_CLONE_DEPTH)" "$(DEPS_CENTIJSON_REPO)" "$(DEPS_BUILD_DIR)/centijson"; \ + if [ -n "$(DEPS_CENTIJSON_REF)" ]; then git -C "$(DEPS_BUILD_DIR)/centijson" checkout "$(DEPS_CENTIJSON_REF)"; fi; \ + if [ "$(PLATFORM)" = "mac" ]; then \ + find "$(DEPS_BUILD_DIR)/centijson" -name "*.c" -print0 | xargs -0 perl -pi -e 's@#include @#include @'; \ + fi; \ + cmake -S "$(DEPS_BUILD_DIR)/centijson" -B "$(DEPS_BUILD_DIR)/centijson/build" -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release; \ + cmake --build "$(DEPS_BUILD_DIR)/centijson/build"; \ + $(MKDIR) deps/centijson/include; \ + header_path=$$(find "$(DEPS_BUILD_DIR)/centijson" \( -name value.h -o -name json.h \) | head -n 1); \ + header_dir=$$(dirname "$$header_path"); \ + lib_path=$$(find "$(DEPS_BUILD_DIR)/centijson" \( -name libjson.a -o -name libcentijson.a \) | head -n 1); \ + if [ -z "$$header_path" ] || [ -z "$$lib_path" ]; then echo "centijson build output not found"; exit 1; fi; \ + cp "$$header_dir"/*.h deps/centijson/include/; \ + cp "$$lib_path" deps/centijson/libjson.a -deps/enet6/include/enet6/enet.h: deps/enet6-lin64.tar.gz | deps/enet6 - tar xzmf $< -C deps/enet6 +deps/enet6/include/enet6/enet.h: | deps/enet6 + @set -eux; \ + if [ -f "$@" ]; then exit 0; fi; \ + if [ "$(DEPS_DOWNLOAD)" = "1" ] && [ -n "$(DEPS_SUFFIX)" ]; then \ + if [ ! -f "deps/enet6-$(DEPS_SUFFIX).tar.gz" ]; then \ + curl -Lfso "deps/enet6-$(DEPS_SUFFIX).tar.gz" \ + "https://github.com/dkfans/kfx-deps/releases/download/$(DEPS_ENET6_TAG)/enet6-$(DEPS_SUFFIX).tar.gz"; \ + fi; \ + if [ -f "deps/enet6-$(DEPS_SUFFIX).tar.gz" ]; then \ + tar xzmf "deps/enet6-$(DEPS_SUFFIX).tar.gz" -C deps/enet6; \ + exit 0; \ + fi; \ + fi; \ + rm -rf "$(DEPS_BUILD_DIR)/enet6"; \ + $(MKDIR) "$(DEPS_BUILD_DIR)"; \ + git clone --depth "$(DEPS_CLONE_DEPTH)" "$(DEPS_ENET6_REPO)" "$(DEPS_BUILD_DIR)/enet6"; \ + if [ -n "$(DEPS_ENET6_REF)" ]; then git -C "$(DEPS_BUILD_DIR)/enet6" checkout "$(DEPS_ENET6_REF)"; fi; \ + cmake -S "$(DEPS_BUILD_DIR)/enet6" -B "$(DEPS_BUILD_DIR)/enet6/build" -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release; \ + cmake --build "$(DEPS_BUILD_DIR)/enet6/build"; \ + $(MKDIR) deps/enet6/include/enet6; \ + header_path=$$(find "$(DEPS_BUILD_DIR)/enet6" -path "*/enet6/enet.h" | head -n 1); \ + lib_path=$$(find "$(DEPS_BUILD_DIR)/enet6" \( -name libenet6.a -o -name libenet.a \) | head -n 1); \ + if [ -z "$$header_path" ] || [ -z "$$lib_path" ]; then echo "enet6 build output not found"; exit 1; fi; \ + header_dir=$$(dirname "$$header_path"); \ + cp "$$header_dir"/*.h deps/enet6/include/enet6/; \ + cp "$$lib_path" deps/enet6/libenet6.a src/ver_defs.h: version.mk $(ECHO) "#define VER_MAJOR $(VER_MAJOR)" > $@.swp diff --git a/src/ariadne.c b/src/ariadne.c index c7d8290ecb..a3f38bd24a 100644 --- a/src/ariadne.c +++ b/src/ariadne.c @@ -1614,9 +1614,7 @@ TbBool triangle_check_and_add_navitree_bak(long ttri) ERRORLOG("invalid triangle received"); return false; } - long n; long nskipped; - n = 0; nskipped = 0; long i; long k; @@ -1644,7 +1642,6 @@ TbBool triangle_check_and_add_navitree_bak(long ttri) } } } - n++; } if (nskipped != 0) { NAVIDBG(6,"navigate heap full, %ld points ignored",nskipped); diff --git a/src/bflib_cpu.c b/src/bflib_cpu.c index 5c7c865809..82ed68b18e 100644 --- a/src/bflib_cpu.c +++ b/src/bflib_cpu.c @@ -28,26 +28,24 @@ extern "C" { #endif /******************************************************************************/ +#if defined(__i386__) || defined(__x86_64__) /** Issue a single request to CPUID. * Fits 'intel features', for instance note that even if only "eax" and "edx" * are of interest, other registers will be modified by the operation, * so we need to tell the compiler about it. */ static inline void cpuid(int code, uint32_t *a, uint32_t *d) { - #if defined(__i386__) || defined(__x86_64__) asm volatile("cpuid":"=a"(*a),"=d"(*d):"0"(code):"ecx","ebx"); - #endif } /** Issue a complete request, storing general registers output in an array. */ static inline void cpuid_string(int code, void * destination) { - #if defined(__i386__) || defined(__x86_64__) uint32_t * where = (uint32_t *) destination; asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)), "=c"(*(where+2)),"=d"(*(where+3)):"0"(code)); - #endif } +#endif /******************************************************************************/ void cpu_detect(struct CPU_INFO *cpu) diff --git a/src/bflib_crash.c b/src/bflib_crash.c index 00545f3dae..1d4bed1f5d 100644 --- a/src/bflib_crash.c +++ b/src/bflib_crash.c @@ -17,6 +17,9 @@ * (at your option) any later version. */ /******************************************************************************/ +#if defined(__APPLE__) && !defined(_DARWIN_C_SOURCE) +#define _DARWIN_C_SOURCE 1 +#endif #if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif @@ -39,7 +42,11 @@ #endif #if defined(BF_POSIX_CRASH) #include +#if defined(__APPLE__) +#include +#else #include +#endif #include #include #endif @@ -86,8 +93,12 @@ static const char* sigstr(int s) case SIGXFSZ : return "File size limit exceeded (4.2 BSD)"; case SIGVTALRM : return "Virtual alarm clock (4.2 BSD)"; case SIGPROF : return "Profiling alarm clock (4.2 BSD)"; +#ifdef SIGWINCH case SIGWINCH : return "Window size change (4.3 BSD, Sun)"; +#endif +#ifdef SIGIO case SIGIO : return "I/O now possible (4.2 BSD)"; +#endif #ifdef SIGSYS case SIGSYS : return "Bad system call"; #endif diff --git a/src/bflib_filelst.h b/src/bflib_filelst.h index 9365e806c7..2410f3b2f7 100644 --- a/src/bflib_filelst.h +++ b/src/bflib_filelst.h @@ -26,8 +26,6 @@ extern "C" { #endif /******************************************************************************/ -#pragma pack(1) - struct TbLoadFiles; typedef const char * ModifyDataLoadFnameFunc(const char *); @@ -51,8 +49,6 @@ struct TbLoadFilesV2 { LoadFilesGetSizeFunc GetSizeFunc; LoadFilesUnpackFunc UnpackFunc; }; - -#pragma pack() /******************************************************************************/ const char * defaultModifyDataLoadFilename(const char *); ModifyDataLoadFnameFunc *LbDataLoadSetModifyFilenameFunction(ModifyDataLoadFnameFunc *newfunc); diff --git a/src/bflib_guibtns.h b/src/bflib_guibtns.h index 6ed4bec6f8..3442b32f6b 100644 --- a/src/bflib_guibtns.h +++ b/src/bflib_guibtns.h @@ -29,8 +29,6 @@ extern "C" { #endif /******************************************************************************/ -#pragma pack(1) - struct GuiButton; struct GuiMenu; struct GuiBox; @@ -217,7 +215,6 @@ struct EventTypeInfo { // Exported variables extern char backup_input_field[INPUT_FIELD_LEN]; extern struct GuiButton *input_button; -#pragma pack() /******************************************************************************/ extern TbCharCount input_field_pos; /******************************************************************************/ diff --git a/src/bflib_network.h b/src/bflib_network.h index b62dc54e26..3d3c0f09de 100644 --- a/src/bflib_network.h +++ b/src/bflib_network.h @@ -35,7 +35,6 @@ extern "C" { #define TIMEOUT_LOBBY_EXCHANGE 3000 #define TIMEOUT_GAMEPLAY_MISSING_PACKET 8000 /******************************************************************************/ -#pragma pack(1) // New Declarations Here ====================================================== @@ -164,6 +163,8 @@ extern const struct NetSP tcpSP; // New Declarations End Here ================================================== +#pragma pack(push, 1) + struct TbNetworkSessionNameEntry; typedef long (*Net_Callback_Func)(void); @@ -245,7 +246,7 @@ long service_flags; /******************************************************************************/ -#pragma pack() +#pragma pack(pop) /******************************************************************************/ void LbNetwork_SetServerPort(int port); void LbNetwork_InitSessionsFromCmdLine(const char * str); diff --git a/src/bflib_sprite.h b/src/bflib_sprite.h index 202f0b3c7b..37bd66314c 100644 --- a/src/bflib_sprite.h +++ b/src/bflib_sprite.h @@ -27,8 +27,6 @@ extern "C" { #endif /******************************************************************************/ -#pragma pack(1) - /** * Type which contains buffer of a sprite, with RLE-encoded alpha channel. */ @@ -65,7 +63,6 @@ struct TiledSprite { unsigned char y_num; unsigned short spr_idx[10][10]; }; -#pragma pack() struct TbSpriteSheet * create_spritesheet(void); struct TbSpriteSheet * load_spritesheet(const char * data_fname, const char * index_fname); diff --git a/src/bflib_vidraw.h b/src/bflib_vidraw.h index 5859266f72..bb57755e13 100644 --- a/src/bflib_vidraw.h +++ b/src/bflib_vidraw.h @@ -29,8 +29,8 @@ extern "C" { #define MAX_SUPPORTED_SPRITE_DIM 256 #define NUM_DRAWITEMS 238 -#define SPRITE_SCALING_XSTEPS max(MAX_SUPPORTED_SPRITE_DIM,MAX_SUPPORTED_SCREEN_WIDTH) -#define SPRITE_SCALING_YSTEPS max(MAX_SUPPORTED_SPRITE_DIM,MAX_SUPPORTED_SCREEN_HEIGHT) +#define SPRITE_SCALING_XSTEPS ((MAX_SUPPORTED_SPRITE_DIM) > (MAX_SUPPORTED_SCREEN_WIDTH) ? (MAX_SUPPORTED_SPRITE_DIM) : (MAX_SUPPORTED_SCREEN_WIDTH)) +#define SPRITE_SCALING_YSTEPS ((MAX_SUPPORTED_SPRITE_DIM) > (MAX_SUPPORTED_SCREEN_HEIGHT) ? (MAX_SUPPORTED_SPRITE_DIM) : (MAX_SUPPORTED_SCREEN_HEIGHT)) /******************************************************************************/ #pragma pack(1) diff --git a/src/config.c b/src/config.c index ac8bc9b1f3..61689cdece 100644 --- a/src/config.c +++ b/src/config.c @@ -44,6 +44,7 @@ #include "vidmode.h" #include "post_inc.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/src/config.h b/src/config.h index 1d3c09d328..f3c38def31 100644 --- a/src/config.h +++ b/src/config.h @@ -115,9 +115,6 @@ enum TbConfigLoadFlags { CnfLd_IgnoreErrors = 0x04, /**< Do not log error message on failures (still, return with error). */ }; -#pragma pack(1) - - /******************************************************************************/ enum confCommandResults @@ -235,8 +232,6 @@ struct ConfigFileData{ /******************************************************************************/ extern char keeper_runtime_directory[152]; - -#pragma pack() /******************************************************************************/ extern unsigned long text_line_number; /******************************************************************************/ diff --git a/src/front_lvlstats.h b/src/front_lvlstats.h index cdf3d6cf88..84273bf485 100644 --- a/src/front_lvlstats.h +++ b/src/front_lvlstats.h @@ -28,8 +28,6 @@ extern "C" { #endif /******************************************************************************/ -#pragma pack(1) - typedef long (*StatGetValueCallback)(void *ptr); struct StatsData { // sizeof = 12 @@ -38,7 +36,6 @@ struct StatsData { // sizeof = 12 void *get_arg; }; -#pragma pack() /******************************************************************************/ void frontstats_draw_main_stats(struct GuiButton *gbtn); void frontstats_draw_scrolling_stats(struct GuiButton *gbtn); diff --git a/src/frontend.h b/src/frontend.h index 9754ace26c..12af27096f 100644 --- a/src/frontend.h +++ b/src/frontend.h @@ -41,7 +41,6 @@ extern "C" { // After that much milliseconds in main menu, demo is started #define MNU_DEMO_IDLE_TIME 30000 /******************************************************************************/ -#pragma pack(1) enum DemoItem_Kind { DIK_PlaySmkVideo, diff --git a/src/gui_topmsg.h b/src/gui_topmsg.h index 73a2da7ad8..68770f154c 100644 --- a/src/gui_topmsg.h +++ b/src/gui_topmsg.h @@ -27,7 +27,6 @@ extern "C" { #endif /******************************************************************************/ -#pragma pack(1) enum ErrorStatisticEntries { ESE_NoFreeThings = 0, @@ -48,7 +47,6 @@ struct ErrorStatistics { const char *msg; }; -#pragma pack() /******************************************************************************/ void erstats_clear(void); long erstat_inc(int stat_num); diff --git a/src/lvl_script_lib.c b/src/lvl_script_lib.c index d0eab84ea4..7808b8c80d 100644 --- a/src/lvl_script_lib.c +++ b/src/lvl_script_lib.c @@ -120,6 +120,7 @@ struct Thing *script_process_new_object(ThingModel tngmodel, MapSubtlCoord stl_x thing->valuable.gold_stored = arg; break; default: + { struct ObjectConfigStats* objst = get_object_model_stats(tngmodel); if (objst->genre == OCtg_GoldHoard) { @@ -129,6 +130,8 @@ struct Thing *script_process_new_object(ThingModel tngmodel, MapSubtlCoord stl_x } check_and_asimilate_thing_by_room(thing); } + break; + } } return thing; } diff --git a/src/player_computer.h b/src/player_computer.h index ad5d93eadd..73e62a43a3 100644 --- a/src/player_computer.h +++ b/src/player_computer.h @@ -244,8 +244,6 @@ enum computer_process_func_list #define INVALID_COMPUTER_PROCESS NULL #define INVALID_COMPUTER_TASK &game.computer_task[0] /******************************************************************************/ -#pragma pack(1) - struct Computer2; struct ComputerProcess; struct ComputerCheck; @@ -460,9 +458,6 @@ struct ExpandRooms { /******************************************************************************/ -#pragma pack() -/******************************************************************************/ - /******************************************************************************/ extern struct ValidRooms valid_rooms_to_build[]; diff --git a/src/player_instances.h b/src/player_instances.h index ebfacd2ba9..0a62ed92dd 100644 --- a/src/player_instances.h +++ b/src/player_instances.h @@ -61,8 +61,6 @@ enum PlayerInstanceNum { PI_UnusedSlot18, }; /******************************************************************************/ -#pragma pack(1) - struct Thing; struct PlayerInfo; @@ -83,9 +81,6 @@ struct PlayerInstanceInfo { // sizeof = 44 #define PLAYER_INSTANCES_COUNT 19 #define PLAYER_INSTANCES_COUNT_OLD 17 -/******************************************************************************/ - -#pragma pack() /******************************************************************************/ extern struct PlayerInstanceInfo player_instance_info[PLAYER_INSTANCES_COUNT]; /******************************************************************************/ diff --git a/src/pre_inc.h b/src/pre_inc.h index 30c5f26c38..28b25e8b11 100644 --- a/src/pre_inc.h +++ b/src/pre_inc.h @@ -9,4 +9,10 @@ #include "pre_file.h" #endif +#include + +#ifndef strnicmp +#define strnicmp strncasecmp +#endif + #endif //GIT_PRE_INC_H diff --git a/src/thing_stats.c b/src/thing_stats.c index fc2c2c467a..7063753b5f 100644 --- a/src/thing_stats.c +++ b/src/thing_stats.c @@ -895,20 +895,30 @@ HitPoints get_thing_max_health(const struct Thing *thing) switch (thing->class_id) { case TCls_Creature: + { struct CreatureControl* cctrl = creature_control_get_from_thing(thing); return cctrl->max_health; + } case TCls_Object: + { struct ObjectConfigStats* objst = get_object_model_stats(thing->model); return objst->health; + } case TCls_Door: + { struct DoorConfigStats* doorst = get_door_model_stats(thing->model); return doorst->health; + } case TCls_Shot: + { struct ShotConfigStats* shotst = get_shot_model_stats(thing->model); return shotst->health; + } case TCls_Trap: + { struct TrapConfigStats* trapst = get_trap_model_stats(thing->model); return trapst->health; + } case TCls_EffectElem: case TCls_EffectGen: default: diff --git a/tools/macos_bundle.sh b/tools/macos_bundle.sh new file mode 100644 index 0000000000..c3b105ff0d --- /dev/null +++ b/tools/macos_bundle.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +set -euo pipefail + +APP_NAME="${APP_NAME:-KeeperFX.app}" +APP_BASENAME="${APP_NAME%.app}" +OUTPUT_DIR="${OUTPUT_DIR:-dist}" +BIN_PATH="${BIN_PATH:-bin/keeperfx}" + +APP_DIR="${OUTPUT_DIR}/${APP_NAME}" +MACOS_DIR="${APP_DIR}/Contents/MacOS" +RES_DIR="${APP_DIR}/Contents/Resources" +FW_DIR="${APP_DIR}/Contents/Frameworks" + +rm -rf "${APP_DIR}" +mkdir -p "${MACOS_DIR}" "${RES_DIR}" "${FW_DIR}" + +cp "${BIN_PATH}" "${MACOS_DIR}/keeperfx" +chmod +x "${MACOS_DIR}/keeperfx" + +cat > "${APP_DIR}/Contents/Info.plist" < + + + + CFBundleName + ${APP_BASENAME} + CFBundleIdentifier + org.keeperfx.${APP_BASENAME} + CFBundleVersion + 1.0 + CFBundleShortVersionString + 1.0 + CFBundleExecutable + keeperfx + CFBundlePackageType + APPL + LSMinimumSystemVersion + 12.0 + + +EOF + +install_name_tool -add_rpath "@executable_path/../Frameworks" "${MACOS_DIR}/keeperfx" 2>/dev/null || true + +declare -a queue +queue=("${MACOS_DIR}/keeperfx") + +seen_file=$(mktemp) +trap 'rm -f "${seen_file}"' EXIT + +while [ ${#queue[@]} -gt 0 ]; do + file="${queue[0]}" + queue=("${queue[@]:1}") + + if grep -Fxq "${file}" "${seen_file}"; then + continue + fi + echo "${file}" >> "${seen_file}" + + deps=$(otool -L "${file}" | tail -n +2 | awk '{print $1}') + for dep in ${deps}; do + case "${dep}" in + /opt/homebrew/*|/usr/local/*) + libname=$(basename "${dep}") + target="${FW_DIR}/${libname}" + if [ ! -f "${target}" ]; then + cp "${dep}" "${target}" + chmod 644 "${target}" || true + queue+=("${target}") + fi + if [ "${file}" = "${MACOS_DIR}/keeperfx" ]; then + install_name_tool -change "${dep}" "@rpath/${libname}" "${file}" || true + else + install_name_tool -change "${dep}" "@loader_path/../Frameworks/${libname}" "${file}" || true + fi + ;; + esac + done + +done + +for dylib in "${FW_DIR}"/*.dylib; do + if [ -f "${dylib}" ]; then + libname=$(basename "${dylib}") + install_name_tool -id "@rpath/${libname}" "${dylib}" || true + install_name_tool -add_rpath "@loader_path/../Frameworks" "${dylib}" 2>/dev/null || true + fi +done + +echo "App bundle created at ${APP_DIR}"