mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added options to use more than one save slot for quick saving (from Mr.Stalin) (#186)
This commit is contained in:
@@ -398,6 +398,14 @@ UseScrollingQuestsList=1
|
||||
;Set to 1 to add additional pages of save slots
|
||||
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 2 to update the HP/AC counters instantly
|
||||
SpeedInterfaceCounterAnims=0
|
||||
|
||||
@@ -640,4 +640,28 @@ struct Window {
|
||||
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];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -494,12 +494,113 @@ void EnableSuperSaving() {
|
||||
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() {
|
||||
if (GetConfigInt("Misc", "ExtraSaveSlots", 0)) {
|
||||
bool extraSaveSlots = (GetConfigInt("Misc", "ExtraSaveSlots", 0) != 0);
|
||||
if (extraSaveSlots) {
|
||||
dlog("Running EnableSuperSaving()", DL_INIT);
|
||||
EnableSuperSaving();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user