Add Support for macOS (#441)

* Fixed soh filters

* add more makefile changes

* almost ready

* more updates

* update

* update

* Update Makefiles to handle both platforms

* Allow for overriding the CXX and CC executables

* Restore original structure while supporting custom CXX flags

* Remove some platform specific libs

* Dynamic target name

* Make X11 paths package-agnostic

* Remove changes to `gfx_opengl.cpp`

* Use OpenGL2 on MacOS instead of OpenGL3

* make it actually render something

* render at least the first texture, still need to figure out the second
one

* Let’s use OpenGL 3 again

* maybe this works to get the right texture? link's eyes still look off a bit

* did this work?

* set the platform to macos

* actual numbers are right, but logic is ugly XXX/TODO, i know

* add zlib to ldflags for ZAPDUtils

* A bit of cleanup

* Revert unneeded changes

* Remove GL_CHECK

* Fix issues with z64 branch

* use an std::map instead of a giant array

* three point filter fix (#2)

* Fix mac compilation

* fix audio for 64 bit

* revert audio heap size, keep bigger pools

* Add more Apple specific checks to our modifications

* Add building instructions for macOS

* Remove unecessary step from building instructions

* Add missing SDL2 & GLEW to Linux LDLIBS

* Update BUILDING.md

Co-authored-by: BountyChocolate123456 <101743444+BountyChocolate123456@users.noreply.github.com>

* Update soh/.gitignore to include other arch binaries

Co-authored-by: BountyChocolate123456 <101743444+BountyChocolate123456@users.noreply.github.com>

* Use right platform name for debugging window

Co-authored-by: BountyChocolate123456 <101743444+BountyChocolate123456@users.noreply.github.com>

* Fix stormlib on macos (arm64)

* Simplify some of the ifdef checks

* Revert an older no longer necessary fix

* Remove remaining unecessary deviations

* Update building instructions after StormLib changes

* Feature: Use OpenGL 4.1 (#1)

* Further tweak the BUILDING

* Tidy up

* reword -j message

* Add Jenkins CI Support (#2)

* Fix type issues

* add target <appbundle> and <filledappbundle>

add makefile targets to create an .app
`filledappbundle` creates the target with the .otr included

this should perhaps be moved to Application Support though

* pull gcc's rpath from otool output

* move make target to the end so it's not default

* Add Jenkins and make exe in par with other platforms

* Actually save build artefacts

* Fix artefact path

* Remove x11 mentions and linking (not used)

* Update building instructions for generating app

* use appsupport directory

* Add new app icon

* Update target to match macOS types

* Update more audio types

* fix null deref in Audio_PlayFanfare

* Remove old import from z64

* address final nit with apple ifdefs

Co-authored-by: KiritoDev <36680385+KiritoDv@users.noreply.github.com>
Co-authored-by: Jeffrey Crowell <github@crowell.biz>
Co-authored-by: BountyChocolate123456 <101743444+BountyChocolate123456@users.noreply.github.com>
This commit is contained in:
David Chavez 2022-06-22 20:59:21 +02:00 committed by GitHub
parent 77e7080a8c
commit e42b18cf71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 441 additions and 69 deletions

7
.gitignore vendored
View File

@ -399,4 +399,9 @@ ZAPDUtils/build/
ZAPD/BuildInfo.h ZAPD/BuildInfo.h
DebugObj/* DebugObj/*
ReleaseObj/* ReleaseObj/*
.tags
tags
oot.otr
oot_save.sav
shipofharkinian.ini

View File

@ -46,6 +46,27 @@ make setup -j$(nproc) OPTFLAGS=-O2 DEBUG=0
make -j $(nproc) OPTFLAGS=-O2 DEBUG=0 make -j $(nproc) OPTFLAGS=-O2 DEBUG=0
``` ```
## macOS
1. Requires `gcc@12, sdl2, libpng, glew, dylibbundler` (can be installed via brew, etc)
```bash
# Clone the repo
git clone https://github.com/HarbourMasters/Shipwright.git
cd ShipWright
# Copy the baserom to the OTRExporter folder
cp <path to your ROM> OTRExporter
cd soh
# Extract the assets/Compile the exporter/Run the exporter
# -jX defines number of cores to use for compilation - lower or remove entirely if having issues
make setup -j8 DEBUG=0 CC=gcc-12 CXX=g++-12
# Compile the code (watch the -j parameter as above)
make -j8 DEBUG=0 CC=gcc-12 CXX=g++-12
# Create macOS app bundle
make filledappbundle
```
9. Launch soh app in the soh folder!
# Compatible Roms # Compatible Roms
``` ```
OOT_PAL_GC checksum 0x09465AC3 OOT_PAL_GC checksum 0x09465AC3

34
Jenkinsfile vendored
View File

@ -122,5 +122,39 @@ pipeline {
} }
} }
} }
stage ('Build macOS') {
agent {
label "SoH-Mac-Builders"
}
steps {
checkout([
$class: 'GitSCM',
branches: scm.branches,
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
extensions: scm.extensions,
userRemoteConfigs: scm.userRemoteConfigs
])
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh '''
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
cd soh
make setup -j4 DEBUG=0 CC=gcc-12 CXX=g++-12
make -j4 DEBUG=0 CC=gcc-12 CXX=g++-12
make -j4 appbundle
mv ../README.md readme.txt
7z a soh-mac.7z soh.app readme.txt
'''
}
archiveArtifacts artifacts: 'soh/soh-mac.7z', followSymlinks: false, onlyIfSuccessful: true
}
post {
always {
step([$class: 'WsCleanup']) // Clean workspace
}
}
}
} }
} }

View File

@ -1,6 +1,6 @@
# Only used for standalone compilation, usually inherits these from the main makefile # Only used for standalone compilation, usually inherits these from the main makefile
CXX := g++ CXX ?= g++
AR := ar AR := ar
FORMAT := clang-format-11 FORMAT := clang-format-11
@ -31,7 +31,7 @@ ifneq ($(LTO),0)
CXXFLAGS += -flto CXXFLAGS += -flto
endif endif
SRC_DIRS := $(shell find -type d -not -path "*build*") SRC_DIRS := $(shell find . -type d -not -path "*build*")
CXX_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) CXX_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
@ -69,4 +69,4 @@ build/%.o: %.cpp
$(LIB): $(O_FILES) $(LIB): $(O_FILES)
$(AR) rcs $@ $^ $(AR) rcs $@ $^
-include $(D_FILES) -include $(D_FILES)

View File

@ -100,7 +100,7 @@ static int FillWritableHandle(
pFileEntry->dwFlags = dwFlags | MPQ_FILE_EXISTS; pFileEntry->dwFlags = dwFlags | MPQ_FILE_EXISTS;
// Initialize the file time, CRC32 and MD5 // Initialize the file time, CRC32 and MD5
assert(sizeof(hf->hctx) >= sizeof(hash_state)); //assert(sizeof(hf->hctx) >= sizeof(hash_state));
memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE); memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE);
md5_init((hash_state *)hf->hctx); md5_init((hash_state *)hf->hctx);
pFileEntry->dwCrc32 = crc32(0, Z_NULL, 0); pFileEntry->dwCrc32 = crc32(0, Z_NULL, 0);

View File

@ -7,12 +7,13 @@ DEBUG ?= 0
COPYCHECK_ARGS ?= COPYCHECK_ARGS ?=
LLD ?= 0 LLD ?= 0
WERROR ?= 0 WERROR ?= 0
UNAME := $(shell uname)
# Use clang++ if available, else use g++ # Use clang++ if available, else use g++
ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0) ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0)
CXX := clang++ CXX ?= clang++
else else
CXX := g++ CXX ?= g++
endif endif
INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils
@ -44,8 +45,15 @@ ifneq ($(DEPRECATION_ON),0)
endif endif
# CXXFLAGS += -DTEXTURE_DEBUG # CXXFLAGS += -DTEXTURE_DEBUG
LDFLAGS := -lm -ldl -lpng \ LDFLAGS := -lm -ldl \
-L../StormLib/build -L../libultraship -lz -lbz2 -pthread -lpulse -lultraship -lstorm -lSDL2 -lGLEW -lGL -lX11 -L../StormLib/build -L../libultraship -lbz2 -pthread -lultraship -lstorm
ifeq ($(UNAME), Darwin)
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL
INC += $(shell pkg-config --cflags libpng)
else
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
endif
# Use LLD if available. Set LLD=0 to not use it # Use LLD if available. Set LLD=0 to not use it
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0) ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
@ -56,21 +64,12 @@ ifneq ($(LLD),0)
LDFLAGS += -fuse-ld=lld LDFLAGS += -fuse-ld=lld
endif endif
UNAME := $(shell uname)
UNAMEM := $(shell uname -m) UNAMEM := $(shell uname -m)
ifneq ($(UNAME), Darwin) ifneq ($(UNAME), Darwin)
LDFLAGS += -Wl,-export-dynamic -lstdc++fs LDFLAGS += -Wl,-export-dynamic -lstdc++fs
EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive
else else
EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a
ifeq ($(UNAMEM),arm64)
ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0)
LDFLAGS += -L $(shell brew --prefix)/lib
INC += -I $(shell brew --prefix)/include
else
$(error Please install libpng via Homebrew)
endif
endif
endif endif

View File

@ -4,7 +4,7 @@
#include "Utils/Directory.h" #include "Utils/Directory.h"
#include "yaz0/yaz0.h" #include "yaz0/yaz0.h"
#ifndef _MSC_VER #ifdef __linux__
#include <byteswap.h> #include <byteswap.h>
#endif #endif
#include <Globals.h> #include <Globals.h>
@ -17,6 +17,10 @@ namespace fs = std::filesystem;
#define __bswap_32 _byteswap_ulong #define __bswap_32 _byteswap_ulong
#define bswap_32 _byteswap_ulong #define bswap_32 _byteswap_ulong
#endif #endif
#if defined __APPLE__
#define __bswap32 __builtin_bswap32
#define bswap32 __builtin_bswap32
#endif
// ROM DMA Table Start // ROM DMA Table Start
#define OOT_OFF_NTSC_10_RC 0x7430 #define OOT_OFF_NTSC_10_RC 0x7430

View File

@ -1,7 +1,8 @@
# Only used for standalone compilation, usually inherits these from the main makefile # Only used for standalone compilation, usually inherits these from the main makefile
CXX ?= g++
CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17 CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17
SRC_DIRS := $(shell find -type d -not -path "*build*") SRC_DIRS := $(shell find . -type d -not -path "*build*")
CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))

View File

@ -1,3 +1,4 @@
CC ?= gcc
CFLAGS = -Wall -O2 -g CFLAGS = -Wall -O2 -g
UC_OBJ = uc_f3d.o uc_f3db.o uc_f3dex.o uc_f3dexb.o uc_f3dex2.o UC_OBJ = uc_f3d.o uc_f3db.o uc_f3dex.o uc_f3dexb.o uc_f3dex2.o
OBJ = gfxd.o $(UC_OBJ) OBJ = gfxd.o $(UC_OBJ)

View File

@ -1,9 +1,10 @@
# Only used for standalone compilation, usually inherits these from the main makefile # Only used for standalone compilation, usually inherits these from the main makefile
CXX := g++ CXX ?= g++
CC := gcc CC ?= gcc
AR := ar AR := ar
FORMAT := clang-format-11 FORMAT := clang-format-11
UNAME := $(shell uname)
ASAN ?= 0 ASAN ?= 0
DEBUG ?= 1 DEBUG ?= 1
@ -16,7 +17,8 @@ WARN := -Wall -Wextra -Werror \
-Wno-unused-function \ -Wno-unused-function \
-Wno-parentheses \ -Wno-parentheses \
-Wno-narrowing \ -Wno-narrowing \
-Wno-missing-field-initializers -Wno-missing-field-initializers \
-Wno-error=multichar
CWARN := CWARN :=
CXXWARN := -Wno-deprecated-enum-enum-conversion CXXWARN := -Wno-deprecated-enum-enum-conversion
@ -25,6 +27,10 @@ CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG
CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0 CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
CPPFLAGS := -MMD CPPFLAGS := -MMD
ifeq ($(UNAME), Darwin) #APPLE
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL
endif
ifneq ($(DEBUG),0) ifneq ($(DEBUG),0)
CXXFLAGS += -g -D_DEBUG CXXFLAGS += -g -D_DEBUG
CFLAGS += -g -D_DEBUG CFLAGS += -g -D_DEBUG
@ -40,7 +46,7 @@ ifneq ($(LTO),0)
CFLAGS += -flto CFLAGS += -flto
endif endif
SRC_DIRS := $(shell find -type d -not -path "*build*") SRC_DIRS := $(shell find . -type d -not -path "*build*")
CXX_FILES := \ CXX_FILES := \
$(shell find libultraship/Factories -name "*.cpp") \ $(shell find libultraship/Factories -name "*.cpp") \
@ -71,6 +77,7 @@ INC_DIRS := $(addprefix -I, \
libultraship/Lib/Fast3D/U64 \ libultraship/Lib/Fast3D/U64 \
libultraship/Lib/spdlog \ libultraship/Lib/spdlog \
libultraship/Lib/spdlog/include \ libultraship/Lib/spdlog/include \
libultraship/Lib/ImGui \
libultraship \ libultraship \
../StormLib/src \ ../StormLib/src \
) )
@ -97,4 +104,4 @@ build/%.o: %.c
$(LIB): $(O_FILES) $(LIB): $(O_FILES)
$(AR) rcs $@ $^ $(AR) rcs $@ $^
-include $(D_FILES) -include $(D_FILES)

View File

@ -8,20 +8,20 @@ namespace Ship
ResourceFile::ParseFileBinary(reader, res); ResourceFile::ParseFileBinary(reader, res);
int seqDataSize = reader->ReadInt32(); uint32_t seqDataSize = reader->ReadInt32();
seq->seqData.reserve(seqDataSize); seq->seqData.reserve(seqDataSize);
for (int i = 0; i < seqDataSize; i++) for (uint32_t i = 0; i < seqDataSize; i++)
seq->seqData.push_back(reader->ReadUByte()); seq->seqData.push_back(reader->ReadUByte());
seq->seqNumber = reader->ReadUByte(); seq->seqNumber = reader->ReadUByte();
seq->medium = reader->ReadUByte(); seq->medium = reader->ReadUByte();
seq->cachePolicy = reader->ReadUByte(); seq->cachePolicy = reader->ReadUByte();
int numFonts = reader->ReadInt32(); uint32_t numFonts = reader->ReadInt32();
for (int i = 0; i < numFonts; i++) for (uint32_t i = 0; i < numFonts; i++)
seq->fonts.push_back(reader->ReadUByte()); seq->fonts.push_back(reader->ReadUByte());
} }
@ -36,26 +36,26 @@ namespace Ship
entry->unk_bit26 = reader->ReadByte(); entry->unk_bit26 = reader->ReadByte();
entry->unk_bit25 = reader->ReadByte(); entry->unk_bit25 = reader->ReadByte();
int dataSize = reader->ReadInt32(); uint32_t dataSize = reader->ReadInt32();
for (int i = 0; i < dataSize; i++) for (uint32_t i = 0; i < dataSize; i++)
entry->data.push_back(reader->ReadUByte()); entry->data.push_back(reader->ReadUByte());
entry->loop.start = reader->ReadUInt32(); entry->loop.start = reader->ReadUInt32();
entry->loop.end = reader->ReadUInt32(); entry->loop.end = reader->ReadUInt32();
entry->loop.count = reader->ReadUInt32(); entry->loop.count = reader->ReadUInt32();
int loopStateCnt = reader->ReadUInt32(); uint32_t loopStateCnt = reader->ReadUInt32();
for (int i = 0; i < loopStateCnt; i++) for (uint32_t i = 0; i < loopStateCnt; i++)
entry->loop.states.push_back(reader->ReadInt16()); entry->loop.states.push_back(reader->ReadInt16());
entry->book.order = reader->ReadInt32(); entry->book.order = reader->ReadInt32();
entry->book.npredictors = reader->ReadInt32(); entry->book.npredictors = reader->ReadInt32();
int bookSize = reader->ReadInt32(); uint32_t bookSize = reader->ReadInt32();
for (int i = 0; i < bookSize; i++) for (uint32_t i = 0; i < bookSize; i++)
entry->book.books.push_back(reader->ReadInt16()); entry->book.books.push_back(reader->ReadInt16());
} }
@ -72,11 +72,11 @@ namespace Ship
soundFont->data2 = reader->ReadInt16(); soundFont->data2 = reader->ReadInt16();
soundFont->data3 = reader->ReadInt16(); soundFont->data3 = reader->ReadInt16();
int drumCnt = reader->ReadInt32(); uint32_t drumCnt = reader->ReadInt32();
int instrumentCnt = reader->ReadInt32(); uint32_t instrumentCnt = reader->ReadInt32();
int sfxCnt = reader->ReadInt32(); uint32_t sfxCnt = reader->ReadInt32();
for (int i = 0; i < drumCnt; i++) for (uint32_t i = 0; i < drumCnt; i++)
{ {
DrumEntry drum; DrumEntry drum;
drum.releaseRate = reader->ReadUByte(); drum.releaseRate = reader->ReadUByte();
@ -92,7 +92,7 @@ namespace Ship
soundFont->drums.push_back(drum); soundFont->drums.push_back(drum);
} }
for (int i = 0; i < instrumentCnt; i++) for (uint32_t i = 0; i < instrumentCnt; i++)
{ {
InstrumentEntry entry; InstrumentEntry entry;
@ -143,7 +143,7 @@ namespace Ship
soundFont->instruments.push_back(entry); soundFont->instruments.push_back(entry);
} }
for (int i = 0; i < sfxCnt; i++) for (uint32_t i = 0; i < sfxCnt; i++)
{ {
SoundFontEntry* entry = new SoundFontEntry(); SoundFontEntry* entry = new SoundFontEntry();
@ -164,9 +164,9 @@ namespace Ship
{ {
std::vector<AdsrEnvelope*> envelopes; std::vector<AdsrEnvelope*> envelopes;
int envelopeCnt = reader->ReadInt32(); uint32_t envelopeCnt = reader->ReadInt32();
for (int i = 0; i < envelopeCnt; i++) for (uint32_t i = 0; i < envelopeCnt; i++)
{ {
AdsrEnvelope* env = new AdsrEnvelope(); AdsrEnvelope* env = new AdsrEnvelope();
env->delay = reader->ReadInt16(); env->delay = reader->ReadInt16();

View File

@ -15,8 +15,8 @@ namespace Ship
struct AdpcmBook struct AdpcmBook
{ {
/* 0x00 */ int32_t order; /* 0x00 */ uint32_t order;
/* 0x04 */ int32_t npredictors; /* 0x04 */ uint32_t npredictors;
/* 0x08 */ std::vector<int16_t> books; // size 8 * order * npredictors. 8-byte aligned /* 0x08 */ std::vector<int16_t> books; // size 8 * order * npredictors. 8-byte aligned
}; };

View File

@ -27,6 +27,9 @@
#include "SDL.h" #include "SDL.h"
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
#include "SDL_opengl.h" #include "SDL_opengl.h"
#elif __APPLE__
#include <SDL.h>
#include <GL/glew.h>
#else #else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <GL/glew.h> #include <GL/glew.h>
@ -67,6 +70,9 @@ struct Framebuffer {
static map<pair<uint64_t, uint32_t>, struct ShaderProgram> shader_program_pool; static map<pair<uint64_t, uint32_t>, struct ShaderProgram> shader_program_pool;
static GLuint opengl_vbo; static GLuint opengl_vbo;
#ifdef __APPLE__
static GLuint opengl_vao;
#endif
static bool current_depth_mask; static bool current_depth_mask;
static uint32_t frame_count; static uint32_t frame_count;
@ -220,37 +226,67 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
size_t num_floats = 4; size_t num_floats = 4;
// Vertex shader // Vertex shader
#ifdef __APPLE__
append_line(vs_buf, &vs_len, "#version 410 core");
append_line(vs_buf, &vs_len, "in vec4 aVtxPos;");
#else
append_line(vs_buf, &vs_len, "#version 110"); append_line(vs_buf, &vs_len, "#version 110");
append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;"); append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;");
#endif
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (cc_features.used_textures[i]) { if (cc_features.used_textures[i]) {
#ifdef __APPLE__
vs_len += sprintf(vs_buf + vs_len, "in vec2 aTexCoord%d;\n", i);
vs_len += sprintf(vs_buf + vs_len, "out vec2 vTexCoord%d;\n", i);
#else
vs_len += sprintf(vs_buf + vs_len, "attribute vec2 aTexCoord%d;\n", i); vs_len += sprintf(vs_buf + vs_len, "attribute vec2 aTexCoord%d;\n", i);
vs_len += sprintf(vs_buf + vs_len, "varying vec2 vTexCoord%d;\n", i); vs_len += sprintf(vs_buf + vs_len, "varying vec2 vTexCoord%d;\n", i);
#endif
num_floats += 2; num_floats += 2;
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (cc_features.clamp[i][j]) { if (cc_features.clamp[i][j]) {
#ifdef __APPLE__
vs_len += sprintf(vs_buf + vs_len, "in float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
vs_len += sprintf(vs_buf + vs_len, "out float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
#else
vs_len += sprintf(vs_buf + vs_len, "attribute float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); vs_len += sprintf(vs_buf + vs_len, "attribute float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
vs_len += sprintf(vs_buf + vs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); vs_len += sprintf(vs_buf + vs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
#endif
num_floats += 1; num_floats += 1;
} }
} }
} }
} }
if (cc_features.opt_fog) { if (cc_features.opt_fog) {
#ifdef __APPLE__
append_line(vs_buf, &vs_len, "in vec4 aFog;");
append_line(vs_buf, &vs_len, "out vec4 vFog;");
#else
append_line(vs_buf, &vs_len, "attribute vec4 aFog;"); append_line(vs_buf, &vs_len, "attribute vec4 aFog;");
append_line(vs_buf, &vs_len, "varying vec4 vFog;"); append_line(vs_buf, &vs_len, "varying vec4 vFog;");
#endif
num_floats += 4; num_floats += 4;
} }
if (cc_features.opt_grayscale) { if (cc_features.opt_grayscale) {
#ifdef __APPLE__
append_line(vs_buf, &vs_len, "in vec4 aGrayscaleColor;");
append_line(vs_buf, &vs_len, "out vec4 vGrayscaleColor;");
#else
append_line(vs_buf, &vs_len, "attribute vec4 aGrayscaleColor;"); append_line(vs_buf, &vs_len, "attribute vec4 aGrayscaleColor;");
append_line(vs_buf, &vs_len, "varying vec4 vGrayscaleColor;"); append_line(vs_buf, &vs_len, "varying vec4 vGrayscaleColor;");
#endif
num_floats += 4; num_floats += 4;
} }
for (int i = 0; i < cc_features.num_inputs; i++) { for (int i = 0; i < cc_features.num_inputs; i++) {
#ifdef __APPLE__
vs_len += sprintf(vs_buf + vs_len, "in vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
vs_len += sprintf(vs_buf + vs_len, "out vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
#else
vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
#endif
num_floats += cc_features.opt_alpha ? 4 : 3; num_floats += cc_features.opt_alpha ? 4 : 3;
} }
append_line(vs_buf, &vs_len, "void main() {"); append_line(vs_buf, &vs_len, "void main() {");
@ -277,26 +313,50 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
append_line(vs_buf, &vs_len, "}"); append_line(vs_buf, &vs_len, "}");
// Fragment shader // Fragment shader
append_line(fs_buf, &fs_len, "#version 130"); #ifdef __APPLE__
append_line(fs_buf, &fs_len, "#version 410 core");
#else
append_line(fs_buf, &fs_len, "#version 120");
#endif
//append_line(fs_buf, &fs_len, "precision mediump float;"); //append_line(fs_buf, &fs_len, "precision mediump float;");
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (cc_features.used_textures[i]) { if (cc_features.used_textures[i]) {
#ifdef __APPLE__
fs_len += sprintf(fs_buf + fs_len, "in vec2 vTexCoord%d;\n", i);
#else
fs_len += sprintf(fs_buf + fs_len, "varying vec2 vTexCoord%d;\n", i); fs_len += sprintf(fs_buf + fs_len, "varying vec2 vTexCoord%d;\n", i);
#endif
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (cc_features.clamp[i][j]) { if (cc_features.clamp[i][j]) {
#ifdef __APPLE__
fs_len += sprintf(fs_buf + fs_len, "in float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
#else
fs_len += sprintf(fs_buf + fs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); fs_len += sprintf(fs_buf + fs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
#endif
} }
} }
} }
} }
if (cc_features.opt_fog) { if (cc_features.opt_fog) {
#ifdef __APPLE__
append_line(fs_buf, &fs_len, "in vec4 vFog;");
#else
append_line(fs_buf, &fs_len, "varying vec4 vFog;"); append_line(fs_buf, &fs_len, "varying vec4 vFog;");
#endif
} }
if (cc_features.opt_grayscale) { if (cc_features.opt_grayscale) {
#ifdef __APPLE__
append_line(fs_buf, &fs_len, "in vec4 vGrayscaleColor;");
#else
append_line(fs_buf, &fs_len, "varying vec4 vGrayscaleColor;"); append_line(fs_buf, &fs_len, "varying vec4 vGrayscaleColor;");
#endif
} }
for (int i = 0; i < cc_features.num_inputs; i++) { for (int i = 0; i < cc_features.num_inputs; i++) {
#ifdef __APPLE__
fs_len += sprintf(fs_buf + fs_len, "in vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
#else
fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
#endif
} }
if (cc_features.used_textures[0]) { if (cc_features.used_textures[0]) {
append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;");
@ -316,7 +376,11 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
} }
if (current_filter_mode == THREE_POINT) { if (current_filter_mode == THREE_POINT) {
#if __APPLE__
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture(tex, texCoord - (off)/texSize)");
#else
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)"); append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
#endif
append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {");
append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));"); append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));");
append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);"); append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);");
@ -330,10 +394,18 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
append_line(fs_buf, &fs_len, "}"); append_line(fs_buf, &fs_len, "}");
} else { } else {
append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {"); append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {");
#if __APPLE__
append_line(fs_buf, &fs_len, " return texture(tex, uv);");
#else
append_line(fs_buf, &fs_len, " return texture2D(tex, uv);"); append_line(fs_buf, &fs_len, " return texture2D(tex, uv);");
#endif
append_line(fs_buf, &fs_len, "}"); append_line(fs_buf, &fs_len, "}");
} }
#if __APPLE__
append_line(fs_buf, &fs_len, "out vec4 outColor;");
#endif
append_line(fs_buf, &fs_len, "void main() {"); append_line(fs_buf, &fs_len, "void main() {");
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@ -405,9 +477,17 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
if (cc_features.opt_invisible) { if (cc_features.opt_invisible) {
append_line(fs_buf, &fs_len, "texel.a = 0.0;"); append_line(fs_buf, &fs_len, "texel.a = 0.0;");
} }
#if __APPLE__
append_line(fs_buf, &fs_len, "outColor = texel;");
#else
append_line(fs_buf, &fs_len, "gl_FragColor = texel;"); append_line(fs_buf, &fs_len, "gl_FragColor = texel;");
#endif
} else { } else {
#if __APPLE__
append_line(fs_buf, &fs_len, "outColor = vec4(texel, 1.0);");
#else
append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);"); append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);");
#endif
} }
append_line(fs_buf, &fs_len, "}"); append_line(fs_buf, &fs_len, "}");
@ -557,7 +637,6 @@ static void gfx_opengl_select_texture(int tile, GLuint texture_id) {
glActiveTexture(GL_TEXTURE0 + tile); glActiveTexture(GL_TEXTURE0 + tile);
glBindTexture(GL_TEXTURE_2D, texture_id); glBindTexture(GL_TEXTURE_2D, texture_id);
} }
static void gfx_opengl_upload_texture(const uint8_t *rgba32_buf, uint32_t width, uint32_t height) { static void gfx_opengl_upload_texture(const uint8_t *rgba32_buf, uint32_t width, uint32_t height) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf);
} }
@ -636,6 +715,11 @@ static void gfx_opengl_init(void) {
glGenBuffers(1, &opengl_vbo); glGenBuffers(1, &opengl_vbo);
glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo); glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo);
#ifdef __APPLE__
glGenVertexArrays(1, &opengl_vao);
glBindVertexArray(opengl_vao);
#endif
glEnable(GL_DEPTH_CLAMP); glEnable(GL_DEPTH_CLAMP);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -2,6 +2,7 @@
#define GFX_PC_H #define GFX_PC_H
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <unordered_map> #include <unordered_map>
#include <list> #include <list>

View File

@ -13,6 +13,8 @@
#include "SDL.h" #include "SDL.h"
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
#include "SDL_opengl.h" #include "SDL_opengl.h"
#elif __APPLE__
#include <SDL.h>
#else #else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
@ -119,7 +121,7 @@ static void set_fullscreen(bool on, bool call_callback) {
} }
static uint64_t previous_time; static uint64_t previous_time;
#ifndef __linux__ #ifdef _WIN32
static HANDLE timer; static HANDLE timer;
#endif #endif
@ -134,7 +136,14 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) {
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
#ifndef __linux #if defined(__APPLE__)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
#endif
#ifdef _WIN32
timer = CreateWaitableTimer(nullptr, false, nullptr); timer = CreateWaitableTimer(nullptr, false, nullptr);
#endif #endif
@ -271,7 +280,7 @@ static inline void sync_framerate_with_timer(void) {
const int64_t next = previous_time + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR; const int64_t next = previous_time + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR;
const int64_t left = next - t; const int64_t left = next - t;
if (left > 0) { if (left > 0) {
#ifdef __linux__ #if defined __linux__ || defined __APPLE__
const timespec spec = { 0, left * 100 }; const timespec spec = { 0, left * 100 };
nanosleep(&spec, nullptr); nanosleep(&spec, nullptr);
#else #else

View File

@ -66,11 +66,15 @@
// SDL // SDL
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended) // (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
#if defined(__APPLE__)
#include "SDL.h"
#include "SDL_syswm.h"
#include "SDL_stdinc.h"
#include <TargetConditionals.h>
#else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h> #include <SDL2/SDL_syswm.h>
#include <SDL2/SDL_stdinc.h> #include <SDL2/SDL_stdinc.h>
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif #endif
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) #if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS)
@ -865,7 +869,11 @@ static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*)
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface) // Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this. // SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
#if SDL_HAS_VULKAN #if SDL_HAS_VULKAN
#if defined(__APPLE__)
#include "SDL_vulkan.h"
#else
#include <SDL2/SDL_vulkan.h> #include <SDL2/SDL_vulkan.h>
#endif
static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
{ {
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;

View File

@ -1,6 +1,10 @@
#pragma once #pragma once
#include "AudioPlayer.h" #include "AudioPlayer.h"
#if __APPLE__
#include <SDL.h>
#else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#endif
namespace Ship { namespace Ship {
class SDLAudioPlayer : public AudioPlayer { class SDLAudioPlayer : public AudioPlayer {

View File

@ -1,6 +1,10 @@
#pragma once #pragma once
#include "Controller.h" #include "Controller.h"
#if __APPLE__
#include <SDL.h>
#else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#endif
#define INVALID_SDL_CONTROLLER_GUID (std::string("00000000000000000000000000000000")) #define INVALID_SDL_CONTROLLER_GUID (std::string("00000000000000000000000000000000"))

View File

@ -137,7 +137,11 @@ namespace SohImGui {
void ImGuiBackendInit() { void ImGuiBackendInit() {
switch (impl.backend) { switch (impl.backend) {
case Backend::SDL: case Backend::SDL:
#if defined(__APPLE__)
ImGui_ImplOpenGL3_Init("#version 410 core");
#else
ImGui_ImplOpenGL3_Init("#version 120"); ImGui_ImplOpenGL3_Init("#version 120");
#endif
break; break;
#if defined(ENABLE_DX11) || defined(ENABLE_DX12) #if defined(ENABLE_DX11) || defined(ENABLE_DX12)
@ -1327,6 +1331,8 @@ namespace SohImGui {
#ifdef _WIN32 #ifdef _WIN32
ImGui::Text("Platform: Windows"); ImGui::Text("Platform: Windows");
#elif __APPLE__
ImGui::Text("Platform: macOS");
#else #else
ImGui::Text("Platform: Linux"); ImGui::Text("Platform: Linux");
#endif #endif

View File

@ -18,7 +18,11 @@
#include "Lib/Fast3D/gfx_sdl.h" #include "Lib/Fast3D/gfx_sdl.h"
#include "Lib/Fast3D/gfx_opengl.h" #include "Lib/Fast3D/gfx_opengl.h"
#include "stox.h" #include "stox.h"
#if __APPLE__
#include <SDL.h>
#else
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#endif
#include <map> #include <map>
#include <string> #include <string>
#include <chrono> #include <chrono>

9
soh/.gitignore vendored
View File

@ -18,12 +18,16 @@ notes/
baserom/ baserom/
docs/doxygen/ docs/doxygen/
*.elf *.elf
*-arm64
*-x86_64
*.sra *.sra
*.z64 *.z64
*.n64 *.n64
*.v64 *.v64
*.map *.map
*.dump *.dump
*.app/
*.icns
out.txt out.txt
shipofharkinian.ini shipofharkinian.ini
imgui.ini imgui.ini
@ -404,4 +408,7 @@ ZAPD/BuildInfo.h
cvars.cfg cvars.cfg
DebugObj/* DebugObj/*
ReleaseObj/* ReleaseObj/*
# Junk from App Bundle
appsupport

View File

@ -1,9 +1,11 @@
CXX := g++ CXX ?= g++
CC := gcc CC ?= gcc
LD := lld LD := lld
AR := ar AR := ar
FORMAT := clang-format-11 FORMAT := clang-format-11
ZAPD := ../ZAPDTR/ZAPD.out ZAPD := ../ZAPDTR/ZAPD.out
UNAME := $(shell uname)
UNAMEM := $(shell uname -m)
LIBULTRASHIP := ../libultraship/libultraship.a LIBULTRASHIP := ../libultraship/libultraship.a
ZAPDUTILS := ../ZAPDTR/ZAPDUtils/ZAPDUtils.a ZAPDUTILS := ../ZAPDTR/ZAPDUtils/ZAPDUtils.a
@ -17,11 +19,22 @@ LTO ?= 0
WARN := \ WARN := \
-Wno-return-type \ -Wno-return-type \
-funsigned-char \ -funsigned-char \
-mhard-float -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -fno-toplevel-reorder -ffreestanding -fwrapv \ -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -fno-toplevel-reorder -ffreestanding -fwrapv \
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib -msse2 -mfpmath=sse CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib -msse2 -mfpmath=sse CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib
LDFLAGS := LDFLAGS :=
ifeq ($(UNAME), Linux) #LINUX
CXXFLAGS += -mhard-float -msse2 -mfpmath=sse
CFLAGS += -mhard-float -msse2 -mfpmath=sse
endif
ifeq ($(UNAME), Darwin) #APPLE
CXXFLAGS += $(shell pkg-config --cflags sdl2) $(shell sdl2-config --cflags) $(shell pkg-config --cflags glew) -framework OpenGL
CFLAGS += $(shell pkg-config --cflags sdl2) $(shell sdl2-config --cflags) $(shell pkg-config --cflags glew) -framework OpenGL
endif
CPPFLAGS := -MMD CPPFLAGS := -MMD
ifneq ($(DEBUG),0) ifneq ($(DEBUG),0)
@ -41,7 +54,13 @@ ifneq ($(LTO),0)
LDFLAGS += -flto LDFLAGS += -flto
endif endif
ifeq ($(UNAME), Linux) #LINUX
TARGET := soh.elf TARGET := soh.elf
endif
ifeq ($(UNAME), Darwin) #APPLE
TARGET := soh-$(UNAMEM)
endif
INC_DIRS := $(addprefix -I, \ INC_DIRS := $(addprefix -I, \
. \ . \
@ -56,26 +75,52 @@ INC_DIRS := $(addprefix -I, \
../libultraship/libultraship/Lib/Fast3D/U64/PR \ ../libultraship/libultraship/Lib/Fast3D/U64/PR \
) )
ifeq ($(UNAME), Linux) #LINUX
INC_DIRS += $(addprefix -I, \
/opt/X11/include \
)
endif
LDDIRS := $(addprefix -L, \ LDDIRS := $(addprefix -L, \
../libultraship/ \ ../libultraship/ \
) )
ifeq ($(UNAME), Linux) #LINUX
LDDIRS += $(addprefix -L, \
/opt/X11/lib \
)
endif
LDLIBS := \ LDLIBS := \
$(ZAPDUTILS) \ $(ZAPDUTILS) \
$(LIBSTORM) \ $(LIBSTORM) \
$(addprefix -l, \ $(addprefix -l, \
X11 \
dl \ dl \
bz2 \ bz2 \
z \ z \
pthread \ pthread \
atomic \ atomic \
ultraship \
)
ifeq ($(UNAME), Linux) #LINUX
LDLIBS += \
$(addprefix -l, \
X11 \
SDL2 \ SDL2 \
GL \ GL \
GLEW \ GLEW \
pulse\ pulse \
ultraship \ )
endif
ifeq ($(UNAME), Darwin) #APPLE
LDLIBS += \
$(addprefix -framework, \
OpenGL \
) \ ) \
$(shell sdl2-config --libs) $(shell pkg-config --libs glew)
endif
ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*") ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*")
ASSET_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml)) ASSET_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml))
@ -114,6 +159,14 @@ O_FILES := \
$(CXX_FILES:%.cpp=build/%.o) $(CXX_FILES:%.cpp=build/%.o)
D_FILES := $(O_FILES:%.o=%.d) D_FILES := $(O_FILES:%.o=%.d)
# Apple App Bundle
APPNAME=soh
APPBUNDLE=$(APPNAME).app
APPBUNDLECONTENTS=$(APPBUNDLE)/Contents
APPBUNDLEEXE=$(APPBUNDLECONTENTS)/MacOS
APPBUNDLERESOURCES=$(APPBUNDLECONTENTS)/Resources
APPBUNDLEICON=$(APPBUNDLECONTENTS)/Resources
# create build directory # create build directory
SRC_DIRS := $(shell find . -type d -a -not -path "*build*") SRC_DIRS := $(shell find . -type d -a -not -path "*build*")
$(shell mkdir -p $(SRC_DIRS:%=build/%)) $(shell mkdir -p $(SRC_DIRS:%=build/%))
@ -157,4 +210,39 @@ $(TARGET): $(LIBULTRASHIP)
$(TARGET): $(O_FILES) $(TARGET): $(O_FILES)
$(CXX) $^ -o $@ $(LDFLAGS) -fuse-ld=$(LD) $(LDDIRS) $(LDLIBS) $(CXX) $^ -o $@ $(LDFLAGS) -fuse-ld=$(LD) $(LDDIRS) $(LDLIBS)
-include $(D_FILES) -include $(D_FILES)
appbundle: macosx/$(APPNAME).icns
rm -rf $(APPBUNDLE)
mkdir $(APPBUNDLE)
mkdir $(APPBUNDLE)/Contents
mkdir $(APPBUNDLE)/Contents/MacOS
mkdir $(APPBUNDLE)/Contents/Resources
cp macosx/Info.plist $(APPBUNDLECONTENTS)/
cp macosx/PkgInfo $(APPBUNDLECONTENTS)/
cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/
cp $(TARGET) $(APPBUNDLEEXE)/soh
cp macosx/launcher.sh $(APPBUNDLEEXE)/launcher.sh
clang -ObjC macosx/appsupport.m -arch arm64 -arch x86_64 -framework Foundation -o macosx/appsupport
cp macosx/appsupport $(APPBUNDLEEXE)/appsupport
otool -l $(TARGET) | grep -A 2 LC_RPATH | tail -n 1 | awk '{print $2}' | dylibbundler -od -b -x $(APPBUNDLEEXE)/soh -d $(APPBUNDLECONTENTS)/libs
macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png
rm -rf macosx/$(APPNAME).iconset
mkdir macosx/$(APPNAME).iconset
sips -z 16 16 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_16x16.png
sips -z 32 32 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_16x16@2x.png
sips -z 32 32 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_32x32.png
sips -z 64 64 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_32x32@2x.png
sips -z 128 128 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_128x128.png
sips -z 256 256 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_128x128@2x.png
sips -z 256 256 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_256x256.png
sips -z 512 512 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_256x256@2x.png
sips -z 512 512 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_512x512.png
cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png
iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset
rm -r macosx/$(APPNAME).iconset
filledappbundle: appbundle
cp ./oot.otr $(APPBUNDLEEXE)/oot.otr

View File

@ -60,7 +60,9 @@ void Locale_ResetRegion(void);
u32 func_80001F48(void); u32 func_80001F48(void);
u32 func_80001F8C(void); u32 func_80001F8C(void);
u32 Locale_IsRegionNative(void); u32 Locale_IsRegionNative(void);
#ifndef __APPLE__
void __assert(const char* exp, const char* file, s32 line); void __assert(const char* exp, const char* file, s32 line);
#endif
void isPrintfInit(void); void isPrintfInit(void);
void osSyncPrintfUnused(const char* fmt, ...); void osSyncPrintfUnused(const char* fmt, ...);
//void osSyncPrintf(const char* fmt, ...); //void osSyncPrintf(const char* fmt, ...);

View File

@ -501,7 +501,7 @@ typedef enum {
/* 0x72 */ GID_BULLET_BAG_50, /* 0x72 */ GID_BULLET_BAG_50,
/* 0x73 */ GID_SWORD_KOKIRI, /* 0x73 */ GID_SWORD_KOKIRI,
/* 0x74 */ GID_SKULL_TOKEN_2, /* 0x74 */ GID_SKULL_TOKEN_2,
/* 0x75 */ GID_MAX /* 0x75 */ GID_MAXIMUM
} GetItemDrawID; } GetItemDrawID;
typedef enum { typedef enum {

35
soh/macosx/Info.plist Normal file
View File

@ -0,0 +1,35 @@
<?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>CFBundleName</key>
<string>Ship of Harkinian</string>
<key>CFBundleExecutable</key>
<string>launcher.sh</string>
<key>CFBundleGetInfoString</key>
<string>2.0.0</string>
<key>CFBundleIconFile</key>
<string>soh.icns</string>
<key>CFBundleIdentifier</key>
<string>com.shipofharkinian.ShipOfHarkinian</string>
<key>CFBundleDocumentTypes</key>
<array>
</array>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.0.0</string>
<key>CFBundleSignature</key>
<string>ZOoT</string>
<key>CFBundleVersion</key>
<string>2.0.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright 2022 HarbourMasters.</string>
<key>LSMinimumSystemVersion</key>
<string>10.3</string>
</dict>
</plist>

1
soh/macosx/PkgInfo Normal file
View File

@ -0,0 +1 @@
APPLZOoT

26
soh/macosx/appsupport.m Normal file
View File

@ -0,0 +1,26 @@
#import <Foundation/Foundation.h>
int main(void) {
NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject];
//If there isn't an App Support Directory yet ...
if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir isDirectory:NULL]) {
NSError *error = nil;
//Create one
if (![[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:&error]) {
NSLog(@"%@", error.localizedDescription);
}
else {
// *** OPTIONAL *** Mark the directory as excluded from iCloud backups
NSURL *url = [NSURL fileURLWithPath:appSupportDir];
if (![url setResourceValue:@YES
forKey:NSURLIsExcludedFromBackupKey
error:&error])
{
NSLog(@"Error excluding %@ from backup %@", url.lastPathComponent, error.localizedDescription);
}
else {
NSLog(@"Yay");
}
}
}
printf("%s\n", [appSupportDir UTF8String]);
}

9
soh/macosx/launcher.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
APPPATH="${0%/*}"
cd "${APPPATH}"
APPPATH=$(pwd)
APPSUPPORT=$(./appsupport)
mkdir -p "${APPSUPPORT}/com.shipofharkinian.soh"
cd "${APPSUPPORT}/com.shipofharkinian.soh"
cp "${APPPATH}/oot.otr" .
${APPPATH}/soh

BIN
soh/macosx/sohIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

@ -40,7 +40,12 @@
#include "macros.h" #include "macros.h"
#include <Utils/StringHelper.h> #include <Utils/StringHelper.h>
#ifdef __APPLE__
#include <SDL_scancode.h>
#else
#include <SDL2/SDL_scancode.h> #include <SDL2/SDL_scancode.h>
#endif
#include <Audio.h> #include <Audio.h>
OTRGlobals* OTRGlobals::Instance; OTRGlobals* OTRGlobals::Instance;

View File

@ -1,6 +1,8 @@
#include "z64.h" #include "z64.h"
#include <assert.h> #include <assert.h>
#ifndef __APPLE__
#include <malloc.h> #include <malloc.h>
#endif
#ifndef _MSC_VER #ifndef _MSC_VER
#include <unistd.h> #include <unistd.h>

View File

@ -4527,12 +4527,17 @@ void Audio_PlayFanfare(u16 seqId)
sp26 = func_800FA0B4(SEQ_PLAYER_FANFARE); sp26 = func_800FA0B4(SEQ_PLAYER_FANFARE);
sp1C = func_800E5E84(sp26 & 0xFF, &sp20); sp1C = func_800E5E84(sp26 & 0xFF, &sp20);
sp18 = func_800E5E84(seqId & 0xFF, &sp20); sp18 = func_800E5E84(seqId & 0xFF, &sp20);
if ((sp26 == NA_BGM_DISABLED) || (*sp1C == *sp18)) { if (!sp1C || !sp18) {
D_8016B9F4 = 1; // disable BGM, we're about to null deref!
} else { D_8016B9F4 = 1;
D_8016B9F4 = 5; } else {
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0); if ((sp26 == NA_BGM_DISABLED) || (*sp1C == *sp18)) {
} D_8016B9F4 = 1;
} else {
D_8016B9F4 = 5;
Audio_SeqCmd1(SEQ_PLAYER_FANFARE, 0);
}
}
D_8016B9F6 = seqId; D_8016B9F6 = seqId;
} }