xoreos  0.0.5
saveload.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/aurora/talkman.h"
26 
27 #include "src/common/configman.h"
28 #include "src/common/filelist.h"
29 #include "src/common/filepath.h"
30 #include "src/common/strutil.h"
31 
32 #include "src/graphics/graphics.h"
33 
35 
41 
42 namespace Engines {
43 
44 namespace KotOR {
45 
47  ::Engines::Console *console,
48  uint8 type,
49  bool frontBackground)
50  : GUI(console),
51  _module(&module),
52  _type(type) {
53  load("saveload");
54  addBackground(kBackgroundTypeMenu, frontBackground);
55 
56  WidgetListBox *lbGames = getListBox("LB_GAMES");
57  if (!lbGames)
58  throw Common::Exception("SaveLoadMenu: No games listbox");
59 
60  lbGames->setItemSelectionEnabled(true);
61  lbGames->setHideScrollbar(false);
62  lbGames->setPadding(3);
63  lbGames->setItemBorderColor(0.0f, 0.667969f, 0.988281f, 1.0f);
64  lbGames->setSoundSelectItem("gui_actscroll");
65  lbGames->createItemWidgets(6);
66 
68  WidgetLabel *panelName = getLabel("LBL_PANELNAME");
69  if (panelName)
70  panelName->setText(TalkMan.getString(1585)); // Load Game
71 
72  WidgetLabel *planetName = getLabel("LBL_PLANETNAME");
73  if (planetName)
74  planetName->setText("");
75 
76  WidgetLabel *areaName = getLabel("LBL_AREANAME");
77  if (areaName)
78  areaName->setText("");
79 
80  WidgetButton *saveLoad = getButton("BTN_SAVELOAD");
81  if (saveLoad)
82  saveLoad->setText(TalkMan.getString(1589)); // Load
83 
84  } else
85  lbGames->addItem(TalkMan.getString(1590));
86 
87  addSavedGameItems(lbGames);
88  lbGames->refreshItemWidgets();
89 }
90 
92  const Common::UString &tag = widget.getTag();
93  if (tag == "BTN_SAVELOAD") {
94  int selectedIndex = getListBox("LB_GAMES")->getSelectedIndex();
95  if (selectedIndex == -1)
96  return;
97  switch (_type) {
99  tryLoadGame(_saveDirs[selectedIndex]);
100  break;
102  trySaveGame(selectedIndex > 0 ? _saveDirs[selectedIndex - 1] : getNewSaveDirectory());
103  break;
104  default:
105  break;
106  }
107  } else if (tag == "BTN_BACK")
108  _returnCode = 1;
109 }
110 
112  if (type == Events::kEventKeyDown) {
113  switch (key) {
114  case Events::kKeyUp:
115  getListBox("LB_GAMES")->selectPreviousItem();
116  break;
117  case Events::kKeyDown:
118  getListBox("LB_GAMES")->selectNextItem();
119  break;
120  default:
121  break;
122  }
123  }
124 }
125 
127  Common::FileList dirs;
128  Common::UString savesDir = Common::FilePath::normalize(ConfigMan.getString("path") + "/saves");
129  dirs.addSubDirectories(savesDir);
130  Common::UString slotTextFormat = TalkMan.getString(1594);
131 
132  dirs.sort(true);
133  for (Common::FileList::const_iterator it = dirs.begin(); it != dirs.end(); ++it) {
134  Common::UString saveDir = *it;
135  Common::UString baseName;
136 
137  try {
138  baseName = getBaseNameFromDirectory(saveDir);
139  } catch (Common::Exception &e) {
140  e.add("Failed to get save base name from directory \"%s\"", saveDir.c_str());
141 
142  printException(e, "WARNING: ");
143  continue;
144  }
145 
146  if (_type == kSaveLoadMenuTypeSave && !baseName.contains("Game"))
147  continue;
148 
149  _saveDirs.push_back(saveDir);
150  SavedGame *save = SavedGame::load(saveDir);
151  uint32 timePlayed = save->getTimePlayed();
152  Common::UString slotText(slotTextFormat);
153 
154  slotText.replaceAll("Game <CUSTOM0>", baseName);
155  slotText.replaceAll("<CUSTOM1>", Common::composeString(timePlayed / 3600));
156  slotText.replaceAll("<CUSTOM2>", Common::composeString(timePlayed % 3600 / 60));
157 
158  if (baseName.contains("Game"))
159  slotText += "\r\n" + save->getName();
160 
161  delete save;
162  listBox->addItem(slotText);
163  }
164 }
165 
167  try {
168  hide();
170  _module->loadSavedGame(save.get());
171  GfxMan.lockFrame();
172  _returnCode = 2;
173  } catch (Common::Exception &e) {
174  warning("Failed to load saved game: %s %s", dir.c_str(), e.what());
175  }
176 }
177 
179 
180 }
181 
183  return "";
184 }
185 
187  Common::UString result;
188  Common::UString relativeDir(Common::FilePath::getFile(dir));
189 
190  if (relativeDir.contains("QUICKSAVE"))
191  result = "Quick Save";
192  else if (relativeDir.contains("AUTOSAVE"))
193  result = "Auto Save";
194  else if (relativeDir.contains("Game")) {
195  /* The format of a normal save directory is something like "000043 - Game42".
196  * The original game seems to ignore the GameXX part, and instead parses
197  * the first number, and then substracts 1 from the result.
198  *
199  * I.e. "000062 - Game42" will appears as "Game 61".
200  *
201  * Directories that fail this parsing, for example "abc - Game 42", simply
202  * won't appear in the save list.
203  */
204 
205  Common::UString::iterator it = relativeDir.begin();
206  while ((it != relativeDir.end()) && (*it == '0'))
207  ++it;
208 
209  Common::UString tmp(it, relativeDir.end());
210  tmp.truncate(tmp.findFirst(' '));
211 
212  int gameIndex = -1;
213 
214  Common::parseString(tmp, gameIndex);
215  gameIndex--;
216 
217  if (gameIndex < 0)
218  throw Common::Exception("Game index is negative (%d)", gameIndex);
219 
220  result = "Game " + Common::composeString(gameIndex);
221 
222  } else
223  throw Common::Exception("Unknown save type");
224 
225  return result;
226 }
227 
228 } // End of namespace KotOR
229 
230 } // End of namespace Engines
void load(const Common::UString &resref)
Definition: gui.cpp:103
static const Common::UString & kBackgroundTypeMenu
Definition: guibackground.h:42
bool addSubDirectories(const UString &directory)
Add subdirectories of a directory to the list.
Definition: filelist.cpp:131
void add(const char *s,...) GCC_PRINTF(2
Definition: error.cpp:58
The global graphics manager.
A label widget for Star Wars: Knights of the Old Republic and Jade Empire.
#define TalkMan
Shortcut for accessing the talk manager.
Definition: talkman.h:111
uint32 _returnCode
The GUI&#39;s return code.
Definition: gui.h:75
void loadSavedGame(SavedGame *save)
Definition: module.cpp:977
A class holding an UTF-8 string.
Definition: ustring.h:48
void createItemWidgets(uint32 count)
Definition: listbox.cpp:131
The global config manager.
UString composeString(T value)
Convert any POD integer, float/double or bool type into a string.
Definition: strutil.cpp:276
uint8_t uint8
Definition: types.h:200
uint32 getTimePlayed() const
Definition: savedgame.cpp:131
A button widget for Star Wars: Knights of the Old Republic and Jade Empire.
void addSavedGameItems(WidgetListBox *listBox)
Definition: saveload.cpp:126
void truncate(const iterator &it)
Definition: ustring.cpp:343
iterator begin() const
Definition: ustring.cpp:253
std::list< UString >::const_iterator const_iterator
Definition: filelist.h:37
virtual void hide()
Hide the GUI.
Definition: gui.cpp:75
void setPadding(uint32 padding)
Definition: listbox.cpp:98
Utility templates and functions for working with strings and streams.
Exception that provides a stack of explanations.
Definition: error.h:36
A scrollbar widget for Star Wars: Knights of the Old Republic and Jade Empire.
Keyboard key was pressed.
Definition: types.h:46
void trySaveGame(const Common::UString &dir)
Definition: saveload.cpp:178
Load/save game menu.
bool contains(const UString &what) const
Definition: ustring.cpp:335
utf8::iterator< std::string::const_iterator > iterator
Definition: ustring.h:50
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
void replaceAll(uint32 what, uint32 with)
Replace all occurrences of a character with another character.
Definition: ustring.cpp:435
WidgetButton * getButton(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:228
#define ConfigMan
Shortcut for accessing the config manager.
Definition: configman.h:176
#define UNUSED(x)
Definition: system.h:170
std::vector< Common::UString > _saveDirs
Definition: saveload.h:58
const Common::UString & getTag() const
Get the widget&#39;s tag.
Definition: widget.cpp:45
A list box widget for Star Wars: Knights of the Old Republic and Jade Empire.
void callbackActive(Widget &widget)
Callback that&#39;s triggered when a widget was activated.
Definition: saveload.cpp:91
void setItemSelectionEnabled(bool itemSelectionEnabled)
Toggle item selection mode.
Definition: listbox.cpp:82
void addItem(const Common::UString &contents)
Definition: listbox.cpp:122
void callbackKeyInput(const Events::Key &key, const Events::EventType &type)
Callback that&#39;s triggered when a key is pressed or released.
Definition: saveload.cpp:111
const Common::UString & getName() const
Definition: savedgame.cpp:123
StackException Exception
Definition: error.h:59
A scoped plain pointer, allowing pointer-y access and normal deletion.
Definition: scopedptr.h:120
void addBackground(const Common::UString &background, bool front=false)
Definition: gui.cpp:300
SaveLoadMenu(Module &module, ::Engines::Console *console, uint8 type=kSaveLoadMenuTypeLoad, bool frontBackground=false)
Definition: saveload.cpp:46
void warning(const char *s,...)
Definition: util.cpp:33
A widget in a GUI.
void setHideScrollbar(bool hideScrollbar)
Toggle scroll bar visibility mode.
Definition: listbox.cpp:94
void setItemBorderColor(float r, float g, float b, float a)
Definition: listbox.cpp:112
WidgetLabel * getLabel(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:204
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
A widget in a GUI.
Definition: widget.h:40
void tryLoadGame(const Common::UString &dir)
Definition: saveload.cpp:166
Common::UString getBaseNameFromDirectory(const Common::UString &dir) const
Definition: saveload.cpp:186
uint32_t uint32
Definition: types.h:204
The global talk manager for Aurora strings.
A list of files.
Definition: filelist.h:35
EventType
Custom event types.
Definition: types.h:45
static SavedGame * load(const Common::UString &dir, bool loadSav=false)
Load saved game from a specified directory.
Definition: savedgame.cpp:38
static UString normalize(const UString &p, bool resolveSymLinks=true)
Normalize a path.
Definition: filepath.cpp:154
Key
Definition: types.h:78
const_iterator begin() const
Return a const_iterator pointing to the beginning of the list.
Definition: filelist.cpp:94
void setText(const Common::UString &text)
WidgetListBox * getListBox(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:288
A list of files.
A KotOR GUI.
Definition: gui.h:57
iterator end() const
Definition: ustring.cpp:257
const char * what() const
Definition: error.cpp:73
void sort(bool caseInsensitive)
Sort this list alphabetically.
Definition: filelist.cpp:74
void printException(Exception &e, const UString &prefix)
Print a whole exception stack to stderr and the log.
Definition: error.cpp:95
static UString getFile(const UString &p)
Return a file name without its path.
Definition: filepath.cpp:81
void parseString(const UString &str, T &value, bool allowEmpty)
Parse a string into any POD integer, float/double or bool type.
Definition: strutil.cpp:215
Common::UString getNewSaveDirectory() const
Definition: saveload.cpp:182
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
Utility class for manipulating file paths.
const_iterator end() const
Return a const_iterator pointing past the end of the list.
Definition: filelist.cpp:98
int getSelectedIndex() const
Definition: listbox.cpp:306
void setSoundSelectItem(const Common::UString &resRef)
Definition: listbox.cpp:328