diff --git a/Aerofoil.sln b/Aerofoil.sln
index 29fe237..f40e54d 100644
--- a/Aerofoil.sln
+++ b/Aerofoil.sln
@@ -49,6 +49,7 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "ReleasePackageInstaller", "
{B852D549-4020-4477-8BFB-E199FF78B047} = {B852D549-4020-4477-8BFB-E199FF78B047}
{2FF15659-5C72-48B8-B55B-3C658E4125B5} = {2FF15659-5C72-48B8-B55B-3C658E4125B5}
{3B7FD18D-7A50-4DF5-AC25-543E539BFACE} = {3B7FD18D-7A50-4DF5-AC25-543E539BFACE}
+ {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67} = {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}
{36DAF5FA-6ADB-4F20-9810-1610DE0AE653} = {36DAF5FA-6ADB-4F20-9810-1610DE0AE653}
EndProjectSection
EndProject
@@ -68,6 +69,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GenerateFonts", "GenerateFo
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2h", "bin2h\bin2h.vcxproj", "{D045F28D-F245-44DD-B576-CC91BF3BE6E9}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HouseTool", "HouseTool\HouseTool.vcxproj", "{B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -188,6 +191,10 @@ Global
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Debug|x64.Build.0 = Debug|x64
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Release|x64.ActiveCfg = Release|x64
{D045F28D-F245-44DD-B576-CC91BF3BE6E9}.Release|x64.Build.0 = Release|x64
+ {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}.Debug|x64.ActiveCfg = Debug|x64
+ {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}.Debug|x64.Build.0 = Debug|x64
+ {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}.Release|x64.ActiveCfg = Release|x64
+ {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Aerofoil/Aerofoil.vcxproj b/Aerofoil/Aerofoil.vcxproj
index 074ea6e..9a46344 100644
--- a/Aerofoil/Aerofoil.vcxproj
+++ b/Aerofoil/Aerofoil.vcxproj
@@ -43,6 +43,7 @@
+
@@ -52,6 +53,7 @@
+
@@ -82,6 +84,7 @@
+
diff --git a/Aerofoil/Aerofoil.vcxproj.filters b/Aerofoil/Aerofoil.vcxproj.filters
index ded91bd..6e8d027 100644
--- a/Aerofoil/Aerofoil.vcxproj.filters
+++ b/Aerofoil/Aerofoil.vcxproj.filters
@@ -28,6 +28,9 @@
Source Files
+
+ Source Files
+
diff --git a/Aerofoil/GpBWCursor_Win32.cpp b/Aerofoil/GpBWCursor_Win32.cpp
index da4a07e..01d1cd9 100644
--- a/Aerofoil/GpBWCursor_Win32.cpp
+++ b/Aerofoil/GpBWCursor_Win32.cpp
@@ -21,6 +21,7 @@
#include "GpBWCursor_Win32.h"
#include "GpWindows.h"
+#include "IGpAllocator.h"
#include
#include
@@ -34,19 +35,19 @@ void GpBWCursor_Win32::Destroy()
this->DecRef();
}
-IGpCursor_Win32 *GpBWCursor_Win32::Create(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY)
+IGpCursor_Win32 *GpBWCursor_Win32::Create(IGpAllocator *alloc, size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY)
{
size_t numBits = width * height;
- size_t numBytes = (width * height + 7) / 8;
- uint8_t *convertedAndData = static_cast(malloc(numBytes));
- uint8_t *convertedXorData = static_cast(malloc(numBytes));
+ size_t numBytes = (numBits + 7) / 8;
+ uint8_t *convertedAndData = static_cast(alloc->Alloc(numBytes));
+ uint8_t *convertedXorData = static_cast(alloc->Alloc(numBytes));
if (!convertedAndData || !convertedXorData)
{
if (convertedAndData)
- free(convertedAndData);
+ alloc->Release(convertedAndData);
if (convertedXorData)
- free(convertedXorData);
+ alloc->Release(convertedXorData);
return nullptr;
}
@@ -62,25 +63,26 @@ IGpCursor_Win32 *GpBWCursor_Win32::Create(size_t width, size_t height, const voi
HCURSOR hcursor = CreateCursor(g_gpWindowsGlobals.m_hInstance, static_cast(hotSpotX), static_cast(hotSpotY), static_cast(width), static_cast(height), convertedAndData, convertedXorData);
- free(convertedAndData);
- free(convertedXorData);
+ alloc->Release(convertedAndData);
+ alloc->Release(convertedXorData);
if (!hcursor)
return nullptr;
- void *storage = malloc(sizeof(GpBWCursor_Win32));
+ void *storage = alloc->Alloc(sizeof(GpBWCursor_Win32));
if (!storage)
{
DestroyCursor(hcursor);
return nullptr;
}
- return new (storage) GpBWCursor_Win32(hcursor);
+ return new (storage) GpBWCursor_Win32(hcursor, alloc);
}
-GpBWCursor_Win32::GpBWCursor_Win32(HCURSOR cursor)
+GpBWCursor_Win32::GpBWCursor_Win32(HCURSOR cursor, IGpAllocator *alloc)
: m_cursor(cursor)
, m_refCount(1)
+ , m_alloc(alloc)
{
}
@@ -104,7 +106,8 @@ void GpBWCursor_Win32::DecRef()
m_refCount--;
if (m_refCount == 0)
{
+ IGpAllocator *alloc = m_alloc;
this->~GpBWCursor_Win32();
- free(this);
+ alloc->Release(this);
}
}
diff --git a/Aerofoil/GpBWCursor_Win32.h b/Aerofoil/GpBWCursor_Win32.h
index 070bb7b..92958d8 100644
--- a/Aerofoil/GpBWCursor_Win32.h
+++ b/Aerofoil/GpBWCursor_Win32.h
@@ -3,6 +3,8 @@
#include "IGpCursor_Win32.h"
#include "GpWindows.h"
+struct IGpAllocator;
+
class GpBWCursor_Win32 final : public IGpCursor_Win32
{
public:
@@ -13,12 +15,13 @@ public:
void IncRef() override;
void DecRef() override;
- static IGpCursor_Win32 *Create(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY);
+ static IGpCursor_Win32 *Create(IGpAllocator *alloc, size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY);
private:
- GpBWCursor_Win32(HCURSOR cursor);
+ GpBWCursor_Win32(HCURSOR cursor, IGpAllocator *alloc);
~GpBWCursor_Win32();
HCURSOR m_cursor;
int m_refCount;
+ IGpAllocator *m_alloc;
};
diff --git a/Aerofoil/GpColorCursor_Win32.cpp b/Aerofoil/GpColorCursor_Win32.cpp
index 5dbfd84..07dc4be 100644
--- a/Aerofoil/GpColorCursor_Win32.cpp
+++ b/Aerofoil/GpColorCursor_Win32.cpp
@@ -20,6 +20,7 @@
*/
#include "GpColorCursor_Win32.h"
+#include "IGpAllocator.h"
#include
#include
@@ -31,7 +32,7 @@ void GpColorCursor_Win32::Destroy()
this->DecRef();
}
-IGpCursor_Win32 *GpColorCursor_Win32::Create(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY)
+IGpCursor_Win32 *GpColorCursor_Win32::Create(IGpAllocator *alloc, size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY)
{
const size_t paddingBits = (sizeof(void*) * 8);
@@ -52,7 +53,7 @@ IGpCursor_Win32 *GpColorCursor_Win32::Create(size_t width, size_t height, const
size_t maskPitch = width + paddingBits - 1;
maskPitch -= maskPitch % paddingBits;
- LPVOID maskBits = malloc(maskPitch * height);
+ LPVOID maskBits = alloc->Alloc(maskPitch * height);
if (!maskBits)
return nullptr;
@@ -71,6 +72,8 @@ IGpCursor_Win32 *GpColorCursor_Win32::Create(size_t width, size_t height, const
ii.hbmMask = CreateBitmap(width, height, 1, 1, maskBits);
ReleaseDC(NULL, hdc);
+ alloc->Release(maskBits);
+
size_t cursorPitch = width * 4;
size_t numPixels = width * height;
@@ -90,19 +93,20 @@ IGpCursor_Win32 *GpColorCursor_Win32::Create(size_t width, size_t height, const
if (!hicon)
return nullptr;
- void *storage = malloc(sizeof(GpColorCursor_Win32));
+ void *storage = alloc->Alloc(sizeof(GpColorCursor_Win32));
if (!storage)
{
DestroyIcon(hicon);
return nullptr;
}
- return new (storage) GpColorCursor_Win32(reinterpret_cast(hicon));
+ return new (storage) GpColorCursor_Win32(alloc, reinterpret_cast(hicon));
}
-GpColorCursor_Win32::GpColorCursor_Win32(HCURSOR cursor)
+GpColorCursor_Win32::GpColorCursor_Win32(IGpAllocator *alloc, HCURSOR cursor)
: m_cursor(cursor)
, m_refCount(1)
+ , m_alloc(alloc)
{
}
@@ -126,7 +130,8 @@ void GpColorCursor_Win32::DecRef()
m_refCount--;
if (m_refCount == 0)
{
+ IGpAllocator *alloc = m_alloc;
this->~GpColorCursor_Win32();
- free(this);
+ alloc->Release(this);
}
}
diff --git a/Aerofoil/GpColorCursor_Win32.h b/Aerofoil/GpColorCursor_Win32.h
index a451ea2..b030f60 100644
--- a/Aerofoil/GpColorCursor_Win32.h
+++ b/Aerofoil/GpColorCursor_Win32.h
@@ -3,6 +3,7 @@
#include "IGpCursor_Win32.h"
#include "GpWindows.h"
+struct IGpAllocator;
class GpColorCursor_Win32 final : public IGpCursor_Win32
{
@@ -14,12 +15,13 @@ public:
void IncRef() override;
void DecRef() override;
- static IGpCursor_Win32 *Create(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY);
+ static IGpCursor_Win32 *Create(IGpAllocator *alloc, size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY);
private:
- GpColorCursor_Win32(HCURSOR cursor);
+ GpColorCursor_Win32(IGpAllocator *alloc, HCURSOR cursor);
~GpColorCursor_Win32();
HCURSOR m_cursor;
int m_refCount;
+ IGpAllocator *m_alloc;
};
diff --git a/Aerofoil/GpFileStream_Win32.h b/Aerofoil/GpFileStream_Win32.h
index fdedf17..9a2767b 100644
--- a/Aerofoil/GpFileStream_Win32.h
+++ b/Aerofoil/GpFileStream_Win32.h
@@ -19,9 +19,13 @@ public:
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
+#if GP_ASYNCIFY_PARANOID
+ void Close();
+#endif
+
private:
HANDLE m_handle;
bool m_readable;
diff --git a/Aerofoil/GpFileSystem_Win32.cpp b/Aerofoil/GpFileSystem_Win32.cpp
index 5cdb345..485fbcc 100644
--- a/Aerofoil/GpFileSystem_Win32.cpp
+++ b/Aerofoil/GpFileSystem_Win32.cpp
@@ -1,8 +1,10 @@
#include "GpFileSystem_Win32.h"
+#include "GpAllocator_C.h"
#include "GpApplicationName.h"
#include "GpFileStream_Win32.h"
#include "GpWindows.h"
+#include "IGpAllocator.h"
#include "IGpDirectoryCursor.h"
#include
@@ -12,33 +14,36 @@
#include
+struct IGpAllocator;
+
extern GpWindowsGlobals g_gpWindowsGlobals;
class GpDirectoryCursor_Win32 final : public IGpDirectoryCursor
{
public:
- static GpDirectoryCursor_Win32 *Create(const HANDLE &handle, const WIN32_FIND_DATAW &findData);
+ static GpDirectoryCursor_Win32 *Create(IGpAllocator *alloc, const HANDLE &handle, const WIN32_FIND_DATAW &findData);
bool GetNext(const char *&outFileName) override;
void Destroy() override;
private:
- GpDirectoryCursor_Win32(const HANDLE &handle, const WIN32_FIND_DATAW &findData);
+ GpDirectoryCursor_Win32(IGpAllocator *alloc, const HANDLE &handle, const WIN32_FIND_DATAW &findData);
~GpDirectoryCursor_Win32();
+ IGpAllocator *m_alloc;
HANDLE m_handle;
WIN32_FIND_DATAW m_findData;
char m_chars[MAX_PATH + 1];
bool m_haveNext;
};
-GpDirectoryCursor_Win32 *GpDirectoryCursor_Win32::Create(const HANDLE &handle, const WIN32_FIND_DATAW &findData)
+GpDirectoryCursor_Win32 *GpDirectoryCursor_Win32::Create(IGpAllocator *alloc, const HANDLE &handle, const WIN32_FIND_DATAW &findData)
{
- void *storage = malloc(sizeof(GpDirectoryCursor_Win32));
+ void *storage = alloc->Alloc(sizeof(GpDirectoryCursor_Win32));
if (!storage)
return nullptr;
- return new (storage) GpDirectoryCursor_Win32(handle, findData);
+ return new (storage) GpDirectoryCursor_Win32(alloc, handle, findData);
}
bool GpDirectoryCursor_Win32::GetNext(const char *&outFileName)
@@ -82,14 +87,16 @@ bool GpDirectoryCursor_Win32::GetNext(const char *&outFileName)
void GpDirectoryCursor_Win32::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpDirectoryCursor_Win32();
- free(this);
+ alloc->Release(this);
}
-GpDirectoryCursor_Win32::GpDirectoryCursor_Win32(const HANDLE &handle, const WIN32_FIND_DATAW &findData)
+GpDirectoryCursor_Win32::GpDirectoryCursor_Win32(IGpAllocator *alloc, const HANDLE &handle, const WIN32_FIND_DATAW &findData)
: m_handle(handle)
, m_findData(findData)
, m_haveNext(true)
+ , m_alloc(alloc)
{
}
@@ -99,6 +106,7 @@ GpDirectoryCursor_Win32::~GpDirectoryCursor_Win32()
}
GpFileSystem_Win32::GpFileSystem_Win32()
+ : m_alloc(GpAllocator_C::GetInstance())
{
// GP TODO: This shouldn't be static init since it allocates memory
m_executablePath[0] = 0;
@@ -137,6 +145,7 @@ GpFileSystem_Win32::GpFileSystem_Win32()
m_userSavesDir.append(L"\\");
m_logsDir.append(L"\\");
m_fontCacheDir.append(L"\\");
+ m_resourcesDir.append(L"\\");
}
DWORD modulePathSize = GetModuleFileNameW(nullptr, m_executablePath, MAX_PATH);
@@ -177,6 +186,7 @@ GpFileSystem_Win32::GpFileSystem_Win32()
{
m_packagedDir = std::wstring(m_executablePath) + L"Packaged\\";
m_housesDir = std::wstring(m_executablePath) + L"Packaged\\Houses\\";
+ m_resourcesDir = std::wstring(m_executablePath) + L"Resources\\";
}
}
@@ -275,7 +285,7 @@ IGpDirectoryCursor *GpFileSystem_Win32::ScanDirectoryNested(PortabilityLayer::Vi
{
wchar_t winPath[MAX_PATH + 2];
- const char **expandedPaths = static_cast(malloc(sizeof(const char*) * (numPaths + 1)));
+ const char **expandedPaths = static_cast(m_alloc->Alloc(sizeof(const char*) * (numPaths + 1)));
if (!expandedPaths)
return nullptr;
@@ -284,7 +294,7 @@ IGpDirectoryCursor *GpFileSystem_Win32::ScanDirectoryNested(PortabilityLayer::Vi
expandedPaths[numPaths] = "*";
const bool isPathResolved = ResolvePath(virtualDirectory, expandedPaths, numPaths + 1, winPath);
- free(expandedPaths);
+ m_alloc->Release(expandedPaths);
if (!isPathResolved)
return nullptr;
@@ -295,7 +305,7 @@ IGpDirectoryCursor *GpFileSystem_Win32::ScanDirectoryNested(PortabilityLayer::Vi
if (ff == INVALID_HANDLE_VALUE)
return nullptr;
- return GpDirectoryCursor_Win32::Create(ff, findData);
+ return GpDirectoryCursor_Win32::Create(m_alloc, ff, findData);
}
bool GpFileSystem_Win32::ValidateFilePathUnicodeChar(uint32_t c) const
@@ -453,9 +463,6 @@ bool GpFileSystem_Win32::ResolvePath(PortabilityLayer::VirtualDirectory_t virtua
case PortabilityLayer::VirtualDirectories::kLogs:
baseDir = m_logsDir.c_str();
break;
- case PortabilityLayer::VirtualDirectories::kFontCache:
- baseDir = m_fontCacheDir.c_str();
- break;
default:
return false;
}
diff --git a/Aerofoil/GpFileSystem_Win32.h b/Aerofoil/GpFileSystem_Win32.h
index 6deff90..45acb89 100644
--- a/Aerofoil/GpFileSystem_Win32.h
+++ b/Aerofoil/GpFileSystem_Win32.h
@@ -41,5 +41,7 @@ private:
std::wstring m_fontCacheDir;
wchar_t m_executablePath[MAX_PATH];
+ IGpAllocator *m_alloc;
+
static GpFileSystem_Win32 ms_instance;
};
diff --git a/Aerofoil/GpLogDriver_Win32.cpp b/Aerofoil/GpLogDriver_Win32.cpp
index 3ac6ea1..1ab20f4 100644
--- a/Aerofoil/GpLogDriver_Win32.cpp
+++ b/Aerofoil/GpLogDriver_Win32.cpp
@@ -1,3 +1,4 @@
+#include "GpAllocator_C.h"
#include "GpLogDriver_Win32.h"
#include "GpFileSystem_Win32.h"
@@ -7,6 +8,7 @@
GpLogDriver_Win32::GpLogDriver_Win32()
: m_stream(nullptr)
, m_isInitialized(false)
+ , m_alloc(GpAllocator_C::GetInstance())
{
}
@@ -58,14 +60,14 @@ void GpLogDriver_Win32::VPrintf(Category category, const char *fmt, va_list args
if (formattedSize <= 0)
return;
- char *charBuff = static_cast(malloc(formattedSize + 1));
+ char *charBuff = static_cast(m_alloc->Alloc(formattedSize + 1));
if (!charBuff)
return;
vsnprintf(charBuff, formattedSize + 1, fmt, args);
m_stream->Write(charBuff, formattedSize);
- free(charBuff);
+ m_alloc->Release(charBuff);
}
m_stream->Write("\n", 1);
diff --git a/Aerofoil/GpLogDriver_Win32.h b/Aerofoil/GpLogDriver_Win32.h
index fe7f9a2..b607cd7 100644
--- a/Aerofoil/GpLogDriver_Win32.h
+++ b/Aerofoil/GpLogDriver_Win32.h
@@ -3,6 +3,7 @@
#include "IGpLogDriver.h"
class GpIOStream;
+struct IGpAllocator;
class GpLogDriver_Win32 : public IGpLogDriver
{
@@ -20,6 +21,7 @@ private:
void InitInternal();
GpIOStream *m_stream;
+ IGpAllocator *m_alloc;
bool m_isInitialized;
static GpLogDriver_Win32 ms_instance;
diff --git a/Aerofoil/GpMain_Win32.cpp b/Aerofoil/GpMain_Win32.cpp
index 6a5fc5c..2343ac7 100644
--- a/Aerofoil/GpMain_Win32.cpp
+++ b/Aerofoil/GpMain_Win32.cpp
@@ -1,4 +1,5 @@
#include "GpMain.h"
+#include "GpAllocator_C.h"
#include "GpAudioDriverFactory.h"
#include "GpBWCursor_Win32.h"
#include "GpColorCursor_Win32.h"
@@ -410,12 +411,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
}
IGpLogDriver *logger = GpLogDriver_Win32::GetInstance();
+ IGpAllocator *alloc = GpAllocator_C::GetInstance();
+ IGpSystemServices *sysServices = GpSystemServices_Win32::GetInstance();
GpDriverCollection *drivers = GpAppInterface_Get()->PL_GetDriverCollection();
drivers->SetDriver(GpFileSystem_Win32::GetInstance());
- drivers->SetDriver(GpSystemServices_Win32::GetInstance());
- drivers->SetDriver(GpLogDriver_Win32::GetInstance());
+ drivers->SetDriver(sysServices);
+ drivers->SetDriver(logger);
+ drivers->SetDriver(alloc);
g_gpWindowsGlobals.m_hInstance = hInstance;
g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance;
@@ -448,7 +452,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
g_gpGlobalConfig.m_logger = logger;
- g_gpGlobalConfig.m_systemServices = GpSystemServices_Win32::GetInstance();
+ g_gpGlobalConfig.m_systemServices = sysServices;
+ g_gpGlobalConfig.m_allocator = alloc;
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDriver_CreateDisplayDriver_D3D11);
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2);
diff --git a/Aerofoil/GpMutex_Win32.cpp b/Aerofoil/GpMutex_Win32.cpp
index 849fc4f..a5acb2b 100644
--- a/Aerofoil/GpMutex_Win32.cpp
+++ b/Aerofoil/GpMutex_Win32.cpp
@@ -1,5 +1,6 @@
#include "GpMutex_Win32.h"
+#include "IGpAllocator.h"
#include "GpWindows.h"
#include
@@ -7,8 +8,9 @@
void GpMutex_Win32::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpMutex_Win32();
- free(this);
+ alloc->Release(this);
}
void GpMutex_Win32::Lock()
@@ -22,16 +24,17 @@ void GpMutex_Win32::Unlock()
}
-GpMutex_Win32 *GpMutex_Win32::Create()
+GpMutex_Win32 *GpMutex_Win32::Create(IGpAllocator *alloc)
{
- void *storage = malloc(sizeof(GpMutex_Win32));
+ void *storage = alloc->Alloc(sizeof(GpMutex_Win32));
if (!storage)
return nullptr;
- return new (storage) GpMutex_Win32();
+ return new (storage) GpMutex_Win32(alloc);
}
-GpMutex_Win32::GpMutex_Win32()
+GpMutex_Win32::GpMutex_Win32(IGpAllocator *alloc)
+ : m_alloc(alloc)
{
InitializeCriticalSection(&m_critSection);
}
diff --git a/Aerofoil/GpMutex_Win32.h b/Aerofoil/GpMutex_Win32.h
index 6b7ca86..d9bf6fb 100644
--- a/Aerofoil/GpMutex_Win32.h
+++ b/Aerofoil/GpMutex_Win32.h
@@ -4,6 +4,8 @@
#include "GpWindows.h"
+struct IGpAllocator;
+
class GpMutex_Win32 final : public IGpMutex
{
public:
@@ -11,11 +13,12 @@ public:
void Lock() override;
void Unlock() override;
- static GpMutex_Win32 *Create();
+ static GpMutex_Win32 *Create(IGpAllocator *alloc);
private:
- const GpMutex_Win32();
+ explicit GpMutex_Win32(IGpAllocator *alloc);
~GpMutex_Win32();
CRITICAL_SECTION m_critSection;
+ IGpAllocator *m_alloc;
};
diff --git a/Aerofoil/GpSystemServices_Win32.cpp b/Aerofoil/GpSystemServices_Win32.cpp
index 8758638..f1e5f86 100644
--- a/Aerofoil/GpSystemServices_Win32.cpp
+++ b/Aerofoil/GpSystemServices_Win32.cpp
@@ -2,11 +2,11 @@
#include "GpMutex_Win32.h"
#include "GpThreadEvent_Win32.h"
#include "GpWindows.h"
+#include "GpAllocator_C.h"
#include "IGpClipboardContents.h"
-#include "UTF16.h"
-#include "UTF8.h"
+#include "GpUnicode.h"
#include
#include
@@ -134,6 +134,7 @@ static DWORD WINAPI StaticStartThread(LPVOID lpThreadParameter)
GpSystemServices_Win32::GpSystemServices_Win32()
: m_isTouchscreenSimulation(false)
+ , m_alloc(GpAllocator_C::GetInstance())
{
}
@@ -181,17 +182,17 @@ void GpSystemServices_Win32::GetLocalDateTime(unsigned int &year, unsigned int &
IGpMutex *GpSystemServices_Win32::CreateMutex()
{
- return GpMutex_Win32::Create();
+ return GpMutex_Win32::Create(m_alloc);
}
IGpMutex *GpSystemServices_Win32::CreateRecursiveMutex()
{
- return GpMutex_Win32::Create();
+ return GpMutex_Win32::Create(m_alloc);
}
IGpThreadEvent *GpSystemServices_Win32::CreateThreadEvent(bool autoReset, bool startSignaled)
{
- return GpThreadEvent_Win32::Create(autoReset, startSignaled);
+ return GpThreadEvent_Win32::Create(m_alloc, autoReset, startSignaled);
}
void *GpSystemServices_Win32::CreateThread(ThreadFunc_t threadFunc, void *context)
diff --git a/Aerofoil/GpSystemServices_Win32.h b/Aerofoil/GpSystemServices_Win32.h
index 90b26b2..d72e2b8 100644
--- a/Aerofoil/GpSystemServices_Win32.h
+++ b/Aerofoil/GpSystemServices_Win32.h
@@ -48,6 +48,8 @@ public:
private:
bool m_isTouchscreenSimulation;
+ IGpAllocator *m_alloc;
+
static GpSystemServices_Win32 ms_instance;
};
diff --git a/Aerofoil/GpThreadEvent_Win32.cpp b/Aerofoil/GpThreadEvent_Win32.cpp
index 1497d10..52d38ee 100644
--- a/Aerofoil/GpThreadEvent_Win32.cpp
+++ b/Aerofoil/GpThreadEvent_Win32.cpp
@@ -1,4 +1,5 @@
#include "GpThreadEvent_Win32.h"
+#include "IGpAllocator.h"
#include
#include
@@ -20,28 +21,30 @@ void GpThreadEvent_Win32::Signal()
void GpThreadEvent_Win32::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpThreadEvent_Win32();
- free(this);
+ alloc->Release(this);
}
-GpThreadEvent_Win32 *GpThreadEvent_Win32::Create(bool autoReset, bool startSignaled)
+GpThreadEvent_Win32 *GpThreadEvent_Win32::Create(IGpAllocator *alloc, bool autoReset, bool startSignaled)
{
HANDLE handle = CreateEventA(nullptr, autoReset ? FALSE : TRUE, startSignaled ? TRUE : FALSE, nullptr);
if (handle == nullptr)
return nullptr;
- void *storage = malloc(sizeof(GpThreadEvent_Win32));
+ void *storage = alloc->Alloc(sizeof(GpThreadEvent_Win32));
if (!storage)
{
CloseHandle(handle);
return nullptr;
}
- return new (storage) GpThreadEvent_Win32(handle);
+ return new (storage) GpThreadEvent_Win32(alloc, handle);
}
-GpThreadEvent_Win32::GpThreadEvent_Win32(const HANDLE &handle)
+GpThreadEvent_Win32::GpThreadEvent_Win32(IGpAllocator *alloc, const HANDLE &handle)
: m_event(handle)
+ , m_alloc(alloc)
{
}
diff --git a/Aerofoil/GpThreadEvent_Win32.h b/Aerofoil/GpThreadEvent_Win32.h
index 20454de..dd6d3f3 100644
--- a/Aerofoil/GpThreadEvent_Win32.h
+++ b/Aerofoil/GpThreadEvent_Win32.h
@@ -12,11 +12,12 @@ public:
void Signal() override;
void Destroy() override;
- static GpThreadEvent_Win32 *Create(bool autoReset, bool startSignaled);
+ static GpThreadEvent_Win32 *Create(IGpAllocator *alloc, bool autoReset, bool startSignaled);
private:
- explicit GpThreadEvent_Win32(const HANDLE &handle);
+ explicit GpThreadEvent_Win32(IGpAllocator *alloc, const HANDLE &handle);
~GpThreadEvent_Win32();
HANDLE m_event;
+ IGpAllocator *m_alloc;
};
diff --git a/AerofoilAndroid/app/jni/main/GpFileSystem_Android.cpp b/AerofoilAndroid/app/jni/main/GpFileSystem_Android.cpp
index b6cb544..a04600c 100644
--- a/AerofoilAndroid/app/jni/main/GpFileSystem_Android.cpp
+++ b/AerofoilAndroid/app/jni/main/GpFileSystem_Android.cpp
@@ -424,9 +424,6 @@ bool GpFileSystem_Android::ResolvePath(PortabilityLayer::VirtualDirectory_t virt
case PortabilityLayer::VirtualDirectories::kPrefs:
prefsAppend = "Prefs";
break;
- case PortabilityLayer::VirtualDirectories::kFontCache:
- prefsAppend = "FontCache";
- break;
default:
return false;
};
diff --git a/AerofoilPortable.props b/AerofoilPortable.props
index 08b2b3e..5412b99 100644
--- a/AerofoilPortable.props
+++ b/AerofoilPortable.props
@@ -1,8 +1,10 @@
-
+
-
+
+ $(SolutionDir)AerofoilPortable;$(IncludePath)
+
-
+
\ No newline at end of file
diff --git a/AerofoilPortable/GpAllocator_C.cpp b/AerofoilPortable/GpAllocator_C.cpp
new file mode 100644
index 0000000..247bfb5
--- /dev/null
+++ b/AerofoilPortable/GpAllocator_C.cpp
@@ -0,0 +1,115 @@
+#include "GpAllocator_C.h"
+#include "CoreDefs.h"
+
+#include
+#include
+#include
+
+struct GpAllocator_C_MMBlock
+{
+ uint8_t m_offsetFromAllocLocation;
+
+ static size_t AlignedSize();
+};
+
+size_t GpAllocator_C_MMBlock::AlignedSize()
+{
+ const size_t paddedSize = sizeof(GpAllocator_C_MMBlock) + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
+ const size_t paddedSizeTruncated = paddedSize - (paddedSize % GP_SYSTEM_MEMORY_ALIGNMENT);
+
+ return paddedSizeTruncated;
+}
+
+void *GpAllocator_C::Realloc(void *buf, size_t newSize)
+{
+ if (buf == nullptr)
+ {
+ if (newSize == 0)
+ return nullptr;
+
+ return this->Alloc(newSize);
+ }
+
+ if (newSize == 0)
+ {
+ this->Free(buf);
+ return nullptr;
+ }
+
+ assert(buf != nullptr);
+
+ const size_t mmBlockSize = GpAllocator_C_MMBlock::AlignedSize();
+ uint8_t *oldBufBytes = static_cast(buf);
+ const GpAllocator_C_MMBlock *oldBufMMBlock = reinterpret_cast(oldBufBytes - GpAllocator_C_MMBlock::AlignedSize());
+
+ const size_t oldBufOffsetFromAlignLoc = oldBufMMBlock->m_offsetFromAllocLocation;
+ uint8_t *oldBufBase = oldBufBytes - GpAllocator_C_MMBlock::AlignedSize() - oldBufOffsetFromAlignLoc;
+
+ const size_t mmBlockSizeWithMaxPadding = GpAllocator_C_MMBlock::AlignedSize() + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
+ if (SIZE_MAX - newSize < mmBlockSizeWithMaxPadding)
+ return nullptr;
+
+ const size_t newBufferSize = newSize + mmBlockSizeWithMaxPadding;
+ uint8_t *newBuffer = static_cast(realloc(oldBufBase, newSize + mmBlockSizeWithMaxPadding));
+ if (!newBuffer)
+ return nullptr;
+
+ const intptr_t offsetFromAlignPoint = reinterpret_cast(newBuffer) & static_cast(GP_SYSTEM_MEMORY_ALIGNMENT - 1);
+ intptr_t alignPadding = 0;
+ if (offsetFromAlignPoint != 0)
+ alignPadding = static_cast(GP_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint;
+
+ // Check if the alignment changed, if so relocate
+ if (static_cast(alignPadding) != oldBufOffsetFromAlignLoc)
+ memmove(newBuffer + alignPadding, newBuffer + oldBufOffsetFromAlignLoc, GpAllocator_C_MMBlock::AlignedSize() + newSize);
+
+ GpAllocator_C_MMBlock *newMMBlock = reinterpret_cast(newBuffer + alignPadding);
+ newMMBlock->m_offsetFromAllocLocation = static_cast(alignPadding);
+
+ return newBuffer + alignPadding + GpAllocator_C_MMBlock::AlignedSize();
+}
+
+void *GpAllocator_C::Alloc(size_t size)
+{
+ if (size == 0)
+ return nullptr;
+
+ const size_t mmBlockSizeWithMaxPadding = GpAllocator_C_MMBlock::AlignedSize() + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
+ if (SIZE_MAX - size < mmBlockSizeWithMaxPadding)
+ return nullptr;
+
+ uint8_t *buffer = static_cast(realloc(nullptr, size + mmBlockSizeWithMaxPadding));
+ if (!buffer)
+ return nullptr;
+
+ const intptr_t offsetFromAlignPoint = reinterpret_cast(buffer) & static_cast(GP_SYSTEM_MEMORY_ALIGNMENT - 1);
+ intptr_t alignPadding = 0;
+ if (offsetFromAlignPoint != 0)
+ alignPadding = static_cast(GP_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint;
+
+ GpAllocator_C_MMBlock *mmBlock = reinterpret_cast(buffer + alignPadding);
+ mmBlock->m_offsetFromAllocLocation = static_cast(alignPadding);
+
+ return buffer + alignPadding + GpAllocator_C_MMBlock::AlignedSize();
+}
+
+void GpAllocator_C::Free(void *buf)
+{
+ if (!buf)
+ return;
+
+ const size_t mmBlockSize = GpAllocator_C_MMBlock::AlignedSize();
+
+ uint8_t *bytes = static_cast(buf);
+ const GpAllocator_C_MMBlock *mmBlock = reinterpret_cast(bytes - GpAllocator_C_MMBlock::AlignedSize());
+
+ void *freeLoc = bytes - GpAllocator_C_MMBlock::AlignedSize() - mmBlock->m_offsetFromAllocLocation;
+ realloc(freeLoc, 0);
+}
+
+GpAllocator_C *GpAllocator_C::GetInstance()
+{
+ return &ms_instance;
+}
+
+GpAllocator_C GpAllocator_C::ms_instance;
diff --git a/AerofoilPortable/GpAllocator_C.h b/AerofoilPortable/GpAllocator_C.h
new file mode 100644
index 0000000..8325f31
--- /dev/null
+++ b/AerofoilPortable/GpAllocator_C.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "IGpAllocator.h"
+
+class GpAllocator_C final : public IGpAllocator
+{
+public:
+ void *Realloc(void *buf, size_t newSize) override;
+
+ static GpAllocator_C *GetInstance();
+
+private:
+ void *Alloc(size_t size);
+ void Free(void *ptr);
+
+ static GpAllocator_C ms_instance;
+};
diff --git a/AerofoilSDL/AerofoilSDL.vcxproj b/AerofoilSDL/AerofoilSDL.vcxproj
index d674526..071b61d 100644
--- a/AerofoilSDL/AerofoilSDL.vcxproj
+++ b/AerofoilSDL/AerofoilSDL.vcxproj
@@ -84,6 +84,7 @@
+
diff --git a/AerofoilSDL/AerofoilSDL.vcxproj.filters b/AerofoilSDL/AerofoilSDL.vcxproj.filters
index 3c86551..d5a22b0 100644
--- a/AerofoilSDL/AerofoilSDL.vcxproj.filters
+++ b/AerofoilSDL/AerofoilSDL.vcxproj.filters
@@ -66,6 +66,9 @@
Source Files
+
+ Source Files
+
diff --git a/AerofoilSDL/GpAudioDriver_SDL2.cpp b/AerofoilSDL/GpAudioDriver_SDL2.cpp
index 4255fe1..070697d 100644
--- a/AerofoilSDL/GpAudioDriver_SDL2.cpp
+++ b/AerofoilSDL/GpAudioDriver_SDL2.cpp
@@ -1,4 +1,5 @@
#include "CoreDefs.h"
+#include "IGpAudioBuffer.h"
#include "IGpAudioDriver.h"
#include "IGpAudioChannel.h"
#include "IGpAudioChannelCallbacks.h"
@@ -13,13 +14,21 @@
#include "SDL_atomic.h"
+#include
+#include
#include
#include
#include
#include
+#include
class GpAudioDriver_SDL2;
+typedef std::chrono::high_resolution_clock::duration GpAudioDriver_SDL2_Duration_t;
+typedef std::chrono::high_resolution_clock::time_point GpAudioDriver_SDL2_TimePoint_t;
+typedef std::chrono::high_resolution_clock::period GpAudioDriver_SDL2_Period_t;
+typedef std::chrono::high_resolution_clock::rep GpAudioDriver_SDL2_Rep_t;
+
static void *AlignedAlloc(size_t size, size_t alignment)
{
void *storage = malloc(size + alignment);
@@ -46,65 +55,130 @@ static void AlignedFree(void *ptr)
free(storageLoc);
}
-struct GpAudioChannelBufferChain_SDL2 final
-{
- GpAudioChannelBufferChain_SDL2();
-
- static GpAudioChannelBufferChain_SDL2 *Alloc();
- void Release();
-
- static const size_t kMaxCapacity = 65536;
-
- size_t m_consumed;
- size_t m_used;
- uint8_t m_data[kMaxCapacity];
- GpAudioChannelBufferChain_SDL2 *m_next;
- bool m_hasTrigger;
-};
-
-class GP_ALIGNED(GP_SYSTEM_MEMORY_ALIGNMENT) GpAudioChannel_SDL2 final : public IGpAudioChannel
+class GpAudioBuffer_SDL2 final : public IGpAudioBuffer
{
public:
- enum ChannelState
- {
- ChannelState_Idle,
- ChannelState_Playing,
- ChannelState_Stopped,
- };
+ static GpAudioBuffer_SDL2 *Create(const void *data, size_t size);
+ void AddRef() override;
+ void Release() override;
+
+ const void *GetData() const;
+ size_t GetSize() const;
+
+private:
+ GpAudioBuffer_SDL2(const void *data, size_t size);
+ ~GpAudioBuffer_SDL2();
+
+ void Destroy();
+
+ const void *m_data;
+ size_t m_size;
+ SDL_atomic_t m_count;
+};
+
+GpAudioBuffer_SDL2 *GpAudioBuffer_SDL2::Create(const void *data, size_t size)
+{
+ void *storage = malloc(size + sizeof(GpAudioBuffer_SDL2));
+ if (!storage)
+ return nullptr;
+
+ void *dataPos = static_cast(storage) + sizeof(GpAudioBuffer_SDL2);
+ memcpy(dataPos, data, size);
+
+ return new (storage) GpAudioBuffer_SDL2(dataPos, size);
+}
+
+
+void GpAudioBuffer_SDL2::AddRef()
+{
+ SDL_AtomicAdd(&m_count, 1);
+}
+
+void GpAudioBuffer_SDL2::Release()
+{
+ int prevCount = SDL_AtomicAdd(&m_count, -1);
+ if (prevCount == 1)
+ this->Destroy();
+}
+
+const void *GpAudioBuffer_SDL2::GetData() const
+{
+ return m_data;
+}
+
+size_t GpAudioBuffer_SDL2::GetSize() const
+{
+ return m_size;
+}
+
+
+GpAudioBuffer_SDL2::GpAudioBuffer_SDL2(const void *data, size_t size)
+ : m_data(data)
+ , m_size(size)
+{
+ SDL_AtomicSet(&m_count, 1);
+}
+
+GpAudioBuffer_SDL2::~GpAudioBuffer_SDL2()
+{
+}
+
+void GpAudioBuffer_SDL2::Destroy()
+{
+ this->~GpAudioBuffer_SDL2();
+ free(this);
+}
+
+
+class GpAudioChannel_SDL2 final : public IGpAudioChannel
+{
+public:
friend class GpAudioDriver_SDL2;
- GpAudioChannel_SDL2();
+ GpAudioChannel_SDL2(GpAudioDriver_SDL2_Duration_t latency, GpAudioDriver_SDL2_Duration_t bufferTime, size_t bufferSamplesMax, uint16_t sampleRate);
~GpAudioChannel_SDL2();
void AddRef();
void Release();
void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) override;
- void PostBuffer(const void *buffer, size_t bufferSize) override;
+ bool PostBuffer(IGpAudioBuffer *buffer) override;
void Stop() override;
void Destroy() override;
- void Consume(uint8_t *output, size_t sz);
+ void Consume(uint8_t *output, size_t sz, GpAudioDriver_SDL2_TimePoint_t mixStartTime, GpAudioDriver_SDL2_TimePoint_t mixEndTime);
- static GpAudioChannel_SDL2 *Alloc(GpAudioDriver_SDL2 *driver);
+ static GpAudioChannel_SDL2 *Alloc(GpAudioDriver_SDL2 *driver, GpAudioDriver_SDL2_Duration_t latency, GpAudioDriver_SDL2_Duration_t bufferTime, size_t bufferSamplesMax, uint16_t sampleRate);
private:
bool Init(GpAudioDriver_SDL2 *driver);
+ static const size_t kMaxBuffers = 16;
+
IGpAudioChannelCallbacks *m_callbacks;
IGpMutex *m_mutex;
GpAudioDriver_SDL2 *m_owner;
SDL_atomic_t m_refCount;
- GpAudioChannelBufferChain_SDL2 *m_firstPendingBuffer;
- GpAudioChannelBufferChain_SDL2 *m_lastPendingBuffer;
+ GpAudioBuffer_SDL2 *m_pendingBuffers[kMaxBuffers];
+ size_t m_nextPendingBufferConsumePos;
+ size_t m_nextPendingBufferInsertionPos;
+ size_t m_numQueuedBuffers;
+ size_t m_firstBufferSamplesConsumed;
- ChannelState m_channelState;
+ GpAudioDriver_SDL2_TimePoint_t m_timestamp; // Time that audio will be consumed if posted to the channel, if m_hasTimestamp is true.
+ GpAudioDriver_SDL2_Duration_t m_latency;
+ GpAudioDriver_SDL2_Duration_t m_bufferTime;
+ size_t m_bufferSamplesMax;
+ size_t m_leadingSilence;
+ uint16_t m_sampleRate;
+ bool m_isMixing;
+ bool m_hasTimestamp;
};
-class GP_ALIGNED(GP_SYSTEM_MEMORY_ALIGNMENT) GpAudioDriver_SDL2 final : public IGpAudioDriver, public IGpPrefsHandler
+class GpAudioDriver_SDL2 final : public IGpAudioDriver, public IGpPrefsHandler
{
public:
friend class GpAudioChannel_SDL2;
@@ -112,6 +186,7 @@ public:
explicit GpAudioDriver_SDL2(const GpAudioDriverProperties &properties);
~GpAudioDriver_SDL2();
+ IGpAudioBuffer *CreateBuffer(const void *data, size_t size) override;
IGpAudioChannel *CreateChannel() override;
void SetMasterVolume(uint32_t vol, uint32_t maxVolume) override;
void Shutdown() override;
@@ -122,25 +197,32 @@ public:
bool Init();
+ static GpAudioDriver_SDL2_TimePoint_t GetCurrentTime();
+
private:
void DetachAudioChannel(GpAudioChannel_SDL2 *channel);
static void SDLCALL StaticMixAudio(void *userdata, Uint8 *stream, int len);
void MixAudio(void *stream, size_t len);
- void RefillMixChunk(GpAudioChannel_SDL2 *const*channels, size_t numChannels);
+ void RefillMixChunk(GpAudioChannel_SDL2 *const*channels, size_t numChannels, size_t maxSamplesToFill, GpAudioDriver_SDL2_TimePoint_t mixStartTime, GpAudioDriver_SDL2_TimePoint_t mixEndTime);
GpAudioDriverProperties m_properties;
IGpMutex *m_mutex;
IGpMutex *m_mixState;
static const size_t kMaxChannels = 16;
- static const size_t kMixChunkSize = 256;
- static const int16_t kMaxAudioVolumeScale = 25;
+ static const size_t kMixChunkSize = 512;
+ static const int16_t kMaxAudioVolumeScale = 64;
GpAudioChannel_SDL2 *m_channels[kMaxChannels];
size_t m_numChannels;
+ unsigned int m_sampleRate;
+ GpAudioDriver_SDL2_Duration_t m_latency;
+ GpAudioDriver_SDL2_Duration_t m_bufferTime;
+ size_t m_bufferSamples;
+
bool m_sdlAudioRunning;
GP_ALIGNED(GP_SYSTEM_MEMORY_ALIGNMENT) int16_t m_mixChunk[kMixChunkSize];
@@ -149,36 +231,24 @@ private:
int16_t m_audioVolumeScale;
};
-GpAudioChannelBufferChain_SDL2::GpAudioChannelBufferChain_SDL2()
- : m_used(0)
- , m_consumed(0)
- , m_next(nullptr)
- , m_hasTrigger(false)
-{
-}
-
-
-GpAudioChannelBufferChain_SDL2 *GpAudioChannelBufferChain_SDL2::Alloc()
-{
- void *storage = AlignedAlloc(sizeof(GpAudioChannelBufferChain_SDL2), GP_SYSTEM_MEMORY_ALIGNMENT);
- return new (storage) GpAudioChannelBufferChain_SDL2();
-}
-
-void GpAudioChannelBufferChain_SDL2::Release()
-{
- this->~GpAudioChannelBufferChain_SDL2();
- AlignedFree(this);
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
// GpAudioChannel
-GpAudioChannel_SDL2::GpAudioChannel_SDL2()
+GpAudioChannel_SDL2::GpAudioChannel_SDL2(GpAudioDriver_SDL2_Duration_t latency, GpAudioDriver_SDL2_Duration_t bufferTime, size_t bufferSamplesMax, uint16_t sampleRate)
: m_callbacks(nullptr)
, m_mutex(nullptr)
, m_owner(nullptr)
- , m_firstPendingBuffer(nullptr)
- , m_lastPendingBuffer(nullptr)
+ , m_latency(latency)
+ , m_bufferTime(bufferTime)
+ , m_bufferSamplesMax(bufferSamplesMax)
+ , m_leadingSilence(0)
+ , m_sampleRate(sampleRate)
+ , m_isMixing(false)
+ , m_hasTimestamp(false)
+ , m_nextPendingBufferConsumePos(0)
+ , m_nextPendingBufferInsertionPos(0)
+ , m_numQueuedBuffers(0)
+ , m_firstBufferSamplesConsumed(0)
{
SDL_AtomicSet(&m_refCount, 1);
}
@@ -190,12 +260,7 @@ GpAudioChannel_SDL2::~GpAudioChannel_SDL2()
if (m_mutex)
m_mutex->Destroy();
- while (m_firstPendingBuffer)
- {
- GpAudioChannelBufferChain_SDL2 *buffer = m_firstPendingBuffer;
- m_firstPendingBuffer = buffer->m_next;
- buffer->Release();
- }
+ assert(m_numQueuedBuffers == 0);
}
void GpAudioChannel_SDL2::AddRef()
@@ -218,54 +283,70 @@ void GpAudioChannel_SDL2::SetAudioChannelContext(IGpAudioChannelCallbacks *callb
m_callbacks = callbacks;
}
-void GpAudioChannel_SDL2::PostBuffer(const void *buffer, size_t bufferSize)
+bool GpAudioChannel_SDL2::PostBuffer(IGpAudioBuffer *buffer)
{
+ buffer->AddRef();
+
m_mutex->Lock();
- while (bufferSize > 0)
+ if (m_numQueuedBuffers == kMaxBuffers)
{
- GpAudioChannelBufferChain_SDL2 *newBuffer = GpAudioChannelBufferChain_SDL2::Alloc();
- if (newBuffer == nullptr)
- break;
-
- if (m_lastPendingBuffer == nullptr)
- m_firstPendingBuffer = newBuffer;
- else
- m_lastPendingBuffer->m_next = newBuffer;
- m_lastPendingBuffer = newBuffer;
-
- size_t bufferable = newBuffer->kMaxCapacity;
- if (bufferSize < bufferable)
- bufferable = bufferSize;
-
- memcpy(newBuffer->m_data, buffer, bufferable);
-
- buffer = static_cast(buffer) + bufferable;
- bufferSize -= bufferable;
- m_lastPendingBuffer->m_used = bufferable;
- m_lastPendingBuffer->m_hasTrigger = (bufferSize == 0);
+ m_mutex->Unlock();
+ buffer->Release();
+ return false;
}
+ size_t leadingSilence = 0;
+ if (m_numQueuedBuffers == 0 && m_hasTimestamp && !m_isMixing)
+ {
+ GpAudioDriver_SDL2_TimePoint_t queueTime = GpAudioDriver_SDL2::GetCurrentTime() + m_latency;
+ if (queueTime > m_timestamp)
+ {
+ const GpAudioDriver_SDL2_Duration_t leadTime = queueTime - m_timestamp;
+
+ if (leadTime > m_bufferTime)
+ leadingSilence = m_bufferSamplesMax;
+ else
+ {
+ const GpAudioDriver_SDL2_Rep_t leadTimeRep = leadTime.count();
+ leadingSilence = leadTimeRep * static_cast(m_sampleRate) * GpAudioDriver_SDL2_Period_t::num / GpAudioDriver_SDL2_Period_t::den;
+ }
+ }
+ }
+
+ m_leadingSilence = leadingSilence;
+
+ m_pendingBuffers[m_nextPendingBufferInsertionPos++] = static_cast(buffer);
+ m_numQueuedBuffers++;
+
+ m_nextPendingBufferInsertionPos = m_nextPendingBufferInsertionPos % kMaxBuffers;
+
m_mutex->Unlock();
+
+ return true;
}
void GpAudioChannel_SDL2::Stop()
{
m_mutex->Lock();
- GpAudioChannelBufferChain_SDL2 *buffer = m_firstPendingBuffer;
- m_firstPendingBuffer = nullptr;
- m_lastPendingBuffer = nullptr;
+ m_leadingSilence = 0;
- while (buffer)
+ size_t numBuffersToDischarge = m_numQueuedBuffers;
+
+ for (size_t i = 0; i < numBuffersToDischarge; i++)
{
- if (buffer->m_hasTrigger && m_callbacks)
+ GpAudioBuffer_SDL2 *buffer = m_pendingBuffers[m_nextPendingBufferConsumePos];
+
+ m_nextPendingBufferConsumePos = (m_nextPendingBufferConsumePos + 1) % kMaxBuffers;
+ m_numQueuedBuffers--;
+
+ m_firstBufferSamplesConsumed = 0;
+
+ if (m_callbacks)
m_callbacks->NotifyBufferFinished();
- GpAudioChannelBufferChain_SDL2 *nextBuffer = buffer->m_next;
buffer->Release();
-
- buffer = nextBuffer;
}
m_mutex->Unlock();
@@ -289,25 +370,57 @@ bool GpAudioChannel_SDL2::Init(GpAudioDriver_SDL2 *driver)
return true;
}
-void GpAudioChannel_SDL2::Consume(uint8_t *output, size_t sz)
+void GpAudioChannel_SDL2::Consume(uint8_t *output, size_t sz, GpAudioDriver_SDL2_TimePoint_t mixStartTime, GpAudioDriver_SDL2_TimePoint_t mixEndTime)
{
m_mutex->Lock();
- while (m_firstPendingBuffer != nullptr)
+ m_isMixing = true;
+ m_hasTimestamp = true;
+ m_timestamp = mixEndTime;
+
+ if (sz <= m_leadingSilence)
{
- GpAudioChannelBufferChain_SDL2 *buffer = m_firstPendingBuffer;
- const size_t available = (buffer->m_used - buffer->m_consumed);
+ memset(output, 0x80, sz);
+ m_leadingSilence -= sz;
+
+ m_isMixing = false;
+ m_mutex->Unlock();
+ return;
+ }
+ else
+ {
+ size_t leadingSilence = m_leadingSilence;
+ if (leadingSilence > 0)
+ {
+ memset(output, 0x80, leadingSilence);
+ output += leadingSilence;
+ sz -= leadingSilence;
+
+ m_leadingSilence = 0;
+ }
+ }
+
+ while (m_numQueuedBuffers > 0)
+ {
+ GpAudioBuffer_SDL2 *buffer = m_pendingBuffers[m_nextPendingBufferConsumePos];
+ const void *bufferData = buffer->GetData();
+ const size_t bufferSize = buffer->GetSize();
+
+ assert(m_firstBufferSamplesConsumed < bufferSize);
+
+ const size_t available = (bufferSize - m_firstBufferSamplesConsumed);
if (available <= sz)
{
- memcpy(output, buffer->m_data + buffer->m_consumed, available);
+ memcpy(output, static_cast(bufferData) + m_firstBufferSamplesConsumed, available);
sz -= available;
output += available;
- m_firstPendingBuffer = buffer->m_next;
- if (m_firstPendingBuffer == nullptr)
- m_lastPendingBuffer = nullptr;
+ m_nextPendingBufferConsumePos = (m_nextPendingBufferConsumePos + 1) % kMaxBuffers;
+ m_numQueuedBuffers--;
- if (buffer->m_hasTrigger && m_callbacks)
+ m_firstBufferSamplesConsumed = 0;
+
+ if (m_callbacks)
m_callbacks->NotifyBufferFinished();
buffer->Release();
@@ -317,26 +430,28 @@ void GpAudioChannel_SDL2::Consume(uint8_t *output, size_t sz)
}
else
{
- memcpy(output, buffer->m_data + buffer->m_consumed, sz);
- buffer->m_consumed += sz;
- buffer += sz;
+ memcpy(output, static_cast(bufferData) + m_firstBufferSamplesConsumed, sz);
+ m_firstBufferSamplesConsumed += sz;
+ output += sz;
sz = 0;
break;
}
}
+ m_isMixing = false;
+
m_mutex->Unlock();
memset(output, 0x80, sz);
}
-GpAudioChannel_SDL2 *GpAudioChannel_SDL2::Alloc(GpAudioDriver_SDL2 *driver)
+GpAudioChannel_SDL2 *GpAudioChannel_SDL2::Alloc(GpAudioDriver_SDL2 *driver, GpAudioDriver_SDL2_Duration_t latency, GpAudioDriver_SDL2_Duration_t bufferTime, size_t bufferSamplesMax, uint16_t sampleRate)
{
void *storage = AlignedAlloc(sizeof(GpAudioChannel_SDL2), GP_SYSTEM_MEMORY_ALIGNMENT);
if (!storage)
return nullptr;
- GpAudioChannel_SDL2 *channel = new (storage) GpAudioChannel_SDL2();
+ GpAudioChannel_SDL2 *channel = new (storage) GpAudioChannel_SDL2(latency, bufferTime, bufferSamplesMax, sampleRate);
if (!channel->Init(driver))
{
channel->Destroy();
@@ -354,6 +469,9 @@ GpAudioDriver_SDL2::GpAudioDriver_SDL2(const GpAudioDriverProperties &properties
: m_properties(properties)
, m_mutex(nullptr)
, m_numChannels(0)
+ , m_sampleRate(0)
+ , m_latency(GpAudioDriver_SDL2_Duration_t::zero())
+ , m_bufferTime(GpAudioDriver_SDL2_Duration_t::zero())
, m_sdlAudioRunning(false)
, m_mixChunkReadOffset(kMixChunkSize)
, m_audioVolumeScale(kMaxAudioVolumeScale)
@@ -375,9 +493,14 @@ GpAudioDriver_SDL2::~GpAudioDriver_SDL2()
m_mutex->Destroy();
}
+IGpAudioBuffer *GpAudioDriver_SDL2::CreateBuffer(const void *data, size_t size)
+{
+ return GpAudioBuffer_SDL2::Create(data, size);
+}
+
IGpAudioChannel *GpAudioDriver_SDL2::CreateChannel()
{
- GpAudioChannel_SDL2 *newChannel = GpAudioChannel_SDL2::Alloc(this);
+ GpAudioChannel_SDL2 *newChannel = GpAudioChannel_SDL2::Alloc(this, m_latency, m_bufferTime, m_bufferSamples, m_sampleRate);
if (!newChannel)
return nullptr;
@@ -437,7 +560,7 @@ bool GpAudioDriver_SDL2::Init()
requestedSpec.channels = 1;
requestedSpec.format = AUDIO_S16;
requestedSpec.freq = m_properties.m_sampleRate;
- requestedSpec.samples = 1024;
+ requestedSpec.samples = kMixChunkSize;
requestedSpec.userdata = this;
if (SDL_OpenAudio(&requestedSpec, nullptr))
@@ -450,6 +573,10 @@ bool GpAudioDriver_SDL2::Init()
SDL_PauseAudio(0);
m_sdlAudioRunning = true;
+ m_sampleRate = requestedSpec.freq;
+ m_latency = GpAudioDriver_SDL2_Duration_t(static_cast(GpAudioDriver_SDL2_Period_t::den * requestedSpec.samples / GpAudioDriver_SDL2_Period_t::num / m_sampleRate));
+ m_bufferTime = GpAudioDriver_SDL2_Duration_t(static_cast(GpAudioDriver_SDL2_Period_t::den * requestedSpec.samples / GpAudioDriver_SDL2_Period_t::num / m_sampleRate));
+ m_bufferSamples = requestedSpec.samples;
return true;
}
@@ -492,8 +619,13 @@ void GpAudioDriver_SDL2::MixAudio(void *stream, size_t len)
}
m_mutex->Unlock();
- size_t samplesRemaining = len / sizeof(int16_t);
+ const size_t totalSamples = len / sizeof(int16_t);
+ size_t samplesRemaining = totalSamples;
+ GpAudioDriver_SDL2_TimePoint_t audioMixStartTime = GpAudioDriver_SDL2::GetCurrentTime();
+ GpAudioDriver_SDL2_TimePoint_t audioMixBlockStartTime = audioMixStartTime;
+
+ size_t samplesSinceStart = 0;
for (;;)
{
size_t availableInMixChunk = kMixChunkSize - m_mixChunkReadOffset;
@@ -510,10 +642,17 @@ void GpAudioDriver_SDL2::MixAudio(void *stream, size_t len)
memcpy(stream, m_mixChunk + m_mixChunkReadOffset, availableInMixChunk * sizeof(int16_t));
stream = static_cast(stream) + availableInMixChunk;
- samplesRemaining -= availableInMixChunk;
+
+ samplesSinceStart += availableInMixChunk;
+
+ GpAudioDriver_SDL2_Duration_t audioMixDurationSinceStart = GpAudioDriver_SDL2_Duration_t(static_cast(GpAudioDriver_SDL2_Period_t::den * samplesSinceStart / GpAudioDriver_SDL2_Period_t::num / m_sampleRate));
+ GpAudioDriver_SDL2_TimePoint_t audioMixBlockEndTime = audioMixStartTime + audioMixDurationSinceStart;
m_mixChunkReadOffset = 0;
- RefillMixChunk(mixingChannels, numChannels);
+ RefillMixChunk(mixingChannels, numChannels, samplesRemaining, audioMixBlockStartTime, audioMixBlockEndTime);
+ audioMixBlockStartTime = audioMixBlockEndTime;
+
+ samplesRemaining -= availableInMixChunk;
}
}
@@ -521,7 +660,7 @@ void GpAudioDriver_SDL2::MixAudio(void *stream, size_t len)
mixingChannels[i]->Release();
}
-void GpAudioDriver_SDL2::RefillMixChunk(GpAudioChannel_SDL2 *const*channels, size_t numChannels)
+void GpAudioDriver_SDL2::RefillMixChunk(GpAudioChannel_SDL2 *const*channels, size_t numChannels, size_t maxSamplesToFill, GpAudioDriver_SDL2_TimePoint_t mixStartTime, GpAudioDriver_SDL2_TimePoint_t mixEndTime)
{
uint8_t audioMixBufferUnaligned[kMixChunkSize + GP_SYSTEM_MEMORY_ALIGNMENT];
uint8_t *audioMixBuffer = audioMixBufferUnaligned;
@@ -536,28 +675,52 @@ void GpAudioDriver_SDL2::RefillMixChunk(GpAudioChannel_SDL2 *const*channels, siz
const int16_t audioVolumeScale = m_audioVolumeScale;
+ size_t samplesToFill = kMixChunkSize;
+ if (samplesToFill > maxSamplesToFill)
+ {
+ m_mixChunkReadOffset += samplesToFill - maxSamplesToFill;
+ samplesToFill = maxSamplesToFill;
+ }
+ else
+ m_mixChunkReadOffset = 0;
+
+ int16_t *mixChunkStart = m_mixChunk + m_mixChunkReadOffset;
+ int16_t audioNormalizeShift = 0;
+
for (size_t i = 0; i < numChannels; i++)
{
- channels[i]->Consume(audioMixBuffer, kMixChunkSize);
+ channels[i]->Consume(audioMixBuffer, samplesToFill, mixStartTime, mixEndTime);
if (i == 0)
{
noAudio = false;
- for (size_t j = 0; j < kMixChunkSize; j++)
- m_mixChunk[j] = (static_cast(audioMixBuffer[j]) - 0x80) * audioVolumeScale;
+ audioNormalizeShift = 0x80;
+ for (size_t j = 0; j < samplesToFill; j++)
+ mixChunkStart[j] = static_cast(audioMixBuffer[j]);
}
else
{
- for (size_t j = 0; j < kMixChunkSize; j++)
- m_mixChunk[j] += (static_cast(audioMixBuffer[j]) - 0x80) * audioVolumeScale;
+ audioNormalizeShift += 0x80;
+ for (size_t j = 0; j < samplesToFill; j++)
+ mixChunkStart[j] += static_cast(audioMixBuffer[j]);
}
}
if (noAudio)
- memset(m_mixChunk, 0, kMixChunkSize * sizeof(m_mixChunk[0]));
+ memset(mixChunkStart, 0, samplesToFill * sizeof(mixChunkStart[0]));
+ else
+ {
+ for (size_t i = 0; i < samplesToFill; i++)
+ mixChunkStart[i] = (mixChunkStart[i] - audioNormalizeShift) * audioVolumeScale;
+ }
}
+GpAudioDriver_SDL2_TimePoint_t GpAudioDriver_SDL2::GetCurrentTime()
+{
+ return std::chrono::high_resolution_clock::now();
+}
+
IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &properties)
{
void *storage = AlignedAlloc(sizeof(GpAudioDriver_SDL2), GP_SYSTEM_MEMORY_ALIGNMENT);
diff --git a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp
index 56d93c6..fb4873f 100644
--- a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp
+++ b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp
@@ -8,6 +8,7 @@
#include "GpRingBuffer.h"
#include "GpInputDriver_SDL_Gamepad.h"
#include "GpSDL.h"
+#include "GpUnicode.h"
#include "IGpCursor.h"
#include "IGpDisplayDriverSurface.h"
#include "IGpLogDriver.h"
@@ -52,68 +53,6 @@ struct GpDisplayDriver_SDL_GL2_Prefs
bool m_isFullScreen;
};
-namespace DeleteMe
-{
- bool DecodeCodePoint(const uint8_t *characters, size_t availableCharacters, size_t &outCharactersDigested, uint32_t &outCodePoint)
- {
- if (availableCharacters <= 0)
- return false;
-
- if ((characters[0] & 0x80) == 0x00)
- {
- outCharactersDigested = 1;
- outCodePoint = characters[0];
- return true;
- }
-
- size_t sz = 0;
- uint32_t codePoint = 0;
- uint32_t minCodePoint = 0;
- if ((characters[0] & 0xe0) == 0xc0)
- {
- sz = 2;
- minCodePoint = 0x80;
- codePoint = (characters[0] & 0x1f);
- }
- else if ((characters[0] & 0xf0) == 0xe0)
- {
- sz = 3;
- minCodePoint = 0x800;
- codePoint = (characters[0] & 0x0f);
- }
- else if ((characters[0] & 0xf8) == 0xf0)
- {
- sz = 4;
- minCodePoint = 0x10000;
- codePoint = (characters[0] & 0x07);
- }
- else
- return false;
-
- if (availableCharacters < sz)
- return false;
-
- for (size_t auxByte = 1; auxByte < sz; auxByte++)
- {
- if ((characters[auxByte] & 0xc0) != 0x80)
- return false;
-
- codePoint = (codePoint << 6) | (characters[auxByte] & 0x3f);
- }
-
- if (codePoint < minCodePoint || codePoint > 0x10ffff)
- return false;
-
- if (codePoint >= 0xd800 && codePoint <= 0xdfff)
- return false;
-
- outCodePoint = codePoint;
- outCharactersDigested = sz;
-
- return true;
- }
-}
-
namespace GpBinarizedShaders
{
extern const char *g_drawQuadV_GL2;
@@ -846,9 +785,6 @@ private:
GpComPtr m_upscaleTextureRTV;
GpComPtr m_upscaleTexture;
- uint32_t m_upscaleTextureWidth;
- uint32_t m_upscaleTextureHeight;
-
GpComPtr m_quadVertexArray;
GpComPtr m_quadVertexBufferKeepalive;
GpComPtr m_quadIndexBuffer;
@@ -905,7 +841,10 @@ private:
uint32_t m_initialHeightVirtual;
float m_pixelScaleX;
float m_pixelScaleY;
+
bool m_useUpscaleFilter;
+ uint32_t m_upscaleTextureWidth;
+ uint32_t m_upscaleTextureHeight;
GpCursor_SDL2 *m_activeCursor;
GpCursor_SDL2 *m_pendingCursor;
@@ -1197,6 +1136,8 @@ GpDisplayDriver_SDL_GL2::GpDisplayDriver_SDL_GL2(const GpDisplayDriverProperties
, m_pixelScaleX(1.0f)
, m_pixelScaleY(1.0f)
, m_useUpscaleFilter(false)
+ , m_upscaleTextureWidth(0)
+ , m_upscaleTextureHeight(0)
, m_pendingCursor(nullptr)
, m_activeCursor(nullptr)
, m_currentStandardCursor(EGpStandardCursors::kArrow)
@@ -1531,8 +1472,7 @@ void GpDisplayDriver_SDL_GL2::ServeTicks(int ticks)
logger->Printf(IGpLogDriver::Category_Information, "Resetting OpenGL context. Physical: %i x %i Virtual %i x %i", static_cast(m_windowWidthPhysical), static_cast(m_windowHeightPhysical), static_cast(m_windowWidthVirtual), static_cast(m_windowHeightVirtual));
// Drop everything and reset
- m_res.~InstancedResources();
- new (&m_res) InstancedResources();
+ m_res = InstancedResources();
if (m_firstSurface)
m_firstSurface->DestroyAll();
@@ -2040,7 +1980,7 @@ void GpDisplayDriver_SDL_GL2::TranslateSDLMessage(const SDL_Event *msg, IGpVOSEv
{
uint32_t codePoint;
size_t numDigested;
- DeleteMe::DecodeCodePoint(reinterpret_cast(teEvt->text) + parseOffset, lenUTF8 - parseOffset, numDigested, codePoint);
+ GpUnicode::UTF8::Decode(reinterpret_cast(teEvt->text) + parseOffset, lenUTF8 - parseOffset, numDigested, codePoint);
parseOffset += numDigested;
@@ -2458,11 +2398,6 @@ bool GpDisplayDriver_SDL_GL2::InitResources(uint32_t physicalWidth, uint32_t phy
if (logger)
logger->Printf(IGpLogDriver::Category_Information, "GpDisplayDriver_SDL_GL2::InitResources");
- if ((m_pixelScaleX < 2.0f && m_pixelScaleX > 1.0f) || (m_pixelScaleY < 2.0f && m_pixelScaleY > 1.0f))
- m_useUpscaleFilter = true;
- else
- m_useUpscaleFilter = false;
-
CheckGLError(m_gl, logger);
if (!InitBackBuffer(virtualWidth, virtualHeight))
@@ -2776,8 +2711,9 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
m_gl.BindFramebuffer(GL_FRAMEBUFFER, 0);
}
+ m_useUpscaleFilter = ((m_pixelScaleX < 2.0f && m_pixelScaleX > 1.0f) || (m_pixelScaleY < 2.0f && m_pixelScaleY > 1.0f));
- if (m_pixelScaleX != floor(m_pixelScaleX) || m_pixelScaleY != floor(m_pixelScaleY))
+ if (m_useUpscaleFilter)
{
uint32_t upscaleX = ceil(m_pixelScaleX);
uint32_t upscaleY = ceil(m_pixelScaleY);
@@ -2792,8 +2728,8 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
return false;
}
- m_res.m_upscaleTextureWidth = width * upscaleX;
- m_res.m_upscaleTextureHeight = height * upscaleY;
+ m_upscaleTextureWidth = width * upscaleX;
+ m_upscaleTextureHeight = height * upscaleY;
GLenum internalFormat = SupportsSizedFormats() ? GL_RGBA8 : GL_RGBA;
@@ -2803,7 +2739,7 @@ bool GpDisplayDriver_SDL_GL2::InitBackBuffer(uint32_t width, uint32_t height)
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- m_gl.TexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_res.m_upscaleTextureWidth, m_res.m_upscaleTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ m_gl.TexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_upscaleTextureWidth, m_upscaleTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
m_gl.BindTexture(GL_TEXTURE_2D, 0);
CheckGLError(m_gl, logger);
@@ -2848,7 +2784,7 @@ void GpDisplayDriver_SDL_GL2::ScaleVirtualScreen()
{
m_gl.BindFramebuffer(GL_FRAMEBUFFER, m_res.m_upscaleTextureRTV->GetID());
- m_gl.Viewport(0, 0, m_res.m_upscaleTextureWidth, m_res.m_upscaleTextureHeight);
+ m_gl.Viewport(0, 0, m_upscaleTextureWidth, m_upscaleTextureHeight);
const BlitQuadProgram &program = m_res.m_scaleQuadProgram;
diff --git a/AerofoilSDL/GpMain_SDL_Win32.cpp b/AerofoilSDL/GpMain_SDL_Win32.cpp
index d492b13..39a0198 100644
--- a/AerofoilSDL/GpMain_SDL_Win32.cpp
+++ b/AerofoilSDL/GpMain_SDL_Win32.cpp
@@ -1,6 +1,7 @@
#include "SDL.h"
#include "GpMain.h"
+#include "GpAllocator_C.h"
#include "GpAudioDriverFactory.h"
#include "GpDisplayDriverFactory.h"
#include "GpGlobalConfig.h"
@@ -59,6 +60,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
drivers->SetDriver(GpFileSystem_Win32::GetInstance());
drivers->SetDriver(GpSystemServices_Win32::GetInstance());
drivers->SetDriver(GpLogDriver_Win32::GetInstance());
+ drivers->SetDriver(GpAllocator_C::GetInstance());
g_gpWindowsGlobals.m_hInstance = hInstance;
g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance;
@@ -86,6 +88,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
g_gpGlobalConfig.m_logger = logger;
g_gpGlobalConfig.m_systemServices = GpSystemServices_Win32::GetInstance();
+ g_gpGlobalConfig.m_allocator = GpAllocator_C::GetInstance();
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_SDL_GL2, GpDriver_CreateDisplayDriver_SDL_GL2);
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_SDL2, GpDriver_CreateAudioDriver_SDL);
diff --git a/AerofoilSDL/ShaderCode/DrawQuad32P.cpp b/AerofoilSDL/ShaderCode/DrawQuad32P.cpp
index 2ae17df..1422afe 100644
--- a/AerofoilSDL/ShaderCode/DrawQuad32P.cpp
+++ b/AerofoilSDL/ShaderCode/DrawQuad32P.cpp
@@ -17,7 +17,7 @@
" vec4 resultColor = vec4(SamplePixel(texCoord.xy), 1.0);\n"\
" resultColor *= constants_Modulation;\n"\
"#ifdef ENABLE_FLICKER\n"\
-" resultColor = ApplyFlicker(constants_FlickerAxis, texCoord.zw, constants_FlickerStartThreshold, constants_FlickerEndThreshold, resultColor * constants_Modulation);\n"\
+" resultColor = ApplyFlicker(constants_FlickerAxis, texCoord.zw, constants_FlickerStartThreshold, constants_FlickerEndThreshold, resultColor);\n"\
" if (resultColor.a < 1.0)\n"\
" discard;\n"\
"#endif\n"\
diff --git a/AerofoilSDL/ShaderCode/DrawQuadPaletteP.cpp b/AerofoilSDL/ShaderCode/DrawQuadPaletteP.cpp
index bd485f1..d9111d3 100644
--- a/AerofoilSDL/ShaderCode/DrawQuadPaletteP.cpp
+++ b/AerofoilSDL/ShaderCode/DrawQuadPaletteP.cpp
@@ -18,7 +18,7 @@
" vec4 resultColor = vec4(SamplePixel(texCoord.xy), 1.0);\n"\
" resultColor *= constants_Modulation;\n"\
"#ifdef ENABLE_FLICKER\n"\
-" resultColor = ApplyFlicker(constants_FlickerAxis, texCoord.zw, constants_FlickerStartThreshold, constants_FlickerEndThreshold, resultColor * constants_Modulation);\n"\
+" resultColor = ApplyFlicker(constants_FlickerAxis, texCoord.zw, constants_FlickerStartThreshold, constants_FlickerEndThreshold, resultColor);\n"\
" if (resultColor.a < 1.0)\n"\
" discard;\n"\
"#endif\n"\
diff --git a/AerofoilWeb/GpFileSystem_Web.cpp b/AerofoilWeb/GpFileSystem_Web.cpp
index a9f2870..a5da4b6 100644
--- a/AerofoilWeb/GpFileSystem_Web.cpp
+++ b/AerofoilWeb/GpFileSystem_Web.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "UTF8.h"
@@ -29,6 +30,111 @@ typedef off_t off64_t;
#define stat64 stat
#endif
+EM_JS(void, FlushFileSystem, (), {
+ Asyncify.handleSleep(wakeUp => {
+ FS.syncfs(false, function (err) {
+ assert(!err);
+ wakeUp();
+ });
+ });
+});
+
+
+class GpDirectoryCursor_Web final : public IGpDirectoryCursor
+{
+public:
+ explicit GpDirectoryCursor_Web(DIR *dir, const std::string &prefix);
+ ~GpDirectoryCursor_Web();
+
+ bool GetNext(const char *&outFileName) override;
+ void Destroy() override;
+
+private:
+ DIR *m_dir;
+ std::string m_prefix;
+ std::string m_decodedFileName;
+};
+
+GpDirectoryCursor_Web::GpDirectoryCursor_Web(DIR *dir, const std::string &prefix)
+ : m_dir(dir)
+ , m_prefix(prefix)
+{
+}
+
+GpDirectoryCursor_Web::~GpDirectoryCursor_Web()
+{
+ closedir(m_dir);
+}
+
+bool GpDirectoryCursor_Web::GetNext(const char *&outFileName)
+{
+ const size_t prefixLength = m_prefix.size();
+
+ for (;;)
+ {
+ struct dirent *dir = readdir(m_dir);
+ if (!dir)
+ return false;
+
+ const char *fname = dir->d_name;
+
+ const size_t fnameLen = strlen(fname);
+ if (fnameLen > prefixLength && (prefixLength == 0 || !memcmp(&m_prefix[0], fname, prefixLength)))
+ {
+ const char *encodedResult = fname + prefixLength;
+
+ m_decodedFileName.clear();
+ for (size_t i = 0; encodedResult[i] != 0; i++)
+ {
+ char c = encodedResult[i];
+ if (c == '%')
+ {
+ char highNibble = encodedResult[i + 1];
+ if ((highNibble >= '0' && highNibble <= '9') || (highNibble >= 'a' && highNibble <= 'f') || (highNibble >= 'A' && highNibble <= 'F'))
+ {
+ char lowNibble = encodedResult[i + 2];
+
+ if ((lowNibble >= '0' && lowNibble <= '9') || (lowNibble >= 'a' && lowNibble <= 'f') || (lowNibble >= 'A' && lowNibble <= 'F'))
+ {
+ bool failedNibble = false;
+ char nibbles[2] = { highNibble, lowNibble };
+ int decNibbles[2];
+ for (int ni = 0; ni < 2; ni++)
+ {
+ char nc = nibbles[ni];
+ if (nc >= '0' && nc <= '9')
+ decNibbles[ni] = nc - '0';
+ else if (nc >= 'a' && nc <= 'f')
+ decNibbles[ni] = 0xa + (nc - 'a');
+ else if (nc >= 'A' && nc <= 'F')
+ decNibbles[ni] = 0xa + (nc - 'A');
+ else
+ failedNibble = true;
+ }
+
+ if (!failedNibble)
+ {
+ c = static_cast((decNibbles[0] << 4) + decNibbles[1]);
+ i += 2;
+ }
+ }
+ }
+ }
+
+ m_decodedFileName += c;
+ }
+
+ outFileName = m_decodedFileName.c_str();
+ return true;
+ }
+ }
+ return true;
+}
+
+void GpDirectoryCursor_Web::Destroy()
+{
+ delete this;
+}
class GpFileStream_Web_StaticMemFile final : public GpIOStream
{
@@ -46,7 +152,7 @@ public:
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
private:
@@ -136,7 +242,7 @@ GpUFilePos_t GpFileStream_Web_StaticMemFile::Tell() const
return m_offset;
}
-void GpFileStream_Web_StaticMemFile::Close()
+void GpFileStream_Web_StaticMemFile::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
delete this;
}
@@ -149,7 +255,7 @@ void GpFileStream_Web_StaticMemFile::Flush()
class GpFileStream_Web_File final : public GpIOStream
{
public:
- GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly);
+ GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly, bool synchronizeOnClose);
~GpFileStream_Web_File();
size_t Read(void *bytesOut, size_t size) override;
@@ -162,7 +268,7 @@ public:
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
private:
@@ -170,13 +276,15 @@ private:
bool m_seekable;
bool m_isReadOnly;
bool m_isWriteOnly;
+ bool m_synchronizeOnClose;
};
-GpFileStream_Web_File::GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly)
+GpFileStream_Web_File::GpFileStream_Web_File(FILE *f, bool readOnly, bool writeOnly, bool synchronizeOnClose)
: m_f(f)
, m_isReadOnly(readOnly)
, m_isWriteOnly(writeOnly)
+ , m_synchronizeOnClose(synchronizeOnClose)
{
m_seekable = (fseek(m_f, 0, SEEK_CUR) == 0);
}
@@ -184,6 +292,9 @@ GpFileStream_Web_File::GpFileStream_Web_File(FILE *f, bool readOnly, bool writeO
GpFileStream_Web_File::~GpFileStream_Web_File()
{
fclose(m_f);
+
+ if (m_synchronizeOnClose)
+ GpFileSystem_Web::MarkFSStateDirty();
}
size_t GpFileStream_Web_File::Read(void *bytesOut, size_t size)
@@ -258,7 +369,7 @@ GpUFilePos_t GpFileStream_Web_File::Tell() const
return static_cast(ftell(m_f));
}
-void GpFileStream_Web_File::Close()
+void GpFileStream_Web_File::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
this->~GpFileStream_Web_File();
free(this);
@@ -269,20 +380,25 @@ void GpFileStream_Web_File::Flush()
fflush(m_f);
}
-bool GpFileSystem_Web::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution)
+
+bool GpFileSystem_Web::ms_fsStateDirty;
+
+
+bool GpFileSystem_Web::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, bool trailingSlash, std::string &resolution)
{
const char *prefsAppend = nullptr;
+ std::string unsanitized;
switch (virtualDirectory)
{
case PortabilityLayer::VirtualDirectories::kApplicationData:
- resolution = std::string("Packaged");
+ unsanitized = std::string("Packaged");
break;
case PortabilityLayer::VirtualDirectories::kGameData:
- resolution = std::string("Packaged/Houses");
+ unsanitized = std::string("Packaged/Houses");
break;
case PortabilityLayer::VirtualDirectories::kFonts:
- resolution = std::string("Resources");
+ unsanitized = std::string("Resources");
break;
case PortabilityLayer::VirtualDirectories::kHighScores:
prefsAppend = "HighScores";
@@ -296,22 +412,55 @@ bool GpFileSystem_Web::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualD
case PortabilityLayer::VirtualDirectories::kPrefs:
prefsAppend = "Prefs";
break;
- case PortabilityLayer::VirtualDirectories::kFontCache:
- prefsAppend = "FontCache";
- break;
default:
return false;
};
if (prefsAppend)
- resolution = m_prefsPath + prefsAppend;
- else
- resolution = m_basePath + resolution;
-
- for (size_t i = 0; i < numPaths; i++)
{
- resolution += "/";
- resolution += paths[i];
+ unsanitized = prefsAppend;
+
+ for (size_t i = 0; i < numPaths; i++)
+ {
+ unsanitized += "/";
+ unsanitized += paths[i];
+ }
+
+ if (trailingSlash)
+ unsanitized += "/";
+
+ std::string sanitized;
+ for (size_t i = 0; i < unsanitized.size(); i++)
+ {
+ char c = unsanitized[i];
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')
+ sanitized += c;
+ else
+ {
+ const char *nibbles = "0123456789abcdef";
+ char subPath[4];
+ subPath[0] = '%';
+ subPath[1] = nibbles[(c >> 4) & 0xf];
+ subPath[2] = nibbles[c & 0xf];
+ subPath[3] = 0;
+
+ sanitized += subPath;
+ }
+ }
+
+ resolution = m_prefsPath + "/" + sanitized;
+ }
+ else
+ {
+ std::string sanitized = m_basePath + unsanitized;
+
+ for (size_t i = 0; i < numPaths; i++)
+ {
+ sanitized += "/";
+ sanitized += paths[i];
+ }
+
+ resolution = sanitized;
}
return true;
@@ -328,8 +477,7 @@ GpFileSystem_Web::~GpFileSystem_Web()
void GpFileSystem_Web::Init()
{
- char *prefsDir = SDL_GetPrefPath("aerofoil", "aerofoil");
- m_prefsPath = prefsDir;
+ m_prefsPath = "/aerofoil";
char *baseDir = SDL_GetBasePath();
m_basePath = baseDir;
@@ -338,14 +486,6 @@ void GpFileSystem_Web::Init()
char baseDirSeparator = m_basePath[m_basePath.size() - 1];
if (m_basePath.size() >= 4 && m_basePath.substr(m_basePath.size() - 4, 3) == "bin")
m_basePath = m_basePath.substr(0, m_basePath.size() - 4) + "lib" + baseDirSeparator + "aerofoil" + baseDirSeparator;
-
- const char *extensions[] = { "HighScores", "Houses", "SavedGames", "Prefs", "FontCache" };
- for (size_t i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++)
- {
- std::string prefsPath = std::string(prefsDir) + extensions[i];
- int created = mkdir(prefsPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- }
- SDL_free(prefsDir);
}
bool GpFileSystem_Web::FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path)
@@ -363,7 +503,7 @@ bool GpFileSystem_Web::FileExists(PortabilityLayer::VirtualDirectory_t virtualDi
}
std::string resolvedPath;
- if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath))
+ if (!ResolvePath(virtualDirectory, &path, 1, false, resolvedPath))
return false;
struct stat s;
@@ -389,7 +529,7 @@ bool GpFileSystem_Web::FileLocked(PortabilityLayer::VirtualDirectory_t virtualDi
}
std::string resolvedPath;
- if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath))
+ if (!ResolvePath(virtualDirectory, &path, 1, false, resolvedPath))
{
if (exists)
exists = false;
@@ -448,7 +588,7 @@ GpIOStream *GpFileSystem_Web::OpenFileNested(PortabilityLayer::VirtualDirectory_
return nullptr;
std::string resolvedPath;
- if (!ResolvePath(virtualDirectory, subPaths, numSubPaths, resolvedPath))
+ if (!ResolvePath(virtualDirectory, subPaths, numSubPaths, false, resolvedPath))
return nullptr;
void *objStorage = malloc(sizeof(GpFileStream_Web_File));
@@ -475,7 +615,7 @@ GpIOStream *GpFileSystem_Web::OpenFileNested(PortabilityLayer::VirtualDirectory_
}
}
- return new (objStorage) GpFileStream_Web_File(f, !writeAccess, false);
+ return new (objStorage) GpFileStream_Web_File(f, !writeAccess, false, writeAccess);
}
bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed)
@@ -484,7 +624,7 @@ bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDi
return false;
std::string resolvedPath;
- if (!ResolvePath(virtualDirectory, &path, 1, resolvedPath))
+ if (!ResolvePath(virtualDirectory, &path, 1, false, resolvedPath))
{
existed = false;
return false;
@@ -493,6 +633,9 @@ bool GpFileSystem_Web::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDi
if (unlink(resolvedPath.c_str()) < 0)
{
existed = (errno != ENOENT);
+ if (existed)
+ FlushFileSystem();
+
return false;
}
existed = true;
@@ -599,7 +742,17 @@ IGpDirectoryCursor *GpFileSystem_Web::ScanDirectoryNested(PortabilityLayer::Virt
if (const GpFileSystem_Web_Resources::FileCatalog *catalog = GetCatalogForVirtualDirectory(virtualDirectory))
return ScanCatalog(*catalog);
- return nullptr;
+ std::string resolvedPrefix;
+ if (!ResolvePath(virtualDirectory, paths, numPaths, true, resolvedPrefix))
+ return nullptr;
+
+ std::string trimmedPrefix = resolvedPrefix.substr(m_prefsPath.size() + 1);
+
+ DIR *d = opendir(m_prefsPath.c_str());
+ if (!d)
+ return nullptr;
+
+ return new GpDirectoryCursor_Web(d, trimmedPrefix);
}
const GpFileSystem_Web_Resources::FileCatalog *GpFileSystem_Web::GetCatalogForVirtualDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory)
@@ -622,5 +775,33 @@ IGpDirectoryCursor *GpFileSystem_Web::ScanCatalog(const GpFileSystem_Web_Resourc
return new GpDirectoryCursor_StringList(paths);
}
+void GpFileSystem_Web::MarkFSStateDirty()
+{
+ ms_fsStateDirty = true;
+}
+
+void GpFileSystem_Web::FlushFS()
+{
+ if (ms_fsStateDirty)
+ {
+ ms_fsStateDirty = false;
+ FlushFileSystem();
+ }
+}
+
+
+#if GP_ASYNCIFY_PARANOID
+void GpIOStream::Close()
+{
+ this->GP_ASYNCIFY_PARANOID_NAMED(Close)();
+ GpFileSystem_Web::FlushFS();
+}
+
+bool IGpFileSystem::DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed)
+{
+ return static_cast(this)->DeleteFile(virtualDirectory, path, existed);
+}
+
+#endif
GpFileSystem_Web GpFileSystem_Web::ms_instance;
diff --git a/AerofoilWeb/GpFileSystem_Web.h b/AerofoilWeb/GpFileSystem_Web.h
index 236a10a..3eb7b81 100644
--- a/AerofoilWeb/GpFileSystem_Web.h
+++ b/AerofoilWeb/GpFileSystem_Web.h
@@ -21,7 +21,7 @@ public:
bool FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) override;
bool FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists) override;
GpIOStream *OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition) override;
- bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) override;
+ bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) GP_ASYNCIFY_PARANOID_OVERRIDE;
IGpDirectoryCursor *ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths) override;
bool ValidateFilePath(const char *path, size_t pathLen) const override;
@@ -29,6 +29,9 @@ public:
void SetDelayCallback(DelayCallback_t delayCallback) override;
+ static void MarkFSStateDirty();
+ static void FlushFS();
+
static GpFileSystem_Web *GetInstance();
private:
@@ -51,12 +54,13 @@ private:
static IGpDirectoryCursor *ScanCatalog(const GpFileSystem_Web_Resources::FileCatalog &catalog);
- bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, std::string &resolution);
+ bool ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths, bool trailingSlash, std::string &resolution);
DelayCallback_t m_delayCallback;
std::string m_prefsPath;
std::string m_basePath;
+ static bool ms_fsStateDirty;
static GpFileSystem_Web ms_instance;
};
diff --git a/AerofoilWeb/GpMain_SDL_Web.cpp b/AerofoilWeb/GpMain_SDL_Web.cpp
index a424a87..6ca001c 100644
--- a/AerofoilWeb/GpMain_SDL_Web.cpp
+++ b/AerofoilWeb/GpMain_SDL_Web.cpp
@@ -19,18 +19,29 @@
#include "IGpVOSEventQueue.h"
#include
+#include
GpXGlobals g_gpXGlobals;
-extern "C" IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
-
IGpDisplayDriver *GpDriver_CreateDisplayDriver_SDL_GL2(const GpDisplayDriverProperties &properties);
IGpAudioDriver *GpDriver_CreateAudioDriver_SDL(const GpAudioDriverProperties &properties);
IGpInputDriver *GpDriver_CreateInputDriver_SDL2_Gamepad(const GpInputDriverProperties &properties);
+EM_JS(void, InitFileSystem, (), {
+ Asyncify.handleSleep(wakeUp => {
+ FS.mkdir('/aerofoil');
+ FS.mount(IDBFS, {}, '/aerofoil');
+ FS.syncfs(true, function (err) {
+ assert(!err);
+ wakeUp();
+ });
+ });
+});
int main(int argc, char* argv[])
{
+ InitFileSystem();
+
GpLogDriver_Web::Init();
IGpLogDriver *logger = GpLogDriver_Web::GetInstance();
diff --git a/AerofoilWeb/Link.bat b/AerofoilWeb/Link.bat
index 9950709..5ea6d17 100644
--- a/AerofoilWeb/Link.bat
+++ b/AerofoilWeb/Link.bat
@@ -1,5 +1,4 @@
set INPUT_DIR=.
set OUTPUT_DIR=bin
-set FLAGS=-flto -O3 -s USE_SDL=2 -s USE_ZLIB=1 -s ASYNCIFY -s ASYNCIFY_IGNORE_INDIRECT -s INITIAL_MEMORY=33554432 -s ASYNCIFY_ADVISE
-
+set FLAGS=-flto -O3 -s USE_SDL=2 -s USE_ZLIB=1 -s ASYNCIFY -s ASYNCIFY_IGNORE_INDIRECT -s INITIAL_MEMORY=33554432 -s ASYNCIFY_ADVISE -lidbfs.js -s ASYNCIFY_IMPORTS=['InitFileSystem','FlushFileSystem'] --shell-file shell_minimal.html
emcc obj/AerofoilWeb_Combined.o obj/AerofoilWeb_Resources.o obj/GpShell_Combined.o obj/AerofoilSDL_Combined.o obj/GpApp_Combined.o obj/PortabilityLayer_Combined.o obj/MacRomanConversion.o -o %OUTPUT_DIR%/aerofoil.html %FLAGS%
diff --git a/AerofoilWeb/shell_minimal.html b/AerofoilWeb/shell_minimal.html
new file mode 100644
index 0000000..d7b8edb
--- /dev/null
+++ b/AerofoilWeb/shell_minimal.html
@@ -0,0 +1,140 @@
+
+
+
+
+
+ Aerofoil Web Pre-Release
+
+
+
+
+
emscripten
+
Downloading...
+
+
+
+
+
+
+ {{{ SCRIPT }}}
+
+
diff --git a/AerofoilX/GpFileSystem_X.cpp b/AerofoilX/GpFileSystem_X.cpp
index d81ca25..cae7130 100644
--- a/AerofoilX/GpFileSystem_X.cpp
+++ b/AerofoilX/GpFileSystem_X.cpp
@@ -185,8 +185,8 @@ bool GpFileSystem_X::ResolvePath(PortabilityLayer::VirtualDirectory_t virtualDir
case PortabilityLayer::VirtualDirectories::kPrefs:
prefsAppend = "Prefs";
break;
- case PortabilityLayer::VirtualDirectories::kFontCache:
- prefsAppend = "FontCache";
+ case PortabilityLayer::VirtualDirectories::kLogs:
+ prefsAppend = "Logs";
break;
case PortabilityLayer::VirtualDirectories::kLogs:
prefsAppend = "..";
@@ -231,7 +231,7 @@ void GpFileSystem_X::Init()
if (m_basePath.size() >= 4 && m_basePath.substr(m_basePath.size() - 4, 3) == "bin")
m_basePath = m_basePath.substr(0, m_basePath.size() - 4) + "lib" + baseDirSeparator + "aerofoil" + baseDirSeparator;
- const char *extensions[] = { "HighScores", "Houses", "SavedGames", "Prefs", "FontCache" };
+ const char *extensions[] = { "HighScores", "Houses", "SavedGames", "Prefs", "Logs" };
for (size_t i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++)
{
std::string prefsPath = std::string(prefsDir) + extensions[i];
diff --git a/AerofoilX/GpMain_SDL_X.cpp b/AerofoilX/GpMain_SDL_X.cpp
index 7f76d72..4d78b8f 100644
--- a/AerofoilX/GpMain_SDL_X.cpp
+++ b/AerofoilX/GpMain_SDL_X.cpp
@@ -32,13 +32,26 @@ int main(int argc, char *argv[])
SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[])
#endif
{
+ bool enableLogging = false;
+ for (int i = 1; i < argc; i++)
+ {
+ if (!strcmp(argv[i], "-diagnostics"))
+ enableLogging = true;
+ }
+
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
return -1;
GpFileSystem_X::GetInstance()->Init();
- GpLogDriver_X::Init();
- IGpLogDriver *logger = GpLogDriver_X::GetInstance();
+ IGpLogDriver *logger = nullptr;
+
+ if (enableLogging)
+ {
+ GpLogDriver_X::Init();
+ logger = GpLogDriver_X::GetInstance();
+ }
+
GpDriverCollection *drivers = GpAppInterface_Get()->PL_GetDriverCollection();
drivers->SetDriver(GpFileSystem_X::GetInstance());
diff --git a/ApplicationResourcePatches/STR/1006.txt b/ApplicationResourcePatches/STR/1006.txt
new file mode 100644
index 0000000..413ecb7
--- /dev/null
+++ b/ApplicationResourcePatches/STR/1006.txt
@@ -0,0 +1,26 @@
+A never-before-seen error has arisen. Proceed with caution! (Save and Quit immediately.)
+I failed to open the house's resource fork. Any unique room backgrounds are not accessible.
+I failed to add a resource to the house's resource fork. See error number.
+I failed to create a new resource fork for the house. See error number for problem.
+There are no houses on this drive! About your only option is to create your own new house with the Editor.
+This house is incompatible with us! You'll need to upgrade Glider PRO to use this house. Do not attempt to play/edit this house!
+The background specified by this room was not found! Try re-selecting a new background (the Room Info menu).
+The room number is out of bounds. I suspect the house file is corrupt. Try deleting this "illegal" room though.
+The data is missing that specifies where the openings in this room are. The house may be damaged. Try selecting a new background though.
+There was a problem with the clipboard (Cut, Copy and Paste commands). I couldn't guess why.
+I think we just ran out of memory. Quit now and give Glider PROª more memory.
+We failed to write the house to disk. (That shouldn't have happened.)
+Well, the music didn't load. Glider PROª will still run, you'll just be musically challenged.
+Wow, there was a problem bringing sounds up. You might try giving Glider PROª more memory - otherwise ... silence.
+Some kind of strange Apple Event error. I think I would just ignore it. Or call Casady & Greene with the error number.
+Did you save the house on the same volume Glider PRO is on? I saved the house but had to re-open the old house because I couldn't find the new one.
+Wow, I couldn't find the old or new house. Go to the Select House menu item and see if it's there. If not, make sure they're on the same volume as Glider PRO.
+Couldn't create a saved game structure. Memory is probably too low.
+The saved game doesn't match the house. Either this game was saved for a different house or the house was modified recently.
+This saved game is an old version. We cannot use this game with this house.
+The number of rooms saved doesn't match the number of house rooms. We cannot use this game with this house.
+The QuickTimeª movie that goes with this house will not be used. Glider PROª must have enough memory to easily load the entire movie into RAM.
+This house has no rooms! Do not attempt to play this house! Select a new house to play.
+There was an error generating or parsing a links list. Memory may be tight.
+This house contains invalid data that couldn't be repaired. Select a new house to play.
+This house contained invalid data, which was repaired. Some things may be missing or not work correctly.
\ No newline at end of file
diff --git a/ApplicationResourcePatches/manifest.json b/ApplicationResourcePatches/manifest.json
index b403f5a..fb2e19e 100644
--- a/ApplicationResourcePatches/manifest.json
+++ b/ApplicationResourcePatches/manifest.json
@@ -37,7 +37,8 @@
"LICS/1003.txt" : "ApplicationResourcePatches/LICS/1003.txt",
"LICS/1004.txt" : "ApplicationResourcePatches/LICS/1004.txt",
"LICS/1005.txt" : "ApplicationResourcePatches/LICS/1005.txt",
- "LICS/1006.txt" : "ApplicationResourcePatches/LICS/1006.txt"
+ "LICS/1006.txt" : "ApplicationResourcePatches/LICS/1006.txt",
+ "STR$23/1006.txt" : "ApplicationResourcePatches/STR/1006.txt"
},
"delete" :
[
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed16c19..e6e9c93 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,7 +118,6 @@ add_library(PortabilityLayer STATIC
PortabilityLayer/SimpleGraphic.cpp
PortabilityLayer/TextPlacer.cpp
PortabilityLayer/UTF8.cpp
- PortabilityLayer/UTF16.cpp
PortabilityLayer/WindowDef.cpp
PortabilityLayer/WindowManager.cpp
PortabilityLayer/WorkerThread.cpp
diff --git a/Common/CoreDefs.h b/Common/CoreDefs.h
index 55fa0c4..8e597ed 100644
--- a/Common/CoreDefs.h
+++ b/Common/CoreDefs.h
@@ -60,12 +60,16 @@ static const size_t GP_SYSTEM_MEMORY_ALIGNMENT = 16;
#define GP_ASYNCIFY_PARANOID 0
#endif
+#define GP_ASYNCIFY_PARANOID_VALIDATION 0
+
#if GP_ASYNCIFY_PARANOID
#define GP_ASYNCIFY_PARANOID_VIRTUAL
#define GP_ASYNCIFY_PARANOID_PURE
#define GP_ASYNCIFY_PARANOID_OVERRIDE
+#define GP_ASYNCIFY_PARANOID_NAMED(n) GpAsyncifyParanoid##n
#else
#define GP_ASYNCIFY_PARANOID_VIRTUAL virtual
#define GP_ASYNCIFY_PARANOID_PURE = 0
#define GP_ASYNCIFY_PARANOID_OVERRIDE override
+#define GP_ASYNCIFY_PARANOID_NAMED(n) n
#endif
diff --git a/ConvertColorCursors/ConvertColorCursors.cpp b/ConvertColorCursors/ConvertColorCursors.cpp
index a35b39e..4d8ee7e 100644
--- a/ConvertColorCursors/ConvertColorCursors.cpp
+++ b/ConvertColorCursors/ConvertColorCursors.cpp
@@ -1,11 +1,13 @@
#include "CFileStream.h"
#include "BMPFormat.h"
+#include "GpAllocator_C.h"
#include "MMHandleBlock.h"
#include "ResourceCompiledTypeList.h"
#include "ResourceFile.h"
#include "SharedTypes.h"
#include "QDStandardPalette.h"
#include "PLBigEndian.h"
+#include "PLDrivers.h"
#include
#include
@@ -141,6 +143,9 @@ int main(int argc, const char **argv)
PortabilityLayer::CFileStream stream(f);
+ GpDriverCollection *drivers = PLDrivers::GetDriverCollection();
+ drivers->SetDriver(GpAllocator_C::GetInstance());
+
PortabilityLayer::ResourceFile *resFile = PortabilityLayer::ResourceFile::Create();
if (!resFile->Load(&stream))
return -1;
diff --git a/ConvertColorCursors/ConvertColorCursors.vcxproj b/ConvertColorCursors/ConvertColorCursors.vcxproj
index 803089b..930df10 100644
--- a/ConvertColorCursors/ConvertColorCursors.vcxproj
+++ b/ConvertColorCursors/ConvertColorCursors.vcxproj
@@ -42,6 +42,7 @@
+
@@ -50,6 +51,7 @@
+
@@ -81,6 +83,7 @@
+
diff --git a/ConvertColorCursors/ConvertColorCursors.vcxproj.filters b/ConvertColorCursors/ConvertColorCursors.vcxproj.filters
index 310100b..d12c435 100644
--- a/ConvertColorCursors/ConvertColorCursors.vcxproj.filters
+++ b/ConvertColorCursors/ConvertColorCursors.vcxproj.filters
@@ -21,5 +21,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/ConvertResources.bat b/ConvertResources.bat
index 86f8bf5..f42e531 100644
--- a/ConvertResources.bat
+++ b/ConvertResources.bat
@@ -86,6 +86,9 @@ x64\Release\FTagData.exe "DefaultTimestamp.timestamp" "Packaged\Houses\Titanic.m
copy /Y GliderProData\ConvertedMovies\*.mov.gpa Packaged\Houses\
+rem Patch bad Castle 'o the Air start room
+x64\Release\HouseTool.exe patch "Packaged\Houses\Castle o' the Air.gpd" .firstRoom 77
+
x64\Release\MergeGPF.exe "Packaged\Houses\Art Museum.gpf"
x64\Release\MergeGPF.exe "Packaged\Houses\California or Bust!.gpf"
x64\Release\MergeGPF.exe "Packaged\Houses\Castle o' the Air.gpf"
diff --git a/GenerateFonts/GenerateFonts.cpp b/GenerateFonts/GenerateFonts.cpp
index 7534a47..d425ddb 100644
--- a/GenerateFonts/GenerateFonts.cpp
+++ b/GenerateFonts/GenerateFonts.cpp
@@ -3,6 +3,7 @@
#include "FontRenderer.h"
#include "IGpFont.h"
#include "IGpFontHandler.h"
+#include "GpAllocator_C.h"
#include "GpAppInterface.h"
#include "GpDriverIndex.h"
#include "GpFontHandlerProperties.h"
@@ -31,7 +32,7 @@ public:
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
const uint8_t *GetBytes() const;
@@ -167,8 +168,14 @@ bool KnownFontSpec::operator!=(const KnownFontSpec &other) const
int toolMain(int argc, const char **argv)
{
+ IGpAllocator *alloc = GpAllocator_C::GetInstance();
+
GpFontHandlerProperties fhProperties;
fhProperties.m_type = EGpFontHandlerType_FreeType2;
+ fhProperties.m_alloc = alloc;
+
+ GpDriverCollection *drivers = PLDrivers::GetDriverCollection();
+ drivers->SetDriver(alloc);
IGpFontHandler *ft2Handler = GpDriver_CreateFontHandler_FreeType2(fhProperties);
@@ -201,8 +208,10 @@ int toolMain(int argc, const char **argv)
int variation = fontFamily->GetVariationForFlags(flags);
PortabilityLayer::FontHacks hacks;
+ PortabilityLayer::VirtualDirectory_t vDir;
const char *path = nullptr;
- fontFamily->GetFontSpec(variation, hacks, path);
+ int typeFaceIndex = 0;
+ fontFamily->GetFontSpec(variation, hacks, vDir, path, typeFaceIndex);
KnownFontSpec spec(path, size, aa, hacks);
@@ -218,7 +227,7 @@ int toolMain(int argc, const char **argv)
{
PortabilityLayer::CFileStream stream(fontFile);
- IGpFont *font = ft2Handler->LoadFont(&stream);
+ IGpFont *font = ft2Handler->LoadFont(&stream, typeFaceIndex);
if (!ft2Handler->KeepStreamOpen())
stream.Close();
diff --git a/GenerateFonts/GenerateFonts.vcxproj b/GenerateFonts/GenerateFonts.vcxproj
index 2a6530b..57a1326 100644
--- a/GenerateFonts/GenerateFonts.vcxproj
+++ b/GenerateFonts/GenerateFonts.vcxproj
@@ -43,6 +43,7 @@
+
@@ -52,6 +53,7 @@
+
@@ -93,6 +95,7 @@
+
diff --git a/GenerateFonts/GenerateFonts.vcxproj.filters b/GenerateFonts/GenerateFonts.vcxproj.filters
index 9e43b4f..e46cc5f 100644
--- a/GenerateFonts/GenerateFonts.vcxproj.filters
+++ b/GenerateFonts/GenerateFonts.vcxproj.filters
@@ -18,5 +18,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/GpApp/Android.mk b/GpApp/Android.mk
index 6225bb7..3359f87 100644
--- a/GpApp/Android.mk
+++ b/GpApp/Android.mk
@@ -15,75 +15,7 @@ LOCAL_CFLAGS := -DGP_DEBUG_CONFIG=0 -DGP_ZLIB_BUILTIN=1
# Add your application source files here...
LOCAL_SRC_FILES := \
- About.cpp \
- AnimCursor.cpp \
- AppleEvents.cpp \
- Banner.cpp \
- ColorUtils.cpp \
- Coordinates.cpp \
- DialogUtils.cpp \
- DynamicMaps.cpp \
- Dynamics.cpp \
- Dynamics2.cpp \
- Dynamics3.cpp \
- Environ.cpp \
- Events.cpp \
- FileError.cpp \
- GameOver.cpp \
- GpAppInterface.cpp \
- Grease.cpp \
- HighScores.cpp \
- House.cpp \
- HouseInfo.cpp \
- HouseIO.cpp \
- HouseLegal.cpp \
- Input.cpp \
- Interactions.cpp \
- InterfaceInit.cpp \
- Link.cpp \
- Main.cpp \
- MainMenuUI.cpp \
- MainWindow.cpp \
- Map.cpp \
- Marquee.cpp \
- Menu.cpp \
- Modes.cpp \
- Music.cpp \
- ObjectAdd.cpp \
- ObjectDraw.cpp \
- ObjectDraw2.cpp \
- ObjectDrawAll.cpp \
- ObjectEdit.cpp \
- ObjectInfo.cpp \
- ObjectRects.cpp \
- Objects.cpp \
- Play.cpp \
- Player.cpp \
- Prefs.cpp \
- RectUtils.cpp \
- Render.cpp \
- Room.cpp \
- RoomGraphics.cpp \
- RoomInfo.cpp \
- RubberBands.cpp \
- SavedGames.cpp \
- Scoreboard.cpp \
- Scrap.cpp \
- SelectHouse.cpp \
- Settings.cpp \
- Sound.cpp \
- SoundSync_Cpp11.cpp \
- SourceExport.cpp \
- StringUtils.cpp \
- StructuresInit.cpp \
- StructuresInit2.cpp \
- Tools.cpp \
- Transit.cpp \
- Transitions.cpp \
- Triggers.cpp \
- Trip.cpp \
- Utilities.cpp \
- WindowUtils.cpp
+ GpApp_Combined.cpp
LOCAL_STATIC_LIBRARIES := PortabilityLayer
diff --git a/GpApp/Banner.cpp b/GpApp/Banner.cpp
index 2c224b5..0bdcc5d 100644
--- a/GpApp/Banner.cpp
+++ b/GpApp/Banner.cpp
@@ -119,7 +119,7 @@ void DrawBannerMessage (Point topLeft)
PasStringCopy((*thisHouse)->banner, bannerStr);
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
@@ -224,7 +224,7 @@ void DisplayStarsRemaining(void)
DrawSurface *surface = starsWindow->GetDrawSurface();
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
NumToString((long)numStarsRemaining, theStr);
diff --git a/GpApp/Events.cpp b/GpApp/Events.cpp
index 8e94c1e..b6f109c 100644
--- a/GpApp/Events.cpp
+++ b/GpApp/Events.cpp
@@ -339,6 +339,8 @@ void KeepWindowInBounds(Window *window)
void HandleEditorResolutionChange(void)
{
+ int oldRoom = thisRoomNumber;
+
FlushResolutionChange();
RecomputeInterfaceRects();
@@ -353,6 +355,9 @@ void HandleEditorResolutionChange(void)
//RefreshScoreboard(wasScoreboardTitleMode);
//DumpScreenOn(&justRoomsRect);
+ CopyRoomToThisRoom(oldRoom);
+ ReflectCurrentRoom(false);
+
if (toolsWindow)
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(toolsWindow, PortabilityLayer::WindowManager::GetInstance()->GetPutInFrontSentinel());
diff --git a/GpApp/GameOver.cpp b/GpApp/GameOver.cpp
index b5beec7..d7e28da 100644
--- a/GpApp/GameOver.cpp
+++ b/GpApp/GameOver.cpp
@@ -108,7 +108,7 @@ void SetUpFinalScreen (void)
{
GetLineOfText(tempStr, count, subStr);
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
offset = ((thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) -
appFont->MeasurePStr(subStr)) / 2;
diff --git a/GpApp/GliderDefines.h b/GpApp/GliderDefines.h
index 6925196..5e167a0 100644
--- a/GpApp/GliderDefines.h
+++ b/GpApp/GliderDefines.h
@@ -39,6 +39,8 @@
#define kYellowQTMovieNotLoaded 22
#define kYellowNoRooms 23
#define kYellowCantOrderLinks 24
+#define kYellowHouseDamaged 25
+#define kYellowHouseRepaired 26
#define kSwitchIfNeeded 0
@@ -261,6 +263,8 @@
#define kMaxStars 4
#define kMaxShredded 4
#define kMaxDynamicObs 18
+#define kMaxSoundTriggers 1
+#define kMaxStairs 1
#define kMaxMasterObjects 216 // kMaxRoomObs * 9
#define kMaxViewWidth 1536
#define kMaxViewHeight (kTileHigh*3+20)
@@ -626,3 +630,13 @@ static const Boolean kFaceLeft = FALSE; // Conflicts with GP input driver
#define kBBQCoalsComponent 1
#define kPendulumComponent 1
#define kStarComponent 1
+
+
+#define kMapGroundValue 56
+#define kUpwardVentMinY 36
+
+#define kMouseholeBottom 295
+#define kFireplaceBottom 297
+#define kManholeSits 322
+#define kGrecoVentTop 303
+#define kSewerBlowerTop 292
diff --git a/GpApp/GliderProtos.h b/GpApp/GliderProtos.h
index b09caf5..a40734a 100644
--- a/GpApp/GliderProtos.h
+++ b/GpApp/GliderProtos.h
@@ -9,6 +9,7 @@
#include "GliderStructs.h"
struct GpMouseInputEvent;
+struct houseType;
//-------------------------------------------------------------- Prototypes
@@ -124,7 +125,7 @@ void DoHouseInfo (void); // --- HouseInfo.c
Boolean OpenHouse (Boolean load); // --- HouseIO.c
Boolean OpenSpecificHouse (const VFileSpec &);
Boolean SaveHouseAs (void);
-Boolean ReadHouse (GpIOStream *houseStream);
+Boolean ReadHouse (GpIOStream *houseStream, bool untrusted);
Boolean WriteHouse (Boolean);
Boolean CloseHouse (void);
void OpenHouseResFork (void);
@@ -149,7 +150,7 @@ void GetDemoInput (gliderPtr); // --- Input.c
void GetInput (gliderPtr);
SInt16 MergeFloorSuite (SInt16, SInt16); // --- Link.c
-void ExtractFloorSuite (SInt16, SInt16 *, SInt16 *);
+void ExtractFloorSuite (const houseType *house, SInt16, SInt16 *, SInt16 *);
void UpdateLinkControl (void);
void UpdateLinkWindow (void);
void OpenLinkWindow (void);
@@ -321,6 +322,7 @@ void DuplicateObject (void);
void MoveObject (SInt16, Boolean);
void DeselectObject (void);
Boolean ObjectHasHandle (SInt16 *, SInt16 *);
+Boolean BlowerTypeHasUpperLimit (SInt16);
void HandleBlowerGlider (void);
void SelectNextObject (void);
void SelectPrevObject (void);
diff --git a/GpApp/GliderStructs.h b/GpApp/GliderStructs.h
index 328c595..1323aa9 100644
--- a/GpApp/GliderStructs.h
+++ b/GpApp/GliderStructs.h
@@ -191,7 +191,7 @@ struct houseType
Str255 banner; // 256
Str255 trailer; // 256
scoresType highScores; // 292
- gameType savedGame; // 40
+ gameType savedGame_Unused; // 40
Boolean hasGame; // 1
Boolean unusedBoolean; // 1
int16_t firstRoom; // 2
diff --git a/GpApp/HighScores.cpp b/GpApp/HighScores.cpp
index c033ad9..aa84ddc 100644
--- a/GpApp/HighScores.cpp
+++ b/GpApp/HighScores.cpp
@@ -149,7 +149,7 @@ void DrawHighScores (DrawSurface *surface)
DisposeGWorld(tempMap);
DisposeGWorld(tempMask);
- PortabilityLayer::RenderedFont *appFont14 = GetFont(PortabilityLayer::FontPresets::kApplication14Bold);
+ PortabilityLayer::RenderedFont *appFont14 = GetFont(PortabilityLayer::FontPresets::kApplication14SyntheticBold);
PasStringCopy(PSTR("\xa5 "), tempStr);
PasStringConcat(tempStr, thisHouseName);
@@ -161,7 +161,7 @@ void DrawHighScores (DrawSurface *surface)
const Point scoreTextPoint = Point::Create(scoreLeft + ((kScoreWide - appFont14->MeasurePStr(tempStr)) / 2), dropIt - 65);
surface->DrawString(scoreTextPoint, tempStr, cyanColor, appFont14);
- PortabilityLayer::RenderedFont *appFont12 = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont12 = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
thisHousePtr = *thisHouse;
// message for score #1
@@ -268,7 +268,7 @@ void DrawHighScores (DrawSurface *surface)
}
}
- PortabilityLayer::RenderedFont *appFont9 = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
+ PortabilityLayer::RenderedFont *appFont9 = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
const Point textPos = Point::Create(scoreLeft + 80, dropIt - 1 + (10 * kScoreSpacing));
GetLocalizedString(8, tempStr);
diff --git a/GpApp/House.cpp b/GpApp/House.cpp
index 78042ed..94da04a 100644
--- a/GpApp/House.cpp
+++ b/GpApp/House.cpp
@@ -385,7 +385,7 @@ void GenerateLinksList (void)
thisObject = thisHousePtr->rooms[r].objects[i];
if (thisObject.data.e.where != -1)
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
roomLinked = GetRoomNumber(floor, suite);
objectLinked = (short)thisObject.data.e.who;
linksList[numLinks].srcRoom = r;
@@ -405,7 +405,7 @@ void GenerateLinksList (void)
thisObject = thisHousePtr->rooms[r].objects[i];
if (thisObject.data.d.where != -1)
{
- ExtractFloorSuite(thisObject.data.d.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.d.where, &floor, &suite);
roomLinked = GetRoomNumber(floor, suite);
objectLinked = (short)thisObject.data.d.who;
linksList[numLinks].srcRoom = r;
@@ -597,7 +597,7 @@ void GenerateRetroLinks (void)
thisObject = thisHousePtr->rooms[r].objects[i];
if (thisObject.data.e.where != -1)
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
roomLinked = GetRoomNumber(floor, suite);
if (roomLinked == thisRoomNumber)
{
@@ -620,7 +620,7 @@ void GenerateRetroLinks (void)
thisObject = thisHousePtr->rooms[r].objects[i];
if (thisObject.data.d.where != -1)
{
- ExtractFloorSuite(thisObject.data.d.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.d.where, &floor, &suite);
roomLinked = GetRoomNumber(floor, suite);
if (roomLinked == thisRoomNumber)
{
@@ -794,7 +794,7 @@ void ConvertHouseVer1To2 (void)
case kDeluxeTrans:
if (thisRoom->objects[h].data.d.where != -1)
{
- ExtractFloorSuite(thisRoom->objects[h].data.d.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisRoom->objects[h].data.d.where, &floor, &suite);
floor += kNumUndergroundFloors;
thisRoom->objects[h].data.d.where = MergeFloorSuite(floor, suite);
}
@@ -810,7 +810,7 @@ void ConvertHouseVer1To2 (void)
case kLgTrigger:
if (thisRoom->objects[h].data.e.where != -1)
{
- ExtractFloorSuite(thisRoom->objects[h].data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisRoom->objects[h].data.e.where, &floor, &suite);
floor += kNumUndergroundFloors;
thisRoom->objects[h].data.e.where = MergeFloorSuite(floor, suite);
}
diff --git a/GpApp/HouseIO.cpp b/GpApp/HouseIO.cpp
index 16a433a..e0cb0f7 100644
--- a/GpApp/HouseIO.cpp
+++ b/GpApp/HouseIO.cpp
@@ -15,6 +15,7 @@
#include "IGpLogDriver.h"
#include "IGpSystemServices.h"
#include "ObjectEdit.h"
+#include "RectUtils.h"
#include "ResourceManager.h"
#include "PLDialogs.h"
@@ -158,7 +159,7 @@ Boolean OpenHouse (Boolean read)
if (read)
{
- Boolean readOK = ReadHouse(houseStream);
+ Boolean readOK = ReadHouse(houseStream, theHousesSpecs[thisHouseIndex].m_dir != PortabilityLayer::VirtualDirectories::kGameData);
houseStream->Close();
return readOK;
@@ -523,7 +524,7 @@ bool ByteSwapHouse(housePtr house, size_t sizeInBytes, bool isSwappedAfter)
SanitizePascalStr(house->banner);
SanitizePascalStr(house->trailer);
ByteSwapScores(&house->highScores);
- ByteSwapSavedGame(&house->savedGame);
+ ByteSwapSavedGame(&house->savedGame_Unused);
PortabilityLayer::ByteSwap::BigInt16(house->firstRoom);
PortabilityLayer::ByteSwap::BigInt16(house->nRooms);
@@ -542,10 +543,1402 @@ bool ByteSwapHouse(housePtr house, size_t sizeInBytes, bool isSwappedAfter)
return true;
}
-Boolean ReadHouse (GpIOStream *houseStream)
+static bool FailCheck(bool value)
+{
+ return value;
+}
+
+static bool SucceedCheck(bool value)
+{
+ return value;
+}
+
+static bool LCheck(bool value)
+{
+ if (!value)
+ return FailCheck(value);
+
+ return value;
+}
+
+static bool RCheck(bool value)
+{
+ if (value)
+ return SucceedCheck(value);
+
+ return value;
+}
+
+template
+bool LegalizePascalStr(uint8_t(&chars)[TSize], bool &anyRepairs)
+{
+ const size_t maxLength = TSize - 1;
+ if (chars[0] > maxLength)
+ {
+ chars[0] = static_cast(maxLength);
+ anyRepairs = RCheck(true);
+ return true;
+ }
+
+ return true;
+}
+
+static void LegalizeBoolean(Boolean &b)
+{
+ if (b < 0 || b > 1)
+ b = 1;
+}
+
+static bool LegalizeScores(scoresType *scores, bool &anyRepairs)
+{
+ if (!LegalizePascalStr(scores->banner, anyRepairs))
+ return LCheck(false);
+
+ for (int i = 0; i < kMaxScores; i++)
+ if (!LegalizePascalStr(scores->names[i], anyRepairs))
+ return LCheck(false);
+
+ return true;
+}
+
+static bool LegalizeRoomLayout(houseType *house, size_t roomNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ if (room->suite == kRoomIsEmpty)
+ return true;
+
+ if (room->suite < 0 || room->suite >= kMaxNumRoomsH)
+ {
+ room->suite = kRoomIsEmpty;
+ anyRepairs = RCheck(true);
+ return true;
+ }
+
+ if (room->floor > (kMaxNumRoomsV - kNumUndergroundFloors) || room->floor <= -kNumUndergroundFloors)
+ {
+ room->suite = kRoomIsEmpty;
+ anyRepairs = RCheck(true);
+ return true;
+ }
+
+ for (size_t ori = 0; ori < roomNum; ori++)
+ {
+ const roomType *otherRoom = house->rooms + ori;
+ if (otherRoom->floor == room->floor && otherRoom->suite == room->suite)
+ {
+ room->suite = kRoomIsEmpty;
+ anyRepairs = RCheck(true);
+ return true;
+ }
+ }
+
+ return true;
+}
+
+static void LegalizeTopLeft(Point &topLeft, bool &anyRepairs)
+{
+ if (topLeft.h < 0)
+ {
+ anyRepairs = RCheck(true);
+ topLeft.h = 0;
+ }
+ else if (topLeft.h >= kRoomWide)
+ {
+ anyRepairs = RCheck(true);
+ topLeft.h = kRoomWide - 1;
+ }
+
+ if (topLeft.v < 0)
+ {
+ anyRepairs = RCheck(true);
+ topLeft.v = 0;
+ }
+ else if (topLeft.v >= kTileHigh)
+ {
+ anyRepairs = RCheck(true);
+ topLeft.v = kTileHigh - 1;
+ }
+}
+
+template
+void LegalizeExpect(const TCondA &condA, const TCondB &condB, TSet &set, const TSetTo &setTo, bool &anyRepairs)
+{
+ if (condA == condB && set != setTo)
+ {
+ set = setTo;
+ anyRepairs = RCheck(true);
+ }
+}
+
+static Boolean ForceRectInRoomRect(Rect &rect)
+{
+ Rect roomRect;
+ QSetRect(&roomRect, 0, 0, kRoomWide, kTileHigh);
+
+ return ForceRectInRect(&rect, &roomRect);
+}
+
+
+static bool LegalizeBlower(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ blowerType *blower = &obj->data.a;
+
+ LegalizeBoolean(blower->initial);
+ LegalizeBoolean(blower->state);
+
+ int direction = -1;
+ for (int i = 0; i < 4; i++)
+ {
+ if (blower->vector & (1 << i))
+ {
+ if (direction >= 0)
+ anyRepairs = RCheck(true);
+ else
+ direction = i;
+ }
+ }
+
+ static const int kDirectionUp = 0;
+ static const int kDirectionRight = 1;
+ static const int kDirectionDown = 2;
+ static const int kDirectionLeft = 3;
+
+ if (direction < 0 || direction > 3)
+ direction = kDirectionUp;
+
+ LegalizeTopLeft(blower->topLeft, anyRepairs);
+
+ switch (obj->what)
+ {
+ case kFloorVent:
+ case kFloorBlower:
+ case kSewerGrate:
+ case kTaper:
+ case kCandle:
+ case kStubby:
+ case kTiki:
+ case kBBQ:
+ case kGrecoVent:
+ case kSewerBlower:
+ if (direction != kDirectionUp)
+ direction = kDirectionUp;
+ break;
+ case kCeilingVent:
+ case kCeilingBlower:
+ if (direction != kDirectionDown)
+ direction = kDirectionDown;
+ break;
+ case kRightFan:
+ if (direction != kDirectionRight)
+ direction = kDirectionRight;
+ break;
+ case kLeftFan:
+ if (direction != kDirectionLeft)
+ direction = kDirectionLeft;
+ break;
+ case kInvisBlower:
+ case kLiftArea:
+ break;
+ default:
+ return LCheck(false);
+ }
+
+ LegalizeExpect(obj->what, kFloorVent, blower->topLeft.v, kFloorVentTop, anyRepairs);
+ LegalizeExpect(obj->what, kFloorBlower, blower->topLeft.v, kFloorBlowerTop, anyRepairs);
+ LegalizeExpect(obj->what, kSewerGrate, blower->topLeft.v, kSewerGrateTop, anyRepairs);
+ LegalizeExpect(obj->what, kCeilingVent, blower->topLeft.v, kCeilingVentTop, anyRepairs);
+ LegalizeExpect(obj->what, kCeilingBlower, blower->topLeft.v, kCeilingBlowerTop, anyRepairs);
+
+ if (blower->vector != (1 << direction))
+ {
+ blower->vector = static_cast(1 << direction);
+
+ // Unfortunately there's a lot of invalid directional data with fans, but because of how the code works, it has no effect
+ //anyRepairs = RCheck(true);
+ }
+
+ if (blower->distance < 0)
+ {
+ blower->distance = 0;
+ anyRepairs = RCheck(true);
+ }
+
+ if (obj->what == kLiftArea)
+ {
+ int maxWidth = kRoomWide - blower->topLeft.h;
+ int maxHeight = kTileHigh - blower->topLeft.v;
+
+ if (blower->distance > maxWidth)
+ {
+ blower->distance = maxWidth;
+ anyRepairs = RCheck(true);
+ }
+
+ if (blower->tall * 2 > maxHeight)
+ {
+ blower->tall = static_cast(maxHeight / 2);
+ anyRepairs = RCheck(true);
+ }
+
+ return true;
+ }
+
+ Rect positionedRect = srcRects[obj->what];
+ ZeroRectCorner(&positionedRect);
+ OffsetRect(&positionedRect, blower->topLeft.h, blower->topLeft.v);
+
+ const Rect basePositionedRect = positionedRect;
+
+ if (ForceRectInRoomRect(positionedRect))
+ {
+ anyRepairs = RCheck(true);
+ blower->topLeft.h = positionedRect.left;
+ blower->topLeft.v = positionedRect.top;
+ }
+
+ int maxDistance = 0;
+ switch (direction)
+ {
+ case kDirectionUp:
+ {
+ int highestAllowed = BlowerTypeHasUpperLimit(obj->what) ? kUpwardVentMinY : 0;
+ maxDistance = blower->topLeft.v - highestAllowed;
+ }
+ break;
+ case kDirectionRight:
+ maxDistance = kRoomWide - positionedRect.right;
+ break;
+ case kDirectionDown:
+ maxDistance = kTileHigh - positionedRect.bottom;
+ break;
+ case kDirectionLeft:
+ maxDistance = positionedRect.left;
+ break;
+ default:
+ assert(false);
+ return LCheck(false);
+ }
+
+ if (blower->distance > maxDistance)
+ {
+ blower->distance = maxDistance;
+ anyRepairs = RCheck(true);
+ }
+
+ return true;
+}
+
+static bool LegalizeFurniture(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ furnitureType *furniture = &obj->data.b;
+
+ bool isVertConstrained = false;
+ bool isHorizConstrained = false;
+ bool isBottomConstrained = false;
+
+ int bottomConstraint = 0;
+
+ switch (obj->what)
+ {
+ default:
+ assert(false);
+ return LCheck(false);
+
+ case kTable:
+ case kShelf:
+ case kDeckTable:
+ isVertConstrained = true;
+ break;
+ case kBooks:
+ case kFilingCabinet:
+ case kWasteBasket:
+ case kMilkCrate:
+ case kStool:
+ case kTrunk:
+ isVertConstrained = true;
+ isHorizConstrained = true;
+ break;
+ case kCabinet:
+ case kInvisObstacle:
+ case kInvisBounce:
+ // No constraints
+ break;
+ case kCounter:
+ isBottomConstrained = true;
+ bottomConstraint = kCounterBottom;
+ break;
+ case kDresser:
+ isBottomConstrained = true;
+ bottomConstraint = kDresserBottom;
+ break;
+ case kManhole:
+ isVertConstrained = true;
+ isHorizConstrained = true;
+ isBottomConstrained = true;
+ bottomConstraint = kManholeSits;
+ break;
+ };
+
+ const Rect baseRect = srcRects[obj->what];
+
+ if (NormalizeRect(&furniture->bounds))
+ anyRepairs = RCheck(true);
+
+ Point topLeft = Point::Create(furniture->bounds.left, furniture->bounds.top);
+ LegalizeTopLeft(topLeft, anyRepairs);
+
+ if (obj->what == kManhole)
+ {
+ if (((topLeft.h - 3) % 64) != 0)
+ {
+ topLeft.h = (((topLeft.h + 29) / 64) * 64) + 3;
+ anyRepairs = RCheck(true);
+ }
+ }
+
+ uint16_t width = furniture->bounds.Width();
+ uint16_t height = furniture->bounds.Height();
+
+ if (width > kRoomWide)
+ {
+ width = kRoomWide;
+ anyRepairs = RCheck(true);
+ }
+
+ if (height > kTileHigh)
+ {
+ height = kTileHigh;
+ anyRepairs = RCheck(true);
+ }
+
+ LegalizeExpect(isVertConstrained, true, height, baseRect.Height(), anyRepairs);
+ LegalizeExpect(isHorizConstrained, true, width, baseRect.Width(), anyRepairs);
+
+ furniture->bounds.left = topLeft.h;
+ furniture->bounds.top = topLeft.v;
+ furniture->bounds.bottom = topLeft.v + static_cast(height);
+ furniture->bounds.right = topLeft.h + static_cast(width);
+
+ if (ForceRectInRoomRect(furniture->bounds))
+ anyRepairs = RCheck(true);
+
+ if (isBottomConstrained && furniture->bounds.bottom != bottomConstraint)
+ {
+ if (furniture->bounds.top > bottomConstraint)
+ furniture->bounds.top = bottomConstraint;
+
+ furniture->bounds.bottom = bottomConstraint;
+ anyRepairs = RCheck(true);
+ }
+
+ return true;
+}
+
+static bool LegalizeBonus(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ bonusType *bonus = &obj->data.c;
+
+ LegalizeBoolean(bonus->state);
+ LegalizeBoolean(bonus->initial);
+
+ if (obj->what == kInvisBonus && bonus->points < 0)
+ {
+ anyRepairs = RCheck(true);
+ bonus->points = 0;
+ }
+
+ LegalizeTopLeft(bonus->topLeft, anyRepairs);
+
+ switch (obj->what)
+ {
+ default:
+ return LCheck(false);
+
+ case kRedClock:
+ case kBlueClock:
+ case kYellowClock:
+ case kCuckoo:
+ case kPaper:
+ case kBattery:
+ case kBands:
+ case kGreaseRt:
+ case kGreaseLf:
+ case kFoil:
+ case kInvisBonus:
+ case kStar:
+ case kSparkle:
+ case kHelium:
+ case kSlider:
+ break;
+ };
+
+ Rect objRect = srcRects[obj->what];
+ ZeroRectCorner(&objRect);
+
+ if (obj->what == kSlider)
+ {
+ if (bonus->length < 0)
+ {
+ anyRepairs = RCheck(true);
+ bonus->length = 0;
+ }
+ else if (bonus->length > kRoomWide)
+ {
+ anyRepairs = RCheck(true);
+ bonus->length = kRoomWide;
+ }
+
+ objRect.right = bonus->length;
+ }
+
+ QOffsetRect(&objRect, bonus->topLeft.h, bonus->topLeft.v);
+
+ if (ForceRectInRoomRect(objRect))
+ {
+ anyRepairs = RCheck(true);
+ bonus->topLeft.h = objRect.left;
+ bonus->topLeft.v = objRect.top;
+ }
+
+ int maxLength = -1;
+ if (obj->what == kGreaseRt)
+ maxLength = kRoomWide - objRect.right;
+
+ if (obj->what == kGreaseLf)
+ maxLength = objRect.left;
+
+ if (obj->what == kSlider)
+ maxLength = kRoomWide - bonus->topLeft.h;
+
+ if (maxLength >= 0)
+ {
+ if (bonus->length < 0)
+ {
+ anyRepairs = RCheck(true);
+ bonus->length = 0;
+ }
+ else if (bonus->length > maxLength)
+ {
+ anyRepairs = RCheck(true);
+ bonus->length = maxLength;
+ }
+ }
+
+ return true;
+}
+
+static void LegalizeRoomLink(houseType *house, int16_t &where, bool &anyRepairs)
+{
+ // Leftover -1 from version conversion, these are generally valid
+ if (where == -100)
+ where = -1;
+
+ if (where < -1)
+ {
+ anyRepairs = RCheck(true);
+ where = -1;
+ }
+ else if (where >= 0)
+ {
+ SInt16 floor, suite;
+ ExtractFloorSuite(house, where, &floor, &suite);
+
+ if (suite < 0 || suite >= kMaxNumRoomsH)
+ {
+ anyRepairs = RCheck(true);
+ where = -1;
+ }
+
+ if (floor > (kMaxNumRoomsV - kNumUndergroundFloors) || floor <= -kNumUndergroundFloors)
+ {
+ anyRepairs = RCheck(true);
+ where = -1;
+ }
+ }
+}
+
+static bool LegalizeTransport(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ transportType *transport = &obj->data.d;
+
+ LegalizeTopLeft(transport->topLeft, anyRepairs);
+ LegalizeRoomLink(house, transport->where, anyRepairs);
+
+ Rect objRect = srcRects[obj->what];
+ ZeroRectCorner(&objRect);
+
+ if (obj->what == kInvisTrans)
+ {
+ if (transport->tall < 0)
+ {
+ anyRepairs = RCheck(true);
+ transport->tall = 0;
+ }
+ else if (transport->tall > kTileHigh)
+ {
+ anyRepairs = RCheck(true);
+ transport->tall = kTileHigh;
+ }
+
+ objRect.right = transport->wide;
+ objRect.bottom = transport->tall;
+ }
+
+
+ if (obj->what == kDeluxeTrans)
+ {
+ uint8_t codedWidth = static_cast((transport->tall >> 8) & 0xff);
+ uint8_t codedHeight = static_cast((transport->tall) & 0xff);
+
+ objRect.right = codedWidth * 4;
+ objRect.bottom = codedHeight * 4;
+ }
+
+ QOffsetRect(&objRect, transport->topLeft.h, transport->topLeft.v);
+
+ if (ForceRectInRoomRect(objRect))
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = objRect.left;
+ transport->topLeft.v = objRect.top;
+
+ if (obj->what == kDeluxeTrans)
+ transport->tall = static_cast(((objRect.Width() / 4) << 8) + objRect.Height() / 4);
+ else if (obj->what == kInvisTrans)
+ {
+ transport->wide = objRect.Width();
+ transport->tall = objRect.Height();
+ }
+ }
+
+ switch (obj->what)
+ {
+ default:
+ return LCheck(false);
+
+ case kUpStairs:
+ case kDownStairs:
+ if (transport->topLeft.v != kStairsTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kStairsTop;
+ }
+ break;
+ case kFloorTrans:
+ if (transport->topLeft.v != kFloorTransTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kFloorTransTop;
+ }
+ break;
+ case kCeilingTrans:
+ if (transport->topLeft.v != kCeilingTransTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kCeilingTransTop;
+ }
+ break;
+ case kDoorInLf:
+ if (transport->topLeft.h != kDoorInLfLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kCeilingTransTop;
+ }
+ if (transport->topLeft.v != kDoorInTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kDoorInTop;
+ }
+ break;
+ case kDoorInRt:
+ if (transport->topLeft.h != kDoorInRtLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kDoorInRtLeft;
+ }
+ if (transport->topLeft.v != kDoorInTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kDoorInTop;
+ }
+ break;
+ case kDoorExRt:
+ if (transport->topLeft.h != kDoorExRtLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kDoorExRtLeft;
+ }
+ if (transport->topLeft.v != kDoorExTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kDoorExTop;
+ }
+ break;
+ case kDoorExLf:
+ if (transport->topLeft.h != kDoorExLfLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kDoorExLfLeft;
+ }
+ if (transport->topLeft.v != kDoorExTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kDoorExTop;
+ }
+ break;
+ case kWindowInLf:
+ if (transport->topLeft.h != kWindowInLfLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kWindowInLfLeft;
+ }
+ if (transport->topLeft.v != kWindowInTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kWindowInTop;
+ }
+ break;
+ case kWindowInRt:
+ if (transport->topLeft.h != kWindowInRtLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kWindowInRtLeft;
+ }
+ if (transport->topLeft.v != kWindowInTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kWindowInTop;
+ }
+ break;
+ case kWindowExRt:
+ if (transport->topLeft.h != kWindowExRtLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kWindowExRtLeft;
+ }
+ if (transport->topLeft.v != kWindowExTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kWindowExTop;
+ }
+ break;
+ case kWindowExLf:
+ if (transport->topLeft.h != kWindowExLfLeft)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.h = kWindowExLfLeft;
+ }
+ if (transport->topLeft.v != kWindowExTop)
+ {
+ anyRepairs = RCheck(true);
+ transport->topLeft.v = kWindowExTop;
+ }
+ break;
+ case kInvisTrans:
+ case kDeluxeTrans:
+ case kMailboxLf:
+ case kMailboxRt:
+ break;
+ }
+
+ return true;
+}
+
+static bool LegalizeSwitch(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ switchType *sw = &obj->data.e;
+
+ if (sw->delay < 0)
+ {
+ sw->delay = 0;
+ anyRepairs = RCheck(true);
+ }
+
+ bool isSwitch = false;
+ bool isTrigger = false;
+
+ switch (obj->what)
+ {
+ default:
+ return RCheck(false);
+
+ case kLightSwitch:
+ case kMachineSwitch:
+ case kThermostat:
+ case kPowerSwitch:
+ case kKnifeSwitch:
+ case kInvisSwitch:
+ isSwitch = true;
+ LegalizeRoomLink(house, sw->where, anyRepairs);
+ break;
+ case kTrigger:
+ case kLgTrigger:
+ LegalizeRoomLink(house, sw->where, anyRepairs);
+ break;
+ case kSoundTrigger:
+ break;
+ };
+
+ if (isSwitch)
+ {
+ switch (sw->type)
+ {
+ case kToggle:
+ case kForceOn:
+ case kForceOff:
+ break;
+ default:
+ anyRepairs = RCheck(true);
+ sw->type = kToggle;
+ break;
+ }
+ }
+
+ if (isTrigger)
+ {
+ if (sw->type != kOneShot)
+ {
+ anyRepairs = RCheck(true);
+ sw->type = kOneShot;
+ }
+ }
+
+ LegalizeTopLeft(sw->topLeft, anyRepairs);
+
+ Rect bounds = srcRects[obj->what];
+ ZeroRectCorner(&bounds);
+ QOffsetRect(&bounds, sw->topLeft.h, sw->topLeft.v);
+
+ if (ForceRectInRoomRect(bounds))
+ {
+ anyRepairs = RCheck(true);
+ sw->topLeft.h = bounds.left;
+ sw->topLeft.v = bounds.top;
+ }
+
+ return true;
+}
+
+static bool LegalizeLight(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ lightType *light = &obj->data.f;
+
+ LegalizeBoolean(light->initial);
+ LegalizeBoolean(light->state);
+
+ LegalizeTopLeft(light->topLeft, anyRepairs);
+
+ Rect bounds = srcRects[obj->what];
+ ZeroRectCorner(&bounds);
+
+ if (obj->what == kTrackLight || obj->what == kFlourescent)
+ {
+ if (light->length < 0)
+ {
+ anyRepairs = RCheck(true);
+ light->length = 0;
+ }
+ else if (light->length > kRoomWide)
+ {
+ anyRepairs = RCheck(true);
+ light->length = kRoomWide;
+ }
+
+ bounds.right = light->length;
+ }
+
+ QOffsetRect(&bounds, light->topLeft.h, light->topLeft.v);
+
+ if (ForceRectInRoomRect(bounds))
+ {
+ anyRepairs = RCheck(true);
+ light->topLeft.h = bounds.left;
+ light->topLeft.v = bounds.top;
+ }
+
+ switch (obj->what)
+ {
+ case kCeilingLight:
+ if (light->topLeft.v != kCeilingLightTop)
+ {
+ anyRepairs = RCheck(true);
+ light->topLeft.v = kCeilingLightTop;
+ }
+ break;
+ case kHipLamp:
+ if (light->topLeft.v != kHipLampTop)
+ {
+ anyRepairs = RCheck(true);
+ light->topLeft.v = kHipLampTop;
+ }
+ break;
+ case kDecoLamp:
+ if (light->topLeft.v != kDecoLampTop)
+ {
+ anyRepairs = RCheck(true);
+ light->topLeft.v = kDecoLampTop;
+ }
+ break;
+ case kFlourescent:
+ if (light->topLeft.v != kFlourescentTop)
+ {
+ anyRepairs = RCheck(true);
+ light->topLeft.v = kFlourescentTop;
+ }
+ break;
+ case kTrackLight:
+ if (light->topLeft.v != kTrackLightTop)
+ {
+ anyRepairs = RCheck(true);
+ light->topLeft.v = kTrackLightTop;
+ }
+ break;
+ case kLightBulb:
+ case kTableLamp:
+ case kInvisLight:
+ break;
+ }
+
+ return true;
+}
+
+static bool LegalizeAppliance(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ applianceType *appl = &obj->data.g;
+
+ LegalizeBoolean(appl->initial);
+ LegalizeBoolean(appl->state);
+
+ LegalizeTopLeft(appl->topLeft, anyRepairs);
+
+ if (obj->what != kCustomPict)
+ {
+ Rect bounds = srcRects[obj->what];
+ ZeroRectCorner(&bounds);
+ QOffsetRect(&bounds, appl->topLeft.h, appl->topLeft.v);
+
+ if (ForceRectInRoomRect(bounds))
+ {
+ anyRepairs = RCheck(true);
+ appl->topLeft.h = bounds.left;
+ appl->topLeft.v = bounds.top;
+ }
+
+ switch (obj->what)
+ {
+ case kToaster:
+ {
+ int maxHeight = bounds.top;
+ if (appl->height < 0)
+ {
+ anyRepairs = RCheck(true);
+ appl->height = 0;
+ }
+ else if (appl->height > maxHeight)
+ {
+ anyRepairs = RCheck(true);
+ appl->height = maxHeight;
+ }
+ }
+ break;
+ case kShredder:
+ case kMacPlus:
+ case kGuitar:
+ case kTV:
+ case kCoffee:
+ case kOutlet:
+ case kVCR:
+ case kStereo:
+ case kMicrowave:
+ case kCinderBlock:
+ case kFlowerBox:
+ case kCDs:
+ break;
+ }
+ }
+
+ return true;
+}
+
+static bool LegalizeEnemy(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ enemyType *enemy = &obj->data.h;
+
+ LegalizeBoolean(enemy->initial);
+ LegalizeBoolean(enemy->state);
+
+ LegalizeTopLeft(enemy->topLeft, anyRepairs);
+
+ Rect bounds = srcRects[obj->what];
+ ZeroRectCorner(&bounds);
+ QOffsetRect(&bounds, enemy->topLeft.h, enemy->topLeft.v);
+
+ if (ForceRectInRoomRect(bounds))
+ {
+ anyRepairs = RCheck(true);
+ enemy->topLeft.h = bounds.left;
+ enemy->topLeft.v = bounds.top;
+ }
+
+ switch (obj->what)
+ {
+ case kBalloon:
+ case kCopterLf:
+ case kCopterRt:
+ {
+ int expectedV = (kTileHigh / 2) - HalfRectTall(&bounds);
+ if (enemy->topLeft.v != expectedV)
+ {
+ anyRepairs = RCheck(true);
+ enemy->topLeft.v = expectedV;
+ }
+ }
+ break;
+ case kDartLf:
+ {
+ int expectedH = kRoomWide - RectWide(&bounds);
+ if (enemy->topLeft.h != expectedH)
+ {
+ anyRepairs = RCheck(true);
+ enemy->topLeft.h = expectedH;
+ }
+ }
+ break;
+ case kDartRt:
+ if (enemy->topLeft.h != 0)
+ {
+ anyRepairs = RCheck(true);
+ enemy->topLeft.h = 0;
+ }
+ break;
+ case kBall:
+ case kFish:
+ {
+ int maxLength = bounds.top;
+ if (enemy->length < 0)
+ {
+ anyRepairs = RCheck(true);
+ enemy->length = 0;
+ }
+ else if (enemy->length > maxLength)
+ {
+ anyRepairs = RCheck(true);
+ enemy->length = maxLength;
+ }
+ }
+ break;
+ case kDrip:
+ {
+ int maxLength = kTileHigh - bounds.bottom;
+ if (enemy->length < 0)
+ {
+ anyRepairs = RCheck(true);
+ enemy->length = 0;
+ }
+ else if (enemy->length > maxLength)
+ {
+ anyRepairs = RCheck(true);
+ enemy->length = maxLength;
+ }
+ }
+ break;
+ case kCobweb:
+ break;
+ }
+
+ return true;
+}
+
+static bool LegalizeClutter(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+ clutterType *blower = &obj->data.i;
+
+ PL_NotYetImplemented_TODO("Validate");
+ return true;
+}
+
+
+static bool LegalizeObject(houseType *house, size_t roomNum, size_t objectNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ objectType *obj = room->objects + objectNum;
+
+ switch (obj->what)
+ {
+ default:
+ obj->what = kObjectIsEmpty;
+ anyRepairs = RCheck(true);
+ break;
+ case kObjectIsEmpty:
+ break;
+
+ case kFloorVent:
+ case kCeilingVent:
+ case kFloorBlower:
+ case kCeilingBlower:
+ case kSewerGrate:
+ case kLeftFan:
+ case kRightFan:
+ case kTaper:
+ case kCandle:
+ case kStubby:
+ case kTiki:
+ case kBBQ:
+ case kInvisBlower:
+ case kGrecoVent:
+ case kSewerBlower:
+ case kLiftArea:
+ return LegalizeBlower(house, roomNum, objectNum, anyRepairs);
+
+ case kTable:
+ case kShelf:
+ case kCabinet:
+ case kFilingCabinet:
+ case kWasteBasket:
+ case kMilkCrate:
+ case kCounter:
+ case kDresser:
+ case kDeckTable:
+ case kStool:
+ case kTrunk:
+ case kInvisObstacle:
+ case kManhole:
+ case kBooks:
+ case kInvisBounce:
+ return LegalizeFurniture(house, roomNum, objectNum, anyRepairs);
+
+ case kRedClock:
+ case kBlueClock:
+ case kYellowClock:
+ case kCuckoo:
+ case kPaper:
+ case kBattery:
+ case kBands:
+ case kGreaseRt:
+ case kGreaseLf:
+ case kFoil:
+ case kInvisBonus:
+ case kStar:
+ case kSparkle:
+ case kHelium:
+ case kSlider:
+ return LegalizeBonus(house, roomNum, objectNum, anyRepairs);
+
+ case kUpStairs:
+ case kDownStairs:
+ case kMailboxLf:
+ case kMailboxRt:
+ case kFloorTrans:
+ case kCeilingTrans:
+ case kDoorInLf:
+ case kDoorInRt:
+ case kDoorExRt:
+ case kDoorExLf:
+ case kWindowInLf:
+ case kWindowInRt:
+ case kWindowExRt:
+ case kWindowExLf:
+ case kInvisTrans:
+ case kDeluxeTrans:
+ return LegalizeTransport(house, roomNum, objectNum, anyRepairs);
+
+ case kLightSwitch:
+ case kMachineSwitch:
+ case kThermostat:
+ case kPowerSwitch:
+ case kKnifeSwitch:
+ case kInvisSwitch:
+ case kTrigger:
+ case kLgTrigger:
+ case kSoundTrigger:
+ return LegalizeSwitch(house, roomNum, objectNum, anyRepairs);
+
+ case kCeilingLight:
+ case kLightBulb:
+ case kTableLamp:
+ case kHipLamp:
+ case kDecoLamp:
+ case kFlourescent:
+ case kTrackLight:
+ case kInvisLight:
+ return LegalizeLight(house, roomNum, objectNum, anyRepairs);
+
+ case kShredder:
+ case kToaster:
+ case kMacPlus:
+ case kGuitar:
+ case kTV:
+ case kCoffee:
+ case kOutlet:
+ case kVCR:
+ case kStereo:
+ case kMicrowave:
+ case kCinderBlock:
+ case kFlowerBox:
+ case kCDs:
+ case kCustomPict:
+ return LegalizeAppliance(house, roomNum, objectNum, anyRepairs);
+
+ case kBalloon:
+ case kCopterLf:
+ case kCopterRt:
+ case kDartLf:
+ case kDartRt:
+ case kBall:
+ case kDrip:
+ case kFish:
+ case kCobweb:
+ return LegalizeEnemy(house, roomNum, objectNum, anyRepairs);
+
+ case kOzma:
+ case kMirror:
+ case kMousehole:
+ case kFireplace:
+ case kFlower:
+ case kWallWindow:
+ case kBear:
+ case kCalendar:
+ case kVase1:
+ case kVase2:
+ case kBulletin:
+ case kCloud:
+ case kFaucet:
+ case kRug:
+ case kChimes:
+ return LegalizeClutter(house, roomNum, objectNum, anyRepairs);
+ }
+
+ return true;
+}
+
+static bool LegalizeRoom(houseType *house, size_t roomNum, bool &anyRepairs)
+{
+ roomType *room = house->rooms + roomNum;
+ if (room->suite == kRoomIsEmpty)
+ return true;
+
+ if (!LegalizePascalStr(room->name, anyRepairs))
+ return LCheck(false);
+
+ LegalizeBoolean(room->visited);
+
+ for (int i = 0; i < kNumTiles; i++)
+ {
+ if (room->tiles[i] < 0)
+ {
+ room->tiles[i] = 0;
+ anyRepairs = RCheck(true);
+ }
+ else if (room->tiles[i] >= kNumTiles)
+ {
+ room->tiles[i] = kNumTiles - 1;
+ anyRepairs = RCheck(true);
+ }
+ }
+
+ // Enforce object type caps
+ enum CapType
+ {
+ CapType_Candle,
+ CapType_Tiki,
+ CapType_Coals,
+ CapType_Pendulum,
+ CapType_RubberBands,
+ CapType_Star,
+ CapType_DynamicObj,
+ CapType_SoundTrigger,
+ CapType_UpStairs,
+ CapType_DownStairs,
+ CapType_Grease,
+
+ CapType_Count,
+ };
+
+ int caps[CapType_Count];
+ caps[CapType_Candle] = kMaxCandles;
+ caps[CapType_Tiki] = kMaxTikis;
+ caps[CapType_Coals] = kMaxCoals;
+ caps[CapType_Pendulum] = kMaxPendulums;
+ caps[CapType_RubberBands] = kMaxRubberBands;
+ caps[CapType_Star] = kMaxStars;
+ caps[CapType_DynamicObj] = kMaxDynamicObs;
+ caps[CapType_SoundTrigger] = kMaxSoundTriggers;
+ caps[CapType_UpStairs] = kMaxStairs;
+ caps[CapType_DownStairs] = kMaxStairs;
+ caps[CapType_Grease] = kMaxGrease;
+
+ int counts[CapType_Count];
+ for (int i = 0; i < CapType_Count; i++)
+ counts[i] = 0;
+
+ for (size_t i = 0; i < kMaxRoomObs; i++)
+ {
+ CapType capType = CapType_Count;
+
+ objectType *obj = room->objects + i;
+ switch (obj->what)
+ {
+ case kTaper:
+ case kCandle:
+ case kStubby:
+ capType = CapType_Candle;
+ break;
+ case kTiki:
+ capType = CapType_Tiki;
+ break;
+ case kBBQ:
+ capType = CapType_Coals;
+ break;
+ case kCuckoo:
+ capType = CapType_Pendulum;
+ break;
+ case kBands:
+ capType = CapType_RubberBands;
+ break;
+ case kStar:
+ capType = CapType_Star;
+ break;
+ case kSparkle:
+ case kToaster:
+ case kMacPlus:
+ case kTV:
+ case kCoffee:
+ case kOutlet:
+ case kVCR:
+ case kStereo:
+ case kMicrowave:
+ case kBalloon:
+ case kCopterLf:
+ case kCopterRt:
+ case kDartLf:
+ case kDartRt:
+ case kBall:
+ case kDrip:
+ case kFish:
+ capType = CapType_DynamicObj;
+ break;
+ case kSoundTrigger:
+ capType = CapType_SoundTrigger;
+ break;
+ case kUpStairs:
+ capType = CapType_UpStairs;
+ break;
+ case kDownStairs:
+ capType = CapType_DownStairs;
+ break;
+ case kGreaseLf:
+ case kGreaseRt:
+ capType = CapType_Grease;
+ break;
+ default:
+ break;
+ };
+
+ if (capType != CapType_Count)
+ {
+ if (counts[capType] == caps[capType])
+ {
+ obj->what = kObjectIsEmpty;
+ anyRepairs = RCheck(true);
+ }
+ else
+ counts[capType]++;
+ }
+ }
+
+ // Check all objects
+ for (size_t i = 0; i < kMaxRoomObs; i++)
+ {
+ if (!LegalizeObject(house, roomNum, i, anyRepairs))
+ return LCheck(false);
+ }
+
+ int16_t numObjects = kMaxRoomObs;
+ for (size_t i = 0; i < kMaxRoomObs; i++)
+ {
+ objectType *obj = room->objects + i;
+
+ if (obj->what == kObjectIsEmpty)
+ numObjects--;
+ }
+
+ if (numObjects != room->numObjects)
+ {
+ anyRepairs = RCheck(true);
+ room->numObjects = numObjects;
+ }
+
+ return true;
+}
+
+static bool LegalizeHouse(houseType *house, bool &anyRepairs)
+{
+ size_t nRooms = house->nRooms;
+
+ if (!LegalizeScores(&house->highScores, anyRepairs))
+ return false;
+
+ PL_NotYetImplemented_TODO("Validate initial pos");
+
+ // Repair room layout
+ for (size_t i = 0; i < nRooms; i++)
+ {
+ if (!LegalizeRoomLayout(house, i, anyRepairs))
+ return LCheck(false);
+ }
+
+ // Repair firstRoom
+ if (house->firstRoom < 0 || house->firstRoom >= house->nRooms || house->rooms[house->firstRoom].suite == kRoomIsEmpty)
+ {
+ if (nRooms != 0)
+ {
+ bool repairedOK = false;
+ for (size_t i = 0; i < nRooms; i++)
+ {
+ if (house->rooms[i].suite == kRoomIsEmpty)
+ continue;
+
+ house->firstRoom = static_cast(i);
+ repairedOK = true;
+ anyRepairs = RCheck(true);
+ }
+
+ if (!repairedOK)
+ return LCheck(false);
+ }
+ }
+
+ for (size_t i = 0; i < nRooms; i++)
+ {
+ if (!LegalizeRoom(house, i, anyRepairs))
+ return LCheck(false);
+ }
+
+ return true;
+}
+
+Boolean ReadHouse (GpIOStream *houseStream, bool untrusted)
{
long byteCount;
- PLError_t theErr;
+ PLError_t theErr;
short whichRoom;
// There should be no padding remaining the house type
@@ -567,6 +1960,21 @@ Boolean ReadHouse (GpIOStream *houseStream)
if (thisHouse != nil)
thisHouse.Dispose();
+ if (byteCount < houseType::kBinaryDataSize)
+ {
+ YellowAlert(kYellowHouseDamaged, 1);
+ return (false);
+ }
+
+ const size_t roomDataSize = static_cast(byteCount) - houseType::kBinaryDataSize;
+ if (roomDataSize % sizeof(roomType) != 0)
+ {
+ YellowAlert(kYellowHouseDamaged, 2);
+ return (false);
+ }
+
+ const size_t roomCountFromDataSize = roomDataSize / sizeof(roomType);
+
// GP: Correct for padding
const size_t alignmentPadding = sizeof(houseType) - sizeof(roomType) - houseType::kBinaryDataSize;
@@ -602,6 +2010,25 @@ Boolean ReadHouse (GpIOStream *houseStream)
ByteSwapHouse(*thisHouse, static_cast(byteCount), false);
numberRooms = (*thisHouse)->nRooms;
+ if (numberRooms < 0 || static_cast(numberRooms) > roomCountFromDataSize)
+ {
+ YellowAlert(kYellowHouseDamaged, 3);
+ return (false);
+ }
+
+ bool anyRepairs = false;
+ if (untrusted)
+ {
+ if (!LegalizeHouse(*thisHouse, anyRepairs))
+ {
+ YellowAlert(kYellowHouseDamaged, 4);
+ return (false);
+ }
+
+ if (anyRepairs)
+ YellowAlert(kYellowHouseRepaired, 0);
+ }
+
#ifdef COMPILEDEMO
if (numberRooms != 45)
return (false);
@@ -651,7 +2078,7 @@ Boolean ReadHouse (GpIOStream *houseStream)
{
}
}
-
+
objActive = kNoObjectSelected;
ReflectCurrentRoom(true);
fileDirty = false;
@@ -685,7 +2112,7 @@ Boolean WriteHouse (Boolean checkIt)
}
GpIOStream *houseStream = nil;
- theErr = houseCFile->OpenData(PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOpen, houseStream);
+ theErr = houseCFile->OpenData(PortabilityLayer::EFilePermission_Write, GpFileCreationDispositions::kCreateOrOverwrite, houseStream);
if (theErr != PLErrors::kNone)
return (false);
diff --git a/GpApp/HouseLegal.cpp b/GpApp/HouseLegal.cpp
index 94e328c..2c18927 100644
--- a/GpApp/HouseLegal.cpp
+++ b/GpApp/HouseLegal.cpp
@@ -9,6 +9,7 @@
#include "PLNumberFormatting.h"
#include "PLStringCompare.h"
#include "PLStandardColors.h"
+#include "PLSysCalls.h"
#include "Externs.h"
#include "ObjectEdit.h"
#include "PLStandardColors.h"
@@ -128,27 +129,17 @@ Boolean KeepObjectLegal (void)
theObject->data.a.topLeft.v = kSewerGrateTop;
theObject->data.a.distance += 2;
}
- if ((theObject->what == kFloorTrans) &&
- (theObject->data.a.topLeft.v != kFloorTransTop))
- {
- theObject->data.a.topLeft.v = kFloorTransTop;
- theObject->data.a.distance += 2;
- }
if (ObjectHasHandle(&direction, &dist))
{
switch (direction)
{
case kAbove:
dist = bounds.top - dist;
- if ((theObject->what == kFloorVent) ||
- (theObject->what == kFloorBlower) ||
- (theObject->what == kTaper) ||
- (theObject->what == kCandle) ||
- (theObject->what == kStubby))
+ if (BlowerTypeHasUpperLimit(theObject->what))
{
- if (dist < 36)
+ if (dist < kUpwardVentMinY)
{
- theObject->data.a.distance += dist - 36;
+ theObject->data.a.distance += dist - kUpwardVentMinY;
unchanged = false;
}
}
@@ -874,6 +865,7 @@ void KeepAllObjectsLegal (void)
GetLocalizedString(19, message);
SetMessageWindowMessage(message, StdColors::Red());
houseErrors++;
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
@@ -908,6 +900,7 @@ void CheckForStaircasePairs (void)
{
GetLocalizedString(20, message);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
else
@@ -923,6 +916,7 @@ void CheckForStaircasePairs (void)
{
GetLocalizedString(21, message);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
@@ -935,6 +929,7 @@ void CheckForStaircasePairs (void)
{
GetLocalizedString(22, message);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
else
@@ -950,6 +945,7 @@ void CheckForStaircasePairs (void)
{
GetLocalizedString(23, message);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
@@ -992,6 +988,7 @@ void CheckHouseForProblems (void)
{
GetLocalizedString(27, message);
SetMessageWindowMessage(message, StdColors::Black());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
houseErrors = 0;
}
@@ -1008,6 +1005,7 @@ void CheckHouseForProblems (void)
GetLocalizedString(28, message2);
PasStringConcat(message, message2);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(45);
}
}
@@ -1027,6 +1025,7 @@ void CheckHouseForProblems (void)
GetLocalizedString(29, message2);
PasStringConcat(message, message2);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
@@ -1042,6 +1041,7 @@ void CheckHouseForProblems (void)
GetLocalizedString(30, message2);
PasStringConcat(message, message2);
SetMessageWindowMessage(message, StdColors::Blue());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(45);
}
}
@@ -1057,6 +1057,7 @@ void CheckHouseForProblems (void)
GetLocalizedString(31, message2);
PasStringConcat(message, message2);
SetMessageWindowMessage(message, StdColors::Blue());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(45);
}
}
@@ -1072,6 +1073,7 @@ void CheckHouseForProblems (void)
GetLocalizedString(32, message2);
PasStringConcat(message, message2);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
@@ -1089,6 +1091,7 @@ void CheckHouseForProblems (void)
GetLocalizedString(34, message2);
PasStringConcat(message, message2);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
@@ -1107,6 +1110,7 @@ void CheckHouseForProblems (void)
{
GetLocalizedString(35, message);
SetMessageWindowMessage(message, StdColors::Red());
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
DelayTicks(60);
}
}
diff --git a/GpApp/Link.cpp b/GpApp/Link.cpp
index b7a48c7..cccf8a8 100644
--- a/GpApp/Link.cpp
+++ b/GpApp/Link.cpp
@@ -42,9 +42,9 @@ short MergeFloorSuite (short floor, short suite)
//-------------------------------------------------------------- ExtractFloorSuite
-void ExtractFloorSuite (short combo, short *floor, short *suite)
+void ExtractFloorSuite (const houseType *house, SInt16 combo, SInt16 *floor, SInt16 *suite)
{
- if ((*thisHouse)->version < 0x0200) // old floor/suite combo
+ if (house->version < 0x0200) // old floor/suite combo
{
*floor = (combo / 100) - kNumUndergroundFloors;
*suite = combo % 100;
diff --git a/GpApp/MainWindow.cpp b/GpApp/MainWindow.cpp
index bd274de..8c01cf8 100644
--- a/GpApp/MainWindow.cpp
+++ b/GpApp/MainWindow.cpp
@@ -72,7 +72,7 @@ void DrawOnSplash(DrawSurface *surface)
if ((thisMac.hasQT) && (hasMovie))
PasStringConcat(houseLoadedStr, PSTR(" (TV)"));
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
const Point textPoint = Point::Create(splashOriginH + 436, splashOriginV + 314);
if (thisMac.isDepth == 4)
diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp
index 44d0fc7..0122e83 100644
--- a/GpApp/Map.cpp
+++ b/GpApp/Map.cpp
@@ -28,7 +28,6 @@
#define kMapScrollBarWidth 16
#define kHScrollRef 5L
#define kVScrollRef 27L
-#define kMapGroundValue 56
#define kNewRoomAlert 1004
#define kYesDoNewRoom 1
#define kThumbnailPictID 1010
diff --git a/GpApp/Marquee.cpp b/GpApp/Marquee.cpp
index cd74b41..6405c64 100644
--- a/GpApp/Marquee.cpp
+++ b/GpApp/Marquee.cpp
@@ -208,7 +208,7 @@ void DragOutMarqueeRect (Window *window, Point start, Rect *theRect)
surface->InvertFrameRect(*theRect, pattern);
wasPt = start;
- while (WaitMouseUp())
+ while (WaitMouseUp_DisarmAsyncify())
{
GetMouse(window, &newPt);
if (wasPt != newPt)
@@ -238,7 +238,7 @@ void DragMarqueeRect (Window *window, DrawSurface *surface, Point start, Rect *t
surface->InvertFrameRect(theMarquee.bounds, pattern);
wasPt = start;
- while (WaitMouseUp())
+ while (WaitMouseUp_DisarmAsyncify())
{
GetMouse(window, &newPt);
if (wasPt != newPt)
@@ -283,7 +283,7 @@ void DragMarqueeHandle (Window *window, DrawSurface *surface, Point start, short
surface->InvertFillRect(theMarquee.handle, pattern);
wasPt = start;
- while (WaitMouseUp())
+ while (WaitMouseUp_DisarmAsyncify())
{
GetMouse(window, &newPt);
if (wasPt != newPt)
@@ -365,7 +365,7 @@ void DragMarqueeCorner (Window *window, DrawSurface *surface, Point start, short
surface->InvertFillRect(theMarquee.handle, pattern);
wasPt = start;
- while (WaitMouseUp())
+ while (WaitMouseUp_DisarmAsyncify())
{
GetMouse(window, &newPt);
if (wasPt != newPt)
diff --git a/GpApp/Music.cpp b/GpApp/Music.cpp
index bb29136..a6ae546 100644
--- a/GpApp/Music.cpp
+++ b/GpApp/Music.cpp
@@ -8,6 +8,7 @@
#include "Environ.h"
#include "Externs.h"
#include "SoundSync.h"
+#include "IGpAudioBuffer.h"
#include "IGpMutex.h"
#include "IGpSystemServices.h"
#include "MemoryManager.h"
@@ -29,11 +30,11 @@ PLError_t DumpMusicSounds (void);
PLError_t OpenMusicChannel (void);
PLError_t CloseMusicChannel (void);
-THandle ParseAndConvertSound(const THandle &handle);
+IGpAudioBuffer *ParseAndConvertSound(const THandle &handle);
PortabilityLayer::AudioChannel *musicChannel;
-Ptr theMusicData[kMaxMusic];
+IGpAudioBuffer *theMusicData[kMaxMusic];
short musicScore[kLastMusicPiece];
short gameScore[kLastGamePiece];
Boolean isMusicOn, isPlayMusicIdle, isPlayMusicGame;
@@ -208,22 +209,23 @@ PLError_t LoadMusicSounds (void)
theErr = PLErrors::kNone;
for (i = 0; i < kMaxMusic; i++)
- theMusicData[i] = nil;
+ {
+ assert(theMusicData[i] == nil);
+ }
for (i = 0; i < kMaxMusic; i++)
{
- theSound = ParseAndConvertSound(PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('snd ', i + kBaseBufferMusicID));
+ theSound = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('snd ', i + kBaseBufferMusicID);
if (theSound == nil)
return PLErrors::kOutOfMemory;
- soundDataSize = GetHandleSize(theSound);
+ IGpAudioBuffer *buffer = ParseAndConvertSound(theSound);
+ theSound.Dispose();
- theMusicData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
- if (theMusicData[i] == nil)
+ if (buffer == nil)
return PLErrors::kOutOfMemory;
- memcpy(theMusicData[i], static_cast(*theSound), soundDataSize);
- theSound.Dispose();
+ theMusicData[i] = buffer;
}
return (theErr);
}
@@ -240,7 +242,7 @@ PLError_t DumpMusicSounds (void)
for (i = 0; i < kMaxMusic; i++)
{
if (theMusicData[i] != nil)
- PortabilityLayer::MemoryManager::GetInstance()->Release(theMusicData[i]);
+ theMusicData[i]->Release();
theMusicData[i] = nil;
}
diff --git a/GpApp/ObjectAdd.cpp b/GpApp/ObjectAdd.cpp
index be32d60..e7da40f 100644
--- a/GpApp/ObjectAdd.cpp
+++ b/GpApp/ObjectAdd.cpp
@@ -16,13 +16,6 @@
#define kNoMoreObjectsAlert 1008
#define kNoMoreSpecialAlert 1028
-#define kMaxSoundTriggers 1
-#define kMaxStairs 1
-#define kMouseholeBottom 295
-#define kFireplaceBottom 297
-#define kManholeSits 322
-#define kGrecoVentTop 303
-#define kSewerBlowerTop 292
short FindEmptyObjectSlot (void);
diff --git a/GpApp/ObjectDraw2.cpp b/GpApp/ObjectDraw2.cpp
index 45749b0..402ec14 100644
--- a/GpApp/ObjectDraw2.cpp
+++ b/GpApp/ObjectDraw2.cpp
@@ -1057,7 +1057,7 @@ void DrawCalendar (Rect *theRect)
backSrcMap->DrawPicture(thePicture, bounds);
thePicture.Dispose();
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
GetTime(&timeRec);
GetIndString(monthStr, kMonthStringID, timeRec.month);
diff --git a/GpApp/ObjectDrawAll.cpp b/GpApp/ObjectDrawAll.cpp
index 924950d..9285bbc 100644
--- a/GpApp/ObjectDrawAll.cpp
+++ b/GpApp/ObjectDrawAll.cpp
@@ -534,7 +534,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
OffsetRectRoomRelative(&itsRect, neighbor);
if (SectRect(&itsRect, &testRect, &whoCares))
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
room = GetRoomNumber(floor, suite);
obj = (short)thisObject.data.e.who;
DrawLightSwitch(&itsRect, GetObjectState(room, obj));
@@ -547,7 +547,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
OffsetRectRoomRelative(&itsRect, neighbor);
if (SectRect(&itsRect, &testRect, &whoCares))
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
room = GetRoomNumber(floor, suite);
obj = (short)thisObject.data.e.who;
DrawMachineSwitch(&itsRect, GetObjectState(room, obj));
@@ -560,7 +560,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
OffsetRectRoomRelative(&itsRect, neighbor);
if (SectRect(&itsRect, &testRect, &whoCares))
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
room = GetRoomNumber(floor, suite);
obj = (short)thisObject.data.e.who;
DrawThermostat(&itsRect, GetObjectState(room, obj));
@@ -573,7 +573,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
OffsetRectRoomRelative(&itsRect, neighbor);
if (SectRect(&itsRect, &testRect, &whoCares))
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
room = GetRoomNumber(floor, suite);
obj = (short)thisObject.data.e.who;
DrawPowerSwitch(&itsRect, GetObjectState(room, obj));
@@ -586,7 +586,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
OffsetRectRoomRelative(&itsRect, neighbor);
if (SectRect(&itsRect, &testRect, &whoCares))
{
- ExtractFloorSuite(thisObject.data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisObject.data.e.where, &floor, &suite);
room = GetRoomNumber(floor, suite);
obj = (short)thisObject.data.e.who;
DrawKnifeSwitch(&itsRect, GetObjectState(room, obj));
diff --git a/GpApp/ObjectEdit.cpp b/GpApp/ObjectEdit.cpp
index 28225b7..065e1df 100644
--- a/GpApp/ObjectEdit.cpp
+++ b/GpApp/ObjectEdit.cpp
@@ -1680,6 +1680,24 @@ void DeselectObject (void)
#endif
}
+
+//-------------------------------------------------------------- ObjectHasHandle
+
+Boolean BlowerTypeHasUpperLimit (SInt16 what)
+{
+ switch (what)
+ {
+ case kFloorVent:
+ case kFloorBlower:
+ case kTaper:
+ case kCandle:
+ case kStubby:
+ return true;
+ default:
+ return false;
+ }
+}
+
//-------------------------------------------------------------- ObjectHasHandle
#ifndef COMPILEDEMO
diff --git a/GpApp/ObjectInfo.cpp b/GpApp/ObjectInfo.cpp
index bedff3c..1cb7d63 100644
--- a/GpApp/ObjectInfo.cpp
+++ b/GpApp/ObjectInfo.cpp
@@ -1075,7 +1075,7 @@ void DoSwitchObjectInfo (void)
PasStringCopy(PSTR("none"), roomStr);
else
{
- ExtractFloorSuite(thisRoom->objects[objActive].data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisRoom->objects[objActive].data.e.where, &floor, &suite);
NumToString((long)floor, roomStr);
PasStringConcat(roomStr, PSTR(" / "));
NumToString((long)suite, tempStr);
@@ -1196,7 +1196,7 @@ void DoTriggerObjectInfo (void)
PasStringCopy(PSTR("none"), roomStr);
else
{
- ExtractFloorSuite(thisRoom->objects[objActive].data.e.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisRoom->objects[objActive].data.e.where, &floor, &suite);
NumToString((long)floor, roomStr);
PasStringConcat(roomStr, PSTR(" / "));
NumToString((long)suite, tempStr);
@@ -1869,7 +1869,7 @@ void DoTransObjectInfo (short what)
PasStringCopy(PSTR("none"), roomStr);
else
{
- ExtractFloorSuite(thisRoom->objects[objActive].data.d.where, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, thisRoom->objects[objActive].data.d.where, &floor, &suite);
NumToString((long)floor, roomStr);
PasStringConcat(roomStr, PSTR(" / "));
NumToString((long)suite, tempStr);
diff --git a/GpApp/ObjectRects.cpp b/GpApp/ObjectRects.cpp
index 8e45ce3..19d9e71 100644
--- a/GpApp/ObjectRects.cpp
+++ b/GpApp/ObjectRects.cpp
@@ -36,6 +36,7 @@ void GetObjectRect (objectPtr who, Rect *itsRect)
switch (who->what)
{
+ default:
case kObjectIsEmpty:
QSetRect(itsRect, 0, 0, 0, 0);
break;
diff --git a/GpApp/Objects.cpp b/GpApp/Objects.cpp
index 3f249ee..d3f61aa 100644
--- a/GpApp/Objects.cpp
+++ b/GpApp/Objects.cpp
@@ -136,7 +136,7 @@ short GetRoomLinked (objectType *who)
compoundRoomNumber = who->data.d.where;
if (compoundRoomNumber != -1) // is object linked
{
- ExtractFloorSuite(compoundRoomNumber, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, compoundRoomNumber, &floor, &suite);
whereLinked = GetRoomNumber(floor, suite);
}
else
@@ -154,7 +154,7 @@ short GetRoomLinked (objectType *who)
compoundRoomNumber = who->data.e.where;
if (compoundRoomNumber != -1) // is object linked
{
- ExtractFloorSuite(compoundRoomNumber, &floor, &suite);
+ ExtractFloorSuite(*thisHouse, compoundRoomNumber, &floor, &suite);
whereLinked = GetRoomNumber(floor, suite);
}
else
@@ -352,7 +352,7 @@ void AddTempManholeRect (Rect *manHole)
//-------------------------------------------------------------- SetObjectState
-Boolean SetObjectState (short room, short object, short action, short local)
+Boolean SetObjectState (SInt16 room, SInt16 object, SInt16 action, SInt16 local)
{
char wasState;
Boolean changed = false;
diff --git a/GpApp/RectUtils.cpp b/GpApp/RectUtils.cpp
index bc3f0ea..a7079a6 100644
--- a/GpApp/RectUtils.cpp
+++ b/GpApp/RectUtils.cpp
@@ -31,15 +31,17 @@ void FrameWHRect (DrawSurface *surface, short left, short top, short wide, short
// This function ensures that a rect's top is less than it's bottomÉ
// and that left is less than right.
-void NormalizeRect (Rect *theRect)
+Boolean NormalizeRect (Rect *theRect)
{
short tempSide;
+ Boolean changed = false;
if (theRect->left > theRect->right)
{
tempSide = theRect->left;
theRect->left = theRect->right;
theRect->right = tempSide;
+ changed = true;
}
if (theRect->top > theRect->bottom)
@@ -47,7 +49,10 @@ void NormalizeRect (Rect *theRect)
tempSide = theRect->top;
theRect->top = theRect->bottom;
theRect->bottom = tempSide;
+ changed = true;
}
+
+ return changed;
}
//-------------------------------------------------------------- ZeroRectCorner
@@ -198,7 +203,8 @@ Boolean ForceRectInRect (Rect *small, Rect *large)
changed = false;
- NormalizeRect(small);
+ if (NormalizeRect(small))
+ changed = true;
if ((small->bottom - small->top) > (large->bottom - large->top))
{
diff --git a/GpApp/RectUtils.h b/GpApp/RectUtils.h
index 5affd19..8c3c9eb 100644
--- a/GpApp/RectUtils.h
+++ b/GpApp/RectUtils.h
@@ -17,7 +17,7 @@ namespace PortabilityLayer
void FrameWHRect (short, short, short, short, PortabilityLayer::ResolveCachingColor &color);
-void NormalizeRect (Rect *);
+Boolean NormalizeRect (Rect *);
void ZeroRectCorner (Rect *);
void CenterRectOnPoint (Rect *, Point);
short HalfRectWide (Rect *);
diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp
index 122ecec..d66dca3 100644
--- a/GpApp/RoomInfo.cpp
+++ b/GpApp/RoomInfo.cpp
@@ -153,9 +153,9 @@ void DragMiniTile (Window *window, DrawSurface *surface, Point mouseIs, short *n
surface->InvertFrameRect(dragRect, pattern);
mouseWas = mouseIs;
- while (WaitMouseUp()) // loop until mouse button let up
+ while (WaitMouseUp_DisarmAsyncify()) // loop until mouse button let up
{
- GetMouse(window, &mouseIs); // get mouse coords
+ GetMouse(window, &mouseIs); // get mouse coords
if (mouseWas != mouseIs) // the mouse has moved
{
surface->InvertFrameRect(dragRect, pattern);
diff --git a/GpApp/Scoreboard.cpp b/GpApp/Scoreboard.cpp
index 16351b4..7d70f12 100644
--- a/GpApp/Scoreboard.cpp
+++ b/GpApp/Scoreboard.cpp
@@ -176,7 +176,7 @@ void RefreshRoomTitle (short mode)
const Point strShadowPoint = Point::Create(1, 10);
const Point strPoint = Point::Create(0, 9);
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
switch (mode)
{
@@ -221,7 +221,7 @@ void RefreshNumGliders (void)
long displayMortals;
DrawSurface *surface = boardGSrcMap;
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
PortabilityLayer::ResolveCachingColor theRGBColor = PortabilityLayer::ResolveCachingColor::FromStandardColor(kGrayBackgroundColor);
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
@@ -256,7 +256,7 @@ void RefreshPoints (void)
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
surface->FillRect(boardPSrcRect, theRGBColor);
@@ -286,7 +286,7 @@ void QuickGlidersRefresh (void)
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
surface->FillRect(boardGSrcRect, theRGBColor);
@@ -316,7 +316,7 @@ void QuickScoreRefresh (void)
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
surface->FillRect(boardPSrcRect, theRGBColor);
diff --git a/GpApp/Sound.cpp b/GpApp/Sound.cpp
index c69b0dc..8475d31 100644
--- a/GpApp/Sound.cpp
+++ b/GpApp/Sound.cpp
@@ -10,6 +10,8 @@
#include "PLSound.h"
#include "DialogManager.h"
#include "Externs.h"
+#include "IGpAudioBuffer.h"
+#include "IGpAudioDriver.h"
#include "IGpLogDriver.h"
#include "MemoryManager.h"
#include "ResourceManager.h"
@@ -31,10 +33,10 @@ PLError_t LoadBufferSounds (void);
void DumpBufferSounds (void);
PLError_t OpenSoundChannels (void);
void CloseSoundChannels (void);
-THandle ParseAndConvertSound(const THandle &handle);
+IGpAudioBuffer *ParseAndConvertSound(const THandle &handle);
PortabilityLayer::AudioChannel *channel0, *channel1, *channel2;
-Ptr theSoundData[kMaxSounds];
+IGpAudioBuffer *theSoundData[kMaxSounds];
short numSoundsLoaded;
Boolean soundLoaded[kMaxSounds], dontLoadSounds;
Boolean channelOpen, isSoundOn, failedSound;
@@ -192,24 +194,20 @@ PLError_t LoadTriggerSound (short soundID)
theErr = PLErrors::kNone;
- theSound = ParseAndConvertSound(LoadHouseResource('snd ', soundID));
+ theSound = LoadHouseResource('snd ', soundID);
if (theSound == nil)
- {
- theErr = PLErrors::kFileNotFound;
- }
+ theErr = PLErrors::kResourceError;
else
{
- soundDataSize = GetHandleSize(theSound);
- theSoundData[kMaxSounds - 1] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
- if (theSoundData[kMaxSounds - 1] == nil)
- {
- theSound.Dispose();
- theErr = PLErrors::kOutOfMemory;
- }
+ IGpAudioBuffer *buffer = ParseAndConvertSound(theSound);
+ theSound.Dispose();
+
+ if (buffer == nil)
+ theErr = PLErrors::kResourceError;
else
{
- memcpy(theSoundData[kMaxSounds - 1], (Byte*)(*theSound), soundDataSize);
- theSound.Dispose();
+ assert(theSoundData[kMaxSounds - 1] == nil);
+ theSoundData[kMaxSounds - 1] = buffer;
}
}
}
@@ -222,7 +220,7 @@ PLError_t LoadTriggerSound (short soundID)
void DumpTriggerSound (void)
{
if (theSoundData[kMaxSounds - 1] != nil)
- PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[kMaxSounds - 1]);
+ theSoundData[kMaxSounds - 1]->Release();
theSoundData[kMaxSounds - 1] = nil;
}
@@ -239,21 +237,21 @@ PLError_t LoadBufferSounds (void)
for (i = 0; i < kMaxSounds - 1; i++)
{
- theSound = ParseAndConvertSound(PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('snd ', i + kBaseBufferSoundID));
+ theSound = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('snd ', i + kBaseBufferSoundID);
if (theSound == nil)
- return (PLErrors::kOutOfMemory);
-
- soundDataSize = GetHandleSize(theSound);
-
- theSoundData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
- if (theSoundData[i] == nil)
- return (PLErrors::kOutOfMemory);
-
- memcpy(theSoundData[i], *theSound, soundDataSize);
+ return (PLErrors::kResourceError);
+
+ IGpAudioBuffer *buffer = ParseAndConvertSound(theSound);
theSound.Dispose();
+
+ if (!buffer)
+ return PLErrors::kResourceError;
+
+ assert(theSoundData[i] == nil);
+ theSoundData[i] = buffer;
}
-
- theSoundData[kMaxSounds - 1] = nil;
+
+ assert(theSoundData[kMaxSounds - 1] == nil);
return (theErr);
}
@@ -267,7 +265,7 @@ void DumpBufferSounds (void)
for (i = 0; i < kMaxSounds; i++)
{
if (theSoundData[i] != nil)
- PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[i]);
+ theSoundData[i]->Release();
theSoundData[i] = nil;
}
}
@@ -406,23 +404,23 @@ void TellHerNoSounds (void)
//-------------------------------------------------------------- ParseAndConvertSound
-THandle ParseAndConvertSoundChecked(const THandle &handle)
+IGpAudioBuffer *ParseAndConvertSoundChecked(const THandle &handle)
{
const uint8_t *dataStart = static_cast(*handle);
const size_t size = handle.MMBlock()->m_size;
if (size < sizeof(PortabilityLayer::RIFFTag))
- return THandle();
+ return nullptr;
PortabilityLayer::RIFFTag mainRiffTag;
memcpy(&mainRiffTag, dataStart, sizeof(PortabilityLayer::RIFFTag));
if (mainRiffTag.m_tag != PortabilityLayer::WaveConstants::kRiffChunkID)
- return THandle();
+ return nullptr;
const uint32_t riffSize = mainRiffTag.m_chunkSize;
if (riffSize < 4 || riffSize - 4 > size - sizeof(PortabilityLayer::RIFFTag))
- return THandle();
+ return nullptr;
const uint8_t *riffStart = dataStart + sizeof(PortabilityLayer::RIFFTag);
const uint8_t *riffEnd = riffStart + riffSize;
@@ -434,7 +432,7 @@ THandle ParseAndConvertSoundChecked(const THandle &handle)
memcpy(&waveMarker, riffStart, 4);
if (waveMarker != PortabilityLayer::WaveConstants::kWaveChunkID)
- return THandle();
+ return nullptr;
const uint8_t *tagSearchLoc = riffStart + 4;
@@ -442,7 +440,7 @@ THandle ParseAndConvertSoundChecked(const THandle &handle)
while (tagSearchLoc != riffEnd)
{
if (riffEnd - tagSearchLoc < sizeof(PortabilityLayer::RIFFTag))
- return THandle();
+ return nullptr;
PortabilityLayer::RIFFTag riffTag;
memcpy(&riffTag, tagSearchLoc, sizeof(PortabilityLayer::RIFFTag));
@@ -455,20 +453,20 @@ THandle ParseAndConvertSoundChecked(const THandle &handle)
const uint32_t riffTagSizeUnpadded = riffTag.m_chunkSize;
if (riffTagSizeUnpadded == 0xffffffffU)
- return THandle();
+ return nullptr;
const uint32_t riffTagSizePadded = riffTagSizeUnpadded + (riffTagSizeUnpadded & 1);
tagSearchLoc += sizeof(PortabilityLayer::RIFFTag);
if (riffEnd - tagSearchLoc < riffTagSizePadded)
- return THandle();
+ return nullptr;
tagSearchLoc += riffTagSizePadded;
}
if (formatTagLoc == nullptr || dataTagLoc == nullptr)
- return THandle();
+ return nullptr;
PortabilityLayer::RIFFTag fmtTag;
memcpy(&fmtTag, formatTagLoc, sizeof(PortabilityLayer::RIFFTag));
@@ -502,7 +500,7 @@ THandle ParseAndConvertSoundChecked(const THandle &handle)
copyableSize = sizeof(PortabilityLayer::WaveFormatChunkV1);
}
else
- return THandle();
+ return nullptr;
memcpy(&formatChunkV3, formatContents, copyableSize);
@@ -510,35 +508,30 @@ THandle ParseAndConvertSoundChecked(const THandle &handle)
const PortabilityLayer::WaveFormatChunkV1 formatChunkV1 = formatChunkV2.m_v1;
if (formatChunkV1.m_bitsPerSample != 8)
- return THandle();
+ return nullptr;
if (formatChunkV1.m_formatCode != PortabilityLayer::WaveConstants::kFormatPCM ||
formatChunkV1.m_numChannels != 1 ||
formatChunkV1.m_blockAlignmentBytes != 1 ||
formatChunkV1.m_bitsPerSample != 8)
- return THandle();
-
- THandle convertedHandle = THandle(PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(4 + dataTag.m_chunkSize));
- if (!convertedHandle)
- return THandle();
-
- uint8_t *handleData = static_cast(*convertedHandle);
+ return nullptr;
uint32_t dataSize = dataTag.m_chunkSize;
- memcpy(handleData, &dataSize, 4);
+ if (dataSize > 0x1000000 || dataSize < 1)
+ return nullptr;
- memcpy(handleData + 4, dataContents, dataSize);
+ IGpAudioDriver *audioDriver = PLDrivers::GetAudioDriver();
+ if (!audioDriver)
+ return nullptr;
- return convertedHandle;
+ return audioDriver->CreateBuffer(dataContents, dataSize);
}
-THandle ParseAndConvertSound(const THandle &handle)
+IGpAudioBuffer *ParseAndConvertSound(const THandle &handle)
{
if (!handle)
- return THandle();
+ return nullptr;
- THandle converted = ParseAndConvertSoundChecked(handle);
- handle.Dispose();
-
- return converted;
+ IGpAudioBuffer *buffer = ParseAndConvertSoundChecked(handle);
+ return buffer;
}
diff --git a/GpApp/Tools.cpp b/GpApp/Tools.cpp
index abe82f8..234292c 100644
--- a/GpApp/Tools.cpp
+++ b/GpApp/Tools.cpp
@@ -156,7 +156,7 @@ void DrawToolName (DrawSurface *surface)
const Point textPoint = Point::Create(toolTextRect.left + 3, toolTextRect.bottom - 6);
- PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
+ PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
ColorText(surface, textPoint, theString, 171L, appFont);
}
#endif
diff --git a/GpAudioDriver_XAudio2/GpAudioBufferXAudio2.cpp b/GpAudioDriver_XAudio2/GpAudioBufferXAudio2.cpp
new file mode 100644
index 0000000..6f4e76d
--- /dev/null
+++ b/GpAudioDriver_XAudio2/GpAudioBufferXAudio2.cpp
@@ -0,0 +1,69 @@
+#include "GpAudioBufferXAudio2.h"
+#include "CoreDefs.h"
+#include "GpWindows.h"
+#include "IGpAllocator.h"
+
+#include
+#include
+
+GpAudioBufferXAudio2 *GpAudioBufferXAudio2::Create(IGpAllocator *alloc, const void *buffer, size_t size)
+{
+ size_t baseSize = sizeof(GpAudioBufferXAudio2);
+ baseSize = baseSize + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
+ baseSize -= baseSize % GP_SYSTEM_MEMORY_ALIGNMENT;
+
+ size_t totalSize = baseSize + size;
+
+ void *storage = alloc->Realloc(nullptr, totalSize);
+ if (!storage)
+ return nullptr;
+
+ void *dataPos = static_cast(storage) + baseSize;
+
+ memcpy(dataPos, buffer, size);
+ return new (storage) GpAudioBufferXAudio2(alloc, dataPos, size);
+}
+
+void GpAudioBufferXAudio2::AddRef()
+{
+ InterlockedIncrement(&m_count);
+}
+
+void GpAudioBufferXAudio2::Release()
+{
+ if (InterlockedDecrement(&m_count) == 0)
+ this->Destroy();
+}
+
+const XAUDIO2_BUFFER *GpAudioBufferXAudio2::GetXA2Buffer() const
+{
+ return &m_xa2Buffer;
+}
+
+GpAudioBufferXAudio2::GpAudioBufferXAudio2(IGpAllocator *alloc, const void *data, size_t size)
+ : m_alloc(alloc)
+ , m_data(data)
+ , m_size(size)
+ , m_count(1)
+{
+ m_xa2Buffer.Flags = 0;
+ m_xa2Buffer.AudioBytes = static_cast(size);
+ m_xa2Buffer.pAudioData = static_cast(data);
+ m_xa2Buffer.PlayBegin = 0;
+ m_xa2Buffer.PlayLength = 0;
+ m_xa2Buffer.LoopBegin = 0;
+ m_xa2Buffer.LoopLength = 0;
+ m_xa2Buffer.LoopCount = 0;
+ m_xa2Buffer.pContext = this;
+}
+
+GpAudioBufferXAudio2::~GpAudioBufferXAudio2()
+{
+}
+
+void GpAudioBufferXAudio2::Destroy()
+{
+ IGpAllocator *alloc = m_alloc;
+ this->~GpAudioBufferXAudio2();
+ m_alloc->Realloc(this, 0);
+}
diff --git a/GpAudioDriver_XAudio2/GpAudioBufferXAudio2.h b/GpAudioDriver_XAudio2/GpAudioBufferXAudio2.h
new file mode 100644
index 0000000..ad5ac06
--- /dev/null
+++ b/GpAudioDriver_XAudio2/GpAudioBufferXAudio2.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "IGpAudioBuffer.h"
+
+#include
+
+struct IGpAllocator;
+
+class GpAudioBufferXAudio2 final : public IGpAudioBuffer
+{
+public:
+ static GpAudioBufferXAudio2 *Create(IGpAllocator *alloc, const void *buffer, size_t size);
+
+ void AddRef() override;
+ void Release() override;
+
+ const XAUDIO2_BUFFER *GetXA2Buffer() const;
+
+private:
+ GpAudioBufferXAudio2(IGpAllocator *alloc, const void *data, size_t size);
+ ~GpAudioBufferXAudio2();
+
+ void Destroy();
+
+ const void *m_data;
+ size_t m_size;
+ IGpAllocator *m_alloc;
+
+ XAUDIO2_BUFFER m_xa2Buffer;
+
+ volatile unsigned int m_count;
+};
diff --git a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp
index 54a13d0..36ccaeb 100644
--- a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp
+++ b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp
@@ -1,25 +1,27 @@
+#include "GpAudioBufferXAudio2.h"
#include "GpAudioChannelXAudio2.h"
#include "GpAudioDriverXAudio2.h"
+#include "IGpAllocator.h"
#include "IGpAudioChannelCallbacks.h"
#include "IGpLogDriver.h"
#include
#include
-GpAudioChannelXAudio2 *GpAudioChannelXAudio2::Create(GpAudioDriverXAudio2 *driver)
+GpAudioChannelXAudio2 *GpAudioChannelXAudio2::Create(IGpAllocator *alloc, GpAudioDriverXAudio2 *driver)
{
IGpLogDriver *logger = driver->GetProperties().m_logger;
- void *storage = malloc(sizeof(GpAudioChannelXAudio2));
+ void *storage = alloc->Realloc(nullptr, sizeof(GpAudioChannelXAudio2));
if (!storage)
{
if (!logger)
- logger->Printf(IGpLogDriver::Category_Error, "GpAudioChannelXAudio2::Create failed, malloc failed");
+ logger->Printf(IGpLogDriver::Category_Error, "GpAudioChannelXAudio2::Create failed, alloc failed");
return nullptr;
}
- GpAudioChannelXAudio2 *channel = new (storage) GpAudioChannelXAudio2(driver);
+ GpAudioChannelXAudio2 *channel = new (storage) GpAudioChannelXAudio2(alloc, driver);
if (!channel->Init())
{
if (!logger)
@@ -77,25 +79,25 @@ void GpAudioChannelXAudio2::SetAudioChannelContext(IGpAudioChannelCallbacks *cal
m_contextCallbacks = callbacks;
}
-void GpAudioChannelXAudio2::PostBuffer(const void *buffer, size_t bufferSize)
+bool GpAudioChannelXAudio2::PostBuffer(IGpAudioBuffer *buffer)
{
- XAUDIO2_BUFFER xa2Buffer;
- xa2Buffer.Flags = 0;
- xa2Buffer.AudioBytes = static_cast(bufferSize);
- xa2Buffer.pAudioData = static_cast(buffer);
- xa2Buffer.PlayBegin = 0;
- xa2Buffer.PlayLength = 0;
- xa2Buffer.LoopBegin = 0;
- xa2Buffer.LoopLength = 0;
- xa2Buffer.LoopCount = 0;
- xa2Buffer.pContext = nullptr;
+ GpAudioBufferXAudio2 *xa2Buffer = static_cast(buffer);
+ xa2Buffer->AddRef();
+
+ HRESULT result = m_sourceVoice->SubmitSourceBuffer(xa2Buffer->GetXA2Buffer(), nullptr);
+ if (result != S_OK)
+ {
+ xa2Buffer->Release();
+ return false;
+ }
- m_sourceVoice->SubmitSourceBuffer(&xa2Buffer, nullptr);
if (m_voiceState == VoiceState_Idle)
{
m_voiceState = VoiceState_Active;
m_sourceVoice->Start(0, 0);
}
+
+ return true;
}
void GpAudioChannelXAudio2::Stop()
@@ -109,8 +111,9 @@ void GpAudioChannelXAudio2::Stop()
void GpAudioChannelXAudio2::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpAudioChannelXAudio2();
- free(this);
+ alloc->Realloc(this, 0);
}
void GpAudioChannelXAudio2::OnBufferEnd()
@@ -119,12 +122,13 @@ void GpAudioChannelXAudio2::OnBufferEnd()
m_contextCallbacks->NotifyBufferFinished();
}
-GpAudioChannelXAudio2::GpAudioChannelXAudio2(GpAudioDriverXAudio2 *driver)
+GpAudioChannelXAudio2::GpAudioChannelXAudio2(IGpAllocator *alloc, GpAudioDriverXAudio2 *driver)
: m_driver(driver)
, m_xAudioCallbacks(this)
, m_sourceVoice(nullptr)
, m_contextCallbacks(nullptr)
, m_voiceState(VoiceState_Idle)
+ , m_alloc(alloc)
{
}
diff --git a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h
index b9317b2..1c0c9b7 100644
--- a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h
+++ b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h
@@ -7,16 +7,17 @@
class GpAudioDriverXAudio2;
class GpAudioChannelXAudio2Callbacks;
struct IXAudio2SourceVoice;
+struct IGpAllocator;
class GpAudioChannelXAudio2 final : public IGpAudioChannel
{
public:
friend class GpAudioChannelXAudio2Callbacks;
- static GpAudioChannelXAudio2 *Create(GpAudioDriverXAudio2 *driver);
+ static GpAudioChannelXAudio2 *Create(IGpAllocator *alloc, GpAudioDriverXAudio2 *driver);
void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) override;
- void PostBuffer(const void *buffer, size_t bufferSize) override;
+ bool PostBuffer(IGpAudioBuffer *buffer) override;
void Stop() override;
void Destroy() override;
@@ -32,12 +33,13 @@ private:
VoiceState_Active,
};
- explicit GpAudioChannelXAudio2(GpAudioDriverXAudio2 *driver);
+ explicit GpAudioChannelXAudio2(IGpAllocator *alloc, GpAudioDriverXAudio2 *driver);
~GpAudioChannelXAudio2();
GpAudioDriverXAudio2 *m_driver;
IXAudio2SourceVoice *m_sourceVoice;
GpAudioChannelXAudio2Callbacks m_xAudioCallbacks;
IGpAudioChannelCallbacks *m_contextCallbacks;
+ IGpAllocator *m_alloc;
VoiceState m_voiceState;
};
diff --git a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2Callbacks.cpp b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2Callbacks.cpp
index 0291043..8016f28 100644
--- a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2Callbacks.cpp
+++ b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2Callbacks.cpp
@@ -1,3 +1,4 @@
+#include "GpAudioBufferXAudio2.h"
#include "GpAudioChannelXAudio2Callbacks.h"
#include "GpAudioChannelXAudio2.h"
@@ -24,6 +25,7 @@ void GpAudioChannelXAudio2Callbacks::OnBufferStart(void* pBufferContext)
void GpAudioChannelXAudio2Callbacks::OnBufferEnd(void* pBufferContext)
{
+ static_cast(pBufferContext)->Release();
m_owner->OnBufferEnd();
}
diff --git a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp
index dfdb0ef..5fe3986 100644
--- a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp
+++ b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp
@@ -1,7 +1,9 @@
#include "GpAudioDriverXAudio2.h"
#include "IGpLogDriver.h"
+#include "GpAudioBufferXAudio2.h"
#include "GpAudioChannelXAudio2.h"
+#include "CoreDefs.h"
#include
@@ -96,9 +98,14 @@ GpAudioDriverXAudio2 *GpAudioDriverXAudio2::Create(const GpAudioDriverProperties
return new GpAudioDriverXAudio2(properties, realSampleRate, xa, mv);
}
+IGpAudioBuffer *GpAudioDriverXAudio2::CreateBuffer(const void *buffer, size_t bufferSize)
+{
+ return GpAudioBufferXAudio2::Create(m_properties.m_alloc, buffer, bufferSize);
+}
+
IGpAudioChannel *GpAudioDriverXAudio2::CreateChannel()
{
- return GpAudioChannelXAudio2::Create(this);
+ return GpAudioChannelXAudio2::Create(m_properties.m_alloc, this);
}
void GpAudioDriverXAudio2::SetMasterVolume(uint32_t vol, uint32_t maxVolume)
diff --git a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h
index 4a9c070..563034f 100644
--- a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h
+++ b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h
@@ -10,6 +10,7 @@ struct IXAudio2MasteringVoice;
class GpAudioDriverXAudio2 : public IGpAudioDriver
{
public:
+ IGpAudioBuffer *CreateBuffer(const void *buffer, size_t bufferSize) override;
IGpAudioChannel *CreateChannel() override;
void SetMasterVolume(uint32_t vol, uint32_t maxVolume) override;
void Shutdown() override;
diff --git a/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj b/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj
index 4af8dee..44a373a 100644
--- a/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj
+++ b/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj
@@ -38,11 +38,14 @@
+
+
+
@@ -69,12 +72,14 @@
+
+
diff --git a/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj.filters b/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj.filters
index 26eedc7..cc33b93 100644
--- a/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj.filters
+++ b/GpAudioDriver_XAudio2/GpAudioDriver_XAudio2.vcxproj.filters
@@ -27,6 +27,9 @@
Header Files
+
+ Header Files
+
@@ -41,6 +44,9 @@
Source Files
+
+ Source Files
+
diff --git a/GpCommon/GpAudioDriverProperties.h b/GpCommon/GpAudioDriverProperties.h
index 1372270..7643463 100644
--- a/GpCommon/GpAudioDriverProperties.h
+++ b/GpCommon/GpAudioDriverProperties.h
@@ -5,6 +5,7 @@
struct IGpSystemServices;
struct IGpAudioDriver;
struct IGpLogDriver;
+struct IGpAllocator;
struct GpAudioDriverProperties
{
@@ -15,4 +16,5 @@ struct GpAudioDriverProperties
IGpLogDriver *m_logger;
IGpSystemServices *m_systemServices;
+ IGpAllocator *m_alloc;
};
diff --git a/GpCommon/GpComPtr.h b/GpCommon/GpComPtr.h
index 6f42d3d..4ea5aac 100644
--- a/GpCommon/GpComPtr.h
+++ b/GpCommon/GpComPtr.h
@@ -1,11 +1,16 @@
#pragma once
+#include "CoreDefs.h"
+
template
class GpComPtr final
{
public:
GpComPtr();
GpComPtr(const GpComPtr &other);
+#if GP_IS_CPP11
+ GpComPtr(GpComPtr &&other);
+#endif
explicit GpComPtr(T *ptr);
~GpComPtr();
@@ -41,6 +46,23 @@ inline GpComPtr::GpComPtr(const GpComPtr &other)
m_ptr->AddRef();
}
+#if GP_IS_CPP11
+template
+inline GpComPtr::GpComPtr(GpComPtr &&other)
+ : m_ptr(other.m_ptr)
+{
+ if (m_ptr)
+ m_ptr->AddRef();
+
+ if (other.m_ptr)
+ {
+ other.m_ptr->Release();
+ other.m_ptr = nullptr;
+ }
+}
+#endif
+
+
template
inline GpComPtr::GpComPtr(T *ptr)
: m_ptr(ptr)
diff --git a/GpCommon/GpDisplayDriverProperties.h b/GpCommon/GpDisplayDriverProperties.h
index 733aa4c..1ffb639 100644
--- a/GpCommon/GpDisplayDriverProperties.h
+++ b/GpCommon/GpDisplayDriverProperties.h
@@ -10,6 +10,7 @@ struct IGpFiber;
struct IGpVOSEventQueue;
struct IGpLogDriver;
struct IGpSystemServices;
+struct IGpAllocator;
struct GpDisplayDriverProperties
{
@@ -43,4 +44,5 @@ struct GpDisplayDriverProperties
IGpVOSEventQueue *m_eventQueue;
IGpLogDriver *m_logger;
IGpSystemServices *m_systemServices;
+ IGpAllocator *m_alloc;
};
diff --git a/GpCommon/GpDriverIndex.h b/GpCommon/GpDriverIndex.h
index 6664218..9d346a2 100644
--- a/GpCommon/GpDriverIndex.h
+++ b/GpCommon/GpDriverIndex.h
@@ -16,6 +16,7 @@ namespace GpDriverIDs
kSystemServices,
kFont,
kEventQueue,
+ kAlloc,
kCount
};
@@ -54,6 +55,7 @@ GP_DEFINE_MULTI_DRIVER(kInput, IGpInputDriver);
GP_DEFINE_DRIVER(kSystemServices, IGpSystemServices);
GP_DEFINE_DRIVER(kFont, IGpFontHandler);
GP_DEFINE_DRIVER(kEventQueue, IGpVOSEventQueue);
+GP_DEFINE_DRIVER(kAlloc, IGpAllocator);
struct GpDriverCollection
{
diff --git a/GpCommon/GpFontHandlerProperties.h b/GpCommon/GpFontHandlerProperties.h
index 2ca1355..413c3d0 100644
--- a/GpCommon/GpFontHandlerProperties.h
+++ b/GpCommon/GpFontHandlerProperties.h
@@ -2,7 +2,11 @@
#include "EGpFontHandlerType.h"
+struct IGpAllocator;
+
struct GpFontHandlerProperties
{
EGpFontHandlerType m_type;
+
+ IGpAllocator *m_alloc;
};
diff --git a/GpCommon/GpIOStream.h b/GpCommon/GpIOStream.h
index 302a3a5..e246e1f 100644
--- a/GpCommon/GpIOStream.h
+++ b/GpCommon/GpIOStream.h
@@ -3,6 +3,7 @@
#include
#include "GpFilePos.h"
+#include "CoreDefs.h"
class GpIOStream
{
@@ -17,11 +18,15 @@ public:
virtual bool SeekEnd(GpUFilePos_t loc) = 0;
virtual GpUFilePos_t Size() const = 0;
virtual GpUFilePos_t Tell() const = 0;
- virtual void Close() = 0;
+ virtual void GP_ASYNCIFY_PARANOID_NAMED(Close)() = 0;
virtual void Flush() = 0;
bool ReadExact(void *bytesOut, size_t size);
bool WriteExact(const void *bytesOut, size_t size);
+
+#if GP_ASYNCIFY_PARANOID
+ void Close();
+#endif
};
inline bool GpIOStream::ReadExact(void *bytesOut, size_t size)
diff --git a/GpCommon/GpInputDriverProperties.h b/GpCommon/GpInputDriverProperties.h
index 0e13548..e8d003d 100644
--- a/GpCommon/GpInputDriverProperties.h
+++ b/GpCommon/GpInputDriverProperties.h
@@ -4,10 +4,12 @@
struct IGpAudioDriver;
struct IGpVOSEventQueue;
+struct IGpAllocator;
struct GpInputDriverProperties
{
EGpInputDriverType m_type;
IGpVOSEventQueue *m_eventQueue;
+ IGpAllocator *m_alloc;
};
diff --git a/GpCommon/GpRenderedGlyphMetrics.h b/GpCommon/GpRenderedGlyphMetrics.h
index b797cc5..91415a8 100644
--- a/GpCommon/GpRenderedGlyphMetrics.h
+++ b/GpCommon/GpRenderedGlyphMetrics.h
@@ -12,4 +12,6 @@ struct GpRenderedGlyphMetrics
int16_t m_bearingX;
int16_t m_bearingY;
int16_t m_advanceX;
+ int16_t m_bitmapOffsetX;
+ int16_t m_bitmapOffsetY;
};
diff --git a/GpCommon/GpUnicode.h b/GpCommon/GpUnicode.h
new file mode 100644
index 0000000..786b4b5
--- /dev/null
+++ b/GpCommon/GpUnicode.h
@@ -0,0 +1,165 @@
+#pragma once
+
+#include
+#include
+
+namespace GpUnicode
+{
+ namespace UTF8
+ {
+ static const unsigned int kMaxEncodedBytes = 4;
+
+ inline bool Decode(const uint8_t *characters, size_t availableCharacters, size_t &outCharactersDigested, uint32_t &outCodePoint)
+ {
+ if (availableCharacters <= 0)
+ return false;
+
+ if ((characters[0] & 0x80) == 0x00)
+ {
+ outCharactersDigested = 1;
+ outCodePoint = characters[0];
+ return true;
+ }
+
+ size_t sz = 0;
+ uint32_t codePoint = 0;
+ uint32_t minCodePoint = 0;
+ if ((characters[0] & 0xe0) == 0xc0)
+ {
+ sz = 2;
+ minCodePoint = 0x80;
+ codePoint = (characters[0] & 0x1f);
+ }
+ else if ((characters[0] & 0xf0) == 0xe0)
+ {
+ sz = 3;
+ minCodePoint = 0x800;
+ codePoint = (characters[0] & 0x0f);
+ }
+ else if ((characters[0] & 0xf8) == 0xf0)
+ {
+ sz = 4;
+ minCodePoint = 0x10000;
+ codePoint = (characters[0] & 0x07);
+ }
+ else
+ return false;
+
+ if (availableCharacters < sz)
+ return false;
+
+ for (size_t auxByte = 1; auxByte < sz; auxByte++)
+ {
+ if ((characters[auxByte] & 0xc0) != 0x80)
+ return false;
+
+ codePoint = (codePoint << 6) | (characters[auxByte] & 0x3f);
+ }
+
+ if (codePoint < minCodePoint || codePoint > 0x10ffff)
+ return false;
+
+ if (codePoint >= 0xd800 && codePoint <= 0xdfff)
+ return false;
+
+ outCodePoint = codePoint;
+ outCharactersDigested = sz;
+
+ return true;
+ }
+
+ inline void Encode(uint8_t *characters, size_t &outCharactersEmitted, uint32_t codePoint)
+ {
+ codePoint &= 0x1fffff;
+
+ uint8_t signalBits = 0;
+ size_t numBytes = 0;
+ if (codePoint < 0x0080)
+ {
+ numBytes = 1;
+ signalBits = 0;
+ }
+ else if (codePoint < 0x0800)
+ {
+ numBytes = 2;
+ signalBits = 0xc0;
+ }
+ else if (codePoint < 0x10000)
+ {
+ numBytes = 3;
+ signalBits = 0xe0;
+ }
+ else
+ {
+ numBytes = 4;
+ signalBits = 0xf0;
+ }
+
+ characters[0] = static_cast((codePoint >> (6 * (numBytes - 1))) | signalBits);
+
+ for (size_t i = 1; i < numBytes; i++)
+ {
+ const uint32_t isolate = ((codePoint >> (6 * (numBytes - 1 - i))) & 0x3f) | 0x80;
+ characters[i] = static_cast(isolate);
+ }
+
+ outCharactersEmitted = numBytes;
+ }
+ }
+
+ namespace UTF16
+ {
+ inline bool Decode(const uint16_t *characters, size_t availableCharacters, size_t &outCharactersDigested, uint32_t &outCodePoint)
+ {
+ if (availableCharacters <= 0)
+ return false;
+
+ if ((characters[0] & 0xff80) == 0x00)
+ {
+ outCharactersDigested = 1;
+ outCodePoint = characters[0];
+ return true;
+ }
+
+ if (characters[0] <= 0xd7ff || characters[0] >= 0xe000)
+ {
+ outCharactersDigested = 1;
+ outCodePoint = characters[0];
+ return true;
+ }
+
+ // Surrogate pair
+ if (characters[0] >= 0xdc00 || availableCharacters < 2)
+ return false;
+
+ if (characters[1] < 0xdc00 || characters[1] >= 0xe000)
+ return false;
+
+ uint16_t highBits = (characters[0] & 0x3ff);
+ uint16_t lowBits = (characters[1] & 0x3ff);
+
+ outCharactersDigested = 2;
+ outCodePoint = (highBits << 10) + lowBits + 0x10000;
+
+ return true;
+ }
+
+ inline void Encode(uint16_t *characters, size_t &outCharactersEmitted, uint32_t codePoint)
+ {
+ if (codePoint <= 0xd7ff || codePoint >= 0xe000)
+ {
+ outCharactersEmitted = 1;
+ characters[0] = static_cast(codePoint);
+ return;
+ }
+
+ uint32_t codePointBits = (codePoint - 0x10000) & 0xfffff;
+ uint16_t lowBits = (codePointBits & 0x3ff);
+ uint16_t highBits = ((codePointBits >> 10) & 0x3ff);
+
+ outCharactersEmitted = 2;
+ characters[0] = (0xd800 + highBits);
+ characters[1] = (0xdc00 + lowBits);
+ }
+ }
+}
diff --git a/GpCommon/GpWindows.h b/GpCommon/GpWindows.h
index bc53aac..8857d87 100644
--- a/GpCommon/GpWindows.h
+++ b/GpCommon/GpWindows.h
@@ -13,6 +13,7 @@
struct IGpBWCursor_Win32;
struct IGpCursor_Win32;
+struct IGpAllocator;
struct IGpVOSEventQueue;
struct GpWindowsGlobals
@@ -28,7 +29,7 @@ struct GpWindowsGlobals
HICON m_hIconSm;
int m_nCmdShow;
- IGpCursor_Win32 *(*m_createColorCursorFunc)(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY);
- IGpCursor_Win32 *(*m_createBWCursorFunc)(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY);
+ IGpCursor_Win32 *(*m_createColorCursorFunc)(IGpAllocator *alloc, size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY);
+ IGpCursor_Win32 *(*m_createBWCursorFunc)(IGpAllocator *alloc, size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY);
void (*m_translateWindowsMessageFunc)(const MSG *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY);
};
diff --git a/GpCommon/IGpAllocator.h b/GpCommon/IGpAllocator.h
new file mode 100644
index 0000000..9cc0703
--- /dev/null
+++ b/GpCommon/IGpAllocator.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include
+#include
+
+struct IGpAllocator
+{
+ virtual void *Realloc(void *buf, size_t newSize) = 0;
+
+ inline void *Alloc(size_t size) { return this->Realloc(nullptr, size); }
+ inline void Release(void *ptr) { this->Realloc(ptr, 0); }
+};
diff --git a/GpCommon/IGpAudioBuffer.h b/GpCommon/IGpAudioBuffer.h
new file mode 100644
index 0000000..89be8de
--- /dev/null
+++ b/GpCommon/IGpAudioBuffer.h
@@ -0,0 +1,8 @@
+#pragma once
+
+struct IGpAudioBuffer
+{
+public:
+ virtual void AddRef() = 0;
+ virtual void Release() = 0;
+};
diff --git a/GpCommon/IGpAudioChannel.h b/GpCommon/IGpAudioChannel.h
index 15a8699..3e18dd3 100644
--- a/GpCommon/IGpAudioChannel.h
+++ b/GpCommon/IGpAudioChannel.h
@@ -3,11 +3,12 @@
#include
struct IGpAudioChannelCallbacks;
+struct IGpAudioBuffer;
struct IGpAudioChannel
{
virtual void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) = 0;
- virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0;
+ virtual bool PostBuffer(IGpAudioBuffer *buffer) = 0;
virtual void Stop() = 0;
virtual void Destroy() = 0;
};
diff --git a/GpCommon/IGpAudioDriver.h b/GpCommon/IGpAudioDriver.h
index 9f77acb..31c086a 100644
--- a/GpCommon/IGpAudioDriver.h
+++ b/GpCommon/IGpAudioDriver.h
@@ -4,10 +4,12 @@
struct IGpAudioChannel;
struct IGpPrefsHandler;
+struct IGpAudioBuffer;
struct IGpAudioDriver
{
public:
+ virtual IGpAudioBuffer *CreateBuffer(const void *buffer, size_t bufferSize) = 0;
virtual IGpAudioChannel *CreateChannel() = 0;
virtual void SetMasterVolume(uint32_t vol, uint32_t maxVolume) = 0;
diff --git a/GpCommon/IGpFileSystem.h b/GpCommon/IGpFileSystem.h
index 72ad02a..f3ea479 100644
--- a/GpCommon/IGpFileSystem.h
+++ b/GpCommon/IGpFileSystem.h
@@ -1,6 +1,7 @@
#pragma once
#include "GpFileCreationDisposition.h"
+#include "CoreDefs.h"
#include "VirtualDirectory.h"
#include
@@ -17,7 +18,7 @@ public:
virtual bool FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) = 0;
virtual bool FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &exists) = 0;
virtual GpIOStream *OpenFileNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* subPaths, size_t numSubPaths, bool writeAccess, GpFileCreationDisposition_t createDisposition) = 0;
- virtual bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) = 0;
+ GP_ASYNCIFY_PARANOID_VIRTUAL bool DeleteFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool &existed) GP_ASYNCIFY_PARANOID_PURE;
virtual IGpDirectoryCursor *ScanDirectoryNested(PortabilityLayer::VirtualDirectory_t virtualDirectory, char const* const* paths, size_t numPaths) = 0;
virtual bool ValidateFilePath(const char *path, size_t pathLen) const = 0;
diff --git a/GpCommon/IGpFont.h b/GpCommon/IGpFont.h
index a1f8157..50caa1f 100644
--- a/GpCommon/IGpFont.h
+++ b/GpCommon/IGpFont.h
@@ -8,6 +8,7 @@ struct GpRenderedFontMetrics;
struct IGpFont
{
virtual void Destroy() = 0;
- virtual IGpFontRenderedGlyph *Render(uint32_t unicodeCodePoint, unsigned int size, bool aa) = 0;
+ virtual IGpFontRenderedGlyph *Render(uint32_t unicodeCodePoint, unsigned int size, unsigned int xScale, unsigned int yScale, bool aa) = 0;
virtual bool GetLineSpacing(unsigned int size, int32_t &outSpacing) = 0;
+ virtual bool SupportScaling() const = 0;
};
diff --git a/GpCommon/IGpFontHandler.h b/GpCommon/IGpFontHandler.h
index c7cd345..f3007f6 100644
--- a/GpCommon/IGpFontHandler.h
+++ b/GpCommon/IGpFontHandler.h
@@ -7,6 +7,6 @@ struct IGpFontHandler
{
virtual void Shutdown() = 0;
- virtual IGpFont *LoadFont(GpIOStream *stream) = 0;
+ virtual IGpFont *LoadFont(GpIOStream *stream, int typeFaceIndex) = 0;
virtual bool KeepStreamOpen() const = 0;
};
diff --git a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_D3D11.cpp
index 3bab0c0..e612160 100644
--- a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_D3D11.cpp
+++ b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_D3D11.cpp
@@ -1,8 +1,8 @@
static unsigned char gs_shaderData[] = {
- 68, 88, 66, 67, 167, 218, 15, 90, 211, 69, 240, 219, 76, 79, 17,
- 242, 61, 175, 125, 206, 1, 0, 0, 0, 44, 8, 0, 0, 5, 0,
+ 68, 88, 66, 67, 200, 182, 33, 104, 202, 4, 76, 179, 221, 223, 225,
+ 247, 101, 77, 248, 3, 1, 0, 0, 0, 12, 8, 0, 0, 5, 0,
0, 0, 52, 0, 0, 0, 172, 2, 0, 0, 4, 3, 0, 0, 56,
- 3, 0, 0, 176, 7, 0, 0, 82, 68, 69, 70, 112, 2, 0, 0,
+ 3, 0, 0, 144, 7, 0, 0, 82, 68, 69, 70, 112, 2, 0, 0,
1, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0,
0, 0, 4, 255, 255, 0, 137, 0, 0, 72, 2, 0, 0, 124, 0,
0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 255,
@@ -54,7 +54,7 @@ static unsigned char gs_shaderData[] = {
1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0,
0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
- 72, 68, 82, 112, 4, 0, 0, 64, 0, 0, 0, 28, 1, 0, 0,
+ 72, 68, 82, 80, 4, 0, 0, 64, 0, 0, 0, 20, 1, 0, 0,
89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0,
0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
0, 0, 88, 16, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 85,
@@ -71,74 +71,72 @@ static unsigned char gs_shaderData[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70,
14, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0,
- 56, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 142, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1,
- 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 56, 0, 0, 7,
- 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0,
- 0, 70, 14, 16, 0, 2, 0, 0, 0, 38, 0, 0, 9, 0, 208,
- 0, 0, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0,
- 0, 0, 0, 70, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16,
- 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0,
- 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0,
- 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 33, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16,
- 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86,
- 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16,
- 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0,
- 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0,
- 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0,
- 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0,
- 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
- 128, 63, 0, 0, 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1,
- 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0,
- 0, 0, 0, 0, 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0,
- 0, 57, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128,
- 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0,
- 0, 0, 0, 16, 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0,
- 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153,
- 62, 154, 153, 25, 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0,
- 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0,
- 0, 0, 128, 63, 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0,
- 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0,
- 0, 0, 2, 0, 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1,
- 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0,
- 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 55, 0, 0,
- 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0,
- 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0,
- 0, 0, 0, 29, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0,
- 2, 64, 0, 0, 230, 174, 37, 61, 230, 174, 37, 61, 230, 174, 37,
- 61, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0,
- 0, 10, 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0,
- 0, 0, 0, 2, 64, 0, 0, 145, 131, 158, 61, 145, 131, 158, 61,
- 145, 131, 158, 61, 0, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16,
- 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64,
- 0, 0, 174, 71, 97, 61, 174, 71, 97, 61, 174, 71, 97, 61, 0,
- 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0,
- 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 110, 167, 114,
- 63, 110, 167, 114, 63, 110, 167, 114, 63, 0, 0, 0, 0, 47, 0,
- 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0,
- 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0,
- 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 25,
- 64, 154, 153, 25, 64, 154, 153, 25, 64, 0, 0, 0, 0, 25, 0,
- 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0,
- 0, 0, 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0,
- 70, 2, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0,
- 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32,
- 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62,
- 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 34, 0, 0, 0,
- 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0,
- 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0,
+ 0, 0, 0, 128, 63, 56, 0, 0, 8, 242, 0, 16, 0, 1, 0,
+ 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0,
+ 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0,
+ 0, 70, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0,
+ 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0,
+ 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8,
+ 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0,
+ 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 55, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16,
+ 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1,
+ 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0,
+ 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0,
+ 0, 55, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0,
+ 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0,
+ 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0,
+ 0, 0, 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57,
+ 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154,
+ 153, 25, 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9,
+ 66, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0,
+ 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0,
+ 128, 63, 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26,
+ 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0,
+ 0, 6, 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0,
+ 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 114,
+ 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0,
+ 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 29, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 2, 64,
+ 0, 0, 230, 174, 37, 61, 230, 174, 37, 61, 230, 174, 37, 61, 0,
+ 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 114, 0, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 2, 64, 0, 0, 145, 131, 158, 61, 145, 131, 158, 61, 145, 131,
+ 158, 61, 0, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0,
+ 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0,
+ 174, 71, 97, 61, 174, 71, 97, 61, 174, 71, 97, 61, 0, 0, 0,
+ 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 110, 167, 114, 63, 110,
+ 167, 114, 63, 110, 167, 114, 63, 0, 0, 0, 0, 47, 0, 0, 5,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 25, 64, 154,
+ 153, 25, 64, 154, 153, 25, 64, 0, 0, 0, 0, 25, 0, 0, 5,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0,
+ 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 33, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 4,
+ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
- 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
};
namespace GpBinarizedShaders
diff --git a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_ICC_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_ICC_D3D11.cpp
index ac4ab75..668b1a9 100644
--- a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_ICC_D3D11.cpp
+++ b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_ICC_D3D11.cpp
@@ -1,8 +1,8 @@
static unsigned char gs_shaderData[] = {
- 68, 88, 66, 67, 63, 150, 199, 197, 210, 83, 220, 166, 163, 78, 42,
- 252, 31, 18, 160, 91, 1, 0, 0, 0, 240, 7, 0, 0, 5, 0,
+ 68, 88, 66, 67, 124, 220, 109, 55, 227, 43, 211, 66, 26, 106, 247,
+ 85, 84, 5, 208, 10, 1, 0, 0, 0, 208, 7, 0, 0, 5, 0,
0, 0, 52, 0, 0, 0, 172, 2, 0, 0, 4, 3, 0, 0, 56,
- 3, 0, 0, 116, 7, 0, 0, 82, 68, 69, 70, 112, 2, 0, 0,
+ 3, 0, 0, 84, 7, 0, 0, 82, 68, 69, 70, 112, 2, 0, 0,
1, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0,
0, 0, 4, 255, 255, 0, 137, 0, 0, 72, 2, 0, 0, 124, 0,
0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 255,
@@ -54,13 +54,13 @@ static unsigned char gs_shaderData[] = {
1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0,
0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
- 72, 68, 82, 52, 4, 0, 0, 64, 0, 0, 0, 13, 1, 0, 0,
+ 72, 68, 82, 20, 4, 0, 0, 64, 0, 0, 0, 5, 1, 0, 0,
89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0,
0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
0, 0, 88, 16, 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 85,
85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0,
101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0,
- 2, 3, 0, 0, 0, 65, 0, 0, 5, 50, 0, 16, 0, 0, 0,
+ 2, 2, 0, 0, 0, 65, 0, 0, 5, 50, 0, 16, 0, 0, 0,
0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 27, 0, 0, 5, 50,
0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0,
54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0,
@@ -71,70 +71,68 @@ static unsigned char gs_shaderData[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70,
14, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0,
- 56, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 142, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1,
- 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 56, 0, 0, 7,
- 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0,
- 0, 70, 14, 16, 0, 2, 0, 0, 0, 38, 0, 0, 9, 0, 208,
- 0, 0, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0,
- 0, 0, 0, 70, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16,
- 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0,
- 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0,
- 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 33, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16,
- 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86,
- 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16,
- 0, 1, 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0,
- 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0,
- 0, 0, 0, 55, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0,
- 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0,
- 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
- 128, 63, 0, 0, 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1,
- 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0,
- 0, 0, 0, 0, 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0,
- 0, 57, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128,
- 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0,
- 0, 0, 0, 16, 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0,
- 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153,
- 62, 154, 153, 25, 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0,
- 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0,
- 0, 0, 128, 63, 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0,
- 0, 26, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0,
- 0, 0, 2, 0, 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1,
- 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0,
- 1, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 55, 32, 0,
- 9, 114, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0,
- 0, 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0,
- 0, 0, 0, 47, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0,
- 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16,
- 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64,
- 0, 0, 102, 102, 230, 63, 102, 102, 230, 63, 102, 102, 230, 63, 0,
- 0, 0, 0, 25, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0,
- 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16,
- 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64,
- 0, 0, 150, 246, 160, 189, 43, 199, 117, 63, 40, 177, 243, 60, 0,
- 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0,
- 6, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 87, 203, 136,
- 63, 86, 131, 197, 60, 225, 104, 227, 58, 0, 0, 0, 0, 70, 2,
- 16, 0, 1, 0, 0, 0, 50, 32, 0, 12, 114, 32, 16, 0, 0,
- 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0,
- 5, 9, 34, 60, 158, 151, 129, 60, 194, 240, 119, 63, 0, 0, 0,
- 0, 70, 2, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32,
- 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62,
- 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 32, 0, 0, 0,
- 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0,
- 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0,
+ 0, 0, 0, 128, 63, 56, 0, 0, 8, 242, 0, 16, 0, 1, 0,
+ 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0,
+ 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0,
+ 0, 70, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0,
+ 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0,
+ 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8,
+ 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 42, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0,
+ 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 55, 0, 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16,
+ 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1,
+ 0, 0, 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0,
+ 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0,
+ 0, 55, 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0,
+ 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0,
+ 0, 1, 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0,
+ 0, 0, 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57,
+ 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154,
+ 153, 25, 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9,
+ 66, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0,
+ 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0,
+ 128, 63, 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26,
+ 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0,
+ 0, 6, 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0,
+ 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 55, 32, 0, 9, 114,
+ 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0,
+ 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 47, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0,
+ 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0,
+ 102, 102, 230, 63, 102, 102, 230, 63, 102, 102, 230, 63, 0, 0, 0,
+ 0, 25, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 1,
+ 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0,
+ 150, 246, 160, 189, 43, 199, 117, 63, 40, 177, 243, 60, 0, 0, 0,
+ 0, 50, 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 6, 0,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 87, 203, 136, 63, 86,
+ 131, 197, 60, 225, 104, 227, 58, 0, 0, 0, 0, 70, 2, 16, 0,
+ 1, 0, 0, 0, 50, 32, 0, 12, 114, 32, 16, 0, 0, 0, 0,
+ 0, 166, 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 9,
+ 34, 60, 158, 151, 129, 60, 194, 240, 119, 63, 0, 0, 0, 0, 70,
+ 2, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0,
+ 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 31, 0, 0, 0, 2, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 14, 0, 0, 0, 4,
+ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
- 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
};
namespace GpBinarizedShaders
diff --git a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp
index 261990f..887a0bb 100644
--- a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp
+++ b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp
@@ -1,8 +1,8 @@
static unsigned char gs_shaderData[] = {
- 68, 88, 66, 67, 55, 11, 130, 121, 223, 86, 90, 24, 177, 20, 124,
- 204, 5, 205, 68, 19, 1, 0, 0, 0, 176, 7, 0, 0, 5, 0,
+ 68, 88, 66, 67, 70, 73, 170, 202, 197, 249, 120, 87, 61, 204, 7,
+ 189, 64, 34, 147, 57, 1, 0, 0, 0, 144, 7, 0, 0, 5, 0,
0, 0, 52, 0, 0, 0, 124, 2, 0, 0, 212, 2, 0, 0, 8,
- 3, 0, 0, 52, 7, 0, 0, 82, 68, 69, 70, 64, 2, 0, 0,
+ 3, 0, 0, 20, 7, 0, 0, 82, 68, 69, 70, 64, 2, 0, 0,
1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0,
0, 0, 4, 255, 255, 0, 137, 0, 0, 24, 2, 0, 0, 92, 0,
0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255,
@@ -51,7 +51,7 @@ static unsigned char gs_shaderData[] = {
0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83,
86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82,
- 36, 4, 0, 0, 64, 0, 0, 0, 9, 1, 0, 0, 89, 0, 0,
+ 4, 4, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 89, 0, 0,
4, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 24,
0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98,
16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3,
@@ -62,75 +62,73 @@ static unsigned char gs_shaderData[] = {
194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0,
- 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 9,
- 242, 0, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1,
- 64, 0, 0, 0, 0, 128, 63, 56, 0, 0, 7, 242, 0, 16, 0,
- 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16,
- 0, 2, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 50, 0,
- 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70,
- 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7,
- 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0,
- 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8, 34, 0,
- 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42,
- 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 8,
- 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
- 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0,
- 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0,
- 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0,
- 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0,
- 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55,
- 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0,
- 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0,
- 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
- 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1,
- 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0,
- 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57, 0, 0,
- 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0,
- 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 16,
- 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0,
- 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154, 153, 25,
- 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9, 66, 0,
- 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0, 0, 0,
- 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63,
- 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16,
- 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 2, 0,
- 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6,
- 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0,
- 86, 5, 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16,
- 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, 7,
- 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 29,
- 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0,
- 230, 174, 37, 61, 230, 174, 37, 61, 230, 174, 37, 61, 0, 0, 0,
- 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0,
- 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2,
- 64, 0, 0, 145, 131, 158, 61, 145, 131, 158, 61, 145, 131, 158, 61,
- 0, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0,
- 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 174, 71,
- 97, 61, 174, 71, 97, 61, 174, 71, 97, 61, 0, 0, 0, 0, 56,
- 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
- 0, 0, 0, 0, 2, 64, 0, 0, 110, 167, 114, 63, 110, 167, 114,
- 63, 110, 167, 114, 63, 0, 0, 0, 0, 47, 0, 0, 5, 114, 0,
- 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56,
- 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
- 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 25, 64, 154, 153, 25,
- 64, 154, 153, 25, 64, 0, 0, 0, 0, 25, 0, 0, 5, 114, 0,
- 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 55,
- 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
- 1, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16,
- 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0,
- 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83,
- 84, 65, 84, 116, 0, 0, 0, 32, 0, 0, 0, 3, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0,
- 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128,
+ 63, 56, 0, 0, 8, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14,
+ 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 50, 0, 16, 0,
+ 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0,
+ 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10,
+ 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8, 34, 0, 16, 0,
+ 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 8, 18, 0,
+ 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58,
+ 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 12,
+ 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0,
+ 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 60,
+ 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0,
+ 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0,
+ 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0,
+ 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0,
+ 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 13, 0,
+ 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57, 0, 0, 8, 18,
+ 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0,
+ 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154, 153, 25, 63, 205,
+ 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9, 66, 0, 16, 0,
+ 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 56, 0,
+ 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1,
+ 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16,
+ 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 5,
+ 16, 0, 1, 0, 0, 0, 55, 0, 0, 9, 114, 0, 16, 0, 0,
+ 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0,
+ 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 29, 0, 0,
+ 10, 114, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 230, 174,
+ 37, 61, 230, 174, 37, 61, 230, 174, 37, 61, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0,
+ 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 145, 131, 158, 61, 145, 131, 158, 61, 145, 131, 158, 61, 0, 0,
+ 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 174, 71, 97, 61,
+ 174, 71, 97, 61, 174, 71, 97, 61, 0, 0, 0, 0, 56, 0, 0,
+ 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 110, 167, 114, 63, 110, 167, 114, 63, 110,
+ 167, 114, 63, 0, 0, 0, 0, 47, 0, 0, 5, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 154, 153, 25, 64, 154, 153, 25, 64, 154,
+ 153, 25, 64, 0, 0, 0, 0, 25, 0, 0, 5, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 55, 0, 0,
+ 9, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0,
+ 0, 0, 70, 2, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0,
+ 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0,
+ 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 31, 0, 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0,
- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
};
namespace GpBinarizedShaders
diff --git a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_ICC_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_ICC_D3D11.cpp
index eba0649..7c4c9b8 100644
--- a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_ICC_D3D11.cpp
+++ b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_ICC_D3D11.cpp
@@ -1,8 +1,8 @@
static unsigned char gs_shaderData[] = {
- 68, 88, 66, 67, 59, 168, 168, 88, 76, 243, 83, 77, 18, 124, 254,
- 1, 241, 101, 79, 130, 1, 0, 0, 0, 116, 7, 0, 0, 5, 0,
+ 68, 88, 66, 67, 108, 52, 221, 105, 109, 174, 81, 46, 155, 29, 71,
+ 86, 93, 178, 121, 166, 1, 0, 0, 0, 84, 7, 0, 0, 5, 0,
0, 0, 52, 0, 0, 0, 124, 2, 0, 0, 212, 2, 0, 0, 8,
- 3, 0, 0, 248, 6, 0, 0, 82, 68, 69, 70, 64, 2, 0, 0,
+ 3, 0, 0, 216, 6, 0, 0, 82, 68, 69, 70, 64, 2, 0, 0,
1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0,
0, 0, 4, 255, 255, 0, 137, 0, 0, 24, 2, 0, 0, 92, 0,
0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255,
@@ -51,82 +51,80 @@ static unsigned char gs_shaderData[] = {
0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83,
86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82,
- 232, 3, 0, 0, 64, 0, 0, 0, 250, 0, 0, 0, 89, 0, 0,
+ 200, 3, 0, 0, 64, 0, 0, 0, 242, 0, 0, 0, 89, 0, 0,
4, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 24,
0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98,
16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3,
- 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0,
+ 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0,
0, 65, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16,
16, 0, 1, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0,
0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8,
194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0,
0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0,
- 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 9,
- 242, 0, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1,
- 64, 0, 0, 0, 0, 128, 63, 56, 0, 0, 7, 242, 0, 16, 0,
- 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16,
- 0, 2, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 50, 0,
- 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70,
- 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7,
- 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0,
- 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8, 34, 0,
- 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42,
- 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 8,
- 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
- 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0,
- 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0,
- 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0,
- 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0,
- 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55,
- 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0,
- 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0,
- 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0,
- 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1,
- 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0,
- 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57, 0, 0,
- 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0,
- 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 16,
- 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0,
- 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154, 153, 25,
- 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9, 66, 0,
- 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0, 0, 0,
- 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63,
- 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16,
- 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 2, 0,
- 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6,
- 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0,
- 86, 5, 16, 0, 1, 0, 0, 0, 55, 32, 0, 9, 114, 0, 16,
- 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, 7,
- 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 47,
- 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
- 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0,
- 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 102, 102,
- 230, 63, 102, 102, 230, 63, 102, 102, 230, 63, 0, 0, 0, 0, 25,
- 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
- 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0,
- 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 150, 246,
- 160, 189, 43, 199, 117, 63, 40, 177, 243, 60, 0, 0, 0, 0, 50,
- 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0,
- 0, 0, 0, 0, 2, 64, 0, 0, 87, 203, 136, 63, 86, 131, 197,
- 60, 225, 104, 227, 58, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0,
- 0, 0, 50, 32, 0, 12, 114, 32, 16, 0, 0, 0, 0, 0, 166,
- 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 9, 34, 60,
- 158, 151, 129, 60, 194, 240, 119, 63, 0, 0, 0, 0, 70, 2, 16,
- 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0,
- 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83,
- 84, 65, 84, 116, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0,
- 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128,
+ 63, 56, 0, 0, 8, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14,
+ 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 50, 0, 16, 0,
+ 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, 18, 0,
+ 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10,
+ 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8, 34, 0, 16, 0,
+ 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 8, 18, 0,
+ 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58,
+ 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 12,
+ 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0,
+ 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 60,
+ 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0,
+ 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0,
+ 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0,
+ 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0,
+ 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 13, 0,
+ 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57, 0, 0, 8, 18,
+ 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 16, 0, 0,
+ 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154, 153, 25, 63, 205,
+ 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9, 66, 0, 16, 0,
+ 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 56, 0,
+ 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 1,
+ 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 9, 16,
+ 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 86, 5,
+ 16, 0, 1, 0, 0, 0, 55, 32, 0, 9, 114, 0, 16, 0, 0,
+ 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, 16, 0,
+ 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 47, 0, 0,
+ 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 102, 102, 230, 63,
+ 102, 102, 230, 63, 102, 102, 230, 63, 0, 0, 0, 0, 25, 0, 0,
+ 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 86,
+ 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 150, 246, 160, 189,
+ 43, 199, 117, 63, 40, 177, 243, 60, 0, 0, 0, 0, 50, 0, 0,
+ 12, 114, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 87, 203, 136, 63, 86, 131, 197, 60, 225,
+ 104, 227, 58, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, 0, 0,
+ 50, 32, 0, 12, 114, 32, 16, 0, 0, 0, 0, 0, 166, 10, 16,
+ 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 9, 34, 60, 158, 151,
+ 129, 60, 194, 240, 119, 63, 0, 0, 0, 0, 70, 2, 16, 0, 1,
+ 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0,
+ 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 29, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 14, 0, 0, 0, 4, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
};
namespace GpBinarizedShaders
diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp
index 0990779..d182a29 100644
--- a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp
+++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp
@@ -1,8 +1,10 @@
#include "GpApplicationName.h"
#include "GpDisplayDriverD3D11.h"
+#include "GpDisplayDriverProperties.h"
#include "GpDisplayDriverSurfaceD3D11.h"
#include "GpVOSEvent.h"
#include "GpWindows.h"
+#include "IGpAllocator.h"
#include "IGpCursor_Win32.h"
#include "IGpVOSEventQueue.h"
@@ -1243,8 +1245,9 @@ void GpDisplayDriverD3D11::ServeTicks(int tickCount)
void GpDisplayDriverD3D11::Shutdown()
{
+ IGpAllocator *alloc = m_properties.m_alloc;
this->~GpDisplayDriverD3D11();
- free(this);
+ alloc->Release(this);
}
void GpDisplayDriverD3D11::GetInitialDisplayResolution(unsigned int *width, unsigned int *height)
@@ -1257,7 +1260,7 @@ void GpDisplayDriverD3D11::GetInitialDisplayResolution(unsigned int *width, unsi
IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, size_t pitch, GpPixelFormat_t pixelFormat, IGpDisplayDriver::SurfaceInvalidateCallback_t invalidateCallback, void *invalidateContext)
{
- return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat);
+ return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat, m_properties.m_alloc);
}
void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects)
@@ -1385,12 +1388,12 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, int32_t
IGpCursor *GpDisplayDriverD3D11::CreateColorCursor(size_t width, size_t height, const void *pixelDataRGBA, size_t hotSpotX, size_t hotSpotY)
{
- return m_osGlobals->m_createColorCursorFunc(width, height, pixelDataRGBA, hotSpotX, hotSpotY);
+ return m_osGlobals->m_createColorCursorFunc(m_properties.m_alloc, width, height, pixelDataRGBA, hotSpotX, hotSpotY);
}
IGpCursor *GpDisplayDriverD3D11::CreateBWCursor(size_t width, size_t height, const void *pixelData, const void *maskData, size_t hotSpotX, size_t hotSpotY)
{
- return m_osGlobals->m_createBWCursorFunc(width, height, pixelData, maskData, hotSpotX, hotSpotY);
+ return m_osGlobals->m_createBWCursorFunc(m_properties.m_alloc, width, height, pixelData, maskData, hotSpotX, hotSpotY);
}
// We can't just set the cursor because we want to post WM_SETCURSOR to keep it limited
@@ -1507,7 +1510,7 @@ bool GpDisplayDriverD3D11::SavePrefs(void *context, IGpPrefsHandler::WritePrefsF
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
{
- void *storage = malloc(sizeof(GpDisplayDriverD3D11));
+ void *storage = properties.m_alloc->Alloc(sizeof(GpDisplayDriverD3D11));
if (!storage)
return nullptr;
diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp
index 9f2f3d2..cd17fbd 100644
--- a/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp
+++ b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp
@@ -1,5 +1,6 @@
#include "GpDisplayDriverSurfaceD3D11.h"
#include "GpComPtr.h"
+#include "IGpAllocator.h"
#include
#include
@@ -55,8 +56,9 @@ void GpDisplayDriverSurfaceD3D11::UploadEntire(const void *data, size_t pitch)
void GpDisplayDriverSurfaceD3D11::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpDisplayDriverSurfaceD3D11();
- free(this);
+ alloc->Release(this);
}
ID3D11ShaderResourceView *GpDisplayDriverSurfaceD3D11::GetSRV() const
@@ -79,7 +81,7 @@ size_t GpDisplayDriverSurfaceD3D11::GetHeight() const
return m_height;
}
-GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, GpPixelFormat_t pixelFormat)
+GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, GpPixelFormat_t pixelFormat, IGpAllocator *alloc)
{
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R8_UNORM;
@@ -127,17 +129,17 @@ GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *d
if (device->CreateShaderResourceView(texture, &srvDesc, srv.GetMutablePtr()) != S_OK)
return nullptr;
- void *storage = malloc(sizeof(GpDisplayDriverSurfaceD3D11));
+ void *storage = alloc->Alloc(sizeof(GpDisplayDriverSurfaceD3D11));
if (!storage)
{
texture->Release();
return nullptr;
}
- return new (storage) GpDisplayDriverSurfaceD3D11(device, deviceContext, texture, srv, width, height, pixelFormat);
+ return new (storage) GpDisplayDriverSurfaceD3D11(device, deviceContext, texture, srv, width, height, pixelFormat, alloc);
}
-GpDisplayDriverSurfaceD3D11::GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, GpPixelFormat_t pixelFormat)
+GpDisplayDriverSurfaceD3D11::GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, GpPixelFormat_t pixelFormat, IGpAllocator *alloc)
: m_width(width)
, m_height(height)
, m_pixelFormat(pixelFormat)
@@ -145,6 +147,7 @@ GpDisplayDriverSurfaceD3D11::GpDisplayDriverSurfaceD3D11(ID3D11Device *device, I
, m_deviceContext(deviceContext)
, m_texture(texture)
, m_srv(srv)
+ , m_alloc(alloc)
{
}
diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h
index a7d7a9c..afbb050 100644
--- a/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h
+++ b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h
@@ -8,6 +8,7 @@ struct ID3D11Device;
struct ID3D11DeviceContext;
struct ID3D11ShaderResourceView;
struct ID3D11Texture2D;
+struct IGpAllocator;
class GpDisplayDriverSurfaceD3D11 final : public IGpDisplayDriverSurface
{
@@ -21,10 +22,10 @@ public:
size_t GetWidth() const;
size_t GetHeight() const;
- static GpDisplayDriverSurfaceD3D11 *Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, GpPixelFormat_t pixelFormat);
+ static GpDisplayDriverSurfaceD3D11 *Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, GpPixelFormat_t pixelFormat, IGpAllocator *alloc);
private:
- GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, GpPixelFormat_t pixelFormat);
+ GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, GpPixelFormat_t pixelFormat, IGpAllocator *alloc);
~GpDisplayDriverSurfaceD3D11();
size_t m_width;
@@ -32,6 +33,7 @@ private:
GpPixelFormat_t m_pixelFormat;
ID3D11Device *m_device;
ID3D11DeviceContext *m_deviceContext;
+ IGpAllocator *m_alloc;
GpComPtr m_texture;
GpComPtr m_srv;
diff --git a/GpFontHandler_FreeType2/GpFontHandler_FreeType2.cpp b/GpFontHandler_FreeType2/GpFontHandler_FreeType2.cpp
index 1ee56aa..270861a 100644
--- a/GpFontHandler_FreeType2/GpFontHandler_FreeType2.cpp
+++ b/GpFontHandler_FreeType2/GpFontHandler_FreeType2.cpp
@@ -3,6 +3,7 @@
#include "CoreDefs.h"
#include "GpIOStream.h"
+#include "IGpAllocator.h"
#include "IGpFont.h"
#include "IGpFontRenderedGlyph.h"
#include "GpRenderedGlyphMetrics.h"
@@ -17,6 +18,8 @@
#include
#include
+struct IGpAllocator;
+
class GpFontRenderedGlyph_FreeType2 final : public IGpFontRenderedGlyph
{
public:
@@ -24,14 +27,15 @@ public:
const void *GetData() const override;
void Destroy() override;
- static GpFontRenderedGlyph_FreeType2 *Create(size_t dataSize, const GpRenderedGlyphMetrics &metrics);
+ static GpFontRenderedGlyph_FreeType2 *Create(IGpAllocator *alloc, size_t dataSize, const GpRenderedGlyphMetrics &metrics);
void *GetMutableData();
private:
- GpFontRenderedGlyph_FreeType2(void *data, const GpRenderedGlyphMetrics &metrics);
+ GpFontRenderedGlyph_FreeType2(IGpAllocator *alloc, void *data, const GpRenderedGlyphMetrics &metrics);
~GpFontRenderedGlyph_FreeType2();
+ IGpAllocator *m_alloc;
void *m_data;
GpRenderedGlyphMetrics m_metrics;
};
@@ -40,20 +44,22 @@ class GpFont_FreeType2 final : public IGpFont
{
public:
void Destroy() override;
- IGpFontRenderedGlyph *Render(uint32_t unicodeCodePoint, unsigned int size, bool aa) override;
+ IGpFontRenderedGlyph *Render(uint32_t unicodeCodePoint, unsigned int size, unsigned int xScale, unsigned int yScale, bool aa) override;
bool GetLineSpacing(unsigned int size, int32_t &outSpacing) override;
+ bool SupportScaling() const override;
- static GpFont_FreeType2 *Create(const FT_StreamRec_ &streamRec, GpIOStream *stream);
+ static GpFont_FreeType2 *Create(IGpAllocator *alloc, const FT_StreamRec_ &streamRec, GpIOStream *stream);
- bool FTLoad(const FT_Library &library);
+ bool FTLoad(const FT_Library &library, int typeFaceIndex);
private:
- explicit GpFont_FreeType2(const FT_StreamRec_ &streamRec, GpIOStream *stream);
+ GpFont_FreeType2(IGpAllocator *alloc, const FT_StreamRec_ &streamRec, GpIOStream *stream);
~GpFont_FreeType2();
FT_StreamRec_ m_ftStream;
FT_Face m_face;
GpIOStream *m_stream;
+ IGpAllocator *m_alloc;
unsigned int m_currentSize;
};
@@ -69,20 +75,21 @@ const void *GpFontRenderedGlyph_FreeType2::GetData() const
void GpFontRenderedGlyph_FreeType2::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpFontRenderedGlyph_FreeType2();
- free(this);
+ alloc->Release(this);
}
-GpFontRenderedGlyph_FreeType2 *GpFontRenderedGlyph_FreeType2::Create(size_t dataSize, const GpRenderedGlyphMetrics &metrics)
+GpFontRenderedGlyph_FreeType2 *GpFontRenderedGlyph_FreeType2::Create(IGpAllocator *alloc, size_t dataSize, const GpRenderedGlyphMetrics &metrics)
{
size_t alignedPrefixSize = (sizeof(GpFontRenderedGlyph_FreeType2) + GP_SYSTEM_MEMORY_ALIGNMENT - 1);
alignedPrefixSize -= alignedPrefixSize % GP_SYSTEM_MEMORY_ALIGNMENT;
- void *storage = malloc(alignedPrefixSize + dataSize);
+ void *storage = alloc->Alloc(alignedPrefixSize + dataSize);
if (!storage)
return nullptr;
- return new (storage) GpFontRenderedGlyph_FreeType2(static_cast(storage) + alignedPrefixSize, metrics);
+ return new (storage) GpFontRenderedGlyph_FreeType2(alloc, static_cast(storage) + alignedPrefixSize, metrics);
}
void *GpFontRenderedGlyph_FreeType2::GetMutableData()
@@ -91,9 +98,10 @@ void *GpFontRenderedGlyph_FreeType2::GetMutableData()
}
-GpFontRenderedGlyph_FreeType2::GpFontRenderedGlyph_FreeType2(void *data, const GpRenderedGlyphMetrics &metrics)
+GpFontRenderedGlyph_FreeType2::GpFontRenderedGlyph_FreeType2(IGpAllocator *alloc, void *data, const GpRenderedGlyphMetrics &metrics)
: m_metrics(metrics)
, m_data(data)
+ , m_alloc(alloc)
{
}
@@ -103,11 +111,12 @@ GpFontRenderedGlyph_FreeType2::~GpFontRenderedGlyph_FreeType2()
void GpFont_FreeType2::Destroy()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpFont_FreeType2();
- free(this);
+ alloc->Release(this);
}
-IGpFontRenderedGlyph *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsigned int size, bool aa)
+IGpFontRenderedGlyph *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsigned int size, unsigned int xScale, unsigned int yScale, bool aa)
{
if (m_currentSize != size)
{
@@ -117,6 +126,14 @@ IGpFontRenderedGlyph *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsign
m_currentSize = size;
}
+ FT_Matrix transform;
+ transform.xx = xScale << 16;
+ transform.xy = 0;
+ transform.yx = 0;
+ transform.yy = yScale << 16;
+
+ FT_Set_Transform(m_face, &transform, nullptr);
+
FT_UInt glyphIndex = FT_Get_Char_Index(m_face, unicodeCodePoint);
if (!glyphIndex)
return nullptr;
@@ -163,6 +180,8 @@ IGpFontRenderedGlyph *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsign
metrics.m_glyphWidth = glyph->bitmap.width;
metrics.m_glyphHeight = glyph->bitmap.rows;
metrics.m_advanceX = glyph->metrics.horiAdvance / 64;
+ metrics.m_bitmapOffsetX = glyph->bitmap_left;
+ metrics.m_bitmapOffsetY = glyph->bitmap_top;
const size_t numRowsRequired = glyph->bitmap.rows;
size_t pitchRequired = 0;
@@ -179,7 +198,7 @@ IGpFontRenderedGlyph *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsign
metrics.m_glyphDataPitch = pitchRequired;
- GpFontRenderedGlyph_FreeType2 *renderedGlyph = GpFontRenderedGlyph_FreeType2::Create(glyphDataSize, metrics);
+ GpFontRenderedGlyph_FreeType2 *renderedGlyph = GpFontRenderedGlyph_FreeType2::Create(m_alloc, glyphDataSize, metrics);
if (!renderedGlyph)
return nullptr;
@@ -247,35 +266,42 @@ bool GpFont_FreeType2::GetLineSpacing(unsigned int size, int32_t &outSpacing)
return true;
}
-
-GpFont_FreeType2 *GpFont_FreeType2::Create(const FT_StreamRec_ &streamRec, GpIOStream *stream)
+bool GpFont_FreeType2::SupportScaling() const
{
- void *storage = malloc(sizeof(GpFont_FreeType2));
+ return true;
+}
+
+GpFont_FreeType2 *GpFont_FreeType2::Create(IGpAllocator *alloc, const FT_StreamRec_ &streamRec, GpIOStream *stream)
+{
+ void *storage = alloc->Alloc(sizeof(GpFont_FreeType2));
if (!storage)
return nullptr;
- return new (storage) GpFont_FreeType2(streamRec, stream);
+ return new (storage) GpFont_FreeType2(alloc, streamRec, stream);
}
-bool GpFont_FreeType2::FTLoad(const FT_Library &library)
+bool GpFont_FreeType2::FTLoad(const FT_Library &library, int typeFaceIndex)
{
FT_Open_Args openArgs;
memset(&openArgs, 0, sizeof(openArgs));
openArgs.flags = FT_OPEN_STREAM;
openArgs.stream = &m_ftStream;
- FT_Error errorCode = FT_Open_Face(library, &openArgs, 0, &m_face);
+ FT_Error errorCode = FT_Open_Face(library, &openArgs, typeFaceIndex, &m_face);
if (errorCode != 0)
return false;
+ FT_Matrix transform;
+
return true;
}
-GpFont_FreeType2::GpFont_FreeType2(const FT_StreamRec_ &streamRec, GpIOStream *stream)
+GpFont_FreeType2::GpFont_FreeType2(IGpAllocator *alloc, const FT_StreamRec_ &streamRec, GpIOStream *stream)
: m_face(nullptr)
, m_ftStream(streamRec)
, m_stream(stream)
, m_currentSize(0)
+ , m_alloc(alloc)
{
assert(stream);
}
@@ -288,13 +314,13 @@ GpFont_FreeType2::~GpFont_FreeType2()
m_stream->Close();
}
-GpFontHandler_FreeType2 *GpFontHandler_FreeType2::Create()
+GpFontHandler_FreeType2 *GpFontHandler_FreeType2::Create(IGpAllocator *alloc)
{
- void *storage = malloc(sizeof(GpFontHandler_FreeType2));
+ void *storage = alloc->Alloc(sizeof(GpFontHandler_FreeType2));
if (!storage)
return nullptr;
- GpFontHandler_FreeType2 *fh = new (storage) GpFontHandler_FreeType2();
+ GpFontHandler_FreeType2 *fh = new (storage) GpFontHandler_FreeType2(alloc);
if (!fh->Init())
{
fh->Shutdown();
@@ -304,7 +330,7 @@ GpFontHandler_FreeType2 *GpFontHandler_FreeType2::Create()
return fh;
}
-IGpFont *GpFontHandler_FreeType2::LoadFont(GpIOStream *stream)
+IGpFont *GpFontHandler_FreeType2::LoadFont(GpIOStream *stream, int typeFaceIndex)
{
FT_StreamRec_ ftStream;
memset(&ftStream, 0, sizeof(ftStream));
@@ -314,14 +340,14 @@ IGpFont *GpFontHandler_FreeType2::LoadFont(GpIOStream *stream)
ftStream.read = FTStreamIo;
ftStream.close = FTStreamClose;
- GpFont_FreeType2 *font = GpFont_FreeType2::Create(ftStream, stream);
+ GpFont_FreeType2 *font = GpFont_FreeType2::Create(m_alloc, ftStream, stream);
if (!font)
{
stream->Close();
return nullptr;
}
- if (!font->FTLoad(m_library))
+ if (!font->FTLoad(m_library, typeFaceIndex))
{
font->Destroy();
return nullptr;
@@ -337,14 +363,16 @@ bool GpFontHandler_FreeType2::KeepStreamOpen() const
void GpFontHandler_FreeType2::Shutdown()
{
+ IGpAllocator *alloc = m_alloc;
this->~GpFontHandler_FreeType2();
- free(this);
+ alloc->Release(this);
}
-GpFontHandler_FreeType2::GpFontHandler_FreeType2()
+GpFontHandler_FreeType2::GpFontHandler_FreeType2(IGpAllocator *alloc)
: m_ftIsInitialized(false)
, m_library(nullptr)
, m_currentSize(0)
+ , m_alloc(alloc)
{
}
@@ -394,18 +422,18 @@ void GpFontHandler_FreeType2::FTStreamClose(FT_Stream stream)
void *GpFontHandler_FreeType2::FTAlloc(long size)
{
- return malloc(static_cast(size));
+ return m_alloc->Alloc(static_cast(size));
}
void GpFontHandler_FreeType2::FTFree(void* block)
{
- free(block);
+ m_alloc->Release(block);
}
void *GpFontHandler_FreeType2::FTRealloc(long curSize, long newSize, void *block)
{
(void)curSize;
- return realloc(block, static_cast(newSize));
+ return m_alloc->Realloc(block, static_cast(newSize));
}
bool GpFontHandler_FreeType2::Init()
@@ -431,5 +459,5 @@ __declspec(dllexport)
#endif
IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties)
{
- return GpFontHandler_FreeType2::Create();
+ return GpFontHandler_FreeType2::Create(properties.m_alloc);
}
diff --git a/GpFontHandler_FreeType2/GpFontHandler_FreeType2.h b/GpFontHandler_FreeType2/GpFontHandler_FreeType2.h
index 3d5c033..d190082 100644
--- a/GpFontHandler_FreeType2/GpFontHandler_FreeType2.h
+++ b/GpFontHandler_FreeType2/GpFontHandler_FreeType2.h
@@ -7,6 +7,7 @@
#include FT_FREETYPE_H
class GpIOStream;
+struct IGpAllocator;
namespace PortabilityLayer
{
@@ -16,15 +17,15 @@ namespace PortabilityLayer
class GpFontHandler_FreeType2 final : public IGpFontHandler
{
public:
- IGpFont *LoadFont(GpIOStream *stream) override;
+ IGpFont *LoadFont(GpIOStream *stream, int typeFaceIndex) override;
void Shutdown() override;
bool KeepStreamOpen() const override;
- static GpFontHandler_FreeType2 *Create();
+ static GpFontHandler_FreeType2 *Create(IGpAllocator *alloc);
private:
- GpFontHandler_FreeType2();
+ explicit GpFontHandler_FreeType2(IGpAllocator *alloc);
~GpFontHandler_FreeType2();
static void *FTAllocThunk(FT_Memory memory, long size);
@@ -44,4 +45,5 @@ private:
FT_Library m_library;
unsigned int m_currentSize;
bool m_ftIsInitialized;
+ IGpAllocator *m_alloc;
};
diff --git a/GpInputDriver_XInput/GpInputDriverXInput.cpp b/GpInputDriver_XInput/GpInputDriverXInput.cpp
index b3ccf41..4fefd05 100644
--- a/GpInputDriver_XInput/GpInputDriverXInput.cpp
+++ b/GpInputDriver_XInput/GpInputDriverXInput.cpp
@@ -2,6 +2,7 @@
#include "GpVOSEvent.h"
#include "GpWindows.h"
#include "IGpVOSEventQueue.h"
+#include "IGpAllocator.h"
#include
#include
@@ -72,8 +73,9 @@ void GpInputDriverXInput::ProcessInput()
void GpInputDriverXInput::Shutdown()
{
+ IGpAllocator *alloc = m_properties.m_alloc;
this->~GpInputDriverXInput();
- free(this);
+ alloc->Release(this);
}
IGpPrefsHandler *GpInputDriverXInput::GetPrefsHandler() const
@@ -83,7 +85,7 @@ IGpPrefsHandler *GpInputDriverXInput::GetPrefsHandler() const
GpInputDriverXInput *GpInputDriverXInput::Create(const GpInputDriverProperties &props)
{
- void *storage = malloc(sizeof(GpInputDriverXInput));
+ void *storage = props.m_alloc->Alloc(sizeof(GpInputDriverXInput));
if (!storage)
return nullptr;
diff --git a/GpShell/Android.mk b/GpShell/Android.mk
index d45af9c..ea38797 100644
--- a/GpShell/Android.mk
+++ b/GpShell/Android.mk
@@ -13,13 +13,6 @@ LOCAL_CFLAGS := -DGP_DEBUG_CONFIG=0
# Add your application source files here...
LOCAL_SRC_FILES := \
- GpAppEnvironment.cpp \
- GpAudioDriverFactory.cpp \
- GpDisplayDriverFactory.cpp \
- GpFontHandlerFactory.cpp \
- GpGlobalConfig.cpp \
- GpInputDriverFactory.cpp \
- GpMain.cpp \
- GpVOSEventQueue.cpp
+ GpShell_Combined.cpp
include $(BUILD_STATIC_LIBRARY)
diff --git a/GpShell/GpGlobalConfig.h b/GpShell/GpGlobalConfig.h
index d37849d..09d5ae6 100644
--- a/GpShell/GpGlobalConfig.h
+++ b/GpShell/GpGlobalConfig.h
@@ -10,6 +10,7 @@
struct IGpLogDriver;
struct IGpSystemServices;
+struct IGpAllocator;
struct GpGlobalConfig
{
@@ -22,6 +23,7 @@ struct GpGlobalConfig
IGpLogDriver *m_logger;
IGpSystemServices *m_systemServices;
+ IGpAllocator *m_allocator;
void *m_osGlobals;
};
diff --git a/GpShell/GpMain.cpp b/GpShell/GpMain.cpp
index b30f3b3..9488181 100644
--- a/GpShell/GpMain.cpp
+++ b/GpShell/GpMain.cpp
@@ -11,6 +11,7 @@
#include "GpInputDriverProperties.h"
#include "GpGlobalConfig.h"
#include "GpAppEnvironment.h"
+#include "IGpAllocator.h"
#include "IGpAudioDriver.h"
#include "IGpDisplayDriver.h"
#include "IGpFontHandler.h"
@@ -36,6 +37,7 @@ int GpMain::Run()
{
GpVOSEventQueue *eventQueue = new GpVOSEventQueue();
GpAppEnvironment *appEnvironment = new GpAppEnvironment();
+ IGpAllocator *alloc = g_gpGlobalConfig.m_allocator;
GpDisplayDriverProperties ddProps;
memset(&ddProps, 0, sizeof(ddProps));
@@ -60,6 +62,7 @@ int GpMain::Run()
ddProps.m_eventQueue = eventQueue;
ddProps.m_logger = g_gpGlobalConfig.m_logger;
ddProps.m_systemServices = g_gpGlobalConfig.m_systemServices;
+ ddProps.m_alloc = g_gpGlobalConfig.m_allocator;
GpAudioDriverProperties adProps;
memset(&adProps, 0, sizeof(adProps));
@@ -68,6 +71,7 @@ int GpMain::Run()
memset(&fontProps, 0, sizeof(fontProps));
fontProps.m_type = g_gpGlobalConfig.m_fontHandlerType;
+ fontProps.m_alloc = g_gpGlobalConfig.m_allocator;
// The sample rate used in all of Glider PRO's sound is 0x56ee8ba3
// This appears to be the "standard" Mac sample rate, probably rounded from 244800/11.
@@ -80,8 +84,9 @@ int GpMain::Run()
#endif
adProps.m_logger = g_gpGlobalConfig.m_logger;
adProps.m_systemServices = g_gpGlobalConfig.m_systemServices;
+ adProps.m_alloc = g_gpGlobalConfig.m_allocator;
- IGpInputDriver **inputDrivers = static_cast(malloc(sizeof(IGpInputDriver*) * g_gpGlobalConfig.m_numInputDrivers));
+ IGpInputDriver **inputDrivers = static_cast(alloc->Alloc(sizeof(IGpInputDriver*) * g_gpGlobalConfig.m_numInputDrivers));
size_t numCreatedInputDrivers = 0;
if (inputDrivers)
@@ -93,6 +98,7 @@ int GpMain::Run()
inputProps.m_type = g_gpGlobalConfig.m_inputDriverTypes[i];
inputProps.m_eventQueue = eventQueue;
+ inputProps.m_alloc = g_gpGlobalConfig.m_allocator;
if (IGpInputDriver *driver = GpInputDriverFactory::CreateInputDriver(inputProps))
inputDrivers[numCreatedInputDrivers++] = driver;
@@ -123,7 +129,7 @@ int GpMain::Run()
for (size_t i = 0; i < numCreatedInputDrivers; i++)
inputDrivers[i]->Shutdown();
- free(inputDrivers);
+ alloc->Release(inputDrivers);
}
return 0;
diff --git a/HouseTool/HouseTool.cpp b/HouseTool/HouseTool.cpp
new file mode 100644
index 0000000..4278ad4
--- /dev/null
+++ b/HouseTool/HouseTool.cpp
@@ -0,0 +1,1813 @@
+#include
+#include "PLCore.h"
+#include "PLBigEndian.h"
+#include "MacRomanConversion.h"
+#include "GpUnicode.h"
+#include "WindowsUnicodeToolShim.h"
+
+#include
+
+typedef uint8_t Boolean;
+
+#define kMaxScores 10
+#define kMaxRoomObs 24
+#define kNumTiles 8
+
+// Object types
+
+#define kFloorVent 0x01 // Blowers
+#define kCeilingVent 0x02
+#define kFloorBlower 0x03
+#define kCeilingBlower 0x04
+#define kSewerGrate 0x05
+#define kLeftFan 0x06
+#define kRightFan 0x07
+#define kTaper 0x08
+#define kCandle 0x09
+#define kStubby 0x0A
+#define kTiki 0x0B
+#define kBBQ 0x0C
+#define kInvisBlower 0x0D
+#define kGrecoVent 0x0E
+#define kSewerBlower 0x0F
+#define kLiftArea 0x10
+
+#define kTable 0x11 // Furniture
+#define kShelf 0x12
+#define kCabinet 0x13
+#define kFilingCabinet 0x14
+#define kWasteBasket 0x15
+#define kMilkCrate 0x16
+#define kCounter 0x17
+#define kDresser 0x18
+#define kDeckTable 0x19
+#define kStool 0x1A
+#define kTrunk 0x1B
+#define kInvisObstacle 0x1C
+#define kManhole 0x1D
+#define kBooks 0x1E
+#define kInvisBounce 0x1F
+
+#define kRedClock 0x21 // Prizes
+#define kBlueClock 0x22
+#define kYellowClock 0x23
+#define kCuckoo 0x24
+#define kPaper 0x25
+#define kBattery 0x26
+#define kBands 0x27
+#define kGreaseRt 0x28
+#define kGreaseLf 0x29
+#define kFoil 0x2A
+#define kInvisBonus 0x2B
+#define kStar 0x2C
+#define kSparkle 0x2D
+#define kHelium 0x2E
+#define kSlider 0x2F
+
+#define kUpStairs 0x31 // Transport
+#define kDownStairs 0x32
+#define kMailboxLf 0x33
+#define kMailboxRt 0x34
+#define kFloorTrans 0x35
+#define kCeilingTrans 0x36
+#define kDoorInLf 0x37
+#define kDoorInRt 0x38
+#define kDoorExRt 0x39
+#define kDoorExLf 0x3A
+#define kWindowInLf 0x3B
+#define kWindowInRt 0x3C
+#define kWindowExRt 0x3D
+#define kWindowExLf 0x3E
+#define kInvisTrans 0x3F
+#define kDeluxeTrans 0x40
+
+#define kLightSwitch 0x41 // Switches
+#define kMachineSwitch 0x42
+#define kThermostat 0x43
+#define kPowerSwitch 0x44
+#define kKnifeSwitch 0x45
+#define kInvisSwitch 0x46
+#define kTrigger 0x47
+#define kLgTrigger 0x48
+#define kSoundTrigger 0x49
+
+#define kCeilingLight 0x51 // Lights
+#define kLightBulb 0x52
+#define kTableLamp 0x53
+#define kHipLamp 0x54
+#define kDecoLamp 0x55
+#define kFlourescent 0x56
+#define kTrackLight 0x57
+#define kInvisLight 0x58
+
+#define kShredder 0x61 // Appliances
+#define kToaster 0x62
+#define kMacPlus 0x63
+#define kGuitar 0x64
+#define kTV 0x65
+#define kCoffee 0x66
+#define kOutlet 0x67
+#define kVCR 0x68
+#define kStereo 0x69
+#define kMicrowave 0x6A
+#define kCinderBlock 0x6B
+#define kFlowerBox 0x6C
+#define kCDs 0x6D
+#define kCustomPict 0x6E
+
+#define kBalloon 0x71 // Enemies
+#define kCopterLf 0x72
+#define kCopterRt 0x73
+#define kDartLf 0x74
+#define kDartRt 0x75
+#define kBall 0x76
+#define kDrip 0x77
+#define kFish 0x78
+#define kCobweb 0x79
+
+#define kOzma 0x81 // Clutter
+#define kMirror 0x82
+#define kMousehole 0x83
+#define kFireplace 0x84
+#define kFlower 0x85
+#define kWallWindow 0x86
+#define kBear 0x87
+#define kCalendar 0x88
+#define kVase1 0x89
+#define kVase2 0x8A
+#define kBulletin 0x8B
+#define kCloud 0x8C
+#define kFaucet 0x8D
+#define kRug 0x8E
+#define kChimes 0x8F
+
+
+struct EnumDef
+{
+ int m_value;
+ const char *m_name;
+};
+
+struct Bool8
+{
+ uint8_t m_value;
+};
+
+template
+struct StaticArray
+{
+ static const int kSize = TSize;
+
+ T m_data[TSize];
+};
+
+
+template
+struct PascalStr
+{
+ static const int kSize = TSize;
+
+ uint8_t m_length;
+ uint8_t m_chars[TSize];
+};
+
+typedef PascalStr<15> PStr15_t;
+typedef PascalStr<27> PStr27_t;
+typedef PascalStr<31> PStr31_t;
+typedef PascalStr<255> PStr255_t;
+
+
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t distance; // 2
+ Bool8 initial; // 1
+ Bool8 state; // 1 F. lf. dn. rt. up
+ uint8_t vector; // 1 | x | x | x | x | 8 | 4 | 2 | 1 |
+ uint8_t tall; // 1
+} blowerType; // total = 10
+
+typedef struct
+{
+ BERect bounds; // 8
+ BEInt16_t pict; // 2
+} furnitureType; // total = 10
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t length; // 2 grease spill
+ BEInt16_t points; // 2 invis bonus
+ Bool8 state; // 1
+ Bool8 initial; // 1
+} bonusType; // total = 10
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t tall; // 2 invis transport
+ BEInt16_t where; // 2
+ uint8_t who; // 1
+ uint8_t wide; // 1
+} transportType; // total = 10
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t delay; // 2
+ BEInt16_t where; // 2
+ uint8_t who; // 1
+ uint8_t type; // 1
+} switchType; // total = 10
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t length; // 2
+ uint8_t byte0; // 1
+ uint8_t byte1; // 1
+ Bool8 initial; // 1
+ Bool8 state; // 1
+} lightType; // total = 10
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t height; // 2 toaster, pict ID
+ uint8_t byte0; // 1
+ uint8_t delay; // 1
+ Bool8 initial; // 1
+ Bool8 state; // 1
+} applianceType; // total = 10
+
+typedef struct
+{
+ BEPoint topLeft; // 4
+ BEInt16_t length; // 2
+ uint8_t delay; // 1
+ uint8_t byte0; // 1
+ Bool8 initial; // 1
+ Bool8 state; // 1
+} enemyType; // total = 10
+
+typedef struct
+{
+ BERect bounds; // 8
+ BEInt16_t pict; // 2
+} clutterType; // total = 10
+
+struct objectType
+{
+ union u
+ {
+ blowerType a;
+ furnitureType b;
+ bonusType c;
+ transportType d;
+ switchType e;
+ lightType f;
+ applianceType g;
+ enemyType h;
+ clutterType i;
+ StaticArray pad;
+
+ u();
+ u(const u &other);
+ ~u();
+ };
+
+ BEInt16_t what; // 2
+ u data; // 10
+}; // total = 12
+
+objectType::u::u()
+{
+ static_assert(sizeof(*this) == 10, "Wrong size");
+}
+
+objectType::u::~u()
+{
+}
+
+objectType::u::u(const u &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+
+typedef objectType *objectPtr;
+
+typedef struct
+{
+ PStr31_t banner; // 32 = 32
+ StaticArray names; // 16 * 10 = 160
+ StaticArray scores; // 4 * 10 = 40
+ StaticArray timeStamps; // 4 * 10 = 40
+ StaticArray levels; // 2 * 10 = 20
+} scoresType; // total = 292
+
+typedef struct
+{
+ BEInt16_t version; // 2
+ BEInt16_t wasStarsLeft; // 2
+ BEUInt32_t timeStamp; // 4
+ BEPoint where; // 4
+ BEInt32_t score; // 4
+ BEInt32_t unusedLong; // 4
+ BEInt32_t unusedLong2; // 4
+ BEInt16_t energy; // 2
+ BEInt16_t bands; // 2
+ BEInt16_t roomNumber; // 2
+ BEInt16_t gliderState; // 2
+ BEInt16_t numGliders; // 2
+ BEInt16_t foil; // 2
+ BEInt16_t unusedShort; // 2
+ Bool8 facing; // 1
+ Bool8 showFoil; // 1
+} gameType; // total = 40
+
+typedef struct
+{
+ BEInt16_t unusedShort; // 2
+ uint8_t unusedByte; // 1
+ Bool8 visited; // 1
+ objectType objects[kMaxRoomObs]; // 24 * 12
+} savedRoom, *saveRoomPtr; // total = 292
+
+typedef struct
+{
+ PStr27_t name; // 28
+ BEInt16_t bounds; // 2
+ uint8_t leftStart; // 1
+ uint8_t rightStart; // 1
+ uint8_t unusedByte; // 1
+ Bool8 visited; // 1
+ BEInt16_t background; // 2
+ StaticArray tiles; // 2 * 8
+ BEInt16_t floor, suite; // 2 + 2
+ BEInt16_t openings; // 2
+ BEInt16_t numObjects; // 2
+ StaticArray objects; // 24 * 12
+} roomType, *roomPtr; // total = 348
+
+struct houseType
+{
+ BEInt16_t version; // 2
+ BEInt16_t unusedShort; // 2
+ BEInt32_t timeStamp; // 4
+ BEInt32_t flags; // 4 (bit 0 = wardBit)
+ BEPoint initial; // 4
+ PStr255_t banner; // 256
+ PStr255_t trailer; // 256
+ scoresType highScores; // 292
+ gameType savedGame_Unused; // 40
+ Bool8 hasGame; // 1
+ Bool8 unusedBoolean; // 1
+ BEInt16_t firstRoom; // 2
+ BEInt16_t nRooms; // 2
+
+ static const size_t kBinaryDataSize = 866;
+};
+
+static const size_t houseSize = sizeof(houseType);
+
+#define ENUM_VALUE_DEF(k) { k, #k }
+
+EnumDef g_objectTypeEnum[] =
+{
+ { -1, "kObjectIsEmpty" },
+ ENUM_VALUE_DEF(kFloorVent),
+ ENUM_VALUE_DEF(kCeilingVent),
+ ENUM_VALUE_DEF(kFloorBlower),
+ ENUM_VALUE_DEF(kCeilingBlower),
+ ENUM_VALUE_DEF(kSewerGrate),
+ ENUM_VALUE_DEF(kLeftFan),
+ ENUM_VALUE_DEF(kRightFan),
+ ENUM_VALUE_DEF(kTaper),
+ ENUM_VALUE_DEF(kCandle),
+ ENUM_VALUE_DEF(kStubby),
+ ENUM_VALUE_DEF(kTiki),
+ ENUM_VALUE_DEF(kBBQ),
+ ENUM_VALUE_DEF(kInvisBlower),
+ ENUM_VALUE_DEF(kGrecoVent),
+ ENUM_VALUE_DEF(kSewerBlower),
+ ENUM_VALUE_DEF(kLiftArea),
+ ENUM_VALUE_DEF(kTable),
+ ENUM_VALUE_DEF(kShelf),
+ ENUM_VALUE_DEF(kCabinet),
+ ENUM_VALUE_DEF(kFilingCabinet),
+ ENUM_VALUE_DEF(kWasteBasket),
+ ENUM_VALUE_DEF(kMilkCrate),
+ ENUM_VALUE_DEF(kCounter),
+ ENUM_VALUE_DEF(kDresser),
+ ENUM_VALUE_DEF(kDeckTable),
+ ENUM_VALUE_DEF(kStool),
+ ENUM_VALUE_DEF(kTrunk),
+ ENUM_VALUE_DEF(kInvisObstacle),
+ ENUM_VALUE_DEF(kManhole),
+ ENUM_VALUE_DEF(kBooks),
+ ENUM_VALUE_DEF(kInvisBounce),
+ ENUM_VALUE_DEF(kRedClock),
+ ENUM_VALUE_DEF(kBlueClock),
+ ENUM_VALUE_DEF(kYellowClock),
+ ENUM_VALUE_DEF(kCuckoo),
+ ENUM_VALUE_DEF(kPaper),
+ ENUM_VALUE_DEF(kBattery),
+ ENUM_VALUE_DEF(kBands),
+ ENUM_VALUE_DEF(kGreaseRt),
+ ENUM_VALUE_DEF(kGreaseLf),
+ ENUM_VALUE_DEF(kFoil),
+ ENUM_VALUE_DEF(kInvisBonus),
+ ENUM_VALUE_DEF(kStar),
+ ENUM_VALUE_DEF(kSparkle),
+ ENUM_VALUE_DEF(kHelium),
+ ENUM_VALUE_DEF(kSlider),
+ ENUM_VALUE_DEF(kUpStairs),
+ ENUM_VALUE_DEF(kDownStairs),
+ ENUM_VALUE_DEF(kMailboxLf),
+ ENUM_VALUE_DEF(kMailboxRt),
+ ENUM_VALUE_DEF(kFloorTrans),
+ ENUM_VALUE_DEF(kCeilingTrans),
+ ENUM_VALUE_DEF(kDoorInLf),
+ ENUM_VALUE_DEF(kDoorInRt),
+ ENUM_VALUE_DEF(kDoorExRt),
+ ENUM_VALUE_DEF(kDoorExLf),
+ ENUM_VALUE_DEF(kWindowInLf),
+ ENUM_VALUE_DEF(kWindowInRt),
+ ENUM_VALUE_DEF(kWindowExRt),
+ ENUM_VALUE_DEF(kWindowExLf),
+ ENUM_VALUE_DEF(kInvisTrans),
+ ENUM_VALUE_DEF(kDeluxeTrans),
+ ENUM_VALUE_DEF(kLightSwitch),
+ ENUM_VALUE_DEF(kMachineSwitch),
+ ENUM_VALUE_DEF(kThermostat),
+ ENUM_VALUE_DEF(kPowerSwitch),
+ ENUM_VALUE_DEF(kKnifeSwitch),
+ ENUM_VALUE_DEF(kInvisSwitch),
+ ENUM_VALUE_DEF(kTrigger),
+ ENUM_VALUE_DEF(kLgTrigger),
+ ENUM_VALUE_DEF(kSoundTrigger),
+ ENUM_VALUE_DEF(kCeilingLight),
+ ENUM_VALUE_DEF(kLightBulb),
+ ENUM_VALUE_DEF(kTableLamp),
+ ENUM_VALUE_DEF(kHipLamp),
+ ENUM_VALUE_DEF(kDecoLamp),
+ ENUM_VALUE_DEF(kFlourescent),
+ ENUM_VALUE_DEF(kTrackLight),
+ ENUM_VALUE_DEF(kInvisLight),
+ ENUM_VALUE_DEF(kShredder),
+ ENUM_VALUE_DEF(kToaster),
+ ENUM_VALUE_DEF(kMacPlus),
+ ENUM_VALUE_DEF(kGuitar),
+ ENUM_VALUE_DEF(kTV),
+ ENUM_VALUE_DEF(kCoffee),
+ ENUM_VALUE_DEF(kOutlet),
+ ENUM_VALUE_DEF(kVCR),
+ ENUM_VALUE_DEF(kStereo),
+ ENUM_VALUE_DEF(kMicrowave),
+ ENUM_VALUE_DEF(kCinderBlock),
+ ENUM_VALUE_DEF(kFlowerBox),
+ ENUM_VALUE_DEF(kCDs),
+ ENUM_VALUE_DEF(kCustomPict),
+ ENUM_VALUE_DEF(kBalloon),
+ ENUM_VALUE_DEF(kCopterLf),
+ ENUM_VALUE_DEF(kCopterRt),
+ ENUM_VALUE_DEF(kDartLf),
+ ENUM_VALUE_DEF(kDartRt),
+ ENUM_VALUE_DEF(kBall),
+ ENUM_VALUE_DEF(kDrip),
+ ENUM_VALUE_DEF(kFish),
+ ENUM_VALUE_DEF(kCobweb),
+ ENUM_VALUE_DEF(kOzma),
+ ENUM_VALUE_DEF(kMirror),
+ ENUM_VALUE_DEF(kMousehole),
+ ENUM_VALUE_DEF(kFireplace),
+ ENUM_VALUE_DEF(kFlower),
+ ENUM_VALUE_DEF(kWallWindow),
+ ENUM_VALUE_DEF(kBear),
+ ENUM_VALUE_DEF(kCalendar),
+ ENUM_VALUE_DEF(kVase1),
+ ENUM_VALUE_DEF(kVase2),
+ ENUM_VALUE_DEF(kBulletin),
+ ENUM_VALUE_DEF(kCloud),
+ ENUM_VALUE_DEF(kFaucet),
+ ENUM_VALUE_DEF(kRug),
+ ENUM_VALUE_DEF(kChimes),
+};
+
+const size_t g_objectTypeEnumSize = sizeof(g_objectTypeEnum) / sizeof(g_objectTypeEnum[0]);
+
+
+struct IDataVisitor
+{
+ virtual IDataVisitor *EnterIndex(int index) = 0;
+ virtual IDataVisitor *EnterNamed(const char *name) = 0;
+ virtual void Exit() = 0;
+
+ virtual void VisitLPStr(uint8_t &length, uint8_t *chars, int capacity) = 0;
+ virtual void VisitInt32(int32_t &v) = 0;
+ virtual void VisitUInt32(uint32_t &v) = 0;
+ virtual void VisitInt16(int16_t &v) = 0;
+ virtual void VisitBool8(uint8_t &v) = 0;
+ virtual void VisitByte(uint8_t &v) = 0;
+ virtual bool VisitEnum(const EnumDef *enumDefs, size_t numDefs, int &v) = 0;
+
+ virtual bool VisitStaticCapacity(size_t size) = 0;
+ virtual void VisitDynamicCapacity(size_t &size) = 0;
+};
+
+bool VisitEnum(const EnumDef *enumDefs, size_t numDefs, IDataVisitor *visitor);
+
+void Visit(roomType &v, IDataVisitor *visitor);
+void Visit(objectType &v, IDataVisitor *visitor);
+void Visit(blowerType &v, IDataVisitor *visitor);
+void Visit(furnitureType &v, IDataVisitor *visitor);
+void Visit(bonusType &v, IDataVisitor *visitor);
+void Visit(transportType &v, IDataVisitor *visitor);
+void Visit(switchType &v, IDataVisitor *visitor);
+void Visit(lightType &v, IDataVisitor *visitor);
+void Visit(applianceType &v, IDataVisitor *visitor);
+void Visit(enemyType &v, IDataVisitor *visitor);
+void Visit(clutterType &v, IDataVisitor *visitor);
+void Visit(scoresType &v, IDataVisitor *visitor);
+void Visit(gameType &v, IDataVisitor *visitor);
+void Visit(Bool8 &v, IDataVisitor *visitor);
+void Visit(uint8_t &v, IDataVisitor *visitor);
+void Visit(BEInt16_t &v, IDataVisitor *visitor);
+void Visit(BEInt32_t &v, IDataVisitor *visitor);
+void Visit(BEUInt32_t &v, IDataVisitor *visitor);
+void Visit(BEPoint &v, IDataVisitor *visitor);
+void Visit(BERect &v, IDataVisitor *visitor);
+
+template
+void Visit(PascalStr &pstr, IDataVisitor *visitor)
+{
+ visitor->VisitLPStr(pstr.m_length, pstr.m_chars, TSize);
+}
+
+template
+void Visit(StaticArray &arr, IDataVisitor *visitor)
+{
+ if (!visitor->VisitStaticCapacity(TSize))
+ return;
+
+ for (int i = 0; i < TSize; i++)
+ {
+ IDataVisitor *subscriptVisitor = visitor->EnterIndex(i);
+ if (subscriptVisitor)
+ {
+ Visit(arr.m_data[i], visitor);
+ subscriptVisitor->Exit();
+ }
+ }
+}
+
+template
+void VisitField(const char *subscriptName, T &subscript, IDataVisitor *visitor)
+{
+ IDataVisitor *subscriptVisitor = visitor->EnterNamed(subscriptName);
+ if (subscriptVisitor)
+ {
+ Visit(subscript, visitor);
+ subscriptVisitor->Exit();
+ }
+}
+
+template
+void VisitArray(T *arr, int size, IDataVisitor *visitor)
+{
+ if (!visitor->VisitStaticCapacity(static_cast(size)))
+ return;
+
+ for (int i = 0; i < size; i++)
+ {
+ IDataVisitor *subscriptVisitor = visitor->EnterIndex(i);
+ if (subscriptVisitor)
+ {
+ Visit(arr[i], visitor);
+ subscriptVisitor->Exit();
+ }
+ }
+}
+
+
+bool VisitEnum(const EnumDef *enumDefs, size_t numDefs, int &v, IDataVisitor *visitor)
+{
+ return visitor->VisitEnum(enumDefs, numDefs, v);
+}
+
+void Visit(houseType &house, std::vector &rooms, IDataVisitor *visitor)
+{
+ VisitField("version", house.version, visitor);
+ VisitField("unusedShort", house.unusedShort, visitor);
+ VisitField("timeStamp", house.timeStamp, visitor);
+ VisitField("flags", house.flags, visitor);
+ VisitField("initial", house.initial, visitor);
+ VisitField("banner", house.banner, visitor);
+ VisitField("trailer", house.trailer, visitor);
+ VisitField("highScores", house.highScores, visitor);
+ VisitField("savedGame", house.savedGame_Unused, visitor);
+ VisitField("hasGame", house.hasGame, visitor);
+ VisitField("unusedBoolean", house.unusedBoolean, visitor);
+ VisitField("firstRoom", house.firstRoom, visitor);
+ VisitField("nRooms", house.nRooms, visitor);
+
+ IDataVisitor *roomsSubscript = visitor->EnterNamed("rooms");
+ if (roomsSubscript)
+ {
+ size_t size = rooms.size();
+ roomsSubscript->VisitDynamicCapacity(size);
+
+ if (size > 0x7fff)
+ size = 0x7fff;
+
+ if (size < rooms.size())
+ rooms.resize(size);
+ else if (size > rooms.size())
+ {
+ roomType emptyRoom;
+ memset(&emptyRoom, 0, sizeof(emptyRoom));
+
+ rooms.reserve(size);
+ while (size > rooms.size())
+ rooms.push_back(emptyRoom);
+ }
+
+ house.nRooms = static_cast(size);
+
+ for (size_t i = 0; i < size; i++)
+ {
+ IDataVisitor *roomSubscript = roomsSubscript->EnterIndex(static_cast(i));
+ if (roomSubscript)
+ {
+ Visit(rooms[i], roomSubscript);
+ roomSubscript->Exit();
+ }
+ }
+
+ roomsSubscript->Exit();
+ }
+}
+
+void Visit(blowerType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("distance", v.distance, visitor);
+ VisitField("initial", v.initial, visitor);
+ VisitField("state", v.state, visitor);
+ VisitField("vector", v.vector, visitor);
+ VisitField("tall", v.tall, visitor);
+}
+
+void Visit(furnitureType &v, IDataVisitor *visitor)
+{
+ VisitField("bounds", v.bounds, visitor);
+ VisitField("pict", v.pict, visitor);
+}
+
+void Visit(bonusType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("length", v.length, visitor);
+ VisitField("points", v.points, visitor);
+ VisitField("state", v.state, visitor);
+ VisitField("initial", v.initial, visitor);
+}
+
+void Visit(transportType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("tall", v.tall, visitor);
+ VisitField("where", v.where, visitor);
+ VisitField("who", v.who, visitor);
+ VisitField("wide", v.wide, visitor);
+}
+
+void Visit(switchType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("delay", v.delay, visitor);
+ VisitField("where", v.where, visitor);
+ VisitField("who", v.who, visitor);
+ VisitField("type", v.type, visitor);
+}
+
+void Visit(lightType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("length", v.length, visitor);
+ VisitField("byte0", v.byte0, visitor);
+ VisitField("byte1", v.byte1, visitor);
+ VisitField("initial", v.initial, visitor);
+ VisitField("state", v.state, visitor);
+}
+
+void Visit(applianceType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("height", v.height, visitor);
+ VisitField("byte0", v.byte0, visitor);
+ VisitField("delay", v.delay, visitor);
+ VisitField("initial", v.initial, visitor);
+ VisitField("state", v.state, visitor);
+}
+
+void Visit(enemyType &v, IDataVisitor *visitor)
+{
+ VisitField("topLeft", v.topLeft, visitor);
+ VisitField("length", v.length, visitor);
+ VisitField("delay", v.delay, visitor);
+ VisitField("byte0", v.byte0, visitor);
+ VisitField("initial", v.initial, visitor);
+ VisitField("state", v.state, visitor);
+}
+
+void Visit(clutterType &v, IDataVisitor *visitor)
+{
+ VisitField("bounds", v.bounds, visitor);
+ VisitField("pict", v.pict, visitor);
+}
+
+void Visit(objectType &v, IDataVisitor *visitor)
+{
+ IDataVisitor *whatVisitor = visitor->EnterNamed("what");
+ if (whatVisitor)
+ {
+ int ev = v.what;
+ if (!VisitEnum(g_objectTypeEnum, g_objectTypeEnumSize, ev, visitor))
+ Visit(v.what, visitor);
+ whatVisitor->Exit();
+ }
+
+ switch (static_cast(v.what))
+ {
+ default:
+ //VisitField("pad", v.data.pad, visitor);
+ break;
+
+ case kFloorVent:
+ case kCeilingVent:
+ case kFloorBlower:
+ case kCeilingBlower:
+ case kSewerGrate:
+ case kLeftFan:
+ case kRightFan:
+ case kTaper:
+ case kCandle:
+ case kStubby:
+ case kTiki:
+ case kBBQ:
+ case kInvisBlower:
+ case kGrecoVent:
+ case kSewerBlower:
+ case kLiftArea:
+ Visit(v.data.a, visitor);
+ break;
+
+ case kTable:
+ case kShelf:
+ case kCabinet:
+ case kFilingCabinet:
+ case kWasteBasket:
+ case kMilkCrate:
+ case kCounter:
+ case kDresser:
+ case kDeckTable:
+ case kStool:
+ case kTrunk:
+ case kInvisObstacle:
+ case kManhole:
+ case kBooks:
+ case kInvisBounce:
+ Visit(v.data.b, visitor);
+ break;
+
+ case kRedClock:
+ case kBlueClock:
+ case kYellowClock:
+ case kCuckoo:
+ case kPaper:
+ case kBattery:
+ case kBands:
+ case kGreaseRt:
+ case kGreaseLf:
+ case kFoil:
+ case kInvisBonus:
+ case kStar:
+ case kSparkle:
+ case kHelium:
+ case kSlider:
+ Visit(v.data.c, visitor);
+ break;
+
+ case kUpStairs:
+ case kDownStairs:
+ case kMailboxLf:
+ case kMailboxRt:
+ case kFloorTrans:
+ case kCeilingTrans:
+ case kDoorInLf:
+ case kDoorInRt:
+ case kDoorExRt:
+ case kDoorExLf:
+ case kWindowInLf:
+ case kWindowInRt:
+ case kWindowExRt:
+ case kWindowExLf:
+ case kInvisTrans:
+ case kDeluxeTrans:
+ Visit(v.data.d, visitor);
+ break;
+
+ case kLightSwitch:
+ case kMachineSwitch:
+ case kThermostat:
+ case kPowerSwitch:
+ case kKnifeSwitch:
+ case kInvisSwitch:
+ case kTrigger:
+ case kLgTrigger:
+ case kSoundTrigger:
+ Visit(v.data.e, visitor);
+ break;
+
+ case kCeilingLight:
+ case kLightBulb:
+ case kTableLamp:
+ case kHipLamp:
+ case kDecoLamp:
+ case kFlourescent:
+ case kTrackLight:
+ case kInvisLight:
+ Visit(v.data.f, visitor);
+ break;
+
+ case kShredder:
+ case kToaster:
+ case kMacPlus:
+ case kGuitar:
+ case kTV:
+ case kCoffee:
+ case kOutlet:
+ case kVCR:
+ case kStereo:
+ case kMicrowave:
+ case kCinderBlock:
+ case kFlowerBox:
+ case kCDs:
+ case kCustomPict:
+ Visit(v.data.g, visitor);
+ break;
+
+ case kBalloon:
+ case kCopterLf:
+ case kCopterRt:
+ case kDartLf:
+ case kDartRt:
+ case kBall:
+ case kDrip:
+ case kFish:
+ case kCobweb:
+ Visit(v.data.h, visitor);
+ break;
+
+ case kOzma:
+ case kMirror:
+ case kMousehole:
+ case kFireplace:
+ case kFlower:
+ case kWallWindow:
+ case kBear:
+ case kCalendar:
+ case kVase1:
+ case kVase2:
+ case kBulletin:
+ case kCloud:
+ case kFaucet:
+ case kRug:
+ case kChimes:
+ Visit(v.data.i, visitor);
+ break;
+ }
+}
+
+void Visit(roomType &v, IDataVisitor *visitor)
+{
+ VisitField("name", v.name, visitor);
+ VisitField("bounds", v.bounds, visitor);
+ VisitField("leftStart", v.leftStart, visitor);
+ VisitField("rightStart", v.rightStart, visitor);
+ VisitField("unusedByte", v.unusedByte, visitor);
+ VisitField("visited", v.visited, visitor);
+ VisitField("background", v.background, visitor);
+ VisitField("tiles", v.tiles, visitor);
+ VisitField("floor", v.floor, visitor);
+ VisitField("suite", v.suite, visitor);
+ VisitField("openings", v.openings, visitor);
+ VisitField("numObjects", v.numObjects, visitor);
+ VisitField("objects", v.objects, visitor);
+}
+
+void Visit(scoresType &v, IDataVisitor *visitor)
+{
+ VisitField("banner", v.banner, visitor);
+ VisitField("names", v.names, visitor);
+ VisitField("scores", v.scores, visitor);
+ VisitField("timeStamps", v.timeStamps, visitor);
+ VisitField("levels", v.levels, visitor);
+}
+
+void Visit(gameType &v, IDataVisitor *visitor)
+{
+ VisitField("version", v.version, visitor);
+ VisitField("starsLeft", v.wasStarsLeft, visitor);
+ VisitField("timeStamp", v.timeStamp, visitor);
+ VisitField("where", v.where, visitor);
+ VisitField("score", v.score, visitor);
+ VisitField("unusedLong", v.unusedLong, visitor);
+ VisitField("unusedLong2", v.unusedLong2, visitor);
+ VisitField("energy", v.energy, visitor);
+ VisitField("bands", v.bands, visitor);
+ VisitField("roomNumber", v.roomNumber, visitor);
+ VisitField("gliderState", v.gliderState, visitor);
+ VisitField("numGliders", v.numGliders, visitor);
+ VisitField("foil", v.foil, visitor);
+ VisitField("unusedShort", v.unusedShort, visitor);
+ VisitField("facing", v.facing, visitor);
+ VisitField("showFoil", v.showFoil, visitor);
+}
+
+void Visit(Bool8 &v, IDataVisitor *visitor)
+{
+ visitor->VisitBool8(v.m_value);
+}
+
+void Visit(uint8_t &v, IDataVisitor *visitor)
+{
+ visitor->VisitByte(v);
+}
+
+void Visit(BEInt16_t &v, IDataVisitor *visitor)
+{
+ int16_t vi = v;
+ visitor->VisitInt16(vi);
+ v = vi;
+}
+
+void Visit(BEInt32_t &v, IDataVisitor *visitor)
+{
+ int32_t vi = v;
+ visitor->VisitInt32(vi);
+ v = vi;
+}
+
+void Visit(BEUInt32_t &v, IDataVisitor *visitor)
+{
+ uint32_t vi = v;
+ visitor->VisitUInt32(vi);
+ v = vi;
+}
+
+void Visit(BEPoint &v, IDataVisitor *visitor)
+{
+ VisitField("h", v.h, visitor);
+ VisitField("v", v.v, visitor);
+}
+
+void Visit(BERect &v, IDataVisitor *visitor)
+{
+ VisitField("top", v.top, visitor);
+ VisitField("left", v.left, visitor);
+ VisitField("bottom", v.bottom, visitor);
+ VisitField("right", v.right, visitor);
+}
+
+int PrintUsage()
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "HouseTool decompile \n");
+ fprintf(stderr, "HouseTool patch \n");
+ return -1;
+}
+
+bool ReadHouseFromPath(const char *path, houseType &house, std::vector &rooms)
+{
+ FILE *f = fopen_utf8(path, "rb");
+ if (!f)
+ return false;
+
+ if (fread(&house, 1, houseType::kBinaryDataSize, f) != houseType::kBinaryDataSize)
+ {
+ fclose(f);
+ return false;
+ }
+
+ int16_t nRooms = house.nRooms;
+ if (nRooms < 0)
+ {
+ fclose(f);
+ return false;
+ }
+
+ rooms.resize(nRooms);
+
+ if (nRooms > 0)
+ {
+ if (fread(&rooms[0], 1, sizeof(roomType) * nRooms, f) != sizeof(roomType) * nRooms)
+ {
+ rooms.clear();
+ fclose(f);
+ return false;
+ }
+ }
+
+ fclose(f);
+ return true;
+}
+
+
+class PatchVisitor final : public IDataVisitor
+{
+public:
+ PatchVisitor(const char *scope, const char *replacementValue);
+
+ IDataVisitor *EnterIndex(int index) override;
+ IDataVisitor *EnterNamed(const char *name) override;
+ void Exit() override;
+
+ void VisitLPStr(uint8_t &length, uint8_t *chars, int capacity) override;
+ void VisitInt32(int32_t &v) override;
+ void VisitUInt32(uint32_t &v) override;
+ void VisitInt16(int16_t &v) override;
+ void VisitBool8(uint8_t &v) override;
+ void VisitByte(uint8_t &v) override;
+ bool VisitEnum(const EnumDef *enumDefs, size_t numDefs, int &v) override;
+
+ bool VisitStaticCapacity(size_t size) override;
+ void VisitDynamicCapacity(size_t &size) override;
+
+ bool PatchedOK() const;
+
+private:
+ static bool DecodeInteger(const std::string &scopeStr, size_t startPos, int &outInteger, size_t &outEndPos);
+ static bool DecodeQuotedString(const std::string &scopeStr, size_t startPos, std::string &outStr, size_t &outEndPos);
+
+ std::string m_scope;
+ std::string m_nextScope;
+ int m_scopeInteger;
+ bool m_nextScopeIsInteger;
+ const char *m_replacementValue;
+
+ void EnterScope();
+ bool TryEnterScope();
+
+ bool m_isDone;
+ bool m_haveScope;
+ bool m_patchedOK;
+};
+
+PatchVisitor::PatchVisitor(const char *scope, const char *replacementValue)
+ : m_scopeInteger(0)
+ , m_nextScopeIsInteger(false)
+ , m_replacementValue(replacementValue)
+ , m_nextScope(scope)
+ , m_isDone(false)
+ , m_haveScope(true)
+ , m_patchedOK(false)
+{
+ EnterScope();
+}
+
+IDataVisitor *PatchVisitor::EnterIndex(int index)
+{
+ if (m_isDone || !m_haveScope || !m_nextScopeIsInteger)
+ return nullptr;
+
+ if (m_scopeInteger == index)
+ {
+ EnterScope();
+ return this;
+ }
+
+ return nullptr;
+}
+
+IDataVisitor *PatchVisitor::EnterNamed(const char *name)
+{
+ if (m_isDone || !m_haveScope || m_nextScopeIsInteger)
+ return nullptr;
+
+ if (m_scope == name)
+ {
+ EnterScope();
+ return this;
+ }
+
+ return nullptr;
+}
+
+void PatchVisitor::Exit()
+{
+ m_isDone = true;
+}
+
+void PatchVisitor::VisitLPStr(uint8_t &length, uint8_t *chars, int capacity)
+{
+ if (m_isDone || m_haveScope)
+ return;
+
+ const uint8_t *replacementUTF8 = reinterpret_cast(m_replacementValue);
+ size_t rLen = strlen(m_replacementValue);
+
+ length = 0;
+ while (rLen > 0)
+ {
+ uint32_t codePoint = 0;
+ size_t charsDigested = 0;
+ if (!GpUnicode::UTF8::Decode(replacementUTF8, rLen, charsDigested, codePoint))
+ break;
+
+ rLen -= charsDigested;
+ replacementUTF8 += charsDigested;
+
+ uint8_t macRomanChar = 0;
+ if (codePoint > 0xffff)
+ macRomanChar = '?';
+ else
+ {
+ if (!MacRoman::FromUnicode(macRomanChar, static_cast(codePoint)))
+ macRomanChar = '?';
+ }
+
+ chars[length++] = macRomanChar;
+ if (length == capacity)
+ break;
+ }
+
+ for (int i = length; i < capacity; i++)
+ chars[i] = 0;
+
+ m_patchedOK = true;
+ m_isDone = true;
+}
+
+void PatchVisitor::VisitInt32(int32_t &v)
+{
+ if (m_isDone || m_haveScope)
+ return;
+
+ int integer = 0;
+ if (sscanf(m_replacementValue, "%i", &integer) == 1)
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = integer;
+ }
+}
+
+void PatchVisitor::VisitUInt32(uint32_t &v)
+{
+ if (m_isDone || m_haveScope)
+ return;
+
+ unsigned int integer = 0;
+ if (sscanf(m_replacementValue, "%u", &integer) == 1)
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = integer;
+ }
+}
+
+void PatchVisitor::VisitInt16(int16_t &v)
+{
+ if (m_isDone || m_haveScope)
+ return;
+
+ int integer = 0;
+ if (sscanf(m_replacementValue, "%i", &integer) == 1)
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = integer;
+ }
+}
+
+void PatchVisitor::VisitBool8(uint8_t &v)
+{
+ if (m_isDone || m_haveScope)
+ return;
+
+ if (!strcmp(m_replacementValue, "true"))
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = 1;
+ }
+ else if (!strcmp(m_replacementValue, "false"))
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = 0;
+ }
+ else
+ {
+ int integer = 0;
+ if (sscanf(m_replacementValue, "%i", &integer) == 1)
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = integer;
+ }
+ }
+}
+
+void PatchVisitor::VisitByte(uint8_t &v)
+{
+ if (m_isDone || m_haveScope)
+ return;
+
+ int integer = 0;
+ if (sscanf(m_replacementValue, "%i", &integer) == 1)
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = integer;
+ }
+}
+
+bool PatchVisitor::VisitEnum(const EnumDef *enumDefs, size_t numDefs, int &v)
+{
+ if (m_isDone || m_haveScope)
+ return false;
+
+ for (size_t i = 0; i < numDefs; i++)
+ {
+ if (!strcmp(enumDefs[i].m_name, m_replacementValue))
+ {
+ m_patchedOK = true;
+ m_isDone = true;
+ v = enumDefs[i].m_value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PatchVisitor::VisitStaticCapacity(size_t size)
+{
+ return true;
+}
+
+void PatchVisitor::VisitDynamicCapacity(size_t &size)
+{
+}
+
+bool PatchVisitor::PatchedOK() const
+{
+ return m_patchedOK;
+}
+
+bool PatchVisitor::DecodeInteger(const std::string &scopeStr, size_t startPos, int &outInteger, size_t &outEndPos)
+{
+ size_t len = scopeStr.length();
+
+ if (startPos >= len)
+ return false;
+
+ bool isNegative = false;
+ char firstChar = scopeStr[startPos];
+ if (firstChar == '-')
+ {
+ isNegative = true;
+ startPos++;
+
+ if (startPos >= len)
+ return false;
+ }
+
+ int resultInteger = 0;
+
+ for (size_t i = startPos; i < len; i++)
+ {
+ char decChar = scopeStr[i];
+ if (decChar >= '0' && decChar <= '9')
+ {
+ int digit = decChar - '0';
+ if (isNegative)
+ resultInteger = resultInteger * 10 - digit;
+ else
+ resultInteger = resultInteger * 10 + digit;
+ }
+ else
+ {
+ if (i == startPos)
+ return false;
+
+ outInteger = resultInteger;
+ outEndPos = i;
+ return true;
+ }
+ }
+
+ outInteger = resultInteger;
+ outEndPos = len;
+ return true;
+}
+
+bool PatchVisitor::DecodeQuotedString(const std::string &scopeStr, size_t startPos, std::string &outString, size_t &outEndPos)
+{
+ size_t len = scopeStr.length();
+
+ if (startPos >= len || scopeStr[startPos] != '\"')
+ return false;
+
+ std::vector decoded;
+ for (size_t i = startPos + 1; i < len; i++)
+ {
+ char decChar = scopeStr[i];
+ if (decChar == '\"')
+ {
+ if (decoded.size() == 0)
+ outString = std::string();
+ else
+ outString = std::string(&decoded[0], decoded.size());
+
+ outEndPos = i + 1;
+ return true;
+ }
+
+ if (decChar == '\\')
+ {
+ i++;
+ if (i == len)
+ return false;
+
+ char escChar = scopeStr[i];
+ if (escChar == '\"')
+ decoded.push_back('\"');
+ else if (escChar == '\\')
+ decoded.push_back('\\');
+ else if (escChar == '/')
+ decoded.push_back('/');
+ else if (escChar == 'b')
+ decoded.push_back('\b');
+ else if (escChar == 'f')
+ decoded.push_back('\f');
+ else if (escChar == 'n')
+ decoded.push_back('\n');
+ else if (escChar == 'r')
+ decoded.push_back('\r');
+ else if (escChar == 't')
+ decoded.push_back('\t');
+ else if (escChar == 'u')
+ {
+ int nibbles[4];
+ for (int ni = 0; ni < 4; ni++)
+ {
+ i++;
+ if (i == len)
+ return false;
+
+ char nibbleChar = scopeStr[i];
+ if (nibbleChar >= '0' && nibbleChar <= '9')
+ nibbles[ni] = nibbleChar - '0';
+ else if (nibbleChar >= 'A' && nibbleChar <= 'F')
+ nibbles[ni] = nibbleChar - 'A' + 0xa;
+ else if (nibbleChar >= 'a' && nibbleChar <= 'f')
+ nibbles[ni] = nibbleChar - 'a' + 0xa;
+ else
+ return false;
+ }
+
+ const uint16_t unicodeCodePoint = (nibbles[0] << 12) + (nibbles[1] << 8) + (nibbles[2] << 4) + nibbles[3];
+ uint8_t encoded[GpUnicode::UTF8::kMaxEncodedBytes];
+ size_t emitted = 0;
+ GpUnicode::UTF8::Encode(encoded, emitted, unicodeCodePoint);
+
+ for (size_t ei = 0; ei < emitted; ei++)
+ decoded.push_back(static_cast(encoded[ei]));
+ }
+ }
+ else
+ {
+ if (decChar < ' ' || decChar > '~')
+ return false;
+
+ decoded.push_back(decChar);
+ }
+ }
+
+ outEndPos = len;
+ return false;
+}
+
+void PatchVisitor::EnterScope()
+{
+ if (!m_haveScope)
+ {
+ m_isDone = true;
+ return;
+ }
+
+ bool shouldHaveScope = (m_nextScope.size() > 0);
+ if (!shouldHaveScope)
+ {
+ m_haveScope = false;
+ return;
+ }
+
+ if (!TryEnterScope())
+ {
+ m_haveScope = false;
+ m_isDone = true;
+ }
+}
+
+bool PatchVisitor::TryEnterScope()
+{
+ if (m_nextScope.size() == 0)
+ return false;
+
+ if (m_nextScope[0] == '.')
+ {
+ size_t lastFieldChar = 1;
+ while (lastFieldChar < m_nextScope.size())
+ {
+ char c = m_nextScope[lastFieldChar];
+ if ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ || c == '_')
+ lastFieldChar++;
+ else
+ break;
+ }
+
+ if (lastFieldChar == 1)
+ return false;
+
+ m_nextScopeIsInteger = false;
+ m_scope = m_nextScope.substr(1, lastFieldChar - 1);
+ m_nextScope = m_nextScope.substr(lastFieldChar);
+
+ return true;
+ }
+
+ if (m_nextScope[0] == '[')
+ {
+ if (m_nextScope.size() == 1)
+ return false;
+
+ if (m_nextScope[1] == '\"')
+ {
+ std::string quotedStr;
+ size_t endPos = 0;
+ if (!DecodeQuotedString(m_nextScope, 1, quotedStr, endPos))
+ return false;
+
+ if (endPos >= m_nextScope.size())
+ return false;
+
+ if (m_nextScope[endPos] != ']')
+ return false;
+
+ m_nextScopeIsInteger = false;
+ m_scope = quotedStr;
+ m_nextScope = m_nextScope.substr(endPos + 1);
+
+ return true;
+ }
+ else
+ {
+ int integer = 0;
+ size_t endPos = 0;
+ if (!DecodeInteger(m_nextScope, 1, integer, endPos))
+ return false;
+
+ if (endPos >= m_nextScope.size())
+ return false;
+
+ if (m_nextScope[endPos] != ']')
+ return false;
+
+ m_nextScopeIsInteger = true;
+ m_scope = "";
+ m_scopeInteger = integer;
+ m_nextScope = m_nextScope.substr(endPos + 1);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+int PatchMain(int argc, const char **argv)
+{
+ if (argc != 5)
+ return PrintUsage();
+
+ houseType house;
+ std::vector rooms;
+
+ if (!ReadHouseFromPath(argv[2], house, rooms))
+ {
+ fprintf(stderr, "Failed to read house\n");
+ return -1;
+ }
+
+ PatchVisitor patcher(argv[3], argv[4]);
+ Visit(house, rooms, &patcher);
+
+ if (!patcher.PatchedOK())
+ fprintf(stderr, "Patch failed\n");
+ else
+ {
+ FILE *houseOutF = fopen_utf8(argv[2], "wb");
+ if (!houseOutF)
+ {
+ fprintf(stderr, "Failed to open output house\n");
+ return -1;
+ }
+
+ fwrite(&house, 1, houseType::kBinaryDataSize, houseOutF);
+ if (rooms.size() > 0)
+ fwrite(&rooms[0], 1, sizeof(roomType) * rooms.size(), houseOutF);
+
+ fclose(houseOutF);
+ }
+
+ return 0;
+}
+
+class DecompileVisitor final : public IDataVisitor
+{
+public:
+ explicit DecompileVisitor(FILE *f);
+
+ IDataVisitor *EnterIndex(int index) override;
+ IDataVisitor *EnterNamed(const char *name) override;
+ void Exit() override;
+
+ void VisitLPStr(uint8_t &length, uint8_t *chars, int capacity) override;
+ void VisitInt32(int32_t &v) override;
+ void VisitUInt32(uint32_t &v) override;
+ void VisitInt16(int16_t &v) override;
+ void VisitBool8(uint8_t &v) override;
+ void VisitByte(uint8_t &v) override;
+ bool VisitEnum(const EnumDef *enumDefs, size_t numDefs, int &v) override;
+
+ bool VisitStaticCapacity(size_t size) override;
+ void VisitDynamicCapacity(size_t &size) override;
+
+private:
+ enum ScopeType
+ {
+ ScopeType_Array,
+ ScopeType_Map,
+ ScopeType_Unknown,
+ };
+
+ FILE *m_f;
+ int m_indentLevel;
+
+ bool m_isInNamed;
+ bool m_isInArray;
+
+ std::vector m_scopes;
+
+ ScopeType GetTopScope();
+ void SetTopScope(ScopeType scopeType);
+ void PopScope();
+ void PushScope();
+
+ void WriteIndent();
+};
+
+DecompileVisitor::DecompileVisitor(FILE *f)
+ : m_f(f)
+{
+ m_scopes.push_back(ScopeType_Unknown);
+}
+
+IDataVisitor *DecompileVisitor::EnterIndex(int index)
+{
+ ScopeType topScope = GetTopScope();
+ if (topScope == ScopeType_Array)
+ {
+ fprintf(m_f, ",\n");
+ WriteIndent();
+ }
+ else
+ {
+ fprintf(m_f, "[\n");
+ WriteIndent();
+ SetTopScope(ScopeType_Array);
+ }
+
+ PushScope();
+
+ fprintf(m_f, "[%i] = ", index);
+
+ return this;
+}
+
+IDataVisitor *DecompileVisitor::EnterNamed(const char *name)
+{
+ ScopeType topScope = GetTopScope();
+ if (topScope == ScopeType_Map)
+ {
+ fprintf(m_f, ",\n");
+ WriteIndent();
+ }
+ else
+ {
+ fprintf(m_f, "{\n");
+ WriteIndent();
+ SetTopScope(ScopeType_Map);
+ }
+
+ PushScope();
+
+ fprintf(m_f, "%s = ", name);
+
+ return this;
+}
+
+void DecompileVisitor::Exit()
+{
+ ScopeType topScope = GetTopScope();
+ if (topScope == ScopeType_Map)
+ {
+ fprintf(m_f, "\n");
+ PopScope();
+ WriteIndent();
+ fprintf(m_f, "}");
+ }
+ else if (topScope == ScopeType_Array)
+ {
+ fprintf(m_f, "\n");
+ PopScope();
+ WriteIndent();
+ fprintf(m_f, "]");
+ }
+ else
+ PopScope();
+}
+
+
+void DecompileVisitor::VisitLPStr(uint8_t &length, uint8_t *chars, int capacity)
+{
+ fputc('\"', m_f);
+ for (size_t i = 0; i < length; i++)
+ {
+ uint16_t unicodeChar = MacRoman::ToUnicode(chars[i]);
+ if (unicodeChar == '\\')
+ fputs("\\\\", m_f);
+ else if (unicodeChar == '\"')
+ fputs("\\\"", m_f);
+ else if (unicodeChar == '\r')
+ fputs("\\r", m_f);
+ else if (unicodeChar == '\n')
+ fputs("\\n", m_f);
+ else if (unicodeChar < 32 || unicodeChar > 126)
+ fprintf(m_f, "\\u%04x", unicodeChar);
+ else
+ {
+ uint8_t ubyte = static_cast(unicodeChar);
+ fwrite(&ubyte, 1, 1, m_f);
+ }
+ }
+ fputc('\"', m_f);
+}
+
+void DecompileVisitor::VisitInt32(int32_t &v)
+{
+ fprintf(m_f, "%i", static_cast(v));
+}
+
+void DecompileVisitor::VisitUInt32(uint32_t &v)
+{
+ fprintf(m_f, "%u", static_cast(v));
+}
+
+
+void DecompileVisitor::VisitInt16(int16_t &v)
+{
+ fprintf(m_f, "%i", static_cast(v));
+}
+
+void DecompileVisitor::VisitBool8(uint8_t &v)
+{
+ if (v == 0)
+ fprintf(m_f, "false");
+ else if (v == 1)
+ fprintf(m_f, "true");
+ else
+ fprintf(m_f, "%i", static_cast(v));
+}
+
+void DecompileVisitor::VisitByte(uint8_t &v)
+{
+ fprintf(m_f, "%i", static_cast(v));
+}
+
+bool DecompileVisitor::VisitEnum(const EnumDef *enumDefs, size_t numDefs, int &v)
+{
+ for (size_t i = 0; i < numDefs; i++)
+ {
+ if (enumDefs[i].m_value == v)
+ {
+ fprintf(m_f, "\"%s\"", enumDefs[i].m_name);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool DecompileVisitor::VisitStaticCapacity(size_t size)
+{
+ return true;
+}
+
+void DecompileVisitor::VisitDynamicCapacity(size_t &size)
+{
+}
+
+DecompileVisitor::ScopeType DecompileVisitor::GetTopScope()
+{
+ return m_scopes[m_scopes.size() - 1];
+}
+
+void DecompileVisitor::SetTopScope(ScopeType scopeType)
+{
+ m_scopes[m_scopes.size() - 1] = scopeType;
+}
+
+void DecompileVisitor::PopScope()
+{
+ m_scopes.pop_back();
+}
+
+void DecompileVisitor::PushScope()
+{
+ m_scopes.push_back(ScopeType_Unknown);
+}
+
+void DecompileVisitor::WriteIndent()
+{
+ for (size_t i = 0; i < m_scopes.size(); i++)
+ fputc('\t', m_f);
+}
+
+int DecompileMain(int argc, const char **argv)
+{
+ if (argc != 4)
+ return PrintUsage();
+
+ houseType house;
+ std::vector rooms;
+
+ if (!ReadHouseFromPath(argv[2], house, rooms))
+ {
+ fprintf(stderr, "Failed to read house\n");
+ return -1;
+ }
+
+ FILE *outF = fopen_utf8(argv[3], "wb");
+ if (!outF)
+ {
+ fprintf(stderr, "Failed to open output house\n");
+ return -1;
+ }
+
+ DecompileVisitor decompiler(outF);
+ Visit(house, rooms, &decompiler);
+
+ fclose(outF);
+
+ return 0;
+}
+
+int toolMain(int argc, const char **argv)
+{
+ static const size_t houseSize = sizeof(houseType);
+ static_assert(sizeof(houseType) >= houseType::kBinaryDataSize, "House type is too small");
+
+ if (argc < 3)
+ return PrintUsage();
+
+ std::string operation = argv[1];
+
+ if (operation == "patch")
+ return PatchMain(argc, argv);
+
+ if (operation == "decompile")
+ return DecompileMain(argc, argv);
+
+ return 0;
+}
diff --git a/HouseTool/HouseTool.vcxproj b/HouseTool/HouseTool.vcxproj
new file mode 100644
index 0000000..d480288
--- /dev/null
+++ b/HouseTool/HouseTool.vcxproj
@@ -0,0 +1,101 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {B31BFF9D-2D14-4B1A-A625-8348CC3D8D67}
+ HouseTool
+ 10.0.17763.0
+
+
+
+ Application
+ true
+ v141
+ MultiByte
+
+
+ Application
+ false
+ v141
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ true
+
+
+ Console
+ true
+ true
+
+
+
+
+ Level3
+ Disabled
+ true
+ true
+
+
+ Console
+
+
+
+
+
+
+
+ {6ec62b0f-9353-40a4-a510-3788f1368b33}
+
+
+ {15009625-1120-405e-8bba-69a16cd6713d}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HouseTool/HouseTool.vcxproj.filters b/HouseTool/HouseTool.vcxproj.filters
new file mode 100644
index 0000000..84f151a
--- /dev/null
+++ b/HouseTool/HouseTool.vcxproj.filters
@@ -0,0 +1,25 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MergeGPF/MergeGPF.cpp b/MergeGPF/MergeGPF.cpp
index b1ea2fd..783f8e1 100644
--- a/MergeGPF/MergeGPF.cpp
+++ b/MergeGPF/MergeGPF.cpp
@@ -5,6 +5,8 @@
#include "DeflateCodec.h"
#include "MacFileInfo.h"
#include "ZipFile.h"
+#include "GpAllocator_C.h"
+#include "PLDrivers.h"
#include
#include
@@ -12,6 +14,9 @@
int toolMain(int argc, const char **argv)
{
+ GpDriverCollection *drivers = PLDrivers::GetDriverCollection();
+ drivers->SetDriver(GpAllocator_C::GetInstance());
+
if (argc != 2)
{
fprintf(stderr, "Usage: MergeGPF ");
diff --git a/MergeGPF/MergeGPF.vcxproj b/MergeGPF/MergeGPF.vcxproj
index 808798b..bc0571a 100644
--- a/MergeGPF/MergeGPF.vcxproj
+++ b/MergeGPF/MergeGPF.vcxproj
@@ -42,6 +42,7 @@
+
@@ -50,6 +51,7 @@
+
@@ -84,6 +86,7 @@
+
diff --git a/MergeGPF/MergeGPF.vcxproj.filters b/MergeGPF/MergeGPF.vcxproj.filters
index f3f177d..3c48d44 100644
--- a/MergeGPF/MergeGPF.vcxproj.filters
+++ b/MergeGPF/MergeGPF.vcxproj.filters
@@ -18,5 +18,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/PortabilityLayer/Android.mk b/PortabilityLayer/Android.mk
index 18452c0..a01634f 100644
--- a/PortabilityLayer/Android.mk
+++ b/PortabilityLayer/Android.mk
@@ -17,92 +17,7 @@ LOCAL_EXPORT_LDLIBS := -lz
# Add your application source files here...
LOCAL_SRC_FILES := \
- AntiAliasTable.cpp \
- AppEventHandler.cpp \
- BinHex4.cpp \
- BitmapImage.cpp \
- ByteSwap.cpp \
- CFileStream.cpp \
- DeflateCodec.cpp \
- DialogManager.cpp \
- DisplayDeviceManager.cpp \
- EllipsePlotter.cpp \
- FileBrowserUI.cpp \
- FileManager.cpp \
- FileSectionStream.cpp \
- FontFamily.cpp \
- FontManager.cpp \
- FontRenderer.cpp \
- GPArchive.cpp \
- HostSuspendHook.cpp \
- IconLoader.cpp \
- InflateStream.cpp \
- InputManager.cpp \
- LinePlotter.cpp \
- MacBinary2.cpp \
- MacFileInfo.cpp \
- MacFileMem.cpp \
- MemoryManager.cpp \
- MemReaderStream.cpp \
- MenuManager.cpp \
- MMBlock.cpp \
- MMHandleBlock.cpp \
- PLApplication.cpp \
- PLButtonWidget.cpp \
- PLControlDefinitions.cpp \
- PLCore.cpp \
- PLCTabReducer.cpp \
- PLDialogs.cpp \
- PLDrivers.cpp \
- PLEditboxWidget.cpp \
- PLEventQueue.cpp \
- PLHacks.cpp \
- PLHandle.cpp \
- PLIconWidget.cpp \
- PLImageWidget.cpp \
- PLInvisibleWidget.cpp \
- PLKeyEncoding.cpp \
- PLLabelWidget.cpp \
- PLMenus.cpp \
- PLMovies.cpp \
- PLNumberFormatting.cpp \
- PLPopupMenuWidget.cpp \
- PLQDOffscreen.cpp \
- PLQDraw.cpp \
- PLResourceManager.cpp \
- PLResources.cpp \
- PLScrollBarWidget.cpp \
- PLSound.cpp \
- PLStandardColors.cpp \
- PLStringCompare.cpp \
- PLSysCalls.cpp \
- PLTimeTaggedVOSEvent.cpp \
- PLWidgets.cpp \
- QDGraf.cpp \
- QDManager.cpp \
- QDPictDecoder.cpp \
- QDPictEmitContext.cpp \
- QDPictHeader.cpp \
- QDPixMap.cpp \
- QDPort.cpp \
- QDStandardPalette.cpp \
- RandomNumberGenerator.cpp \
- ResolveCachingColor.cpp \
- ResourceCompiledRef.cpp \
- ResourceFile.cpp \
- ScanlineMask.cpp \
- ScanlineMaskBuilder.cpp \
- ScanlineMaskConverter.cpp \
- ScanlineMaskIterator.cpp \
- SimpleGraphic.cpp \
- TextPlacer.cpp \
- UTF8.cpp \
- UTF16.cpp \
- WindowDef.cpp \
- WindowManager.cpp \
- WorkerThread.cpp \
- XModemCRC.cpp \
- ZipFileProxy.cpp
+ PortabilityLayer_Combined.cpp
LOCAL_STATIC_LIBRARIES := MacRomanConversion stb
diff --git a/PortabilityLayer/AntiAliasTable.cpp b/PortabilityLayer/AntiAliasTable.cpp
index c5e7e9a..e40cc01 100644
--- a/PortabilityLayer/AntiAliasTable.cpp
+++ b/PortabilityLayer/AntiAliasTable.cpp
@@ -35,40 +35,6 @@ namespace PortabilityLayer
return minIndexInclusive;
}
-
- bool AntiAliasTable::LoadFromCache(const char *cacheFileName)
- {
- GpIOStream *stream = PLDrivers::GetFileSystem()->OpenFile(PortabilityLayer::VirtualDirectories::kFontCache, cacheFileName, false, GpFileCreationDispositions::kOpenExisting);
- if (!stream)
- return false;
-
- BEUInt32_t cacheVersion;
- if (stream->Read(&cacheVersion, sizeof(cacheVersion)) != sizeof(cacheVersion) || cacheVersion != kCacheVersion)
- {
- stream->Close();
- return false;
- }
-
- const size_t readSize = sizeof(m_aaTranslate);
- const bool readOK = (stream->Read(m_aaTranslate, readSize) == readSize);
- stream->Close();
-
- return readOK;
- }
-
- void AntiAliasTable::SaveToCache(const char *cacheFileName)
- {
- GpIOStream *stream = PLDrivers::GetFileSystem()->OpenFile(PortabilityLayer::VirtualDirectories::kFontCache, cacheFileName, true, GpFileCreationDispositions::kCreateOrOverwrite);
- if (!stream)
- return;
-
- BEUInt32_t cacheVersion(static_cast(kCacheVersion));
- stream->Write(&cacheVersion, sizeof(cacheVersion));
-
- stream->Write(m_aaTranslate, sizeof(m_aaTranslate));
- stream->Close();
- }
-
void AntiAliasTable::GenerateForPaletteFast(const RGBAColor &baseColorRef)
{
const RGBAColor baseColor = baseColorRef;
@@ -191,16 +157,8 @@ namespace PortabilityLayer
}
}
- void AntiAliasTable::GenerateForPalette(const RGBAColor &baseColorRef, const RGBAColor *colors, size_t numColors, bool cacheable)
+ void AntiAliasTable::GenerateForPalette(const RGBAColor &baseColorRef, const RGBAColor *colors, size_t numColors)
{
- char cacheFileName[256];
- if (cacheable)
- {
- sprintf(cacheFileName, "aa_p_%02x%02x%02x%02x.cache", static_cast(baseColorRef.r), static_cast(baseColorRef.g), static_cast(baseColorRef.b), static_cast(baseColorRef.a));
- if (LoadFromCache(cacheFileName))
- return;
- }
-
const RGBAColor baseColor = baseColorRef;
if (numColors > 256)
@@ -259,21 +217,10 @@ namespace PortabilityLayer
m_aaTranslate[i][b] = static_cast(bestColor);
}
}
-
- if (cacheable)
- SaveToCache(cacheFileName);
}
- void AntiAliasTable::GenerateForSimpleScale(uint8_t colorChannel, bool cacheable)
+ void AntiAliasTable::GenerateForSimpleScale(uint8_t colorChannel)
{
- char cacheFileName[256];
- if (cacheable)
- {
- sprintf(cacheFileName, "aa_t_%02x.cache", static_cast(colorChannel));
- if (LoadFromCache(cacheFileName))
- return;
- }
-
const double gamma = 1.8;
const double rcpGamma = 1.0 / gamma;
const double rcp255 = 1.0 / 255.0;
@@ -294,8 +241,5 @@ namespace PortabilityLayer
m_aaTranslate[baseColor][opacity] = static_cast(floor(blendedColorGammaSpace * 255.0 + 0.5));
}
}
-
- if (cacheable)
- SaveToCache(cacheFileName);
}
}
diff --git a/PortabilityLayer/AntiAliasTable.h b/PortabilityLayer/AntiAliasTable.h
index 7ee582e..dfc3dc3 100644
--- a/PortabilityLayer/AntiAliasTable.h
+++ b/PortabilityLayer/AntiAliasTable.h
@@ -12,14 +12,8 @@ namespace PortabilityLayer
// Striped 256x16 because constant background color is more likely than constant sample
uint8_t m_aaTranslate[256][16];
- void GenerateForPalette(const RGBAColor &baseColor, const RGBAColor *colors, size_t numColors, bool cacheable);
+ void GenerateForPalette(const RGBAColor &baseColor, const RGBAColor *colors, size_t numColors);
void GenerateForPaletteFast(const RGBAColor &baseColor);
- void GenerateForSimpleScale(uint8_t colorChannel, bool cacheable);
-
- private:
- bool LoadFromCache(const char *path);
- void SaveToCache(const char *path);
-
- static const unsigned int kCacheVersion = 1;
+ void GenerateForSimpleScale(uint8_t colorChannel);
};
}
diff --git a/PortabilityLayer/CFileStream.cpp b/PortabilityLayer/CFileStream.cpp
index f013edc..da7ee46 100644
--- a/PortabilityLayer/CFileStream.cpp
+++ b/PortabilityLayer/CFileStream.cpp
@@ -81,7 +81,7 @@ namespace PortabilityLayer
return static_cast(ftell(m_file));
}
- void CFileStream::Close()
+ void CFileStream::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
if (m_file)
{
diff --git a/PortabilityLayer/CFileStream.h b/PortabilityLayer/CFileStream.h
index 5bb0a6c..aefe406 100644
--- a/PortabilityLayer/CFileStream.h
+++ b/PortabilityLayer/CFileStream.h
@@ -23,7 +23,7 @@ namespace PortabilityLayer
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
private:
diff --git a/PortabilityLayer/DeflateCodec.cpp b/PortabilityLayer/DeflateCodec.cpp
index b87b64c..ff1caa0 100644
--- a/PortabilityLayer/DeflateCodec.cpp
+++ b/PortabilityLayer/DeflateCodec.cpp
@@ -371,6 +371,6 @@ uint32_t PortabilityLayer::DeflateContext::CRC32(uint32_t inputValue, const void
PortabilityLayer::InflateContext *PortabilityLayer::InflateContext::Create()
-{
+{
return InflateContextImpl::Create();
}
diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp
index 2a01013..18f0803 100644
--- a/PortabilityLayer/DialogManager.cpp
+++ b/PortabilityLayer/DialogManager.cpp
@@ -3,6 +3,7 @@
#include "IGpDisplayDriver.h"
#include "IGpLogDriver.h"
#include "IGpSystemServices.h"
+#include "MemoryManager.h"
#include "ResourceManager.h"
#include "QDPixMap.h"
#include "Rect2i.h"
@@ -361,7 +362,7 @@ namespace PortabilityLayer
void DialogTemplate::Destroy()
{
this->~DialogTemplate();
- free(this);
+ DisposePtr(this);
}
ArrayView DialogTemplate::GetItems() const
@@ -374,7 +375,7 @@ namespace PortabilityLayer
PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(m_window);
this->~DialogImpl();
- free(this);
+ DisposePtr(this);
}
Window *DialogImpl::GetWindow() const
@@ -646,7 +647,7 @@ namespace PortabilityLayer
const size_t itemsSize = sizeof(DialogItem) * numItems;
- void *storage = malloc(alignedSize + itemsSize);
+ void *storage = NewPtr(alignedSize + itemsSize);
if (!storage)
return nullptr;
@@ -882,7 +883,7 @@ namespace PortabilityLayer
const size_t dtlItemSize = sizeof(DialogTemplateItem) * numItems;
- void *storage = malloc(dtlAlignedSize + dtlItemSize);
+ void *storage = NewPtr(dtlAlignedSize + dtlItemSize);
if (!storage)
{
dtemplateH.Dispose();
diff --git a/PortabilityLayer/FileBrowserUI.cpp b/PortabilityLayer/FileBrowserUI.cpp
index 24d9531..4735d03 100644
--- a/PortabilityLayer/FileBrowserUI.cpp
+++ b/PortabilityLayer/FileBrowserUI.cpp
@@ -459,7 +459,13 @@ namespace PortabilityLayer
break;
}
- if (WaitForEvent(&evtHolder, 1))
+ bool haveEvent = false;
+ {
+ PL_ASYNCIFY_PARANOID_DISARM_FOR_SCOPE();
+ haveEvent = WaitForEvent(&evtHolder, 1);
+ }
+
+ if (haveEvent)
rcvEvt = &evtHolder;
else
rcvEvt = nullptr;
diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp
index e1ccccd..0ffdf85 100644
--- a/PortabilityLayer/FileManager.cpp
+++ b/PortabilityLayer/FileManager.cpp
@@ -10,6 +10,7 @@
#include "ResTypeID.h"
#include "ZipFileProxy.h"
+#include "PLCore.h"
#include "PLDrivers.h"
#include "PLPasStr.h"
#include "PLErrorCodes.h"
@@ -39,17 +40,17 @@ namespace PortabilityLayer
bool CompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename) override;
bool NonCompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename, const char *extension) override;
- bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) override;
- bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) override;
+ bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) GP_ASYNCIFY_PARANOID_OVERRIDE;
+ bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) GP_ASYNCIFY_PARANOID_OVERRIDE;
- PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) override;
- PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) override;
+ PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) GP_ASYNCIFY_PARANOID_OVERRIDE;
+ PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) GP_ASYNCIFY_PARANOID_OVERRIDE;
PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override;
PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override;
- bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) override;
- bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) override;
+ bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_OVERRIDE;
+ bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_OVERRIDE;
static FileManagerImpl *GetInstance();
@@ -474,12 +475,12 @@ namespace PortabilityLayer
void CompositeFileImpl::Close()
{
this->~CompositeFileImpl();
- free(this);
+ DisposePtr(this);
}
CompositeFileImpl *CompositeFileImpl::Create(VirtualDirectory_t dirID, const PLPasStr &filename, GpIOStream *stream, ZipFileProxy *zipFile, const MacFileProperties &mfp, bool resInline, bool dataInline, size_t inlineDataIndex)
{
- void *storage = malloc(sizeof(CompositeFileImpl));
+ void *storage = NewPtr(sizeof(CompositeFileImpl));
if (!storage)
return nullptr;
@@ -506,4 +507,36 @@ namespace PortabilityLayer
if (m_stream)
m_stream->Close();
}
+
+#if GP_ASYNCIFY_PARANOID
+ bool FileManager::PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI)
+ {
+ return static_cast(this)->PromptSaveFile(dirID, extension, path, outPathLength, pathCapacity, initialFileName, promptText, composites, callbackAPI);
+ }
+
+ bool FileManager::PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI)
+ {
+ return static_cast(this)->PromptOpenFile(dirID, extension, path, outPathLength, pathCapacity, promptText, composites, callbackAPI);
+ }
+
+ PLError_t FileManager::CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp)
+ {
+ return static_cast(this)->CreateFile(dirID, filename, mfp);
+ }
+
+ PLError_t FileManager::CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType)
+ {
+ return static_cast(this)->CreateFileAtCurrentTime(dirID, filename, fileCreator, fileType);
+ }
+
+ bool FileManager::DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext)
+ {
+ return static_cast(this)->DeleteNonCompositeFile(dirID, filename, ext);
+ }
+
+ bool FileManager::DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename)
+ {
+ return static_cast(this)->DeleteCompositeFile(dirID, filename);
+ }
+#endif
}
diff --git a/PortabilityLayer/FileManager.h b/PortabilityLayer/FileManager.h
index 93f8045..a2f8482 100644
--- a/PortabilityLayer/FileManager.h
+++ b/PortabilityLayer/FileManager.h
@@ -46,17 +46,17 @@ namespace PortabilityLayer
virtual bool CompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename) = 0;
virtual bool NonCompositeFileExists(VirtualDirectory_t dirID, const PLPasStr &filename, const char *extension) = 0;
- virtual bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) = 0;
- virtual bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) = 0;
+ GP_ASYNCIFY_PARANOID_VIRTUAL bool DeleteNonCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename, const char *ext) GP_ASYNCIFY_PARANOID_PURE;
+ GP_ASYNCIFY_PARANOID_VIRTUAL bool DeleteCompositeFile(VirtualDirectory_t dirID, const PLPasStr &filename) GP_ASYNCIFY_PARANOID_PURE;
- virtual PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) = 0;
- virtual PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) = 0;
+ GP_ASYNCIFY_PARANOID_VIRTUAL PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) GP_ASYNCIFY_PARANOID_PURE;
+ GP_ASYNCIFY_PARANOID_VIRTUAL PLError_t CreateFileAtCurrentTime(VirtualDirectory_t dirID, const PLPasStr &filename, const ResTypeID &fileCreator, const ResTypeID &fileType) GP_ASYNCIFY_PARANOID_PURE;
virtual PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0;
virtual PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0;
- virtual bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) = 0;
- virtual bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) = 0;
+ GP_ASYNCIFY_PARANOID_VIRTUAL bool PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_PURE;
+ GP_ASYNCIFY_PARANOID_VIRTUAL bool PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) GP_ASYNCIFY_PARANOID_PURE;
static FileManager *GetInstance();
};
diff --git a/PortabilityLayer/FileSectionStream.cpp b/PortabilityLayer/FileSectionStream.cpp
index cdc2c16..38fe5aa 100644
--- a/PortabilityLayer/FileSectionStream.cpp
+++ b/PortabilityLayer/FileSectionStream.cpp
@@ -1,4 +1,5 @@
#include "FileSectionStream.h"
+#include "PLCore.h"
#include
#include
@@ -21,7 +22,7 @@ namespace PortabilityLayer
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
private:
@@ -148,10 +149,10 @@ namespace PortabilityLayer
return m_expectedPosition - m_start;
}
- void FileSectionStreamImpl::Close()
+ void FileSectionStreamImpl::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
this->~FileSectionStreamImpl();
- free(this);
+ DisposePtr(this);
}
void FileSectionStreamImpl::Flush()
@@ -161,7 +162,7 @@ namespace PortabilityLayer
GpIOStream *FileSectionStream::Create(GpIOStream *stream, GpUFilePos_t start, GpUFilePos_t size)
{
- void *storage = malloc(sizeof(FileSectionStreamImpl));
+ void *storage = NewPtr(sizeof(FileSectionStreamImpl));
if (!storage)
return nullptr;
diff --git a/PortabilityLayer/FontFamily.cpp b/PortabilityLayer/FontFamily.cpp
index 39a5a7c..8e7c85e 100644
--- a/PortabilityLayer/FontFamily.cpp
+++ b/PortabilityLayer/FontFamily.cpp
@@ -7,6 +7,7 @@
#include "MemReaderStream.h"
#include "MemoryManager.h"
+#include "PLCore.h"
#include "PLDrivers.h"
#include
@@ -15,16 +16,20 @@
namespace PortabilityLayer
{
FontFamily::FontSpec::FontSpec()
- : m_fontPath(nullptr)
+ : m_fontVDir(VirtualDirectories::kUnspecified)
+ , m_fontPath(nullptr)
, m_font(nullptr)
, m_hacks(FontHacks_None)
+ , m_typeFaceIndex(0)
, m_isRegistered(false)
{
}
- void FontFamily::AddFont(int flags, const char *path, FontHacks fontHacks)
+ void FontFamily::AddFont(int flags, VirtualDirectory_t vDir, const char *path, int typeFaceIndex, FontHacks fontHacks)
{
+ m_fontSpecs[flags].m_fontVDir = vDir;
m_fontSpecs[flags].m_fontPath = path;
+ m_fontSpecs[flags].m_typeFaceIndex = typeFaceIndex;
m_fontSpecs[flags].m_hacks = fontHacks;
m_fontSpecs[flags].m_isRegistered = true;
@@ -55,7 +60,7 @@ namespace PortabilityLayer
if (spec.m_font)
return spec.m_font;
- GpIOStream *sysFontStream = PLDrivers::GetFileSystem()->OpenFile(PortabilityLayer::VirtualDirectories::kFonts, spec.m_fontPath, false, GpFileCreationDispositions::kOpenExisting);
+ GpIOStream *sysFontStream = PLDrivers::GetFileSystem()->OpenFile(spec.m_fontVDir, spec.m_fontPath, false, GpFileCreationDispositions::kOpenExisting);
if (!sysFontStream)
return nullptr;
@@ -93,7 +98,7 @@ namespace PortabilityLayer
IGpFontHandler *fontHandler = PLDrivers::GetFontHandler();
- IGpFont *font = fontHandler->LoadFont(sysFontStream);
+ IGpFont *font = fontHandler->LoadFont(sysFontStream, spec.m_typeFaceIndex);
if (!fontHandler->KeepStreamOpen())
sysFontStream->Close();
@@ -106,18 +111,31 @@ namespace PortabilityLayer
return font;
}
+ void FontFamily::UnloadVariation(int variation)
+ {
+ FontSpec &spec = m_fontSpecs[variation];
+ if (spec.m_font)
+ {
+ spec.m_font->Destroy();
+ spec.m_font = nullptr;
+ }
+ }
+
PortabilityLayer::FontHacks FontFamily::GetHacksForVariation(int variation) const
{
return m_fontSpecs[variation].m_hacks;
}
- bool FontFamily::GetFontSpec(int variation, FontHacks &outHacks, const char *&outPath)
+ bool FontFamily::GetFontSpec(int variation, FontHacks &outHacks, VirtualDirectory_t &outVDir, const char *&outPath, int &outTypeFaceIndex)
{
- if (!m_fontSpecs[variation].m_isRegistered)
+ const FontSpec &spec = m_fontSpecs[variation];
+ if (!spec.m_isRegistered)
return false;
- outHacks = m_fontSpecs[variation].m_hacks;
- outPath = m_fontSpecs[variation].m_fontPath;
+ outHacks = spec.m_hacks;
+ outVDir = spec.m_fontVDir;
+ outPath = spec.m_fontPath;
+ outTypeFaceIndex = spec.m_typeFaceIndex;
return true;
}
@@ -141,7 +159,7 @@ namespace PortabilityLayer
FontFamily *FontFamily::Create(FontFamilyID_t familyID)
{
- void *storage = malloc(sizeof(FontFamily));
+ void *storage = NewPtr(sizeof(FontFamily));
if (!storage)
return nullptr;
@@ -151,7 +169,7 @@ namespace PortabilityLayer
void FontFamily::Destroy()
{
this->~FontFamily();
- free(this);
+ DisposePtr(this);
}
FontFamily::FontFamily(FontFamilyID_t familyID)
diff --git a/PortabilityLayer/FontFamily.h b/PortabilityLayer/FontFamily.h
index df1f1de..61fbbeb 100644
--- a/PortabilityLayer/FontFamily.h
+++ b/PortabilityLayer/FontFamily.h
@@ -2,6 +2,7 @@
#include "FontFamilyID.h"
#include "FontHacks.h"
+#include "VirtualDirectory.h"
#include
@@ -15,8 +16,9 @@ namespace PortabilityLayer
FontFamilyFlag_None = 0,
FontFamilyFlag_Bold = 1,
+ FontFamilyFlag_SyntheticBold = 2,
- FontFamilyFlag_All = 1,
+ FontFamilyFlag_All = (FontFamilyFlag_Bold | FontFamilyFlag_SyntheticBold),
};
class FontFamily final
@@ -24,12 +26,13 @@ namespace PortabilityLayer
public:
static const unsigned int kNumVariations = FontFamilyFlag_All + 1;
- void AddFont(int flags, const char *path, FontHacks fontHacks);
+ void AddFont(int flags, VirtualDirectory_t vDir, const char *path, int typeFaceIndex, FontHacks fontHacks);
void SetDefaultVariation(int defaultVariation);
- bool GetFontSpec(int variation, FontHacks &outHacks, const char *&outPath);
+ bool GetFontSpec(int variation, FontHacks &outHacks, VirtualDirectory_t &outVDir, const char *&outPath, int &outTypeFaceIndex);
int GetVariationForFlags(int flags) const;
IGpFont *GetFontForVariation(int variation);
+ void UnloadVariation(int variation);
FontHacks GetHacksForVariation(int variation) const;
FontFamilyID_t GetFamilyID() const;
@@ -46,7 +49,9 @@ namespace PortabilityLayer
IGpFont *m_font;
FontHacks m_hacks;
+ VirtualDirectory_t m_fontVDir;
const char *m_fontPath;
+ int m_typeFaceIndex;
bool m_isRegistered;
};
diff --git a/PortabilityLayer/FontHacks.h b/PortabilityLayer/FontHacks.h
index 55a7444..c9a06b0 100644
--- a/PortabilityLayer/FontHacks.h
+++ b/PortabilityLayer/FontHacks.h
@@ -6,5 +6,6 @@ namespace PortabilityLayer
{
FontHacks_None,
FontHacks_Roboto,
+ FontHacks_SyntheticBold_OpenSans,
};
}
diff --git a/PortabilityLayer/FontManager.cpp b/PortabilityLayer/FontManager.cpp
index bf51a8d..0483878 100644
--- a/PortabilityLayer/FontManager.cpp
+++ b/PortabilityLayer/FontManager.cpp
@@ -6,6 +6,7 @@
#include "GpIOStream.h"
#include "IGpFileSystem.h"
#include "IGpFont.h"
+#include "IGpSystemServices.h"
#include "MemReaderStream.h"
#include "PLBigEndian.h"
@@ -32,8 +33,6 @@ namespace PortabilityLayer
FontFamily *GetFont(FontFamilyID_t fontFamilyID) const override;
void GetFontPreset(FontPreset_t fontPreset, FontFamilyID_t *outFamilyID, int *outSize, int *outVariationFlags, bool *outAA) const override;
- RenderedFont *GetRenderedFontFromFamily(FontFamily *font, int size, bool aa, int flags) override;
-
RenderedFont *LoadCachedRenderedFont(FontFamilyID_t familyID, int size, bool aa, int flags) override;
void PurgeCache() override;
@@ -41,6 +40,9 @@ namespace PortabilityLayer
static FontManagerImpl *GetInstance();
private:
+ RenderedFont *LoadAndRenderFontUsingFontHandler(FontFamily *font, int size, bool aa, int flags);
+ RenderedFont *LoadAndRenderFont(FontFamilyID_t familyID, int size, bool aa, int flags);
+
static const unsigned int kNumCachedRenderedFonts = 32;
struct CachedRenderedFont
@@ -48,8 +50,9 @@ namespace PortabilityLayer
RenderedFont *m_rfont;
int m_fontCacheID;
int m_size;
- uint32_t m_lastUsage;
+ int m_flags;
bool m_aa;
+ uint32_t m_lastUsage;
};
struct FontPreset
@@ -62,7 +65,7 @@ namespace PortabilityLayer
FontManagerImpl();
- bool FindOrReserveCacheSlot(int cacheID, int size, bool aa, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF);
+ bool FindOrReserveCacheSlot(int cacheID, int size, bool aa, int flags, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF);
void ReplaceCachedRenderedFont(CachedRenderedFont &cacheSlot, RenderedFont *rfont, int cacheID, int size, bool aa, int flags);
void ResetUsageCounter();
@@ -77,6 +80,8 @@ namespace PortabilityLayer
PortabilityLayer::CompositeFile *m_fontArchiveFile;
THandle m_fontArchiveCatalogData;
+ bool m_hasPreinstalledFonts;
+
static FontManagerImpl ms_instance;
static FontPreset ms_fontPresets[FontPresets::kCount];
};
@@ -87,19 +92,20 @@ namespace PortabilityLayer
m_fontFamilies[static_cast(i)] = FontFamily::Create(static_cast(i));
if (m_fontFamilies[FontFamilyIDs::kSystem])
- m_fontFamilies[FontFamilyIDs::kSystem]->AddFont(FontFamilyFlag_None, "Fonts/OpenSans/OpenSans-ExtraBold.ttf", FontHacks_None);
+ m_fontFamilies[FontFamilyIDs::kSystem]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-ExtraBold.ttf", 0, FontHacks_None);
if (m_fontFamilies[FontFamilyIDs::kApplication])
{
- m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_None, "Fonts/OpenSans/OpenSans-SemiBold.ttf", FontHacks_None);
- m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_Bold, "Fonts/OpenSans/OpenSans-Bold.ttf", FontHacks_None);
+ m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-SemiBold.ttf", 0, FontHacks_None);
+ m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_Bold, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-Bold.ttf", 0, FontHacks_None);
+ m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_SyntheticBold, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-Regular.ttf", 0, FontHacks_SyntheticBold_OpenSans);
}
if (m_fontFamilies[FontFamilyIDs::kHandwriting])
- m_fontFamilies[FontFamilyIDs::kHandwriting]->AddFont(FontFamilyFlag_None, "Fonts/GochiHand/GochiHand-Regular.ttf", FontHacks_None);
+ m_fontFamilies[FontFamilyIDs::kHandwriting]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/GochiHand/GochiHand-Regular.ttf", 0, FontHacks_None);
if (m_fontFamilies[FontFamilyIDs::kMonospace])
- m_fontFamilies[FontFamilyIDs::kMonospace]->AddFont(FontFamilyFlag_None, "Fonts/Roboto/RobotoMono-Regular.ttf", FontHacks_None);
+ m_fontFamilies[FontFamilyIDs::kMonospace]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/Roboto/RobotoMono-Regular.ttf", 0, FontHacks_None);
memset(m_cachedRenderedFonts, 0, sizeof(m_cachedRenderedFonts));
}
@@ -139,23 +145,10 @@ namespace PortabilityLayer
*outAA = ms_fontPresets[preset].m_aa;
if (outFamilyID)
- {
- switch (ms_fontPresets[preset].m_familyID)
- {
- case FontFamilyIDs::kApplication:
- if (ms_fontPresets[preset].m_textSize < 11 && (ms_fontPresets[preset].m_variationFlags & FontFamilyFlag_Bold) != 0)
- *outFamilyID = FontFamilyIDs::kSystem; // Use heavier font below 11pt
- else
- *outFamilyID = FontFamilyIDs::kApplication;
- break;
- default:
- *outFamilyID = ms_fontPresets[preset].m_familyID;
- break;
- }
- }
+ *outFamilyID = ms_fontPresets[preset].m_familyID;
}
- bool FontManagerImpl::FindOrReserveCacheSlot(int cacheID, int size, bool aa, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF)
+ bool FontManagerImpl::FindOrReserveCacheSlot(int cacheID, int size, bool aa, int flags, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF)
{
CachedRenderedFont *newCacheSlot = &m_cachedRenderedFonts[0];
@@ -168,7 +161,7 @@ namespace PortabilityLayer
break;
}
- if (crf.m_fontCacheID == cacheID && crf.m_size == size && crf.m_aa == aa)
+ if (crf.m_fontCacheID == cacheID && crf.m_size == size && crf.m_aa == aa && crf.m_flags == flags)
{
crf.m_lastUsage = m_usageCounter;
RenderedFont *rf = crf.m_rfont;
@@ -199,6 +192,7 @@ namespace PortabilityLayer
cacheSlot.m_size = size;
cacheSlot.m_rfont = rfont;
cacheSlot.m_aa = aa;
+ cacheSlot.m_flags = flags;
if (m_usageCounter == UINT32_MAX)
ResetUsageCounter();
@@ -206,44 +200,49 @@ namespace PortabilityLayer
m_usageCounter++;
}
- RenderedFont *FontManagerImpl::GetRenderedFontFromFamily(FontFamily *fontFamily, int size, bool aa, int flags)
+ RenderedFont *FontManagerImpl::LoadAndRenderFontUsingFontHandler(FontFamily *fontFamily, int size, bool aa, int flags)
{
PortabilityLayer::FontManager *fm = PortabilityLayer::FontManager::GetInstance();
- RenderedFont *rfont = nullptr;
- CachedRenderedFont *cacheSlot = nullptr;
- FontFamilyID_t familyID = fontFamily->GetFamilyID();
-
- if (this->FindOrReserveCacheSlot(familyID, size, aa, cacheSlot, rfont))
- return rfont;
-
- rfont = fm->LoadCachedRenderedFont(familyID, size, aa, flags);
- if (rfont)
- {
- ReplaceCachedRenderedFont(*cacheSlot, rfont, familyID, size, aa, flags);
- return rfont;
- }
-
const int variation = fontFamily->GetVariationForFlags(flags);
IGpFont *hostFont = fontFamily->GetFontForVariation(variation);
if (!hostFont)
return nullptr;
-
- rfont = FontRenderer::GetInstance()->RenderFont(hostFont, size, aa, fontFamily->GetHacksForVariation(variation));
- if (rfont)
- {
- ReplaceCachedRenderedFont(*cacheSlot, rfont, familyID, size, aa, flags);
-
- return rfont;
- }
+ RenderedFont *rfont = FontRenderer::GetInstance()->RenderFont(hostFont, size, aa, fontFamily->GetHacksForVariation(variation));
+ fontFamily->UnloadVariation(variation);
return rfont;
}
RenderedFont *FontManagerImpl::LoadCachedRenderedFont(FontFamilyID_t familyID, int size, bool aa, int flags)
{
+ CachedRenderedFont *cacheSlot = nullptr;
+ RenderedFont *rfont = nullptr;
+
+ if (this->FindOrReserveCacheSlot(familyID, size, aa, flags, cacheSlot, rfont))
+ return rfont;
+
+ rfont = LoadAndRenderFont(familyID, size, aa, flags);
+ if (rfont)
+ ReplaceCachedRenderedFont(*cacheSlot, rfont, familyID, size, aa, flags);
+
+ return rfont;
+ }
+
+ RenderedFont *FontManagerImpl::LoadAndRenderFont(FontFamilyID_t familyID, int size, bool aa, int flags)
+ {
+ FontFamily *fontFamily = this->GetFont(familyID);
+
+ RenderedFont *rfont = nullptr;
+ if (PLDrivers::GetFontHandler() != nullptr)
+ {
+ rfont = LoadAndRenderFontUsingFontHandler(fontFamily, size, aa, flags);
+ if (rfont != nullptr)
+ return rfont;
+ }
+
if (!m_fontArchive)
{
m_fontArchiveFile = PortabilityLayer::FileManager::GetInstance()->OpenCompositeFile(VirtualDirectories::kApplicationData, PSTR("Fonts"));
@@ -266,12 +265,17 @@ namespace PortabilityLayer
}
}
- FontFamily *fontFamily = this->GetFont(familyID);
int variation = fontFamily->GetVariationForFlags(flags);
FontHacks hacks = FontHacks_None;
+ VirtualDirectory_t vDir = VirtualDirectories::kUnspecified;
const char *path = nullptr;
- if (!fontFamily->GetFontSpec(variation, hacks, path))
+ int typeFaceIndex = 0;
+ if (!fontFamily->GetFontSpec(variation, hacks, vDir, path, typeFaceIndex))
+ return nullptr;
+
+ // Only single TTF fonts are supported by the prerendered font system currently
+ if (vDir != VirtualDirectories::kFonts || typeFaceIndex != 0)
return nullptr;
size_t pathLen = strlen(path);
@@ -328,13 +332,13 @@ namespace PortabilityLayer
return nullptr;
THandle res = m_fontArchive->LoadResource('RFNT', 1000 + static_cast(fontIndex));
- if (!res)
- return nullptr;
+ if (res)
+ {
+ PortabilityLayer::MemReaderStream stream(*res, res.MMBlock()->m_size);
- PortabilityLayer::MemReaderStream stream(*res, res.MMBlock()->m_size);
-
- RenderedFont *rfont = PortabilityLayer::FontRenderer::GetInstance()->LoadCache(&stream);
- res.Dispose();
+ rfont = PortabilityLayer::FontRenderer::GetInstance()->LoadCache(&stream);
+ res.Dispose();
+ }
return rfont;
}
@@ -356,6 +360,7 @@ namespace PortabilityLayer
FontManagerImpl::FontManagerImpl()
: m_fontArchive(nullptr)
, m_fontArchiveFile(nullptr)
+ , m_hasPreinstalledFonts(false)
{
for (int fid = 0; fid < FontFamilyIDs::kCount; fid++)
m_fontFamilies[fid] = nullptr;
@@ -409,11 +414,12 @@ namespace PortabilityLayer
{ FontFamilyIDs::kApplication, 8, FontFamilyFlag_None, true },
{ FontFamilyIDs::kApplication, 9, FontFamilyFlag_None, true },
- { FontFamilyIDs::kApplication, 9, FontFamilyFlag_Bold, true },
- { FontFamilyIDs::kApplication, 10, FontFamilyFlag_Bold, true },
+ { FontFamilyIDs::kApplication, 9, FontFamilyFlag_SyntheticBold, true },
+ { FontFamilyIDs::kApplication, 10, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 12, FontFamilyFlag_Bold, true },
+ { FontFamilyIDs::kApplication, 12, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 14, FontFamilyFlag_None, true },
- { FontFamilyIDs::kApplication, 14, FontFamilyFlag_Bold, true },
+ { FontFamilyIDs::kApplication, 14, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 18, FontFamilyFlag_None, true },
{ FontFamilyIDs::kApplication, 40, FontFamilyFlag_None, true },
diff --git a/PortabilityLayer/FontManager.h b/PortabilityLayer/FontManager.h
index 8c281bd..9dacc93 100644
--- a/PortabilityLayer/FontManager.h
+++ b/PortabilityLayer/FontManager.h
@@ -2,6 +2,7 @@
#include "FontHacks.h"
#include "FontFamilyID.h"
+#include "FontPresets.h"
struct IGpFont;
@@ -10,34 +11,6 @@ namespace PortabilityLayer
class FontFamily;
class RenderedFont;
- namespace FontPresets
- {
- enum FontPreset
- {
- kSystem12,
- kSystem12Bold,
-
- kApplication8,
- kApplication9,
- kApplication9Bold,
- kApplication10Bold,
- kApplication12Bold,
- kApplication14,
- kApplication14Bold,
- kApplication18,
- kApplication40,
-
- kMono10,
-
- kHandwriting24,
- kHandwriting48,
-
- kCount,
- };
- }
-
- typedef FontPresets::FontPreset FontPreset_t;
-
class FontManager
{
public:
@@ -47,8 +20,6 @@ namespace PortabilityLayer
virtual FontFamily *GetFont(FontFamilyID_t fontFamilyID) const = 0;
virtual void GetFontPreset(FontPreset_t fontPreset, FontFamilyID_t *outFamilyID, int *outSize, int *outVariationFlags, bool *outAA) const = 0;
- virtual RenderedFont *GetRenderedFontFromFamily(FontFamily *fontFamily, int fontSize, bool aa, int flags) = 0;
-
virtual RenderedFont *LoadCachedRenderedFont(FontFamilyID_t familyID, int size, bool aa, int flags) = 0;
virtual void PurgeCache() = 0;
diff --git a/PortabilityLayer/FontPresets.h b/PortabilityLayer/FontPresets.h
new file mode 100644
index 0000000..33257a0
--- /dev/null
+++ b/PortabilityLayer/FontPresets.h
@@ -0,0 +1,33 @@
+#pragma once
+
+namespace PortabilityLayer
+{
+ namespace FontPresets
+ {
+ enum FontPreset
+ {
+ kSystem12,
+ kSystem12Bold,
+
+ kApplication8,
+ kApplication9,
+ kApplication9SyntheticBold,
+ kApplication10SyntheticBold,
+ kApplication12Bold,
+ kApplication12SyntheticBold,
+ kApplication14,
+ kApplication14SyntheticBold,
+ kApplication18,
+ kApplication40,
+
+ kMono10,
+
+ kHandwriting24,
+ kHandwriting48,
+
+ kCount,
+ };
+ }
+
+ typedef FontPresets::FontPreset FontPreset_t;
+}
diff --git a/PortabilityLayer/FontRenderer.cpp b/PortabilityLayer/FontRenderer.cpp
index 5cfef15..82c6c90 100644
--- a/PortabilityLayer/FontRenderer.cpp
+++ b/PortabilityLayer/FontRenderer.cpp
@@ -11,6 +11,7 @@
#include "GpRenderedGlyphMetrics.h"
#include "PLBigEndian.h"
+#include "PLCore.h"
#include "PLDrivers.h"
#include "PLPasStr.h"
#include "DeflateCodec.h"
@@ -59,6 +60,8 @@ namespace PortabilityLayer
BEInt16_t m_bearingX;
BEInt16_t m_bearingY;
BEInt16_t m_advanceX;
+ BEInt16_t m_bitmapOffsetX;
+ BEInt16_t m_bitmapOffsetY;
};
struct SerializedFontMetrics
@@ -101,9 +104,31 @@ namespace PortabilityLayer
static FontRendererImpl *GetInstance();
private:
+ static void SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa, uint8_t character, int size, FontHacks fontHacks);
+
static FontRendererImpl ms_instance;
};
+ class ReRenderedGlyph final : public IGpFontRenderedGlyph
+ {
+ public:
+ const GpRenderedGlyphMetrics &GetMetrics() const override;
+ const void *GetData() const override;
+ void Destroy() override;
+
+ void *GetMutableData();
+ GpRenderedGlyphMetrics &GetMutableMetrics();
+
+ static ReRenderedGlyph *Create(unsigned int width, unsigned int height, bool aa);
+
+ private:
+ explicit ReRenderedGlyph(void *data, unsigned int width, unsigned int height, size_t pitch, size_t dataSize);
+
+ GpRenderedGlyphMetrics m_metrics;
+ void *m_data;
+ size_t m_dataSize;
+ };
+
bool RenderedFontImpl::GetGlyph(unsigned int character, const GpRenderedGlyphMetrics *&outMetricsPtr, const void *&outData) const
{
const size_t dataOffset = m_dataOffsets[character];
@@ -142,7 +167,7 @@ namespace PortabilityLayer
void RenderedFontImpl::Destroy()
{
this->~RenderedFontImpl();
- free(this);
+ DisposePtr(this);
}
void RenderedFontImpl::SetCharData(unsigned int charID, const void *data, size_t dataOffset, const GpRenderedGlyphMetrics &metrics)
@@ -227,7 +252,7 @@ namespace PortabilityLayer
const size_t allocSize = alignedPrefixSize + glyphDataSize;
- void *storage = malloc(allocSize);
+ void *storage = NewPtr(allocSize);
if (!storage)
return nullptr;
@@ -293,6 +318,8 @@ namespace PortabilityLayer
result.m_glyphDataPitch = static_cast(metrics.m_glyphDataPitch);
result.m_glyphHeight = metrics.m_glyphHeight;
result.m_glyphWidth = metrics.m_glyphWidth;
+ result.m_bitmapOffsetX = metrics.m_bitmapOffsetX;
+ result.m_bitmapOffsetY = metrics.m_bitmapOffsetY;
return result;
}
@@ -306,6 +333,8 @@ namespace PortabilityLayer
result.m_glyphDataPitch = static_cast(metrics.m_glyphDataPitch);
result.m_glyphHeight = metrics.m_glyphHeight;
result.m_glyphWidth = metrics.m_glyphWidth;
+ result.m_bitmapOffsetX = metrics.m_bitmapOffsetX;
+ result.m_bitmapOffsetY = metrics.m_bitmapOffsetY;
return result;
}
@@ -347,13 +376,42 @@ namespace PortabilityLayer
for (unsigned int i = 0; i < numCharacters; i++)
glyphs[i] = nullptr;
+ bool isSyntheticBold = false;
+ if (fontHacks == FontHacks_SyntheticBold_OpenSans)
+ isSyntheticBold = true;
+
+ unsigned int xScale = 1;
+ unsigned int yScale = 1;
+ bool syntheticBoldAA = false;
+ if (isSyntheticBold)
+ {
+ if (aa)
+ {
+ syntheticBoldAA = true;
+ xScale = 8;
+ yScale = 8;
+ }
+ }
+
for (unsigned int i = 0; i < numCharacters; i++)
{
uint16_t unicodeCodePoint = MacRoman::ToUnicode(i);
if (unicodeCodePoint == 0xffff)
continue;
- glyphs[i] = font->Render(unicodeCodePoint, size, aa);
+ glyphs[i] = font->Render(unicodeCodePoint, size, xScale, yScale, aa);
+ }
+
+ if (isSyntheticBold)
+ {
+ if (syntheticBoldAA)
+ {
+ for (unsigned int i = 0; i < numCharacters; i++)
+ {
+ if (glyphs[i])
+ SynthesizeBoldAA(glyphs[i], xScale, yScale, syntheticBoldAA, i, size, fontHacks);
+ }
+ }
}
size_t glyphDataSize = GP_SYSTEM_MEMORY_ALIGNMENT; // So we can use 0 to mean no data
@@ -401,6 +459,20 @@ namespace PortabilityLayer
}
}
+ /*
+ if (fontHacks == FontHacks_SyntheticBold_OpenSans && size == 12)
+ {
+ if (i == 'i')
+ metrics.m_bearingX++;
+ }
+
+ if (fontHacks == FontHacks_SyntheticBold_OpenSans && size == 9)
+ {
+ if (i == 'V')
+ metrics.m_advanceX++;
+ }
+ */
+
rfont->SetCharData(i, data, fillOffset, metrics);
fillOffset += metrics.m_glyphDataPitch * metrics.m_glyphHeight;
@@ -465,6 +537,137 @@ namespace PortabilityLayer
return true;
}
+ void FontRendererImpl::SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa, uint8_t character, int size, FontHacks fontHacks)
+ {
+ unsigned int extraWidth = 1;
+
+ GpRenderedGlyphMetrics metrics = glyph->GetMetrics();
+ const void *existingData = glyph->GetData();
+
+ uint32_t existingWidth = metrics.m_glyphWidth;
+ uint32_t existingHeight = metrics.m_glyphHeight;
+
+ uint32_t leftPadding = 0;
+ uint32_t topPadding = 0;
+
+ {
+ const int32_t leftCoord = metrics.m_bitmapOffsetX;
+ int32_t leftCoordRemainder = leftCoord % static_cast(xScale);
+
+ if (leftCoordRemainder > 0)
+ leftPadding = leftCoordRemainder;
+ else if (leftCoordRemainder < 0)
+ leftPadding = leftCoordRemainder + static_cast(xScale);
+
+ const int32_t topCoord = metrics.m_bitmapOffsetY;
+ int32_t topCoordRemainder = topCoord % static_cast(yScale);
+
+ if (topCoordRemainder != 0)
+ {
+ if (topCoordRemainder < 0)
+ topCoordRemainder += static_cast(yScale);
+
+ topPadding = static_cast(yScale) - topCoordRemainder;
+ }
+ }
+
+ uint32_t paddedWidth = existingWidth + leftPadding;
+ uint32_t paddedHeight = existingHeight + topPadding;
+
+ uint32_t newWidth = (paddedWidth + xScale - 1) / xScale + extraWidth;
+ uint32_t newHeight = (paddedHeight + yScale - 1) / yScale;
+
+ ReRenderedGlyph *newGlyph = ReRenderedGlyph::Create(newWidth, newHeight, aa);
+ if (!newGlyph)
+ return;
+
+ uint16_t *fattenAccumulateBuffer = static_cast(MemoryManager::GetInstance()->Alloc(newWidth * sizeof(uint16_t)));
+ if (!fattenAccumulateBuffer)
+ {
+ newGlyph->Destroy();
+ return;
+ }
+
+ GpRenderedGlyphMetrics &newMetrics = newGlyph->GetMutableMetrics();
+ newMetrics.m_advanceX = metrics.m_advanceX + static_cast(extraWidth);
+ newMetrics.m_bearingX = (metrics.m_bitmapOffsetX - static_cast(leftPadding)) / static_cast(xScale);
+ newMetrics.m_bearingY = (metrics.m_bitmapOffsetY + static_cast(topPadding)) / static_cast(yScale);
+ newMetrics.m_bitmapOffsetX = newMetrics.m_bearingX;
+ newMetrics.m_bitmapOffsetY = newMetrics.m_bearingY;
+
+ const size_t existingDataPitch = metrics.m_glyphDataPitch;
+ const size_t newPitch = newMetrics.m_glyphDataPitch;
+ uint8_t *newData = static_cast(newGlyph->GetMutableData());
+
+ for (unsigned int outY = 0; outY < newHeight; outY++)
+ {
+ memset(fattenAccumulateBuffer, 0, newWidth * sizeof(uint16_t));
+
+ for (unsigned int subY = 0; subY < yScale; subY++)
+ {
+ uint32_t originalY = subY + outY * yScale;
+ if (originalY < topPadding)
+ continue;
+
+ originalY -= topPadding;
+ if (originalY >= existingHeight)
+ break;
+
+ const uint8_t *existingRow = static_cast(existingData) + originalY * existingDataPitch;
+
+ unsigned int streakCounter = 0;
+ unsigned int outX = 0;
+ unsigned int outSubX = 0;
+ for (unsigned int unpaddedOriginalX = 0; unpaddedOriginalX < newWidth * xScale; unpaddedOriginalX++)
+ {
+ if (unpaddedOriginalX > leftPadding)
+ {
+ uint32_t originalX = unpaddedOriginalX - leftPadding;
+
+ if (originalX < existingWidth)
+ {
+ //if (existingRow[originalX / 8] & (1 << (originalX & 7)))
+ uint8_t v = ((existingRow[originalX / 2] >> ((originalX & 1) * 4)) & 0xf);
+ if (v >= 8)
+ streakCounter = xScale + 1;
+ }
+ }
+
+ if (streakCounter > 0)
+ {
+ streakCounter--;
+ fattenAccumulateBuffer[outX]++;
+ }
+
+ outSubX++;
+ if (outSubX == xScale)
+ {
+ outSubX = 0;
+ outX++;
+ }
+ }
+ }
+
+ uint8_t *outRow = newData + outY * newPitch;
+ unsigned int divisor = xScale * yScale;
+ for (unsigned int x = 0; x < newWidth; x++)
+ {
+ uint32_t fraction = static_cast(fattenAccumulateBuffer[x]) * 15;
+ fraction = (fraction * 2 + divisor) / (divisor * 2);
+
+ uint8_t *outByte = outRow + (x / 2);
+ (*outByte) |= fraction << ((x & 1) * 4);
+
+ size_t outOffset = outByte - newData;
+ }
+ }
+
+ MemoryManager::GetInstance()->Release(fattenAccumulateBuffer);
+
+ glyph->Destroy();
+ glyph = newGlyph;
+ }
+
FontRendererImpl *FontRendererImpl::GetInstance()
{
return &ms_instance;
@@ -472,6 +675,67 @@ namespace PortabilityLayer
FontRendererImpl FontRendererImpl::ms_instance;
+ const GpRenderedGlyphMetrics &ReRenderedGlyph::GetMetrics() const
+ {
+ return m_metrics;
+ }
+
+ const void *ReRenderedGlyph::GetData() const
+ {
+ return m_data;
+ }
+
+ void ReRenderedGlyph::Destroy()
+ {
+ this->~ReRenderedGlyph();
+ PortabilityLayer::MemoryManager::GetInstance()->Release(this);
+ }
+
+ void *ReRenderedGlyph::GetMutableData()
+ {
+ return m_data;
+ }
+
+ GpRenderedGlyphMetrics &ReRenderedGlyph::GetMutableMetrics()
+ {
+ return m_metrics;
+ }
+
+ ReRenderedGlyph *ReRenderedGlyph::Create(unsigned int width, unsigned int height, bool aa)
+ {
+ size_t pitchRequired = 0;
+ if (aa)
+ pitchRequired = (width + 1) / 2;
+ else
+ pitchRequired = (width + 7) / 8;
+
+ pitchRequired = pitchRequired + (GP_SYSTEM_MEMORY_ALIGNMENT - 1);
+ pitchRequired -= pitchRequired % GP_SYSTEM_MEMORY_ALIGNMENT;
+
+ size_t baseRequired = sizeof(ReRenderedGlyph);
+ baseRequired = baseRequired + (GP_SYSTEM_MEMORY_ALIGNMENT - 1);
+ baseRequired -= baseRequired % GP_SYSTEM_MEMORY_ALIGNMENT;
+
+ size_t totalRequired = baseRequired + pitchRequired * height;
+ void *storage = MemoryManager::GetInstance()->Alloc(totalRequired);
+ if (!storage)
+ return nullptr;
+
+ uint8_t *data = static_cast(storage) + baseRequired;
+ memset(data, 0, pitchRequired * height);
+
+ return new (storage) ReRenderedGlyph(data, width, height, pitchRequired, totalRequired - baseRequired);
+ }
+
+ ReRenderedGlyph::ReRenderedGlyph(void *data, unsigned int width, unsigned int height, size_t pitch, size_t dataSize)
+ : m_data(data)
+ , m_dataSize(dataSize)
+ {
+ m_metrics.m_glyphWidth = width;
+ m_metrics.m_glyphHeight = height;
+ m_metrics.m_glyphDataPitch = pitch;
+ }
+
FontRenderer *FontRenderer::GetInstance()
{
return FontRendererImpl::GetInstance();
diff --git a/PortabilityLayer/InflateStream.cpp b/PortabilityLayer/InflateStream.cpp
index a05d653..619a65c 100644
--- a/PortabilityLayer/InflateStream.cpp
+++ b/PortabilityLayer/InflateStream.cpp
@@ -1,5 +1,6 @@
#include "InflateStream.h"
#include "DeflateCodec.h"
+#include "PLCore.h"
#include
#include
@@ -22,7 +23,7 @@ namespace PortabilityLayer
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
private:
@@ -222,10 +223,10 @@ namespace PortabilityLayer
return m_decompressedPos;
}
- void InflateStreamImpl::Close()
+ void InflateStreamImpl::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
this->~InflateStreamImpl();
- free(this);
+ DisposePtr(this);
}
void InflateStreamImpl::Flush()
@@ -238,7 +239,7 @@ namespace PortabilityLayer
if (!inflateContext)
return nullptr;
- void *storage = malloc(sizeof(InflateStreamImpl));
+ void *storage = NewPtr(sizeof(InflateStreamImpl));
if (!storage)
{
inflateContext->Destroy();
diff --git a/PortabilityLayer/MMBlock.cpp b/PortabilityLayer/MMBlock.cpp
deleted file mode 100644
index 3902d6e..0000000
--- a/PortabilityLayer/MMBlock.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "MMBlock.h"
-
-namespace PortabilityLayer
-{
- size_t MMBlock::AlignedSize()
- {
- const size_t paddedSize = sizeof(MMBlock) + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
- const size_t paddedSizeTruncated = paddedSize - (paddedSize % GP_SYSTEM_MEMORY_ALIGNMENT);
-
- return paddedSizeTruncated;
- }
-}
diff --git a/PortabilityLayer/MMBlock.h b/PortabilityLayer/MMBlock.h
deleted file mode 100644
index 7e9ef0c..0000000
--- a/PortabilityLayer/MMBlock.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-#ifndef __PL_MM_BLOCK_H__
-#define __PL_MM_BLOCK_H__
-
-#include
-
-#include "CoreDefs.h"
-#include "SmallestInt.h"
-
-namespace PortabilityLayer
-{
- struct MMBlock
- {
- SmallestUInt::ValueType_t m_offsetFromAllocLocation;
-
- static size_t AlignedSize();
- };
-}
-
-#endif
diff --git a/PortabilityLayer/MemReaderStream.cpp b/PortabilityLayer/MemReaderStream.cpp
index cf051b6..9d5aad8 100644
--- a/PortabilityLayer/MemReaderStream.cpp
+++ b/PortabilityLayer/MemReaderStream.cpp
@@ -104,7 +104,7 @@ namespace PortabilityLayer
return static_cast(m_loc);
}
- void MemReaderStream::Close()
+ void MemReaderStream::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
}
@@ -128,7 +128,7 @@ namespace PortabilityLayer
return new (storage) MemBufferReaderStream(buffer, size);
}
- void MemBufferReaderStream::Close()
+ void MemBufferReaderStream::GP_ASYNCIFY_PARANOID_NAMED(Close)()
{
this->~MemBufferReaderStream();
MemoryManager::GetInstance()->Release(this);
diff --git a/PortabilityLayer/MemReaderStream.h b/PortabilityLayer/MemReaderStream.h
index b73dc9b..35f0dc7 100644
--- a/PortabilityLayer/MemReaderStream.h
+++ b/PortabilityLayer/MemReaderStream.h
@@ -23,7 +23,7 @@ namespace PortabilityLayer
bool SeekEnd(GpUFilePos_t loc) override;
GpUFilePos_t Size() const override;
GpUFilePos_t Tell() const override;
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
void Flush() override;
private:
@@ -41,7 +41,7 @@ namespace PortabilityLayer
static MemBufferReaderStream *Create(void *buffer, size_t size);
- void Close() override;
+ void GP_ASYNCIFY_PARANOID_NAMED(Close)() override;
private:
MemBufferReaderStream() GP_DELETED;
diff --git a/PortabilityLayer/MemoryManager.cpp b/PortabilityLayer/MemoryManager.cpp
index 5697df2..6fba318 100644
--- a/PortabilityLayer/MemoryManager.cpp
+++ b/PortabilityLayer/MemoryManager.cpp
@@ -1,8 +1,9 @@
#include "MemoryManager.h"
-#include "MMBlock.h"
#include "MMHandleBlock.h"
#include "ResourceCompiledRef.h"
#include "ResourceManager.h"
+#include "IGpAllocator.h"
+#include "PLDrivers.h"
#include
#include
@@ -28,7 +29,6 @@ namespace PortabilityLayer
static MemoryManagerImpl *GetInstance();
private:
-
static MemoryManagerImpl ms_instance;
};
@@ -42,75 +42,17 @@ namespace PortabilityLayer
void *MemoryManagerImpl::Realloc(void *buf, size_t newSize)
{
- assert(buf != nullptr);
-
- const size_t mmBlockSize = MMBlock::AlignedSize();
- uint8_t *oldBufBytes = static_cast(buf);
- const MMBlock *oldBufMMBlock = reinterpret_cast(oldBufBytes - MMBlock::AlignedSize());
-
- const size_t oldBufOffsetFromAlignLoc = oldBufMMBlock->m_offsetFromAllocLocation;
- uint8_t *oldBufBase = oldBufBytes - MMBlock::AlignedSize() - oldBufOffsetFromAlignLoc;
-
- const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
- if (SIZE_MAX - newSize < mmBlockSizeWithMaxPadding)
- return nullptr;
-
- const size_t newBufferSize = newSize + mmBlockSizeWithMaxPadding;
- uint8_t *newBuffer = static_cast(realloc(oldBufBase, newSize + mmBlockSizeWithMaxPadding));
- if (!newBuffer)
- return nullptr;
-
- const intptr_t offsetFromAlignPoint = reinterpret_cast(newBuffer) & static_cast(GP_SYSTEM_MEMORY_ALIGNMENT - 1);
- intptr_t alignPadding = 0;
- if (offsetFromAlignPoint != 0)
- alignPadding = static_cast(GP_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint;
-
- // Check if the alignment changed, if so relocate
- if (static_cast(alignPadding) != oldBufOffsetFromAlignLoc)
- memmove(newBuffer + alignPadding, newBuffer + oldBufOffsetFromAlignLoc, MMBlock::AlignedSize() + newSize);
-
- MMBlock *newMMBlock = reinterpret_cast(newBuffer + alignPadding);
- newMMBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding);
-
- return newBuffer + alignPadding + MMBlock::AlignedSize();
+ return PLDrivers::GetAlloc()->Realloc(buf, newSize);
}
void *MemoryManagerImpl::Alloc(size_t size)
{
- if (size == 0)
- return nullptr;
-
- const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + GP_SYSTEM_MEMORY_ALIGNMENT - 1;
- if (SIZE_MAX - size < mmBlockSizeWithMaxPadding)
- return nullptr;
-
- uint8_t *buffer = static_cast(malloc(size + mmBlockSizeWithMaxPadding));
- if (!buffer)
- return nullptr;
-
- const intptr_t offsetFromAlignPoint = reinterpret_cast(buffer) & static_cast(GP_SYSTEM_MEMORY_ALIGNMENT - 1);
- intptr_t alignPadding = 0;
- if (offsetFromAlignPoint != 0)
- alignPadding = static_cast(GP_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint;
-
- MMBlock *mmBlock = reinterpret_cast(buffer + alignPadding);
- mmBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding);
-
- return buffer + alignPadding + MMBlock::AlignedSize();
+ return PLDrivers::GetAlloc()->Realloc(nullptr, size);
}
void MemoryManagerImpl::Release(void *buf)
{
- if (!buf)
- return;
-
- const size_t mmBlockSize = MMBlock::AlignedSize();
-
- uint8_t *bytes = static_cast(buf);
- const MMBlock *mmBlock = reinterpret_cast(bytes - MMBlock::AlignedSize());
-
- void *freeLoc = bytes - MMBlock::AlignedSize() - mmBlock->m_offsetFromAllocLocation;
- free(freeLoc);
+ PLDrivers::GetAlloc()->Realloc(buf, 0);
}
MMHandleBlock *MemoryManagerImpl::AllocHandle(size_t size)
diff --git a/PortabilityLayer/MemoryManager.h b/PortabilityLayer/MemoryManager.h
index 5d56fe4..0b0baf2 100644
--- a/PortabilityLayer/MemoryManager.h
+++ b/PortabilityLayer/MemoryManager.h
@@ -1,10 +1,10 @@
#pragma once
-#ifndef __PL_MEMORY_MANAGER_H__
-#define __PL_MEMORY_MANAGER_H__
#include
#include
+struct IGpAllocator;
+
namespace PortabilityLayer
{
struct MMHandleBlock;
@@ -50,5 +50,3 @@ namespace PortabilityLayer
return objectHdl;
}
}
-
-#endif
diff --git a/PortabilityLayer/MenuManager.cpp b/PortabilityLayer/MenuManager.cpp
index a2b565e..7ba0c94 100644
--- a/PortabilityLayer/MenuManager.cpp
+++ b/PortabilityLayer/MenuManager.cpp
@@ -155,7 +155,7 @@ namespace PortabilityLayer
bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) override;
void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) GP_ASYNCIFY_PARANOID_OVERRIDE;
- void PopupMenuSelect(const THandle