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
|
;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
|
||||||
|
|||||||
@@ -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];
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user