Skip to content

Commit

Permalink
Introduce App Directory Path (#572)
Browse files Browse the repository at this point in the history
* Introduce app directory path concept

* macos: Remove hacky way of using applicaiton directory

* Update the new SaveManager

* Address stack user after return

* Remove unecessary property

* Use std::string for filepath

* Improve clang specific detections

* Use new path system for imgui files

* Improve helper for getting relative paths
  • Loading branch information
dcvz authored Jul 13, 2022
1 parent 97ad234 commit 7b04f67
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 70 deletions.
5 changes: 3 additions & 2 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ make setup -j8 DEBUG=0
# Compile the code (watch the -j parameter as above)
make -j8 DEBUG=0
# Create macOS app bundle
make filledappbundle
make appbundle
```
9. Launch soh app in the soh folder!
9. Copy your OTR file to ~/Library/Application\ Support/com.shipofharkinian.soh
10. Launch soh app in the soh folder!

# Compatible Roms
```
Expand Down
2 changes: 1 addition & 1 deletion ZAPDTR/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ 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
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation
INC += $(shell pkg-config --cflags libpng)
else
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
Expand Down
37 changes: 30 additions & 7 deletions libultraship/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

CXX ?= g++
CC ?= gcc
AR := ar
AR := ar
FORMAT := clang-format-11
UNAME := $(shell uname)

Expand All @@ -11,6 +11,15 @@ DEBUG ?= 1
OPTFLAGS ?= -O0
LTO ?= 0

# flag to save whether the compiler being used is clang or gcc by checking CXX --version
CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang)
ifeq ($(CXX_IS_CLANG),1)
MXX := $(CXX)
else
MXX ?= clang++
endif


WARN := -Wall -Wextra -Werror \
-Wno-unused-variable \
-Wno-unused-parameter \
Expand All @@ -29,8 +38,7 @@ WARN := -Wall -Wextra -Werror \
CWARN :=
CXXWARN := -Wno-deprecated-enum-enum-conversion -Wno-deprecated-copy

COMPILER_VERSION := $(shell $(CXX) --version)
ifneq '' '$(findstring g++,$(COMPILER_VERSION))'
ifneq ($(CXX_IS_CLANG),1)
WARN += -Wno-error=stringop-overflow
CXXWARN += -Wno-error=maybe-uninitialized
endif
Expand All @@ -39,12 +47,17 @@ 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
MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc

# if not using clang, ask clang to use gcc standard library
ifneq ($(CXX_IS_CLANG),1)
STD_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | head -n 1)
CXX_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | tail -n 1)
MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM}
endif

ifeq ($(UNAME), Linux)
WARN += -Wno-error=stringop-overflow # This is required with clang on Linux.
ifeq ($(UNAME), Darwin) #APPLE
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation
endif

ifneq ($(DEBUG),0)
Expand Down Expand Up @@ -78,12 +91,19 @@ C_FILES := \
libultraship/mixer.c \
libultraship/Lib/stb/stb_impl.c

MM_FILES := \
libultraship/OSXFolderManager.mm

FMT_FILES := $(shell find libultraship/ -type f \( -name "*.cpp" -o -name "*.h" \) -a -not -path "libultraship/Lib/*")

O_FILES := \
$(CXX_FILES:%.cpp=build/%.o) \
$(C_FILES:%.c=build/%.o)

ifeq ($(UNAME), Darwin) #APPLE
O_FILES += $(MM_FILES:%.mm=build/%.o)
endif

D_FILES := $(O_FILES:%.o=%.d)

LIB := libultraship.a
Expand Down Expand Up @@ -117,6 +137,9 @@ build/%.o: %.cpp
build/%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@

build/%.o: %.mm
$(MXX) $(MMFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@

$(LIB): $(O_FILES)
$(AR) rcs $@ $^

Expand Down
4 changes: 2 additions & 2 deletions libultraship/libultraship/ConfigFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ namespace Ship {
}

bool ConfigFile::CreateDefaultConfig() {
(*this)["ARCHIVE"]["Main Archive"] = "oot.otr";
(*this)["ARCHIVE"]["Main Archive"] = "";
(*this)["ARCHIVE"]["Patches Directory"] = "";

(*this)["SAVE"]["Save Filename"] = "oot_save.sav";
(*this)["SAVE"]["Save Filename"] = "";

(*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto";
(*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged";
Expand Down
30 changes: 26 additions & 4 deletions libultraship/libultraship/GlobalCtx2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/sohconsole_sink.h"
#include "ModManager.h"
#ifdef __APPLE__
#include "OSXFolderManager.h"
#endif

namespace Ship {
std::weak_ptr<GlobalCtx2> GlobalCtx2::Context;
ModManager* INSTANCE;

std::shared_ptr<GlobalCtx2> GlobalCtx2::GetInstance() {
return Context.lock();
}
Expand All @@ -29,6 +33,22 @@ namespace Ship {
return GetInstance();
}

std::string GlobalCtx2::GetAppDirectoryPath() {
#ifdef __APPLE__
FolderManager folderManager;
std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask));
fpath.append("/com.shipofharkinian.soh");
return fpath;
#endif

return ".";

}

std::string GlobalCtx2::GetPathRelativeToAppDirectory(const char* path) {
return GlobalCtx2::GetAppDirectoryPath() + "/" + path;
}

GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") {

}
Expand All @@ -40,14 +60,14 @@ namespace Ship {

void GlobalCtx2::InitWindow() {
InitLogging();
Config = std::make_shared<ConfigFile>(GlobalCtx2::GetInstance(), "shipofharkinian.ini");
Config = std::make_shared<ConfigFile>(GlobalCtx2::GetInstance(), GetPathRelativeToAppDirectory("shipofharkinian.ini"));
MainPath = (*Config)["ARCHIVE"]["Main Archive"];
if (MainPath.empty()) {
MainPath = "oot.otr";
MainPath = GetPathRelativeToAppDirectory("oot.otr");
}
PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"];
if (PatchesPath.empty()) {
PatchesPath = "./";
PatchesPath = GetAppDirectoryPath() + "/";
}
ResMan = std::make_shared<ResourceMgr>(GlobalCtx2::GetInstance(), MainPath, PatchesPath);
Win = std::make_shared<Window>(GlobalCtx2::GetInstance());
Expand All @@ -67,11 +87,13 @@ namespace Ship {

void GlobalCtx2::InitLogging() {
try {
auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str());

// Setup Logging
spdlog::init_thread_pool(8192, 1);
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/" + GetName() + ".log", 1024 * 1024 * 10, 10);
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
SohConsoleSink->set_level(spdlog::level::trace);
ConsoleSink->set_level(spdlog::level::trace);
FileSink->set_level(spdlog::level::trace);
Expand Down
3 changes: 3 additions & 0 deletions libultraship/libultraship/GlobalCtx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ namespace Ship {
std::shared_ptr<spdlog::logger> GetLogger() { return Logger; }
std::shared_ptr<ConfigFile> GetConfig() { return Config; }

static std::string GetAppDirectoryPath();
static std::string GetPathRelativeToAppDirectory(const char* path);

void WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);

Expand Down
5 changes: 5 additions & 0 deletions libultraship/libultraship/ImGuiImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ namespace SohImGui {
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu");
}

auto imguiIniPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui.ini");
auto imguiLogPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui_log.txt");
io->IniFilename = strcpy(new char[imguiIniPath.length() + 1], imguiIniPath.c_str());
io->LogFilename = strcpy(new char[imguiLogPath.length() + 1], imguiLogPath.c_str());

if (UseViewports()) {
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
}
Expand Down
60 changes: 60 additions & 0 deletions libultraship/libultraship/OSXFolderManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// OSXFolderManager.h
// libultraship
//
// Created by David Chavez on 28.06.22.
//

#ifndef OSXFolderManager_h
#define OSXFolderManager_h

#include <stdio.h>
namespace Ship {
enum {
NSApplicationDirectory = 1,
NSDemoApplicationDirectory,
NSDeveloperApplicationDirectory,
NSAdminApplicationDirectory,
NSLibraryDirectory,
NSDeveloperDirectory,
NSUserDirectory,
NSDocumentationDirectory,
NSDocumentDirectory,
NSCoreServiceDirectory,
NSAutosavedInformationDirectory = 11,
NSDesktopDirectory = 12,
NSCachesDirectory = 13,
NSApplicationSupportDirectory = 14,
NSDownloadsDirectory = 15,
NSInputMethodsDirectory = 16,
NSMoviesDirectory = 17,
NSMusicDirectory = 18,
NSPicturesDirectory = 19,
NSPrinterDescriptionDirectory = 20,
NSSharedPublicDirectory = 21,
NSPreferencePanesDirectory = 22,
NSApplicationScriptsDirectory = 23,
NSItemReplacementDirectory = 99,
NSAllApplicationsDirectory = 100,
NSAllLibrariesDirectory = 101,
NSTrashDirectory = 102
};
typedef unsigned long SearchPathDirectory;

enum {
NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~)
NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library)
NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network)
NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System)
NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items
};
typedef unsigned long SearchPathDomainMask;

class FolderManager {
public:
const char *pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask);
const char *pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, SearchPathDomainMask domainMask, const char *itemPath, bool create = false);
};
};

#endif /* OSXFolderManager_h */
37 changes: 37 additions & 0 deletions libultraship/libultraship/OSXFolderManager.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// OSXFolderManager.m
// libultraship
//
// Created by David Chavez on 28.06.22.
//

#include "OSXFolderManager.h"
#import <Foundation/Foundation.h>

using namespace Ship;

const char * FolderManager::pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *URLs = [fileManager URLsForDirectory:(NSSearchPathDirectory)directory inDomains:domainMask];
if (URLs.count == 0) return NULL;

NSURL *URL = [URLs objectAtIndex:0];
NSString *path = URL.path;

// `fileSystemRepresentation` on an `NSString` gives a path suitable for POSIX APIs
return path.fileSystemRepresentation;
}

const char * FolderManager::pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory,
SearchPathDomainMask domainMask, const char *itemPath, bool create) {

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *nsPath = [fileManager stringWithFileSystemRepresentation:itemPath length:strlen(itemPath)];
NSURL *itemURL = (nsPath ? [NSURL fileURLWithPath:nsPath] : nil);

NSURL *URL = [fileManager URLForDirectory:(NSSearchPathDirectory)directory
inDomain:domainMask
appropriateForURL:itemURL
create:create error:NULL];
return URL.path.fileSystemRepresentation;
}
8 changes: 1 addition & 7 deletions soh/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ ifeq ($(UNAME), Darwin) #APPLE
LDLIBS += \
$(addprefix -framework , \
OpenGL \
Foundation \
) \
$(shell sdl2-config --libs) $(shell pkg-config --libs glew)
endif
Expand Down Expand Up @@ -224,9 +225,6 @@ appbundle: macosx/$(APPNAME).icns
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
Expand All @@ -244,7 +242,3 @@ macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.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

2 changes: 1 addition & 1 deletion soh/macosx/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleName</key>
<string>Ship of Harkinian</string>
<key>CFBundleExecutable</key>
<string>launcher.sh</string>
<string>soh</string>
<key>CFBundleGetInfoString</key>
<string>2.0.0</string>
<key>CFBundleIconFile</key>
Expand Down
26 changes: 0 additions & 26 deletions soh/macosx/appsupport.m

This file was deleted.

9 changes: 0 additions & 9 deletions soh/macosx/launcher.sh

This file was deleted.

Loading

0 comments on commit 7b04f67

Please sign in to comment.