mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-01 11:52:47 +00:00
Autodetect System version for correct AutoQuit
Reads the System resource to find out the System Software version for running correct AutoQuit. Includes other minor changes. Signed-off-by: Szymon Łopaciuk <szymon@lopaciuk.eu>
This commit is contained in:
parent
a3919a0bb4
commit
89d4565f0d
@ -25,6 +25,45 @@ using std::vector;
|
|||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
|
||||||
|
/* Adapted from http://sebastien.kirche.free.fr/python_stuff/MacOS-aliases.txt */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int16_t type; /* type of data */
|
||||||
|
int16_t size; /* length of variable length data */
|
||||||
|
char data[]; /* actual data */
|
||||||
|
} VarData;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Type Code: alis */
|
||||||
|
char userType[4] = {0, 0, 0, 0}; /* for application use, can be zeros */
|
||||||
|
uint16_t size; /* alias record size, including variable length data */
|
||||||
|
int16_t version = 2; /* alias version, current 2 */
|
||||||
|
int16_t type = 0; /* file = 0, directory = 1 */
|
||||||
|
char volumeNameSize;
|
||||||
|
char volumeName[27]; /* volume name */
|
||||||
|
uint32_t volumeCreationDate; /* volume creation date, seconds since 1904 */
|
||||||
|
uint16_t volumeSig = 0x4244; /*BD*/ /* volume signature MFS = RW, HFS = BD */
|
||||||
|
int16_t volumeType = 5; /* [HD] = 0, Foreign = 1, Floppy: 400K, 800K, 1400K = 2-4, OtherEjectable = 5 */
|
||||||
|
int32_t parentDirID; /* parent directory ID, 0 for relative searches */
|
||||||
|
char fileNameSize;
|
||||||
|
char fileName[63]; /* file or directory name */
|
||||||
|
int32_t fileNum; /* file number or directory ID */
|
||||||
|
uint32_t fileCreationDate; /* file or directory creation date, seconds since 1904 */
|
||||||
|
char typeCode[4]; /* file type */
|
||||||
|
char creatorCode[4]; /* file's creator */
|
||||||
|
int16_t nlvlFrom = 0; /* next level up from alias, used in relative searches */
|
||||||
|
int16_t nlvlTo = 0; /* next level down to target, ditto */
|
||||||
|
uint32_t volumeAttr = 0; /* various flags (locked, ejectable), see link above */
|
||||||
|
int16_t volumeFSID = 0; /* file system ID for the volume, 0 for MFS, HFS */
|
||||||
|
int16_t unused = 0;
|
||||||
|
uint32_t unused1 = 0;
|
||||||
|
uint32_t unused2 = 0;
|
||||||
|
VarData vdata[]; /* variable length data, see link above */
|
||||||
|
} AliasData;
|
||||||
|
|
||||||
|
|
||||||
class MiniVMacLauncher : public Launcher
|
class MiniVMacLauncher : public Launcher
|
||||||
{
|
{
|
||||||
fs::path imagePath;
|
fs::path imagePath;
|
||||||
@ -36,6 +75,7 @@ class MiniVMacLauncher : public Launcher
|
|||||||
hfsvol *vol;
|
hfsvol *vol;
|
||||||
|
|
||||||
void CopySystemFile(const std::string& fn, bool required);
|
void CopySystemFile(const std::string& fn, bool required);
|
||||||
|
uint16_t GetSystemVersion(const std::string& systemFileName);
|
||||||
void MakeAlias(const std::string& dest, const std::string& src);
|
void MakeAlias(const std::string& dest, const std::string& src);
|
||||||
fs::path ConvertImage(const fs::path& path);
|
fs::path ConvertImage(const fs::path& path);
|
||||||
public:
|
public:
|
||||||
@ -128,13 +168,8 @@ MiniVMacLauncher::MiniVMacLauncher(po::variables_map &options)
|
|||||||
vmacDir = fs::absolute( options["minivmac-dir"].as<std::string>() );
|
vmacDir = fs::absolute( options["minivmac-dir"].as<std::string>() );
|
||||||
vmacPath = fs::absolute( options["minivmac-path"].as<std::string>(), vmacDir );
|
vmacPath = fs::absolute( options["minivmac-path"].as<std::string>(), vmacDir );
|
||||||
|
|
||||||
bool usesAutQuit7 = options.count("autquit7-image");
|
|
||||||
|
|
||||||
systemImage = fs::absolute(options["system-image"].as<std::string>(), vmacDir);
|
systemImage = fs::absolute(options["system-image"].as<std::string>(), vmacDir);
|
||||||
fs::path autoquitImage = fs::absolute(options[usesAutQuit7 ? "autquit7-image" : "autoquit-image"].as<std::string>(), vmacDir);
|
|
||||||
|
|
||||||
systemImage = ConvertImage(systemImage);
|
systemImage = ConvertImage(systemImage);
|
||||||
autoquitImage = ConvertImage(autoquitImage);
|
|
||||||
|
|
||||||
std::vector<unsigned char> bootblock1(1024);
|
std::vector<unsigned char> bootblock1(1024);
|
||||||
fs::ifstream(systemImage).read((char*) bootblock1.data(), 1024);
|
fs::ifstream(systemImage).read((char*) bootblock1.data(), 1024);
|
||||||
@ -142,35 +177,38 @@ MiniVMacLauncher::MiniVMacLauncher(po::variables_map &options)
|
|||||||
if(bootblock1[0] != 'L' || bootblock1[1] != 'K' || bootblock1[0xA] > 15)
|
if(bootblock1[0] != 'L' || bootblock1[1] != 'K' || bootblock1[0xA] > 15)
|
||||||
throw std::runtime_error("Not a bootable Mac disk image: " + systemImage.string());
|
throw std::runtime_error("Not a bootable Mac disk image: " + systemImage.string());
|
||||||
|
|
||||||
string systemFileName(bootblock1.begin() + 0xB, bootblock1.begin() + 0xB + bootblock1[0xA]);
|
|
||||||
|
|
||||||
|
|
||||||
int size = 5000*1024;
|
|
||||||
|
|
||||||
fs::ofstream(imagePath, std::ios::binary | std::ios::trunc).seekp(size-1).put(0);
|
|
||||||
hfs_format(imagePath.string().c_str(), 0, 0, "SysAndApp", 0, NULL);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string finderName = std::string(usesAutQuit7 ? "Finder" : "AutoQuit");
|
|
||||||
bootblock1[0x1A] = finderName.size();
|
|
||||||
memcpy(&bootblock1[0x1B], finderName.c_str(), finderName.size());
|
|
||||||
bootblock1[0x5A] = 3;
|
|
||||||
memcpy(&bootblock1[0x5B],"App", 3);
|
|
||||||
|
|
||||||
fs::fstream(imagePath, std::ios::in | std::ios::out | std::ios::binary)
|
|
||||||
.write((const char*) bootblock1.data(), 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vol = hfs_mount(imagePath.string().c_str(), 0, HFS_MODE_RDWR);
|
|
||||||
assert(vol);
|
|
||||||
|
|
||||||
sysvol = hfs_mount(systemImage.string().c_str(),0, HFS_MODE_RDONLY);
|
sysvol = hfs_mount(systemImage.string().c_str(),0, HFS_MODE_RDONLY);
|
||||||
assert(sysvol);
|
assert(sysvol);
|
||||||
hfsvolent ent;
|
hfsvolent ent;
|
||||||
hfs_vstat(sysvol, &ent);
|
hfs_vstat(sysvol, &ent);
|
||||||
hfs_setcwd(sysvol, ent.blessed);
|
hfs_setcwd(sysvol, ent.blessed);
|
||||||
|
|
||||||
|
string systemFileName(bootblock1.begin() + 0xB, bootblock1.begin() + 0xB + bootblock1[0xA]);
|
||||||
|
uint16_t sysver = GetSystemVersion(systemFileName);
|
||||||
|
|
||||||
|
bool usesAutQuit7 = (sysver >= 0x700);
|
||||||
|
fs::path autoquitImage = fs::absolute(options[usesAutQuit7 ? "autquit7-image" : "autoquit-image"].as<std::string>(), vmacDir);
|
||||||
|
autoquitImage = ConvertImage(autoquitImage);
|
||||||
|
|
||||||
|
int size = 5000*1024;
|
||||||
|
|
||||||
|
fs::ofstream(imagePath, std::ios::binary | std::ios::trunc).seekp(size-1).put(0);
|
||||||
|
hfs_format(imagePath.string().c_str(), 0, 0, "SysAndApp", 0, NULL);
|
||||||
|
|
||||||
|
if(!usesAutQuit7)
|
||||||
|
{
|
||||||
|
std::string finderName = std::string(usesAutQuit7 ? "Finder" : "AutoQuit");
|
||||||
|
bootblock1[0x1A] = finderName.size();
|
||||||
|
memcpy(&bootblock1[0x1B], finderName.c_str(), finderName.size());
|
||||||
|
bootblock1[0x5A] = 3;
|
||||||
|
memcpy(&bootblock1[0x5B],"App", 3);
|
||||||
|
}
|
||||||
|
fs::fstream(imagePath, std::ios::in | std::ios::out | std::ios::binary)
|
||||||
|
.write((const char*) bootblock1.data(), 1024);
|
||||||
|
|
||||||
|
|
||||||
|
vol = hfs_mount(imagePath.string().c_str(), 0, HFS_MODE_RDWR);
|
||||||
|
assert(vol);
|
||||||
|
|
||||||
hfs_vstat(vol, &ent);
|
hfs_vstat(vol, &ent);
|
||||||
ent.blessed = hfs_getcwd(vol);
|
ent.blessed = hfs_getcwd(vol);
|
||||||
@ -200,7 +238,7 @@ MiniVMacLauncher::MiniVMacLauncher(po::variables_map &options)
|
|||||||
hfs_close(file);
|
hfs_close(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
hfs_umount(sysvol); sysvol = NULL;
|
hfs_umount(sysvol);
|
||||||
sysvol = hfs_mount(autoquitImage.string().c_str(),0, HFS_MODE_RDONLY);
|
sysvol = hfs_mount(autoquitImage.string().c_str(),0, HFS_MODE_RDONLY);
|
||||||
if(!sysvol)
|
if(!sysvol)
|
||||||
throw std::runtime_error("Cannot open disk image: " + autoquitImage.string());
|
throw std::runtime_error("Cannot open disk image: " + autoquitImage.string());
|
||||||
@ -379,6 +417,22 @@ void MiniVMacLauncher::MakeAlias(const std::string& dest, const std::string& src
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MiniVMacLauncher::GetSystemVersion(const std::string& systemFileName)
|
||||||
|
{
|
||||||
|
hfsdirent fileent;
|
||||||
|
hfs_stat(sysvol, systemFileName.c_str(), &fileent);
|
||||||
|
hfsfile* system = hfs_open(sysvol, systemFileName.c_str());
|
||||||
|
std::vector<uint8_t> buffer(fileent.u.file.rsize);
|
||||||
|
hfs_setfork(system, 1);
|
||||||
|
hfs_read(system, buffer.data(), fileent.u.file.rsize);
|
||||||
|
hfs_close(system);
|
||||||
|
std::istringstream systemResStream(std::string((char*)buffer.data(), buffer.size()));
|
||||||
|
Resources systemRes(systemResStream);
|
||||||
|
Resource vers = systemRes.resources[ResRef('vers', 1)];
|
||||||
|
return (uint16_t)vers.getData()[0] << 8 | vers.getData()[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MiniVMacLauncher::Go(int timeout)
|
bool MiniVMacLauncher::Go(int timeout)
|
||||||
{
|
{
|
||||||
fs::current_path(tempDir);
|
fs::current_path(tempDir);
|
||||||
@ -423,7 +477,8 @@ bool MiniVMac::CheckOptions(variables_map &options)
|
|||||||
&& options.count("minivmac-dir") != 0
|
&& options.count("minivmac-dir") != 0
|
||||||
&& options.count("minivmac-rom") != 0
|
&& options.count("minivmac-rom") != 0
|
||||||
&& options.count("system-image") != 0
|
&& options.count("system-image") != 0
|
||||||
&& (options.count("autoquit-image") + options.count("autquit7-image")) == 1;
|
&& options.count("autoquit-image") != 0
|
||||||
|
&& options.count("autquit7-image") != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Launcher> MiniVMac::MakeLauncher(variables_map &options)
|
std::unique_ptr<Launcher> MiniVMac::MakeLauncher(variables_map &options)
|
||||||
|
@ -3,45 +3,6 @@
|
|||||||
|
|
||||||
#include "LaunchMethod.h"
|
#include "LaunchMethod.h"
|
||||||
|
|
||||||
|
|
||||||
/* Adapted from http://sebastien.kirche.free.fr/python_stuff/MacOS-aliases.txt */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int16_t type; /* type of data */
|
|
||||||
int16_t size; /* length of variable length data */
|
|
||||||
char data[]; /* actual data */
|
|
||||||
} VarData;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
/* Type Code: alis */
|
|
||||||
char userType[4] = {0, 0, 0, 0}; /* for application use, can be zeros */
|
|
||||||
uint16_t size; /* alias record size, including variable length data */
|
|
||||||
int16_t version = 2; /* alias version, current 2 */
|
|
||||||
int16_t type = 0; /* file = 0, directory = 1 */
|
|
||||||
char volumeNameSize;
|
|
||||||
char volumeName[27]; /* volume name */
|
|
||||||
uint32_t volumeCreationDate; /* volume creation date, seconds since 1904 */
|
|
||||||
uint16_t volumeSig = 0x4244; /*BD*/ /* volume signature MFS = RW, HFS = BD */
|
|
||||||
int16_t volumeType = 5; /* [HD] = 0, Foreign = 1, Floppy: 400K, 800K, 1400K = 2-4, OtherEjectable = 5 */
|
|
||||||
int32_t parentDirID; /* parent directory ID, 0 for relative searches */
|
|
||||||
char fileNameSize;
|
|
||||||
char fileName[63]; /* file or directory name */
|
|
||||||
int32_t fileNum; /* file number or directory ID */
|
|
||||||
uint32_t fileCreationDate; /* file or directory creation date, seconds since 1904 */
|
|
||||||
char typeCode[4]; /* file type */
|
|
||||||
char creatorCode[4]; /* file's creator */
|
|
||||||
int16_t nlvlFrom = 0; /* next level up from alias, used in relative searches */
|
|
||||||
int16_t nlvlTo = 0; /* next level down to target, ditto */
|
|
||||||
uint32_t volumeAttr = 0; /* various flags (locked, ejectable), see link above */
|
|
||||||
int16_t volumeFSID = 0; /* file system ID for the volume, 0 for MFS, HFS */
|
|
||||||
int16_t unused = 0;
|
|
||||||
uint32_t unused1 = 0;
|
|
||||||
uint32_t unused2 = 0;
|
|
||||||
VarData vdata[]; /* variable length data, see link above */
|
|
||||||
} AliasData;
|
|
||||||
|
|
||||||
|
|
||||||
class MiniVMac : public LaunchMethod
|
class MiniVMac : public LaunchMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user