diff --git a/Aerofoil/Aerofoil.vcxproj b/Aerofoil/Aerofoil.vcxproj
index 3b3db1c..00cb81e 100644
--- a/Aerofoil/Aerofoil.vcxproj
+++ b/Aerofoil/Aerofoil.vcxproj
@@ -177,6 +177,7 @@
+
diff --git a/Aerofoil/Aerofoil.vcxproj.filters b/Aerofoil/Aerofoil.vcxproj.filters
index 3f6d759..eda19b8 100644
--- a/Aerofoil/Aerofoil.vcxproj.filters
+++ b/Aerofoil/Aerofoil.vcxproj.filters
@@ -150,6 +150,9 @@
Header Files
+
+ Header Files
+
diff --git a/Aerofoil/GpAppEnvironment.cpp b/Aerofoil/GpAppEnvironment.cpp
index bde43d5..a8ce647 100644
--- a/Aerofoil/GpAppEnvironment.cpp
+++ b/Aerofoil/GpAppEnvironment.cpp
@@ -142,6 +142,7 @@ void GpAppEnvironment::InitializeApplicationState()
{
GpAppInterface_Get()->PL_HostDisplayDriver_SetInstance(m_displayDriver);
GpAppInterface_Get()->PL_HostAudioDriver_SetInstance(m_audioDriver);
+ GpAppInterface_Get()->PL_HostInputDriver_SetInstances(m_inputDrivers, m_numInputDrivers);
GpAppInterface_Get()->PL_InstallHostSuspendHook(GpAppEnvironment::StaticSuspendHookFunc, this);
GpAppInterface_Get()->PL_HostFontHandler_SetInstance(m_fontHandler);
diff --git a/GpApp/Externs.h b/GpApp/Externs.h
index f4783f5..79d4ca3 100644
--- a/GpApp/Externs.h
+++ b/GpApp/Externs.h
@@ -96,7 +96,6 @@ typedef struct
long wasGPFlipMap;
long wasGPFaceLeftMap, wasGPFaceRightMap;
short wasVolume;
- short prefVersion;
short wasMaxFiles;
short wasEditH, wasEditV;
short wasMapH, wasMapV;
@@ -175,8 +174,10 @@ Boolean CheckFileError (short, const PLPasStr &); // --- File Error.c
THandle LoadHouseResource(const PortabilityLayer::ResTypeID &resTypeID, int16_t resID); // --- HouseIO.c
-Boolean SavePrefs (prefsInfo *, short); // --- Prefs.c
-Boolean LoadPrefs (prefsInfo *, short);
+Boolean SavePrefs (prefsInfo *, THandle *modulePrefs, short); // --- Prefs.c
+Boolean LoadPrefs (prefsInfo *, THandle *modulePrefs, short);
+Boolean SaveModulePrefs (THandle currentModulePrefs, THandle *outModulePrefs);
+Boolean ApplyModulePrefs (THandle *modulePrefs);
void PasStringCopy (StringPtr, StringPtr); // --- StringUtils.c
short WhichStringFirst (StringPtr, StringPtr);
diff --git a/GpApp/GpAppInterface.cpp b/GpApp/GpAppInterface.cpp
index e1369e5..45345b1 100644
--- a/GpApp/GpAppInterface.cpp
+++ b/GpApp/GpAppInterface.cpp
@@ -7,6 +7,7 @@
#include "HostDisplayDriver.h"
#include "HostLogDriver.h"
#include "HostSystemServices.h"
+#include "HostInputDriver.h"
#include "HostVOSEventQueue.h"
#include "MenuManager.h"
#include "WindowManager.h"
@@ -21,6 +22,7 @@ public:
void PL_Render(IGpDisplayDriver *displayDriver) override;
void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) override;
void PL_HostDisplayDriver_SetInstance(IGpDisplayDriver *instance) override;
+ void PL_HostInputDriver_SetInstances(IGpInputDriver *const* instances, size_t numInstances) override;
void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) override;
void PL_HostAudioDriver_SetInstance(IGpAudioDriver *instance) override;
void PL_HostLogDriver_SetInstance(IGpLogDriver *instance) override;
@@ -72,6 +74,11 @@ void GpAppInterfaceImpl::PL_HostAudioDriver_SetInstance(IGpAudioDriver *instance
PortabilityLayer::HostAudioDriver::SetInstance(instance);
}
+void GpAppInterfaceImpl::PL_HostInputDriver_SetInstances(IGpInputDriver *const* instances, size_t numInstances)
+{
+ PortabilityLayer::HostInputDriver::SetInstances(instances, numInstances);
+}
+
void GpAppInterfaceImpl::PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance)
{
PortabilityLayer::HostFontHandler::SetInstance(instance);
diff --git a/GpApp/Main.cpp b/GpApp/Main.cpp
index 352d722..d573f8a 100644
--- a/GpApp/Main.cpp
+++ b/GpApp/Main.cpp
@@ -15,7 +15,7 @@
#include "WindowManager.h"
-#define kPrefsVersion 0x0036
+#define kPrefsVersion 0x0037
void ReadInPrefs (void);
@@ -45,6 +45,8 @@ extern Boolean isMapOpen, isToolsOpen, isCoordOpen;
extern Boolean doPrettyMap, doBitchDialogs;
//extern Boolean didValidation;
+THandle globalModulePrefs;
+
//============================================================== Functions
//-------------------------------------------------------------- ReadInPrefs
@@ -55,8 +57,10 @@ extern Boolean doPrettyMap, doBitchDialogs;
void ReadInPrefs (void)
{
prefsInfo thePrefs;
+
+ THandle modulePrefs;
- if (LoadPrefs(&thePrefs, kPrefsVersion))
+ if (LoadPrefs(&thePrefs, &modulePrefs, kPrefsVersion))
{
#ifdef COMPILEDEMO
PasStringCopy("\pDemo House", thisHouseName);
@@ -126,6 +130,13 @@ void ReadInPrefs (void)
doBackground = thePrefs.wasDoBackground;
doPrettyMap = thePrefs.wasPrettyMap;
doBitchDialogs = thePrefs.wasBitchDialogs;
+
+ if (modulePrefs)
+ ApplyModulePrefs(&modulePrefs);
+
+ globalModulePrefs.Dispose();
+ globalModulePrefs = modulePrefs;
+ modulePrefs = nullptr;
}
else
{
@@ -201,6 +212,8 @@ void ReadInPrefs (void)
doBackground = false;
doPrettyMap = false;
doBitchDialogs = true;
+
+ modulePrefs.Dispose();
}
if ((numNeighbors > 1) && (thisMac.constrainedScreen.right <= 512))
@@ -293,9 +306,13 @@ void WriteOutPrefs (void)
thePrefs.wasDoBackground = doBackground;
thePrefs.wasPrettyMap = doPrettyMap;
thePrefs.wasBitchDialogs = doBitchDialogs;
-
- if (!SavePrefs(&thePrefs, kPrefsVersion))
+
+ THandle modulePrefs;
+
+ if (!SaveModulePrefs(globalModulePrefs, &modulePrefs) || !SavePrefs(&thePrefs, &modulePrefs, kPrefsVersion))
SysBeep(1);
+
+ modulePrefs.Dispose();
UnivSetSoundVolume(wasVolume, thisMac.hasSM3);
}
@@ -325,6 +342,9 @@ int gpAppMain()
SetUpAppleEvents();
LoadCursors();
ReadInPrefs();
+
+ SpinCursor(2); // Tick once to let the display driver flush any resolution changes from prefs
+ FlushResolutionChange();
#if defined COMPILEDEMO
copyGood = true;
@@ -339,7 +359,7 @@ int gpAppMain()
else if (didValidation)
WriteOutPrefs(); SpinCursor(3);
#endif
-
+
// if ((thisMac.numScreens > 1) && (isUseSecondScreen))
// ReflectSecondMonitorEnvirons(false, true, true);
HandleDepthSwitching();
diff --git a/GpApp/Prefs.cpp b/GpApp/Prefs.cpp
index 2f63671..f8b0222 100644
--- a/GpApp/Prefs.cpp
+++ b/GpApp/Prefs.cpp
@@ -10,25 +10,42 @@
#include "Externs.h"
#include "Environ.h"
#include "FileManager.h"
+#include "IGpAudioDriver.h"
+#include "IGpDisplayDriver.h"
+#include "IGpInputDriver.h"
+#include "IGpPrefsHandler.h"
#include "IOStream.h"
+#include "MemoryManager.h"
+#include "HostAudioDriver.h"
+#include "HostDisplayDriver.h"
+#include "HostInputDriver.h"
#define kPrefCreatorType 'ozm5'
#define kPrefFileType 'gliP'
-#define kPrefFileName PSTR("Glider Prefs")
+#define kPrefFileName PSTR("Glider Prefs v2")
#define kDefaultPrefFName PSTR("Preferences")
#define kPrefsStringsID 160
#define kNewPrefsAlertID 160
#define kPrefsFNameIndex 1
+typedef struct modulePrefsListEntry
+{
+ THandle m_identifier;
+ THandle m_contents;
+ uint32_t m_version;
+} modulePrefsListEntry;
Boolean CanUseFindFolder (void);
-Boolean WritePrefs (const prefsInfo *);
-PLError_t ReadPrefs (prefsInfo *);
+Boolean WritePrefs (const prefsInfo *, short versionNow, THandle *theModulePrefs);
+PLError_t ReadPrefs (prefsInfo *thePrefs, short versionNeed, Boolean *isOldVersion, THandle *theModulePrefs);
Boolean DeletePrefs ();
void BringUpDeletePrefsAlert (void);
+THandle theModulePrefs;
+
+
//============================================================== Functions
//-------------------------------------------------------------- CanUseFindFolder
@@ -39,7 +56,7 @@ Boolean CanUseFindFolder (void)
//-------------------------------------------------------------- WritePrefs
-Boolean WritePrefs (const prefsInfo *thePrefs)
+Boolean WritePrefs (const prefsInfo *thePrefs, short versionNow, THandle modulePrefs)
{
PLError_t theErr;
PortabilityLayer::IOStream *fileStream;
@@ -66,15 +83,70 @@ Boolean WritePrefs (const prefsInfo *thePrefs)
CheckFileError(theErr, PSTR("Preferences"));
return(false);
}
-
+
+ uint32_t version = versionNow;
+ if (fileStream->Write(&version, sizeof(version)) != sizeof(version))
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(false);
+ }
+
byteCount = sizeof(*thePrefs);
if (fileStream->Write(thePrefs, byteCount) != byteCount)
{
CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
return(false);
}
+ uint32_t numEntries = 0;
+ if (modulePrefs)
+ numEntries = modulePrefs.MMBlock()->m_size / sizeof(modulePrefsListEntry);
+
+ if (fileStream->Write(&numEntries, sizeof(numEntries)) != sizeof(numEntries))
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(false);
+ }
+
+ for (uint32_t i = 0; i < numEntries; i++)
+ {
+ modulePrefsListEntry *entry = (*modulePrefs) + i;
+
+ uint32_t version = entry->m_version;
+
+ if (fileStream->Write(&version, sizeof(version)) != sizeof(version))
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(false);
+ }
+
+ THandle handles[2] = { entry->m_identifier.StaticCast(), entry->m_contents.StaticCast() };
+
+ for (int hi = 0; hi < 2; hi++)
+ {
+ uint32_t hSize = handles[hi].MMBlock()->m_size;
+
+ if (fileStream->Write(&hSize, sizeof(hSize)) != sizeof(hSize))
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(false);
+ }
+
+ if (fileStream->Write(*handles[hi], hSize) != hSize)
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(false);
+ }
+ }
+ }
+
fileStream->Close();
return(true);
@@ -82,19 +154,39 @@ Boolean WritePrefs (const prefsInfo *thePrefs)
//-------------------------------------------------------------- SavePrefs
-Boolean SavePrefs (prefsInfo *thePrefs, short versionNow)
+Boolean SavePrefs (prefsInfo *thePrefs, THandle *modulePrefs, short versionNow)
{
- thePrefs->prefVersion = versionNow;
-
- if (!WritePrefs(thePrefs))
+ if (!WritePrefs(thePrefs, versionNow, modulePrefs->StaticCast()))
return(false);
return(true);
}
+static void DestroyModulePrefs(THandle *theModulePrefs)
+{
+ if (!*theModulePrefs)
+ return;
+
+ modulePrefsListEntry *firstOldEntry = **theModulePrefs;
+
+ if (!firstOldEntry)
+ return;
+
+ size_t numOldPrefs = theModulePrefs->MMBlock()->m_size / sizeof(modulePrefsListEntry);
+
+ for (size_t i = 0; i < numOldPrefs; i++)
+ {
+ firstOldEntry[i].m_contents.Dispose();
+ firstOldEntry[i].m_identifier.Dispose();
+ firstOldEntry[i].~modulePrefsListEntry();
+ }
+
+ theModulePrefs->Dispose();
+}
+
//-------------------------------------------------------------- ReadPrefs
-PLError_t ReadPrefs (prefsInfo *thePrefs)
+PLError_t ReadPrefs (prefsInfo *thePrefs, short versionNeed, Boolean *isOldVersion, THandle *theModulePrefs)
{
PLError_t theErr;
PortabilityLayer::IOStream *fileStream;
@@ -102,6 +194,8 @@ PLError_t ReadPrefs (prefsInfo *thePrefs)
VFileSpec theSpecs;
Str255 fileName;
+ *isOldVersion = false;
+
PortabilityLayer::FileManager *fm = PortabilityLayer::FileManager::GetInstance();
PasStringCopy(kPrefFileName, fileName);
@@ -117,6 +211,21 @@ PLError_t ReadPrefs (prefsInfo *thePrefs)
CheckFileError(theErr, PSTR("Preferences"));
return(theErr);
}
+
+ uint32_t version = 0;
+ if (fileStream->Read(&version, sizeof(version)) != sizeof(version))
+ {
+ CheckFileError(theErr, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+
+ if (version != versionNeed)
+ {
+ *isOldVersion = true;
+ fileStream->Close();
+ return(PLErrors::kNone);
+ }
byteCount = sizeof(*thePrefs);
@@ -124,7 +233,81 @@ PLError_t ReadPrefs (prefsInfo *thePrefs)
{
CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
fileStream->Close();
- return(theErr);
+ return(PLErrors::kIOError);
+ }
+
+ uint32_t numModulePrefs = 0;
+ if (fileStream->Read(&numModulePrefs, sizeof(numModulePrefs)) != sizeof(numModulePrefs))
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+
+ DestroyModulePrefs(theModulePrefs);
+
+ if (numModulePrefs)
+ {
+ PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
+
+ *theModulePrefs = THandle(mm->AllocHandle(numModulePrefs * sizeof(modulePrefsListEntry)));
+
+ if (!*theModulePrefs)
+ {
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+
+ modulePrefsListEntry *firstNewEntry = **theModulePrefs;
+
+ for (size_t i = 0; i < numModulePrefs; i++)
+ new (firstNewEntry + i) modulePrefsListEntry();
+
+ for (uint32_t i = 0; i < numModulePrefs; i++)
+ {
+ if (fileStream->Read(&firstNewEntry[i].m_version, sizeof(firstNewEntry[i].m_version)) != sizeof(firstNewEntry[i].m_version))
+ {
+ DestroyModulePrefs(theModulePrefs);
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+
+ for (int subHandle = 0; subHandle < 2; subHandle++)
+ {
+ uint32_t handleSz;
+ if (fileStream->Read(&handleSz, sizeof(handleSz)) != sizeof(handleSz))
+ {
+ DestroyModulePrefs(theModulePrefs);
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+
+ PortabilityLayer::MMHandleBlock *mmBlock = mm->AllocHandle(handleSz);
+ if (!mmBlock)
+ {
+ DestroyModulePrefs(theModulePrefs);
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+
+ if (subHandle == 0)
+ firstNewEntry[i].m_identifier = THandle(mmBlock);
+ else
+ firstNewEntry[i].m_contents = THandle(mmBlock);
+
+ if (fileStream->Read(mmBlock->m_contents, handleSz) != handleSz)
+ {
+ DestroyModulePrefs(theModulePrefs);
+ CheckFileError(PLErrors::kIOError, PSTR("Preferences"));
+ fileStream->Close();
+ return(PLErrors::kIOError);
+ }
+ }
+ }
}
fileStream->Close();
@@ -147,14 +330,42 @@ Boolean DeletePrefs ()
return PortabilityLayer::FileManager::GetInstance()->DeleteFile(theSpecs.m_dir, theSpecs.m_name);
}
+//-------------------------------------------------------------- RunFunctionOnAllPrefsHandlers
+bool RunFunctionOnAllPrefsHandlers (void *context, bool (*func) (void *context, IGpPrefsHandler *handler))
+{
+ IGpPrefsHandler *ddHandler = PortabilityLayer::HostDisplayDriver::GetInstance()->GetPrefsHandler();
+ if (ddHandler && !func(context, ddHandler))
+ return false;
+
+ IGpPrefsHandler *adHandler = PortabilityLayer::HostAudioDriver::GetInstance()->GetPrefsHandler();
+ if (adHandler && !func(context, adHandler))
+ return false;
+
+ size_t numInputDrivers = PortabilityLayer::HostInputDriver::NumInstances();
+
+ for (size_t i = 0; i < numInputDrivers; i++)
+ {
+ IGpPrefsHandler *idHandler = PortabilityLayer::HostInputDriver::GetInstance(i)->GetPrefsHandler();
+ if (idHandler && !func(context, idHandler))
+ return false;
+ }
+
+ return true;
+}
+
+
+
//-------------------------------------------------------------- LoadPrefs
-Boolean LoadPrefs (prefsInfo *thePrefs, short versionNeed)
+Boolean LoadPrefs (prefsInfo *thePrefs, THandle *modulePrefs, short versionNeed)
{
PLError_t theErr;
Boolean noProblems;
+ Boolean isOldVersion = 0;
+
+ THandle mPrefs;
- theErr = ReadPrefs(thePrefs);
+ theErr = ReadPrefs(thePrefs, versionNeed, &isOldVersion, &mPrefs);
if (theErr == PLErrors::kFileNotFound)
return (false);
@@ -165,19 +376,164 @@ Boolean LoadPrefs (prefsInfo *thePrefs, short versionNeed)
noProblems = DeletePrefs();
return (false);
}
-
- if (thePrefs->prefVersion != versionNeed)
+
+ if (isOldVersion)
{
BringUpDeletePrefsAlert();
noProblems = DeletePrefs();
return(false);
}
+ *modulePrefs = mPrefs.StaticCast();
+
return (true);
}
//-------------------------------------------------------------- BringUpDeletePrefsAlert
+static THandle CloneHandle(THandle hdl)
+{
+ if (!hdl)
+ return THandle();
+
+ PortabilityLayer::MMHandleBlock *newHdl = PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(hdl.MMBlock()->m_size);
+ if (!newHdl)
+ return THandle();
+
+ memcpy(newHdl->m_contents, hdl.MMBlock()->m_contents, hdl.MMBlock()->m_size);
+
+ return THandle(newHdl);
+}
+
+struct SaveModulePrefsContext
+{
+ size_t m_numModulePrefs;
+ THandle m_newPrefs;
+};
+
+bool SaveModulePrefsWriteFunc(void *vcontext, const void *identifier, size_t identifierSize, const void *contents, size_t contentsSize, uint32_t version)
+{
+ PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
+
+ SaveModulePrefsContext *context = static_cast(vcontext);
+ modulePrefsListEntry *saveToEntry = nullptr;
+
+ for (size_t i = 0; i < context->m_numModulePrefs; i++)
+ {
+ modulePrefsListEntry *checkEntry = (*context->m_newPrefs) + i;
+ THandle candidateIdentHdl = checkEntry->m_identifier;
+ size_t candidateIdentSize = candidateIdentHdl.MMBlock()->m_size;
+
+ if (candidateIdentSize == identifierSize && !memcmp(*candidateIdentHdl, identifier, candidateIdentSize))
+ {
+ saveToEntry = checkEntry;
+ break;
+ }
+ }
+
+ if (!saveToEntry)
+ {
+ if (context->m_numModulePrefs == 0)
+ context->m_newPrefs = THandle(mm->AllocHandle(sizeof(modulePrefsListEntry)));
+ else
+ mm->ResizeHandle(context->m_newPrefs.MMBlock(), (context->m_numModulePrefs + 1) * sizeof(modulePrefsListEntry));
+
+ saveToEntry = (*context->m_newPrefs) + context->m_numModulePrefs;
+ new (saveToEntry) modulePrefsListEntry();
+
+ context->m_numModulePrefs++;
+ }
+
+ if (saveToEntry->m_contents)
+ saveToEntry->m_contents.Dispose();
+
+ if (!saveToEntry->m_identifier)
+ {
+ saveToEntry->m_identifier = THandle(mm->AllocHandle(identifierSize));
+ memcpy(*saveToEntry->m_identifier, identifier, identifierSize);
+ }
+
+ saveToEntry->m_contents = THandle(mm->AllocHandle(contentsSize));
+ memcpy(*saveToEntry->m_contents, contents, contentsSize);
+
+ saveToEntry->m_version = version;
+
+ return true;
+}
+
+bool SaveModulePrefsCallback(void *vcontext, IGpPrefsHandler *handler)
+{
+ return handler->SavePrefs(vcontext, SaveModulePrefsWriteFunc);
+}
+
+Boolean SaveModulePrefs(THandle currentModulePrefs, THandle *outModulePrefs)
+{
+ SaveModulePrefsContext context;
+
+ size_t numModulePrefs = 0;
+ THandle newPrefs;
+
+ if (currentModulePrefs)
+ {
+ numModulePrefs = currentModulePrefs.MMBlock()->m_size / sizeof(modulePrefsListEntry);
+ newPrefs = CloneHandle(currentModulePrefs).StaticCast();
+
+ modulePrefsListEntry *entries = *newPrefs;
+ for (size_t i = 0; i < numModulePrefs; i++)
+ {
+ entries[i].m_contents = CloneHandle(entries[i].m_contents.StaticCast()).StaticCast();
+ entries[i].m_identifier = CloneHandle(entries[i].m_identifier.StaticCast()).StaticCast();
+ }
+ }
+ else
+ newPrefs = THandle(PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(0));
+
+ context.m_newPrefs = newPrefs;
+ context.m_numModulePrefs = numModulePrefs;
+
+ bool savedOK = RunFunctionOnAllPrefsHandlers(&context, SaveModulePrefsCallback);
+
+ if (savedOK)
+ {
+ outModulePrefs->Dispose();
+ *outModulePrefs = context.m_newPrefs.StaticCast();
+ }
+
+ return savedOK;
+}
+
+//-------------------------------------------------------------- BringUpDeletePrefsAlert
+
+struct ApplyModulePrefsContext
+{
+ size_t m_numModulePrefs;
+ THandle m_newPrefs;
+};
+
+bool ApplyModulePrefsCallback(void *vcontext, IGpPrefsHandler *handler)
+{
+ ApplyModulePrefsContext *context = static_cast(vcontext);
+
+ const modulePrefsListEntry *entries = *(context->m_newPrefs);
+
+ for (size_t i = 0; i < context->m_numModulePrefs; i++)
+ handler->ApplyPrefs(*entries[i].m_identifier, entries[i].m_identifier.MMBlock()->m_size, *entries[i].m_contents, entries[i].m_contents.MMBlock()->m_size, entries[i].m_version);
+
+ return true;
+}
+
+Boolean ApplyModulePrefs (THandle *modulePrefs)
+{
+ ApplyModulePrefsContext context;
+
+ context.m_newPrefs = modulePrefs->StaticCast();
+ context.m_numModulePrefs = context.m_newPrefs.MMBlock()->m_size / sizeof(modulePrefsListEntry);
+
+ return RunFunctionOnAllPrefsHandlers(&context, ApplyModulePrefsCallback);
+}
+
+//-------------------------------------------------------------- BringUpDeletePrefsAlert
+
void BringUpDeletePrefsAlert (void)
{
short whoCares;
diff --git a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp
index 5fabe56..dfdb0ef 100644
--- a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp
+++ b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.cpp
@@ -10,6 +10,11 @@ void GpAudioDriverXAudio2::Shutdown()
delete this;
}
+IGpPrefsHandler *GpAudioDriverXAudio2::GetPrefsHandler() const
+{
+ return nullptr;
+}
+
const GpAudioDriverProperties &GpAudioDriverXAudio2::GetProperties() const
{
return m_properties;
diff --git a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h
index e931ed1..4a9c070 100644
--- a/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h
+++ b/GpAudioDriver_XAudio2/GpAudioDriverXAudio2.h
@@ -14,6 +14,8 @@ public:
void SetMasterVolume(uint32_t vol, uint32_t maxVolume) override;
void Shutdown() override;
+ IGpPrefsHandler *GetPrefsHandler() const override;
+
const GpAudioDriverProperties &GetProperties() const;
IXAudio2 *GetXA2() const;
IXAudio2MasteringVoice *GetMasteringVoice() const;
diff --git a/GpCommon/IGpAudioDriver.h b/GpCommon/IGpAudioDriver.h
index f3b16cb..9f77acb 100644
--- a/GpCommon/IGpAudioDriver.h
+++ b/GpCommon/IGpAudioDriver.h
@@ -3,6 +3,7 @@
#include
struct IGpAudioChannel;
+struct IGpPrefsHandler;
struct IGpAudioDriver
{
@@ -12,4 +13,6 @@ public:
virtual void SetMasterVolume(uint32_t vol, uint32_t maxVolume) = 0;
virtual void Shutdown() = 0;
+
+ virtual IGpPrefsHandler *GetPrefsHandler() const = 0;
};
diff --git a/GpCommon/IGpDisplayDriver.h b/GpCommon/IGpDisplayDriver.h
index 12348f9..e5439d2 100644
--- a/GpCommon/IGpDisplayDriver.h
+++ b/GpCommon/IGpDisplayDriver.h
@@ -5,6 +5,7 @@
struct IGpDisplayDriverSurface;
struct IGpCursor;
+struct IGpPrefsHandler;
struct GpDisplayDriverProperties;
struct GpDisplayDriverSurfaceEffects
@@ -45,6 +46,7 @@ public:
virtual void RequestResetVirtualResolution() = 0;
virtual const GpDisplayDriverProperties &GetProperties() const = 0;
+ virtual IGpPrefsHandler *GetPrefsHandler() const = 0;
};
inline GpDisplayDriverSurfaceEffects::GpDisplayDriverSurfaceEffects()
diff --git a/GpCommon/IGpInputDriver.h b/GpCommon/IGpInputDriver.h
index 6480331..cadd333 100644
--- a/GpCommon/IGpInputDriver.h
+++ b/GpCommon/IGpInputDriver.h
@@ -1,7 +1,11 @@
#pragma once
+struct IGpPrefsHandler;
+
struct IGpInputDriver
{
virtual void ProcessInput() = 0;
virtual void Shutdown() = 0;
+
+ virtual IGpPrefsHandler *GetPrefsHandler() const = 0;
};
diff --git a/GpCommon/IGpPrefsHandler.h b/GpCommon/IGpPrefsHandler.h
new file mode 100644
index 0000000..4bb065b
--- /dev/null
+++ b/GpCommon/IGpPrefsHandler.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include
+
+struct IGpPrefsHandler
+{
+ typedef bool (*WritePrefsFunc_t) (void *context, const void *identifier, size_t identifierSize, const void *contents, size_t contentsSize, uint32_t version);
+
+ virtual void ApplyPrefs(const void *identifier, size_t identifierSize, const void *contents, size_t contentsSize, uint32_t version) = 0;
+ virtual bool SavePrefs(void *context, WritePrefsFunc_t writeFunc) = 0;
+};
diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp
index 9933b53..1647510 100644
--- a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp
+++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp
@@ -21,6 +21,14 @@
static GpDisplayDriverSurfaceEffects gs_defaultEffects;
+static const char *kPrefsIdentifier = "GpDisplayDriverD3D11";
+static uint32_t kPrefsVersion = 1;
+
+struct GpDisplayDriverD3D11_Prefs
+{
+ bool m_isFullScreen;
+};
+
namespace GpBinarizedShaders
{
extern const unsigned char *g_drawQuadV_D3D11[2];
@@ -1449,6 +1457,29 @@ const GpDisplayDriverProperties &GpDisplayDriverD3D11::GetProperties() const
return m_properties;
}
+IGpPrefsHandler *GpDisplayDriverD3D11::GetPrefsHandler() const
+{
+ const IGpPrefsHandler *cPrefsHandler = this;
+ return const_cast(cPrefsHandler);
+}
+
+void GpDisplayDriverD3D11::ApplyPrefs(const void *identifier, size_t identifierSize, const void *contents, size_t contentsSize, uint32_t version)
+{
+ if (version == kPrefsVersion && identifierSize == strlen(kPrefsIdentifier) && !memcmp(identifier, kPrefsIdentifier, identifierSize))
+ {
+ const GpDisplayDriverD3D11_Prefs *prefs = static_cast(contents);
+ m_isFullScreenDesired = prefs->m_isFullScreen;
+ }
+}
+
+bool GpDisplayDriverD3D11::SavePrefs(void *context, IGpPrefsHandler::WritePrefsFunc_t writeFunc)
+{
+ GpDisplayDriverD3D11_Prefs prefs;
+ prefs.m_isFullScreen = m_isFullScreenDesired;
+
+ return writeFunc(context, kPrefsIdentifier, strlen(kPrefsIdentifier), &prefs, sizeof(prefs), kPrefsVersion);
+}
+
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
{
void *storage = malloc(sizeof(GpDisplayDriverD3D11));
diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h
index 201ead5..61ec143 100644
--- a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h
+++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h
@@ -4,12 +4,15 @@
#include "GpRingBuffer.h"
#include "IGpDisplayDriver.h"
+#include "IGpPrefsHandler.h"
#include "GpCoreDefs.h"
#include "GpDisplayDriverProperties.h"
#include "GpComPtr.h"
#include "GpPixelFormat.h"
+#include "IGpPrefsHandler.h"
+
struct GpWindowsGlobals;
struct IGpCursor_Win32;
struct IGpCursor;
@@ -30,7 +33,7 @@ struct ID3D11Texture2D;
struct ID3D11VertexShader;
-class GpDisplayDriverD3D11 : public IGpDisplayDriver
+class GpDisplayDriverD3D11 : public IGpDisplayDriver, public IGpPrefsHandler
{
public:
void Run() override;
@@ -54,6 +57,10 @@ public:
void RequestResetVirtualResolution() override;
const GpDisplayDriverProperties &GetProperties() const override;
+ IGpPrefsHandler *GetPrefsHandler() const override;
+
+ void ApplyPrefs(const void *identifier, size_t identifierSize, const void *contents, size_t contentsSize, uint32_t version) override;
+ bool SavePrefs(void *context, IGpPrefsHandler::WritePrefsFunc_t writeFunc) override;
static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties);
diff --git a/GpInputDriver_XInput/GpInputDriverXInput.cpp b/GpInputDriver_XInput/GpInputDriverXInput.cpp
index 0f4d8ef..7796bc4 100644
--- a/GpInputDriver_XInput/GpInputDriverXInput.cpp
+++ b/GpInputDriver_XInput/GpInputDriverXInput.cpp
@@ -76,6 +76,11 @@ void GpInputDriverXInput::Shutdown()
free(this);
}
+IGpPrefsHandler *GpInputDriverXInput::GetPrefsHandler() const
+{
+ return nullptr;
+}
+
GpInputDriverXInput *GpInputDriverXInput::Create(const GpInputDriverProperties &props)
{
void *storage = malloc(sizeof(GpInputDriverXInput));
diff --git a/GpInputDriver_XInput/GpInputDriverXInput.h b/GpInputDriver_XInput/GpInputDriverXInput.h
index c0981cd..971c504 100644
--- a/GpInputDriver_XInput/GpInputDriverXInput.h
+++ b/GpInputDriver_XInput/GpInputDriverXInput.h
@@ -13,6 +13,8 @@ public:
void ProcessInput() override;
void Shutdown() override;
+ IGpPrefsHandler *GetPrefsHandler() const override;
+
static GpInputDriverXInput *Create(const GpInputDriverProperties &props);
private:
diff --git a/PortabilityLayer/GpAppInterface.h b/PortabilityLayer/GpAppInterface.h
index 347742e..1b0b518 100644
--- a/PortabilityLayer/GpAppInterface.h
+++ b/PortabilityLayer/GpAppInterface.h
@@ -21,6 +21,7 @@
struct IGpAudioDriver;
struct IGpLogDriver;
+struct IGpInputDriver;
namespace PortabilityLayer
{
@@ -43,6 +44,7 @@ public:
virtual void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) = 0;
virtual void PL_HostDisplayDriver_SetInstance(IGpDisplayDriver *instance) = 0;
virtual void PL_HostLogDriver_SetInstance(IGpLogDriver *instance) = 0;
+ virtual void PL_HostInputDriver_SetInstances(IGpInputDriver *const* instances, size_t numInstances) = 0;
virtual void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) = 0;
virtual void PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance) = 0;
virtual void PL_HostVOSEventQueue_SetInstance(PortabilityLayer::HostVOSEventQueue *instance) = 0;
diff --git a/PortabilityLayer/HostInputDriver.cpp b/PortabilityLayer/HostInputDriver.cpp
new file mode 100644
index 0000000..8d59621
--- /dev/null
+++ b/PortabilityLayer/HostInputDriver.cpp
@@ -0,0 +1,23 @@
+#include "HostInputDriver.h"
+
+namespace PortabilityLayer
+{
+ size_t HostInputDriver::NumInstances()
+ {
+ return ms_numInstances;
+ }
+
+ IGpInputDriver *HostInputDriver::GetInstance(size_t index)
+ {
+ return ms_instances[index];
+ }
+
+ void HostInputDriver::SetInstances(IGpInputDriver *const* instances, size_t numInstances)
+ {
+ ms_instances = instances;
+ ms_numInstances = numInstances;
+ }
+
+ IGpInputDriver *const* HostInputDriver::ms_instances;
+ size_t HostInputDriver::ms_numInstances;
+}
diff --git a/PortabilityLayer/HostInputDriver.h b/PortabilityLayer/HostInputDriver.h
index 8f5379d..8593c1e 100644
--- a/PortabilityLayer/HostInputDriver.h
+++ b/PortabilityLayer/HostInputDriver.h
@@ -1,17 +1,18 @@
#pragma once
-#include "HostKeyID.h"
+struct IGpInputDriver;
namespace PortabilityLayer
{
class HostInputDriver
{
public:
-
- static HostInputDriver *GetInstance();
- static void SetInstance(HostInputDriver *instance);
+ static size_t NumInstances();
+ static IGpInputDriver *GetInstance(size_t index);
+ static void SetInstances(IGpInputDriver *const* instances, size_t numInstances);
private:
- static HostInputDriver *ms_instance;
+ static IGpInputDriver *const* ms_instances;
+ static size_t ms_numInstances;
};
}
diff --git a/PortabilityLayer/PLApplication.cpp b/PortabilityLayer/PLApplication.cpp
index 65504d2..7c2352f 100644
--- a/PortabilityLayer/PLApplication.cpp
+++ b/PortabilityLayer/PLApplication.cpp
@@ -1,24 +1,24 @@
-#include "PLApplication.h"
+#include "PLApplication.h"
#include "PLCore.h"
-#include "HostSystemServices.h"
-
-#include
-#include
-
-namespace PortabilityLayer
-{
- namespace Utils
- {
- void MakePStr(unsigned char *dest, size_t sz, const char *src)
- {
- assert(sz <= 255);
- dest[0] = static_cast(sz);
- memcpy(dest + 1, src, sz);
- }
- }
-}
-
-void SysBeep(int duration)
+#include "HostSystemServices.h"
+
+#include
+#include
+
+namespace PortabilityLayer
{
- PortabilityLayer::HostSystemServices::GetInstance()->Beep();
-}
+ namespace Utils
+ {
+ void MakePStr(unsigned char *dest, size_t sz, const char *src)
+ {
+ assert(sz <= 255);
+ dest[0] = static_cast(sz);
+ memcpy(dest + 1, src, sz);
+ }
+ }
+}
+
+void SysBeep(int duration)
+{
+ PortabilityLayer::HostSystemServices::GetInstance()->Beep();
+}
diff --git a/PortabilityLayer/PortabilityLayer.vcxproj b/PortabilityLayer/PortabilityLayer.vcxproj
index 32cc412..fcc1386 100644
--- a/PortabilityLayer/PortabilityLayer.vcxproj
+++ b/PortabilityLayer/PortabilityLayer.vcxproj
@@ -312,6 +312,7 @@
+
diff --git a/PortabilityLayer/PortabilityLayer.vcxproj.filters b/PortabilityLayer/PortabilityLayer.vcxproj.filters
index d715b21..ee488c6 100644
--- a/PortabilityLayer/PortabilityLayer.vcxproj.filters
+++ b/PortabilityLayer/PortabilityLayer.vcxproj.filters
@@ -728,5 +728,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file