Skip to content

Commit

Permalink
Quick Saving:
Browse files Browse the repository at this point in the history
Create quick load menu by sorting entries by date time
Add auto quicksaving and quick saving
TODO: Somehow check if quick save already happened so qs button can't get spammed.
  • Loading branch information
Dextinfire committed Sep 29, 2024
1 parent 7fb5212 commit 1867088
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 53 deletions.
13 changes: 7 additions & 6 deletions src/data/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ void LoadMemoryNew(LoadProcess load) {
if (Implementation) Implementation->LoadMemoryNew(load);
}

void FlushWorkingSaveEntry(SaveType type, int id) {
if (Implementation) Implementation->FlushWorkingSaveEntry(type, id);
void FlushWorkingSaveEntry(SaveType type, int id, int autoSaveType) {
if (Implementation)
Implementation->FlushWorkingSaveEntry(type, id, autoSaveType);
}

void WriteSaveFile() {
Expand Down Expand Up @@ -172,11 +173,11 @@ void SetCheckpointId(int id) {
if (Implementation) Implementation->SetCheckpointId(id);
}

int GetQuickSaveCount() {
if (Implementation) return Implementation->GetQuickSaveCount();
int GetQuickSaveOpenSlot() {
if (Implementation) return Implementation->GetQuickSaveOpenSlot();
ImpLog(LL_Warning, LC_VMStub,
"%s: save system not implemented, returning 0\n", __func__);
return 0;
"%s: save system not implemented, returning -1\n", __func__);
return -1;
}

Sprite const& GetSaveThumbnail(SaveType type, int id) {
Expand Down
17 changes: 13 additions & 4 deletions src/data/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class SaveSystemBase {
virtual void SaveMemory() = 0;
virtual void LoadEntry(SaveType type, int id) = 0;
virtual void LoadMemoryNew(LoadProcess){};
virtual void FlushWorkingSaveEntry(SaveType type, int id) = 0;
virtual void FlushWorkingSaveEntry(SaveType type, int id,
int autoSaveType) = 0;
virtual void WriteSaveFile() = 0;
virtual uint32_t GetSavePlayTime(SaveType type, int id) = 0;
virtual uint8_t GetSaveFlags(SaveType type, int id) = 0;
Expand All @@ -93,7 +94,15 @@ class SaveSystemBase {
virtual bool GetBgmFlag(int id) = 0;
virtual void SetCheckpointId(int id) = 0;
virtual Sprite const& GetSaveThumbnail(SaveType type, int id) = 0;
int GetQuickSaveCount() { return QuickSaveCount; }
int GetQuickSaveOpenSlot() {
for (int i = 0; i < MaxSaveEntries; i++) {
if (QuickSaveEntries[i]->Status == 0) return i;
}
for (int i = 0; i < MaxSaveEntries; i++) {
if (GetSaveFlags(SaveQuick, i) != 1) return i;
}
return -1;
}
Sprite const& GetWorkingSaveThumbnail() { return WorkingSaveThumbnail; }

protected:
Expand All @@ -113,7 +122,7 @@ SaveError MountSaveFile();
void SaveMemory();
void LoadEntry(SaveType type, int id);
void LoadMemoryNew(LoadProcess process);
void FlushWorkingSaveEntry(SaveType type, int id);
void FlushWorkingSaveEntry(SaveType type, int id, int autoSaveType = 0);
void WriteSaveFile();
uint32_t GetSavePlayTime(SaveType type, int id);
uint8_t GetSaveFlags(SaveType type, int id);
Expand All @@ -130,7 +139,7 @@ void GetEVStatus(int evId, int* totalVariations, int* viewedVariations);
bool GetEVVariationIsUnlocked(int evId, int variationIdx);
bool GetBgmFlag(int id);
void SetCheckpointId(int id);
int GetQuickSaveCount();
int GetQuickSaveOpenSlot();
Sprite const& GetSaveThumbnail(SaveType type, int id);
Sprite const& GetWorkingSaveThumbnail();

Expand Down
38 changes: 33 additions & 5 deletions src/games/cclcc/savemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,51 @@ void SaveMenu::Show() {
State = Showing;
FadeAnimation.StartIn();
int id = 0;
Impacto::SaveSystem::SaveType saveType =
ScrWork[SW_SAVEMENUMODE] == SaveMenuPageType::QuickLoad
? SaveSystem::SaveType::SaveQuick
: SaveSystem::SaveType::SaveFull;

std::array<int, SaveSystem::MaxSaveEntries> saveEntryIds;
for (int i = 0; i < SaveSystem::MaxSaveEntries; i++) {
saveEntryIds[i] = i;
}
if (saveType == SaveSystem::SaveType::SaveQuick) {
// quick saves are sorted by time and status
std::sort(saveEntryIds.begin(), saveEntryIds.end(),
[saveType](int a, int b) {
int statusA = SaveSystem::GetSaveStatus(saveType, a);
int statusB = SaveSystem::GetSaveStatus(saveType, b);
if (statusA == statusB) {
std::tm ta = SaveSystem::GetSaveDate(saveType, a);
std::tm tb = SaveSystem::GetSaveDate(saveType, b);
std::time_t th = std::mktime(&ta);
std::time_t tl = std::mktime(&tb);
if (th == -1 || tl == -1) {
ImpLog(LL_Error, LC_General,
"Failed to convert time to time_t\n");
return statusA > statusB;
}
return difftime(th, tl) > 0;
}
return statusA > statusB;
});
}

for (int p = 0; p < Pages; ++p) {
MainItems[p] = new Widgets::Group(this);
MainItems[p]->WrapFocus = false;

for (int i = 0; i < RowsPerPage; i++) {
// Start on right col
for (int j = EntriesPerRow - 1; j >= 0; j--) {
Impacto::SaveSystem::SaveType saveType =
ScrWork[SW_SAVEMENUMODE] == SaveMenuPageType::QuickLoad
? SaveSystem::SaveType::SaveQuick
: SaveSystem::SaveType::SaveFull;
glm::vec2 buttonPos =
(j == 0)
? glm::vec2{EntryStartXL, EntryStartYL + (i * EntryYPadding)}
: glm::vec2{EntryStartXR, EntryStartYR + (i * EntryYPadding)};
SaveEntryButton* saveEntryButton = new SaveEntryButton(
id, EntryHighlightedBoxSprite[ScrWork[SW_SAVEMENUMODE]],
saveEntryIds[id], id,
EntryHighlightedBoxSprite[ScrWork[SW_SAVEMENUMODE]],
EntryHighlightedTextSprite[ScrWork[SW_SAVEMENUMODE]], p,
buttonPos, SlotLockedSprite[ScrWork[SW_SAVEMENUMODE]], saveType,
NoDataSprite[ScrWork[SW_SAVEMENUMODE]],
Expand Down
10 changes: 7 additions & 3 deletions src/games/cclcc/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,20 +232,24 @@ SaveError SaveSystem::MountSaveFile() {
// return 0;
//}

void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) {
void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id,
int autoSaveType) {
SaveFileEntry* entry = 0;
switch (type) {
case SaveQuick:
entry = (SaveFileEntry*)QuickSaveEntries[QuickSaveCount++];
entry = (SaveFileEntry*)QuickSaveEntries[id];
break;
case SaveFull:
entry = (SaveFileEntry*)FullSaveEntries[id];
break;
}

if (entry != 0) {
if (entry != 0 && GetSaveFlags(type, id) != 1) {
Renderer->FreeTexture(entry->SaveThumbnail.Sheet.Texture);
*entry = *WorkingSaveEntry;
if (type == SaveQuick) {
entry->SaveType = autoSaveType;
}
time_t rawtime;
time(&rawtime);
entry->SaveDate = *localtime(&rawtime);
Expand Down
2 changes: 1 addition & 1 deletion src/games/cclcc/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SaveSystem : public SaveSystemBase {
void SaveMemory() override;
void LoadEntry(SaveType type, int id) override;
void LoadMemoryNew(LoadProcess load) override;
void FlushWorkingSaveEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id, int autoSaveType) override;
void WriteSaveFile() override;
uint32_t GetSavePlayTime(SaveType type, int id) override;
uint8_t GetSaveFlags(SaveType type, int id) override;
Expand Down
8 changes: 6 additions & 2 deletions src/games/chlcc/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ SaveError SaveSystem::MountSaveFile() {
// return 0;
//}

void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) {
void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id,
int autoSaveType) {
SaveFileEntry* entry = 0;
switch (type) {
case SaveQuick:
Expand All @@ -144,8 +145,11 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) {
}

if (WorkingSaveEntry != 0) {
if (entry != 0) {
if (entry != 0 && GetSaveFlags(type, id) != 1) {
*entry = *WorkingSaveEntry;
if (type == SaveQuick) {
entry->SaveType = autoSaveType;
}
time_t rawtime;
time(&rawtime);
entry->SaveDate = *localtime(&rawtime);
Expand Down
2 changes: 1 addition & 1 deletion src/games/chlcc/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class SaveSystem : public SaveSystemBase {
SaveError MountSaveFile() override;
void SaveMemory() override;
void LoadEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id, int autoSaveType) override;
void WriteSaveFile() override;
uint32_t GetSavePlayTime(SaveType type, int id) override;
uint8_t GetSaveFlags(SaveType type, int id) override;
Expand Down
9 changes: 7 additions & 2 deletions src/games/mo6tw/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ SaveError SaveSystem::MountSaveFile() {
// return 0;
//}

void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) {
void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id,
int autoSaveType) {
SaveFileEntry* entry = 0;
switch (type) {
case SaveQuick:
Expand All @@ -202,7 +203,11 @@ void SaveSystem::FlushWorkingSaveEntry(SaveType type, int id) {
}

if (WorkingSaveEntry != 0) {
if (entry != 0) {
if (entry != 0 && GetSaveFlags(type, id) != 1) {
Renderer->FreeTexture(entry->SaveThumbnail.Sheet.Texture);
if (type == SaveQuick) {
entry->SaveType = autoSaveType;
}
entry->Status = 1;

std::time_t t = std::time(0);
Expand Down
2 changes: 1 addition & 1 deletion src/games/mo6tw/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class SaveSystem : public SaveSystemBase {
SaveError MountSaveFile() override;
void SaveMemory() override;
void LoadEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id, int autoSaveType) override;
void WriteSaveFile() override;
uint32_t GetSavePlayTime(SaveType type, int id) override;
uint8_t GetSaveFlags(SaveType type, int id) override;
Expand Down
8 changes: 3 additions & 5 deletions src/ui/widgets/cclcc/saveentrybutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,17 @@ using namespace Impacto::SaveSystem;
glm::vec4 SaveEntryButton::FocusedAlpha = glm::vec4(1.0f);
Animation SaveEntryButton::FocusedAlphaFade;

SaveEntryButton::SaveEntryButton(int id, Sprite const& focusedBox,
SaveEntryButton::SaveEntryButton(int id, int index, Sprite const& focusedBox,
Sprite const& focusedText, int page,
glm::vec2 pos, Sprite lockedSymbol,
SaveSystem::SaveType saveType,
Sprite NoDataSprite, Sprite BrokenDataSprite)
: Widgets::Button(
(saveType == SaveSystem::SaveType::SaveFull
? id
: SaveSystem::GetQuickSaveCount() - id - 1),
id,
Sprite(SpriteSheet(), focusedBox.Bounds.X, focusedBox.Bounds.Y,
focusedBox.Bounds.Width, focusedBox.Bounds.Height),
Sprite(SpriteSheet(), 0, 0, 0, 0), focusedBox, pos),
Index(id),
Index(index),
Page(page),
FocusedSpriteLabel(focusedText, glm::vec2{pos.x, pos.y - 34}),
LockedSymbol(lockedSymbol,
Expand Down
8 changes: 4 additions & 4 deletions src/ui/widgets/cclcc/saveentrybutton.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ namespace CCLCC {

class SaveEntryButton : public Widgets::Button {
public:
SaveEntryButton(int id, Sprite const& focusedBox, Sprite const& focusedText,
int page, glm::vec2 pos, Sprite lockedSymbol,
SaveSystem::SaveType saveType, Sprite noDataSprite,
Sprite brokenDataSprite);
SaveEntryButton(int id, int index, Sprite const& focusedBox,
Sprite const& focusedText, int page, glm::vec2 pos,
Sprite lockedSymbol, SaveSystem::SaveType saveType,
Sprite noDataSprite, Sprite brokenDataSprite);
void Render() override;
int GetPage() const;
void AddNormalSpriteLabel(Sprite norm, glm::vec2 pos);
Expand Down
27 changes: 26 additions & 1 deletion src/vm/inst_dialogue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,32 @@ VmInstruction(InstSelect) {
switch (type) {
case 0: {
UI::SelectionMenuPtr->Show();
SaveIconDisplay::ShowFor(2.4f);
bool flag = GetFlag(1282);
int unk = ScrWork[2108];
if (unk < 0x100) {
ScrWork[2108] = unk + 0x10;
SetFlag(1286, 1);
ResetInstruction;
BlockThread;
}
SetFlag(thread->DialoguePageId + 1213, 0);
if (ScrWork[2112] == 2) {
thread->Ip += 12;
return;
} else {
SaveSystem::SaveMemory();
int quicksaveEntries = SaveSystem::GetQuickSaveOpenSlot();
if (!flag && quicksaveEntries != -1) {
SaveIconDisplay::ShowFor(2.4f);
SaveSystem::FlushWorkingSaveEntry(SaveSystem::SaveType::SaveQuick,
quicksaveEntries, 2);
}
ScrWork[2112] = 0;
if (quicksaveEntries == -1) {
thread->Ip += 12;
}
}
SetFlag(1286, 0);
} break;
case 1: {
if (!UI::SelectionMenuPtr->ChoiceMade) {
Expand Down
50 changes: 32 additions & 18 deletions src/vm/inst_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,46 +710,57 @@ VmInstruction(InstDebugData) {
}
VmInstruction(InstAutoSave) {
StartInstruction;
auto quickSave = [&](int autosaveRestartCheck, int saveType) {
SaveSystem::SaveMemory();
if (ScrWork[2112] != autosaveRestartCheck) {
int quicksaveEntries = SaveSystem::GetQuickSaveOpenSlot();
if (quicksaveEntries != -1) {
SaveIconDisplay::ShowFor(2.4f);
SaveSystem::FlushWorkingSaveEntry(SaveSystem::SaveType::SaveQuick,
quicksaveEntries, saveType);
}
}
SetFlag(1285, 1);
ScrWork[2112] = 0;
};

PopUint8(type);
switch (type) {
case 0: // QuickSave
SaveIconDisplay::ShowFor(2.4f);
case 20:
if (ScrWork[SW_TITLE] == 0xffff) break;
SaveSystem::SaveMemory();
if (ScrWork[2112] != 1) {
// TODO: Quicksave(1)
}
SetFlag(1285, 1);
ScrWork[2112] = 0;
quickSave(1, 1);
ImpLogSlow(LL_Warning, LC_VMStub,
"STUB instruction AutoSave(type: QuickSave)\n");
break;
case 1: // AutoSaveRestart (?)
case 21:
if (ScrWork[SW_TITLE] == 0xffff) break;
SaveSystem::SaveMemory();
if ((ScrWork[2112] != 3)) {
// TODO: Quicksave(3)
}
SetFlag(1285, 1);
ScrWork[2112] = 0;
quickSave(3, 3);
ImpLogSlow(LL_Warning, LC_VMStub, "STUB instruction AutoSave(type: %i)\n",
type);
break;
case 3: // DisableAutoSave
// Check quicksave, quicksave(0)
case 3: { // DisableAutoSave
int quicksaveEntries = SaveSystem::GetQuickSaveOpenSlot();
if (quicksaveEntries != -1) {
SaveIconDisplay::ShowFor(2.4f);
SaveSystem::FlushWorkingSaveEntry(SaveSystem::SaveType::SaveQuick,
quicksaveEntries, 0);
}

SetFlag(1285, 0);
ImpLogSlow(LL_Warning, LC_VMStub, "STUB instruction AutoSave(type: %i)\n",
type);
break;
case 5: // EnableAutoSave
} break;
case 5: { // EnableAutoSave
ImpLogSlow(LL_Warning, LC_VMStub, "STUB instruction AutoSave(type: %i)\n",
type);
if (ScrWork[SW_TITLE] != 0xffff) {
SaveSystem::SaveMemory();
SetFlag(1285, 1);
ScrWork[2112] = 0;
}
break;
} break;
case 10: { // SetCheckpointId
if (Profile::Vm::UseReturnIds) {
PopUint16(checkpointId);
Expand All @@ -771,6 +782,9 @@ VmInstruction(InstAutoSave) {
ImpLogSlow(LL_Warning, LC_VMStub, "STUB instruction AutoSave(arg1: %i)\n",
type);
break;
case 0xff: {
BlockThread;
} break;
default:
// More quicksave cases here
break;
Expand Down

0 comments on commit 1867088

Please sign in to comment.