From 2550dfdd6f19624498ecf65ef52eba2517dbf65a Mon Sep 17 00:00:00 2001 From: "simon.kagstrom" Date: Mon, 25 Jan 2010 12:07:57 +0000 Subject: [PATCH] Add save/load game states --- gui.cpp | 6 ++ gui.hh | 3 + main_menu.cpp | 9 +++ mocks/C64.h | 10 ++++ save_game_menu.cpp | 143 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 save_game_menu.cpp diff --git a/gui.cpp b/gui.cpp index 9804dc0..3672b06 100644 --- a/gui.cpp +++ b/gui.cpp @@ -17,6 +17,7 @@ extern SDL_Surface *screen; #define METADATA_ROOT_PATH "metadata" #define GAME_ROOT_PATH "discs" #define TMP_ROOT_PATH "tmp" +#define SAVE_GAME_ROOT_PATH "saves" static const char *get_theme_path(const char *dir, const char *what) { @@ -31,6 +32,7 @@ static const char *get_theme_path(const char *dir, const char *what) /* These are a bit of special cases... */ #include "disc_menu.cpp" +#include "save_game_menu.cpp" #include "bind_keys_menu.cpp" #include "theme_menu.cpp" #include "options_menu.cpp" @@ -85,6 +87,7 @@ Gui::Gui() this->metadata_base_path = METADATA_ROOT_PATH; this->game_base_path = GAME_ROOT_PATH; this->tmp_path = TMP_ROOT_PATH; + this->save_game_path = SAVE_GAME_ROOT_PATH; this->cur_gameInfo = new GameInfo(); this->gameInfoChanged = false; @@ -94,6 +97,7 @@ Gui::Gui() this->mv = NULL; this->dv = NULL; + this->sgv = NULL; this->ov = NULL; this->nv = NULL; this->tv = NULL; @@ -105,6 +109,7 @@ Gui::~Gui() { delete this->mv; delete this->dv; + delete this->sgv; delete this->ov; delete this->nv; delete this->tv; @@ -210,6 +215,7 @@ bool Gui::setTheme(const char *path) this->mv = new MainView(); this->dv = new DiscView(); + this->sgv = new SaveGameView(); this->ov = new OptionsView(); this->nv = new NetworkView(); this->tv = new ThemeView(); diff --git a/gui.hh b/gui.hh index 933185e..99e40bc 100644 --- a/gui.hh +++ b/gui.hh @@ -18,6 +18,7 @@ class GameInfo; class MainView; class BindKeysView; class DiscView; +class SaveGameView; class OptionsView; class NetworkView; class ThemeView; @@ -101,6 +102,7 @@ public: MainView *mv; DiscView *dv; + SaveGameView *sgv; OptionsView *ov; NetworkView *nv; GameInfoView *giv; @@ -114,6 +116,7 @@ public: const char *theme_base_path; const char *game_base_path; const char *tmp_path; + const char *save_game_path; GameInfo *cur_gameInfo; bool gameInfoChanged; diff --git a/main_menu.cpp b/main_menu.cpp index 9d4e161..98cd311 100644 --- a/main_menu.cpp +++ b/main_menu.cpp @@ -63,6 +63,15 @@ public: Gui::gui->dv->runStartSequence(this->p_submenus[0].sel == 1); break; case 4: /* Load/save states */ + if (this->p_submenus[1].sel == 1) + Gui::gui->sgv->saveSnapshot(); + else + { + Gui::gui->sgv->setDirectory(Gui::gui->save_game_path); + Gui::gui->pushView(Gui::gui->sgv); + + Gui::gui->sgv->setLoadSnapshot(this->p_submenus[1].sel == 0); + } break; case 6: /* Keyboard */ switch(this->p_submenus[2].sel) diff --git a/mocks/C64.h b/mocks/C64.h index 61a30be..194c1ca 100644 --- a/mocks/C64.h +++ b/mocks/C64.h @@ -38,6 +38,16 @@ public: printf("Faking %s\n", what); } + void LoadSnapshot(const char *name) + { + printf("Loading savegame %s\n", name); + } + + void SaveSnapshot(const char *name) + { + printf("Saving savegame %s\n", name); + } + int network_connection_type; private: diff --git a/save_game_menu.cpp b/save_game_menu.cpp new file mode 100644 index 0000000..da7ab60 --- /dev/null +++ b/save_game_menu.cpp @@ -0,0 +1,143 @@ +#include /* unlink */ + +#include + +#include "menu.hh" +#include "file_browser.hh" +#include "game_info.hh" +#include "game_info_box.hh" +#include "utils.hh" + +static const char *save_exts[] = {".sav", ".SAV", NULL}; + +class SaveGameMenu; + +class SaveGameView : public GuiView +{ +public: + SaveGameView(); + + ~SaveGameView(); + + void pushEvent(SDL_Event *ev); + + void loadGameInfo(const char *what); + + void setDirectory(const char *path); + + void setLoadSnapshot(bool which); + + void saveSnapshot(); + + /* Inherited */ + void runLogic(); + + void draw(SDL_Surface *where); + + SaveGameMenu *menu; + GameInfoBox *gameInfo; +}; + + +class SaveGameMenu : public FileBrowser +{ + friend class SaveGameView; + +public: + SaveGameMenu(Font *font) : + FileBrowser(save_exts, font) + { + this->loadSnapshot = true; + } + + ~SaveGameMenu() + { + } + + virtual void selectCallback(int which) + { + const char *fileName = this->pp_msgs[this->cur_sel]; + + if (this->loadSnapshot) + TheC64->LoadSnapshot(fileName); + else + unlink(fileName); + Gui::gui->popView(); + } + + virtual void hoverCallback(int which) + { + } + + virtual void escapeCallback(int which) + { + Gui::gui->popView(); + } + + bool loadSnapshot; +}; + + +SaveGameView::SaveGameView() : GuiView() +{ + this->menu = new SaveGameMenu(Gui::gui->default_font); + this->gameInfo = new GameInfoBox(Gui::gui->default_font); +} + +SaveGameView::~SaveGameView() +{ + delete this->menu; + delete this->gameInfo; +} + +void SaveGameView::loadGameInfo(const char *what) +{ + this->gameInfo->loadGameInfo(what); +} + +void SaveGameView::setDirectory(const char *path) +{ + this->menu->setDirectory(path); +} + +void SaveGameView::setLoadSnapshot(bool what) +{ + this->menu->loadSnapshot = what; +} + +void SaveGameView::saveSnapshot() +{ + const char *name = "unknown"; + char buf[255]; + + if (strlen(Gui::gui->np->DrivePath[0]) != 0) + name = Gui::gui->np->DrivePath[0]; + snprintf(buf, sizeof(buf), "%s/%s.sav", Gui::gui->save_game_path, name); + + TheC64->SaveSnapshot(buf); +} + +void SaveGameView::runLogic() +{ + this->menu->runLogic(); +} + +void SaveGameView::pushEvent(SDL_Event *ev) +{ + this->menu->pushEvent(ev); +} + +void SaveGameView::draw(SDL_Surface *where) +{ + SDL_Rect dst; + + /* Blit the backgrounds */ + dst = (SDL_Rect){20,45,300,400}; + SDL_BlitSurface(Gui::gui->main_menu_bg, NULL, where, &dst); + + dst = (SDL_Rect){350,13,0,0}; + SDL_BlitSurface(Gui::gui->disc_info, NULL, where, &dst); + + this->menu->draw(where, 50, 70, 280, 375); + this->gameInfo->draw(where, 360, 55, 262, 447); +}