mirror of
				https://github.com/Zelda64Recomp/Zelda64Recomp.git
				synced 2025-10-30 08:03:03 +00:00 
			
		
		
		
	Fix portable mode on macOS.
This commit is contained in:
		
							parent
							
								
									1c8668fb65
								
							
						
					
					
						commit
						0aff04ba4b
					
				
					 4 changed files with 47 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -12,7 +12,8 @@ namespace zelda64 {
 | 
			
		|||
// Apple specific methods that usually require Objective-C. Implemented in support_apple.mm.
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
    void dispatch_on_ui_thread(std::function<void()> func);
 | 
			
		||||
    const char* get_bundle_resource_directory();
 | 
			
		||||
    std::filesystem::path get_bundle_resource_directory();
 | 
			
		||||
    std::filesystem::path get_bundle_directory();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#include "recomp_input.h"
 | 
			
		||||
#include "zelda_sound.h"
 | 
			
		||||
#include "zelda_render.h"
 | 
			
		||||
#include "zelda_support.h"
 | 
			
		||||
#include "ultramodern/config.hpp"
 | 
			
		||||
#include "librecomp/files.hpp"
 | 
			
		||||
#include <filesystem>
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +137,14 @@ std::filesystem::path zelda64::get_app_folder_path() {
 | 
			
		|||
       return std::filesystem::current_path();
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
   // Check for portable file in the directory containing the app bundle.
 | 
			
		||||
   const auto app_bundle_path = zelda64::get_bundle_directory().parent_path();
 | 
			
		||||
   if (std::filesystem::exists(app_bundle_path / "portable.txt")) {
 | 
			
		||||
       return app_bundle_path;
 | 
			
		||||
   }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   std::filesystem::path recomp_dir{};
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,9 +25,7 @@ namespace zelda64 {
 | 
			
		|||
    std::filesystem::path get_asset_path(const char* asset) {
 | 
			
		||||
        std::filesystem::path base_path = "";
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
        const char* resource_dir = get_bundle_resource_directory();
 | 
			
		||||
        base_path = resource_dir;
 | 
			
		||||
        free((void*)resource_dir);
 | 
			
		||||
        base_path = get_bundle_resource_directory();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return base_path / "assets" / asset;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
#include "zelda_support.h"
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import <objc/runtime.h>
 | 
			
		||||
#import <objc/message.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +13,41 @@ namespace zelda64 {
 | 
			
		|||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char* get_bundle_resource_directory() {
 | 
			
		||||
    std::filesystem::path get_bundle_resource_directory() {
 | 
			
		||||
        NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
 | 
			
		||||
        return strdup([bundlePath UTF8String]);
 | 
			
		||||
        return std::filesystem::path([bundlePath UTF8String]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::filesystem::path get_bundle_directory() {
 | 
			
		||||
        NSURL *bundleUrl = [[NSBundle mainBundle] bundleURL];
 | 
			
		||||
 | 
			
		||||
        // The OS may relocate the app elsewhere for security reasons if, for example,
 | 
			
		||||
        // it was downloaded and opened from the Downloads folder. In this case, we need
 | 
			
		||||
        // to untranslocate the path to find out where the actual app bundle is.
 | 
			
		||||
        if (void* securityHandle = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY)) {
 | 
			
		||||
            using IsTranslocatedURLFunc = Boolean (*)(CFURLRef path, bool* isTranslocated,
 | 
			
		||||
                                                      CFErrorRef* __nullable error);
 | 
			
		||||
            using CreateOriginalPathForURLFunc = CFURLRef __nullable (*)(CFURLRef translocatedPath,
 | 
			
		||||
                                                                         CFErrorRef* __nullable error);
 | 
			
		||||
 | 
			
		||||
            const auto IsTranslocatedURL = reinterpret_cast<IsTranslocatedURLFunc>(
 | 
			
		||||
                dlsym(securityHandle, "SecTranslocateIsTranslocatedURL"));
 | 
			
		||||
            const auto CreateOriginalPathForURL = reinterpret_cast<CreateOriginalPathForURLFunc>(
 | 
			
		||||
                dlsym(securityHandle, "SecTranslocateCreateOriginalPathForURL"));
 | 
			
		||||
 | 
			
		||||
            bool translocated = false;
 | 
			
		||||
            if (IsTranslocatedURL && CreateOriginalPathForURL &&
 | 
			
		||||
                IsTranslocatedURL((__bridge CFURLRef) bundleUrl, &translocated, nullptr) && translocated) {
 | 
			
		||||
                CFURLRef untranslocated = CreateOriginalPathForURL((__bridge CFURLRef) bundleUrl, nullptr);
 | 
			
		||||
                if (untranslocated) {
 | 
			
		||||
                    bundleUrl = (NSURL*) untranslocated;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            dlclose(securityHandle);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return std::filesystem::path([bundleUrl fileSystemRepresentation]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue