diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 759d63ee0..2428bd5a8 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -1,4 +1,4 @@ -OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardSelector.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/Token.o objs/Translate.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o +OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardSelector.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateAwards.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/Rules.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/SimplePad.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/Token.o objs/Translate.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) diff --git a/projects/mtg/bin/Res/graphics/awardback.jpg b/projects/mtg/bin/Res/graphics/awardback.jpg new file mode 100644 index 000000000..2ead9b90d Binary files /dev/null and b/projects/mtg/bin/Res/graphics/awardback.jpg differ diff --git a/projects/mtg/bin/Res/graphics/button_trophy.png b/projects/mtg/bin/Res/graphics/button_trophy.png new file mode 100644 index 000000000..681903f63 Binary files /dev/null and b/projects/mtg/bin/Res/graphics/button_trophy.png differ diff --git a/projects/mtg/bin/Res/graphics/trophy.png b/projects/mtg/bin/Res/graphics/trophy.png new file mode 100644 index 000000000..0f94c5e54 Binary files /dev/null and b/projects/mtg/bin/Res/graphics/trophy.png differ diff --git a/projects/mtg/bin/Res/graphics/trophy_prx_eviltwin.png b/projects/mtg/bin/Res/graphics/trophy_prx_eviltwin.png new file mode 100644 index 000000000..5604ceb8a Binary files /dev/null and b/projects/mtg/bin/Res/graphics/trophy_prx_eviltwin.png differ diff --git a/projects/mtg/bin/Res/graphics/trophy_prx_handler.png b/projects/mtg/bin/Res/graphics/trophy_prx_handler.png new file mode 100644 index 000000000..99212e799 Binary files /dev/null and b/projects/mtg/bin/Res/graphics/trophy_prx_handler.png differ diff --git a/projects/mtg/bin/Res/graphics/trophy_prx_rimom.png b/projects/mtg/bin/Res/graphics/trophy_prx_rimom.png new file mode 100644 index 000000000..abe2dfd20 Binary files /dev/null and b/projects/mtg/bin/Res/graphics/trophy_prx_rimom.png differ diff --git a/projects/mtg/bin/Res/graphics/trophy_prx_rnddeck.png b/projects/mtg/bin/Res/graphics/trophy_prx_rnddeck.png new file mode 100644 index 000000000..eeec6e73c Binary files /dev/null and b/projects/mtg/bin/Res/graphics/trophy_prx_rnddeck.png differ diff --git a/projects/mtg/bin/Res/graphics/trophy_set.png b/projects/mtg/bin/Res/graphics/trophy_set.png new file mode 100644 index 000000000..5d434d18b Binary files /dev/null and b/projects/mtg/bin/Res/graphics/trophy_set.png differ diff --git a/projects/mtg/bin/daily_build/template.exe b/projects/mtg/bin/daily_build/template.exe index 98a5d8ee1..13b5566dc 100644 Binary files a/projects/mtg/bin/daily_build/template.exe and b/projects/mtg/bin/daily_build/template.exe differ diff --git a/projects/mtg/include/GameApp.h b/projects/mtg/include/GameApp.h index 104ed8678..72a15fb20 100644 --- a/projects/mtg/include/GameApp.h +++ b/projects/mtg/include/GameApp.h @@ -31,9 +31,6 @@ #include "../include/CardEffect.h" -#define MAX_STATE 6 - - #define PLAYER_TYPE_CPU 0 #define PLAYER_TYPE_HUMAN 1 #define PLAYER_TYPE_TESTSUITE 2 @@ -59,7 +56,7 @@ class GameApp: public JApp GameState* mCurrentState; GameState* mNextState; - GameState* mGameStates[MAX_STATE]; + GameState* mGameStates[GAME_STATE_MAX]; public: diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index 8906c2a5c..45f2b8475 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -6,6 +6,7 @@ using std::map; using std::string; #include +#include #include "../include/SimplePad.h" #include "../include/GameApp.h" @@ -23,14 +24,10 @@ public: enum { //Global settings ACTIVE_PROFILE, - DIFFICULTY_MODE_UNLOCKED, - MOMIR_MODE_UNLOCKED, - EVILTWIN_MODE_UNLOCKED, - RANDOMDECK_MODE_UNLOCKED, LANG, LAST_GLOBAL = LANG, //This must be the value above, to keep ordering. //Values /must/ match ordering in optionNames, or everything loads wrong. - //Profile settings + //Profile settings ACTIVE_THEME, ACTIVE_MODE, MUSICVOLUME, @@ -62,6 +59,11 @@ public: INTERRUPT_ENDTURN, INTERRUPT_CLEANUP, INTERRUPT_AFTEREND, + BEGIN_AWARDS, //Options after this use the GameOptionAward struct, which includes a timestamp. + DIFFICULTY_MODE_UNLOCKED = BEGIN_AWARDS, + MOMIR_MODE_UNLOCKED, + EVILTWIN_MODE_UNLOCKED, + RANDOMDECK_MODE_UNLOCKED, LAST_NAMED, //Any option after this does not look up in optionNames. SET_UNLOCKS = LAST_NAMED + 1, //For sets. }; @@ -109,6 +111,19 @@ public: EnumDefinition * def; }; +class GameOptionAward: public GameOption { +public: + virtual string menuStr(); + virtual bool write(std::ofstream * file, string name); + virtual bool read(string input); + virtual bool giveAward(); //Returns false if already awarded + virtual bool isViewed() {return viewed;}; + virtual void setViewed(bool v = true) {viewed = v;}; +private: + time_t achieved; //When was it awarded? + bool viewed; //Flag it as "New!" or not. +}; + class OptionVolume: public EnumDefinition{ public: enum { MUTE = 0, MAX = 100 }; @@ -181,6 +196,7 @@ public: void keypadUpdate(float dt) {if(keypad) keypad->Update(dt);}; void keypadRender() {if(keypad) keypad->Render();}; + bool newAward(); //These return a filepath accurate to the current mode/profile/theme, and can //optionally fallback to a file within a certain directory. diff --git a/projects/mtg/include/GameState.h b/projects/mtg/include/GameState.h index 762bba549..36e8faa1d 100644 --- a/projects/mtg/include/GameState.h +++ b/projects/mtg/include/GameState.h @@ -11,11 +11,13 @@ using namespace std; enum ENUM_GAME_STATE { - GAME_STATE_MENU = 0x01, - GAME_STATE_DUEL = 0x02, - GAME_STATE_DECK_VIEWER = 0x03, - GAME_STATE_SHOP = 0x04, - GAME_STATE_OPTIONS = 0x05, + GAME_STATE_MENU = 1, + GAME_STATE_DUEL = 2, + GAME_STATE_DECK_VIEWER = 3, + GAME_STATE_SHOP = 4, + GAME_STATE_OPTIONS = 5, + GAME_STATE_AWARDS = 6, + GAME_STATE_MAX = 7, }; diff --git a/projects/mtg/include/OptionItem.h b/projects/mtg/include/OptionItem.h index ea2b0420f..9f33ad167 100644 --- a/projects/mtg/include/OptionItem.h +++ b/projects/mtg/include/OptionItem.h @@ -10,7 +10,6 @@ using std::string; #define MAX_OPTION_TABS 5 -#define MAX_OPTION_ITEMS 20 #define MAX_ONSCREEN_OPTIONS 8 #define OPTION_CENTER 4 @@ -130,6 +129,67 @@ protected: int id; }; +class WDataSource{ +public: + WDataSource() {}; + virtual JQuad * getImage() {return NULL;}; + virtual MTGCard * getCard() {return NULL;}; + virtual bool thisCard(int mtgid) {return false;}; + + virtual int getPos() {return -1;}; + virtual bool setPos(int pos) {return false;}; + virtual bool next() {return false;}; + virtual bool prev() {return false;}; +}; + +class WSrcImage: public WDataSource{ +public: + virtual JQuad * getImage(); + WSrcImage(string s); + +private: + string filename; +}; + +class WSrcMTGSet: public WDataSource{ +public: + WSrcMTGSet(int setid); + + virtual JQuad * getImage(); + virtual MTGCard * getCard(); + + virtual bool thisCard(int mtgid); + virtual bool next(); + virtual bool prev(); + virtual int getPos() {return currentCard;}; + virtual bool setPos(int pos); + +protected: + vector cards; + int currentCard; +}; + +class WGuiImage: public WGuiItem{ +public: + WGuiImage(WDataSource * wds, float _w = 0, float _h = 0, int _margin = 0); + virtual bool Selectable() {return false;}; + virtual void Render(); + virtual float getHeight(); + virtual void imageScale(float _w, float _h); +protected: + int margin; + float imgW, imgH; + WDataSource * source; +}; + +class WGuiCardImage: public WGuiImage{ +public: + WGuiCardImage(WDataSource * wds, int _offset=0); + virtual void Render(); +protected: + int offset; +}; + //This is our base class for decorators. It wraps everything about WGuiBase. class WGuiDeco: public WGuiBase{ public: @@ -174,10 +234,24 @@ protected: WGuiBase * it; }; +class WGuiAward: public WGuiItem{ +public: + WGuiAward(int _id, string name, string _text); + virtual ~WGuiAward(); + virtual void Render(); + virtual bool Selectable() {return Visible();}; + virtual bool Visible(); + virtual int getId() {return id;}; + virtual void Overlay(); +protected: + int id; + string text; +}; + class WGuiSplit: public WGuiItem{ public: WGuiSplit(WGuiBase* _left,WGuiBase* _right); - ~WGuiSplit(); + virtual ~WGuiSplit(); virtual void Reload(); virtual void Overlay(); @@ -206,7 +280,7 @@ public: class WDecoConfirm: public WGuiDeco{ public: WDecoConfirm(JGuiListener * _listener, WGuiBase * it); - ~WDecoConfirm(); + virtual ~WDecoConfirm(); virtual bool isModal(); virtual void setData(); @@ -261,13 +335,6 @@ protected: JGuiListener * mListener; }; -class WGuiText:public WGuiItem { - public: - WGuiText(string _displayValue): WGuiItem(_displayValue) {}; - virtual bool Selectable() {return false;}; - virtual void Render(); -}; - class WGuiHeader:public WGuiItem{ public: WGuiHeader(string _displayValue): WGuiItem(_displayValue) {}; @@ -277,41 +344,7 @@ class WGuiHeader:public WGuiItem{ }; -class WGuiList: public WGuiItem{ - public: - WGuiList(string name); - ~WGuiList(); - - string failMsg; - int nbitems; - int current; - - virtual bool hasFocus() {return mFocus;}; - virtual void setFocus(bool bFocus) {mFocus = bFocus;}; - virtual bool Leaving(u32 key); - virtual void Entering(u32 key); - virtual void Render(); - virtual void confirmChange(bool confirmed); - virtual void renderBack(WGuiBase * it); - virtual void Reload(); - virtual void ButtonPressed(int controllerId, int controlId); - virtual void Update(float dt); - virtual void setData(); - virtual bool isModal(); - virtual void setModal(bool val); - - void Add(WGuiBase * item); - WGuiBase * Current(); - void nextOption(); - void prevOption(); - - WGuiBase * operator[](int); -protected: - bool mFocus; - WGuiBase * listItems[MAX_OPTION_ITEMS]; -}; - -class WGuiMenu{ +class WGuiMenu: public WGuiItem{ public: virtual ~WGuiMenu(); @@ -323,16 +356,49 @@ public: virtual void ButtonPressed(int controllerId, int controlId); virtual void Add(WGuiBase* item); //Remember, does not set X & Y of items automatically. virtual void confirmChange(bool confirmed); + virtual bool Leaving(u32 key); + virtual void Entering(u32 key); + virtual void renderBack(WGuiBase * it); WGuiBase * Current(); - void nextItem(); - void prevItem(); + virtual void nextItem(); + virtual void prevItem(); + virtual bool isModal(); + virtual void setModal(bool val); + void setData(); protected: u32 buttonNext, buttonPrev; vector items; int currentItem; + u32 held; + float duration; +}; + +class WGuiFlow: public WGuiMenu{ +public: + WGuiFlow(); +}; + +class WGuiList: public WGuiMenu{ + public: + WGuiList(string name, WDataSource * syncme = NULL); + + string failMsg; + + virtual void Render(); + virtual void confirmChange(bool confirmed); + virtual void ButtonPressed(int controllerId, int controlId); + virtual void setData(); + + virtual void nextItem(); + virtual void prevItem(); + + WGuiBase * operator[](int); +protected: + WDataSource * sync; + bool mFocus; }; class WGuiTabMenu: public WGuiMenu { diff --git a/projects/mtg/src/CardSelector.cpp b/projects/mtg/src/CardSelector.cpp index e6fefbfe5..096d56771 100644 --- a/projects/mtg/src/CardSelector.cpp +++ b/projects/mtg/src/CardSelector.cpp @@ -138,7 +138,11 @@ bool CardSelector::CheckUserInput(u32 key) active = closest(cards, limitor, active); break; case PSP_CTRL_TRIANGLE: - bigMode = (bigMode+1) % NB_BIG_MODES; + bigMode = (bigMode+1) % NB_BIG_MODES; + if(bigMode == BIG_MODE_TEXT) + options[Options::DISABLECARDS].number = 1; + else + options[Options::DISABLECARDS].number = 0; return true; default: return false; diff --git a/projects/mtg/src/Credits.cpp b/projects/mtg/src/Credits.cpp index ffae93bfa..e0b9a8cb7 100644 --- a/projects/mtg/src/Credits.cpp +++ b/projects/mtg/src/Credits.cpp @@ -78,32 +78,38 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){ bonus.push_back(b); } + GameOptionAward * goa = NULL; if (unlocked == -1){ unlocked = isDifficultyUnlocked(); if (unlocked){ unlockedTex = resources.RetrieveTexture("unlocked.png"); unlockedQuad = resources.RetrieveQuad("unlocked.png", 2, 2, 396, 96); - options[Options::DIFFICULTY_MODE_UNLOCKED] = GameOption(1); + goa = (GameOptionAward*) &options[Options::DIFFICULTY_MODE_UNLOCKED]; + goa->giveAward(); options.save(); } else if ((unlocked = isMomirUnlocked())) { unlockedTex = resources.RetrieveTexture("momir_unlocked.png"); unlockedQuad = resources.RetrieveQuad("momir_unlocked.png", 2, 2, 396, 96); - options[Options::MOMIR_MODE_UNLOCKED] = GameOption(1); + goa = (GameOptionAward*) &options[Options::MOMIR_MODE_UNLOCKED]; + goa->giveAward(); options.save(); } else if ((unlocked = isEvilTwinUnlocked())) { unlockedTex = resources.RetrieveTexture("eviltwin_unlocked.png"); unlockedQuad = resources.RetrieveQuad("eviltwin_unlocked.png", 2, 2, 396, 96); - options[Options::EVILTWIN_MODE_UNLOCKED] = GameOption(1); + goa = (GameOptionAward*) &options[Options::EVILTWIN_MODE_UNLOCKED]; + goa->giveAward(); options.save(); }else if((unlocked = isRandomDeckUnlocked())) { unlockedTex = resources.RetrieveTexture("randomdeck_unlocked.png"); unlockedQuad = resources.RetrieveQuad("randomdeck_unlocked.png", 2, 2, 396, 96); - options[Options::RANDOMDECK_MODE_UNLOCKED] = GameOption(1); + goa = (GameOptionAward*) &options[Options::RANDOMDECK_MODE_UNLOCKED]; + goa->giveAward(); options.save(); }else if((unlocked = unlockRandomSet())) { unlockedTex = resources.RetrieveTexture("set_unlocked.png"); unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96); - options[Options::optionSet(unlocked - 1)] = GameOption(1); + goa = (GameOptionAward*) &options[Options::optionSet(unlocked - 1)]; + goa->giveAward(); options.save(); MTGSetInfo * si = setlist.getInfo(unlocked - 1); if(si) unlockedString = si->getName(); //Show the set's pretty name for unlocks. diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index 29b857f5f..f38fcab0a 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -15,6 +15,7 @@ #include "../include/GameStateDuel.h" #include "../include/GameStateOptions.h" #include "../include/GameStateShop.h" +#include "../include/GameStateAwards.h" #include "../include/DeckStats.h" #include "../include/Translate.h" @@ -41,7 +42,7 @@ GameApp::GameApp(): JApp() #endif mScreenShotCount = 0; - for (int i=0; i < MAX_STATE ; i++) + for (int i=0; i < GAME_STATE_MAX ; i++) mGameStates[i] = NULL; mShowDebugInfo = false; @@ -174,6 +175,9 @@ void GameApp::Create() mGameStates[GAME_STATE_OPTIONS] = NEW GameStateOptions(this); mGameStates[GAME_STATE_OPTIONS]->Create(); + mGameStates[GAME_STATE_AWARDS] = NEW GameStateAwards(this); + mGameStates[GAME_STATE_AWARDS]->Create(); + mCurrentState = NULL; mNextState = mGameStates[GAME_STATE_MENU]; @@ -194,7 +198,7 @@ void GameApp::LoadGameStates() void GameApp::Destroy() { LOG("==Destroying GameApp=="); - for (int i=GAME_STATE_MENU;i<=MAX_STATE-1;i++) + for (int i=GAME_STATE_MENU;i<=GAME_STATE_MAX-1;i++) { if (mGameStates[i]){ mGameStates[i]->Destroy(); diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index 0147abecc..5eb11fa84 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -2,6 +2,7 @@ #include "../include/utils.h" #include "../include/MTGDeck.h" #include "../include/GameOptions.h" +#include "../include/Translate.h" #include "../include/OptionItem.h" #include #include @@ -12,10 +13,6 @@ const char * Options::optionNames[] = { //Global options "Profile", - "prx_handler", - "prx_rimom", - "prx_eviltwin", - "prx_rnddeck", "Lang", //Options set on a per-profile basis "Theme", @@ -48,6 +45,11 @@ const char * Options::optionNames[] = { "interruptEndTurn", "interruptCleanup", "interruptAfterEnd", +//Unlocked modes + "prx_handler", + "prx_rimom", + "prx_eviltwin", + "prx_rnddeck", }; int Options::getID(string name){ if(!name.size()) @@ -166,8 +168,7 @@ bool GameOption::isDefault(){ return false; } -PIXEL_TYPE GameOption::asColor(PIXEL_TYPE fallback) -{ +PIXEL_TYPE GameOption::asColor(PIXEL_TYPE fallback){ unsigned char color[4]; string temp; int subpixel=0; @@ -257,7 +258,6 @@ bool GameOption::write(std::ofstream * file, string name){ GameOptions::GameOptions(string filename){ mFilename = filename; - values.reserve(Options::LAST_NAMED); //Reserve space for all named options. load(); } @@ -338,6 +338,7 @@ GameOption * GameOptions::get(int optionID) { while(x <= optionID){ switch(x){ + //Enum options case Options::HANDDIRECTION: goEnum = NEW GameOptionEnum(); goEnum->def = OptionHandDirection::getInstance(); @@ -354,7 +355,10 @@ GameOption * GameOptions::get(int optionID) { go = goEnum; break; default: - go = NEW GameOption(); + if(x >= Options::BEGIN_AWARDS) + go = NEW GameOptionAward(); + else + go = NEW GameOption(); break; } values.push_back(go); @@ -386,6 +390,20 @@ GameSettings::~GameSettings(){ SAFE_DELETE(keypad); } +bool GameSettings::newAward(){ + if(!profileOptions) + return false; + + for(int x=Options::BEGIN_AWARDS;x < Options::SET_UNLOCKS + setlist.size();x++){ + GameOptionAward * goa = dynamic_cast(profileOptions->get(x)); + if(!goa) + continue; + if(!goa->isViewed()) + return true; + } + return false; +} + GameOption GameSettings::invalid_option = GameOption(0); GameOption& GameSettings::operator[](int optionID){ @@ -482,8 +500,17 @@ void GameSettings::checkProfile(){ globalOptions = NEW GameOptions(GLOBAL_SETTINGS); //If it doesn't exist, load current profile. - if(!profileOptions) + if(!profileOptions){ profileOptions = NEW GameOptions(profileFile(PLAYER_SETTINGS,"",false)); + //Backwards compatability hack for unlocked modes. + for(int x=Options::BEGIN_AWARDS;x(globalOptions->get(x)); + if(goa){ + GameOptionAward * dupe = dynamic_cast(profileOptions->get(x)); + if(dupe && !dupe->number) dupe->giveAward(); + } + } + } //Validation of collection, etc, only happens if the game is up. if(theGame == NULL || theGame->collection == NULL) @@ -603,6 +630,7 @@ void GameSettings::keypadShutdown(){ SAFE_DELETE(keypad); } +//EnumDefinition int EnumDefinition::findIndex(int value){ vector::iterator it; for(it = values.begin();it!=values.end();it++){ @@ -613,6 +641,7 @@ int EnumDefinition::findIndex(int value){ return INVALID_ID; //Failed! } +//GameOptionEnum string GameOptionEnum::menuStr(){ if(def){ int idx = def->findIndex(number); @@ -626,7 +655,7 @@ string GameOptionEnum::menuStr(){ } bool GameOptionEnum::write(std::ofstream * file, string name){ - if(!file || !def || number < 0 || number >= (int) def->values.size()) + if(!file || !def || number <= 0 || number >= (int) def->values.size()) return false; char writer[1024]; @@ -640,6 +669,7 @@ bool GameOptionEnum::read(string input){ if(!def) return false; + number = 0; std::transform(input.begin(),input.end(),input.begin(),::tolower); vector::iterator it; @@ -654,6 +684,8 @@ bool GameOptionEnum::read(string input){ return false; } + +//Enum Definitions OptionClosedHand OptionClosedHand::mDef; OptionClosedHand::OptionClosedHand(){ mDef.values.push_back(EnumDefinition::assoc(INVISIBLE, "invisible")); @@ -682,4 +714,107 @@ OptionDifficulty::OptionDifficulty(){ mDef.values.push_back(EnumDefinition::assoc(HARD, "Hard")); mDef.values.push_back(EnumDefinition::assoc(HARDER, "Harder")); mDef.values.push_back(EnumDefinition::assoc(EVIL, "Evil")); -}; \ No newline at end of file +}; + +//GameOptionAward +bool GameOptionAward::read(string input){ + //This is quick and dirty. + bool bNumeric = true; + achieved = time(NULL); + tm * at = localtime(&achieved); + viewed = false; + + size_t inlen = input.size(); + if(!inlen){ + return true; //Default reader doesn't care about invalid formatting. + }else if(inlen < 8 || input != "0"){ //Regardless of what garbage this is fed, a non-zero value is "Awarded" + number = 1; + } + + size_t w = input.find("V"); + + if(w != string::npos) + viewed = true; + + //TODO: Something cleaner. + int tvals[5]; + int i; + for(i=0;i<5;i++) + tvals[i] = 0; + + string buf; + for(size_t t=0,i=0;;t++){ + if(!isdigit(input[t])){ + if(!isspace(input[t]) && buf.size()){ + tvals[i] = atoi(buf.c_str()); + if(tvals[i] < 0) + tvals[i] = 0; + buf.clear(); + i++; //Advance through input. + } + }else{ + buf+= input[t]; + } + + if(t >= input.size() || i >= 5) + break; + } + + if(tvals[0] >= 1900) + tvals[0] -= 1900; + if(tvals[1] > 0) + tvals[1]--; + at->tm_year = tvals[0]; + at->tm_mon = tvals[1]; + at->tm_mday = tvals[2]; + if(tvals[3]) + at->tm_hour = tvals[3]; + if(tvals[4]) + at->tm_min = tvals[4]; + at->tm_isdst = -1; + + achieved = mktime(at); + if(achieved == -1) + achieved = time(NULL); + return true; +} + +bool GameOptionAward::write(std::ofstream * file, string name){ + char writer[1024]; + + if(!file) + return false; + + if(number == 0) //Is not unlocked. Don't write. + return true; + + tm * at = localtime(&achieved); + if(!at) return false; //Hurrah for paranoia. + + + sprintf(writer,"%s=%d/%d/%d@%d:%d %s\n", name.c_str(), + at->tm_year + 1900, at->tm_mon + 1, at->tm_mday, at->tm_hour, at->tm_min, (viewed ? "V" : "")); + (*file)< Constants::MTG_COLOR_LAND) colorFilter =-1; break; - case PSP_CTRL_TRIANGLE : + case PSP_CTRL_TRIANGLE: + options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; + break; + case PSP_CTRL_SQUARE : if (last_user_activity > 0.2) { last_user_activity = 0; @@ -297,14 +300,14 @@ void GameStateDeckViewer::Update(float dt) } stw.needUpdate = true; break; - case PSP_CTRL_SQUARE : + /*case PSP_CTRL_SQUARE : if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY){ last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; }else{ last_user_activity = 0; mStage = STAGE_WAITING; } - break; + break;*/ case PSP_CTRL_START : mStage = STAGE_MENU; break; @@ -317,12 +320,18 @@ void GameStateDeckViewer::Update(float dt) scrollSpeed = HIGH_SPEED; break; case PSP_CTRL_LTRIGGER : - if ((mStage == STAGE_ONSCREEN_MENU) && (--stw.currentPage < 0)) { + if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY){ + last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; + } + else if ((mStage == STAGE_ONSCREEN_MENU) && (--stw.currentPage < 0)) { stw.currentPage = stw.pageCount; } break; case PSP_CTRL_RTRIGGER : - if ((mStage == STAGE_ONSCREEN_MENU) && (++stw.currentPage > stw.pageCount)) { + if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY){ + last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; + } + else if ((mStage == STAGE_ONSCREEN_MENU) && (++stw.currentPage > stw.pageCount)) { stw.currentPage = 0; } break; @@ -497,6 +506,7 @@ void GameStateDeckViewer::renderOnScreenMenu(){ font->SetColor(ARGB(255,255,255,255)); JRenderer * r = JRenderer::GetInstance(); float pspIconsSize = 0.5; + float fH = font->GetHeight() + 1; float leftTransition = onScreenTransition*84; float rightTransition = onScreenTransition*204; @@ -505,6 +515,7 @@ void GameStateDeckViewer::renderOnScreenMenu(){ float rightPspX = SCREEN_WIDTH-100 + rightTransition; float rightPspY = SCREEN_HEIGHT/2 - 20 ; + if (stw.currentPage == 0) { //FillRects r->FillRect(0-(onScreenTransition*84),0,84,SCREEN_HEIGHT,ARGB(128,0,0,0)); @@ -519,7 +530,6 @@ void GameStateDeckViewer::renderOnScreenMenu(){ r->RenderQuad(pspIcons[2],leftPspX - 20, leftPspY,0,pspIconsSize,pspIconsSize); r->RenderQuad(pspIcons[3],leftPspX + 20, leftPspY,0,pspIconsSize,pspIconsSize); - font->DrawString(_("Prev."), leftPspX - 35, leftPspY-15); font->DrawString(_("Next"), leftPspX + 15, leftPspY-15); font->DrawString(_("card"), leftPspX - 35, leftPspY); @@ -534,14 +544,15 @@ void GameStateDeckViewer::renderOnScreenMenu(){ r->RenderQuad(pspIcons[6],rightPspX-20, rightPspY,0,pspIconsSize,pspIconsSize); r->RenderQuad(pspIcons[7],rightPspX, rightPspY + 20,0,pspIconsSize,pspIconsSize); + font->DrawString(_("Toggle Images"), rightPspX - 35, rightPspY - 40); + if (displayed_deck == myCollection){ font->DrawString(_("Add card"), rightPspX + 20, rightPspY-15); - font->DrawString(_("Display Deck"), rightPspX - 35, rightPspY - 40); + font->DrawString(_("View Deck"), rightPspX - 20 , rightPspY-15, JGETEXT_RIGHT); }else{ font->DrawString(_("Remove card"), rightPspX + 20, rightPspY-15); - font->DrawString(_("Display Collection"), rightPspX - 35, rightPspY - 40); + font->DrawString(_("View Collection"), rightPspX - 20 , rightPspY-15, JGETEXT_RIGHT); } - font->DrawString(_("Deck info"), rightPspX - 70 , rightPspY-15); font->DrawString(_("Sell card"), rightPspX - 30 , rightPspY+20); //Bottom menus font->DrawString(_("menu"), SCREEN_WIDTH-35 +rightTransition, SCREEN_HEIGHT-15); @@ -564,16 +575,16 @@ void GameStateDeckViewer::renderOnScreenMenu(){ sprintf(buffer, _("Your Deck: %i cards").c_str(), value); font->DrawString(buffer, SCREEN_WIDTH-200+rightTransition, SCREEN_HEIGHT/2 + 25); - font->DrawString(_("You are currently viewing your"), SCREEN_WIDTH-200+rightTransition, 5); if (displayed_deck == myCollection){ - font->DrawString(_("collection. Press TRIANGLE"), SCREEN_WIDTH-200+rightTransition, 19); - font->DrawString(_("to switch to your deck."), SCREEN_WIDTH-200+rightTransition, 33); + font->DrawString(_("in: collection"), 5-leftTransition, 5); + font->DrawString(_("Use SQUARE to view your deck,"), SCREEN_WIDTH-200+rightTransition, 5); }else{ - font->DrawString(_("deck. Press TRIANGLE to"), SCREEN_WIDTH-200+rightTransition, 19); - font->DrawString(_("switch to your collection."), SCREEN_WIDTH-200+rightTransition, 33); + font->DrawString(_("in: deck"), 5-leftTransition, 5); + font->DrawString(_("Use SQUARE to view collection,"), SCREEN_WIDTH-200+rightTransition, 5); } - font->DrawString(_("Press L/R to cycle through"), SCREEN_WIDTH-200+rightTransition, 47); - font->DrawString(_("deck statistics."), SCREEN_WIDTH-200+rightTransition, 61); + font->DrawString(_("Press L/R to cycle through"), SCREEN_WIDTH-200+rightTransition, 5+fH); + font->DrawString(_("deck statistics."), SCREEN_WIDTH-200+rightTransition, 5+fH*2); + } else { if (stw.needUpdate) { updateStats(); @@ -1294,7 +1305,6 @@ void GameStateDeckViewer::Render() { }else{ mFont->DrawString(_("No Card"), SCREEN_WIDTH/2, SCREEN_HEIGHT/2,JGETEXT_CENTER); } - if (mStage == STAGE_ONSCREEN_MENU){ renderOnScreenMenu(); }else if (mStage == STAGE_WELCOME){ diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 1547e5221..a9bca13be 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -392,6 +392,8 @@ void GameStateMenu::Update(float dt) } if (mGuiController) mGuiController->Update(dt); + if(mEngine->GetButtonState(PSP_CTRL_RTRIGGER)) //Hook for GameStateAward state + mParent->SetNextState(GAME_STATE_AWARDS); break; case MENU_STATE_MAJOR_SUBMENU : subMenuController->Update(dt); @@ -505,16 +507,27 @@ void GameStateMenu::Render() mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); mFont->SetColor(ARGB(128,255,255,255)); - mFont->DrawString(GAME_VERSION, SCREEN_WIDTH-10,5,JGETEXT_RIGHT); + mFont->DrawString(GAME_VERSION, SCREEN_WIDTH-74,5,JGETEXT_RIGHT); mFont->DrawString(nbcardsStr,10, 5); mFont->SetScale(1.f); mFont->SetColor(ARGB(255,255,255,255)); - renderer->FillRoundRect(SCREEN_WIDTH/2 - 100,SCREEN_HEIGHT-20, 191,6,5,ARGB(100,10,5,0)); + renderer->FillRoundRect(SCREEN_WIDTH/2 - 100,SCREEN_HEIGHT, 191,6,5,ARGB(100,10,5,0)); scroller->Render(); - renderer->RenderQuad(mBg, SCREEN_WIDTH/2, 50); + + if(mBg) + renderer->RenderQuad(mBg,SCREEN_WIDTH/2,50); + JQuad * jq = resources.RetrieveTempQuad("button_trophy.png"); + if(jq){ + int alp = 255; + if(options.newAward()) + alp = (int) (sin(timeIndex) * 255); + + jq->SetColor(ARGB(abs(alp),255,255,255)); + renderer->RenderQuad(jq, SCREEN_WIDTH-64, 0); + } } if (subMenuController){ subMenuController->Render(); diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index 92ed7700e..185272f3a 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -78,7 +78,7 @@ void GameStateOptions::Start() optionsMenu->Add(2, "Back to Main Menu"); optionsMenu->Add(3, "Cancel"); - optionsTabs->Current()->Entering(0); + optionsTabs->Entering(0); } @@ -91,7 +91,7 @@ void GameStateOptions::End() void GameStateOptions::Update(float dt) -{ +{ timer += dt; if(options.keypadActive()){ @@ -160,7 +160,7 @@ void GameStateOptions::Render() "Please support this project with donations at http://wololo.net/wagic", }; - JLBFont * mFont = resources.GetJLBFont("magic"); + JLBFont * mFont = resources.GetJLBFont(Constants::MAGIC_FONT); mFont->SetColor(ARGB(255,200,200,200)); mFont->SetScale(1.0); float startpos = 272 - timer * 10; diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 6bc942b06..2ab4ff486 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -683,6 +683,7 @@ int MTGSets::size(){ //MTGSetInfo MTGSetInfo::MTGSetInfo(string _id) { + string whitespaces (" \t\f\v\n\r"); id = _id; block = -1; year = -1; @@ -706,7 +707,7 @@ MTGSetInfo::MTGSetInfo(string _id) { continue; string key = s.substr(0,i); - string value = s.substr(i+1); + string value = s.substr(i+1,i+1-s.find_last_not_of(whitespaces)); if(key.compare("name") == 0) name = value; diff --git a/projects/mtg/src/OptionItem.cpp b/projects/mtg/src/OptionItem.cpp index 70ba1b7c2..6b1db129e 100644 --- a/projects/mtg/src/OptionItem.cpp +++ b/projects/mtg/src/OptionItem.cpp @@ -52,6 +52,8 @@ WGuiItem::WGuiItem(string _display){ mFocus = false; width=SCREEN_WIDTH; height=20; + x=0; + y=0; } void WGuiItem::Update(float dt){ @@ -70,17 +72,6 @@ void WGuiHeader::Render(){ mFont->DrawString(_(displayValue).c_str(),x+width/2,y,JGETEXT_CENTER); } -//WGuiText -void WGuiText::Render(){ - JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); - mFont->SetScale(.8); - mFont->SetColor(getColor(WGuiColor::TEXT_BODY)); - - JRenderer * renderer = JRenderer::GetInstance(); - mFont->DrawString(_(displayValue).c_str(),x,y,JGETEXT_LEFT); - mFont->SetScale(1); -} - //OptionItem OptionItem::OptionItem( int _id, string _displayValue): WGuiItem(_displayValue) { id = _id; @@ -433,91 +424,73 @@ OptionDirectory::OptionDirectory(string _root, int _id, string _displayValue): O initSelections(); } -//WGuiList -WGuiList::WGuiList(string name): WGuiItem(name){ - failMsg = "NO OPTIONS AVAILABLE"; - nbitems = 0; - current = -1; - width = SCREEN_WIDTH-10; - y = 0; - x = 0; - mFocus = false; -} -WGuiList::~WGuiList(){ - for (int i = 0 ; i < nbitems; i++){ - SAFE_DELETE(listItems[i]); - } -} -void WGuiList::setModal(bool val){ - listItems[current]->setModal(val); -} -bool WGuiList::isModal(){ - if(current >= 0 && current < nbitems) - if(listItems[current]->isModal()) - return true; - return false; -} -void WGuiList::Add(WGuiBase * item){ - if (nbitems < MAX_OPTION_ITEMS){ - listItems[nbitems] = item; - nbitems++; - } -} -bool WGuiList::Leaving(u32 key){ - if(key == PSP_CTRL_DOWN && current < nbitems-1) +bool WGuiMenu::Leaving(u32 key){ + int nbitems = (int) items.size(); + if(key == buttonNext && currentItem < nbitems-1) return false; - else if(key == PSP_CTRL_UP && current > 0) + else if(key == buttonPrev && currentItem > 0) return false; - if(current >= 0 && current < nbitems) - if(!listItems[current]->Leaving(key)) + if(currentItem >= 0 && currentItem < nbitems) + if(!items[currentItem]->Leaving(key)) return false; mFocus = false; return true; } -void WGuiList::Entering(u32 key){ +void WGuiMenu::Entering(u32 key){ mFocus = true; //Try to force a selectable option. - if(current == -1){ - for (int i = 0 ; i < nbitems; i++){ - if(listItems[i]->Selectable()) { - current = i; + if(currentItem == -1){ + for (size_t i = 0 ; i < items.size(); i++){ + if(items[i]->Selectable()) { + currentItem = i; break; } } } - if(current >= 0 && current < nbitems) - listItems[current]->Entering(key); - - + if(currentItem >= 0 && currentItem < (int) items.size()) + items[currentItem]->Entering(key); return; } -void WGuiList::renderBack(WGuiBase * it){ +void WGuiMenu::renderBack(WGuiBase * it){ if(!it) return; WGuiHeader * header = dynamic_cast(it); JRenderer * renderer = JRenderer::GetInstance(); if(header) - renderer->FillRoundRect(it->getX()-5,it->getY()-2,it->getWidth()-5,it->getHeight(),2,it->getColor(WGuiColor::BACK_HEADER)); + renderer->FillRoundRect(it->getX()-2,it->getY()-2,it->getWidth(),it->getHeight(),2,it->getColor(WGuiColor::BACK_HEADER)); else{ WGuiSplit * split = dynamic_cast(it); if(split && split->left->Visible() && split->right->Visible()){ if(split->left) - renderer->FillRoundRect(split->left->getX()-5,split->getY()-2,split->left->getWidth()-5,split->getHeight(),2,split->left->getColor(WGuiColor::BACK)); + renderer->FillRoundRect(split->left->getX()-2,split->getY()-2,split->left->getWidth()-6,split->getHeight(),2,split->left->getColor(WGuiColor::BACK)); if(split->right) - renderer->FillRoundRect(split->right->getX()-5,split->getY()-2,split->right->getWidth()-5,split->getHeight(),2,split->right->getColor(WGuiColor::BACK)); + renderer->FillRoundRect(split->right->getX()-2,split->getY()-2,split->right->getWidth(),split->getHeight(),2,split->right->getColor(WGuiColor::BACK)); } else - renderer->FillRoundRect(it->getX()-5,it->getY()-2,it->getWidth()-5,it->getHeight(),2,it->getColor(WGuiColor::BACK)); + renderer->FillRoundRect(it->getX()-2,it->getY()-2,it->getWidth(),it->getHeight(),2,it->getColor(WGuiColor::BACK)); } } +//WGuiList +WGuiList::WGuiList(string name, WDataSource * syncme): WGuiMenu(PSP_CTRL_DOWN,PSP_CTRL_UP){ + failMsg = "NO OPTIONS AVAILABLE"; + width = SCREEN_WIDTH-10; + height = SCREEN_HEIGHT-10; + y = 5; + x = 5; + mFocus = false; + sync = syncme; + displayValue = name; +} void WGuiList::confirmChange(bool confirmed){ - for(int x=0;xconfirmChange(confirmed); + for(size_t x=0;xconfirmChange(confirmed); } } void WGuiList::Render(){ @@ -526,10 +499,10 @@ void WGuiList::Render(){ int listSelectable=0; int adjustedCurrent=0; int start = 0, nowPos = 0, vHeight=0; + int nbitems = (int) items.size(); - //List is empty. - if (!nbitems && failMsg != ""){ + if (!items.size() && failMsg != ""){ JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); mFont->SetColor(getColor(WGuiColor::TEXT_FAIL)); mFont->DrawString(_(failMsg).c_str(),x+width/2, y, JGETEXT_RIGHT); @@ -537,41 +510,41 @@ void WGuiList::Render(){ } //Force a selectable option. - if(current == -1){ + if(currentItem == -1){ for (int i = 0 ; i < nbitems; i++){ - if(listItems[i]->Selectable()) { - current = i; + if(items[i]->Selectable()) { + currentItem = i; if(hasFocus()) - listItems[current]->Entering(0); + items[currentItem]->Entering(0); break; } } } //Find out how large our list is. for (int pos=0;pos < nbitems; pos++){ - listHeight+=listItems[pos]->getHeight()+5; - if(listItems[pos]->Selectable()){ + listHeight+=items[pos]->getHeight()+5; + if(items[pos]->Selectable()){ listSelectable++; - if(pos < current) adjustedCurrent++; + if(pos < currentItem) adjustedCurrent++; } } //Always fill screen if(listHeight > SCREEN_HEIGHT) { - for (start=current;start > 0; start--){ - if(!listItems[start]->Visible()) + for (start=currentItem;start > 0; start--){ + if(!items[start]->Visible()) continue; - vHeight += listItems[start]->getHeight()+5; + vHeight += items[start]->getHeight()+5; if(vHeight >= (SCREEN_HEIGHT-60)/2) break; } vHeight = 0; for (nowPos=nbitems;nowPos > 1; nowPos--){ - if(!listItems[start]->Visible()) + if(!items[start]->Visible()) continue; - vHeight += listItems[nowPos-1]->getHeight()+5; + vHeight += items[nowPos-1]->getHeight()+5; } if(vHeight <= SCREEN_HEIGHT-40 && nowPos < start) @@ -585,110 +558,59 @@ void WGuiList::Render(){ if(start >= 0) { for (int pos=0;pos < nbitems; pos++){ - if(!listItems[pos]->Visible()) + if(!items[pos]->Visible()) continue; if(pos < start){ - vHeight += listItems[pos]->getHeight() + 5; + vHeight += items[pos]->getHeight() + 5; continue; } - - listItems[pos]->setY(y+nowPos); - listItems[pos]->setX(x); + items[pos]->setY(y+nowPos); + items[pos]->setX(x); if(listHeight > SCREEN_HEIGHT && listSelectable > 1) - listItems[pos]->setWidth(width-10); + items[pos]->setWidth(width-10); else - listItems[pos]->setWidth(width); - nowPos += listItems[pos]->getHeight() + 5; - renderBack(listItems[pos]); - listItems[pos]->Render(); + items[pos]->setWidth(width); + nowPos += items[pos]->getHeight() + 5; + renderBack(items[pos]); + items[pos]->Render(); if(nowPos > SCREEN_HEIGHT) break; } //Draw scrollbar if(listHeight > SCREEN_HEIGHT && listSelectable > 1){ - int barPosition = 35+((float)adjustedCurrent/listSelectable)*(SCREEN_HEIGHT-40); - int barLength = (SCREEN_HEIGHT-40) / listSelectable; + int barPosition = y-5+((float)adjustedCurrent/listSelectable)*(SCREEN_HEIGHT-y); + int barLength = (SCREEN_HEIGHT-y) / listSelectable; if(barLength < 4) barLength = 4; - renderer->FillRect(x+width-8,39,2,SCREEN_HEIGHT-42, + renderer->FillRect(x+width-2,y-1,2,SCREEN_HEIGHT-y, getColor(WGuiColor::SCROLLBAR)); - renderer->FillRoundRect(x+width-12,barPosition,5,barLength,2, + renderer->FillRoundRect(x+width-5,barPosition,5,barLength,2, getColor(WGuiColor::SCROLLBUTTON)); } //Render current overlay. - if(current > 0 && current < nbitems && listItems[current]->Visible()) - listItems[current]->Overlay(); + if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) + items[currentItem]->Overlay(); } } void WGuiList::setData(){ - for (int i = 0; i < nbitems; i++){ - listItems[i]->setData(); + for (size_t i = 0; i < items.size(); i++){ + items[i]->setData(); } } -WGuiBase * WGuiList::Current(){ - if(current >= 0 && current < nbitems) - return listItems[current]; - - return NULL; +void WGuiList::nextItem(){ + WGuiMenu::nextItem(); + if(sync) + sync->setPos(currentItem); } - -void WGuiList::nextOption(){ - int potential = current; - - if (potential < nbitems-1){ - potential++; - while(potential < nbitems-1 && listItems[potential]->Selectable() == false) - potential++; - if(potential == nbitems || !listItems[potential]->Selectable()) - potential = -1; - else if(potential != current && listItems[current]->Leaving(PSP_CTRL_DOWN)){ - current = potential; - listItems[current]->Entering(PSP_CTRL_DOWN); - } - } -} -void WGuiList::prevOption(){ - int potential = current; - - if (potential > 0){ - potential--; - while(potential > 0 && listItems[potential]->Selectable() == false) - potential--; - if(potential < 0 || !listItems[potential]->Selectable()) - potential = -1; - else if(listItems[current]->Leaving(PSP_CTRL_UP)){ - current = potential; - listItems[current]->Entering(PSP_CTRL_UP); - } - } -} - -void WGuiList::Update(float dt){ - JGE * mEngine = JGE::GetInstance(); - bool kidModal = false; - - if(current >= 0 && current < nbitems) - kidModal = listItems[current]->isModal(); - - if(!kidModal && hasFocus()){ - if (mEngine->GetButtonClick(PSP_CTRL_UP)) - prevOption(); - else if (mEngine->GetButtonClick(PSP_CTRL_DOWN)) - nextOption(); - } - - if(current >= 0 && current < nbitems) - listItems[current]->Update(dt); - - for (int i = 0 ; i < nbitems; i++){ - if(i != current) - listItems[i]->Update(dt); - } +void WGuiList::prevItem(){ + WGuiMenu::prevItem(); + if(sync) + sync->setPos(currentItem); } void WGuiList::ButtonPressed(int controllerId, int controlId){ @@ -700,14 +622,6 @@ void WGuiList::ButtonPressed(int controllerId, int controlId){ it->ButtonPressed(controllerId,controlId); } -void WGuiList::Reload() -{ - for(int i=0;iReload(); - } -} - OptionTheme::OptionTheme(): OptionDirectory(RESPATH"/themes",Options::ACTIVE_THEME, "Current Theme"){ addSelection("Default"); sort(selections.begin(),selections.end()); @@ -1121,17 +1035,16 @@ void WGuiSplit::confirmChange(bool confirmed){ } //WGuiMenu -WGuiMenu::WGuiMenu(u32 next = PSP_CTRL_RIGHT, u32 prev = PSP_CTRL_LEFT){ +WGuiMenu::WGuiMenu(u32 next = PSP_CTRL_RIGHT, u32 prev = PSP_CTRL_LEFT): WGuiItem(""){ buttonNext = next; buttonPrev = prev; - currentItem = 0; + currentItem = -1; } WGuiMenu::~WGuiMenu(){ for(vector::iterator it = items.begin();it!=items.end();it++) SAFE_DELETE(*it); items.clear(); } - void WGuiMenu::setData(){ for(vector::iterator it = items.begin();it!=items.end();it++) (*it)->setData(); @@ -1167,7 +1080,8 @@ void WGuiMenu::Add(WGuiBase * it){ items.push_back(it); } -//WGuiTabMenu +//WGuiMenu +/* void WGuiMenu::Update(float dt){ JGE * mEngine = JGE::GetInstance(); @@ -1190,12 +1104,102 @@ void WGuiMenu::Update(float dt){ } if(c) c->Update(dt); +}*/ + + +void WGuiMenu::Update(float dt){ + int nbitems = (int) items.size(); + JGE * mEngine = JGE::GetInstance(); + bool kidModal = false; + + if(!mEngine->GetButtonState(held)) + held = 0; + else + duration += dt; + + if(currentItem >= 0 && currentItem < nbitems) + kidModal = items[currentItem]->isModal(); + + if(!kidModal && hasFocus()){ + if (mEngine->GetButtonClick(buttonPrev)){ + prevItem(); + held = buttonPrev; + duration = 0; + } + else if(held == buttonPrev && duration > 1){ + prevItem(); + duration = .92; + } + else if (mEngine->GetButtonClick(buttonNext)){ + nextItem(); + held = buttonNext; + duration = 0; + } + else if(held == buttonNext && duration > 1){ + nextItem(); + duration = .92; + } + } + + if(currentItem >= 0 && currentItem < nbitems) + items[currentItem]->Update(dt); + + for (int i = 0 ; i < nbitems; i++){ + if(i != currentItem) + items[i]->Update(dt); + } } +void WGuiMenu::nextItem(){ + int potential = currentItem; + int nbitems = (int) items.size(); + + if (potential < nbitems-1){ + potential++; + while(potential < nbitems-1 && items[potential]->Selectable() == false) + potential++; + if(potential == nbitems || !items[potential]->Selectable()) + potential = -1; + else if(potential != currentItem && items[currentItem]->Leaving(buttonNext)){ + currentItem = potential; + items[currentItem]->Entering(buttonNext); + } + } +} + +void WGuiMenu::prevItem(){ + int potential = currentItem; + + if (potential > 0){ + potential--; + while(potential > 0 && items[potential]->Selectable() == false) + potential--; + if(potential < 0 || !items[potential]->Selectable()) + potential = -1; + else if(items[currentItem]->Leaving(buttonPrev)){ + currentItem = potential; + items[currentItem]->Entering(buttonPrev); + } + } +} + +void WGuiMenu::setModal(bool val){ + WGuiBase* c = Current(); + if(c) + c->setModal(val); +} +bool WGuiMenu::isModal(){ + WGuiBase* c = Current(); + if(c) + return c->isModal(); + + return false; +} +//WGuiTabMenu void WGuiTabMenu::Add(WGuiBase * it){ if (it){ - it->setY(40); - it->setX(10); + it->setY(it->getY()+35); + it->setHeight(it->getHeight()-35); WGuiMenu::Add(it); } } @@ -1207,7 +1211,7 @@ void WGuiTabMenu::Render(){ if (!items.size()) return; - int offset = 0; + int offset = x; for(vector::iterator it = items.begin();it!=items.end();it++){ int w = mFont->GetStringWidth(_((*it)->getDisplay()).c_str()); @@ -1227,3 +1231,228 @@ void WGuiTabMenu::save(){ setData(); ::options.save(); } + + +//WGuiAward +void WGuiAward::Overlay(){ + char buf[1024]; + JRenderer * r = JRenderer::GetInstance(); + JQuad * trophy = NULL; + + string n = Options::getName(id); + if(n.size()){ + sprintf(buf,"trophy_%s.png",n.c_str()); //Trophy specific to the award + trophy = resources.RetrieveTempQuad(buf); //Themed version... + } + + if(!trophy && id >= Options::SET_UNLOCKS){ + trophy = resources.RetrieveTempQuad("trophy_set.png"); //TODO FIXME: Should look in set dir too. + } + + if(!trophy) //Fallback to basic trophy image. + trophy = resources.RetrieveTempQuad("trophy.png"); + + if(trophy) + r->RenderQuad(trophy, 0, SCREEN_HEIGHT-256); + +} +void WGuiAward::Render(){ + GameOptionAward * goa = dynamic_cast(&options[id]); + + if(!goa) + return; + + JRenderer * renderer = JRenderer::GetInstance(); + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + mFont->SetScale(1); + mFont->SetColor(getColor(WGuiColor::TEXT)); + + float myX = x; + float myY = y; + float fH = mFont->GetHeight(); + float fM = fH / 5; //Font Margin is 20% font height + + renderer->FillRoundRect(x-fM/2,y-fM,getWidth()-fM,fH-fM,fM,getColor(WGuiColor::BACK_TAB)); + myX += fM; + + mFont->DrawString(_(displayValue).c_str(),myX,myY,JGETEXT_LEFT); + myY += fH + 3*fM; + + mFont->SetScale(.75); + fH = mFont->GetHeight(); + if(text.size()){ + mFont->DrawString(_(text).c_str(),myX,myY,JGETEXT_LEFT); + myY+=fH + fM; + } + string s = goa->menuStr(); + if(s.size()){ + mFont->DrawString(s.c_str(),myX,myY,JGETEXT_LEFT); + myY+=fH + fM; + } + setHeight(myY-y); + mFont->SetScale(1); +} + +WGuiAward::WGuiAward(int _id, string name, string _text): WGuiItem(name){ + id = _id; + text = _text; + height = 60; + +} +WGuiAward::~WGuiAward(){ + GameOptionAward * goa = dynamic_cast(&options[id]); + if(goa) + goa->setViewed(true); //FIXME: This removes "New" status even if the award hasn't been selected. +} +bool WGuiAward::Visible(){ + //WGuiAward is only visible when it's tied to an already acchieved award. + GameOptionAward * goa = dynamic_cast(&options[id]); + if(!goa || !goa->number) + return false; + return true; +} + +//WGuiImage +WGuiImage::WGuiImage(WDataSource * wds, float _w, float _h, int _margin): WGuiItem("") { + imgW = _w; + imgH = _h; + margin = _margin; + source = wds; +} + +void WGuiImage::imageScale(float _w, float _h){ + imgH = _h; + imgW = _w; +} + +float WGuiImage::getHeight(){ + JQuad * q = NULL; + + if(imgH == 0 ){ + if(source && (q = source->getImage())) //Intentional assignment. + return MAX(height,q->mHeight+(2*margin)); + } + + return MAX(height,imgH+(2*margin)); +} + +void WGuiImage::Render(){ + if(!source) + return; + + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * q = source->getImage(); + if(q){ + float xS = 1, yS = 1; + if(imgH != 0 && q->mHeight != 0) + yS = imgH / q->mHeight; + if(imgW != 0 && q->mWidth != 0) + xS = imgW / q->mWidth; + + renderer->RenderQuad(q,x+margin, y+margin,0,xS,yS); + } +} + +WGuiCardImage::WGuiCardImage(WDataSource * wds, int _offset) : WGuiImage(wds){ + offset = _offset; +}; + +void WGuiCardImage::Render(){ + if(!source) + return; + + JRenderer * renderer = JRenderer::GetInstance(); + MTGCard * c = source->getCard(); + if(!c) + return; + + Pos p(x+margin, y+margin, 1,0,255); + + int oldpos = source->getPos(); + + if(offset){ + source->setPos(oldpos+offset); + c = source->getCard(); + } + + JQuad * q = source->getImage(); + if(!q || options[Options::DISABLECARDS].number) + CardGui::alternateRender(c,p); + else + CardGui::RenderBig(c,p); + + if(offset) + source->setPos(oldpos); +} +//WSrcImage +JQuad * WSrcImage::getImage(){ + return resources.RetrieveTempQuad(filename); +} + +WSrcImage::WSrcImage(string s){ + filename = s; +} + +//WSrcMTGSet +WSrcMTGSet::WSrcMTGSet(int setid){ + MTGAllCards * ac = GameApp::collection; + map::iterator it; + + for(it = ac->collection.begin();it != ac->collection.end();it++){ + if(it->second->setId == setid) + cards.push_back(it->second); + } + + currentCard = -1; + if(cards.size()) + currentCard = 0; +} +JQuad * WSrcMTGSet::getImage(){ + MTGCard * c = getCard(); + if(c) + return resources.RetrieveCard(c); + return NULL; +} +MTGCard * WSrcMTGSet::getCard(){ + int size = (int) cards.size(); + if(!size || currentCard < 0 || currentCard >= size) + return NULL; + + return cards[currentCard]; +} + +bool WSrcMTGSet::next(){ + if(currentCard < (int) cards.size()) + currentCard++; + else + return false; + + return true; +} + +bool WSrcMTGSet::prev(){ + if(currentCard > 0) + currentCard--; + else + return false; + + return true; +} + +bool WSrcMTGSet::setPos(int pos){ + if(pos < 0 || pos >= (int) cards.size()) + return false; + + currentCard = pos; + return true; +} + +bool WSrcMTGSet::thisCard(int mtgid){ + for(size_t t=0;tgetId() == mtgid){ + currentCard = (int) t; + return true; + } + } + return false; +} \ No newline at end of file diff --git a/projects/mtg/src/ShopItem.cpp b/projects/mtg/src/ShopItem.cpp index a1c6ef434..ad151b5cc 100644 --- a/projects/mtg/src/ShopItem.cpp +++ b/projects/mtg/src/ShopItem.cpp @@ -274,7 +274,11 @@ void ShopItems::Update(float dt){ showCardList = false; } } - if (JGE::GetInstance()->GetButtonClick(PSP_CTRL_TRIANGLE)){ + + if(JGE::GetInstance()->GetButtonClick(PSP_CTRL_TRIANGLE)){ + options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; + } + if (JGE::GetInstance()->GetButtonClick(PSP_CTRL_CROSS)){ showCardList = !showCardList; } SAFE_DELETE(dialog); diff --git a/projects/mtg/template.vcproj b/projects/mtg/template.vcproj index 0f6f4c274..31c261b71 100644 --- a/projects/mtg/template.vcproj +++ b/projects/mtg/template.vcproj @@ -468,6 +468,10 @@ RelativePath=".\src\GameState.cpp" > + + @@ -817,6 +821,10 @@ RelativePath=".\include\GameState.h" > + +