Compare commits

...

6 Commits

Author SHA1 Message Date
Skeagle
fba5525f81
Merge a2a8a82e88 into 1881d3aa29 2023-10-08 19:18:18 -06:00
Iliyas Jorio
1881d3aa29 README: Mention Bugdom 2 2023-10-08 23:51:52 +02:00
Iliyas Jorio
c6a38eab19 Update ghc::filesystem to v1.5.14 2023-09-28 22:11:18 +02:00
Iliyas Jorio
9af72c9717 Optional case-sensitive FSSpec 2023-09-28 20:51:05 +02:00
Iliyas Jorio
d9d1f906c5 User-configurable POMME_DEBUG_ constants 2023-09-28 20:51:05 +02:00
Iliyas Jorio
b8d624facd Use u8string for all filesystem paths 2023-09-28 20:51:05 +02:00
11 changed files with 1394 additions and 954 deletions

View File

@ -10,6 +10,7 @@ The goal isn't to achieve 100% source compatibility with old Mac C programs, but
- [Billy Frontier](https://github.com/jorio/BillyFrontier) - [Billy Frontier](https://github.com/jorio/BillyFrontier)
- [Bugdom](https://github.com/jorio/Bugdom) - [Bugdom](https://github.com/jorio/Bugdom)
- [Bugdom 2](https://github.com/jorio/Bugdom2)
- [Cro-Mag Rally](https://github.com/jorio/CroMagRally) - [Cro-Mag Rally](https://github.com/jorio/CroMagRally)
- [Mighty Mike](https://github.com/jorio/MightyMike) - [Mighty Mike](https://github.com/jorio/MightyMike)
- [Nanosaur](https://github.com/jorio/Nanosaur) - [Nanosaur](https://github.com/jorio/Nanosaur)

File diff suppressed because it is too large Load Diff

View File

@ -112,7 +112,9 @@ OSErr FSMakeFSSpec(short vRefNum, long dirID, const char* cstrFileName, FSSpec*
if (!IsVolumeLegal(vRefNum)) if (!IsVolumeLegal(vRefNum))
return nsvErr; return nsvErr;
return volumes.at(vRefNum)->FSMakeFSSpec(dirID, cstrFileName, spec); u8string fileName((const char8_t*)cstrFileName);
return volumes.at(vRefNum)->FSMakeFSSpec(dirID, fileName, spec);
} }
static OSErr OpenFork(const FSSpec* spec, ForkType forkType, char permission, short* refNum) static OSErr OpenFork(const FSSpec* spec, ForkType forkType, char permission, short* refNum)
@ -165,7 +167,7 @@ OSErr FindFolder(short vRefNum, OSType folderType, Boolean createFolder, short*
throw std::runtime_error("FindFolder only supports kOnSystemDisk"); throw std::runtime_error("FindFolder only supports kOnSystemDisk");
} }
fs::path path; fs::path path = "";
switch (folderType) switch (folderType)
{ {
@ -175,7 +177,8 @@ OSErr FindFolder(short vRefNum, OSType folderType, Boolean createFolder, short*
path = Pomme::Platform::Windows::GetPreferencesFolder(); path = Pomme::Platform::Windows::GetPreferencesFolder();
#elif defined(__APPLE__) #elif defined(__APPLE__)
const char *home = getenv("HOME"); const char *home = getenv("HOME");
if (!home) { if (!home)
{
return fnfErr; return fnfErr;
} }
path = fs::path(home) / "Library" / "Preferences"; path = fs::path(home) / "Library" / "Preferences";
@ -203,6 +206,11 @@ OSErr FindFolder(short vRefNum, OSType folderType, Boolean createFolder, short*
return fnfErr; return fnfErr;
} }
if (path.empty())
{
return fnfErr;
}
path = path.lexically_normal(); path = path.lexically_normal();
bool exists = fs::exists(path); bool exists = fs::exists(path);
@ -223,9 +231,15 @@ OSErr FindFolder(short vRefNum, OSType folderType, Boolean createFolder, short*
OSErr DirCreate(short vRefNum, long parentDirID, const char* cstrDirectoryName, long* createdDirID) OSErr DirCreate(short vRefNum, long parentDirID, const char* cstrDirectoryName, long* createdDirID)
{ {
return IsVolumeLegal(vRefNum) if (!IsVolumeLegal(vRefNum))
? volumes.at(vRefNum)->DirCreate(parentDirID, cstrDirectoryName, createdDirID) {
: (OSErr)nsvErr; return (OSErr)nsvErr;
}
u8string directoryName((const char8_t*)cstrDirectoryName);
const auto& volume = volumes.at(vRefNum);
return volume->DirCreate(parentDirID, directoryName, createdDirID);
} }
OSErr FSpCreate(const FSSpec* spec, OSType creator, OSType fileType, ScriptCode scriptTag) OSErr FSpCreate(const FSSpec* spec, OSType creator, OSType fileType, ScriptCode scriptTag)

View File

@ -68,9 +68,15 @@ long HostVolume::GetDirectoryID(const fs::path& dirPath)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Internal utilities // Internal utilities
fs::path HostVolume::ToPath(long parID, const std::string& name) fs::path HostVolume::ToPath(long parID, const char* name)
{ {
fs::path path = directories.at(parID) / AsU8(name); return ToPath(parID, u8string((const char8_t*)name));
}
fs::path HostVolume::ToPath(long parID, const u8string& name)
{
fs::path path = directories.at(parID);
path /= name;
return path.lexically_normal(); return path.lexically_normal();
} }
@ -161,12 +167,9 @@ OSErr HostVolume::OpenFork(const FSSpec* spec, ForkType forkType, char permissio
return noErr; return noErr;
} }
static bool CaseInsensitiveAppendToPath( static bool CaseInsensitiveAppendToPath(fs::path& path, const u8string& element, bool skipFiles = false)
fs::path& path,
const std::string& element,
bool skipFiles = false)
{ {
fs::path naiveConcat = path / AsU8(element); fs::path naiveConcat = path / element;
if (!fs::exists(path)) if (!fs::exists(path))
{ {
@ -180,6 +183,18 @@ static bool CaseInsensitiveAppendToPath(
return true; return true;
} }
#if POMME_CASE_SENSITIVE_FSSPEC
if (!skipFiles)
{
fs::path candidateResourcePath = naiveConcat;
candidateResourcePath += ".rsrc";
if (fs::is_regular_file(candidateResourcePath))
{
path = naiveConcat;
return true;
}
}
#else
// Convert path element to uppercase for case-insensitive comparisons // Convert path element to uppercase for case-insensitive comparisons
const auto uppercaseElement = UppercaseCopy(element); const auto uppercaseElement = UppercaseCopy(element);
@ -199,11 +214,7 @@ static bool CaseInsensitiveAppendToPath(
} }
// Convert candidate filename to uppercase for case-insensitive comparison // Convert candidate filename to uppercase for case-insensitive comparison
#if LEGACY_FILESYSTEM_IMPLEMENTATION // ghc::path::u8string returns an std::string const u8string uppercaseCandidateFilename = UppercaseCopy(candidateFilename.u8string());
const std::string uppercaseCandidateFilename = UppercaseCopy(candidateFilename.u8string());
#else // C++20
const std::string uppercaseCandidateFilename = UppercaseCopy(FromU8(candidateFilename.u8string()));
#endif
if (uppercaseElement == uppercaseCandidateFilename) if (uppercaseElement == uppercaseCandidateFilename)
{ {
@ -211,6 +222,7 @@ static bool CaseInsensitiveAppendToPath(
return true; return true;
} }
} }
#endif
path = naiveConcat; path = naiveConcat;
return false; return false;
@ -219,7 +231,7 @@ static bool CaseInsensitiveAppendToPath(
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Implementation // Implementation
OSErr HostVolume::FSMakeFSSpec(long dirID, const std::string& fileName, FSSpec* spec) OSErr HostVolume::FSMakeFSSpec(long dirID, const u8string& fileName, FSSpec* spec)
{ {
if (dirID < 0 || (unsigned long) dirID >= directories.size()) if (dirID < 0 || (unsigned long) dirID >= directories.size())
{ {
@ -231,12 +243,12 @@ OSErr HostVolume::FSMakeFSSpec(long dirID, const std::string& fileName, FSSpec*
// Case-insensitive sanitization // Case-insensitive sanitization
bool exists = fs::exists(path); bool exists = fs::exists(path);
std::string::size_type begin = (suffix.at(0) == ':') ? 1 : 0; u8string::size_type begin = (suffix.at(0) == ':') ? 1 : 0;
// Iterate on path elements between colons // Iterate on path elements between colons
while (begin < suffix.length()) while (begin < suffix.length())
{ {
auto end = suffix.find(":", begin); auto end = suffix.find(':', begin);
bool isLeaf = end == std::string::npos; // no ':' found => end of path bool isLeaf = end == std::string::npos; // no ':' found => end of path
if (isLeaf) end = suffix.length(); if (isLeaf) end = suffix.length();
@ -264,7 +276,7 @@ OSErr HostVolume::FSMakeFSSpec(long dirID, const std::string& fileName, FSSpec*
return exists ? noErr : fnfErr; return exists ? noErr : fnfErr;
} }
OSErr HostVolume::DirCreate(long parentDirID, const std::string& directoryName, long* createdDirID) OSErr HostVolume::DirCreate(long parentDirID, const u8string& directoryName, long* createdDirID)
{ {
const auto path = ToPath(parentDirID, directoryName); const auto path = ToPath(parentDirID, directoryName);

View File

@ -2,6 +2,7 @@
#include "Files/Volume.h" #include "Files/Volume.h"
#include "CompilerSupport/filesystem.h" #include "CompilerSupport/filesystem.h"
#include "Utilities/StringUtils.h"
#include <vector> #include <vector>
namespace Pomme::Files namespace Pomme::Files
@ -14,7 +15,8 @@ namespace Pomme::Files
{ {
std::vector<fs::path> directories; std::vector<fs::path> directories;
fs::path ToPath(long parID, const std::string& name); fs::path ToPath(long parID, const char* name);
fs::path ToPath(long parID, const u8string& name);
public: public:
explicit HostVolume(short vRefNum); explicit HostVolume(short vRefNum);
@ -31,7 +33,7 @@ namespace Pomme::Files
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Toolbox API Implementation // Toolbox API Implementation
OSErr FSMakeFSSpec(long dirID, const std::string& fileName, FSSpec* spec) override; OSErr FSMakeFSSpec(long dirID, const u8string& fileName, FSSpec* spec) override;
OSErr OpenFork(const FSSpec* spec, ForkType forkType, char permission, std::unique_ptr<ForkHandle>& stream) override; OSErr OpenFork(const FSSpec* spec, ForkType forkType, char permission, std::unique_ptr<ForkHandle>& stream) override;
@ -39,6 +41,6 @@ namespace Pomme::Files
OSErr FSpDelete(const FSSpec* spec) override; OSErr FSpDelete(const FSSpec* spec) override;
OSErr DirCreate(long parentDirID, const std::string& directoryName, long* createdDirID) override; OSErr DirCreate(long parentDirID, const u8string& directoryName, long* createdDirID) override;
}; };
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "Utilities/StringUtils.h"
namespace Pomme::Files namespace Pomme::Files
{ {
@ -48,7 +49,7 @@ namespace Pomme::Files
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Toolbox API Implementation // Toolbox API Implementation
virtual OSErr FSMakeFSSpec(long dirID, const std::string& suffix, FSSpec* spec) = 0; virtual OSErr FSMakeFSSpec(long dirID, const u8string& suffix, FSSpec* spec) = 0;
virtual OSErr OpenFork(const FSSpec* spec, ForkType forkType, char permission, std::unique_ptr<ForkHandle>& handle) = 0; virtual OSErr OpenFork(const FSSpec* spec, ForkType forkType, char permission, std::unique_ptr<ForkHandle>& handle) = 0;
@ -56,6 +57,6 @@ namespace Pomme::Files
virtual OSErr FSpDelete(const FSSpec* spec) = 0; virtual OSErr FSpDelete(const FSSpec* spec) = 0;
virtual OSErr DirCreate(long parentDirID, const std::string& directoryName, long* createdDirID) = 0; virtual OSErr DirCreate(long parentDirID, const u8string& directoryName, long* createdDirID) = 0;
}; };
} }

View File

@ -1,14 +1,22 @@
#undef NOUSER #undef NOUSER
#include "PommeDebug.h"
#include "Platform/Windows/PommeWindows.h" #include "Platform/Windows/PommeWindows.h"
#include <shlobj.h> #include <shlobj.h>
std::filesystem::path Pomme::Platform::Windows::GetPreferencesFolder() std::filesystem::path Pomme::Platform::Windows::GetPreferencesFolder()
{ {
wchar_t* wpath = nullptr; PWSTR wpath = nullptr;
SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &wpath); HRESULT result = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &wpath);
auto path = std::filesystem::path(wpath);
std::filesystem::path path = "";
if (result == S_OK)
{
path = std::filesystem::path(wpath);
}
CoTaskMemFree(static_cast<void*>(wpath)); CoTaskMemFree(static_cast<void*>(wpath));
return path; return path;
} }

View File

@ -6,13 +6,33 @@
#include <sstream> #include <sstream>
#include <cstdint> #include <cstdint>
#define POMME_DEBUG_MEMORY false #if !defined(POMME_DEBUG_MEMORY)
#define POMME_DEBUG_SOUND false #define POMME_DEBUG_MEMORY 0
#define POMME_DEBUG_PICT false #endif
#define POMME_DEBUG_FILES false
#define POMME_DEBUG_RESOURCES false #if !defined(POMME_DEBUG_SOUND)
#define POMME_DEBUG_INPUT false #define POMME_DEBUG_SOUND 0
#define POMME_DEBUG_3DMF false #endif
#if !defined(POMME_DEBUG_PICT)
#define POMME_DEBUG_PICT 0
#endif
#if !defined(POMME_DEBUG_FILES)
#define POMME_DEBUG_FILES 0
#endif
#if !defined(POMME_DEBUG_RESOURCES)
#define POMME_DEBUG_RESOURCES 0
#endif
#if !defined(POMME_DEBUG_INPUT)
#define POMME_DEBUG_INPUT 0
#endif
#if !defined(POMME_DEBUG_3DMF)
#define POMME_DEBUG_3DMF 0
#endif
#define POMME_GENLOG(define, prefix) if (!define) {} else std::cout << "[" << prefix << "] " << __func__ << ":\t" #define POMME_GENLOG(define, prefix) if (!define) {} else std::cout << "[" << prefix << "] " << __func__ << ":\t"
#define POMME_GENLOG_NOPREFIX(define) if (!define) {} else std::cout #define POMME_GENLOG_NOPREFIX(define) if (!define) {} else std::cout

View File

@ -268,8 +268,9 @@ SndListHandle Pomme_SndLoadFileAsResource(short fRefNum)
auto& spec = Pomme::Files::GetSpec(fRefNum); auto& spec = Pomme::Files::GetSpec(fRefNum);
auto& stream = Pomme::Files::GetStream(fRefNum); auto& stream = Pomme::Files::GetStream(fRefNum);
std::string fileName = UppercaseCopy(spec.cName); u8string fileName((const char8_t*) spec.cName);
fs::path extension = fs::path(AsU8(fileName)).extension(); fileName = UppercaseCopy(fileName);
fs::path extension = fs::path(fileName).extension();
// Guess media container from extension // Guess media container from extension
if (extension == ".AIFF" if (extension == ".AIFF"

View File

@ -3,9 +3,9 @@
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
std::string UppercaseCopy(const std::string& in) std::u8string UppercaseCopy(const u8string& in)
{ {
std::string out; std::u8string out;
std::transform( std::transform(
in.begin(), in.begin(),
in.end(), in.end(),
@ -16,13 +16,3 @@ std::string UppercaseCopy(const std::string& in)
}); });
return out; return out;
} }
u8string AsU8(const std::string s)
{
return u8string(s.begin(), s.end());
}
std::string FromU8(const u8string u8s)
{
return std::string(u8s.begin(), u8s.end());
}

View File

@ -6,10 +6,7 @@
typedef std::u8string u8string; typedef std::u8string u8string;
#else #else
typedef std::string u8string; typedef std::string u8string;
typedef char char8_t;
#endif #endif
std::string UppercaseCopy(const std::string&); u8string UppercaseCopy(const u8string&);
u8string AsU8(const std::string);
std::string FromU8(const u8string);