mirror of
https://github.com/autc04/Retro68.git
synced 2025-02-16 19:32:07 +00:00
LaunchAPPL: make minivmac backend work with the mac version
This commit is contained in:
parent
5808ab19f6
commit
39112683a3
@ -6,7 +6,7 @@
|
||||
# ########### Classic Environment
|
||||
|
||||
# If you are on a PowerPC Mac running Tiger (10.4),
|
||||
# uncomment the following to use the Classic Environment:
|
||||
# uncomment the following to use the Classic Environment:
|
||||
|
||||
# emulator = classic
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
# ########### Carbon on Mac OS X (native PowerPC or Rosetta)
|
||||
|
||||
# If you are on any Mac running Snow Leopard (10.6) or earlier
|
||||
# and you are developing Carbon applications, use the following:
|
||||
# and you are developing Carbon applications, use the following:
|
||||
|
||||
# emulator = carbon
|
||||
|
||||
@ -22,21 +22,25 @@
|
||||
# ########### Mini vMac (old 68K Macs)
|
||||
|
||||
# To use Mini vMac with LaunchAPPL, you need to supply the ROM file,
|
||||
# a system disk image, and a download of autoquit from the minivmac web
|
||||
# site, currently at
|
||||
# http://www.gryphel.com/c/minivmac/extras/autoquit/index.html
|
||||
# LaunchAPPL does not currently support MultiFinder or System 7.
|
||||
# a system disk image, and a download of autoquit from the minivmac web
|
||||
# site, currently at
|
||||
# http://www.gryphel.com/c/minivmac/extras/autoquit/index.html
|
||||
# LaunchAPPL does not currently support MultiFinder or System 7.
|
||||
|
||||
# Fill in the information below and uncomment the lines:
|
||||
|
||||
# emulator = minivmac
|
||||
|
||||
# The directory containing vMac.ROM
|
||||
# All other paths relevant to Mini vMac are relative to this directory.
|
||||
# All minivmac related paths are specified relative to minivmac-dir:
|
||||
# minivmac-dir = /path/to/directory/with/vMac.ROM/
|
||||
|
||||
# First, we need Mini vMac itself:
|
||||
# minivmac-path = ./Mini vMac
|
||||
# On Macs, specify the path of the application bundle, not the executable inside it:
|
||||
# minivmac-path = ./Mini vMac.app
|
||||
|
||||
# A ROM file:
|
||||
# minivmac-rom = ./vMac.ROM
|
||||
|
||||
# Next, a system disk image (System 6 or earlier)
|
||||
# system-image = ./System.dsk
|
||||
@ -51,7 +55,7 @@
|
||||
# emulator = executor
|
||||
|
||||
# If Executor is in your PATH and the SystemFolder environment variable
|
||||
# is already set up, nothing else is required.
|
||||
# is already set up, nothing else is required.
|
||||
|
||||
# in case it's somewhere else:
|
||||
# executor-path = /usr/local/bin/executor
|
||||
@ -60,8 +64,8 @@
|
||||
# executor-system-folder = /path/to/ExecutorVolume/System Folder
|
||||
|
||||
# Pass more options to Executor.
|
||||
# Note that each "word" needs to be specified separately:
|
||||
# executor-option = -size # emulated screen size
|
||||
# Note that each "word" needs to be specified separately:
|
||||
# executor-option = -size # emulated screen size
|
||||
# executor-option = 1600x1200
|
||||
|
||||
# executor-option = -appearance # uncommenting these two lines
|
||||
|
@ -73,6 +73,10 @@ int Launcher::ChildProcess(string program, vector<string> args, int timeout)
|
||||
{
|
||||
execvp(argv[0], const_cast<char* const *> (argv.data()));
|
||||
perror("exec failed");
|
||||
std::cerr << "Tried to execute: " << program;
|
||||
for(auto a : args)
|
||||
std::cerr << " " << a;
|
||||
std::cerr << std::endl;
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,12 @@ extern "C" {
|
||||
#include <fstream>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define ResType MacResType
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
@ -36,11 +42,37 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Recursive directory copy from https://stackoverflow.com/a/39146566
|
||||
*/
|
||||
static void copyDirectoryRecursively(const fs::path& sourceDir, const fs::path& destinationDir)
|
||||
{
|
||||
if (!fs::exists(sourceDir) || !fs::is_directory(sourceDir))
|
||||
{
|
||||
throw std::runtime_error("Source directory " + sourceDir.string() + " does not exist or is not a directory");
|
||||
}
|
||||
if (fs::exists(destinationDir))
|
||||
{
|
||||
throw std::runtime_error("Destination directory " + destinationDir.string() + " already exists");
|
||||
}
|
||||
if (!fs::create_directory(destinationDir))
|
||||
{
|
||||
throw std::runtime_error("Cannot create destination directory " + destinationDir.string());
|
||||
}
|
||||
|
||||
for (const auto& dirEnt : fs::recursive_directory_iterator{sourceDir})
|
||||
{
|
||||
const auto& path = dirEnt.path();
|
||||
auto relativePathStr = path.lexically_relative(sourceDir);
|
||||
fs::copy(path, destinationDir / relativePathStr);
|
||||
}
|
||||
}
|
||||
|
||||
MiniVMacLauncher::MiniVMacLauncher(po::variables_map &options)
|
||||
: Launcher(options),
|
||||
sysvol(NULL), vol(NULL)
|
||||
{
|
||||
imagePath = tempDir / "image.dsk";
|
||||
imagePath = tempDir / "disk1.dsk";
|
||||
vmacDir = fs::absolute( options["minivmac-dir"].as<std::string>() );
|
||||
vmacPath = fs::absolute( options["minivmac-path"].as<std::string>(), vmacDir );
|
||||
|
||||
@ -119,6 +151,86 @@ MiniVMacLauncher::MiniVMacLauncher(po::variables_map &options)
|
||||
|
||||
hfs_umount(sysvol); sysvol = NULL;
|
||||
hfs_umount(vol); vol = NULL;
|
||||
|
||||
fs::path romFile = fs::absolute( options["minivmac-rom"].as<std::string>(), vmacDir );
|
||||
|
||||
fs::create_symlink(
|
||||
romFile,
|
||||
tempDir / romFile.filename() );
|
||||
|
||||
if(romFile.filename() != "vMac.ROM")
|
||||
{
|
||||
// If the ROM file is not named vMac.ROM, this might be for two different
|
||||
// reasons.
|
||||
// 1. The user didn't bother to rename it to the correct "vMac.ROM"
|
||||
// 2. The user is using a MacII version of Mini vMac and has named the
|
||||
// ROM file MacII.ROM on purpose.
|
||||
|
||||
// To be on the safe side, provide both the user-specified name and
|
||||
// the standard vMac.ROM.
|
||||
|
||||
fs::create_symlink(
|
||||
romFile,
|
||||
tempDir / romFile.filename() );
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
/*
|
||||
A special case for the Mac.
|
||||
|
||||
The Mac build of Mini vMac does not look for files (vMac.ROM, disk1.dsk)
|
||||
in the current directory, but rather in the parent directory
|
||||
of the .app bundle.
|
||||
|
||||
Also, it ignores command line arguments.
|
||||
|
||||
So we just copy the entire application bundle over to our temporary
|
||||
directory. It is five times smaller than System 6, so this really does not
|
||||
matter.
|
||||
*/
|
||||
if(vmacPath.extension().string() == ".app")
|
||||
{
|
||||
fs::path appPath = tempDir / "minivmac.app";
|
||||
|
||||
copyDirectoryRecursively( vmacPath, appPath );
|
||||
|
||||
// The following 30 lines of code should rather be written as:
|
||||
// vmacPath = appPath / "Contents" / "MacOS" / Bundle(appPath).getExecutablePath();
|
||||
// But this is CoreFoundation, so it's a tiny little bit more verbose:
|
||||
|
||||
CFStringRef appPathCF
|
||||
= CFStringCreateWithCString(
|
||||
kCFAllocatorDefault, appPath.string().c_str(), kCFStringEncodingUTF8);
|
||||
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(
|
||||
kCFAllocatorDefault, appPathCF, kCFURLPOSIXPathStyle, true);
|
||||
|
||||
CFBundleRef bundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
|
||||
|
||||
CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
|
||||
|
||||
CFStringRef executablePath = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
|
||||
|
||||
if(const char *ptr = CFStringGetCStringPtr(executablePath, kCFURLPOSIXPathStyle))
|
||||
{
|
||||
vmacPath = string(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<char> buffer(
|
||||
CFStringGetMaximumSizeForEncoding(
|
||||
CFStringGetLength(executablePath), kCFStringEncodingUTF8) + 1);
|
||||
CFStringGetCString(executablePath, buffer.data(), buffer.size(), kCFStringEncodingUTF8);
|
||||
vmacPath = string(buffer.data());
|
||||
}
|
||||
vmacPath = appPath / "Contents" / "MacOS" / vmacPath;
|
||||
|
||||
CFRelease(appPathCF);
|
||||
CFRelease(bundleURL);
|
||||
CFRelease(bundle);
|
||||
CFRelease(executableURL);
|
||||
CFRelease(executablePath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
MiniVMacLauncher::~MiniVMacLauncher()
|
||||
@ -159,17 +271,12 @@ void MiniVMacLauncher::CopySystemFile(const std::string &fn, bool required)
|
||||
|
||||
bool MiniVMacLauncher::Go(int timeout)
|
||||
{
|
||||
fs::path minivmacdir = fs::absolute( options["minivmac-dir"].as<std::string>() );
|
||||
std::string minivmacpath = options["minivmac-path"].as<std::string>();
|
||||
|
||||
fs::current_path(minivmacdir);
|
||||
|
||||
return ChildProcess(minivmacpath, { imagePath.string() }, timeout) == 0;
|
||||
fs::current_path(tempDir);
|
||||
return ChildProcess(vmacPath.string(), {}, timeout) == 0;
|
||||
}
|
||||
|
||||
void MiniVMacLauncher::DumpOutput()
|
||||
{
|
||||
sleep(1);
|
||||
vol = hfs_mount(imagePath.string().c_str(), 0, HFS_MODE_RDONLY);
|
||||
hfsdirent fileent;
|
||||
int statres = hfs_stat(vol, "out", &fileent);
|
||||
@ -191,6 +298,7 @@ void MiniVMac::GetOptions(options_description &desc)
|
||||
desc.add_options()
|
||||
("minivmac-dir", po::value<std::string>(),"directory containing vMac.ROM")
|
||||
("minivmac-path", po::value<std::string>()->default_value("./minivmac"),"relative path to minivmac")
|
||||
("minivmac-rom", po::value<std::string>()->default_value("./vMac.ROM"),"minivmac ROM file")
|
||||
("system-image", po::value<std::string>(),"path to disk image with system")
|
||||
("autoquit-image", po::value<std::string>(),"path to autoquit disk image, available from the minivmac web site")
|
||||
;
|
||||
@ -200,6 +308,7 @@ bool MiniVMac::CheckOptions(variables_map &options)
|
||||
{
|
||||
return options.count("minivmac-path") != 0
|
||||
&& options.count("minivmac-dir") != 0
|
||||
&& options.count("minivmac-rom") != 0
|
||||
&& options.count("system-image") != 0
|
||||
&& options.count("autoquit-image") != 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user