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
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
```
## 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
```
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
CXX := g++
CXX ?= g++
AR := ar
FORMAT := clang-format-11
@ -31,7 +31,7 @@ ifneq ($(LTO),0)
CXXFLAGS += -flto
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))
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
@ -69,4 +69,4 @@ build/%.o: %.cpp
$(LIB): $(O_FILES)
$(AR) rcs $@ $^
-include $(D_FILES)
-include $(D_FILES)

View File

@ -100,7 +100,7 @@ static int FillWritableHandle(
pFileEntry->dwFlags = dwFlags | MPQ_FILE_EXISTS;
// 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);
md5_init((hash_state *)hf->hctx);
pFileEntry->dwCrc32 = crc32(0, Z_NULL, 0);

View File

@ -7,12 +7,13 @@ DEBUG ?= 0
COPYCHECK_ARGS ?=
LLD ?= 0
WERROR ?= 0
UNAME := $(shell uname)
# Use clang++ if available, else use g++
ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0)
CXX := clang++
CXX ?= clang++
else
CXX := g++
CXX ?= g++
endif
INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils
@ -44,8 +45,15 @@ ifneq ($(DEPRECATION_ON),0)
endif
# CXXFLAGS += -DTEXTURE_DEBUG
LDFLAGS := -lm -ldl -lpng \
-L../StormLib/build -L../libultraship -lz -lbz2 -pthread -lpulse -lultraship -lstorm -lSDL2 -lGLEW -lGL -lX11
LDFLAGS := -lm -ldl \
-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
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
@ -56,21 +64,12 @@ ifneq ($(LLD),0)
LDFLAGS += -fuse-ld=lld
endif
UNAME := $(shell uname)
UNAMEM := $(shell uname -m)
ifneq ($(UNAME), Darwin)
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive
else
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

View File

@ -4,7 +4,7 @@
#include "Utils/Directory.h"
#include "yaz0/yaz0.h"
#ifndef _MSC_VER
#ifdef __linux__
#include <byteswap.h>
#endif
#include <Globals.h>
@ -17,6 +17,10 @@ namespace fs = std::filesystem;
#define __bswap_32 _byteswap_ulong
#define bswap_32 _byteswap_ulong
#endif
#if defined __APPLE__
#define __bswap32 __builtin_bswap32
#define bswap32 __builtin_bswap32
#endif
// ROM DMA Table Start
#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
CXX ?= g++
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))
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))

View File

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

View File

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

View File

@ -8,20 +8,20 @@ namespace Ship
ResourceFile::ParseFileBinary(reader, res);
int seqDataSize = reader->ReadInt32();
uint32_t seqDataSize = reader->ReadInt32();
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->seqNumber = reader->ReadUByte();
seq->medium = 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());
}
@ -36,26 +36,26 @@ namespace Ship
entry->unk_bit26 = 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->loop.start = reader->ReadUInt32();
entry->loop.end = 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->book.order = 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());
}
@ -72,11 +72,11 @@ namespace Ship
soundFont->data2 = reader->ReadInt16();
soundFont->data3 = reader->ReadInt16();
int drumCnt = reader->ReadInt32();
int instrumentCnt = reader->ReadInt32();
int sfxCnt = reader->ReadInt32();
uint32_t drumCnt = reader->ReadInt32();
uint32_t instrumentCnt = reader->ReadInt32();
uint32_t sfxCnt = reader->ReadInt32();
for (int i = 0; i < drumCnt; i++)
for (uint32_t i = 0; i < drumCnt; i++)
{
DrumEntry drum;
drum.releaseRate = reader->ReadUByte();
@ -92,7 +92,7 @@ namespace Ship
soundFont->drums.push_back(drum);
}
for (int i = 0; i < instrumentCnt; i++)
for (uint32_t i = 0; i < instrumentCnt; i++)
{
InstrumentEntry entry;
@ -143,7 +143,7 @@ namespace Ship
soundFont->instruments.push_back(entry);
}
for (int i = 0; i < sfxCnt; i++)
for (uint32_t i = 0; i < sfxCnt; i++)
{
SoundFontEntry* entry = new SoundFontEntry();
@ -164,9 +164,9 @@ namespace Ship
{
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();
env->delay = reader->ReadInt16();

View File

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

View File

@ -27,6 +27,9 @@
#include "SDL.h"
#define GL_GLEXT_PROTOTYPES 1
#include "SDL_opengl.h"
#elif __APPLE__
#include <SDL.h>
#include <GL/glew.h>
#else
#include <SDL2/SDL.h>
#include <GL/glew.h>
@ -67,6 +70,9 @@ struct Framebuffer {
static map<pair<uint64_t, uint32_t>, struct ShaderProgram> shader_program_pool;
static GLuint opengl_vbo;
#ifdef __APPLE__
static GLuint opengl_vao;
#endif
static bool current_depth_mask;
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;
// 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, "attribute vec4 aVtxPos;");
#endif
for (int i = 0; i < 2; 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, "varying vec2 vTexCoord%d;\n", i);
#endif
num_floats += 2;
for (int j = 0; j < 2; 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, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i);
#endif
num_floats += 1;
}
}
}
}
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, "varying vec4 vFog;");
#endif
num_floats += 4;
}
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, "varying vec4 vGrayscaleColor;");
#endif
num_floats += 4;
}
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, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1);
#endif
num_floats += cc_features.opt_alpha ? 4 : 3;
}
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, "}");
// 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;");
for (int i = 0; i < 2; 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);
#endif
for (int j = 0; j < 2; 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);
#endif
}
}
}
}
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;");
#endif
}
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;");
#endif
}
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);
#endif
}
if (cc_features.used_textures[0]) {
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 __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)");
#endif
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, " 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, "}");
} else {
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);");
#endif
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() {");
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) {
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;");
#endif
} 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);");
#endif
}
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);
glBindTexture(GL_TEXTURE_2D, texture_id);
}
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);
}
@ -636,6 +715,11 @@ static void gfx_opengl_init(void) {
glGenBuffers(1, &opengl_vbo);
glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo);
#ifdef __APPLE__
glGenVertexArrays(1, &opengl_vao);
glBindVertexArray(opengl_vao);
#endif
glEnable(GL_DEPTH_CLAMP);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

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

View File

@ -13,6 +13,8 @@
#include "SDL.h"
#define GL_GLEXT_PROTOTYPES 1
#include "SDL_opengl.h"
#elif __APPLE__
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#define GL_GLEXT_PROTOTYPES 1
@ -119,7 +121,7 @@ static void set_fullscreen(bool on, bool call_callback) {
}
static uint64_t previous_time;
#ifndef __linux__
#ifdef _WIN32
static HANDLE timer;
#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_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);
#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 left = next - t;
if (left > 0) {
#ifdef __linux__
#if defined __linux__ || defined __APPLE__
const timespec spec = { 0, left * 100 };
nanosleep(&spec, nullptr);
#else

View File

@ -66,11 +66,15 @@
// SDL
// (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_syswm.h>
#include <SDL2/SDL_stdinc.h>
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#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)
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
#if SDL_HAS_VULKAN
#if defined(__APPLE__)
#include "SDL_vulkan.h"
#else
#include <SDL2/SDL_vulkan.h>
#endif
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;

View File

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

View File

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

View File

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

View File

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

9
soh/.gitignore vendored
View File

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

View File

@ -1,9 +1,11 @@
CXX := g++
CC := gcc
CXX ?= g++
CC ?= gcc
LD := lld
AR := ar
FORMAT := clang-format-11
ZAPD := ../ZAPDTR/ZAPD.out
UNAME := $(shell uname)
UNAMEM := $(shell uname -m)
LIBULTRASHIP := ../libultraship/libultraship.a
ZAPDUTILS := ../ZAPDTR/ZAPDUtils/ZAPDUtils.a
@ -17,11 +19,22 @@ LTO ?= 0
WARN := \
-Wno-return-type \
-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
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -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
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
ifneq ($(DEBUG),0)
@ -41,7 +54,13 @@ ifneq ($(LTO),0)
LDFLAGS += -flto
endif
ifeq ($(UNAME), Linux) #LINUX
TARGET := soh.elf
endif
ifeq ($(UNAME), Darwin) #APPLE
TARGET := soh-$(UNAMEM)
endif
INC_DIRS := $(addprefix -I, \
. \
@ -56,26 +75,52 @@ INC_DIRS := $(addprefix -I, \
../libultraship/libultraship/Lib/Fast3D/U64/PR \
)
ifeq ($(UNAME), Linux) #LINUX
INC_DIRS += $(addprefix -I, \
/opt/X11/include \
)
endif
LDDIRS := $(addprefix -L, \
../libultraship/ \
)
ifeq ($(UNAME), Linux) #LINUX
LDDIRS += $(addprefix -L, \
/opt/X11/lib \
)
endif
LDLIBS := \
$(ZAPDUTILS) \
$(LIBSTORM) \
$(addprefix -l, \
X11 \
dl \
bz2 \
z \
pthread \
atomic \
ultraship \
)
ifeq ($(UNAME), Linux) #LINUX
LDLIBS += \
$(addprefix -l, \
X11 \
SDL2 \
GL \
GLEW \
pulse\
ultraship \
pulse \
)
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_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml))
@ -114,6 +159,14 @@ O_FILES := \
$(CXX_FILES:%.cpp=build/%.o)
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
SRC_DIRS := $(shell find . -type d -a -not -path "*build*")
$(shell mkdir -p $(SRC_DIRS:%=build/%))
@ -157,4 +210,39 @@ $(TARGET): $(LIBULTRASHIP)
$(TARGET): $(O_FILES)
$(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_80001F8C(void);
u32 Locale_IsRegionNative(void);
#ifndef __APPLE__
void __assert(const char* exp, const char* file, s32 line);
#endif
void isPrintfInit(void);
void osSyncPrintfUnused(const char* fmt, ...);
//void osSyncPrintf(const char* fmt, ...);

View File

@ -501,7 +501,7 @@ typedef enum {
/* 0x72 */ GID_BULLET_BAG_50,
/* 0x73 */ GID_SWORD_KOKIRI,
/* 0x74 */ GID_SKULL_TOKEN_2,
/* 0x75 */ GID_MAX
/* 0x75 */ GID_MAXIMUM
} GetItemDrawID;
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 <Utils/StringHelper.h>
#ifdef __APPLE__
#include <SDL_scancode.h>
#else
#include <SDL2/SDL_scancode.h>
#endif
#include <Audio.h>
OTRGlobals* OTRGlobals::Instance;

View File

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

View File

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