From baa43d1cab5008a5a2b28923eb37e40d4d186dc7 Mon Sep 17 00:00:00 2001 From: "simon.kagstrom" Date: Sat, 16 Jan 2010 14:08:39 +0000 Subject: [PATCH] Add a game info menu, only halfly implemented as of now --- Makefile | 4 +- game_info.cpp | 31 ++++++++++-- game_info.hh | 4 ++ game_info_box.hh | 79 +++++++++++++++++++------------ game_info_menu.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++ gui.cpp | 21 +++++---- gui.hh | 7 +++ main_menu.cpp | 1 + menu_messages.cpp | 8 ++++ menu_messages.hh | 1 + sdl_ttf_font.hh | 2 +- utils.hh | 2 + 12 files changed, 228 insertions(+), 47 deletions(-) create mode 100644 game_info_menu.cpp diff --git a/Makefile b/Makefile index cc041f7..7cf0855 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,9 @@ widget.oo: widget.cpp widget.hh gui.oo: gui.cpp gui.hh Makefile font.hh menu.hh sdl_ttf_font.hh \ dialogue_box.hh help_box.hh main_menu.cpp disc_menu.cpp \ file_browser.hh timer.hh game_info.hh widget.hh options_menu.cpp \ - network_menu.cpp theme_menu.cpp bind_keys_menu.cpp mocks/Prefs.h mocks/C64.h + network_menu.cpp theme_menu.cpp bind_keys_menu.cpp game_info_menu.cpp \ + game_info_box.hh \ + mocks/Prefs.h mocks/C64.h \ virtual_keyboard.oo: virtual_keyboard.hh virtual_keyboard.cpp widget.hh listener.hh diff --git a/game_info.cpp b/game_info.cpp index 65b6dde..abc011b 100644 --- a/game_info.cpp +++ b/game_info.cpp @@ -21,13 +21,22 @@ GameInfo::GameInfo(const char *filename, GameInfo::GameInfo(GameInfo *gi) { - this->name = xstrdup(gi->name); - this->author = xstrdup(gi->author); - this->filename = xstrdup(gi->filename); + if (!gi) + { + this->filename = NULL; + this->name = NULL; + this->author = NULL; this->screenshot = NULL; + return; + } - if (gi->screenshot) - this->screenshot = SDL_DisplayFormatAlpha(gi->screenshot); + this->name = gi->name ? xstrdup(gi->name) : NULL; + this->author = gi->author ? xstrdup(gi->author) : NULL; + this->filename = gi->filename ? xstrdup(gi->filename) : NULL; + this->screenshot = NULL; + + if (gi->screenshot) + this->screenshot = SDL_DisplayFormatAlpha(gi->screenshot); } GameInfo::~GameInfo() @@ -164,3 +173,15 @@ GameInfo *GameInfo::loadFromFile(const char *fileName) return out; } + +void GameInfo::setAuthor(const char *author) +{ + free((void*)this->author); + this->author = xstrdup(author); +} + +void GameInfo::setName(const char *name) +{ + free((void*)this->name); + this->name = xstrdup(name); +} diff --git a/game_info.hh b/game_info.hh index 1ef6bbb..397cd86 100644 --- a/game_info.hh +++ b/game_info.hh @@ -26,6 +26,10 @@ public: ~GameInfo(); + void setAuthor(const char *author); + + void setName(const char *name); + void resetDefaults(); /** Returns an allocated dump structure */ diff --git a/game_info_box.hh b/game_info_box.hh index b716497..d84660a 100644 --- a/game_info_box.hh +++ b/game_info_box.hh @@ -1,3 +1,6 @@ +#ifndef _GAME_INFO_BOX_H_ +#define _GAME_INFO_BOX_H_ + #include "menu.hh" #include "game_info.hh" @@ -14,14 +17,14 @@ public: void setGameInfo(GameInfo *gi) { /* Make a copy */ + if (this->gi) + delete this->gi; this->gi = new GameInfo(gi); + this->updateMessages(); } void loadGameInfo(const char *what) { - this->setText(NULL); - memset(this->gi_messages, 0, sizeof(this->gi_messages)); - /* Reset the current game info */ if (this->gi) { @@ -30,26 +33,19 @@ public: } /* No need to do this for directories or the special "None" field */ - if (strcmp(what, "None") == 0 || - what[0] == '[') - return; - - size_t len = strlen(Gui::gui->metadata_base_path) + strlen(what) + 6; - char *tmp = (char*)xmalloc(len); - sprintf(tmp, "%s/%s.lra", Gui::gui->metadata_base_path, what); - - /* Might return NULL, but that's OK */ - this->gi = GameInfo::loadFromFile(tmp); - if (this->gi) + if ( !(strcmp(what, "None") == 0 || + what[0] == '[') ) { - this->gi_messages[0] = "Game:"; - this->gi_messages[1] = this->gi->name; - this->gi_messages[2] = "Author:"; - this->gi_messages[3] = this->gi->author; - this->setText(this->gi_messages); - } + size_t len = strlen(Gui::gui->metadata_base_path) + strlen(what) + 6; + char *tmp = (char*)xmalloc(len); - free(tmp); + sprintf(tmp, "%s/%s.lra", Gui::gui->metadata_base_path, what); + + /* Might return NULL, but that's OK */ + this->gi = GameInfo::loadFromFile(tmp); + free(tmp); + } + this->updateMessages(); } virtual void selectCallback(int which) @@ -66,20 +62,41 @@ public: { if (!this->gi) return; - if (!this->gi->screenshot) - return; + if (this->gi->screenshot) + { + SDL_Rect dst; - SDL_Rect dst; + /* Blit the screenshot */ + dst = (SDL_Rect){x + w / 2 - this->gi->screenshot->w / 2, y, w, h}; + SDL_BlitSurface(this->gi->screenshot, NULL, where, &dst); - /* Blit the backgrounds */ - dst = (SDL_Rect){x + w / 2 - this->gi->screenshot->w / 2, y, w, h}; - SDL_BlitSurface(this->gi->screenshot, NULL, where, &dst); - - Menu::draw(where, x, y + this->gi->screenshot->h + 10, - w, h - this->gi->screenshot->h - 10); + Menu::draw(where, x, y + this->gi->screenshot->h + 10, + w, h - this->gi->screenshot->h - 10); + } + else + Menu::draw(where, x, y + 10, w, h - 10); + } + + void updateMessages() + { + this->setText(NULL); + memset(this->gi_messages, 0, sizeof(this->gi_messages)); + + this->gi_messages[0] = "Game:"; + this->gi_messages[1] = " "; + this->gi_messages[2] = "Author:"; + this->gi_messages[3] = " "; + if (this->gi) + { + this->gi_messages[1] = this->gi->name ? this->gi->name : " "; + this->gi_messages[3] = this->gi->author ? this->gi->author : " "; + } + + this->setText(this->gi_messages); } -private: const char *gi_messages[6]; GameInfo *gi; }; + +#endif /* _GAME_INFO_BOX_H_ */ diff --git a/game_info_menu.cpp b/game_info_menu.cpp new file mode 100644 index 0000000..10c356a --- /dev/null +++ b/game_info_menu.cpp @@ -0,0 +1,115 @@ +#include "gui.hh" +#include "menu.hh" +#include "game_info_box.hh" +#include "virtual_keyboard.hh" + +class GameInfoView; + +class GameInfoMenu : public Menu, public KeyboardListener +{ + friend class GameInfoView; + +public: + GameInfoMenu(Font *font, GameInfoBox *box) : Menu(font) + { + this->box = box; + this->setText(game_info_menu_messages); + } + + virtual void stringCallback(const char *str) + { + switch (this->cur_sel) + { + case 2: + this->box->gi->setName(str); + break; + case 3: + this->box->gi->setAuthor(str); + break; + default: + panic("Cur sel is %d, not possible!\n", this->cur_sel); + break; + } + this->box->updateMessages(); + } + + virtual void selectCallback(int which) + { + switch (which) + { + case 0: + break; + case 2: + case 3: + VirtualKeyboard::kbd->activate(); + VirtualKeyboard::kbd->registerListener(this); + break; + default: + panic("Impossible menu option\n"); + break; + } + } + + virtual void hoverCallback(int which) + { + } + + virtual void escapeCallback(int which) + { + Gui::gui->popView(); + } + +private: + GameInfoBox *box; +}; + + +class GameInfoView : public GuiView +{ +public: + GameInfoView() : GuiView() + { + this->gameInfo = new GameInfoBox(Gui::gui->default_font);; + this->menu = new GameInfoMenu(Gui::gui->default_font, this->gameInfo); + } + + ~GameInfoView() + { + delete this->gameInfo; + delete this->menu; + } + + void runLogic() + { + this->menu->runLogic(); + } + + void pushEvent(SDL_Event *ev) + { + this->menu->pushEvent(ev); + } + + void viewPushCallback() + { + this->gameInfo->setGameInfo(Gui::gui->cur_gameInfo); + } + + void 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); + } + +protected: + GameInfoMenu *menu; + GameInfoBox *gameInfo; +}; diff --git a/gui.cpp b/gui.cpp index e916ac7..66a895e 100644 --- a/gui.cpp +++ b/gui.cpp @@ -34,6 +34,7 @@ static const char *get_theme_path(const char *dir, const char *what) #include "theme_menu.cpp" #include "options_menu.cpp" #include "network_menu.cpp" +#include "game_info_menu.cpp" #include "main_menu.cpp" GuiView::GuiView() @@ -83,6 +84,8 @@ Gui::Gui() this->metadata_base_path = METADATA_ROOT_PATH; this->game_base_path = GAME_ROOT_PATH; + this->cur_gameInfo = new GameInfo(); + this->dlg = NULL; this->kbd = NULL; @@ -91,6 +94,7 @@ Gui::Gui() this->ov = NULL; this->nv = NULL; this->tv = NULL; + this->giv = NULL; this->bkv = NULL; } @@ -162,17 +166,9 @@ bool Gui::setTheme(const char *path) this->nv = new NetworkView(); this->tv = new ThemeView(); this->bkv = new BindKeysView(); + this->giv = new GameInfoView(); this->pushView(mv); } - else - { - this->mv->updateTheme(); - this->dv->updateTheme(); - this->ov->updateTheme(); - this->nv->updateTheme(); - this->tv->updateTheme(); - this->bkv->updateTheme(); - } VirtualKeyboard::kbd->updateTheme(); @@ -317,6 +313,13 @@ Font *Gui::loadThemeFont(const char *dir, const char *what, int size) return new Font_TTF(fnt, 255,255,255); } +void Gui::updateGameInfo(GameInfo *gi) +{ + panic_if(!gi, "gi must be set\n"); + delete this->cur_gameInfo; + this->cur_gameInfo = gi; +} + /* The singleton/factory stuff */ Gui *Gui::gui; diff --git a/gui.hh b/gui.hh index 052cd23..c76ca9f 100644 --- a/gui.hh +++ b/gui.hh @@ -13,6 +13,7 @@ class DialogueBox; class StatusBar; +class GameInfo; class MainView; class BindKeysView; @@ -20,6 +21,7 @@ class DiscView; class OptionsView; class NetworkView; class ThemeView; +class GameInfoView; class VirtualKeyboard; @@ -59,6 +61,8 @@ public: return this->views[this->n_views-1]; } + void updateGameInfo(GameInfo *gi); + void exitMenu(); /* These are private, keep off! */ @@ -97,6 +101,7 @@ public: DiscView *dv; OptionsView *ov; NetworkView *nv; + GameInfoView *giv; ThemeView *tv; BindKeysView *bkv; @@ -107,6 +112,8 @@ public: const char *theme_base_path; const char *game_base_path; + GameInfo *cur_gameInfo; + /* New preferences */ Prefs *np; diff --git a/main_menu.cpp b/main_menu.cpp index 73d2f90..476ad23 100644 --- a/main_menu.cpp +++ b/main_menu.cpp @@ -81,6 +81,7 @@ public: } break; case 9: /* Game info */ + Gui::gui->pushView(Gui::gui->giv); break; case 10: /* Networking */ Gui::gui->pushView(Gui::gui->nv); diff --git a/menu_messages.cpp b/menu_messages.cpp index 7272b2f..e44ef42 100644 --- a/menu_messages.cpp +++ b/menu_messages.cpp @@ -246,3 +246,11 @@ const char **network_menu_help[] = { NULL, }; + +const char **game_info_menu_messages = (const char*[]){ + /*00*/ "Capture game screenshot", + /*01*/ " ", + /*02*/ "Set game name", + /*02*/ "Set game author", + NULL +}; diff --git a/menu_messages.hh b/menu_messages.hh index e3004ac..9334677 100644 --- a/menu_messages.hh +++ b/menu_messages.hh @@ -9,6 +9,7 @@ extern const char **bind_key_menu_messages; extern const char **options_menu_messages; extern const char **options_menu_help[]; +extern const char **game_info_menu_messages; /* The menu messages are dynamically generated */ extern const char **network_menu_help[]; diff --git a/sdl_ttf_font.hh b/sdl_ttf_font.hh index f1c0820..7b21d1f 100644 --- a/sdl_ttf_font.hh +++ b/sdl_ttf_font.hh @@ -47,7 +47,7 @@ public: SDL_Rect dst; p = TTF_RenderText_Blended(this->font, msg, this->clr); - panic_if(!p, "TTF error for %s: %s\n", msg, TTF_GetError()); + panic_if(!p, "TTF error for '%s': %s\n", msg, TTF_GetError()); dst = (SDL_Rect){x, y, w, h}; diff --git a/utils.hh b/utils.hh index 09a5998..41c7e64 100644 --- a/utils.hh +++ b/utils.hh @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ class Font; fprintf(stderr, "=============PANIC PANIC PANIC===========\n"); \ fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); fprintf(stderr, x); \ fprintf(stderr, "=========================================\n"); \ + assert(0); \ exit(1); \ } while(0)