diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 130dd0bd52..f4a33522b0 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -56,46 +56,66 @@ class DLoadSaveMenu : public DListMenu DECLARE_CLASS(DLoadSaveMenu, DListMenu) protected: - static List SaveGames; - static FSaveGameNode *TopSaveGame; - static FSaveGameNode *lastSaveSlot; - static FSaveGameNode *SelSaveGame; + static TDeletingArray SaveGames; + static int LastSaved; + + int Selected; + int TopItem; - friend void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); + int savepicLeft; + int savepicTop; + int savepicWidth; + int savepicHeight; - static FSaveGameNode *RemoveSaveSlot (FSaveGameNode *file); - static void UnloadSaveStrings(); - static void InsertSaveNode (FSaveGameNode *node); + int rowHeight; + int listboxLeft; + int listboxTop; + int listboxWidth; + + int listboxRows; + int listboxHeight; + int listboxRight; + int listboxBottom; + + int commentLeft; + int commentTop; + int commentWidth; + int commentHeight; + int commentRight; + int commentBottom; + + + static int InsertSaveNode (FSaveGameNode *node); static void ReadSaveStrings (); - static void NotifyNewSave (const char *file, const char *title, bool okForQuicksave); FTexture *SavePic; FBrokenLines *SaveComment; bool mEntering; char savegamestring[SAVESTRINGSIZE]; - bool mWheelScrolled; DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); void Destroy(); + int RemoveSaveSlot (int index); void UnloadSaveData (); void ClearSaveStuff (); - void ExtractSaveData (const FSaveGameNode *node); + void ExtractSaveData (int index); void Drawer (); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); bool Responder(event_t *ev); +public: + static void NotifyNewSave (const char *file, const char *title, bool okForQuicksave); + }; IMPLEMENT_CLASS(DLoadSaveMenu) -List DLoadSaveMenu::SaveGames; -FSaveGameNode *DLoadSaveMenu::TopSaveGame; -FSaveGameNode *DLoadSaveMenu::lastSaveSlot; -FSaveGameNode *DLoadSaveMenu::SelSaveGame; +TDeletingArray DLoadSaveMenu::SaveGames; +int DLoadSaveMenu::LastSaved = -1; FSaveGameNode *quickSaveSlot; @@ -105,78 +125,54 @@ FSaveGameNode *quickSaveSlot; // //============================================================================= -FSaveGameNode *DLoadSaveMenu::RemoveSaveSlot (FSaveGameNode *file) +int DLoadSaveMenu::RemoveSaveSlot (int index) { - FSaveGameNode *next = static_cast(file->Succ); + FSaveGameNode *file = SaveGames[index]; - if (file == TopSaveGame) - { - TopSaveGame = next; - } - if (quickSaveSlot == file) + if (quickSaveSlot == SaveGames[index]) { quickSaveSlot = NULL; } - if (lastSaveSlot == file) + if (Selected == index) { - lastSaveSlot = NULL; + Selected = -1; } - file->Remove (); if (!file->bNoDelete) delete file; - return next; + SaveGames.Delete(index); + if ((unsigned)index >= SaveGames.Size()) index--; + return index; } - //============================================================================= // // // //============================================================================= -void DLoadSaveMenu::UnloadSaveStrings() +int DLoadSaveMenu::InsertSaveNode (FSaveGameNode *node) { - while (!SaveGames.IsEmpty()) + if (SaveGames.Size() == 0) { - RemoveSaveSlot (static_cast(SaveGames.Head)); - } -} - - -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::InsertSaveNode (FSaveGameNode *node) -{ - FSaveGameNode *probe; - - if (SaveGames.IsEmpty ()) - { - SaveGames.AddHead (node); - return; + return SaveGames.Push(node); } if (node->bOldVersion) { // Add node at bottom of list - probe = static_cast(SaveGames.TailPred); - while (probe->Pred != NULL && probe->bOldVersion && - stricmp (node->Title, probe->Title) < 0) - { - probe = static_cast(probe->Pred); - } - node->Insert (probe); + return SaveGames.Push(node); } else - { // Add node at top of list - probe = static_cast(SaveGames.Head); - while (probe->Succ != NULL && !probe->bOldVersion && - stricmp (node->Title, probe->Title) > 0) + { // Add node at top of list + unsigned int i; + for(i = 0; i < SaveGames.Size(); i++) { - probe = static_cast(probe->Succ); + if (SaveGames[i]->bOldVersion || + stricmp (node->Title, SaveGames[i]->Title) <= 0) + { + break; + } } - node->InsertBefore (probe); + SaveGames.Insert(i, node); + return i; } } @@ -191,14 +187,12 @@ void DLoadSaveMenu::InsertSaveNode (FSaveGameNode *node) void DLoadSaveMenu::ReadSaveStrings () { - if (SaveGames.IsEmpty ()) + if (SaveGames.Size() == 0) { void *filefirst; findstate_t c_file; FString filter; - atterm (UnloadSaveStrings); - filter = G_BuildSaveName ("*.zds", -1); filefirst = I_FindFirst (filter.GetChars(), &c_file); if (filefirst != ((void *)(-1))) @@ -309,10 +303,6 @@ void DLoadSaveMenu::ReadSaveStrings () I_FindClose (filefirst); } } - if (SelSaveGame == NULL || SelSaveGame->Succ == NULL) - { - SelSaveGame = static_cast(SaveGames.Head); - } } @@ -332,10 +322,9 @@ void DLoadSaveMenu::NotifyNewSave (const char *file, const char *title, bool okF ReadSaveStrings (); // See if the file is already in our list - for (node = static_cast(SaveGames.Head); - node->Succ != NULL; - node = static_cast(node->Succ)) + for (unsigned i=0; iFilename.Compare (file) == 0) #else @@ -345,25 +334,26 @@ void DLoadSaveMenu::NotifyNewSave (const char *file, const char *title, bool okF strcpy (node->Title, title); node->bOldVersion = false; node->bMissingWads = false; - break; + if (okForQuicksave) + { + if (quickSaveSlot == NULL) quickSaveSlot = node; + LastSaved = i; + } + return; } } - if (node->Succ == NULL) - { - node = new FSaveGameNode; - strcpy (node->Title, title); - node->Filename = file; - node->bOldVersion = false; - node->bMissingWads = false; - InsertSaveNode (node); - SelSaveGame = node; - } + node = new FSaveGameNode; + strcpy (node->Title, title); + node->Filename = file; + node->bOldVersion = false; + node->bMissingWads = false; + int index = InsertSaveNode (node); if (okForQuicksave) { if (quickSaveSlot == NULL) quickSaveSlot = node; - lastSaveSlot = node; + LastSaved = index; } } @@ -382,7 +372,28 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc) : DListMenu(parent, desc) { ReadSaveStrings(); - mWheelScrolled = false; + + savepicLeft = 10; + savepicTop = 54*CleanYfac; + savepicWidth = 216*screen->GetWidth()/640; + savepicHeight = 135*screen->GetHeight()/400; + + rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; + listboxLeft = savepicLeft + savepicWidth + 14; + listboxTop = savepicTop; + listboxWidth = screen->GetWidth() - listboxLeft - 10; + int listboxHeight1 = screen->GetHeight() - listboxTop - 10; + listboxRows = (listboxHeight1 - 1) / rowHeight; + listboxHeight = listboxRows * rowHeight + 1; + listboxRight = listboxLeft + listboxWidth; + listboxBottom = listboxTop + listboxHeight; + + commentLeft = savepicLeft; + commentTop = savepicTop + savepicHeight + 16; + commentWidth = savepicWidth; + commentHeight = (51+(screen->GetHeight()>200?10:0))*CleanYfac; + commentRight = commentLeft + commentWidth; + commentBottom = commentTop + commentHeight; } void DLoadSaveMenu::Destroy() @@ -420,7 +431,7 @@ void DLoadSaveMenu::UnloadSaveData () void DLoadSaveMenu::ClearSaveStuff () { UnloadSaveData(); - if (quickSaveSlot == (FSaveGameNode *)1) + if (quickSaveSlot == (FSaveGameNode*)1) { quickSaveSlot = NULL; } @@ -432,15 +443,16 @@ void DLoadSaveMenu::ClearSaveStuff () // //============================================================================= -void DLoadSaveMenu::ExtractSaveData (const FSaveGameNode *node) +void DLoadSaveMenu::ExtractSaveData (int index) { FILE *file; PNGHandle *png; + FSaveGameNode *node; UnloadSaveData (); - if (node != NULL && - node->Succ != NULL && + if ((unsigned)index < SaveGames.Size() && + (node = SaveGames[index]) && !node->Filename.IsEmpty() && !node->bOldVersion && (file = fopen (node->Filename.GetChars(), "rb")) != NULL) @@ -512,30 +524,9 @@ void DLoadSaveMenu::Drawer () { Super::Drawer(); - const int savepicLeft = 10; - const int savepicTop = 54*CleanYfac; - const int savepicWidth = 216*screen->GetWidth()/640; - const int savepicHeight = 135*screen->GetHeight()/400; - - const int rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; - const int listboxLeft = savepicLeft + savepicWidth + 14; - const int listboxTop = savepicTop; - const int listboxWidth = screen->GetWidth() - listboxLeft - 10; - const int listboxHeight1 = screen->GetHeight() - listboxTop - 10; - const int listboxRows = (listboxHeight1 - 1) / rowHeight; - const int listboxHeight = listboxRows * rowHeight + 1; - const int listboxRight = listboxLeft + listboxWidth; - const int listboxBottom = listboxTop + listboxHeight; - - const int commentLeft = savepicLeft; - const int commentTop = savepicTop + savepicHeight + 16; - const int commentWidth = savepicWidth; - const int commentHeight = (51+(screen->GetHeight()>200?10:0))*CleanYfac; - const int commentRight = commentLeft + commentWidth; - const int commentBottom = commentTop + commentHeight; - FSaveGameNode *node; int i; + unsigned j; bool didSeeSelected = false; // Draw picture area @@ -558,10 +549,10 @@ void DLoadSaveMenu::Drawer () screen->Clear (savepicLeft, savepicTop, savepicLeft+savepicWidth, savepicTop+savepicHeight, 0, 0); - if (!SaveGames.IsEmpty ()) + if (SaveGames.Size() > 0) { const char *text = - (SelSaveGame == NULL || !SelSaveGame->bOldVersion) + (Selected == -1 || SaveGames[Selected]->bOldVersion) ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); const int textlen = SmallFont->StringWidth (text)*CleanXfac; @@ -588,110 +579,73 @@ void DLoadSaveMenu::Drawer () } // Draw file area - do + V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); + screen->Clear (listboxLeft, listboxTop, listboxRight, listboxBottom, 0, 0); + + if (SaveGames.Size() == 0) { - V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); - screen->Clear (listboxLeft, listboxTop, listboxRight, listboxBottom, 0, 0); + const char * text = GStrings("MNU_NOFILES"); + const int textlen = SmallFont->StringWidth (text)*CleanXfac; - if (SaveGames.IsEmpty ()) + screen->DrawText (SmallFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, + listboxTop+(listboxHeight-rowHeight)/2, text, + DTA_CleanNoMove, true, TAG_DONE); + return; + } + + for (i = 0, j = TopItem; i < listboxRows && j < SaveGames.Size(); i++,j++) + { + int color; + node = SaveGames[j]; + if (node->bOldVersion) { - const char * text = GStrings("MNU_NOFILES"); - const int textlen = SmallFont->StringWidth (text)*CleanXfac; - - screen->DrawText (SmallFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, - listboxTop+(listboxHeight-rowHeight)/2, text, - DTA_CleanNoMove, true, TAG_DONE); - return; + color = CR_BLUE; } - - for (i = 0, node = TopSaveGame; - i < listboxRows && node->Succ != NULL; - ++i, node = static_cast(node->Succ)) + else if (node->bMissingWads) { - int color; - if (node->bOldVersion) - { - color = CR_BLUE; - } - else if (node->bMissingWads) - { - color = CR_ORANGE; - } - else if (node == SelSaveGame) - { - color = CR_WHITE; - } - else - { - color = CR_TAN; - } - if (node == SelSaveGame) - { - screen->Clear (listboxLeft, listboxTop+rowHeight*i, - listboxRight, listboxTop+rowHeight*(i+1), -1, - mEntering ? MAKEARGB(255,255,0,0) : MAKEARGB(255,0,0,255)); - didSeeSelected = true; - if (!mEntering) - { - screen->DrawText (SmallFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, - DTA_CleanNoMove, true, TAG_DONE); - } - else - { - screen->DrawText (SmallFont, CR_WHITE, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, savegamestring, - DTA_CleanNoMove, true, TAG_DONE); - - screen->DrawText (SmallFont, CR_WHITE, - listboxLeft+1+SmallFont->StringWidth (savegamestring)*CleanXfac, - listboxTop+rowHeight*i+CleanYfac, - (gameinfo.gametype & (GAME_DoomStrifeChex)) ? "_" : "[", - DTA_CleanNoMove, true, TAG_DONE); - } - } - else + color = CR_ORANGE; + } + else if (j == Selected) + { + color = CR_WHITE; + } + else + { + color = CR_TAN; + } + if (j == Selected) + { + screen->Clear (listboxLeft, listboxTop+rowHeight*i, + listboxRight, listboxTop+rowHeight*(i+1), -1, + mEntering ? MAKEARGB(255,255,0,0) : MAKEARGB(255,0,0,255)); + didSeeSelected = true; + if (!mEntering) { screen->DrawText (SmallFont, color, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, DTA_CleanNoMove, true, TAG_DONE); } - } - - // This is dumb: If the selected node was not visible, - // scroll down and redraw. M_SaveLoadResponder() - // guarantees that if the node is not visible, it will - // always be below the visible list instead of above it. - // This should not really be done here, but I don't care. - - if (!didSeeSelected) - { - // no, this shouldn't be here - and that's why there's now another hack in here - // so that the mouse scrolling does not get screwed by this code... - if (mWheelScrolled) - { - didSeeSelected = true; - SelSaveGame = NULL; - mWheelScrolled = false; - } - for (i = 1; node->Succ != NULL && node != SelSaveGame; ++i) - { - node = static_cast(node->Succ); - } - if (node->Succ == NULL) - { // SelSaveGame is invalid - didSeeSelected = true; - } else { - do - { - TopSaveGame = static_cast(TopSaveGame->Succ); - } while (--i); + screen->DrawText (SmallFont, CR_WHITE, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, savegamestring, + DTA_CleanNoMove, true, TAG_DONE); + + screen->DrawText (SmallFont, CR_WHITE, + listboxLeft+1+SmallFont->StringWidth (savegamestring)*CleanXfac, + listboxTop+rowHeight*i+CleanYfac, + (gameinfo.gametype & (GAME_DoomStrifeChex)) ? "_" : "[", + DTA_CleanNoMove, true, TAG_DONE); } } - } while (!didSeeSelected); -} + else + { + screen->DrawText (SmallFont, color, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, + DTA_CleanNoMove, true, TAG_DONE); + } + } +} //============================================================================= // @@ -704,47 +658,68 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) switch (mkey) { case MKEY_Up: - if (SelSaveGame == NULL) + if (SaveGames.Size() > 1) { - SelSaveGame = TopSaveGame; - } - else if (SelSaveGame->Succ != NULL) - { - if (SelSaveGame != SaveGames.Head) - { - if (SelSaveGame == TopSaveGame) - { - TopSaveGame = static_cast(TopSaveGame->Pred); - } - SelSaveGame = static_cast(SelSaveGame->Pred); - } + if (Selected == -1) Selected = TopItem; else { - SelSaveGame = static_cast(SaveGames.TailPred); + if (--Selected < 0) Selected = SaveGames.Size()-1; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); } UnloadSaveData (); - ExtractSaveData (SelSaveGame); + ExtractSaveData (Selected); } return true; case MKEY_Down: - if (SelSaveGame == NULL) + if (SaveGames.Size() > 1) { - SelSaveGame = TopSaveGame; - } - else if (SelSaveGame->Succ != NULL) - { - if (SelSaveGame != SaveGames.TailPred) + if (Selected == -1) Selected = TopItem; + else { - SelSaveGame = static_cast(SelSaveGame->Succ); + if (unsigned(++Selected) >= SaveGames.Size()) Selected = 0; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); + } + UnloadSaveData (); + ExtractSaveData (Selected); + } + return true; + + case MKEY_PageDown: + if (SaveGames.Size() > 1) + { + if (TopItem >= (int)SaveGames.Size() - listboxRows) + { + TopItem = 0; + if (Selected != -1) Selected = 0; } else { - SelSaveGame = TopSaveGame = - static_cast(SaveGames.Head); + TopItem = MIN(TopItem + listboxRows, SaveGames.Size() - listboxRows); + if (TopItem > Selected && Selected != -1) Selected = TopItem; } UnloadSaveData (); - ExtractSaveData (SelSaveGame); + ExtractSaveData (Selected); + } + return true; + + case MKEY_PageUp: + if (SaveGames.Size() > 1) + { + if (TopItem == 0) + { + TopItem = SaveGames.Size() - listboxRows; + if (Selected != -1) Selected = TopItem; + } + else + { + TopItem = MAX(TopItem - listboxRows, 0); + if (Selected >= TopItem + listboxRows) Selected = TopItem; + } + UnloadSaveData (); + ExtractSaveData (Selected); } return true; @@ -753,22 +728,12 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) case MKEY_MBYes: { - if (SelSaveGame != NULL && SelSaveGame->Succ != NULL) + if (Selected != -1) { - FSaveGameNode *next = static_cast(SelSaveGame->Succ); - if (next->Succ == NULL) - { - next = static_cast(SelSaveGame->Pred); - if (next->Pred == NULL) - { - next = NULL; - } - } - - remove (SelSaveGame->Filename.GetChars()); + remove (SaveGames[Selected]->Filename.GetChars()); UnloadSaveData (); - SelSaveGame = RemoveSaveSlot (SelSaveGame); - ExtractSaveData (SelSaveGame); + Selected = RemoveSaveSlot (Selected); + ExtractSaveData (Selected); } return true; } @@ -786,39 +751,16 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) bool DLoadSaveMenu::MouseEvent(int type, int x, int y) { - const int savepicLeft = 10; - const int savepicTop = 54*CleanYfac; - const int savepicWidth = 216*screen->GetWidth()/640; - - const int rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; - const int listboxLeft = savepicLeft + savepicWidth + 14; - const int listboxTop = savepicTop; - const int listboxWidth = screen->GetWidth() - listboxLeft - 10; - const int listboxHeight1 = screen->GetHeight() - listboxTop - 10; - const int listboxRows = (listboxHeight1 - 1) / rowHeight; - const int listboxHeight = listboxRows * rowHeight + 1; - const int listboxRight = listboxLeft + listboxWidth; - const int listboxBottom = listboxTop + listboxHeight; - if (x >= listboxLeft && x < listboxLeft + listboxWidth && y >= listboxTop && y < listboxTop + listboxHeight) { int lineno = (y - listboxTop) / rowHeight; - FSaveGameNode *top = TopSaveGame; - while (lineno > 0 && top->Succ != NULL) + + if (TopItem + lineno < (int)SaveGames.Size()) { - lineno--; - top = (FSaveGameNode *)top->Succ; - } - if (lineno == 0) - { - if (SelSaveGame != top) - { - SelSaveGame = top; - UnloadSaveData (); - ExtractSaveData (SelSaveGame); - // Sound? - } + Selected = TopItem + lineno; + UnloadSaveData (); + ExtractSaveData (Selected); if (type == MOUSE_Release) { if (MenuEvent(MKEY_Enter, true)) @@ -827,12 +769,10 @@ bool DLoadSaveMenu::MouseEvent(int type, int x, int y) } } } - else SelSaveGame = NULL; - } - else - { - SelSaveGame = NULL; + else Selected = -1; } + else Selected = -1; + return Super::MouseEvent(type, x, y); } @@ -848,16 +788,16 @@ bool DLoadSaveMenu::Responder (event_t *ev) { if (ev->subtype == EV_GUI_KeyDown) { - if (SelSaveGame != NULL && SelSaveGame->Succ != NULL) + if (Selected != -1) { switch (ev->data1) { case GK_F1: - if (!SelSaveGame->Filename.IsEmpty()) + if (!SaveGames[Selected]->Filename.IsEmpty()) { char workbuf[512]; - mysnprintf (workbuf, countof(workbuf), "File on disk:\n%s", SelSaveGame->Filename.GetChars()); + mysnprintf (workbuf, countof(workbuf), "File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); if (SaveComment != NULL) { V_FreeBrokenLines (SaveComment); @@ -871,7 +811,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) { FString EndString; EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", - GStrings("MNU_DELETESG"), SelSaveGame->Title, GStrings("PRESSYN")); + GStrings("MNU_DELETESG"), SaveGames[Selected]->Title, GStrings("PRESSYN")); M_StartMessage (EndString, 0); } return true; @@ -880,36 +820,13 @@ bool DLoadSaveMenu::Responder (event_t *ev) } else if (ev->subtype == EV_GUI_WheelUp) { - if (TopSaveGame != SaveGames.Head && TopSaveGame != NULL) - { - TopSaveGame = static_cast(TopSaveGame->Pred); - mWheelScrolled = true; - } + if (TopItem > 0) TopItem--; return true; } else if (ev->subtype == EV_GUI_WheelDown) { - const int savepicTop = 54*CleanYfac; - const int listboxTop = savepicTop; - const int rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; - const int listboxHeight1 = screen->GetHeight() - listboxTop - 10; - const int listboxRows = (listboxHeight1 - 1) / rowHeight; - - FSaveGameNode *node = TopSaveGame; - if (node != NULL) - { - int count = 1; - while (node != NULL && node != SaveGames.TailPred) - { - node = (FSaveGameNode*)node->Succ; - count++; - } - if (count > listboxRows) - { - TopSaveGame = (FSaveGameNode*)TopSaveGame->Succ; - mWheelScrolled = true; - } - } + if (TopItem < (int)SaveGames.Size() - listboxRows) TopItem++; + return true; } } return Super::Responder(ev); @@ -952,17 +869,17 @@ DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) { strcpy (NewSaveNode.Title, ""); NewSaveNode.bNoDelete = true; - SaveGames.AddHead (&NewSaveNode); - TopSaveGame = static_cast(SaveGames.Head); - if (lastSaveSlot == NULL) + SaveGames.Insert(0, &NewSaveNode); + TopItem = 0; + if (LastSaved == -1) { - SelSaveGame = &NewSaveNode; + Selected = 0; } else { - SelSaveGame = lastSaveSlot; + Selected = LastSaved + 1; } - ExtractSaveData (SelSaveGame); + ExtractSaveData (Selected); } //============================================================================= @@ -973,17 +890,11 @@ DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) void DSaveMenu::Destroy() { - if (SaveGames.Head == &NewSaveNode) + if (SaveGames[0] == &NewSaveNode) { - SaveGames.RemHead (); - if (SelSaveGame == &NewSaveNode) - { - SelSaveGame = static_cast(SaveGames.Head); - } - if (TopSaveGame == &NewSaveNode) - { - TopSaveGame = static_cast(SaveGames.Head); - } + SaveGames.Delete(0); + if (Selected == 0) Selected = -1; + else Selected--; } } @@ -1034,16 +945,16 @@ bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) { return true; } - if (SelSaveGame == NULL || SelSaveGame->Succ == NULL) + if (Selected == -1) { return false; } if (mkey == MKEY_Enter) { - if (SelSaveGame != &NewSaveNode) + if (Selected != 0) { - strcpy (savegamestring, SelSaveGame->Title); + strcpy (savegamestring, SaveGames[Selected]->Title); } else { @@ -1056,7 +967,7 @@ bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) else if (mkey == MKEY_Input) { mEntering = false; - DoSave(SelSaveGame); + DoSave(SaveGames[Selected]); } else if (mkey == MKEY_Abort) { @@ -1075,18 +986,18 @@ bool DSaveMenu::Responder (event_t *ev) { if (ev->subtype == EV_GUI_KeyDown) { - if (SelSaveGame != NULL && SelSaveGame->Succ != NULL) + if (Selected != -1) { switch (ev->data1) { case GK_DEL: case '\b': // cannot delete 'new save game' item - if (SelSaveGame == &NewSaveNode) return true; + if (Selected == 0) return true; break; case 'N': - SelSaveGame = TopSaveGame = &NewSaveNode; + Selected = TopItem = 0; UnloadSaveData (); return true; } @@ -1124,8 +1035,9 @@ IMPLEMENT_CLASS(DLoadMenu) DLoadMenu::DLoadMenu(DMenu *parent, FListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { - TopSaveGame = static_cast(SaveGames.Head); - ExtractSaveData (SelSaveGame); + TopItem = 0; + ExtractSaveData (Selected); + } //============================================================================= @@ -1140,21 +1052,21 @@ bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) { return true; } - if (SelSaveGame == NULL || SelSaveGame->Succ == NULL) + if (Selected == -1) { return false; } if (mkey == MKEY_Enter) { - G_LoadGame (SelSaveGame->Filename.GetChars()); + G_LoadGame (SaveGames[Selected]->Filename.GetChars()); if (gamestate == GS_FULLCONSOLE) { gamestate = GS_HIDECONSOLE; } - if (quickSaveSlot == (FSaveGameNode *)1) + if (quickSaveSlot == (FSaveGameNode*)1) { - quickSaveSlot = SelSaveGame; + quickSaveSlot = SaveGames[Selected]; } M_ClearMenus(); BorderNeedRefresh = screen->GetPageCount (); diff --git a/src/menu/menu.h b/src/menu/menu.h index b1073a0410..c4dc8b9e5e 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -56,7 +56,7 @@ struct FGameStartup extern FGameStartup GameStartupInfo; -struct FSaveGameNode : public Node +struct FSaveGameNode { char Title[SAVESTRINGSIZE]; FString Filename;