mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-04-29 23:41:38 -06:00
Save preferences as json
Preferences have keys as defined in ht.h. These keys can be used to read/write preferences. Preferences are saved in a .json on the disk. This is much easier to work with than the old presences binary structures as it doesn’t require preference versioning.
This commit is contained in:
parent
122a2d198f
commit
71dd4eb5b5
308
game/game.cpp
308
game/game.cpp
@ -275,27 +275,27 @@ bool Game::Init(int imm)
|
||||
|
||||
// Load prefs first
|
||||
|
||||
LoadPreferences();
|
||||
if (!LoadPreferences())
|
||||
return false;
|
||||
|
||||
// Suck what we can from preferences
|
||||
// Suck what we can from preferences
|
||||
|
||||
gtGameSpeed = gprefsInit.ctGameSpeed;
|
||||
gfLassoSelection = gprefsInit.fLassoSelection != 0;
|
||||
gnHueOffset = gprefsInit.nHueOffset;
|
||||
gnSatMultiplier = gprefsInit.nSatMultiplier;
|
||||
gnLumOffset = gprefsInit.nLumOffset;
|
||||
strncpyz(gszUsername, gprefsInit.szUsername, sizeof(gszUsername));
|
||||
strncpyz(gszPassword, gprefsInit.szPassword, sizeof(gszPassword));
|
||||
strncpyz(gszToken, gprefsInit.szToken, sizeof(gszToken));
|
||||
gfAnonymous = (gprefsInit.fAnonymous != 0);
|
||||
gwfPerfOptions = gprefsInit.wfPerfOptions;
|
||||
gwfHandicap = gprefsInit.wfHandicap;
|
||||
gkey = gprefsInit.key;
|
||||
gnDemoRank = gprefsInit.nDemoRank;
|
||||
gnScrollSpeed = gprefsInit.nScrollSpeed;
|
||||
gfIgnoreBluetoothWarning = (gprefsInit.wfPrefs & kfPrefIgnoreBluetoothWarning) ? true : false;
|
||||
strncpyz(gszAskURL, gprefsInit.szAskURL, sizeof(gszAskURL));
|
||||
strncpyz(gszDeviceId, gprefsInit.szDeviceId, sizeof(gszDeviceId));
|
||||
gtGameSpeed = gpprefs->GetInteger(knPrefGameSpeed);
|
||||
gfLassoSelection = gpprefs->GetBool(kfPrefLassoSelection);
|
||||
gnHueOffset = gpprefs->GetInteger(knPrefHueOffset);
|
||||
gnSatMultiplier = gpprefs->GetInteger(knPrefSatMultiplier);
|
||||
gnLumOffset = gpprefs->GetInteger(knPrefLumOffset);
|
||||
strncpy(gszUsername, gpprefs->GetString(kszPrefUsername), sizeof(gszUsername));
|
||||
strncpy(gszPassword, gpprefs->GetString(kszPrefPassword), sizeof(gszPassword));
|
||||
strncpy(gszToken, gpprefs->GetString(kszPrefToken), sizeof(gszToken));
|
||||
gfAnonymous = gpprefs->GetBool(kfPrefAnonymous);
|
||||
gwfPerfOptions = (word)gpprefs->GetInteger(kwfPrefPerfOptions);
|
||||
gwfHandicap = (word)gpprefs->GetInteger(kwfPrefHandicap);
|
||||
gnDemoRank = gpprefs->GetInteger(knPrefDemoRank);
|
||||
gnScrollSpeed = gpprefs->GetFloat(knPrefScrollSpeed);
|
||||
// gfIgnoreBluetoothWarning = gpprefs->GetBool(kfPrefIgnoreBluetoothWarning);
|
||||
strncpy(gszAskURL, gpprefs->GetString(kszPrefAskUrl), sizeof(gszAskURL));
|
||||
strncpy(gszDeviceId, gpprefs->GetString(kszPrefDeviceId), sizeof(gszDeviceId));
|
||||
|
||||
// Temp buffer used for several things, including decompression, TBitmap compiling.
|
||||
|
||||
@ -420,9 +420,9 @@ bool Game::Init(int imm)
|
||||
// Init sound system
|
||||
|
||||
gsndm.Init();
|
||||
if (gprefsInit.nVolume != (word)-1)
|
||||
gsndm.SetVolume(gprefsInit.nVolume);
|
||||
gsndm.Enable((gprefsInit.wfPrefs & kfPrefSoundMuted) == 0);
|
||||
if (gpprefs->GetInteger(knPrefVolume) != (word)-1)
|
||||
gsndm.SetVolume(gpprefs->GetInteger(knPrefVolume));
|
||||
gsndm.Enable(!gpprefs->GetBool(kfPrefSoundMuted));
|
||||
|
||||
// Clear out stale save games
|
||||
|
||||
@ -1071,17 +1071,17 @@ bool Game::InitDisplay(int immRequested)
|
||||
bool fMatchesPrefs = true;
|
||||
ModeInfo mode;
|
||||
gpdisp->GetModeInfo(m_amm[immBest].imode, &mode);
|
||||
if (mode.cx != gprefsInit.cxModeBest)
|
||||
if (mode.cx != gpprefs->GetInteger(knPrefCxModeBest))
|
||||
fMatchesPrefs = false;
|
||||
if (mode.cy != gprefsInit.cyModeBest)
|
||||
if (mode.cy != gpprefs->GetInteger(knPrefCyModeBest))
|
||||
fMatchesPrefs = false;
|
||||
if (mode.nDepth != gprefsInit.nDepthModeBest)
|
||||
if (mode.nDepth != gpprefs->GetInteger(knPrefDepthModeBest))
|
||||
fMatchesPrefs = false;
|
||||
if (mode.nDegreeOrientation != gprefsInit.nDegreeOrientationBest)
|
||||
if (mode.nDegreeOrientation != gpprefs->GetInteger(knPrefDegreeOrientationBest))
|
||||
fMatchesPrefs = false;
|
||||
if (m_amm[immBest].nDepthData != gprefsInit.nDepthDataBest)
|
||||
if (m_amm[immBest].nDepthData != gpprefs->GetInteger(knPrefDepthDataBest))
|
||||
fMatchesPrefs = false;
|
||||
if (m_amm[immBest].nSizeData != gprefsInit.nSizeDataBest)
|
||||
if (m_amm[immBest].nSizeData != gpprefs->GetInteger(knPrefSizeDataBest))
|
||||
fMatchesPrefs = false;
|
||||
if (fMatchesPrefs) {
|
||||
// Looks like there hasn't been a config change (new data / new device) so try
|
||||
@ -1091,17 +1091,17 @@ bool Game::InitDisplay(int immRequested)
|
||||
ModeMatch *pmmT = &m_amm[immT];
|
||||
ModeInfo modeT;
|
||||
gpdisp->GetModeInfo(pmmT->imode, &modeT);
|
||||
if (modeT.cx != gprefsInit.cxModeLast)
|
||||
if (modeT.cx != gpprefs->GetInteger(knPrefCxModeLast))
|
||||
continue;
|
||||
if (modeT.cy != gprefsInit.cyModeLast)
|
||||
if (modeT.cy != gpprefs->GetInteger(knPrefCyModeLast))
|
||||
continue;
|
||||
if (modeT.nDepth != gprefsInit.nDepthModeLast)
|
||||
if (modeT.nDepth != gpprefs->GetInteger(knPrefDepthModeLast))
|
||||
continue;
|
||||
if (modeT.nDegreeOrientation != gprefsInit.nDegreeOrientationLast)
|
||||
if (modeT.nDegreeOrientation != gpprefs->GetInteger(knPrefDegreeOrientationLast))
|
||||
continue;
|
||||
if (pmmT->nDepthData != gprefsInit.nDepthDataLast)
|
||||
if (pmmT->nDepthData != gpprefs->GetInteger(knPrefDepthDataLast))
|
||||
continue;
|
||||
if (pmmT->nSizeData != gprefsInit.nSizeDataLast)
|
||||
if (pmmT->nSizeData != gpprefs->GetInteger(knPrefSizeDataLast))
|
||||
continue;
|
||||
immNew = immT;
|
||||
break;
|
||||
@ -2054,6 +2054,9 @@ void Game::Exit()
|
||||
|
||||
SavePreferences();
|
||||
|
||||
delete gpprefs;
|
||||
gpprefs = NULL;
|
||||
|
||||
Status("Exit Simulation (one-time)...");
|
||||
gsim.OneTimeExit();
|
||||
|
||||
@ -2449,219 +2452,108 @@ void Game::SetGameSpeed(int t)
|
||||
}
|
||||
|
||||
// Preferences support.
|
||||
//
|
||||
// Note always save and load assuming a storage format of big endian.
|
||||
// That way we don't have a headache when someone upgrades from a 68K Palm to a
|
||||
// ARM Palm with ARM HT and then HotSyncs, restoring a little endian preferences database.
|
||||
|
||||
Preferences gprefsInit;
|
||||
Preferences *gpprefs;
|
||||
|
||||
void Game::LoadPreferences()
|
||||
bool Game::LoadPreferences()
|
||||
{
|
||||
// Try to load preferences. If this fails,
|
||||
// initialize preferences to default values.
|
||||
// gprefsInit is a global that holds the preferences that are used during initialization
|
||||
// It's a global because we won't be able to process all preferences related initialization
|
||||
// here.
|
||||
// Try to load preferences.
|
||||
|
||||
if (!LoadPreferences2()) {
|
||||
// Initialize preferences to default values
|
||||
gpprefs = PrefsFromFile();
|
||||
|
||||
memset(&gprefsInit, 0, sizeof(gprefsInit));
|
||||
Date date;
|
||||
HostGetCurrentDate(&date);
|
||||
gprefsInit.fAnonymous = 0;
|
||||
gprefsInit.nYearLastRun = date.nYear;
|
||||
gprefsInit.nMonthLastRun = date.nMonth;
|
||||
gprefsInit.nDayLastRun = date.nDay;
|
||||
gprefsInit.nVolume = (word)-1;
|
||||
gprefsInit.wfPerfOptions = kfPerfMax;
|
||||
gprefsInit.ctGameSpeed = kctUpdate / 2;
|
||||
gprefsInit.wfHandicap = kfHcapDefault;
|
||||
#if defined(WIN) && !defined(CE)
|
||||
gprefsInit.nScale = -1;
|
||||
#endif
|
||||
gprefsInit.nScrollSpeed = 1.0;
|
||||
strncpyz(gprefsInit.szAskURL, "http://", sizeof(gprefsInit.szAskURL));
|
||||
strncpyz(gprefsInit.szDeviceId, HostGenerateDeviceId(), sizeof(gprefsInit.szDeviceId));
|
||||
}
|
||||
}
|
||||
// Failed? Initialize preferences to default values
|
||||
|
||||
bool Game::LoadPreferences2()
|
||||
{
|
||||
Preferences prefs;
|
||||
int cbRead = HostLoadPreferences(&prefs, sizeof(prefs));
|
||||
if (cbRead != (int)BigDword(prefs.prefv.cbSize))
|
||||
return false;
|
||||
|
||||
switch (BigDword(prefs.prefv.dwVersion)) {
|
||||
case knVersionPreferencesV100:
|
||||
if (cbRead != sizeof(PreferencesV100))
|
||||
if (gpprefs == NULL) {
|
||||
gpprefs = PrefsFromDefaults();
|
||||
if (gpprefs == NULL)
|
||||
return false;
|
||||
if (!LoadPreferencesV100((PreferencesV100 *)&prefs))
|
||||
return false;
|
||||
strncpyz(gprefsInit.szDeviceId, HostGenerateDeviceId(), sizeof(gprefsInit.szDeviceId));
|
||||
return true;
|
||||
|
||||
case knVersionPreferencesV101:
|
||||
if (cbRead != sizeof(PreferencesV101))
|
||||
return false;
|
||||
return LoadPreferencesV101((PreferencesV101 *)&prefs);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Game::LoadPreferencesV100(PreferencesV100 *pprefsV100)
|
||||
{
|
||||
strncpyz(gprefsInit.szUsername, pprefsV100->szUsername,
|
||||
sizeof(gprefsInit.szUsername));
|
||||
strncpyz(gprefsInit.szPassword, pprefsV100->szPassword,
|
||||
sizeof(gprefsInit.szPassword));
|
||||
strncpyz(gprefsInit.szToken, pprefsV100->szToken,
|
||||
sizeof(gprefsInit.szToken));
|
||||
gprefsInit.fAnonymous = BigWord(pprefsV100->fAnonymous);
|
||||
gprefsInit.nYearLastRun = BigWord(pprefsV100->nYearLastRun);
|
||||
gprefsInit.nMonthLastRun = BigWord(pprefsV100->nMonthLastRun);
|
||||
gprefsInit.nDayLastRun = BigWord(pprefsV100->nDayLastRun);
|
||||
gprefsInit.nVolume = BigWord(pprefsV100->nVolume);
|
||||
gprefsInit.wfPrefs = BigWord(pprefsV100->wfPrefs);
|
||||
gprefsInit.wfPerfOptions = BigWord(pprefsV100->wfPerfOptions);
|
||||
gprefsInit.ctGameSpeed = BigDword(pprefsV100->ctGameSpeed);
|
||||
gprefsInit.fLassoSelection = BigWord(pprefsV100->fLassoSelection);
|
||||
gprefsInit.nHueOffset = BigWord(pprefsV100->nHueOffset);
|
||||
gprefsInit.nSatMultiplier = BigWord(pprefsV100->nSatMultiplier);
|
||||
gprefsInit.nLumOffset = BigWord(pprefsV100->nLumOffset);
|
||||
gprefsInit.cxModeBest = BigWord(pprefsV100->cxModeBest);
|
||||
gprefsInit.cyModeBest = BigWord(pprefsV100->cyModeBest);
|
||||
gprefsInit.nDepthModeBest = BigWord(pprefsV100->nDepthModeBest);
|
||||
gprefsInit.nDepthDataBest = BigWord(pprefsV100->nDepthDataBest);
|
||||
gprefsInit.nSizeDataBest = BigWord(pprefsV100->nSizeDataBest);
|
||||
gprefsInit.nDegreeOrientationBest = BigWord(pprefsV100->nDegreeOrientationBest);
|
||||
gprefsInit.cxModeLast = BigWord(pprefsV100->cxModeLast);
|
||||
gprefsInit.cyModeLast = BigWord(pprefsV100->cyModeLast);
|
||||
gprefsInit.nDepthModeLast = BigWord(pprefsV100->nDepthModeLast);
|
||||
gprefsInit.nDepthDataLast = BigWord(pprefsV100->nDepthDataLast);
|
||||
gprefsInit.nSizeDataLast = BigWord(pprefsV100->nSizeDataLast);
|
||||
gprefsInit.nDegreeOrientationLast = BigWord(pprefsV100->nDegreeOrientationLast);
|
||||
gprefsInit.nDemoRank = BigWord(pprefsV100->nDemoRank);
|
||||
gprefsInit.nScrollSpeed = pprefsV100->nScrollSpeed;
|
||||
strncpyz(gprefsInit.szAskURL, pprefsV100->szAskURL,
|
||||
sizeof(gprefsInit.szAskURL));
|
||||
|
||||
// Migrate obsolete handicap combinations
|
||||
|
||||
gprefsInit.wfHandicap = BigWord(pprefsV100->wfHandicap);
|
||||
if (gprefsInit.wfHandicap == 0) // old hard
|
||||
gprefsInit.wfHandicap = kfHcapHard; // new hard
|
||||
else if (gprefsInit.wfHandicap == (kfHcapDecreasedTimeToBuild | kfHcapIncreasedFirePower | kfHcapIncreasedMinerLoadValue | kfHcapShowEnemyBuildProgress | kfHcapShowEnemyResourceStatus))
|
||||
gprefsInit.wfHandicap = kfHcapEasy;
|
||||
else if (gprefsInit.wfHandicap == (kfHcapDecreasedTimeToBuild | kfHcapShowEnemyBuildProgress | kfHcapShowEnemyResourceStatus))
|
||||
gprefsInit.wfHandicap = kfHcapNormal;
|
||||
else if (gprefsInit.wfHandicap != kfHcapEasy && gprefsInit.wfHandicap != kfHcapNormal && gprefsInit.wfHandicap != kfHcapHard)
|
||||
gprefsInit.wfHandicap = kfHcapDefault;
|
||||
|
||||
gprefsInit.key = pprefsV100->key;
|
||||
#if defined(WIN) && !defined(CE)
|
||||
gprefsInit.nScale = BigWord(pprefsV100->nScale);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Game::LoadPreferencesV101(PreferencesV101 *pprefsV101)
|
||||
{
|
||||
// Since order is the same as V100 except for extra fields at the end, load V100 first
|
||||
if (!LoadPreferencesV100((PreferencesV100 *)pprefsV101))
|
||||
return false;
|
||||
|
||||
// PreferencesV101 has this new field, load it
|
||||
strncpyz(gprefsInit.szDeviceId, pprefsV101->szDeviceId, sizeof(gprefsInit.szDeviceId));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Game::SavePreferences()
|
||||
{
|
||||
// Only if we've gone through initialization ok
|
||||
// Only if we've gone through initialization ok
|
||||
|
||||
if (!(m_wf & kfGameInitDone))
|
||||
return;
|
||||
|
||||
// Always save the latest version of the preferences
|
||||
|
||||
Preferences prefs;
|
||||
gpprefs->Set(knPrefVersion, knVersionPreferencesLatest);
|
||||
gpprefs->Set(kszPrefUsername, gszUsername);
|
||||
gpprefs->Set(kszPrefPassword, gszPassword);
|
||||
gpprefs->Set(kszPrefToken, gszToken);
|
||||
gpprefs->Set(kfPrefAnonymous, gfAnonymous);
|
||||
|
||||
prefs.prefv.dwVersion = BigDword(knVersionPreferences);
|
||||
prefs.prefv.cbSize = BigDword(sizeof(prefs));
|
||||
strncpyz(prefs.szUsername, gszUsername, sizeof(prefs.szUsername));
|
||||
strncpyz(prefs.szPassword, gszPassword, sizeof(prefs.szPassword));
|
||||
strncpyz(prefs.szToken, gszToken, sizeof(prefs.szToken));
|
||||
prefs.fAnonymous = gfAnonymous ? BigWord(1) : 0;
|
||||
Date date;
|
||||
HostGetCurrentDate(&date);
|
||||
prefs.nYearLastRun = BigWord(date.nYear);
|
||||
prefs.nMonthLastRun = BigWord(date.nMonth);
|
||||
prefs.nDayLastRun = BigWord(date.nDay);
|
||||
prefs.nVolume = BigWord(gsndm.GetVolume());
|
||||
word wfPrefs = gsndm.IsEnabled() ? 0 : kfPrefSoundMuted;
|
||||
wfPrefs |= gfIgnoreBluetoothWarning ? kfPrefIgnoreBluetoothWarning : 0;
|
||||
prefs.wfPrefs = BigWord(wfPrefs);
|
||||
prefs.wfPerfOptions = BigWord((gwfPerfOptions & kfPerfAll) | (kfPerfMax & ~kfPerfAll));
|
||||
prefs.ctGameSpeed = BigDword((dword)gtGameSpeed);
|
||||
prefs.fLassoSelection = gfLassoSelection ? BigWord(1) : 0;
|
||||
prefs.nHueOffset = BigWord(gnHueOffset);
|
||||
prefs.nSatMultiplier = BigWord(gnSatMultiplier);
|
||||
prefs.nLumOffset = BigWord(gnLumOffset);
|
||||
prefs.wfHandicap = BigWord(gwfHandicap);
|
||||
prefs.nDemoRank = BigWord(gnDemoRank);
|
||||
prefs.nScrollSpeed = gnScrollSpeed;
|
||||
strncpyz(prefs.szAskURL, gszAskURL, sizeof(prefs.szAskURL));
|
||||
strncpyz(prefs.szDeviceId, gszDeviceId, sizeof(prefs.szDeviceId));
|
||||
gpprefs->Set(knPrefYearLastRun, date.nYear);
|
||||
gpprefs->Set(knPrefMonthLastRun, date.nMonth);
|
||||
gpprefs->Set(knPrefDayLastRun, date.nDay);
|
||||
|
||||
gpprefs->Set(knPrefVolume, gsndm.GetVolume());
|
||||
gpprefs->Set(kfPrefSoundMuted, !gsndm.IsEnabled());
|
||||
// gpprefs->Set(kfPrefIgnoreBluetoothWarning, gfIgnoreBluetoothWarning);
|
||||
gpprefs->Set(kwfPrefPerfOptions, BigWord((gwfPerfOptions & kfPerfAll) | (kfPerfMax & ~kfPerfAll)));
|
||||
gpprefs->Set(knPrefGameSpeed, gtGameSpeed);
|
||||
gpprefs->Set(kfPrefLassoSelection, gfLassoSelection);
|
||||
gpprefs->Set(knPrefHueOffset, gnHueOffset);
|
||||
gpprefs->Set(knPrefSatMultiplier, gnSatMultiplier);
|
||||
gpprefs->Set(knPrefLumOffset, gnLumOffset);
|
||||
gpprefs->Set(kwfPrefHandicap, gwfHandicap);
|
||||
gpprefs->Set(knPrefDemoRank, gnDemoRank);
|
||||
gpprefs->Set(knPrefScrollSpeed, gnScrollSpeed);
|
||||
gpprefs->Set(kszPrefAskUrl, gszAskURL);
|
||||
gpprefs->Set(kszPrefDeviceId, gszDeviceId);
|
||||
|
||||
if (gpdisp == NULL || m_immBest == -1) {
|
||||
prefs.cxModeBest = 0;
|
||||
prefs.cyModeBest = 0;
|
||||
prefs.nDepthModeBest = 0;
|
||||
prefs.nDepthDataBest = 0;
|
||||
prefs.nSizeDataBest = 0;
|
||||
prefs.nDegreeOrientationBest = 0;
|
||||
gpprefs->Set(knPrefCxModeBest, 0);
|
||||
gpprefs->Set(knPrefCyModeBest, 0);
|
||||
gpprefs->Set(knPrefDepthModeBest, 0);
|
||||
gpprefs->Set(knPrefDepthDataBest, 0);
|
||||
gpprefs->Set(knPrefSizeDataBest, 0);
|
||||
gpprefs->Set(knPrefDegreeOrientationBest, 0);
|
||||
} else {
|
||||
ModeInfo mode;
|
||||
gpdisp->GetModeInfo(m_amm[m_immBest].imode, &mode);
|
||||
prefs.cxModeBest = BigWord(mode.cx);
|
||||
prefs.cyModeBest = BigWord(mode.cy);
|
||||
prefs.nDepthModeBest = BigWord(mode.nDepth);
|
||||
prefs.nDepthDataBest = BigWord(m_amm[m_immBest].nDepthData);
|
||||
prefs.nSizeDataBest = BigWord(m_amm[m_immBest].nSizeData);
|
||||
prefs.nDegreeOrientationBest = BigWord(mode.nDegreeOrientation);
|
||||
gpprefs->Set(knPrefCxModeBest, mode.cx);
|
||||
gpprefs->Set(knPrefCyModeBest, mode.cy);
|
||||
gpprefs->Set(knPrefDepthModeBest, mode.nDepth);
|
||||
gpprefs->Set(knPrefDepthDataBest, m_amm[m_immBest].nDepthData);
|
||||
gpprefs->Set(knPrefSizeDataBest, m_amm[m_immBest].nSizeData);
|
||||
gpprefs->Set(knPrefDegreeOrientationBest, mode.nDegreeOrientation);
|
||||
}
|
||||
if (gpdisp == NULL || m_immCurrent == -1) {
|
||||
prefs.cxModeLast = 0;
|
||||
prefs.cyModeLast = 0;
|
||||
prefs.nDepthModeLast = 0;
|
||||
prefs.nDepthDataLast = 0;
|
||||
prefs.nSizeDataLast = 0;
|
||||
prefs.nDegreeOrientationLast = 0;
|
||||
gpprefs->Set(knPrefCxModeLast, 0);
|
||||
gpprefs->Set(knPrefCyModeLast, 0);
|
||||
gpprefs->Set(knPrefDepthModeLast, 0);
|
||||
gpprefs->Set(knPrefDepthDataLast, 0);
|
||||
gpprefs->Set(knPrefSizeDataLast, 0);
|
||||
gpprefs->Set(knPrefDegreeOrientationLast, 0);
|
||||
} else {
|
||||
ModeInfo mode;
|
||||
gpdisp->GetModeInfo(m_amm[m_immCurrent].imode, &mode);
|
||||
prefs.cxModeLast = BigWord(mode.cx);
|
||||
prefs.cyModeLast = BigWord(mode.cy);
|
||||
prefs.nDepthModeLast = BigWord(mode.nDepth);
|
||||
prefs.nDepthDataLast = BigWord(m_amm[m_immCurrent].nDepthData);
|
||||
prefs.nSizeDataLast = BigWord(m_amm[m_immCurrent].nSizeData);
|
||||
prefs.nDegreeOrientationLast = BigWord(mode.nDegreeOrientation);
|
||||
gpprefs->Set(knPrefCxModeLast, mode.cx);
|
||||
gpprefs->Set(knPrefCyModeLast, mode.cx);
|
||||
gpprefs->Set(knPrefDepthModeLast, mode.nDepth);
|
||||
gpprefs->Set(knPrefDepthDataLast, m_amm[m_immCurrent].nDepthData);
|
||||
gpprefs->Set(knPrefSizeDataLast, m_amm[m_immCurrent].nSizeData);
|
||||
gpprefs->Set(knPrefDegreeOrientationLast, mode.nDegreeOrientation);
|
||||
}
|
||||
prefs.key = gkey;
|
||||
|
||||
gpprefs->Set(kszPrefKey, (const char *)gkey.ab);
|
||||
|
||||
#if defined(WIN) && !defined(CE)
|
||||
if (gpdisp == NULL) {
|
||||
prefs.nScale = (word)-1;
|
||||
gpprefs->Set(knPrefScale, -1);
|
||||
} else {
|
||||
prefs.nScale = BigWord(gpdisp->GetScale());
|
||||
gpprefs->Set(knPrefScale, gpdisp->GetScale());
|
||||
}
|
||||
#endif
|
||||
|
||||
HostSavePreferences(&prefs, sizeof(prefs));
|
||||
|
||||
gpprefs->Save();
|
||||
}
|
||||
|
||||
bool Game::GetVar(const char *pszName, char *pszBuff, int cbBuff)
|
||||
|
||||
162
game/ht.h
162
game/ht.h
@ -266,6 +266,7 @@ typedef word CacheHandle; // hc
|
||||
#define secDrm secCode16
|
||||
#define secBtTransport secCode17
|
||||
#define secTexAtlasMgr secCode13
|
||||
#define secPreferences secCode9
|
||||
|
||||
// Performance options
|
||||
|
||||
@ -2273,8 +2274,6 @@ class MultiFormMgr;
|
||||
class InputUIForm;
|
||||
class Form;
|
||||
class Chatter;
|
||||
struct PreferencesV100;
|
||||
struct PreferencesV101;
|
||||
class Game // game
|
||||
{
|
||||
public:
|
||||
@ -2354,10 +2353,7 @@ public:
|
||||
private:
|
||||
bool CheckMemoryAvailable() secGame;
|
||||
void Suspend() secGame;
|
||||
void LoadPreferences() secGame;
|
||||
bool LoadPreferences2() secGame;
|
||||
bool LoadPreferencesV100(PreferencesV100 *pprefsV100);
|
||||
bool LoadPreferencesV101(PreferencesV101 *pprefsV101);
|
||||
bool LoadPreferences() secGame;
|
||||
bool InitDisplay(int imm) secGame;
|
||||
int FindBestModeMatch2(int nDepthData, int nSizeData, int nDepthMode, int cxWidthModeMin, int cxWidthModeMax, byte bfMatch) secGame;
|
||||
int FindBestModeMatch(int nSizeDataAbove) secGame;
|
||||
@ -8320,89 +8316,80 @@ bool DrmValidate() secDrm;
|
||||
// Preferences support
|
||||
//
|
||||
|
||||
// Preferences structures change over time. They get backed up by HotSync.
|
||||
// By carefully versioning the structure HT can load older preference versions
|
||||
// successfully. Every prefs structure has a version; these are meant to be supported
|
||||
// versions of preferences; meaning HT will load older versions of each versioned prefs
|
||||
// structure. They are also sub-versioned by size; this allows us during development to
|
||||
// add / remove fields and not have HT crash because it is assuming the wrong thing.
|
||||
|
||||
// prefs flags
|
||||
|
||||
#define kfPrefSoundMuted 1 // must be 1 for compatibility with fMute
|
||||
#define kfPrefIgnoreBluetoothWarning 2
|
||||
|
||||
// Preferences is stored in pack 2 alignment
|
||||
#pragma pack(push, 2)
|
||||
|
||||
// The header necessary on all preferences structures
|
||||
|
||||
struct PreferencesVersion
|
||||
{
|
||||
dword dwVersion;
|
||||
dword cbSize;
|
||||
};
|
||||
|
||||
// The versions of preferences structures HT can successfully read
|
||||
// Use fixed size datatypes
|
||||
|
||||
struct PreferencesV100 // prefs
|
||||
{
|
||||
PreferencesVersion prefv;
|
||||
char szUsername[kcbPlayerName];
|
||||
char szPassword[kcbPlayerName];
|
||||
char szToken[kcbTokenMax];
|
||||
word fAnonymous;
|
||||
word nYearLastRun; // demo time check
|
||||
word nMonthLastRun;
|
||||
word nDayLastRun;
|
||||
word nVolume; // volume
|
||||
word wfPrefs;
|
||||
word wfPerfOptions;
|
||||
word wfHandicap; // Difficulty-affecting flags
|
||||
int ctGameSpeed; // game speed
|
||||
word fLassoSelection;
|
||||
short nHueOffset; // HSL settings
|
||||
short nSatMultiplier;
|
||||
short nLumOffset;
|
||||
word cxModeBest; // Remember what mode / data is best. Check against in case config changes
|
||||
word cyModeBest;
|
||||
word nDepthModeBest;
|
||||
word nDepthDataBest;
|
||||
word nSizeDataBest;
|
||||
word nDegreeOrientationBest;
|
||||
word cxModeLast; // Remember what mode / data was chosen
|
||||
word cyModeLast;
|
||||
word nDepthModeLast;
|
||||
word nDepthDataLast;
|
||||
word nSizeDataLast;
|
||||
word nDegreeOrientationLast;
|
||||
Key key; // DRM key
|
||||
short nDemoRank;
|
||||
#if defined(WIN) && !defined(CE)
|
||||
short nScale;
|
||||
#endif
|
||||
double nScrollSpeed;
|
||||
char szAskURL[512];
|
||||
};
|
||||
|
||||
struct PreferencesV101 : public PreferencesV100
|
||||
{
|
||||
// md5 hash (16 bytes) to hex chars (32 bytes) plus zero terminator, rounded up to even number
|
||||
char szDeviceId[34];
|
||||
};
|
||||
typedef PreferencesV101 Preferences;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
// The current version
|
||||
|
||||
#define knVersionPreferencesV100 0x100
|
||||
#define knVersionPreferencesV101 0x101
|
||||
#define knVersionPreferences knVersionPreferencesV101
|
||||
extern Preferences gprefsInit;
|
||||
bool HostSavePreferences(void *pv, int cb) secHost;
|
||||
int HostLoadPreferences(void *pv, int cb) secHost;
|
||||
#define knVersionPreferencesV01 1
|
||||
#define knVersionPreferencesLatest knVersionPreferencesV01
|
||||
|
||||
// Keys
|
||||
|
||||
#define knPrefVersion "version"
|
||||
#define kszPrefUsername "username"
|
||||
#define kszPrefPassword "password"
|
||||
#define kszPrefToken "token"
|
||||
#define kfPrefAnonymous "anonymous"
|
||||
#define knPrefYearLastRun "year_last_run" // demo time check
|
||||
#define knPrefMonthLastRun "month_last_run"
|
||||
#define knPrefDayLastRun "day_last_run"
|
||||
#define kwfPrefPerfOptions "perf_options"
|
||||
#define knPrefVolume "volume" // in percent (0 - 100)
|
||||
#define kfPrefSoundMuted "sound_muted"
|
||||
#define kwfPrefHandicap "handicap" // Difficulty-affecting flags
|
||||
#define knPrefGameSpeed "game_speed"
|
||||
#define kfPrefLassoSelection "lassos_election"
|
||||
#define knPrefHueOffset "hue_offset" // HSL settings
|
||||
#define knPrefSatMultiplier "sat_multiplier"
|
||||
#define knPrefLumOffset "lum_offset"
|
||||
#define knPrefCxModeBest "cx_mode_best" // Remember what mode / data is best. Check against in case config
|
||||
#define knPrefCyModeBest "cy_mode_best"
|
||||
#define knPrefDepthModeBest "depth_mode_best"
|
||||
#define knPrefDepthDataBest "depth_data_best"
|
||||
#define knPrefSizeDataBest "size_data_best"
|
||||
#define knPrefDegreeOrientationBest "degree_orientation_best"
|
||||
|
||||
#define knPrefCxModeLast "cx_mode_last" // Remember what mode / data was chosen
|
||||
#define knPrefCyModeLast "cy_mode_best"
|
||||
#define knPrefDepthModeLast "depth_mode_last"
|
||||
#define knPrefDepthDataLast "depth_data_last"
|
||||
#define knPrefSizeDataLast "size_data_last"
|
||||
#define knPrefDegreeOrientationLast "degree_orientation_last"
|
||||
|
||||
#define kszPrefKey "key" // DRM key
|
||||
#define knPrefDemoRank "demo_rank"
|
||||
// #define knPrefScale "scale"
|
||||
#define knPrefScrollSpeed "scroll_speed"
|
||||
// #define kfPrefIgnoreBluetoothWarning "ignore_bluetooth_warning"
|
||||
#define kszPrefAskUrl "ask_url"
|
||||
#define kszPrefDeviceId "did"
|
||||
|
||||
class Preferences
|
||||
{
|
||||
public:
|
||||
Preferences() secPreferences;
|
||||
~Preferences() secPreferences;
|
||||
|
||||
bool InitFromFile() secPreferences;
|
||||
bool InitFromDeafults() secPreferences;
|
||||
|
||||
bool Save() secPreferences;
|
||||
const char *GetString(const char *key) secPreferences;
|
||||
int GetInteger(const char *key) secPreferences;
|
||||
float GetFloat(const char *key) secPreferences;
|
||||
bool GetBool(const char *key) secPreferences;
|
||||
|
||||
void Set(const char *key, const char *psz) secPreferences;
|
||||
void Set(const char *key, int n) secPreferences;
|
||||
void Set(const char *key, float n) secPreferences;
|
||||
void Set(const char *key, bool f) secPreferences;
|
||||
|
||||
private:
|
||||
json::JsonMap *m_pmap;
|
||||
char *m_pszJson;
|
||||
};
|
||||
Preferences *PrefsFromFile() secPreferences;
|
||||
Preferences *PrefsFromDefaults() secPreferences;
|
||||
|
||||
extern Preferences *gpprefs;
|
||||
|
||||
// Our in-game MessageBox
|
||||
|
||||
@ -8773,6 +8760,7 @@ void HostMessageBox(TCHAR *pszFormat, ...) secHost;
|
||||
Display *HostCreateDisplay() secDisplay;
|
||||
bool HostIsPenDown() secHost;
|
||||
const char *HostGetMainDataDir() secHost;
|
||||
const char *HostGetPrefsFilename() secHost;
|
||||
void HostSuspendModalLoop(DibBitmap *pbm) secHost;
|
||||
void HostNotEnoughMemory(bool fStorage, dword cbFree, dword cbNeed) secHost;
|
||||
bool HostGetOwnerName(char *pszBuff, int cb, bool fShowError) secHost;
|
||||
|
||||
152
game/preferences.cpp
Normal file
152
game/preferences.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include "ht.h"
|
||||
#include "yajl/wrapper/jsonbuilder.h"
|
||||
|
||||
namespace wi {
|
||||
|
||||
Preferences::Preferences() {
|
||||
m_pmap = NULL;
|
||||
m_pszJson = NULL;
|
||||
}
|
||||
|
||||
Preferences::~Preferences() {
|
||||
delete m_pmap;
|
||||
delete[] m_pszJson;
|
||||
}
|
||||
|
||||
|
||||
Preferences *PrefsFromFile() {
|
||||
Preferences *pprefs = new Preferences();
|
||||
Assert(pprefs != NULL, "out of memory!");
|
||||
if (pprefs == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!pprefs->InitFromFile()) {
|
||||
delete pprefs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pprefs;
|
||||
}
|
||||
|
||||
Preferences *PrefsFromDefaults() {
|
||||
Preferences *pprefs = new Preferences();
|
||||
Assert(pprefs != NULL, "out of memory!");
|
||||
if (pprefs == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!pprefs->InitFromDeafults()) {
|
||||
delete pprefs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pprefs;
|
||||
}
|
||||
|
||||
bool Preferences::InitFromFile() {
|
||||
FileHandle hf = HostOpenFile(HostGetPrefsFilename(), kfOfRead);
|
||||
if (hf == NULL)
|
||||
return NULL;
|
||||
|
||||
// Read length
|
||||
|
||||
dword cb;
|
||||
HostSeekFile(hf, 0, kfSeekEnd);
|
||||
cb = HostTellFile(hf);
|
||||
HostSeekFile(hf, 0, kfSeekSet);
|
||||
|
||||
// Read prefs
|
||||
|
||||
byte *pb = new byte[cb];
|
||||
if (HostReadFile(pb, cb, 1, hf) != 1) {
|
||||
HostCloseFile(hf);
|
||||
return false;
|
||||
}
|
||||
HostCloseFile(hf);
|
||||
|
||||
m_pszJson = (char *)pb;
|
||||
if (m_pszJson == NULL)
|
||||
return false;
|
||||
|
||||
json::JsonBuilder builder;
|
||||
builder.Start();
|
||||
|
||||
if (!builder.Update(m_pszJson, (int)strlen(m_pszJson)))
|
||||
return false;
|
||||
|
||||
json::JsonObject *obj = builder.End();
|
||||
if (obj == NULL)
|
||||
return false;
|
||||
|
||||
m_pmap = (json::JsonMap *)obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Preferences::InitFromDeafults() {
|
||||
m_pmap = new json::JsonMap();
|
||||
|
||||
Date date;
|
||||
HostGetCurrentDate(&date);
|
||||
Set(knPrefYearLastRun, date.nYear);
|
||||
Set(knPrefMonthLastRun, date.nMonth);
|
||||
Set(knPrefDayLastRun, date.nDay);
|
||||
|
||||
Set(kfPrefAnonymous, 0);
|
||||
Set(knPrefVolume, 100);
|
||||
Set(kfPrefSoundMuted, false);
|
||||
Set(kwfPrefPerfOptions, kfPerfMax);
|
||||
Set(knPrefGameSpeed, kctUpdate / 2);
|
||||
Set(kwfPrefHandicap, kfHcapDefault);
|
||||
Set(knPrefScrollSpeed, 1.0f);
|
||||
Set(kszPrefAskUrl, "http://");
|
||||
Set(kszPrefDeviceId, HostGenerateDeviceId());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Preferences::Save() {
|
||||
FileHandle hf = HostOpenFile(HostGetPrefsFilename(), kfOfWrite);
|
||||
if (hf == NULL)
|
||||
return false;
|
||||
const char *psz = m_pmap->ToJson();
|
||||
dword cb = (dword)strlen(psz);
|
||||
if (HostWriteFile((void *)psz, sizeof(char), cb, hf) < cb) {
|
||||
HostCloseFile(hf);
|
||||
return false;
|
||||
}
|
||||
HostCloseFile(hf);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *Preferences::GetString(const char *key) {
|
||||
return m_pmap->GetString(key);
|
||||
}
|
||||
|
||||
int Preferences::GetInteger(const char *key) {
|
||||
return m_pmap->GetInteger(key);
|
||||
}
|
||||
|
||||
float Preferences::GetFloat(const char *key) {
|
||||
return m_pmap->GetFloat(key);
|
||||
}
|
||||
|
||||
bool Preferences::GetBool(const char *key) {
|
||||
return m_pmap->GetBool(key);
|
||||
}
|
||||
|
||||
void Preferences::Set(const char *key, const char *psz) {
|
||||
m_pmap->SetObject(key, json::NewJsonString(psz, (int)strlen(psz)));
|
||||
}
|
||||
|
||||
void Preferences::Set(const char *key, int n) {
|
||||
m_pmap->SetObject(key, new json::JsonNumber(n));
|
||||
}
|
||||
|
||||
void Preferences::Set(const char *key, float n) {
|
||||
m_pmap->SetObject(key, new json::JsonNumber(n));
|
||||
}
|
||||
|
||||
void Preferences::Set(const char *key, bool f) {
|
||||
m_pmap->SetObject(key, new json::JsonBool(f));
|
||||
}
|
||||
|
||||
} // namespace wi
|
||||
@ -781,38 +781,6 @@ void HostGetCurrentDate(Date *pdate)
|
||||
pdate->nDay = ptm->tm_mday;
|
||||
}
|
||||
|
||||
bool HostSavePreferences(void *pv, int cb)
|
||||
{
|
||||
LOG() << HostHelpers::GetPrefsFilename();
|
||||
|
||||
FILE *pf = fopen(HostHelpers::GetPrefsFilename(), "wb");
|
||||
if (pf == NULL) {
|
||||
LOG() << "error opening preferences! " << errno;
|
||||
return false;
|
||||
}
|
||||
if (fwrite(pv, cb, 1, pf) != 1) {
|
||||
LOG() << "error writing preferences! " << errno;
|
||||
fclose(pf);
|
||||
return false;
|
||||
}
|
||||
fclose(pf);
|
||||
return true;
|
||||
}
|
||||
|
||||
int HostLoadPreferences(void *pv, int cb)
|
||||
{
|
||||
FILE *pf = fopen(HostHelpers::GetPrefsFilename(), "rb");
|
||||
if (pf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read prefs
|
||||
|
||||
int cbRead = (int)fread(pv, 1, cb, pf);
|
||||
fclose(pf);
|
||||
return cbRead;
|
||||
}
|
||||
|
||||
const char *HostGetMainDataDir()
|
||||
{
|
||||
return HostHelpers::GetMainDataDir();
|
||||
@ -823,6 +791,11 @@ const char *HostGetSaveGamesDir()
|
||||
return HostHelpers::GetSaveGamesDir();
|
||||
}
|
||||
|
||||
const char *HostGetPrefsFilename()
|
||||
{
|
||||
return HostHelpers::GetPrefsFilename();
|
||||
}
|
||||
|
||||
void HostNotEnoughMemory(bool fStorage, dword cbFree, dword cbNeed)
|
||||
{
|
||||
HostMessageBox(TEXT((char *)"Need %ld bytes of memory but only %ld bytes are free!"), cbNeed, cbFree);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user