Added options to use more than one save slot for quick saving (from Mr.Stalin) (#186)

This commit is contained in:
NovaRain
2018-09-06 07:01:14 +08:00
parent 6bd7d3ebca
commit 9d9d8ada49
3 changed files with 134 additions and 1 deletions
+8
View File
@@ -398,6 +398,14 @@ UseScrollingQuestsList=1
;Set to 1 to add additional pages of save slots ;Set to 1 to add additional pages of save slots
ExtraSaveSlots=0 ExtraSaveSlots=0
;To use more than one save slot for quick saving (F6 key) without picking a slot beforehand, set the next two lines
;AutoQuickSave sets how many save slots on a page you want to use for quick saving (valid range: 1..10)
;AutoQuickSavePage is the page number to use (valid range: 1..1000, only works if ExtraSaveSlots is enabled)
;The quick saves will be rotated from the first slot on the page to the n-th slot
;Set to 0 to disable
AutoQuickSave=0
AutoQuickSavePage=0
;Set to 1 to speed up the HP/AC counter animations ;Set to 1 to speed up the HP/AC counter animations
;Set to 2 to update the HP/AC counters instantly ;Set to 2 to update the HP/AC counters instantly
SpeedInterfaceCounterAnims=0 SpeedInterfaceCounterAnims=0
+24
View File
@@ -640,4 +640,28 @@ struct Window {
long drawFuncP; long drawFuncP;
}; };
#pragma pack(1)
struct LSData {
char signature[24];
short majorVer;
short minorVer;
char charR;
char playerName[32];
char comment[30];
char unused1;
short realMonth;
short realDay;
short realYear;
short unused2;
long realTime;
short gameMonth;
short gameDay;
short gameYear;
short unused3;
long gameTime;
short mapElev;
short mapNumber;
char mapName[16];
};
} }
+102 -1
View File
@@ -494,12 +494,113 @@ void EnableSuperSaving() {
MakeCalls(AddPageOffset03, {0x47E756}); MakeCalls(AddPageOffset03, {0x47E756});
} }
static void GetSaveFileTime(char* filename, FILETIME* ftSlot) {
char fname[65];
sprintf_s(fname, "%s\\%s", fo::var::patches, filename);
HANDLE hFile = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
GetFileTime(hFile, NULL, NULL, ftSlot);
CloseHandle(hFile);
} else {
ftSlot->dwHighDateTime = 0;
ftSlot->dwLowDateTime = 0;
};
}
static const char* commentFmt = "%02d/%02d/%d - %02d:%02d:%02d";
static void CreateSaveComment(char* bufstr) {
SYSTEMTIME stUTC, stLocal;
GetSystemTime(&stUTC);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
char buf[30];
sprintf_s(buf, commentFmt, stLocal.wDay, stLocal.wMonth, stLocal.wYear, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
strcpy(bufstr, buf);
}
static DWORD autoQuickSave = 0;
static DWORD quickSavePage = 0;
static FILETIME ftPrevSlot;
static DWORD __stdcall QuickSaveGame(fo::DbFile* file, char* filename) {
unsigned int currSlot = fo::var::slot_cursor;
if (file) { // This slot is not empty
fo::func::db_fclose(file);
FILETIME ftCurrSlot;
GetSaveFileTime(filename, &ftCurrSlot);
if (currSlot == 0 || ftCurrSlot.dwHighDateTime > ftPrevSlot.dwHighDateTime
|| (ftCurrSlot.dwHighDateTime == ftPrevSlot.dwHighDateTime && ftCurrSlot.dwLowDateTime > ftPrevSlot.dwLowDateTime)) {
ftPrevSlot.dwHighDateTime = ftCurrSlot.dwHighDateTime;
ftPrevSlot.dwLowDateTime = ftCurrSlot.dwLowDateTime;
if (++currSlot > 9 || currSlot > autoQuickSave) {
currSlot = 0;
} else {
fo::var::slot_cursor = currSlot;
return 0x47B929; // check next slot
}
}
}
// Save to slot
fo::var::slot_cursor = currSlot;
fo::LSData* saveData = (fo::LSData*)FO_VAR_LSData;
CreateSaveComment(saveData[currSlot].comment);
fo::var::quick_done = 1;
return 0x47B9A4; // normal return
}
static void __declspec(naked) SaveGame_hack0() {
__asm {
mov ds:[FO_VAR_flptr], eax;
push ecx;
push edi;
push eax;
call QuickSaveGame;
pop ecx;
jmp eax;
}
}
static void __declspec(naked) SaveGame_hack1() {
__asm {
mov ds:[FO_VAR_slot_cursor], 0;
mov eax, quickSavePage;
mov LSPageOffset, eax;
retn;
}
}
void ExtraSaveSlots::init() { void ExtraSaveSlots::init() {
if (GetConfigInt("Misc", "ExtraSaveSlots", 0)) { bool extraSaveSlots = (GetConfigInt("Misc", "ExtraSaveSlots", 0) != 0);
if (extraSaveSlots) {
dlog("Running EnableSuperSaving()", DL_INIT); dlog("Running EnableSuperSaving()", DL_INIT);
EnableSuperSaving(); EnableSuperSaving();
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
} }
autoQuickSave = GetConfigInt("Misc", "AutoQuickSave", 0);
quickSavePage = GetConfigInt("Misc", "AutoQuickSavePage", 0);
if (autoQuickSave >= 1 && autoQuickSave <= 10) {
dlog("Applying auto quick save patch.", DL_INIT);
autoQuickSave--;
if (quickSavePage > 0) {
if (quickSavePage > 1000) quickSavePage = 1000;
quickSavePage = (quickSavePage - 1) * 10;
}
if (extraSaveSlots) {
MakeCall(0x47B923, SaveGame_hack1);
SafeWrite8(0x47B928, 0x90);
} else {
SafeWrite8(0x47B923, 0x89);
SafeWrite32(0x47B924, 0x5193B83D); // mov [slot_cursor], edi(0)
}
MakeJump(0x47B984, SaveGame_hack0);
dlogr(" Done", DL_INIT);
}
} }
} }