diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index ef5a97022..bdb58c8ee 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/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckMetaData.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/GameStateTransitions.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/Tasks.o +OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardPrimitive.o objs/CardSelector.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckMetaData.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/GameStateTransitions.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/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/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.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/Taskboard.png b/projects/mtg/bin/Res/graphics/Taskboard.png index b9d5437bc..55086879e 100644 Binary files a/projects/mtg/bin/Res/graphics/Taskboard.png and b/projects/mtg/bin/Res/graphics/Taskboard.png differ diff --git a/projects/mtg/include/DeckDataWrapper.h b/projects/mtg/include/DeckDataWrapper.h index b5b72b8ff..935ffb338 100644 --- a/projects/mtg/include/DeckDataWrapper.h +++ b/projects/mtg/include/DeckDataWrapper.h @@ -4,6 +4,7 @@ #include "../include/MTGDefinitions.h" #include "../include/MTGCard.h" #include "../include/CardPrimitive.h" +#include "../include/WDataSrc.h" #include #include using std::map; @@ -23,27 +24,22 @@ class Cmp1 { // compares cards by their name } }; -class DeckDataWrapper{ +class DeckDataWrapper: public WSrcDeck { public: - int colors[Constants::MTG_NB_COLORS+1]; - int currentColor; - map cards; MTGDeck * parent; + int counts[Constants::MTG_NB_COLORS]; DeckDataWrapper(MTGDeck * deck); ~DeckDataWrapper(); - int Add(MTGCard * card, int quantity = 1); + int Add(MTGCard * c, int quantity=1); + int Remove(MTGCard * c, int quantity=1, bool erase=false); int Add(MTGDeck * deck); - int Remove(MTGCard * card); - MTGCard * getNext(MTGCard * previous = NULL, int color = -1); - MTGCard * getPrevious(MTGCard * next = NULL, int color = -1); - void updateCounts(MTGCard * card = NULL, int quantity = 1); - int getCount(int color = -1); - int totalPrice(); + int getCount(int color=-1); + void updateCounts(); + bool next() {currentPos++; return true;}; + bool prev() {currentPos--; return true;}; void save(); - int countByName(MTGCard * card); - int count(MTGCard * card); }; #endif diff --git a/projects/mtg/include/GameStateAwards.h b/projects/mtg/include/GameStateAwards.h index 889248060..d1e297770 100644 --- a/projects/mtg/include/GameStateAwards.h +++ b/projects/mtg/include/GameStateAwards.h @@ -7,7 +7,7 @@ class WGuiList; class WGuiMenu; -class WSrcMTGSet; +class WSrcCards; class GameStateAwards: public GameState, public JGuiListener { @@ -16,7 +16,7 @@ class GameStateAwards: public GameState, public JGuiListener WGuiMenu * detailview; JQuad * mBg; JTexture * mBgTex; - WSrcMTGSet * setSrc; + WSrcCards * setSrc; SimpleMenu * menu; bool showMenu; bool showAlt; diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index 24e969dae..807153ac5 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -15,6 +15,8 @@ #include "../include/PlayerData.h" #include "../include/DeckDataWrapper.h" #include "../include/DeckStats.h" +#include "../include/WDataSrc.h" +#include "../include/WGui.h" #define NO_USER_ACTIVITY_HELP_DELAY 10 #define NO_USER_ACTIVITY_SHOWCARD_DELAY 0.1 @@ -28,7 +30,8 @@ enum STAGE_TRANSITION_DOWN = 4, STAGE_ONSCREEN_MENU = 5, STAGE_WELCOME = 6, - STAGE_MENU = 7 + STAGE_MENU = 7, + STAGE_FILTERS = 8 }; @@ -41,6 +44,8 @@ enum #define MED_SPEED 5.0 #define LOW_SPEED 1.5 +#define MAX_SAVED_FILTERS 8 + static const int STATS_FOR_TURNS = 8; static const int STATS_MAX_MANA_COST = 9; @@ -100,11 +105,12 @@ private: int mStage; int nbDecks; int deckNum; - int colorFilter; + int useFilter[2]; JMusic * bgMusic; JQuad * backQuad; + WGuiFilters * filterDeck; + WGuiFilters * filterCollection; SimpleMenu * welcome_menu; - bool showing_user_deck; SimpleMenu * menu; SimpleMenu * sellMenu; PriceList* pricelist; @@ -116,7 +122,6 @@ private: MTGCard * currentCard; MTGCard * cardIndex[7]; int hudAlpha; - float scrollSpeed; int delSellMenu; string newDeckname; StatsWrapper stw; @@ -127,12 +132,12 @@ public: virtual ~GameStateDeckViewer(); void updateDecks(); void rotateCards(int direction); - void loadIndexes(MTGCard * current = NULL); + void loadIndexes(); + void updateFilters(); void switchDisplay(); void Start(); virtual void End(); void addRemove(MTGCard * card); - int Remove(MTGCard * card); virtual void Update(float dt); void renderOnScreenBasicInfo(); void renderSlideBar(); diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index acea3d472..8c7360cde 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -4,7 +4,11 @@ #include #include "../include/GameState.h" #include "../include/SimpleMenu.h" -#include "../include/ShopItem.h" +#include "../include/OptionItem.h" +#include "../include/PriceList.h" +#include "../include/PlayerData.h" +#include "../include/CardDisplay.h" +#include "../include/DeckDataWrapper.h" #include "../include/Tasks.h" @@ -14,28 +18,74 @@ #define STAGE_SHOP_SHOP 4 #define STAGE_SHOP_TASKS 5 #define STAGE_FADE_IN 6 +#define STAGE_ASK_ABOUT 7 +#define BOOSTER_SLOTS 3 +#define SHOP_SLOTS 11 + +#define SHOP_ITEMS SHOP_SLOTS+1 +#define LIST_FADEIN 11 + +struct ShopBooster{ + MTGSetInfo * mainSet; + MTGSetInfo * altSet; +}; class GameStateShop: public GameState, public JGuiListener { private: - ShopItems * shop; + WSrcCards * srcCards; JTexture * altThumb[8]; JQuad * mBack; JQuad * mBg; JTexture * mBgTex; TaskList * taskList; + float mElapsed; + WGuiMenu * shopMenu; + WGuiFilters * filterMenu; //Filter menu slides in sideways from right, or up from bottom. + WGuiCardImage * bigDisplay; + CardDisplay * boosterDisplay; + vector subBooster; + MTGDeck * booster; + bool bListCards; - SimpleMenu * menu; + void beginFilters(); + void makeDisplay(MTGDeck * d); + void deleteDisplay(); + + WSyncable bigSync; + SimpleMenu * menu; + PriceList * pricelist; + PlayerData * playerdata; + bool mTouched; + int mPrices[SHOP_ITEMS]; + int mCounts[SHOP_ITEMS]; + int mInventory[SHOP_ITEMS]; + int lightAlpha; + int alphaChange; + + DeckDataWrapper * myCollection; + int mStage; - char starterBuffer[128], boosterBuffer[128]; - char setNames[SHOP_BOOSTERS][128]; - int setIds[SHOP_BOOSTERS]; + ShopBooster mBooster[BOOSTER_SLOTS]; + void load(); + void save(bool force=false); + + void assembleBooster(int controlId); + void beginPurchase(int controlId); + void purchaseCard(int controlId); + void purchaseBooster(int controlId); + int purchasePrice(int offset); + string descPurchase(int controlId, bool tiny = false); + + + static int randomKey; public: GameStateShop(GameApp* parent); virtual ~GameStateShop(); + static void passOneDay() {randomKey = rand();}; virtual void Start(); virtual void End(); virtual void Create(); @@ -43,6 +93,7 @@ class GameStateShop: public GameState, public JGuiListener virtual void Update(float dt); virtual void Render(); virtual void ButtonPressed(int controllerId, int controlId); + static float _x1[],_y1[],_x2[],_y2[],_x3[],_y3[],_x4[],_y4[]; }; diff --git a/projects/mtg/include/MTGCard.h b/projects/mtg/include/MTGCard.h index a7db8f198..ab09e3644 100644 --- a/projects/mtg/include/MTGCard.h +++ b/projects/mtg/include/MTGCard.h @@ -19,6 +19,7 @@ using namespace std; class MTGCard { protected: + friend class MTGSetInfo; int mtgid; char rarity; char image_name[MTGCARD_NAME_SIZE]; @@ -38,7 +39,6 @@ class MTGCard { int getId(); - char getRarity(); void setRarity(char _rarity); diff --git a/projects/mtg/include/MTGDeck.h b/projects/mtg/include/MTGDeck.h index 7299aa7f2..6f7e24632 100644 --- a/projects/mtg/include/MTGDeck.h +++ b/projects/mtg/include/MTGDeck.h @@ -61,14 +61,16 @@ public: int Add(const char * subtype); int findSet(string value); int findBlock(string s); - int size(); + int getSetNum(MTGSetInfo*i); + int operator[](string id); //Returns set id index, -1 for failure. string operator[](int id); //Returns set id name, "" for failure. MTGSetInfo* getInfo(int setID); - + MTGSetInfo* randomSet(int blockId = -1, int atleast = -1); //Tries to match, otherwise 100% random unlocked set + protected: vector blocks; vector setinfo; diff --git a/projects/mtg/include/OptionItem.h b/projects/mtg/include/OptionItem.h index f8cf5bdd0..9df935482 100644 --- a/projects/mtg/include/OptionItem.h +++ b/projects/mtg/include/OptionItem.h @@ -6,6 +6,9 @@ #include #include "../include/GameApp.h" #include "../include/GameOptions.h" +#include "../include/WFilter.h" +#include "../include/WDataSrc.h" +#include "../include/WGui.h" using std::string; @@ -16,122 +19,6 @@ using std::string; #define PATH_MAX 4096 #endif -class WGuiColor{ -public: - enum { - SCROLLBAR, - SCROLLBUTTON, - //Foregrounds only after this - TEXT, - TEXT_HEADER, - TEXT_FAIL, - TEXT_TAB, - TEXT_BODY, - //Backgrounds only after this - BACK, - BACK_ALERT, - BACK_HEADER, - BACK_FAIL, - BACK_TAB, - }; -}; - -//Complete item interface -class WGuiBase{ -public: - WGuiBase() {}; - virtual ~WGuiBase() {}; - - virtual bool Selectable() {return true;}; - virtual bool isModal() {return false;}; - virtual bool Visible() {return true;}; - - virtual bool Changed() {return false;}; - virtual void confirmChange(bool confirmed) {}; - virtual PIXEL_TYPE getColor(int type); - - virtual void Entering(u32 key)=0; - virtual bool Leaving(u32 key)=0; - - virtual void Update(float dt)=0; - virtual void updateValue(){}; - virtual void Render()=0; - virtual void setData()=0; - virtual void ButtonPressed(int controllerId, int controlId){}; - virtual void Reload(){}; - virtual void Overlay(){}; - virtual void Underlay(){}; - - virtual bool hasFocus()=0; - virtual void setFocus(bool bFocus)=0; - virtual float getX()=0; - virtual float getY()=0; - virtual float getWidth()=0; - virtual float getHeight()=0; - virtual int getId() {return INVALID_ID;}; - virtual string getDisplay(){return "";}; - - virtual void setModal(bool val){}; - virtual void setDisplay(string s){}; - virtual void setX(float _x){}; - virtual void setY(float _y){}; - virtual void setWidth(float _w){}; - virtual void setHeight(float _h){}; - virtual void setId(int _id){}; - virtual void setHidden(bool bHidden) {}; - virtual void setVisible(bool bVisisble) {}; - - virtual void renderBack(WGuiBase * it); - virtual void subBack(WGuiBase * item) {}; - - virtual bool CheckUserInput(u32 key) {return false;}; -}; - -//This is our base class for concrete items. -class WGuiItem: public WGuiBase{ -public: - virtual void Entering(u32 key); - virtual bool Leaving(u32 key); - virtual bool CheckUserInput(u32 key); - virtual void Update(float dt) {}; - virtual void Render(); - - WGuiItem(string _display, u8 _mF = 0); - virtual ~WGuiItem() {}; - - string _(string input); //Override global with our flag checker. - - virtual void setData(){}; - - virtual bool hasFocus() {return mFocus;}; - virtual void setFocus(bool bFocus) {mFocus = bFocus;}; - - virtual string getDisplay(){return displayValue;}; - virtual void setDisplay(string s){displayValue=s;}; - - virtual int getId() {return INVALID_ID;}; - virtual float getX() {return x;}; - virtual float getY() {return y;}; - virtual float getWidth() {return width;}; - virtual float getHeight() {return height;}; - virtual void setId(int _id){}; - virtual void setX(float _x){x = _x;}; - virtual void setY(float _y){y = _y;}; - virtual void setWidth(float _w){width = _w;}; - virtual void setHeight(float _h){height = _h;}; - enum { - NO_TRANSLATE = (1<<1), - }; - - u8 mFlags; - -protected: - bool mFocus; - float x, y; - float width, height; - string displayValue; -}; - class OptionItem: public WGuiItem{ public: OptionItem( int _id, string _displayValue); @@ -145,327 +32,6 @@ 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 getControlID() {return -1;}; //TODO FIXME: Need a "not a valid button" define. - virtual int getPos() {return -1;}; - virtual bool setPos(int pos) {return false;}; - virtual bool next() {return false;}; - virtual bool prev() {return false;}; - virtual void Update(float dt) {}; -}; - -class WSrcImage: public WDataSource{ -public: - virtual JQuad * getImage(); - WSrcImage(string s); - -protected: - string filename; -}; - -class WSrcMTGSet: public WDataSource{ -public: - WSrcMTGSet(int setid, float mDelay=0.2); - - 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); - virtual void Update(float dt); - -protected: - vector cards; - int currentCard; - float mDelay; - float mLastInput; -}; - - -struct WCardSort{ -public: - virtual bool operator()(const MTGCard*l, const MTGCard*r) = 0; -}; - -struct WCSortCollector: public WCardSort{ - bool operator()(const MTGCard*l, const MTGCard*r); -}; - -struct WCSortAlpha: public WCardSort{ - bool operator()(const MTGCard*l, const MTGCard*r); -}; - -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: - WGuiDeco(WGuiBase* _it) {it = _it;}; - virtual ~WGuiDeco() {SAFE_DELETE(it);}; - - virtual bool Selectable() {return it->Selectable();}; - virtual bool Visible() {return it->Visible();}; - virtual bool Changed() {return it->Changed();}; - virtual void confirmChange(bool confirmed) {it->confirmChange(confirmed);}; - - virtual void Entering(u32 key) {it->Entering(key);}; - virtual bool Leaving(u32 key) {return it->Leaving(key);}; - virtual void Update(float dt) {it->Update(dt);}; - virtual void updateValue() {it->updateValue();}; - virtual void Reload() {it->Reload();}; - virtual void Overlay() {it->Overlay();}; - virtual void Underlay() {it->Underlay();}; - virtual void Render() {it->Render();}; - virtual void setData() {it->setData();}; - - virtual void ButtonPressed(int controllerId, int controlId) {it->ButtonPressed(controllerId, controlId);}; - - virtual bool hasFocus() {return it->hasFocus();}; - virtual string getDisplay() {return it->getDisplay();}; - virtual int getId() {return it->getId();}; - virtual float getX() {return it->getX();}; - virtual float getY() {return it->getY();}; - virtual float getWidth() {return it->getWidth();}; - virtual float getHeight() {return it->getHeight();}; - virtual PIXEL_TYPE getColor(int type) {return it->getColor(type);}; - WGuiBase * getDecorated() {return it;}; - - virtual void setFocus(bool bFocus) {it->setFocus(bFocus);}; - virtual void setDisplay(string s) {it->setDisplay(s);}; - virtual void setId(int _id) {it->setId(_id);}; - virtual void setX(float _x) {it->setX(_x);}; - virtual void setY(float _y) {it->setY(_y);}; - virtual void setWidth(float _w) {it->setWidth(_w);}; - virtual void setHeight(float _h) {it->setHeight(_h);}; - virtual void setHidden(bool bHidden) {it->setHidden(bHidden);}; - virtual void setVisible(bool bVisisble) {it->setVisible(bVisisble);}; - virtual bool CheckUserInput(u32 key) {return it->CheckUserInput(key);}; -protected: - WGuiBase * it; -}; - -class WGuiAward: public WGuiItem{ -public: - WGuiAward(int _id, string name, string _text, string _details=""); - virtual ~WGuiAward(); - virtual void Render(); - virtual bool Selectable() {return Visible();}; - virtual bool Visible(); - virtual int getId() {return id;}; - virtual void Underlay(); - virtual void Overlay(); - -protected: - string details; - int id; - string text; -}; - -class WGuiSplit: public WGuiItem{ -public: - WGuiSplit(WGuiBase* _left,WGuiBase* _right); - virtual ~WGuiSplit(); - - virtual void Reload(); - virtual void Overlay(); - virtual void Underlay(); - virtual void setData(); - virtual bool isModal(); - virtual void setModal(bool val); - virtual void Render(); - virtual void Update(float dt); - virtual void setX(float _x); - virtual void setY(float _y); - virtual void setWidth(float _w); - virtual void setHeight(float _h); - virtual float getHeight(); - virtual void ButtonPressed(int controllerId, int controlId); - virtual void confirmChange(bool confirmed); - - virtual void Entering(u32 key); - virtual bool Leaving(u32 key); - virtual bool CheckUserInput(u32 key); - - bool bRight; - float percentRight; - WGuiBase* right; - WGuiBase* left; -}; - -class WDecoConfirm: public WGuiDeco{ -public: - WDecoConfirm(JGuiListener * _listener, WGuiBase * it); - virtual ~WDecoConfirm(); - - virtual bool isModal(); - virtual void setData(); - virtual void setModal(bool val); - virtual void Entering(u32 key); - virtual bool Leaving(u32 key); - virtual void Update(float dt); - virtual void Overlay(); - virtual void ButtonPressed(int controllerId, int controlId); - virtual bool CheckUserInput(u32 key); - - string confirm; - string cancel; -protected: - enum { - OP_UNCONFIRMED, - OP_CONFIRMING, - OP_CONFIRMED, - } mState; - SimpleMenu * confirmMenu; - JGuiListener * listener; - bool bModal; -}; - -class WDecoEnum : public WGuiDeco { - public: - WDecoEnum(WGuiBase * _it,EnumDefinition *_edef = NULL); - virtual void Render(); - string lookupVal(int value); - protected: - EnumDefinition * edef; -}; - -class WDecoCheat: public WGuiDeco { - public: - WDecoCheat(WGuiBase * _it); - virtual bool Visible(); - bool Selectable(); - virtual void Reload(); -protected: - bool bVisible; -}; - -class WGuiButton: public WGuiDeco{ -public: - WGuiButton( WGuiBase* _it, int _controller, int _control, JGuiListener * jgl); - virtual void updateValue(); - virtual bool CheckUserInput(u32 key); - virtual bool Selectable() {return Visible();}; - virtual PIXEL_TYPE getColor(int type); -protected: - int control, controller; - JGuiListener * mListener; -}; - -class WGuiHeader:public WGuiItem{ - public: - - WGuiHeader(string _displayValue): WGuiItem(_displayValue) {}; - virtual bool Selectable() {return false;}; - virtual void Render(); - -}; - -class WDecoStyled: public WGuiDeco{ -public: - WDecoStyled(WGuiItem * _it) : WGuiDeco(_it) {mStyle=DS_DEFAULT;}; - PIXEL_TYPE getColor(int type); - void subBack(WGuiBase * item); - enum { - DS_DEFAULT = (1<<0), - DS_COLOR_BRIGHT = (1<<1), - DS_COLOR_DARK = (1<<2), - DS_STYLE_ALERT = (1<<3), - DS_STYLE_EDGED = (1<<4), - DS_STYLE_BACKLESS = (1<<5), - }; - - u8 mStyle; -}; - -class WGuiMenu: public WGuiItem{ -public: - - virtual ~WGuiMenu(); - WGuiMenu(u32 next, u32 prev); - - virtual void Render(); - virtual void Reload(); - virtual void Update(float dt); - 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 subBack(WGuiBase * item); - virtual bool CheckUserInput(u32 key); - - - WGuiBase * Current(); - virtual bool nextItem(); - virtual bool prevItem(); - virtual bool isModal(); - virtual void setModal(bool val); - - void setData(); - -protected: - u32 buttonNext, buttonPrev; - vector items; - int currentItem; - u32 held; - float duration; -}; - -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 bool nextItem(); - virtual bool prevItem(); - - WGuiBase * operator[](int); -protected: - WDataSource * sync; - bool mFocus; -}; - -class WGuiTabMenu: public WGuiMenu { - public: - WGuiTabMenu() : WGuiMenu(PSP_CTRL_RTRIGGER,PSP_CTRL_LTRIGGER) {}; - virtual void Render(); - virtual void Add(WGuiBase * it); - void save(); -}; - class OptionInteger:public OptionItem{ public: int value; //Current value. diff --git a/projects/mtg/include/ShopItem.h b/projects/mtg/include/ShopItem.h deleted file mode 100644 index 55bd3421d..000000000 --- a/projects/mtg/include/ShopItem.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef _SHOP_ITEM_H -#define _SHOP_ITEM_H - -#include -#include -#include "SimpleMenu.h" -#include "MTGDeck.h" -#include "../include/PriceList.h" -#include "../include/PlayerData.h" -#include "../include/CardDisplay.h" -#include "../include/DeckDataWrapper.h" - -#include -using std::string; - -class hgeDistortionMesh; - -#define SHOP_BOOSTERS 3 - -class ShopItem:public JGuiObject{ - private: - friend class ShopItems; - bool mHasFocus; - bool mRelease; - JLBFont *mFont; - string mText; - float xy[8]; - JQuad * quad; - JQuad * thumb; - float mScale; - float mTargetScale; - hgeDistortionMesh* mesh; - - void updateThumb(); - - public: - int nameCount; - int quantity; - MTGCard * card; - int price; - ShopItem(int id, JLBFont * font, int _cardid, float _xy[], bool hasFocus, MTGAllCards * collection, int _price, DeckDataWrapper * ddw); - ShopItem(int id, JLBFont * font, char* text, JQuad * _quad, JQuad * _thumb,float _xy[], bool hasFocus, int _price); - ~ShopItem(); - int updateCount(DeckDataWrapper * ddw); - - virtual void Render(); - virtual void Update(float dt); - - virtual void Entering(); - virtual bool Leaving(u32 key); - virtual bool ButtonPressed(); - - const char * getText(); - virtual ostream& toString(ostream& out) const; -}; - -class ShopItems:public JGuiController,public JGuiListener{ - private: - PlayerData * playerdata; - PriceList * pricelist; - int mX, mY, mHeight; - JLBFont* mFont; - JTexture * mBgAATex; - JQuad * mBgAA; - MTGAllCards * collection; - SimpleMenu * dialog; - int showPriceDialog; - int setIds[SHOP_BOOSTERS]; - MTGCardInstance * displayCards[100]; - CardDisplay * display; - void safeDeleteDisplay(); - DeckDataWrapper * myCollection; - - int lightAlpha; - int alphaChange; - - public: - bool showCardList; - ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y, MTGAllCards * _collection, int _setIds[]); - ~ShopItems(); - void Render(); - virtual void Update(float dt); - void Add(int cardid); - void Add(char * text, JQuad * quad, JQuad * thumb,int _price); - void pricedialog(int id, int mode=1); - virtual void ButtonPressed(int controllerId, int controlId); - bool CheckUserInput(u32 key); - void savePriceList(); - void saveAll(); - static float _x1[],_y1[],_x2[],_y2[],_x3[],_y3[],_x4[],_y4[]; -}; - -#endif diff --git a/projects/mtg/include/WDataSrc.h b/projects/mtg/include/WDataSrc.h new file mode 100644 index 000000000..ce61a9386 --- /dev/null +++ b/projects/mtg/include/WDataSrc.h @@ -0,0 +1,126 @@ +#ifndef _WDATASRC_H_ +#define _WDATASRC_H_ + +class WCardFilter; +struct WCardSort; +struct WDistort; +class PriceList; +class MTGDeck; +class MTGAllCards; + +class WSyncable{ +public: + WSyncable(int i=0) {hooked = NULL;currentPos = 0;}; + virtual ~WSyncable() {}; + //Local + virtual bool Hook(WSyncable* s); + virtual int getOffset() {return currentPos;}; + virtual bool setOffset(int i) {currentPos = i; return true;}; + //Recursive + virtual int getPos(); + virtual bool next(); + virtual bool prev(); +protected: + WSyncable * hooked; //Simple link list + int currentPos; +}; + +class WDataSource: public WSyncable{ +public: + WDataSource() {}; + virtual JQuad * getImage(int offset=0) {return NULL;}; + virtual JQuad * getThumb(int offset=0) {return NULL;}; + virtual MTGCard * getCard(int offset=0, bool ignore=false) {return NULL;}; + virtual MTGDeck * getDeck(int offset=0) {return NULL;}; + virtual WDistort * getDistort(int offset=0) {return NULL;}; + virtual bool thisCard(int mtgid) {return false;}; + virtual int getControlID() {return -1;}; //TODO FIXME: Need a "not a valid button" define. + virtual void Update(float dt) {mLastInput += dt;}; + virtual void Touch() {mLastInput = 0;}; + virtual float getElapsed() {return mLastInput;}; + virtual void setElapsed(float f) {mLastInput = f;}; +protected: + float mLastInput; +}; + +class WSrcImage: public WDataSource{ +public: + virtual JQuad * getImage(int offset=0); + WSrcImage(string s); + +protected: + string filename; +}; + +class WSrcCards: public WDataSource{ +public: + WSrcCards(float delay=0.2); + ~WSrcCards(); + + virtual JQuad * getImage(int offset=0); + virtual JQuad * getThumb(int offset=0); + virtual MTGCard * getCard(int offset=0, bool ignore=false); + virtual int Size(bool all=false); //Returns the number of cards currently matched + + virtual void Shuffle(); + virtual bool thisCard(int mtgid); + virtual bool next(); + virtual bool prev(); + + virtual void Sort(int method); + virtual bool setOffset(int pos); + virtual void addFilter(WCardFilter * f); + virtual void clearFilters(); + virtual bool matchesFilters(MTGCard * c); + virtual void validateFilters(); + virtual void bakeFilters(); //Discards all invalidated cards. + virtual float filterFee(); + + virtual int addToDeck(MTGDeck * i, int num=-1); //Returns num that didn't add + virtual int loadMatches(MTGAllCards* ac); //loadMatches adds the cards from something + virtual int loadMatches(MTGDeck * deck); //into this, if it matches our filter + virtual int loadMatches(WSrcCards* src, bool all=false); //If all==true, ignore filters on src. + + enum { + MAX_CYCLES = 4, //How many cycles to search, for addToDeck + SORT_COLLECTOR, + SORT_ALPHA + }; +protected: + vector cards; + vector validated; + WCardFilter * filtersRoot; + float mDelay; +}; + +class WSrcUnlockedCards: public WSrcCards{ //Only unlocked cards. +public: + WSrcUnlockedCards(float mDelay=0.2); +}; + +class WSrcDeck: public WSrcCards{ +public: + WSrcDeck(float delay=0.2) : WSrcCards(delay) {totalCards=0;}; + virtual int loadMatches(MTGDeck * deck); + virtual int Add(MTGCard * c, int quantity=1); + virtual int Remove(MTGCard * c, int quantity=1, bool erase=false); + void Rebuild(MTGDeck * d); + int count(MTGCard * c); + int countByName(MTGCard * card, bool editions=false); + int totalPrice(); + int totalCopies(); +protected: + map copies; //Maps MTGID to card counts. + int totalCards; +}; + +struct WCSortCollector{ + bool operator()(const MTGCard*l, const MTGCard*r); +}; + +struct WCSortAlpha{ + bool operator()(const MTGCard*l, const MTGCard*r); +}; + + +#endif \ No newline at end of file diff --git a/projects/mtg/include/WFilter.h b/projects/mtg/include/WFilter.h new file mode 100644 index 000000000..4ae769a22 --- /dev/null +++ b/projects/mtg/include/WFilter.h @@ -0,0 +1,136 @@ +#ifndef _WFILTER_H_ +#define _WFILTER_H_ + +class WCardFilter; + +class WCFilterFactory{ +public: + WCFilterFactory() {}; + static WCFilterFactory * GetInstance(); + static void Destroy(); + WCardFilter * Construct(string x); +private: + size_t findNext(string src, size_t start, char open='(', char close=')'); + WCardFilter * Leaf(string src); + WCardFilter * Terminal(string type, string arg); + static WCFilterFactory * me; +}; + +class WCardFilter{ +public: + WCardFilter() {}; + virtual ~WCardFilter() {}; + virtual bool isMatch(MTGCard * c) {return true;}; + virtual string getCode() = 0; + virtual float filterFee() {return 0.0f;}; +}; + +class WCFBranch: public WCardFilter{ +public: + WCFBranch(WCardFilter * a, WCardFilter * b) {lhs=a;rhs=b;}; + ~WCFBranch() {SAFE_DELETE(lhs); SAFE_DELETE(rhs);}; + virtual bool isMatch(MTGCard * c) = 0; + virtual string getCode() = 0; + virtual WCardFilter * Right(){return rhs;}; + virtual WCardFilter * Left(){return lhs;}; +protected: + WCardFilter *lhs, *rhs; +}; + +class WCFilterOR: public WCFBranch{ +public: + WCFilterOR(WCardFilter * a, WCardFilter * b): WCFBranch(a,b) {}; + bool isMatch(MTGCard *c); + string getCode(); + float filterFee(); +}; + +class WCFilterAND: public WCFBranch{ +public: + WCFilterAND(WCardFilter * a, WCardFilter * b): WCFBranch(a,b) {}; + bool isMatch(MTGCard *c) {return (lhs->isMatch(c) && rhs->isMatch(c));}; + string getCode(); + float filterFee(); +}; + +class WCFilterGROUP: public WCardFilter{ +public: + WCFilterGROUP(WCardFilter * _k) {kid = _k;}; + ~WCFilterGROUP() {SAFE_DELETE(kid);}; + bool isMatch(MTGCard *c) {return kid->isMatch(c);}; + string getCode(); + float filterFee() {return kid->filterFee();}; +protected: + WCardFilter * kid; +}; + +class WCFilterNOT: public WCardFilter{ +public: + WCFilterNOT(WCardFilter * _k) {kid = _k;}; + ~WCFilterNOT() {SAFE_DELETE(kid);}; + bool isMatch(MTGCard *c) {return !kid->isMatch(c);}; + string getCode(); +protected: + WCardFilter * kid; +}; + +class WCFilterNULL: public WCardFilter{ +public: + WCFilterNULL() {}; + string getCode() {return "NULL";}; + bool isMatch(MTGCard *c) {return true;}; +}; + + +//Filter terminals: +class WCFilterSet: public WCardFilter{ +public: + WCFilterSet(int _setid=-1) {setid=_setid;}; + WCFilterSet(string arg); + bool isMatch(MTGCard *c) {return (setid==-1 || c->setId == setid);}; + string getCode(); + float filterFee() {return 0.1f;}; +protected: + int setid; +}; +class WCFilterColor: public WCardFilter{ +public: + WCFilterColor(int _c) {color = _c;}; + WCFilterColor(string arg); + bool isMatch(MTGCard * c); + string getCode(); + float filterFee() {return 0.1f;}; +protected: + int color; +}; +class WCFilterType: public WCardFilter{ +public: + WCFilterType(string arg) {type = arg;}; + bool isMatch(MTGCard * c); + string getCode(); + float filterFee() {return 0.2f;}; +protected: + string type; +}; +class WCFilterRarity: public WCardFilter{ +public: + WCFilterRarity(char _r) {rarity = _r;}; + WCFilterRarity(string arg); + bool isMatch(MTGCard * c); + string getCode(); + float filterFee(); +protected: + char rarity; +}; +class WCFilterAbility: public WCardFilter{ +public: + WCFilterAbility(int _a) {ability = _a;}; + WCFilterAbility(string arg); + bool isMatch(MTGCard * c); + string getCode(); + float filterFee(); +protected: + int ability; +}; + +#endif \ No newline at end of file diff --git a/projects/mtg/include/WGui.h b/projects/mtg/include/WGui.h new file mode 100644 index 000000000..59b6c1179 --- /dev/null +++ b/projects/mtg/include/WGui.h @@ -0,0 +1,479 @@ +#ifndef _WGUI_H_ +#define _WGUI_H_ + +class hgeDistortionMesh; + +class WGuiColor{ +public: + enum { + SCROLLBAR, + SCROLLBUTTON, + //Foregrounds only after this + TEXT, + TEXT_HEADER, + TEXT_FAIL, + TEXT_TAB, + TEXT_BODY, + //Backgrounds only after this + BACK, + BACK_ALERT, + BACK_HEADER, + BACK_FAIL, + BACK_TAB, + }; +}; + +struct WDistort { + WDistort(); + WDistort(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); + float & operator[](int p); +protected: + float xy[8]; +}; + +//Complete item interface +class WGuiBase: public JGuiListener { +public: + WGuiBase() {}; + virtual ~WGuiBase() {}; + + virtual bool Selectable() {return true;}; + virtual bool isModal() {return false;}; + virtual bool Visible() {return true;}; + + virtual bool Changed() {return false;}; + virtual void confirmChange(bool confirmed) {}; + virtual PIXEL_TYPE getColor(int type); + virtual float getMargin(int type) {return 4;}; + + virtual void Entering(u32 key)=0; + virtual bool Leaving(u32 key)=0; + + virtual void Update(float dt)=0; + virtual void updateValue(){}; + virtual void Render()=0; + virtual void setData()=0; + virtual void ButtonPressed(int controllerId, int controlId){}; + virtual void Reload(){}; + virtual void Overlay(){}; + virtual void Underlay(){}; + + virtual bool hasFocus()=0; + virtual void setFocus(bool bFocus)=0; + virtual float getX()=0; + virtual float getY()=0; + virtual float getWidth()=0; + virtual float getHeight()=0; + virtual int getId() {return INVALID_ID;}; + virtual string getDisplay() const {return "";}; + virtual float minWidth(){return getWidth();}; + virtual float minHeight(){return getHeight();}; + + virtual void setModal(bool val){}; + virtual void setDisplay(string s){}; + virtual void setX(float _x){}; + virtual void setY(float _y){}; + virtual void setWidth(float _w){}; + virtual void setHeight(float _h){}; + virtual void setId(int _id){}; + virtual void setHidden(bool bHidden) {}; + virtual void setVisible(bool bVisisble) {}; + + virtual void renderBack(WGuiBase * it); + virtual void subBack(WGuiBase * item) {}; + + virtual bool CheckUserInput(u32 key) {return false;}; +}; + +//This is our base class for concrete items. +class WGuiItem: public WGuiBase{ +public: + virtual void Entering(u32 key); + virtual bool Leaving(u32 key); + virtual bool CheckUserInput(u32 key); + virtual void Update(float dt) {}; + virtual void Render(); + + WGuiItem(string _display, u8 _mF = 0); + virtual ~WGuiItem() {}; + + string _(string input); //Override global with our flag checker. + + virtual void setData(){}; + + virtual bool hasFocus() {return mFocus;}; + virtual void setFocus(bool bFocus) {mFocus = bFocus;}; + + virtual string getDisplay() const {return displayValue;}; + virtual void setDisplay(string s){displayValue=s;}; + + virtual int getId() {return INVALID_ID;}; + virtual float getX() {return x;}; + virtual float getY() {return y;}; + virtual float getWidth() {return width;}; + virtual float getHeight() {return height;}; + virtual float minWidth(); + virtual float minHeight(); + virtual void setId(int _id){}; + virtual void setX(float _x){x = _x;}; + virtual void setY(float _y){y = _y;}; + virtual void setWidth(float _w){width = _w;}; + virtual void setHeight(float _h){height = _h;}; + enum { + NO_TRANSLATE = (1<<1), + }; + + u8 mFlags; + +protected: + bool mFocus; + float x, y; + float width, height; + string displayValue; +}; + +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); + virtual void setSource(WDataSource *s) {source = s;}; +protected: + int margin; + float imgW, imgH; + WDataSource * source;}; + +class WGuiCardImage: public WGuiImage{ +public: + WGuiCardImage(WDataSource * wds, bool _thumb=false); + virtual void Render(); + WSyncable mOffset; +protected: + bool bThumb; +}; + +class WGuiCardDistort: public WGuiCardImage{ +public: + WGuiCardDistort(WDataSource * wds, bool _thumb=false, WDataSource * _distort=NULL); + ~WGuiCardDistort(); + virtual void Render(); + + WDistort xy; +protected: + hgeDistortionMesh* mesh; + WDataSource * distortSrc; +}; + +//This is our base class for decorators. It wraps everything about WGuiBase. +class WGuiDeco: public WGuiBase{ +public: + WGuiDeco(WGuiBase* _it) {it = _it;}; + virtual ~WGuiDeco() {SAFE_DELETE(it);}; + + virtual bool Selectable() {return it->Selectable();}; + virtual bool Visible() {return it->Visible();}; + virtual bool Changed() {return it->Changed();}; + virtual void confirmChange(bool confirmed) {it->confirmChange(confirmed);}; + + virtual void Entering(u32 key) {it->Entering(key);}; + virtual bool Leaving(u32 key) {return it->Leaving(key);}; + virtual void Update(float dt) {it->Update(dt);}; + virtual void updateValue() {it->updateValue();}; + virtual void Reload() {it->Reload();}; + virtual void Overlay() {it->Overlay();}; + virtual void Underlay() {it->Underlay();}; + virtual void Render() {it->Render();}; + virtual void setData() {it->setData();}; + + virtual void ButtonPressed(int controllerId, int controlId) {it->ButtonPressed(controllerId, controlId);}; + + virtual bool hasFocus() {return it->hasFocus();}; + virtual string getDisplay() const {return it->getDisplay();}; + virtual int getId() {return it->getId();}; + virtual float getX() {return it->getX();}; + virtual float getY() {return it->getY();}; + virtual float getWidth() {return it->getWidth();}; + virtual float getHeight() {return it->getHeight();}; + virtual PIXEL_TYPE getColor(int type) {return it->getColor(type);}; + WGuiBase * getDecorated() {return it;}; + + virtual void setFocus(bool bFocus) {it->setFocus(bFocus);}; + virtual void setDisplay(string s) {it->setDisplay(s);}; + virtual void setId(int _id) {it->setId(_id);}; + virtual void setX(float _x) {it->setX(_x);}; + virtual void setY(float _y) {it->setY(_y);}; + virtual void setWidth(float _w) {it->setWidth(_w);}; + virtual void setHeight(float _h) {it->setHeight(_h);}; + virtual void setHidden(bool bHidden) {it->setHidden(bHidden);}; + virtual void setVisible(bool bVisisble) {it->setVisible(bVisisble);}; + virtual bool CheckUserInput(u32 key) {return it->CheckUserInput(key);}; +protected: + WGuiBase * it; +}; + +class WGuiAward: public WGuiItem{ +public: + WGuiAward(int _id, string name, string _text, string _details=""); + virtual ~WGuiAward(); + virtual void Render(); + virtual bool Selectable() {return Visible();}; + virtual bool Visible(); + virtual int getId() {return id;}; + virtual void Underlay(); + virtual void Overlay(); + +protected: + string details; + int id; + string text; +}; + +class WGuiSplit: public WGuiItem{ +public: + WGuiSplit(WGuiBase* _left,WGuiBase* _right); + virtual ~WGuiSplit(); + + virtual void Reload(); + virtual void Overlay(); + virtual void Underlay(); + virtual void setData(); + virtual bool isModal(); + virtual void setModal(bool val); + virtual void Render(); + virtual void Update(float dt); + virtual void setX(float _x); + virtual void setY(float _y); + virtual void setWidth(float _w); + virtual void setHeight(float _h); + virtual float getHeight(); + virtual void ButtonPressed(int controllerId, int controlId); + virtual void confirmChange(bool confirmed); + + virtual void Entering(u32 key); + virtual bool Leaving(u32 key); + virtual bool CheckUserInput(u32 key); + + bool bRight; + float percentRight; + WGuiBase* right; + WGuiBase* left; +}; + +class WDecoConfirm: public WGuiDeco{ +public: + WDecoConfirm(JGuiListener * _listener, WGuiBase * it); + virtual ~WDecoConfirm(); + + virtual bool isModal(); + virtual void setData(); + virtual void setModal(bool val); + virtual void Entering(u32 key); + virtual bool Leaving(u32 key); + virtual void Update(float dt); + virtual void Overlay(); + virtual void ButtonPressed(int controllerId, int controlId); + virtual bool CheckUserInput(u32 key); + + string confirm; + string cancel; +protected: + enum { + OP_UNCONFIRMED, + OP_CONFIRMING, + OP_CONFIRMED, + } mState; + SimpleMenu * confirmMenu; + JGuiListener * listener; + bool bModal; +}; + +class WDecoEnum : public WGuiDeco { + public: + WDecoEnum(WGuiBase * _it,EnumDefinition *_edef = NULL); + virtual void Render(); + string lookupVal(int value); + protected: + EnumDefinition * edef; +}; + +class WDecoCheat: public WGuiDeco { + public: + WDecoCheat(WGuiBase * _it); + virtual bool Visible(); + bool Selectable(); + virtual void Reload(); +protected: + bool bVisible; +}; + +class WGuiButton: public WGuiDeco{ +public: + WGuiButton( WGuiBase* _it, int _controller, int _control, JGuiListener * jgl); + virtual void updateValue(); + virtual bool CheckUserInput(u32 key); + virtual bool Selectable() {return Visible();}; + virtual PIXEL_TYPE getColor(int type); + virtual int getControlID() {return control;}; + virtual int getControllerID() {return controller;}; +protected: + int control, controller; + JGuiListener * mListener; +}; + +class WGuiHeader:public WGuiItem{ + public: + WGuiHeader(string _displayValue): WGuiItem(_displayValue) {}; + virtual bool Selectable() {return false;}; + virtual void Render(); +}; + +class WDecoStyled: public WGuiDeco{ +public: + WDecoStyled(WGuiItem * _it) : WGuiDeco(_it) {mStyle=DS_DEFAULT;}; + PIXEL_TYPE getColor(int type); + void subBack(WGuiBase * item); + enum { + DS_DEFAULT = (1<<0), + DS_COLOR_BRIGHT = (1<<1), + DS_COLOR_DARK = (1<<2), + DS_STYLE_ALERT = (1<<3), + DS_STYLE_EDGED = (1<<4), + DS_STYLE_BACKLESS = (1<<5), + }; + + u8 mStyle; +}; + +class WGuiMenu: public WGuiItem{ +public: + friend class WGuiFilters; + virtual ~WGuiMenu(); + WGuiMenu(u32 next, u32 prev, bool mDPad = false, WSyncable * syncme=NULL); + + virtual void Render(); + virtual void Reload(); + virtual void Update(float dt); + 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 subBack(WGuiBase * item); + virtual bool CheckUserInput(u32 key); + WGuiBase * Current(); + virtual int getSelected() {return currentItem;}; + virtual bool nextItem(); + virtual bool prevItem(); + virtual bool isModal(); + virtual void setModal(bool val); + + void setData(); + +protected: + virtual void syncMove(); + virtual bool isButtonDir(u32 key, int dir); //For the DPad override. + u32 buttonNext, buttonPrev; + bool mDPad; + vector items; + int currentItem; + u32 held; + WSyncable * sync; + float duration; +}; + +class WGuiList: public WGuiMenu{ + public: + WGuiList(string name, WSyncable * syncme = NULL); + + string failMsg; + + virtual void Render(); + virtual void confirmChange(bool confirmed); + virtual void ButtonPressed(int controllerId, int controlId); + virtual void setData(); + WGuiBase * operator[](int); +protected: + bool mFocus; +}; +class WGuiTabMenu: public WGuiMenu { + public: + WGuiTabMenu() : WGuiMenu(PSP_CTRL_RTRIGGER,PSP_CTRL_LTRIGGER) {}; + virtual void Render(); + virtual void Add(WGuiBase * it); + void save(); +}; +class WGuiListRow: public WGuiList{ + public: + WGuiListRow(string n, WSyncable * s = NULL); + virtual void Render(); +}; + +class WGuiFilters: public WGuiItem { +public: + friend class WGuiFilterItem; + WGuiFilters(string header, WSrcCards * src); + ~WGuiFilters(); + bool CheckUserInput(u32 key); + string getCode(); //For use in filter factory. + void Update(float dt); + void Render(); + void Entering(u32 key); + void addColumn(); + bool isAvailable(int type); + bool isAvailableCode(string code); + void Finish(); + bool isFinished() {return bFinished;}; + void ButtonPressed(int controllerId, int controlId); + void buildList(); +protected: + bool bFinished; + WSrcCards* source; + SimpleMenu* subMenu; + WGuiList * list; +}; + +class WGuiFilterItem: public WGuiItem { +public: + friend class WGuiFilters; + friend struct WLFiltersSort; + WGuiFilterItem(WGuiFilters * parent); + void updateValue(); + void ButtonPressed(int controllerId, int controlId); + string getCode(); + bool isModal(); + enum { + STATE_UNSET, + STATE_CHOOSE_TYPE, + STATE_CHOOSE_VAL, + STATE_FINISHED, + STATE_REMOVE, + STATE_CANCEL, + BEGIN_FILTERS = 0, + FILTER_SET = BEGIN_FILTERS, + FILTER_RARITY, + FILTER_COLOR, + FILTER_TYPE, + FILTER_BASIC, + END_FILTERS + }; +protected: + void addArg(string display, string code); + int filterType; + int filterVal; + vector< pair > args; + int mState; + bool mNew; + WGuiFilters * mParent; +}; + +struct WListSort{ + virtual bool operator()(const WGuiBase*l, const WGuiBase*r); +}; + +struct WLFiltersSort{ + bool operator()(const WGuiBase*l, const WGuiBase*r); +}; + +#endif \ No newline at end of file diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 384884984..54246285a 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -276,7 +276,7 @@ void CardGui::alternateRender(MTGCard * card, const Pos& pos){ #ifdef _DEBUG else{ char buf[2048]; - sprintf(buf, "\n==\nTypeless card: %s %s\n", setlist[card->setId].c_str(), card->data->getName().c_str()); + sprintf(buf, "Typeless card: %s %s (%i)\n", setlist[card->setId].c_str(), card->data->getName().c_str(), card->getId()); OutputDebugString(buf); } #endif diff --git a/projects/mtg/src/Credits.cpp b/projects/mtg/src/Credits.cpp index 91f86cb2e..f8fbb9d66 100644 --- a/projects/mtg/src/Credits.cpp +++ b/projects/mtg/src/Credits.cpp @@ -7,6 +7,7 @@ #include "../include/Translate.h" #include "../include/MTGDeck.h" #include "../include/GameObserver.h" +#include "../include/GameStateShop.h" CreditBonus::CreditBonus(int _value, string _text){ value = _value; @@ -150,6 +151,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){ playerdata->credits += value; + GameStateShop::passOneDay(); playerdata->taskList->passOneDay(); if (playerdata->taskList->getTaskCount() < 6) { playerdata->taskList->addRandomTask(); diff --git a/projects/mtg/src/DeckDataWrapper.cpp b/projects/mtg/src/DeckDataWrapper.cpp index 671d60bac..f414db526 100644 --- a/projects/mtg/src/DeckDataWrapper.cpp +++ b/projects/mtg/src/DeckDataWrapper.cpp @@ -2,180 +2,67 @@ #include "../include/DeckDataWrapper.h" #include "../include/MTGDeck.h" #include "../include/PriceList.h" +#include "../include/WDataSrc.h" DeckDataWrapper::DeckDataWrapper(MTGDeck * deck){ - parent = deck; - for (int i = 0; i <= Constants::MTG_NB_COLORS; i++){ - colors[i] = 0; - } + parent = deck; + for(int c=0;c::iterator it; - for (it = deck->cards.begin(); it!=deck->cards.end(); it++){ - MTGCard * card = deck->getCardById(it->first); - Add(card,it->second); - } - return 1; + if(loadMatches(deck)) + return 1; + return 0; } +int DeckDataWrapper::Remove(MTGCard * c, int quantity,bool erase){ + if(WSrcDeck::Remove(c,quantity,erase)){ + for(int i=0;idata->hasColor(i)) + counts[i]-=quantity; + } + return 1; + } + return 0; +} +int DeckDataWrapper::Add(MTGCard * c, int quantity){ + if(WSrcDeck::Add(c,quantity)){ + for(int i=0;idata && c->data->hasColor(i)) + counts[i]+=quantity; + } + return 1; + } + return 0; +} +int DeckDataWrapper::getCount(int color){ + if(color < 0 || color >=Constants::MTG_NB_COLORS) + return Size(true); + return counts[color]; +} +void DeckDataWrapper::updateCounts(){ + map::iterator it; + for(int c=0;cremoveAll(); - map::iterator it; - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCard * current = (*it).first; - for (int i = 0; i < (*it).second; i++){ - parent->add(current); + for(int i=0;idata->hasColor(c)){ + it = copies.find(card->getMTGId()); + if(it != copies.end()) + counts[c]+=it->second; + } } } +} +void DeckDataWrapper::save(){ + Rebuild(parent); parent->save(); } DeckDataWrapper::~DeckDataWrapper(){ SAFE_DELETE(parent); -} - -void DeckDataWrapper::updateCounts(MTGCard * card, int increment){ - if (!card){ - for (int i = 0; i < Constants::MTG_NB_COLORS+1; i++){ - colors[i] = 0; - } - map::iterator it; - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCard * current = (*it).first; - colors[Constants::MTG_NB_COLORS] += (*it).second; - for (int i = 0; i < Constants::MTG_NB_COLORS; i++){ - if (current->data->hasColor(i)) colors[i]+=(*it).second; - } - } - }else{ - colors[Constants::MTG_NB_COLORS] += increment; - for (int i = 0; i < Constants::MTG_NB_COLORS; i++){ - if (card->data->hasColor(i)) colors[i]+=increment; - } - } -} - -int DeckDataWrapper::Add(MTGCard * card, int quantity){ - if(cards.find(card) == cards.end()){ - cards[card] = quantity; - }else{ - cards[card]+= quantity; - } - updateCounts(card,quantity); - return cards[card]; -} - -int DeckDataWrapper::Remove(MTGCard * card){ - if(cards.find(card) == cards.end() || cards[card] <= 0) return 0; - cards[card]--; - updateCounts(card,-1); - return 1; -} - -int DeckDataWrapper::count(MTGCard * card){ - if(cards.find(card) == cards.end()){ - cards[card] = 0; - } - return cards[card]; -} - -int DeckDataWrapper::countByName(MTGCard * card){ - string name = card->data->name; - int total = 0; - map::iterator it,it_origin; - it = cards.find(card); - if(it == cards.end()){ - cards[card] = 0; - it = cards.find(card); - } - it_origin = it; - - while(it !=cards.end()){ - MTGCard * _card = (*it).first; - if (name.compare(_card->data->name) !=0){ - it = cards.end(); - }else{ - total+= (*it).second; - it++; - } - } - - it = cards.find(card); - if (it == cards.begin()) return total; - it--; - while(1){ - MTGCard * _card = (*it).first; - if (name.compare(_card->data->name) !=0){ - break; - }else{ - total+= (*it).second; - if (it == cards.begin()) break; - it--; - - } - } - return total; -} - - -MTGCard * DeckDataWrapper::getNext(MTGCard * previous, int color){ - map::iterator it; - - it = cards.find(previous); - - while(1){ - if (it == cards.end()){ - it = cards.begin(); - }else{ - it++; - } - if (it == cards.end()) return NULL; - MTGCard * card = (*it).first; - if (card == previous) return NULL; - if ((*it).second >0 && (color ==-1 || card->data->hasColor(color))){ - return card; - } - } -} - -MTGCard * DeckDataWrapper::getPrevious(MTGCard * next, int color){ - map::iterator it; - it = cards.find(next); - - while(1){ - if (it == cards.begin()){ - it = cards.end(); - }else{ - it--; - } - if (it == cards.end()) return NULL; - MTGCard * card = (*it).first; - if (card == next) return NULL; - if ((*it).second >0 && (color ==-1 || card->data->hasColor(color))){ - return card; - } - } -} - -int DeckDataWrapper::getCount(int color){ - if (color == -1) return colors[Constants::MTG_NB_COLORS]; - return colors[color]; -} - -int DeckDataWrapper::totalPrice(){ - int total = 0; - PriceList * pricelist = NEW PriceList(RESPATH"/settings/prices.dat",this->parent->database); - map::iterator it; - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCard * current = (*it).first; - int nb = (*it).second; - if (nb) total += pricelist->getPrice(current->getMTGId()); - } - delete pricelist; - return total; -} +} \ No newline at end of file diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index b657ea28f..680720945 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -20,6 +20,7 @@ #include "../include/DeckStats.h" #include "../include/DeckMetaData.h" #include "../include/Translate.h" +#include "../include/WFilter.h" #define DEFAULT_DURATION .25 @@ -233,7 +234,7 @@ void GameApp::Destroy() SAFE_DELETE(music); Translator::EndInstance(); - + WCFilterFactory::Destroy(); SimpleMenu::destroy(); options.theGame = NULL; diff --git a/projects/mtg/src/GameStateAwards.cpp b/projects/mtg/src/GameStateAwards.cpp index 59a0a0219..4de33e80b 100644 --- a/projects/mtg/src/GameStateAwards.cpp +++ b/projects/mtg/src/GameStateAwards.cpp @@ -210,20 +210,23 @@ bool GameStateAwards::enterSet(int setid){ SAFE_DELETE(detailview); SAFE_DELETE(setSrc); - setSrc = NEW WSrcMTGSet(setid); + setSrc = NEW WSrcCards(); + setSrc->addFilter(NEW WCFilterSet(setid)); + setSrc->loadMatches(mParent->collection); + setSrc->bakeFilters(); + setSrc->Sort(WSrcCards::SORT_COLLECTOR); + detailview = NEW WGuiMenu(PSP_CTRL_DOWN,PSP_CTRL_UP); WGuiList * spoiler = NEW WGuiList("Spoiler",setSrc); spoiler->setX(210); spoiler->setWidth(SCREEN_WIDTH - 220); - while(true){ - MTGCard * c = setSrc->getCard(); + for(int t=0;tSize();t++){ + MTGCard * c = setSrc->getCard(t); if(c) spoiler->Add(NEW WGuiItem(c->data->name)); - if(!setSrc->next()) - break; } - setSrc->setPos(0); + setSrc->setOffset(0); spoiler->Entering(0); WGuiCardImage * wi = NEW WGuiCardImage(setSrc); wi->setX(105); @@ -257,18 +260,18 @@ bool GameStateAwards::enterStats(int option){ MTGCard * costly = NULL; MTGCard * strong = NULL; MTGCard * tough = NULL; - map::iterator it; - for (it = ddw->cards.begin(); it!=ddw->cards.end(); it++){ - MTGCard * c = it->first; + for (int t=0;tSize();t++){ + MTGCard * c = ddw->getCard(t); if(!c) continue; - if(!c->data->isLand() && (many == NULL || it->second > dupes)){ + int count = ddw->count(c); + if(!c->data->isLand() && (many == NULL || count > dupes)){ many = c; - dupes = it->second; + dupes = count; } unique++; - counts[c->setId]+=it->second; + counts[c->setId]+=count; if(costly == NULL || c->data->getManaCost()->getConvertedCost() > costly->data->getManaCost()->getConvertedCost()) costly = c; @@ -290,7 +293,7 @@ bool GameStateAwards::enterStats(int option){ sprintf(buf,_("Total Value: %ic").c_str(),ddw->totalPrice()); detailview->Add(NEW WGuiItem(buf,WGuiItem::NO_TRANSLATE));//ddw->colors - sprintf(buf,_("Total Cards (including duplicates): %i").c_str(),ddw->getCount()); + sprintf(buf,_("Total Cards (including duplicates): %i").c_str(),ddw->totalCopies()); detailview->Add(NEW WGuiItem(buf,WGuiItem::NO_TRANSLATE));//ddw->colors sprintf(buf,_("Unique Cards: %i").c_str(),unique); diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index 6c99a6076..f6129e5c2 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -7,6 +7,7 @@ #include "../include/Translate.h" #include "../include/ManaCostHybrid.h" #include "../include/MTGCardInstance.h" +#include "../include/WFilter.h" #include @@ -29,47 +30,78 @@ void StringExplode(string str, string separator, vector* results){ GameStateDeckViewer::GameStateDeckViewer(GameApp* parent): GameState(parent) { bgMusic = NULL; - scrollSpeed = MED_SPEED; nbDecks = 0; deckNum = 0; + useFilter[0] = 0; + useFilter[1] = 0; mSwitching = false; welcome_menu = NULL; + myCollection = NULL; + myDeck = NULL; + filterDeck = NULL; + filterCollection = NULL; } GameStateDeckViewer::~GameStateDeckViewer() { SAFE_DELETE(bgMusic); + SAFE_DELETE(myDeck); + SAFE_DELETE(myCollection); + SAFE_DELETE(filterDeck); + SAFE_DELETE(filterCollection); } void GameStateDeckViewer::rotateCards(int direction){ - int maxCards=displayed_deck->getCount(colorFilter); - if (maxCards==0) - return; int left = direction; - if (left){ - MTGCard * currentCard = displayed_deck->getNext(cardIndex[6],colorFilter); - for (int i = 1; i<7; i++){ - cardIndex[i-1] = cardIndex[i]; - } - cardIndex[6] = currentCard; - }else{ - MTGCard * currentCard = displayed_deck->getPrevious(cardIndex[0],colorFilter); - for (int i = 5; i>=0; i--){ - cardIndex[i+1] = cardIndex[i]; - } - cardIndex[0] = currentCard; - } + if (left) + displayed_deck->next(); + else + displayed_deck->prev(); + loadIndexes(); } +void GameStateDeckViewer::updateFilters(){ + displayed_deck->clearFilters(); + int i = (displayed_deck == myDeck); -void GameStateDeckViewer::loadIndexes(MTGCard * current){ - for (int i = 0; i < 7; i++){ - cardIndex[i] = NULL; + if(useFilter[i] == 0){ + if(i && filterDeck) + filterDeck->Finish(); + else if(filterCollection) + filterCollection->Finish(); + return; } - MTGCard * _current = current; - _current = displayed_deck->getNext(NULL,colorFilter); + WCFilterFactory * wc = WCFilterFactory::GetInstance(); + switch(useFilter[i]-1){ + case Constants::MTG_COLOR_ARTIFACT: + displayed_deck->addFilter(wc->Construct("c:x;")); + break; + case Constants::MTG_COLOR_GREEN: + displayed_deck->addFilter(wc->Construct("c:g;")); + break; + case Constants::MTG_COLOR_BLUE: + displayed_deck->addFilter(wc->Construct("c:u;")); + break; + case Constants::MTG_COLOR_RED: + displayed_deck->addFilter(wc->Construct("c:r;")); + break; + case Constants::MTG_COLOR_BLACK: + displayed_deck->addFilter(wc->Construct("c:b;")); + break; + case Constants::MTG_COLOR_WHITE: + displayed_deck->addFilter(wc->Construct("c:w;")); + break; + case Constants::MTG_COLOR_LAND: + displayed_deck->addFilter(wc->Construct("t:Land;")); + break; + } + //No sanity checking for color filters + //if(!displayed_deck->Size()) + // displayed_deck->clearFilters(); +} +void GameStateDeckViewer::loadIndexes(){ + int x=0; for (int i = 0; i < 7; i++){ - cardIndex[i] = _current; - _current = displayed_deck->getNext(_current,colorFilter); + cardIndex[i] = displayed_deck->getCard(i); } } @@ -80,6 +112,7 @@ void GameStateDeckViewer::switchDisplay(){ displayed_deck = myCollection; } currentCard = NULL; + updateFilters(); loadIndexes(); } @@ -103,7 +136,9 @@ void GameStateDeckViewer::Start() pricelist = NEW PriceList(RESPATH"/settings/prices.dat",mParent->collection); playerdata = NEW PlayerData(mParent->collection); sellMenu = NULL; - myCollection = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), mParent->collection)); + MTGDeck * myC = NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), mParent->collection); + myCollection = NEW DeckDataWrapper(myC); + myCollection->Sort(WSrcCards::SORT_ALPHA); displayed_deck = myCollection; myDeck = NULL; @@ -113,6 +148,7 @@ void GameStateDeckViewer::Start() menu->Add(2,"Switch decks without saving"); if(options[Options::CHEATMODE].number) menu->Add(-1,"*Complete collection & reset*"); + menu->Add(22,"Filter by..."); menu->Add(3,"Back to main menu"); menu->Add(4,"Cancel"); @@ -154,16 +190,14 @@ void GameStateDeckViewer::Start() JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true); } } - colorFilter = ALL_COLORS; mStage = STAGE_WELCOME; - mRotation = 0; mSlide = 0; mAlpha = 255; currentCard = NULL; - loadIndexes(currentCard); + loadIndexes(); last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; onScreenTransition = 0; @@ -187,30 +221,30 @@ void GameStateDeckViewer::End() SAFE_DELETE(myDeck); SAFE_DELETE(pricelist); SAFE_DELETE(playerdata); + SAFE_DELETE(filterDeck); + SAFE_DELETE(filterCollection); } void GameStateDeckViewer::addRemove(MTGCard * card){ if (!card) return; - if (displayed_deck->Remove(card)){ + if (displayed_deck->Remove(card,1,(displayed_deck==myDeck))){ if (displayed_deck == myCollection){ myDeck->Add(card); + myDeck->Sort(WSrcCards::SORT_ALPHA); }else{ myCollection->Add(card); } } stw.needUpdate = true; + loadIndexes(); } -int GameStateDeckViewer::Remove(MTGCard * card){ - if (!card) return 0; - int result = displayed_deck->Remove(card); - return result; -} - - void GameStateDeckViewer::Update(float dt) { + + int myD = (displayed_deck == myDeck); + if(options.keypadActive()){ options.keypadUpdate(dt); @@ -244,25 +278,27 @@ void GameStateDeckViewer::Update(float dt) { case PSP_CTRL_LEFT : last_user_activity = 0; - currentCard = displayed_deck->getNext(currentCard,colorFilter); + currentCard = displayed_deck->getCard(1); mStage = STAGE_TRANSITION_LEFT; break; case PSP_CTRL_RIGHT : last_user_activity = 0; - currentCard = displayed_deck->getPrevious(currentCard,colorFilter); + currentCard = displayed_deck->getCard(-1); mStage = STAGE_TRANSITION_RIGHT; break; case PSP_CTRL_UP : last_user_activity = 0; mStage = STAGE_TRANSITION_UP; - colorFilter--; - if (colorFilter < -1) colorFilter = Constants::MTG_COLOR_LAND; + useFilter[myD]++; + if(useFilter[myD] >= MAX_SAVED_FILTERS) + useFilter[myD] = 0; break; case PSP_CTRL_DOWN : last_user_activity = 0; mStage = STAGE_TRANSITION_DOWN; - colorFilter ++; - if (colorFilter > Constants::MTG_COLOR_LAND) colorFilter =-1; + useFilter[myD]--; + if(useFilter[myD] < 0) + useFilter[myD] = MAX_SAVED_FILTERS-1; break; case PSP_CTRL_TRIANGLE: options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; @@ -284,7 +320,7 @@ void GameStateDeckViewer::Update(float dt) char buffer[4096]; { MTGCard * card = cardIndex[2]; - if (card && displayed_deck->cards[card]){ + if (card && displayed_deck->count(card)){ int rnd = (rand() % 20); price = pricelist->getPrice(card->getMTGId()) / 2; price = price - price * (rnd -10)/100; @@ -308,12 +344,16 @@ void GameStateDeckViewer::Update(float dt) mStage = STAGE_MENU; break; case PSP_CTRL_SELECT : - if (scrollSpeed == HIGH_SPEED) - scrollSpeed = MED_SPEED; - else if (scrollSpeed == MED_SPEED) - scrollSpeed = LOW_SPEED; - else - scrollSpeed = HIGH_SPEED; + mStage = STAGE_FILTERS; + if(displayed_deck == myDeck){ + if(!filterDeck) + filterDeck = NEW WGuiFilters("Filter by...",myDeck); + filterDeck->Entering(0); + }else if(displayed_deck == myCollection){ + if(!filterCollection) + filterCollection = NEW WGuiFilters("Filter by...",myCollection); + filterCollection->Entering(0); + } break; case PSP_CTRL_LTRIGGER : if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY){ @@ -350,7 +390,7 @@ void GameStateDeckViewer::Update(float dt) } if (mStage == STAGE_TRANSITION_RIGHT || mStage == STAGE_TRANSITION_LEFT) { if (mStage == STAGE_TRANSITION_RIGHT){ - mRotation -= dt * scrollSpeed; + mRotation -= dt * MED_SPEED; if (mRotation < -1.0f){ do { rotateCards(mStage); @@ -360,7 +400,7 @@ void GameStateDeckViewer::Update(float dt) mRotation = 0; } }else if(mStage == STAGE_TRANSITION_LEFT){ - mRotation += dt * scrollSpeed; + mRotation += dt * MED_SPEED; if (mRotation > 1.0f){ do { rotateCards(mStage); @@ -374,7 +414,8 @@ void GameStateDeckViewer::Update(float dt) if (mStage == STAGE_TRANSITION_DOWN){ mSlide -= 0.05f; if (mSlide < -1.0f){ - loadIndexes(currentCard); + updateFilters(); + loadIndexes(); mSlide = 1; }else if (mSlide > 0 && mSlide < 0.05){ mStage = STAGE_WAITING; @@ -383,7 +424,8 @@ void GameStateDeckViewer::Update(float dt) } if (mStage == STAGE_TRANSITION_UP){ mSlide += 0.05f; if (mSlide > 1.0f){ - loadIndexes(currentCard); + updateFilters(); + loadIndexes(); mSlide = -1; }else if (mSlide < 0 && mSlide > -0.05){ mStage = STAGE_WAITING; @@ -396,6 +438,44 @@ void GameStateDeckViewer::Update(float dt) welcome_menu->Update(dt); }else if (mStage == STAGE_MENU){ menu->Update(dt); + }else if(mStage == STAGE_FILTERS){ + u32 key = mEngine->ReadButton(); + + if(displayed_deck == myDeck){ + if(filterDeck){ + if(key == PSP_CTRL_SELECT){ + useFilter[(displayed_deck == myDeck)] = 0; + filterDeck->Finish(); + filterDeck->Update(dt); + loadIndexes(); + return; + } + if(!filterDeck->isFinished()){ + filterDeck->CheckUserInput(key); + filterDeck->Update(dt); + } else { + mStage = STAGE_WAITING; + loadIndexes(); + } + } + }else{ + if(filterCollection ){ + if(key == PSP_CTRL_SELECT){ + useFilter[(displayed_deck == myDeck)] = 0; + filterCollection->Finish(); + filterCollection->Update(dt); + loadIndexes(); + return; + } + if(!filterCollection->isFinished()){ + filterCollection->CheckUserInput(key); + filterCollection->Update(dt); + } else { + mStage = STAGE_WAITING; + loadIndexes(); + } + } + } } @@ -404,43 +484,37 @@ void GameStateDeckViewer::Update(float dt) void GameStateDeckViewer::renderOnScreenBasicInfo(){ JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT); - char buffer[30], buffer2[30]; + char buffer[256]; + int myD = (displayed_deck == myDeck); float y = 0; JRenderer::GetInstance()->FillRoundRect(SCREEN_WIDTH-125,y-5,110,15,5,ARGB(128,0,0,0)); - sprintf(buffer, "DECK: %i", myDeck->getCount()); - mFont->DrawString(buffer, SCREEN_WIDTH-120 , y); - - if (colorFilter != ALL_COLORS){ - sprintf(buffer2, "( %i)", myDeck->getCount(colorFilter)); - mFont->DrawString(buffer2, SCREEN_WIDTH-55 , y); - JRenderer::GetInstance()->RenderQuad(mIcons[colorFilter], SCREEN_WIDTH-42 , y + 6 , 0.0f,0.5,0.5); - } - + int now, total; + now = displayed_deck->Size(); + total = displayed_deck->Size(true); + if(now != total) + sprintf(buffer, "%s%i of %i (%i cards)", (displayed_deck == myDeck) ? "DECK: " : " ", now, total,displayed_deck->totalCopies()); + else + sprintf(buffer, "%s%i (%i cards)", (displayed_deck == myDeck) ? "DECK: " : " " , total,displayed_deck->totalCopies()); + mFont->DrawString(buffer, SCREEN_WIDTH-22, y+5,JGETEXT_RIGHT); + if (useFilter[myD] != 0) + JRenderer::GetInstance()->RenderQuad(mIcons[useFilter[myD]-1], SCREEN_WIDTH-10 , y + 10 , 0.0f,0.5,0.5); } void GameStateDeckViewer::renderSlideBar(){ JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT); - int total = displayed_deck->getCount(colorFilter); + int total = displayed_deck->Size(); float filler = 15; float y = SCREEN_HEIGHT_F-25; float bar_size = SCREEN_WIDTH_F - 2*filler; JRenderer * r = JRenderer::GetInstance(); typedef map::reverse_iterator rit; - - int currentPos = 0; - { - rit end = rit(displayed_deck->cards.begin()); - rit it = rit(displayed_deck->cards.find(cardIndex[2])); - if (-1 == colorFilter) - for (; it != end; ++it) - currentPos += it->second; - else - for (; it != end; ++it) - if (it->first->data->hasColor(colorFilter)) currentPos += it->second; - } + int currentPos = displayed_deck->getOffset(); + if(total == 0) + return; + currentPos = abs(currentPos) % total; float cursor_pos = bar_size * currentPos / total; r->FillRoundRect(filler + 5,y+5,bar_size,0,3,ARGB(hudAlpha/2,0,0,0)); @@ -530,8 +604,8 @@ void GameStateDeckViewer::renderOnScreenMenu(){ font->DrawString(_("Next"), leftPspX + 15, leftPspY-15); font->DrawString(_("card"), leftPspX - 35, leftPspY); font->DrawString(_("card"), leftPspX + 15, leftPspY); - font->DrawString(_("Next color"), leftPspX - 33, leftPspY - 35); - font->DrawString(_("Prev. color"), leftPspX -33 , leftPspY +25); + font->DrawString(_("Next edition"), leftPspX - 33, leftPspY - 35); + font->DrawString(_("Prev. edition"), leftPspX -33 , leftPspY +25); //RIGHT PSP CIRCLE render r->FillCircle(rightPspX+(onScreenTransition*204),rightPspY,40,ARGB(128,50,50,50)); @@ -552,6 +626,7 @@ void GameStateDeckViewer::renderOnScreenMenu(){ font->DrawString(_("Sell card"), rightPspX - 30 , rightPspY+20); //Bottom menus font->DrawString(_("menu"), SCREEN_WIDTH-35 +rightTransition, SCREEN_HEIGHT-15); + font->DrawString(_("filter"), SCREEN_WIDTH-95 +rightTransition, SCREEN_HEIGHT-15); @@ -596,6 +671,7 @@ void GameStateDeckViewer::renderOnScreenMenu(){ r->FillRect(10+leftTransition,10,SCREEN_WIDTH/2-10,SCREEN_HEIGHT-20,ARGB(128,0,0,0)); r->FillRect(SCREEN_WIDTH/2+rightTransition,10,SCREEN_WIDTH/2-10,SCREEN_HEIGHT-20,ARGB(128,0,0,0)); font->DrawString(_("menu"), SCREEN_WIDTH-35 +rightTransition, SCREEN_HEIGHT-15); + font->DrawString(_("filter"), SCREEN_WIDTH-95 +rightTransition, SCREEN_HEIGHT-15); int nb_letters = 0; float posX, posY; @@ -1021,7 +1097,7 @@ void GameStateDeckViewer::updateStats() { stw.totalManaCost = 0; stw.totalCreatureCost = 0; stw.totalSpellCost = 0; - MTGCard * current = myDeck->getNext(); + MTGCard * current = myDeck->getCard(); // Clearing arrays for (int i=0; i<=STATS_MAX_MANA_COST; i++) { @@ -1045,10 +1121,11 @@ void GameStateDeckViewer::updateStats() { } } - while (current){ + for(int ic=0;icSize();ic++){ + current = myDeck->getCard(ic); currentCost = current->data->getManaCost(); convertedCost = currentCost->getConvertedCost(); - currentCount = myDeck->cards[current]; + currentCount = myDeck->count(current); // Add to the cards per cost counters stw.totalManaCost += convertedCost * currentCount; @@ -1133,9 +1210,6 @@ void GameStateDeckViewer::updateStats() { stw.totalCostPerColor[hybridCost->color1] += hybridCost->value1*currentCount; stw.totalCostPerColor[hybridCost->color2] += hybridCost->value2*currentCount; } - - - current = myDeck->getNext(current); } stw.totalColoredSymbols = 0; @@ -1172,13 +1246,11 @@ void GameStateDeckViewer::updateStats() { // or at least be calculated for all common types in one go int GameStateDeckViewer::countCardsByType(const char * _type) { int result = 0; - - MTGCard * current = myDeck->getNext(); - while (current){ + for(int i=0;iSize();i++){ + MTGCard * current = myDeck->getCard(i); if(current->data->hasType(_type)){ - result += myDeck->cards[current]; + result += myDeck->count(current); } - current = myDeck->getNext(current); } return result; } @@ -1221,7 +1293,7 @@ void GameStateDeckViewer::renderCard(int id, float rotation){ if (quad){ showName = 0; int quadAlpha = alpha; - if ( !displayed_deck->cards[card]) quadAlpha /=2; + if ( !displayed_deck->count(card)) quadAlpha /=2; quad->SetColor(ARGB(mAlpha,quadAlpha,quadAlpha,quadAlpha)); float _scale = scale *(285 / quad->mHeight); JRenderer::GetInstance()->RenderQuad(quad, x , y , 0.0f,_scale,_scale); @@ -1249,7 +1321,7 @@ void GameStateDeckViewer::renderCard(int id, float rotation){ float qtY = y -135*scale; float qtX = x + 40*scale; char buffer[4096]; - sprintf(buffer, "x%i", displayed_deck->cards[card]); + sprintf(buffer, "x%i", displayed_deck->count(card)); JLBFont * font = mFont; font->SetColor(ARGB(fontAlpha/2,0,0,0)); JRenderer::GetInstance()->FillRect(qtX, qtY,font->GetStringWidth(buffer) + 6,16,ARGB(fontAlpha/2,0,0,0)); @@ -1271,15 +1343,8 @@ void GameStateDeckViewer::Render() { JRenderer * r = JRenderer::GetInstance(); r->ClearScreen(ARGB(0,0,0,0)); - - - if(displayed_deck == myDeck){ + if(displayed_deck == myDeck) renderDeckBackground(); - } - - - - int order[3] = {1,2,3}; if (mRotation < 0.5 && mRotation > -0.5){ order[1]=3; @@ -1298,7 +1363,7 @@ void GameStateDeckViewer::Render() { renderCard(order[i],mRotation); } - if (displayed_deck->getCount(colorFilter)>0){ + if (displayed_deck->Size()>0){ renderSlideBar(); }else{ mFont->DrawString(_("No Card"), SCREEN_WIDTH/2, SCREEN_HEIGHT/2,JGETEXT_CENTER); @@ -1317,19 +1382,30 @@ void GameStateDeckViewer::Render() { } if (sellMenu) sellMenu->Render(); + if(displayed_deck == myDeck){ + if(filterDeck && !filterDeck->isFinished()) + filterDeck->Render(); + }else{ + if(filterCollection && !filterCollection->isFinished()) + filterCollection->Render(); + } + if(options.keypadActive()) options.keypadRender(); + + } int GameStateDeckViewer::loadDeck(int deckid){ - SAFE_DELETE(myCollection); + stw.currentPage = 0; stw.pageCount = 9; stw.needUpdate = true; - string profile = options[Options::ACTIVE_PROFILE].str; - myCollection = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), mParent->collection)); + //string profile = options[Options::ACTIVE_PROFILE].str; + //SAFE_DELETE(myCollection); + //myCollection = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), mParent->collection)); displayed_deck = myCollection; char deckname[256]; sprintf(deckname,"deck%i.txt",deckid); @@ -1337,24 +1413,18 @@ int GameStateDeckViewer::loadDeck(int deckid){ myDeck = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(deckname,"",false,false).c_str(), mParent->collection)); // Check whether the cards in the deck are actually available in the player's collection: - MTGCard * current = myDeck->getNext(); int cheatmode = options[Options::CHEATMODE].number; - while (current){ - int howmanyinDeck = myDeck->cards[current]; - for (int i = 0; i < howmanyinDeck; i++){ - int deleted = myCollection->Remove(current); - if (!deleted){ // Card was not present in the collection - if (cheatmode) { // (PSY) Are we in cheatmode? - playerdata->collection->add(current); // (PSY) Yes - add the card to the collection - } else { - myDeck->Remove(current); // No - remove the card from the deck - } - } + for(int i=0;iSize();i++){ + MTGCard * current = myDeck->getCard(i); + int howmanyinDeck = myDeck->count(current); + for (int i = myCollection->count(current); i < howmanyinDeck; i++){ + if(cheatmode) //Are we cheating? + playerdata->collection->add(current); //Yup, add it to collection. + else + myDeck->Remove(current); //Nope. Remove it from deck. } - current = myDeck->getNext(current); } currentCard = NULL; - loadIndexes(); // Load deck statistics // TODO: Code cleanup (Copypasted with slight changes from GameStateMenu.cpp) char buffer[512]; @@ -1400,6 +1470,9 @@ int GameStateDeckViewer::loadDeck(int deckid){ stw.gamesPlayed = 0; stw.percentVictories = 0; } + + myDeck->Sort(WSrcCards::SORT_ALPHA); + loadIndexes(); return 1; } @@ -1451,6 +1524,18 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) case 4: mStage = STAGE_WAITING; break; + case 22: + mStage = STAGE_FILTERS; + if(displayed_deck == myDeck){ + if(!filterDeck) + filterDeck = NEW WGuiFilters("Filter by...",myDeck); + filterDeck->Entering(0); + }else if(displayed_deck == myCollection){ + if(!filterCollection) + filterCollection = NEW WGuiFilters("Filter by...",myCollection); + filterCollection->Entering(0); + } + break; } break; case 2: @@ -1464,7 +1549,8 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) price = price - (rnd * price)/100; pricelist->setPrice(card->getMTGId(),price*2); playerdata->collection->remove(card->getMTGId()); - Remove(card); + displayed_deck->Remove(card,1); + loadIndexes(); } } case 21: diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index c6c20ec24..35d401011 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -377,7 +377,6 @@ void GameStateMenu::Update(float dt) if (!nextDirectory(RESPATH"/sets/","_cards.dat")){ //Remove temporary translations Translator::GetInstance()->tempValues.clear(); - //Debug #ifdef _DEBUG char buf[4096]; diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 248374549..c4f0e52fa 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -8,35 +8,100 @@ #include "../include/MTGDeck.h" #include "../include/Translate.h" #include "../include/GameOptions.h" +#include +float GameStateShop::_x1[] = { 79, 19, 27,103,154,187,102,144,198,133,183}; +float GameStateShop::_y1[] = {150,194,222,167,164,156,195,190,175,220,220}; + +float GameStateShop::_x2[] = {103, 48, 74,135,183,215,138,181,231,171,225}; +float GameStateShop::_y2[] = {155,179,218,165,166,155,195,186,177,225,216}; + +float GameStateShop::_x3[] = { 48, 61, 9, 96,139,190, 81,146,187, 97,191}; +float GameStateShop::_y3[] = {164,205,257,184,180,170,219,212,195,251,252}; + +float GameStateShop::_x4[] = { 76, 90, 65,131,171,221,123,187,225,141,237}; +float GameStateShop::_y4[] = {169,188,250,182,182,168,220,208,198,259,245}; + +int GameStateShop::randomKey = 0; GameStateShop::GameStateShop(GameApp* parent): GameState(parent) { - shop = NULL; + menu = NULL; for(int i=0;i<8;i++) altThumb[i] = NULL; mBack = NULL; + boosterDisplay = NULL; mBg = NULL; mBgTex = NULL; taskList = NULL; - menu = NULL; + srcCards = NULL; + shopMenu = NULL; + bigDisplay = NULL; + myCollection = NULL; + pricelist = NULL; + playerdata = NULL; + booster = NULL; + lightAlpha = 0; + filterMenu = NULL; + alphaChange = 0; + for(int i=0;isetElapsed(15); + WCFilterFactory * wff = WCFilterFactory::GetInstance(); + //srcCards->addFilter(wff->Construct("c:red;&t:instant;")); + //srcCards->bakeFilters(); + + bigSync = 0; + shopMenu = NEW WGuiMenu(PSP_CTRL_DOWN,PSP_CTRL_UP,true,&bigSync); + MTGAllCards * ac = GameApp::collection; + playerdata = NEW PlayerData(ac);; + myCollection = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), ac)); + pricelist = NEW PriceList(RESPATH"/settings/prices.dat",ac); + for(int i=0;imOffset.setOffset(i-BOOSTER_SLOTS); + } + dist->xy = WDistort(_x1[i],_y1[i],_x2[i],_y2[i],_x3[i],_y3[i],_x4[i],_y4[i]); + shopMenu->Add(NEW WGuiButton(dist,-102,i,this)); + } + shopMenu->Entering(0); + + if(!bigDisplay){ + bigDisplay = NEW WGuiCardImage(srcCards); + bigDisplay->mOffset.Hook(&bigSync); + bigDisplay->mOffset.setOffset(-BOOSTER_SLOTS); + bigDisplay->setX(385); + bigDisplay->setY(135); + } + //alternateRender doesn't lock, so lock our thumbnails for hgeDistort. altThumb[0] = resources.RetrieveTexture("artifact_thumb.jpg", RETRIEVE_LOCK); altThumb[1] = resources.RetrieveTexture("green_thumb.jpg", RETRIEVE_LOCK); @@ -47,6 +112,7 @@ void GameStateShop::Start() altThumb[6] = resources.RetrieveTexture("land_thumb.jpg", RETRIEVE_LOCK); altThumb[7] = resources.RetrieveTexture("gold_thumb.jpg", RETRIEVE_LOCK); + mBack = resources.GetQuad("back"); resources.Unmiss("shop.jpg"); //Last resort. mBgTex = resources.RetrieveTexture("shop.jpg", RETRIEVE_LOCK, TEXTURE_SUB_5551); @@ -57,109 +123,294 @@ void GameStateShop::Start() JRenderer::GetInstance()->EnableVSync(true); - shop = NULL; taskList = NULL; load(); } +string GameStateShop::descPurchase(int controlId, bool tiny){ + char buffer[4096]; + string name; + if(controlId < BOOSTER_SLOTS){ + if(mBooster[controlId].altSet == mBooster[controlId].mainSet) + mBooster[controlId].altSet = 0; + if(mBooster[controlId].altSet) + sprintf(buffer,_("%s & %s Booster (15 Cards)").c_str(),mBooster[controlId].mainSet->id.c_str(),mBooster[controlId].altSet->id.c_str()); + else + sprintf(buffer,_("%s Booster (15 Cards)").c_str(),mBooster[controlId].mainSet->id.c_str()); + name = buffer; + } + else{ + MTGCard * c = srcCards->getCard(controlId-BOOSTER_SLOTS); + if(!c) + return ""; + name = c->data->getName(); + } + if(mInventory[controlId] <= 0){ + if(tiny) + sprintf(buffer,_("SOLD OUT").c_str(),name.c_str()); + else + sprintf(buffer,_("%s : SOLD OUT").c_str(),name.c_str()); + return buffer; + } + + if(tiny) + return name; + + if(mCounts[controlId] < 1) + sprintf(buffer,_("%s : %i credits").c_str(),name.c_str(),mPrices[controlId]); + else + sprintf(buffer,_("%s (%i) : %i credits").c_str(),name.c_str(),mCounts[controlId],mPrices[controlId]); + return buffer; +} +void GameStateShop::assembleBooster(int controlId){ + int mSet = -1; + MTGSetInfo * si = setlist.randomSet(-1); + mBooster[controlId].mainSet = si; + mBooster[controlId].altSet = NULL; + + int mSetCount = si->counts[MTGSetInfo::TOTAL_CARDS]; + if(mSetCount < 80){ + if(rand() % 100 < 50){ //50% Chance of picking a pure pack instead. Combo packs are more rare :) + si = setlist.randomSet(-1,80); + mSetCount = si->counts[MTGSetInfo::TOTAL_CARDS]; + mBooster[controlId].mainSet = si; + }else + mBooster[controlId].altSet = setlist.randomSet(si->block,mSetCount); + } + else { + mBooster[controlId].altSet = NULL; + if(rand() % 100 < 10) //10% chance of having a mixed booster anyways. + mBooster[controlId].altSet = setlist.randomSet(si->block); + } + + for(int attempts=0;attempts<10;attempts++){ + if(mBooster[controlId].altSet != mBooster[controlId].mainSet) + break; + mBooster[controlId].altSet = setlist.randomSet(-1,mSetCount); + } + + int price = mBooster[controlId].mainSet->boosterCost(); + mInventory[controlId] = 2+rand()%4; + if(mBooster[controlId].altSet != NULL){ + price += mBooster[controlId].altSet->boosterCost(); + price /= 2; + price = price + .05 * price; //Mixed sets add a 5% premium. + mInventory[controlId] = 1+rand()%2; + } + mPrices[controlId] = price; +} +void GameStateShop::beginPurchase(int controlId){ + JLBFont * mFont = resources.GetJLBFont(Constants::MENU_FONT); + mFont->SetScale(DEFAULT_MENU_FONT_SCALE); + SAFE_DELETE(menu); + if(mInventory[controlId] <= 0){ + menu = NEW SimpleMenu(-145,this,Constants::MENU_FONT,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,_("Sold Out").c_str()); + menu->Add(-1,"Ok"); + } + else if(playerdata->credits - mPrices[controlId] < 0){ + menu = NEW SimpleMenu(-145,this,Constants::MENU_FONT,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,_("Not enough credits").c_str()); + menu->Add(-1,"Ok"); + if(options[Options::CHEATMODE].number) { + menu->Add(-2,"Steal it"); + } + } + else{ + string s; + if(controlId < BOOSTER_SLOTS) + s = _("Purchase Booster"); + else + s = _("Purchase Card"); + menu = NEW SimpleMenu(-145,this,Constants::MENU_FONT,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,s.c_str()); + menu->Add(controlId,"Yes"); + menu->Add(-1,"No"); + } +} + +void GameStateShop::purchaseCard(int controlId){ + MTGCard * c = srcCards->getCard(controlId-BOOSTER_SLOTS); + if(!c || !c->data || playerdata->credits - mPrices[controlId] < 0) + return; + playerdata->collection->add(c); + myCollection->Add(c); + playerdata->credits -= mPrices[controlId]; + mCounts[controlId]++; + mInventory[controlId]--; + mTouched = true; + menu->Close(); +} +void GameStateShop::purchaseBooster(int controlId){ + if(playerdata->credits - mPrices[controlId] < 0) + return; + playerdata->credits -= mPrices[controlId]; + mInventory[controlId]--; + WSrcCards * pool = NEW WSrcCards(); + WCFilterSet *main, *alt; + + int num = setlist.getSetNum(mBooster[controlId].mainSet); + main = NEW WCFilterSet(num); + if(mBooster[controlId].altSet){ + num = setlist.getSetNum(mBooster[controlId].altSet); + alt = NEW WCFilterSet(num); + pool->addFilter(NEW WCFilterOR(main,alt)); + }else + pool->addFilter(main); + pool->loadMatches(srcCards,true); + pool->Shuffle(); + + SAFE_DELETE(booster); + booster = NEW MTGDeck(mParent->collection); + + //Add cards to booster. Pool is shuffled, so just step through. + int carryover = 1; + if(!(rand() % 8)){ + pool->addFilter(NEW WCFilterRarity(Constants::RARITY_M)); + carryover = pool->addToDeck(booster,carryover); + } + pool->clearFilters(); + pool->addFilter(NEW WCFilterRarity(Constants::RARITY_R)); + carryover = pool->addToDeck(booster,carryover); + pool->clearFilters(); + pool->addFilter(NEW WCFilterRarity(Constants::RARITY_U)); + carryover = pool->addToDeck(booster,carryover+3); + pool->clearFilters(); + pool->addFilter(NEW WCFilterRarity(Constants::RARITY_C)); + carryover = pool->addToDeck(booster,carryover+11); + + myCollection->Add(booster); + makeDisplay(booster); + + save(true); + SAFE_DELETE(pool); + menu->Close(); +} + +int GameStateShop::purchasePrice(int offset){ + MTGCard * c = NULL; + if(!pricelist || !srcCards || (c = srcCards->getCard(offset)) == NULL) + return 0; + int rnd = abs(c->getMTGId() + randomKey) % 20; + float price = (float) pricelist->getPrice(c->getMTGId()); + price = price + price * (rnd -10)/100; + return (int) (price + price * srcCards->filterFee()); +} void GameStateShop::load(){ - if (shop) shop->saveAll(); - SAFE_DELETE(shop); - int sets[500]; - int boosterSets[500]; - int unlocked[500]; int nbsets = 0; int nbboostersets = 0; - //Figure out which sets are available. - for (int i = 0; i < setlist.size(); i++){ - unlocked[i] = options[Options::optionSet(i)].number; - } - for (int i = 0; i < setlist.size(); i++){ - if (unlocked[i]){ - sets[nbsets] = i; - nbsets++; - if (mParent->collection->countBySet(i) > 80){ //Only sets with more than 80 cards can get boosters and starters - boosterSets[nbboostersets] = i; - nbboostersets++; - } - } - } - if (nbboostersets){ - for (int i = 0; i < SHOP_BOOSTERS; i++){ - setIds[i] = boosterSets[(rand() % nbboostersets)]; - } - }else{ - for (int i = 0; i < SHOP_BOOSTERS; i++){ - setIds[i] = (rand() % setlist.size()); - } - } JQuad * mBackThumb = resources.GetQuad("back_thumb"); - - - - shop = NEW ShopItems(10, this, resources.GetJLBFont(Constants::MAIN_FONT), 10, 0, mParent->collection, setIds); - MTGSetInfo * si = NULL; - for (int i = 0; i < SHOP_BOOSTERS; i++){ - si = setlist.getInfo(setIds[i]); - if(!si) + for(int i=0;igetCard(i-BOOSTER_SLOTS)) == NULL){ + mPrices[i] = 0; + mCounts[i] = 0; + mInventory[i] = 0; continue; - - sprintf(setNames[i], "%s %s (%i %s)", si->id.c_str(), _("Booster").c_str(), si->boosterSize(), _("Cards").c_str()); - shop->Add(setNames[i],mBack,mBackThumb, si->boosterCost()); - } - - MTGDeck * tempDeck = NEW MTGDeck(mParent->collection); - tempDeck->addRandomCards(8,sets,nbsets); - for (map::iterator it = tempDeck->cards.begin(); it!=tempDeck->cards.end(); it++){ - for (int j = 0; j < it->second; j++){ - shop->Add(it->first); } - } - delete tempDeck; -} + mPrices[i] = purchasePrice(i); + mCounts[i] = myCollection->countByName(c); + switch(c->getRarity()){ + case Constants::RARITY_C: + mInventory[i] = 2 + rand() % 8; + break; + case Constants::RARITY_L: + mInventory[i] = 100; + break; + case Constants::RARITY_U: + mInventory[i] = 1 + rand() % 5; + break; + case Constants::RARITY_R: + mInventory[i] = 1 + rand() % 2; + break; + } + } + + +} +void GameStateShop::save(bool force) +{ + if(mTouched || force){ + if(pricelist) + pricelist->save(); + if(playerdata) + playerdata->save(); + } + mTouched = false; +} void GameStateShop::End() { + save(); JRenderer::GetInstance()->EnableVSync(false); resources.Release(mBgTex); mBgTex = NULL; mBg = NULL; + mElapsed = 0; + SAFE_DELETE(shopMenu); + SAFE_DELETE(bigDisplay); + SAFE_DELETE(srcCards); + SAFE_DELETE(playerdata); + SAFE_DELETE(pricelist); + SAFE_DELETE(myCollection); + SAFE_DELETE(booster); + SAFE_DELETE(filterMenu); + deleteDisplay(); //Release alternate thumbnails. for(int i=0;i<8;i++){ resources.Release(altThumb[i]); + altThumb[i] = NULL; } - SAFE_DELETE(shop); SAFE_DELETE(menu); SAFE_DELETE(taskList); } void GameStateShop::Destroy(){ } - +void GameStateShop::beginFilters(){ + if(!filterMenu){ + filterMenu = NEW WGuiFilters("Ask about...",srcCards); + filterMenu->setY(2); + filterMenu->setHeight(SCREEN_HEIGHT-2); + } + mStage = STAGE_ASK_ABOUT; + filterMenu->Entering(0); +} void GameStateShop::Update(float dt) -{ +{ + if(menu && menu->closed) + SAFE_DELETE(menu); + srcCards->Update(dt); + alphaChange = (500 - (rand() % 1000)) * dt; + lightAlpha+= alphaChange; + if (lightAlpha < 0) lightAlpha = 0; + if (lightAlpha > 50) lightAlpha = 50; // mParent->effect->UpdateSmall(dt); // mParent->effect->UpdateBig(dt); + if(mStage != STAGE_FADE_IN) + mElapsed += dt; + u32 btn; - if (menu){ - menu->Update(dt); - if (menu->closed) SAFE_DELETE(menu); - } switch(mStage){ case STAGE_SHOP_MENU: - if (!menu){ + if (menu){ + menu->Update(dt); + }else{ menu = NEW SimpleMenu(11,this,Constants::MENU_FONT,SCREEN_WIDTH/2-100,20); + menu->Add(22,"Ask about..."); + menu->Add(14,"Check task board"); + if(options[Options::CHEATMODE].number) + menu->Add(-2,"Steal 1,000 credits"); menu->Add(12,"Save & Back to Main Menu"); - menu->Add(14,"See available tasks"); menu->Add(13, "Cancel"); } break; case STAGE_SHOP_TASKS: if(menu){ + menu->Update(dt); return; } if(taskList){ @@ -173,7 +424,7 @@ void GameStateShop::Update(float dt) if(!menu){ menu = NEW SimpleMenu(11,this,Constants::MENU_FONT,SCREEN_WIDTH/2-100,20); menu->Add(12,"Save & Back to Main Menu"); - menu->Add(15,"Close tasks"); + menu->Add(15,"Return to shop"); menu->Add(13, "Cancel"); } } @@ -193,18 +444,67 @@ void GameStateShop::Update(float dt) } #endif break; + case STAGE_ASK_ABOUT: + btn = mEngine->ReadButton(); + if(menu && !menu->closed){ + menu->CheckUserInput(btn); + menu->Update(dt); + return; + } + if(filterMenu){ + if(btn == PSP_CTRL_SELECT){ + filterMenu->Finish(); + filterMenu->Update(dt); + return; + } + if(filterMenu->isFinished()){ + load(); + mStage = STAGE_SHOP_SHOP; + }else{ + filterMenu->CheckUserInput(btn); + filterMenu->Update(dt); + } + return; + } + break; case STAGE_SHOP_SHOP: btn = mEngine->ReadButton(); + if(menu && !menu->closed){ + menu->CheckUserInput(btn); + menu->Update(dt); + return; + } if (btn == PSP_CTRL_START){ + if(boosterDisplay){ + deleteDisplay(); + return; + } mStage = STAGE_SHOP_MENU; return; + }else if(btn == PSP_CTRL_SELECT){ + beginFilters(); }else if(btn == PSP_CTRL_SQUARE){ - load(); - } - if (shop){ - shop->CheckUserInput(btn); - shop->Update(dt); + srcCards->Shuffle(); + load(); + }else if(btn == PSP_CTRL_TRIANGLE){ + options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; + }else if (boosterDisplay){ + if(btn == PSP_CTRL_CROSS) + deleteDisplay(); + else { + boosterDisplay->CheckUserInput(btn); + boosterDisplay->Update(dt);} + return; + }else if(btn == PSP_CTRL_CROSS){ + bListCards = !bListCards; + }else if(shopMenu){ + if(shopMenu->CheckUserInput(btn)) + srcCards->Touch(); } + + if(shopMenu) + shopMenu->Update(dt); + break; case STAGE_FADE_IN: mParent->DoAnimation(TRANSITION_FADE_IN); @@ -213,57 +513,156 @@ void GameStateShop::Update(float dt) } } +void GameStateShop::makeDisplay(MTGDeck * d){ + deleteDisplay(); + boosterDisplay = NEW CardDisplay(12,NULL, SCREEN_WIDTH - 200, SCREEN_HEIGHT/2,this,NULL,5); + map::iterator it; + + for (it = d->cards.begin(); it!=d->cards.end(); it++){ + MTGCard * c = d->getCardById(it->first); + MTGCardInstance * ci = NEW MTGCardInstance(c, NULL); + boosterDisplay->AddCard(ci); + subBooster.push_back(ci); + } +} +void GameStateShop::deleteDisplay(){ + vector::iterator i; + for(i=subBooster.begin();i!=subBooster.end();i++){ + if(!*i) continue; + delete *i; + } + subBooster.clear(); + SAFE_DELETE(boosterDisplay); +} void GameStateShop::Render() { //Erase + JLBFont * mFont = resources.GetJLBFont(Constants::MAIN_FONT); JRenderer * r = JRenderer::GetInstance(); r->ClearScreen(ARGB(0,0,0,0)); if(mStage == STAGE_FADE_IN) return; - if (mBg) r->RenderQuad(mBg,0,0); + if (mBg) + r->RenderQuad(mBg,0,0); + JQuad * quad = resources.RetrieveTempQuad("shop_light.jpg",TEXTURE_SUB_5551); + if (quad){ + r->EnableTextureFilter(false); + r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); + quad->SetColor(ARGB(lightAlpha,255,255,255)); + r->RenderQuad(quad,0,0); + r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); + r->EnableTextureFilter(true); + } + + if(shopMenu) + shopMenu->Render(); + if(filterMenu && !filterMenu->isFinished()) + filterMenu->Render(); + else{ + if(boosterDisplay) + boosterDisplay->Render(); + else if(bigDisplay){ + if(bigDisplay->mOffset.getPos() >= 0) + bigDisplay->setSource(srcCards); + else + bigDisplay->setSource(NULL); + bigDisplay->Render(); + float elp = srcCards->getElapsed(); + //Render the card list overlay. + if( bListCards || elp > LIST_FADEIN){ + char alpha = 200; + if(!bListCards && elp < LIST_FADEIN+.25){ + alpha = 800 *(elp-LIST_FADEIN); + } + r->FillRoundRect(300,10, 160, SHOP_SLOTS * 20 + 15,5,ARGB(alpha,0,0,0)); + alpha+=55; + for(int i=0;igetSelected()) + mFont->SetColor(ARGB(alpha,255,255,0)); + else + mFont->SetColor(ARGB(alpha,255,255,255)); + char buffer[512]; + string s = descPurchase(i,true); + sprintf(buffer, "%s", s.c_str()); + float x = 310; + float y = 25 + 20*i; + mFont->DrawString(buffer,x,y); + } + } + } + } + + //Render the info bar + r->FillRect(0,SCREEN_HEIGHT-17,SCREEN_WIDTH,17,ARGB(128,0,0,0)); + char c[512]; + sprintf(c,_("credits: %i").c_str(), playerdata->credits); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(c, 5, SCREEN_HEIGHT - 12); + sprintf(c, "%s", _("[]:other cards").c_str()); + unsigned int len = 4 + mFont->GetStringWidth(c); + mFont->DrawString(c,SCREEN_WIDTH-len,SCREEN_HEIGHT-14); + + mFont->SetColor(ARGB(255,255,255,0)); + mFont->DrawString(descPurchase(bigSync.getPos()).c_str(), SCREEN_WIDTH/2, SCREEN_HEIGHT - 14,JGETEXT_CENTER); + mFont->SetColor(ARGB(255,255,255,255)); - if (shop) - shop->Render(); - if (mStage == STAGE_SHOP_TASKS && taskList) { taskList->Render(); } - - if (menu){ + if (menu) menu->Render(); - } } void GameStateShop::ButtonPressed(int controllerId, int controlId) { - if (controllerId == 10){ - if (shop) - shop->pricedialog(controlId); + int sel = bigSync.getOffset(); + + switch(controllerId){ + case -102: //Buying something... + beginPurchase(controlId); + return; + case -145: + if(controlId == -1){ //Nope, don't buy. + menu->Close(); + return; + } + if(sel > -1 && sel < SHOP_ITEMS){ + if(controlId == -2) + playerdata->credits += mPrices[sel]; + if(sel < BOOSTER_SLOTS) //Clicked a booster. + purchaseBooster(sel); + else + purchaseCard(sel); + } + return; } - else{ - switch(controlId){ - case 12: - if (shop) shop->saveAll(); - if (taskList) taskList->save(); - mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU); - mStage = STAGE_SHOP_SHOP; - break; - case 14: - mStage = STAGE_SHOP_TASKS; - if (!taskList) - taskList = NEW TaskList(); - taskList->Start(); - break; - case 15: - if(taskList) - taskList->End(); - break; - default: - mStage = STAGE_SHOP_SHOP; - } - if (menu) menu->Close(); + //Basic Menu. + switch(controlId){ + case 12: + if (taskList) taskList->save(); + mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU); + mStage = STAGE_SHOP_SHOP; + break; + case 14: + mStage = STAGE_SHOP_TASKS; + if (!taskList) + taskList = NEW TaskList(); + taskList->Start(); + break; + case 15: + if(taskList) + taskList->End(); + break; + case 22: + beginFilters(); + break; + case -2: + playerdata->credits += 1000; + default: + mStage = STAGE_SHOP_SHOP; } + SAFE_DELETE(menu); } diff --git a/projects/mtg/src/GameStateTransitions.cpp b/projects/mtg/src/GameStateTransitions.cpp index f6826f51d..670df65e4 100644 --- a/projects/mtg/src/GameStateTransitions.cpp +++ b/projects/mtg/src/GameStateTransitions.cpp @@ -7,7 +7,6 @@ #include "../include/Translate.h" #include "../include/OptionItem.h" #include "../include/GameOptions.h" -#include "../include/DeckDataWrapper.h" TransitionBase::TransitionBase(GameApp* parent, GameState* _from, GameState* _to, float duration): GameState(parent){ from = _from; @@ -15,7 +14,12 @@ TransitionBase::TransitionBase(GameApp* parent, GameState* _from, GameState* _to mDuration = duration; bAnimationOnly = false; } - +TransitionBase::~TransitionBase(){ + if(!bAnimationOnly){ + if(from) + from->End(); + } +} void TransitionBase::Update(float dt){ if(from && !Finished()) from->Update(dt); @@ -36,12 +40,7 @@ void TransitionBase::Start() { void TransitionBase::End() { mElapsed = 0; }; -TransitionBase::~TransitionBase(){ - if(!bAnimationOnly){ - if(from) - from->End(); - } -} + void TransitionFade::Render(){ if(from) from->Render(); diff --git a/projects/mtg/src/MTGCard.cpp b/projects/mtg/src/MTGCard.cpp index 1db00b1f4..15b098a4a 100644 --- a/projects/mtg/src/MTGCard.cpp +++ b/projects/mtg/src/MTGCard.cpp @@ -30,7 +30,6 @@ MTGCard::MTGCard(MTGCard * source){ mtgid = source->mtgid; setId = source->setId; data = source->data; - } int MTGCard::init(){ @@ -57,7 +56,6 @@ int MTGCard::getMTGId(){ int MTGCard::getId(){ return mtgid; } - char MTGCard::getRarity(){ return rarity; } diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 7d885fc17..251dc03a9 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -727,6 +727,43 @@ MTGSetInfo* MTGSets::getInfo(int setID){ return setinfo[setID]; } +MTGSetInfo* MTGSets::randomSet(int blockId, int atleast){ + char * unlocked = (char *)calloc(size(),sizeof(char)); + int attempts = 50; + //Figure out which sets are available. + for (int i = 0; i < size(); i++){ + unlocked[i] = options[Options::optionSet(i)].number; + } + //No luck randomly. Now iterate from a random location. + int a = 0, iter = 0; + while(iter < 3){ + a = rand()%size(); + for(int i=a;iblock == blockId) + && (atleast == -1 || setinfo[i]->totalCards() >= atleast)){ + free(unlocked); + return setinfo[i]; + } + } + for(int i=0;iblock == blockId) + && (atleast == -1 || setinfo[i]->totalCards() >= atleast)){ + free(unlocked); + return setinfo[i]; + } + } + blockId = -1; + iter++; + if(iter == 2) + atleast = -1; + } + free(unlocked); + return NULL; +} + int blockSize(int blockId); + int MTGSets::Add(const char * name){ int setid = findSet(name); if(setid != -1) @@ -781,12 +818,18 @@ string MTGSets::operator[](int id){ return si->id; } - +int MTGSets::getSetNum(MTGSetInfo*i){ + int it; + for(it=0;it #include -//WGuiBase - -PIXEL_TYPE WGuiBase::getColor(int type){ - switch(type){ - case WGuiColor::TEXT_BODY: - case WGuiColor::SCROLLBUTTON: - return ARGB(255,255,255,255); - case WGuiColor::SCROLLBAR: - return ARGB(150,50,50,50); - case WGuiColor::BACK_HEADER: - return ARGB(150,80,80,80); - default: - if(type < WGuiColor::BACK){ - if(hasFocus()) - return ARGB(255,255,255,0); - else - return ARGB(255,255,255,255); - } - else - return ARGB(150,50,50,50); - } - return ARGB(150,50,50,50); -} - - -void WGuiBase::renderBack(WGuiBase * it){ - if(!it) return; - WDecoStyled * styled = dynamic_cast(it); - if(styled) - styled->renderBack(styled->getDecorated()); - else - subBack(it); -} - - -//WGuiItem -void WGuiItem::Entering(u32 key){ - mFocus = true; -} - -bool WGuiItem::Leaving(u32 key){ - mFocus = false; - return true; -} - -void WGuiItem::Render(){ - JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); - mFont->SetColor(getColor(WGuiColor::TEXT)); - JRenderer * renderer = JRenderer::GetInstance(); - float fH = (height-mFont->GetHeight())/2; - string trans = _(displayValue); - float fW = mFont->GetStringWidth(trans.c_str()); - float boxW = getWidth(); - float oldS = mFont->GetScale(); - if(fW > boxW){ - mFont->SetScale(boxW/fW); - } - mFont->DrawString(trans,x+(width/2),y+fH,JGETEXT_CENTER); - mFont->SetScale(oldS); -} - -WGuiItem::WGuiItem(string _display, u8 _mF){ - mFlags=_mF; - displayValue = _display; - mFocus = false; - width=SCREEN_WIDTH; - height=20; - x=0; - y=0; -} - -string WGuiItem::_(string input){ - if(mFlags & WGuiItem::NO_TRANSLATE) - return input; - return ::_(input); -} -bool WGuiItem::CheckUserInput(u32 key){ - if(mFocus && key == PSP_CTRL_CIRCLE){ - updateValue(); - return true; - } - return false; -} - -//WDecoStyled -void WDecoStyled::subBack(WGuiBase * item){ - if(!item) - return; - JRenderer * renderer = JRenderer::GetInstance(); - if(mStyle & DS_STYLE_BACKLESS) - return; - //TODO: if(mStyle & DS_STYLE_EDGED) Draw the edged box ala SimpleMenu - else{ //Draw standard style - WGuiSplit * split = dynamic_cast(item); - if(split && split->left->Visible() && split->right->Visible()){ - if(split->left) - 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()-2,split->getY()-2,split->right->getWidth(),split->getHeight(),2,split->right->getColor(WGuiColor::BACK)); - } - else{ - renderer->FillRoundRect(item->getX()-2,item->getY()-2,item->getWidth(),item->getHeight(),2,getColor(WGuiColor::BACK)); - } - } - -} - -PIXEL_TYPE WDecoStyled::getColor(int type){ - switch(type){ - case WGuiColor::BACK: - case WGuiColor::BACK_HEADER: - if(mStyle & DS_COLOR_DARK) - return ARGB(150,35,35,35); - else if(mStyle & DS_COLOR_BRIGHT) - return ARGB(150,80,80,80); - else if(mStyle & DS_STYLE_ALERT) - return ARGB(150,120,80,80); - else - return ARGB(150,50,50,50); - default: - return WGuiBase::getColor(type); - } - return ARGB(150,50,50,50); -} - -//WGuiHeader -void WGuiHeader::Render(){ - JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); - mFont->SetColor(getColor(WGuiColor::TEXT)); - - JRenderer * renderer = JRenderer::GetInstance(); - mFont->DrawString(_(displayValue).c_str(),x+width/2,y,JGETEXT_CENTER); -} - //OptionItem OptionItem::OptionItem( int _id, string _displayValue): WGuiItem(_displayValue) { id = _id; @@ -476,208 +342,6 @@ OptionDirectory::OptionDirectory(string root, int id, string displayValue, strin initSelections(); } -bool WGuiMenu::Leaving(u32 key){ - int nbitems = (int) items.size(); - if(key == buttonNext && currentItem < nbitems-1) - return false; - else if(key == buttonPrev && currentItem > 0) - return false; - - if(currentItem >= 0 && currentItem < nbitems) - if(!items[currentItem]->Leaving(key)) - return false; - - mFocus = false; - return true; -} -void WGuiMenu::Entering(u32 key){ - mFocus = true; - - //Try to force a selectable option. - if(currentItem == -1){ - for (size_t i = 0 ; i < items.size(); i++){ - if(items[i]->Selectable()) { - currentItem = i; - break; - } - } - } - - if(currentItem >= 0 && currentItem < (int) items.size()) - items[currentItem]->Entering(key); - return; -} - -void WGuiMenu::subBack(WGuiBase * item){ - if(!item) - return; - JRenderer * renderer = JRenderer::GetInstance(); - - WGuiSplit * split = dynamic_cast(item); - if(split && split->left->Visible() && split->right->Visible()){ - if(split->left) - 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()-2,split->getY()-2,split->right->getWidth(),split->getHeight(),2,split->right->getColor(WGuiColor::BACK)); - } - else - renderer->FillRoundRect(item->getX()-2,item->getY()-2,item->getWidth(),item->getHeight(),2,item->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(size_t x=0;xconfirmChange(confirmed); - } -} -void WGuiList::Render(){ - JRenderer * renderer = JRenderer::GetInstance(); - int listHeight=40; - int listSelectable=0; - int adjustedCurrent=0; - int start = 0, nowPos = 0, vHeight=0; - int nbitems = (int) items.size(); - - //List is empty. - 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); - return; - } - - //Force a selectable option. - if(currentItem == -1){ - for (int i = 0 ; i < nbitems; i++){ - if(items[i]->Selectable()) { - currentItem = i; - if(hasFocus()) - items[currentItem]->Entering(0); - break; - } - } - } - //Find out how large our list is, with all items and margin. - for (int pos=0;pos < nbitems; pos++){ - listHeight+=items[pos]->getHeight()+1; //What does the +1 do exactly ? - if(items[pos]->Selectable()){ - listSelectable++; - if(pos < currentItem) adjustedCurrent++; - } - } - - //Always fill screen - if(listHeight > SCREEN_HEIGHT) - { - for (start=currentItem;start > 0; start--){ - if(!items[start]->Visible()) - continue; - - vHeight += items[start]->getHeight()+5; - if(vHeight >= (SCREEN_HEIGHT-60)/2) - break; - } - vHeight = 0; - if(start >= 0) - for (nowPos=nbitems;nowPos > 1; nowPos--){ - if(!items[start]->Visible()) - continue; - vHeight += items[nowPos-1]->getHeight()+5; - } - - if(vHeight <= SCREEN_HEIGHT-40 && nowPos < start) - start = nowPos; - } - - vHeight = 0; - nowPos = 0; - - //Render items. - if(start >= 0) - { - //Render current underlay. - if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) - items[currentItem]->Underlay(); - - for (int pos=0;pos < nbitems; pos++){ - if(!items[pos]->Visible()) - continue; - - if(pos < start){ - vHeight += items[pos]->getHeight() + 5; - continue; - } - - items[pos]->setY(y+nowPos); - items[pos]->setX(x); - if(listHeight > SCREEN_HEIGHT && listSelectable > 1) - items[pos]->setWidth(width-10); - else - items[pos]->setWidth(width); - nowPos += items[pos]->getHeight() + 5; - renderBack(items[pos]); - items[pos]->Render(); - if(nowPos > SCREEN_HEIGHT) //Stop displaying things once we reach the bottom of the screen. - break; - } - - //Draw scrollbar - if(listHeight > SCREEN_HEIGHT && listSelectable > 1){ - 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-2,y-1,2,SCREEN_HEIGHT-y, - getColor(WGuiColor::SCROLLBAR)); - renderer->FillRoundRect(x+width-5,barPosition,5,barLength,2, - getColor(WGuiColor::SCROLLBUTTON)); - } - - //Render current overlay. - if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) - items[currentItem]->Overlay(); - } -} - -void WGuiList::setData(){ - for (size_t i = 0; i < items.size(); i++){ - items[i]->setData(); - } -} - -bool WGuiList::nextItem(){ - bool rez = WGuiMenu::nextItem(); - if(sync) - sync->setPos(currentItem); - return rez; -} -bool WGuiList::prevItem(){ - bool rez = WGuiMenu::prevItem(); - if(sync) - sync->setPos(currentItem); - return rez; -} - -void WGuiList::ButtonPressed(int controllerId, int controlId){ - WGuiBase * it; - - if(!(it = Current())) - return; - - it->ButtonPressed(controllerId,controlId); -} - const string OptionTheme::DIRTESTER = "preview.png"; OptionTheme::OptionTheme() : OptionDirectory(RESPATH"/themes", Options::ACTIVE_THEME, "Current Theme", DIRTESTER){ addSelection("Default"); @@ -763,873 +427,4 @@ void OptionTheme::confirmChange(bool confirmed){ resources.Refresh(); //Update images prior_value = value; } -} -string WDecoEnum::lookupVal(int value){ - - if(edef == NULL){ - int id = getId(); - if(id != INVALID_ID){ - GameOptionEnum * goEnum = dynamic_cast(options.get(getId())); - if(goEnum) - edef = goEnum->def; - } - } - - if(edef){ - int idx = edef->findIndex(value); - if(idx != INVALID_ID) - return edef->values[idx].second; - } - - char buf[32]; - sprintf(buf,"%d",value); - return buf; -} - -void WDecoEnum::Render() -{ - JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); - mFont->SetColor(getColor(WGuiColor::TEXT)); - JRenderer * renderer = JRenderer::GetInstance(); - mFont->DrawString(_(getDisplay()).c_str(),getX(),getY()); - OptionInteger* opt = dynamic_cast(it); - if(opt) - mFont->DrawString(_(lookupVal(opt->value)).c_str(), getWidth() -10, getY(), JGETEXT_RIGHT); -} - -WDecoEnum::WDecoEnum(WGuiBase * _it, EnumDefinition *_edef) : WGuiDeco(_it) {edef = _edef;} -//WDecoCheat -WDecoCheat::WDecoCheat(WGuiBase * _it): WGuiDeco(_it){ - bVisible = (options[Options::ACTIVE_PROFILE].str == SECRET_PROFILE); -} -void WDecoCheat::Reload(){ - bVisible = (options[Options::ACTIVE_PROFILE].str == SECRET_PROFILE); -} -bool WDecoCheat::Visible(){ - if(bVisible && it && it->Visible()) - return true; - return false; -} -bool WDecoCheat::Selectable(){ - if(!it || !Visible()) - return false; - return it->Selectable(); -} -//WDecoConfirm - -WDecoConfirm::WDecoConfirm(JGuiListener * _listener, WGuiBase * _it): WGuiDeco(_it){ - listener = _listener; - confirm = "Confirm"; - cancel = "Cancel"; - confirmMenu = NULL; - bModal = false; - mState = OP_CONFIRMED; -} - -WDecoConfirm::~WDecoConfirm(){ - SAFE_DELETE(confirmMenu); -} - -void WDecoConfirm::Entering(u32 key){ - setFocus(true); - - if(it) - it->Entering(key); - - SAFE_DELETE(confirmMenu); - mState = OP_CONFIRMED; - confirmMenu = NEW SimpleMenu(444, listener,Constants::MENU_FONT, 50,170); - confirmMenu->Add(1,confirm.c_str()); - confirmMenu->Add(2,cancel.c_str()); -} - -bool WDecoConfirm::isModal(){ - if(bModal || (it && it->isModal())) - return true; - - return false; -} - -void WDecoConfirm::setModal(bool val){ - bModal = val; -} -void WDecoConfirm::setData(){ - if(!it) - return; - - it->setData(); -} - -bool WDecoConfirm::Leaving(u32 key){ - if(!it) - return true; - - //Choice must be confirmed. - if(mState == OP_UNCONFIRMED){ - if(!isModal()) - setModal(true); - if(!it->Changed()) - mState = OP_CONFIRMED; - else - mState = OP_CONFIRMING; - } - - if(mState == OP_CONFIRMED && it->Leaving(key)){ - setFocus(false); - setModal(false); - SAFE_DELETE(confirmMenu); - return true; - } - - return false; -} -bool WDecoConfirm::CheckUserInput(u32 key){ - if(hasFocus()){ - if (mState == OP_CONFIRMED && key == PSP_CTRL_CIRCLE) - mState = OP_UNCONFIRMED; - - if (mState != OP_CONFIRMING && it){ - if(it->CheckUserInput(key)) - return true; - } else if(confirmMenu && confirmMenu->CheckUserInput(key)) - return true; - } - return false; -} - -void WDecoConfirm::Update(float dt){ - if (hasFocus()){ - if (it && mState != OP_CONFIRMING) - it->Update(dt); - else - confirmMenu->Update(dt); - } -} - -void WDecoConfirm::Overlay(){ - if (confirmMenu && mState == OP_CONFIRMING) - confirmMenu->Render(); - - if(it) - it->Overlay(); -} - -void WDecoConfirm::ButtonPressed(int controllerId, int controlId){ - if(controllerId == 444){ - setModal(false); - switch(controlId){ - case 1: - mState = OP_CONFIRMED; - if(it) - it->confirmChange(true); - break; - case 2: - mState = OP_CONFIRMED; - if(it) - it->confirmChange(false); - break; - } - } - else - it->ButtonPressed(controllerId,controlId); -} - -WGuiButton::WGuiButton( WGuiBase* _it, int _controller, int _control, JGuiListener * jgl): WGuiDeco(_it) { - control = _control; - controller = _controller; - mListener = jgl; -} - -void WGuiButton::updateValue(){ - if(mListener) - mListener->ButtonPressed(controller, control); -} - -bool WGuiButton::CheckUserInput(u32 key){ - if (hasFocus() && key == PSP_CTRL_CIRCLE){ - updateValue(); - return true; - } - return false; -} - -PIXEL_TYPE WGuiButton::getColor(int type){ - if(type == WGuiColor::BACK && hasFocus()) - return it->getColor(WGuiColor::BACK_HEADER); - return it->getColor(type); -}; - -WGuiSplit::WGuiSplit(WGuiBase* _left, WGuiBase* _right) : WGuiItem("") { - right = _right; - left = _left; - bRight = false; - percentRight = 0.5f; - if(!left->Selectable()) - bRight = true; -} -WGuiSplit::~WGuiSplit(){ - SAFE_DELETE(left); - SAFE_DELETE(right); -} - -void WGuiSplit::setData(){ - left->setData(); - right->setData(); -} -void WGuiSplit::setX(float _x){ - x = _x; - left->setX(x); - right->setX(x+(1-percentRight)*width); -} -void WGuiSplit::setY(float _y){ - y = _y; - left->setY(y); - right->setY(y); -} -void WGuiSplit::setWidth(float _w){ - width = _w; - if(right->Visible()) - left->setWidth((1-percentRight)*width); - else - left->setWidth(width); - - right->setWidth(percentRight*width); -} -void WGuiSplit::setHeight(float _h){ - left->setHeight(_h); - right->setHeight(_h); - height = _h; -} -float WGuiSplit::getHeight(){ - float lH, rH; - lH = left->getHeight(); - rH = right->getHeight(); - if(lH > rH) - return lH; - - return rH; -} - -void WGuiSplit::Render(){ - if(right->Visible()) - right->Render(); - if(left->Visible()) - left->Render(); -} - -bool WGuiSplit::isModal(){ - if(bRight) - return right->isModal(); - - return left->isModal(); -} -void WGuiSplit::setModal(bool val){ - if(bRight) - return right->setModal(val); - - return left->setModal(val); -} - -bool WGuiSplit::CheckUserInput(u32 key){ - if(hasFocus()){ - if (!bRight){ - if(key == PSP_CTRL_RIGHT && !isModal() - && right->Selectable() && left->Leaving(PSP_CTRL_RIGHT)){ - bRight = !bRight; - right->Entering(PSP_CTRL_RIGHT); - return true; - } - if(left->CheckUserInput(key)) - return true; - } - else - { - if (key == PSP_CTRL_LEFT && !isModal() - && left->Selectable() && right->Leaving(PSP_CTRL_LEFT)){ - bRight = !bRight; - left->Entering(PSP_CTRL_LEFT); - return true; - } - } - if(right->CheckUserInput(key)) - return true; - } - - return false; -} - -void WGuiSplit::Update(float dt){ - if(bRight) - right->Update(dt); - else - left->Update(dt); -} - -void WGuiSplit::Entering(u32 key){ - mFocus = true; - if(bRight) - right->Entering(key); - else - left->Entering(key); -} -bool WGuiSplit::Leaving(u32 key){ - - if(bRight){ - if(right->Leaving(key)){ - mFocus = false; - return true; - } - } - else{ - if(left->Leaving(key)){ - mFocus = false; - return true; - } - } - - return false; -} -void WGuiSplit::Overlay(){ - if(bRight) - right->Overlay(); - else - left->Overlay(); -} -void WGuiSplit::Underlay(){ - if(bRight) - right->Underlay(); - else - left->Underlay(); -} -void WGuiSplit::ButtonPressed(int controllerId, int controlId) -{ - if(bRight) - right->ButtonPressed(controllerId, controlId); - else - left->ButtonPressed(controllerId, controlId); -} -void WGuiSplit::Reload(){ - left->Reload(); - right->Reload(); -} -void WGuiSplit::confirmChange(bool confirmed){ - right->confirmChange(confirmed); - left->confirmChange(confirmed); -} - -//WGuiMenu -WGuiMenu::WGuiMenu(u32 next = PSP_CTRL_RIGHT, u32 prev = PSP_CTRL_LEFT): WGuiItem(""){ - buttonNext = next; - buttonPrev = prev; - 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(); -}; - -void WGuiMenu::Reload(){ - for(vector::iterator it = items.begin();it!=items.end();it++) - (*it)->Reload(); -}; - -void WGuiMenu::Render(){ - for(vector::iterator it = items.begin();it!=items.end();it++) - (*it)->Render(); -} -void WGuiMenu::confirmChange(bool confirmed){ - for(vector::iterator it = items.begin();it!=items.end();it++) - (*it)->confirmChange(confirmed); -} - -void WGuiMenu::ButtonPressed(int controllerId, int controlId){ - WGuiBase * it = Current(); - if(!it) return; - it->ButtonPressed(controllerId,controlId); -} - -WGuiBase * WGuiMenu::Current(){ - if(currentItem >= 0 && currentItem < (int) items.size()) - return items[currentItem]; - return NULL; -} -void WGuiMenu::Add(WGuiBase * it){ - if(it) - items.push_back(it); -} - - -bool WGuiMenu::CheckUserInput(u32 key){ - bool kidModal = false; - bool handledInput = false; - int nbitems = (int) items.size(); - JGE * mEngine = JGE::GetInstance(); - - if(!mEngine->GetButtonState(held)) //Key isn't held down. - held = 0; - - if(currentItem >= 0 && currentItem < nbitems) - kidModal = items[currentItem]->isModal(); - - if(!kidModal && hasFocus()){ - if (key == buttonPrev){ - held = buttonPrev; - duration = 0; - if(prevItem()) - return true; - } - else if(held == buttonPrev && duration > 1){ - duration = .92; - if(prevItem()) - return true; - } - else if (key == buttonNext){ - held = buttonNext; - duration = 0; - if(nextItem()) - return true; - } - else if(held == buttonNext && duration > 1){ - duration = .92; - if(nextItem()) - return true; - } - } - - if(currentItem >= 0 && currentItem < nbitems) - return items[currentItem]->CheckUserInput(key); - - return false; -} - -void WGuiMenu::Update(float dt){ - int nbitems = (int) items.size(); - JGE * mEngine = JGE::GetInstance(); - - if(held) - duration += dt; - - if(currentItem >= 0 && currentItem < nbitems) - items[currentItem]->Update(dt); - - for (int i = 0 ; i < nbitems; i++){ - if(i != currentItem) - items[i]->Update(dt); - } -} - -bool 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); - return true; - } - } - return false; -} - -bool 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); - return true; - } - } - return false; -} - -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(it->getY()+35); - it->setHeight(it->getHeight()-35); - WGuiMenu::Add(it); - } -} - -void WGuiTabMenu::Render(){ - JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); - JRenderer * renderer = JRenderer::GetInstance(); - - if (!items.size()) - return; - - int offset = x; - - for(vector::iterator it = items.begin();it!=items.end();it++){ - int w = mFont->GetStringWidth(_((*it)->getDisplay()).c_str()); - mFont->SetColor((*it)->getColor(WGuiColor::TEXT_TAB)); - renderer->FillRoundRect(offset+5,5,w + 5,25,2,(*it)->getColor(WGuiColor::BACK_TAB)); - mFont->DrawString(_((*it)->getDisplay()).c_str(),offset+10,10); - offset += w + 10 + 2; - } - - WGuiBase * c = Current(); - if(c) - c->Render(); -} - -void WGuiTabMenu::save(){ - confirmChange(true); - setData(); - ::options.save(); -} - - -//WGuiAward -void WGuiAward::Overlay(){ - JRenderer * r = JRenderer::GetInstance(); - JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); - mFont->SetScale(.8); - mFont->SetColor(getColor(WGuiColor::TEXT)); - - string s = details; - if(s.size()){ - float fW = mFont->GetStringWidth(s.c_str()); - float fH = mFont->GetHeight(); - - if(fH < 16) - fH = 18; - JQuad * button = resources.RetrieveQuad("iconspsp.png", (float)4*32, 0, 32, 32,"",RETRIEVE_NORMAL); - - r->FillRoundRect(5,10,fW+32,fH+2,2,getColor(WGuiColor::BACK)); - if(button) - r->RenderQuad(button, 10,12,0,.5,.5); - mFont->DrawString(s,30,16); - } - - mFont->SetScale(1); -} -void WGuiAward::Underlay(){ - 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-trophy->mHeight); - } - -} -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, string _details): WGuiItem(name){ - id = _id; - text = _text; - height = 60; - details = _details; -} -WGuiAward::~WGuiAward(){ - GameOptionAward * goa = dynamic_cast(&options[id]); - if(goa) - goa->setViewed(true); -} -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; -} - -bool WCSortAlpha::operator()(const MTGCard*l, const MTGCard*r){ - if(!l || !r || !l->data || !r->data) - return false; - string ln = l->data->getLCName(); - string rn = r->data->getLCName(); - return (ln < rn); -} -bool WCSortCollector::operator()(const MTGCard*l, const MTGCard*r){ - if(!l || !r || !l->data || !r->data) - return false; - - int lc, rc; - lc = l->data->countColors(); rc = r->data->countColors(); - if(lc == 0) lc = 999; - if(rc == 0) rc = 999; - - int isW = (int)l->data->hasColor(Constants::MTG_COLOR_WHITE) - (int) r->data->hasColor(Constants::MTG_COLOR_WHITE); - int isU = (int)l->data->hasColor(Constants::MTG_COLOR_BLUE) - (int) r->data->hasColor(Constants::MTG_COLOR_BLUE); - int isB = (int)l->data->hasColor(Constants::MTG_COLOR_BLACK) - (int) r->data->hasColor(Constants::MTG_COLOR_BLACK); - int isR = (int)l->data->hasColor(Constants::MTG_COLOR_RED) - (int) r->data->hasColor(Constants::MTG_COLOR_RED); - int isG = (int)l->data->hasColor(Constants::MTG_COLOR_GREEN) - (int) r->data->hasColor(Constants::MTG_COLOR_GREEN); - int isArt = (int)l->data->hasType(Subtypes::TYPE_ARTIFACT) - (int) r->data->hasType(Subtypes::TYPE_ARTIFACT); - int isLand = (int)l->data->hasType(Subtypes::TYPE_LAND) - (int) r->data->hasType(Subtypes::TYPE_LAND); - - //Nested if hell. TODO: Farm these out to their own objects as a user-defined filter/sort system. - if(!isLand){ - int isBasic = (int)l->data->hasType("Basic") - (int) r->data->hasType("Basic"); - if(!isBasic){ - if(!isArt){ - if(lc == rc){ - if(!isG){ - if(!isR){ - if(!isB){ - if(!isU){ - if(!isW){ - string ln = l->data->getLCName(); - string rn = r->data->getLCName(); - if(ln.substr(0,4) == "the ") - ln = ln.substr(4); - if(rn.substr(0,4) == "the ") - rn = rn.substr(4); - return (ln < rn); - } - return (isW < 0); - } - return (isU < 0); - } - return (isB < 0); - } - return (isR < 0); - } - return (isG < 0); - } - return (lc < rc); - } - return (isArt < 0); - } - else return(isBasic < 0); - } - return (isLand < 0); -} -//WSrcMTGSet -WSrcMTGSet::WSrcMTGSet(int setid, float delay){ - MTGAllCards * ac = GameApp::collection; - map::iterator it; - mDelay = delay; - mLastInput = 0; - - for(it = ac->collection.begin();it != ac->collection.end();it++){ - if(it->second->setId == setid && it->second->getId() >= 0) - cards.push_back(it->second); - } - - std::sort(cards.begin(),cards.end(),WCSortCollector()); - - currentCard = -1; - if(cards.size()) - currentCard = 0; -} -JQuad * WSrcMTGSet::getImage(){ -#if defined WIN32 || defined LINUX //Loading delay only on PSP. -#else - if(mDelay && mLastInput < mDelay){ - return resources.RetrieveCard(getCard(),RETRIEVE_EXISTING); - } -#endif - - return resources.RetrieveCard(getCard()); -} -void WSrcMTGSet::Update(float dt){ - mLastInput += dt; -} -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; - - mLastInput = 0; - return true; -} - -bool WSrcMTGSet::prev(){ - if(currentCard > 0) - currentCard--; - else - return false; - - mLastInput = 0; - return true; -} - -bool WSrcMTGSet::setPos(int pos){ - if(pos < 0 || pos >= (int) cards.size()) - return false; - - currentCard = pos; - mLastInput = 0; - 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 deleted file mode 100644 index 75e8cc32e..000000000 --- a/projects/mtg/src/ShopItem.cpp +++ /dev/null @@ -1,554 +0,0 @@ -#include "../include/config.h" -#include "../include/ShopItem.h" -#include "../include/GameStateShop.h" -#include "../include/CardGui.h" -#include "../include/WResourceManager.h" -#include "../include/Translate.h" -#include - - - - float ShopItems::_x1[] = { 79, 19, 27,103,154,187,102,144,198,133,183}; - float ShopItems::_y1[] = {150,194,222,167,164,156,195,190,175,220,220}; - - float ShopItems::_x2[] = {103, 48, 74,135,183,215,138,181,231,171,225}; - float ShopItems::_y2[] = {155,179,218,165,166,155,195,186,177,225,216}; - - float ShopItems::_x3[] = { 48, 61, 9, 96,139,190, 81,146,187, 97,191}; - float ShopItems::_y3[] = {164,205,257,184,180,170,219,212,195,251,252}; - - float ShopItems::_x4[] = { 76, 90, 65,131,171,221,123,187,225,141,237}; - float ShopItems::_y4[] = {169,188,250,182,182,168,220,208,198,259,245}; - - -ShopItem::ShopItem(int id, JLBFont *font, char* text, JQuad * _quad,JQuad * _thumb, float _xy[], bool hasFocus, int _price): JGuiObject(id), mFont(font), mText(text), quad(_quad), thumb(_thumb), price(_price) -{ - for (int i = 0; i < 8; ++i){ - xy[i] = _xy[i]; - } - quantity = 10; - card = NULL; - mHasFocus = hasFocus; - mRelease = false; - - mScale = 1.0f; - mTargetScale = 1.0f; - - mesh=NEW hgeDistortionMesh(2,2); - mesh->SetTexture(thumb->mTex); - float x0,y0,w0,h0; - thumb->GetTextureRect(&x0,&y0,&w0,&h0); - mesh->SetTextureRect(x0,y0,w0,h0); - mesh->Clear(ARGB(0xFF,0xFF,0xFF,0xFF)); - mesh->SetDisplacement(0, 0, xy[0],xy[1], HGEDISP_NODE); - mesh->SetDisplacement(1, 0, xy[2] - w0,xy[3], HGEDISP_NODE); - mesh->SetDisplacement(0, 1,xy[4],xy[5]-h0, HGEDISP_NODE); - mesh->SetDisplacement(1, 1, xy[6]-w0,xy[7]-h0, HGEDISP_NODE); - mesh->SetColor(1,1,ARGB(255,100,100,100)); - mesh->SetColor(0,1,ARGB(255,100,100,100)); - mesh->SetColor(1,0,ARGB(255,100,100,100)); - mesh->SetColor(0,0,ARGB(255,200,200,200)); - if (hasFocus) - Entering(); -} - -ShopItem::ShopItem(int id, JLBFont *font, int _cardid, float _xy[], bool hasFocus, MTGAllCards * collection, int _price, DeckDataWrapper * ddw): JGuiObject(id), mFont(font), price(_price){ - for (int i = 0; i < 8; ++i){ - xy[i] = _xy[i]; - } - mHasFocus = hasFocus; - mRelease = false; - mScale = 1.0f; - mTargetScale = 1.0f; - - if (hasFocus) - Entering(); - - card = collection->getCardById(_cardid); - updateCount(ddw); - - quantity = 1 + (rand() % 4); - if (card->getRarity() == Constants::RARITY_L) quantity = 50; - quad = NULL; - - mesh = NULL; - thumb = NULL; - updateThumb(); -} - - -int ShopItem::updateCount(DeckDataWrapper * ddw){ - if (!card) return 0; - nameCount = ddw->countByName(card); - return nameCount; -} - -ShopItem::~ShopItem(){ - OutputDebugString("delete shopitem\n"); - if(thumb) - resources.Release(thumb->mTex); - SAFE_DELETE(mesh); -} - -const char * ShopItem::getText(){ - return mText.c_str(); -} - -void ShopItem::updateThumb(){ - if(card == NULL) - return; - - if(thumb && mRelease) - resources.Release(thumb->mTex); - mRelease = false; - - if(mesh) - SAFE_DELETE(mesh); - else if(thumb) - SAFE_DELETE(thumb); - - thumb = resources.RetrieveCard(card,RETRIEVE_LOCK,TEXTURE_SUB_THUMB); -#if defined (WIN32) || defined (LINUX) - //On pcs we render the big image if the thumbnail is not available - if (!thumb) thumb = resources.RetrieveCard(card,RETRIEVE_LOCK); -#endif - if (!thumb) - thumb = CardGui::alternateThumbQuad(card); - else - mRelease = true; - - - if (thumb){ - mesh=NEW hgeDistortionMesh(2,2); - mesh->SetTexture(thumb->mTex); - float x0,y0,w0,h0; - thumb->GetTextureRect(&x0,&y0,&w0,&h0); - mesh->SetTextureRect(x0,y0,w0,h0); - mesh->Clear(ARGB(0xFF,0xFF,0xFF,0xFF)); - mesh->SetDisplacement(0, 0, xy[0],xy[1], HGEDISP_NODE); - mesh->SetDisplacement(1, 0, xy[2] - w0,xy[3], HGEDISP_NODE); - mesh->SetDisplacement(0, 1,xy[4],xy[5]-h0, HGEDISP_NODE); - mesh->SetDisplacement(1, 1, xy[6]-w0,xy[7]-h0, HGEDISP_NODE); - mesh->SetColor(1,1,ARGB(255,100,100,100)); - mesh->SetColor(0,1,ARGB(255,100,100,100)); - mesh->SetColor(1,0,ARGB(255,100,100,100)); - mesh->SetColor(0,0,ARGB(255,200,200,200)); - }else{ - mesh = NULL; - } -} - -void ShopItem::Render(){ - if (mHasFocus){ - mFont->SetColor(ARGB(255,255,255,0)); - }else{ - mFont->SetColor(ARGB(255,255,255,255)); - } - if (!quantity){ - mFont->SetColor(ARGB(255,128,128,128)); - } - - if (card){ - if (nameCount){ - char buffer[512]; - sprintf(buffer, "%s (%i)", _(card->data->name).c_str(), nameCount ); - mText = buffer; - }else{ - mText = _(card->data->name).c_str(); - } - } - - JRenderer * renderer = JRenderer::GetInstance(); - - if (mesh){ - mesh->Render(0,0); - }else{ - //ERROR Management - } - if (mHasFocus){ - if (card) quad = resources.RetrieveCard(card); - if (quad){ - float scale = 0.9 * 285/ quad->mHeight; - quad->SetColor(ARGB(255,255,255,255)); - renderer->RenderQuad(quad,SCREEN_WIDTH - 105,SCREEN_HEIGHT/2 - 5,0, scale,scale); - }else{ - if (card) CardGui::alternateRender(card,Pos(SCREEN_WIDTH - 105,SCREEN_HEIGHT/2 - 5,0.9f* 285/250, 0,255)); - - } - } -} - -void ShopItem::Update(float dt) -{ - if (mScale < mTargetScale){ - mScale += 8.0f*dt; - if (mScale > mTargetScale) - mScale = mTargetScale; - }else if (mScale > mTargetScale){ - mScale -= 8.0f*dt; - if (mScale < mTargetScale) - mScale = mTargetScale; - } -} - - - - -void ShopItem::Entering() -{ - for (int i = 0; i < 2; ++i){ - for (int j = 0; j < 2; ++j){ - mesh->SetColor(i,j,ARGB(255,255,255,255)); - } - } - - - mHasFocus = true; - mTargetScale = 1.2f; -} - - -bool ShopItem::Leaving(u32 key) -{ - mesh->SetColor(1,1,ARGB(255,100,100,100)); - mesh->SetColor(0,1,ARGB(255,100,100,100)); - mesh->SetColor(1,0,ARGB(255,100,100,100)); - mesh->SetColor(0,0,ARGB(255,200,200,200)); - - mHasFocus = false; - mTargetScale = 1.0f; - return true; -} - - -bool ShopItem::ButtonPressed() -{ - return (quantity >0); -} - - -ShopItems::ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y, MTGAllCards * _collection, int _setIds[]): JGuiController(id, listener), mX(x), mY(y), mFont(font), collection(_collection){ - mHeight = 0; - showPriceDialog = -1; - dialog = NULL; - pricelist = NEW PriceList(RESPATH"/settings/prices.dat",_collection); - playerdata = NEW PlayerData(_collection); - display = NULL; - for (int i=0; i < SHOP_BOOSTERS; i++){ - setIds[i] = _setIds[i]; - }; - myCollection = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), _collection)); - showCardList = true; - - mBgAA = NULL; - mBgAATex = resources.RetrieveTexture("shop_aliasing.png",RETRIEVE_LOCK); - if(mBgAATex){ - mBgAA = resources.RetrieveQuad("shop_aliasing.png"); - mBgAA->SetTextureRect(0,1,250,119); - } - - lightAlpha = 0; - alphaChange = 0; -} - - - -void ShopItems::Add(int cardid){ - int rnd = (rand() % 20); - int price = pricelist->getPrice(cardid); - price = price + price * (rnd -10)/100; - float xy[] = {_x1[mCount],_y1[mCount],_x2[mCount],_y2[mCount],_x3[mCount],_y3[mCount],_x4[mCount],_y4[mCount]}; - JGuiController::Add(NEW ShopItem(mCount, mFont, cardid, xy, (mCount == 0),collection, price,myCollection)); - mHeight += 22; -} - -void ShopItems::Add(char * text, JQuad * quad,JQuad * thumb, int price){ - float xy[] = {_x1[mCount],_y1[mCount],_x2[mCount],_y2[mCount],_x3[mCount],_y3[mCount],_x4[mCount],_y4[mCount]}; - JGuiController::Add(NEW ShopItem(mCount, mFont, text, quad, thumb, xy, (mCount == 0), price)); - mHeight += 22; -} - -void ShopItems::Update(float dt){ - - if (display){ - display->Update(dt); - }else{ - if (showPriceDialog!=-1){ - ShopItem * item = ((ShopItem *)mObjects[showPriceDialog]); - int price = item->price; - char buffer[4096]; - sprintf(buffer,"%s : %i credits",item->getText(),price); - if(!dialog){ - dialog = NEW SimpleMenu(1,this,Constants::MENU_FONT,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,buffer); - dialog->Add(1,"Yes"); - dialog->Add(2,"No"); - if(options[Options::CHEATMODE].number) { - dialog->Add(3,"*Steal 1,000 credits*"); - } - } - else{ - dialog->Update(dt); - } - }else{ - SAFE_DELETE(dialog); - JGuiController::Update(dt); - } - - } - - alphaChange = (500 - (rand() % 1000)) * dt; - lightAlpha+= alphaChange; - if (lightAlpha < 0) lightAlpha = 0; - if (lightAlpha > 50) lightAlpha = 50; -} - - -void ShopItems::Render(){ - JGuiController::Render(); - JRenderer * r = JRenderer::GetInstance(); - - - if (mBgAA) - r->RenderQuad(mBgAA,0,SCREEN_HEIGHT-127); - - JQuad * quad = resources.RetrieveTempQuad("shop_light.jpg",TEXTURE_SUB_5551); - if (quad){ - r->EnableTextureFilter(false); - r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); - quad->SetColor(ARGB(lightAlpha,255,255,255)); - r->RenderQuad(quad,0,0); - r->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); - r->EnableTextureFilter(true); - } - - - if (display) display->Render(); - - if (showPriceDialog!=-1){ - if(dialog){ - dialog->Render(); - } - } - - mFont->SetColor(ARGB(255,255,255,255)); - char c[4096]; - r->FillRect(0,SCREEN_HEIGHT-17,SCREEN_WIDTH,17,ARGB(128,0,0,0)); - sprintf(c, "%s", _("[]:other cards").c_str()); - unsigned int len = 4 + mFont->GetStringWidth(c); - mFont->DrawString(c,SCREEN_WIDTH-len,SCREEN_HEIGHT-14); - - char credits[512]; - sprintf(credits,_("credits: %i").c_str(), playerdata->credits); - mFont->SetColor(ARGB(200,0,0,0)); - mFont->DrawString(credits, 5, SCREEN_HEIGHT - 12); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(credits, 5, SCREEN_HEIGHT - 14); - - if(mCurr >= 0){ - mFont->SetColor(ARGB(255,255,255,0)); - ShopItem * item = ((ShopItem *)mObjects[mCurr]); - mFont->DrawString(item->mText.c_str(), SCREEN_WIDTH/2 - 50, SCREEN_HEIGHT - 14,JGETEXT_CENTER); - mFont->SetColor(ARGB(255,255,255,255)); - } - - if (showCardList){ - r->FillRoundRect(290,5, 160, mCount * 20 + 15,5,ARGB(200,0,0,0)); - - for (int i = 0; i< mCount; ++i){ - if (!mObjects[i]) continue; - ShopItem * s = (ShopItem *)(mObjects[i]); - if (i == mCurr) mFont->SetColor(ARGB(255,255,255,0)); - else mFont->SetColor(ARGB(255,255,255,255)); - char buffer[512]; - sprintf(buffer, "%s", s->getText()); - float x = 300; - float y = 10 + 20*i; - mFont->DrawString(buffer,x,y); - } - } -} - -void ShopItems::pricedialog(int id, int mode){ - if (mode){ - showPriceDialog = id; - }else{ - showPriceDialog = -1; - } -} - -void ShopItems::ButtonPressed(int controllerId, int controlId){ - if (controllerId == 12){ - safeDeleteDisplay(); - return; - } - - ShopItem * item = ((ShopItem *)mObjects[showPriceDialog]); - int price = item->price; - switch(controlId){ - case 1: - if (playerdata->credits >= price){ - playerdata->credits -= price; - if (item->card){ - int rnd = (rand() % 25); - price = price + (rnd * price)/100; - pricelist->setPrice(item->card->getMTGId(),price); - playerdata->collection->add(item->card); - item->quantity--; - myCollection->Add(item->card); - item->nameCount++; - item->price = price; - }else{ - safeDeleteDisplay(); - display = NEW CardDisplay(12,NULL, SCREEN_WIDTH - 200, SCREEN_HEIGHT/2,this,NULL,5); - - MTGDeck * tempDeck = NEW MTGDeck(playerdata->collection->database); - int rare_or_mythic = Constants::RARITY_R; - int rnd = rand() % 8; - if (rnd == 0) rare_or_mythic = Constants::RARITY_M; - int sets[] = {setIds[showPriceDialog]}; - MTGSetInfo* si = setlist.getInfo(setIds[showPriceDialog]); - - tempDeck->addRandomCards(si->booster[MTGSetInfo::RARE], sets,1,rare_or_mythic); - tempDeck->addRandomCards(si->booster[MTGSetInfo::UNCOMMON], sets,1,Constants::RARITY_U); - tempDeck->addRandomCards(si->booster[MTGSetInfo::COMMON], sets,1,Constants::RARITY_C); - tempDeck->addRandomCards(si->booster[MTGSetInfo::LAND], sets,1,Constants::RARITY_L); - - //Check for duplicates. Does not guarentee none, just makes them extremely unlikely. - //Code is kind of inefficient, but shouldn't be used often enough to matter. - int loops=0; - for(map::iterator it = tempDeck->cards.begin();it!= tempDeck->cards.end() && loops < 15;it++,loops++){ - int dupes = it->second - 1; - if(dupes <= 0) - continue; - - for(int x=0;xremove(it->first); - - int rarity = (int) tempDeck->database->getCardById(it->first)->getRarity(); - tempDeck->addRandomCards(dupes,sets,1,rarity); - it = tempDeck->cards.begin(); - } - - playerdata->collection->add(tempDeck); - myCollection->Add(tempDeck); - - for (int j = 0; j < mCount; j++){ - ShopItem * si = ((ShopItem *)mObjects[j]); - si->updateCount(myCollection); - } - - int i = 0; - for(int cycle=0;cycle<4;cycle++) - for (map::iterator it = tempDeck->cards.begin(); it!=tempDeck->cards.end(); it++){ - MTGCard * c = tempDeck->getCardById(it->first); - char rarity = c->getRarity(); - if((cycle == 0 && rarity == Constants::RARITY_L) - || (cycle == 1 && rarity == Constants::RARITY_C) - || (cycle == 2 && rarity == Constants::RARITY_U) - || (cycle == 3 && (rarity == Constants::RARITY_R || rarity == Constants::RARITY_M))) - for (int j = 0; j < it->second; j++){ - MTGCardInstance * card = NEW MTGCardInstance(c, NULL); - displayCards[i] = card; - display->AddCard(card); - i++; - } - } - delete tempDeck; - } - //Check if we just scored an award... - if(myCollection && myCollection->totalPrice() > 10000){ - GameOptionAward * goa = dynamic_cast(&options[Options::AWARD_COLLECTOR]); - if(goa) - goa->giveAward(); - } - showPriceDialog = -1; - }else{ - //error not enough money - } - break; - case 2: - if (item->card){ - int rnd = (rand() % 25); - price = price - (rnd * price)/100; - pricelist->setPrice(item->card->getMTGId(),price); - } - showPriceDialog = -1; - break; - case 3: // (PSY) Cheatmode: get free money - playerdata->credits += 1000; - break; - } -} - - -void ShopItems::safeDeleteDisplay(){ - if (!display) return; - for (int i = 0; i < display->mCount; i++){ - delete displayCards[i]; - } - SAFE_DELETE(display); -} - -void ShopItems::saveAll(){ - savePriceList(); - playerdata->save(); -} - -void ShopItems::savePriceList(){ - pricelist->save(); -} - -ShopItems::~ShopItems(){ - SAFE_DELETE(pricelist); - SAFE_DELETE(playerdata); - SAFE_DELETE(dialog); - safeDeleteDisplay(); - SAFE_DELETE(myCollection); - resources.Release(mBgAATex); -} - -ostream& ShopItem::toString(ostream& out) const -{ - return out << "ShopItem ::: mHasFocus : " << mHasFocus - << " ; mFont : " << mFont - << " ; mText : " << mText - << " ; quad : " << quad - << " ; thumb : " << thumb - << " ; mScale : " << mScale - << " ; mTargetScale : " << mTargetScale - << " ; nameCount : " << nameCount - << " ; quantity : " << quantity - << " ; card : " << card - << " ; price : " << price; -} - -bool ShopItems::CheckUserInput(u32 key){ - if (display && display->CheckUserInput(key)) - return true; - if(showPriceDialog==-1){ - u32 buttons[] = {PSP_CTRL_LEFT,PSP_CTRL_DOWN,PSP_CTRL_RIGHT,PSP_CTRL_UP,PSP_CTRL_CIRCLE}; - for (int i = 0; i < 5; ++i){ - if (key == buttons[i]) - showCardList = false; - } - - if(key == PSP_CTRL_TRIANGLE){ - options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; - vector::iterator it; - for(it=mObjects.begin();it!=mObjects.end();it++){ - ShopItem * si = dynamic_cast(*it); - if(si) - si->updateThumb(); - } - return true; - } - if (key == PSP_CTRL_CROSS){ - showCardList = !showCardList; - return true; - } - } - else if(dialog) - return dialog->CheckUserInput(key); - - return JGuiController::CheckUserInput(key); -} diff --git a/projects/mtg/src/Tasks.cpp b/projects/mtg/src/Tasks.cpp index 1bc622cc3..f1ef332ac 100644 --- a/projects/mtg/src/Tasks.cpp +++ b/projects/mtg/src/Tasks.cpp @@ -164,8 +164,6 @@ void Task::loadAIDeckNames() { while (found){ found = 0; char buffer[512]; - char smallDeckName[512]; - char deckDesc[512]; sprintf(buffer, "%s/deck%i.txt",RESPATH"/ai/baka",nbDecks + 1); if(fileExists(buffer)){ diff --git a/projects/mtg/src/WDataSrc.cpp b/projects/mtg/src/WDataSrc.cpp new file mode 100644 index 000000000..6d78dc106 --- /dev/null +++ b/projects/mtg/src/WDataSrc.cpp @@ -0,0 +1,490 @@ +#include "../include/config.h" +#include "../include/OptionItem.h" +#include "../include/PlayerData.h" +#include "../include/Translate.h" +#include "../include/PriceList.h" +#include "../include/Subtypes.h" +#include + +//WSyncable +bool WSyncable::Hook(WSyncable* s){ + if(hooked) + return false; + hooked = s; + return true; +} +int WSyncable::getPos(){ + if(hooked) + return hooked->getPos()+currentPos; + return currentPos; +} +bool WSyncable::next(){ + if(hooked) + return hooked->next(); + ++currentPos; + return true; +} +bool WSyncable::prev(){ + if(hooked) + return hooked->prev(); + --currentPos; + return true; +} + +//WSrcImage +JQuad * WSrcImage::getImage( int offset){ + return resources.RetrieveTempQuad(filename); +} + +WSrcImage::WSrcImage(string s){ + filename = s; +} +//WSrcCards +WSrcCards::WSrcCards(float delay){ + mDelay = delay; + mLastInput = 0; + currentPos = 0; + filtersRoot=NULL; +} +JQuad * WSrcCards::getImage( int offset){ +#if defined WIN32 || defined LINUX //Loading delay only on PSP. +#else + if(mDelay && mLastInput < mDelay){ + return resources.RetrieveCard(getCard(offset),RETRIEVE_EXISTING); + } +#endif + + return resources.RetrieveCard(getCard(offset)); +} +JQuad * WSrcCards::getThumb( int offset){ + return resources.RetrieveCard(getCard(offset),RETRIEVE_THUMB); +} +WSrcCards::~WSrcCards(){ + clearFilters(); + cards.clear(); +} +void WSrcCards::bakeFilters(){ + vector temp; + + setOffset(0); + for(int t=0;tisMatch(c); +} +int WSrcCards::Size(bool all){ + if(!all && filtersRoot) + return (int) validated.size(); + return (int) cards.size(); +} +MTGCard * WSrcCards::getCard(int offset, bool ignore){ + int oldpos; + int size = (int) cards.size(); + MTGCard * c = NULL; + if(!ignore && filtersRoot) + size = (int) validated.size(); + + if(!size) + return NULL; + + oldpos = currentPos; + if(offset != 0) + currentPos += offset; + while(currentPos < 0) + currentPos = size+currentPos; + currentPos = currentPos % size; + + if(!ignore && filtersRoot) + c = cards[validated[currentPos]]; + else + c = cards[currentPos]; + currentPos = oldpos; + return c; +} +int WSrcCards::loadMatches(MTGAllCards* ac){ + map::iterator it; + int count = 0; + if(!ac) + return count; + + for(it=ac->collection.begin();it!=ac->collection.end();it++){ + if(it->second && (matchesFilters(it->second))){ + cards.push_back(it->second); + count++; + } + } + validateFilters(); + return count; +} +int WSrcCards::loadMatches(MTGDeck * deck){ + map::iterator it; + int count = 0; + if(!deck) + return count; + for(it=deck->cards.begin();it!=deck->cards.end();it++){ + MTGCard * c = deck->getCardById(it->first); + if(c && (matchesFilters(c))){ + cards.push_back(c); + count++; + } + } + validateFilters(); + return count; +} +int WSrcCards::loadMatches(WSrcCards* src, bool all){ + int count = 0; + if(!src) + return count; + + MTGCard * c = NULL; + size_t t = 0; + int oldp = src->getOffset(); + src->setOffset(0); + for(int t=0;tSize(all);t++){ + c = src->getCard(t,all); + if(matchesFilters(c)){ + cards.push_back(c); + count++; + } + } + src->setOffset(oldp); + validateFilters(); + return count; +} +int WSrcCards::addToDeck(MTGDeck * i, int num){ + int oldpos = getOffset(); + int added = 0; + int cycles = 0; + + if(!i){ + if(num < 0) + return 0; + return num; + } + + setOffset(0); + if(num < 0){ //Add it all; + MTGCard * c; + for(;;){ + c = getCard(); + if(!c || !next()) + break; + i->add(c); + } + }else while(added < num){ + MTGCard * c = getCard(); + if(!next() || !c){ + if(++cycles == WSrcCards::MAX_CYCLES){ //Abort the search, too many cycles. + setOffset(oldpos); + return num - added; + } + setOffset(0); + continue; + }else{ + i->add(c); + added++; + } + } + setOffset(oldpos); + return 0; +} +bool WSrcCards::next(){ + int oldpos = currentPos; + bool bMatch = true; + int size = (int)cards.size(); + if(filtersRoot) + size = (int)validated.size(); + if(currentPos+1 >= size) + return false; + currentPos++; + return true; +} + +bool WSrcCards::prev(){ + int oldpos = currentPos; + bool bMatch = true; + if(currentPos == 0) + return false; + + currentPos--; + return true; +} + +bool WSrcCards::setOffset(int pos){ + if(pos < 0 || pos >= (int) cards.size()) + return false; + + currentPos = pos; + if(!matchesFilters(cards[currentPos])) + return next(); + + return true; +} +void WSrcCards::Shuffle(){ + vector a; + MTGCard * temp; + vector::iterator k; + + while(cards.size()){ + k = cards.begin(); + k += rand() % cards.size(); + temp = *k; + cards.erase(k); + a.push_back(temp); + } +#if defined WIN32 || defined LINUX //PC performs a double shuffle for less streaking. + while(a.size()){ + k = a.begin(); + k += rand() % a.size(); + temp = *k; + a.erase(k); + cards.push_back(temp); + } +#else //PSP does a straight swap for speed. + cards.swap(a); +#endif + validateFilters(); +} +void WSrcCards::validateFilters(){ + validated.clear(); + for(size_t t=0;tgetId() == mtgid){ + currentPos = (int) t; + return matchesFilters(cards[currentPos]); + } + } + return false; +} + +void WSrcCards::addFilter(WCardFilter * f) { + if(filtersRoot == NULL) + filtersRoot = f; + else + filtersRoot = NEW WCFilterAND(f,filtersRoot); + validateFilters(); + currentPos = 0; +} +float WSrcCards::filterFee(){ + if(filtersRoot) + return filtersRoot->filterFee(); + return 0; +}; +void WSrcCards::clearFilters() { + SAFE_DELETE(filtersRoot); + validated.clear(); +} + +void WSrcCards::Sort(int method){ + switch(method){ + case SORT_COLLECTOR: + std::sort(cards.begin(),cards.end(),WCSortCollector()); + break; + case SORT_ALPHA: + default: + std::sort(cards.begin(),cards.end(),WCSortAlpha()); + break; + } + validateFilters(); +} +//WSrcUnlockedCards +WSrcUnlockedCards::WSrcUnlockedCards(float delay): WSrcCards(mDelay){ + MTGAllCards * ac = GameApp::collection; + map::iterator it; + + char * unlocked = NULL; + unlocked = (char *)calloc(setlist.size(),sizeof(char)); + //Figure out which sets are available. + for (int i = 0; i < setlist.size(); i++){ + unlocked[i] = options[Options::optionSet(i)].number; + } + + for(it=ac->collection.begin();it!=ac->collection.end();it++){ + if(it->second && unlocked[it->second->setId]) + cards.push_back(it->second); + } + if(unlocked){ + free(unlocked); + unlocked = NULL; + } + + + if(cards.size()){ + Shuffle(); + currentPos = 0; + } +} + +//WSrcDeck +int WSrcDeck::loadMatches(MTGDeck * deck){ + map::iterator it; + int count = 0; + if(!deck) + return count; + for(it=deck->cards.begin();it!=deck->cards.end();it++){ + MTGCard * c = deck->getCardById(it->first); + if(c && matchesFilters(c)){ + Add(c,it->second); + count++; + } + } + validateFilters(); + return count; +} + +int WSrcDeck::Add(MTGCard * c, int quantity){ + if(!c) + return 0; + if(copies.find(c->getMTGId()) == copies.end()) + cards.push_back(c); //FIXME Make sure these two stay synced. + copies[c->getMTGId()] += quantity; + totalCards += quantity; + return 1; +} + +int WSrcDeck::Remove(MTGCard * c, int quantity, bool erase){ + if(!c) return 0; + map::iterator it = copies.find(c->getMTGId()); + if(it == copies.end()) return 0; + int amt = it->second; + if(amt < quantity) + return 0; + amt -= quantity; + it->second = amt; + if(erase && amt == 0){ + copies.erase(it); + vector::iterator i = find(cards.begin(),cards.end(),c); + if(i != cards.end()) + cards.erase(i); + } + totalCards -= quantity; + return 1; +} + +void WSrcDeck::Rebuild(MTGDeck * d){ + d->removeAll(); + map::iterator it; + for ( it=copies.begin() ; it != copies.end(); it++ ){ + for (int i = 0; i < it->second; i++){ + d->add(it->first); + } + } +} + +int WSrcDeck::count(MTGCard * c){ + if(copies.find(c->getMTGId()) == copies.end()) + return 0; + return copies[c->getMTGId()]; +} + +int WSrcDeck::countByName(MTGCard * card, bool editions){ + string name = card->data->getLCName(); + int total = 0; + vector::iterator it; + for(it = cards.begin();it!=cards.end();it++){ + if(*it && (*it)->data->getLCName() == card->data->getLCName()){ + if(editions) + total++; + else + total += copies[card->getMTGId()]; + } + } + return total; +} + +int WSrcDeck::totalPrice(){ + int total = 0; + PriceList * pricelist = NEW PriceList(RESPATH"/settings/prices.dat",GameApp::collection); + map::iterator it; + for ( it=copies.begin() ; it != copies.end(); it++ ){ + int nb = it->second; + if (nb) total += pricelist->getPrice(it->first); + } + delete pricelist; + return total; +} + +int WSrcDeck::totalCopies(){ + return totalCards; +} +//Sorting methods: + +bool WCSortAlpha::operator()(const MTGCard*l, const MTGCard*r){ + if(!l || !r || !l->data || !r->data) + return false; + string ln = l->data->getLCName(); + string rn = r->data->getLCName(); + return (ln < rn); +} +bool WCSortCollector::operator()(const MTGCard*l, const MTGCard*r){ + if(!l || !r || !l->data || !r->data) + return false; + + if(l->setId != r->setId) + return (l->setId < r->setId); + + int lc, rc; + lc = l->data->countColors(); rc = r->data->countColors(); + if(lc == 0) lc = 999; + if(rc == 0) rc = 999; + + int isW = (int)l->data->hasColor(Constants::MTG_COLOR_WHITE) - (int) r->data->hasColor(Constants::MTG_COLOR_WHITE); + int isU = (int)l->data->hasColor(Constants::MTG_COLOR_BLUE) - (int) r->data->hasColor(Constants::MTG_COLOR_BLUE); + int isB = (int)l->data->hasColor(Constants::MTG_COLOR_BLACK) - (int) r->data->hasColor(Constants::MTG_COLOR_BLACK); + int isR = (int)l->data->hasColor(Constants::MTG_COLOR_RED) - (int) r->data->hasColor(Constants::MTG_COLOR_RED); + int isG = (int)l->data->hasColor(Constants::MTG_COLOR_GREEN) - (int) r->data->hasColor(Constants::MTG_COLOR_GREEN); + int isArt = (int)l->data->hasType(Subtypes::TYPE_ARTIFACT) - (int) r->data->hasType(Subtypes::TYPE_ARTIFACT); + int isLand = (int)l->data->hasType(Subtypes::TYPE_LAND) - (int) r->data->hasType(Subtypes::TYPE_LAND); + + //Nested if hell. TODO: Farm these out to their own objects as a user-defined filter/sort system. + if(!isLand){ + int isBasic = (int)l->data->hasType("Basic") - (int) r->data->hasType("Basic"); + if(!isBasic){ + if(!isArt){ + if(lc == rc){ + if(!isG){ + if(!isR){ + if(!isB){ + if(!isU){ + if(!isW){ + string ln = l->data->getLCName(); + string rn = r->data->getLCName(); + if(ln.substr(0,4) == "the ") + ln = ln.substr(4); + if(rn.substr(0,4) == "the ") + rn = rn.substr(4); + return (ln < rn); + } + return (isW < 0); + } + return (isU < 0); + } + return (isB < 0); + } + return (isR < 0); + } + return (isG < 0); + } + return (lc < rc); + } + return (isArt < 0); + } + else return(isBasic < 0); + } + return (isLand < 0); +} \ No newline at end of file diff --git a/projects/mtg/src/WFilter.cpp b/projects/mtg/src/WFilter.cpp new file mode 100644 index 000000000..9d01e230f --- /dev/null +++ b/projects/mtg/src/WFilter.cpp @@ -0,0 +1,329 @@ +#include "../include/config.h" +#include "../include/OptionItem.h" +#include "../include/PlayerData.h" +#include "../include/Translate.h" +#include + + +//WCFilterFactory +WCFilterFactory* WCFilterFactory::me = NULL; + +WCFilterFactory* WCFilterFactory::GetInstance() { + if(!me) + me = NEW WCFilterFactory(); + return me; +} +void WCFilterFactory::Destroy(){ + SAFE_DELETE(me); +} +size_t WCFilterFactory::findNext(string src, size_t start,char open, char close){ + int num = 0; + for(size_t x=start;xdata) + return false; + return (c->data->hasColor(color) > 0); +} +string WCFilterColor::getCode(){ + char buf[12]; + char c = '?'; + if(color < 0 || color >= Constants::MTG_NB_COLORS) + c = Constants::MTGColorChars[color]; + sprintf(buf,"color:%c;",c); + return buf; +}; +WCFilterColor::WCFilterColor(string arg){ + color = -1; + char c = tolower(arg[0]); + for(int i=0;idata) + return false; + return (c->getRarity() == rarity); +} +string WCFilterRarity::getCode(){ + char buf[64]; + const char* rarities[7] = {"any","token","land","common","uncommon","rare","mythic"}; + int x = 0; + switch(rarity){ + case 'M': x=6; break; + case 'R': x=5; break; + case 'U': x=4; break; + case 'C': x=3; break; + case 'L': x=2; break; + case 'T': x=1; break; + } + sprintf(buf,"rarity:%s;",rarities[x]); + return buf; +}; +WCFilterRarity::WCFilterRarity(string arg){ + rarity = -1; + char c = toupper(arg[0]); + switch(c){ + case 'M': + case 'R': + case 'U': + case 'C': + case 'L': + case 'T': + rarity = c; + break; + } +} +//WCFilterAbility +bool WCFilterAbility::isMatch(MTGCard * c){ + if(ability < 0) + return false; + map::iterator it = c->data->basicAbilities.find(ability); + + if(it != c->data->basicAbilities.end()){ + if(it->second > 0) + return true; + } + return false; +} +WCFilterAbility::WCFilterAbility(string arg){ + std::transform(arg.begin(),arg.end(),arg.begin(),::tolower); + for(int i = 0;i= Constants::NB_BASIC_ABILITIES) + return ""; + sprintf(buf,"ability:%s;",Constants::MTGBasicAbilities[ability]); + return buf; +}; +float WCFilterAbility::filterFee(){ + switch(ability){ + case Constants::SHROUD: + case Constants::DEATHTOUCH: + case Constants::UNBLOCKABLE: + case Constants::WITHER: + case Constants::PERSIST: + return 0.4f; + case Constants::PROTECTIONBLACK: + case Constants::PROTECTIONWHITE: + case Constants::PROTECTIONBLUE: + case Constants::PROTECTIONRED: + case Constants::PROTECTIONGREEN: + case Constants::DOUBLESTRIKE: + case Constants::LIFELINK: + return 0.35f; + case Constants::TRAMPLE: + case Constants::FLYING: + case Constants::FEAR: + case Constants::VIGILANCE: + case Constants::FIRSTSTRIKE: + return 0.3f; + case Constants::PLAINSHOME: + case Constants::SWAMPHOME: + case Constants::ISLANDHOME: + case Constants::MOUNTAINHOME: + case Constants::FORESTHOME: + return -0.1f; + case Constants::DEFENDER: + case Constants::CLOUD: + return 0.1f; + default: + return 0.2f; + } + return 0.0f; +} +//WCFilterType +bool WCFilterType::isMatch(MTGCard * c){ + return c->data->hasType(type.c_str()); +} +string WCFilterType::getCode(){ + char buf[4068]; + sprintf(buf,"type:%s;",type.c_str()); + return buf; +} +//Misc. filter code +float WCFilterAND::filterFee(){ + return lhs->filterFee() + rhs->filterFee(); +} +float WCFilterOR::filterFee(){ + if(lhs->filterFee() > rhs->filterFee()) + return lhs->filterFee(); + return rhs->filterFee(); +} +string WCFilterNOT::getCode(){ + char buf[4068]; + sprintf(buf,"{%s}",kid->getCode().c_str()); + return buf; +} +string WCFilterGROUP::getCode(){ + char buf[4068]; + sprintf(buf,"(%s)",kid->getCode().c_str()); + return buf; +} + +string WCFilterAND::getCode(){ + char buf[4068]; + sprintf(buf,"%s&%s",lhs->getCode().c_str(),rhs->getCode().c_str()); + return buf; +} +string WCFilterOR::getCode(){ + char buf[4068]; + sprintf(buf,"%s|%s",lhs->getCode().c_str(),rhs->getCode().c_str()); + return buf; +} + + +bool WCFilterOR::isMatch(MTGCard *c){ + if(lhs->isMatch(c)) + return true; + if(rhs->isMatch(c)) + return true; + return false; +}; \ No newline at end of file diff --git a/projects/mtg/src/WGui.cpp b/projects/mtg/src/WGui.cpp new file mode 100644 index 000000000..cee3cb5f2 --- /dev/null +++ b/projects/mtg/src/WGui.cpp @@ -0,0 +1,1624 @@ +#include "../include/config.h" +#include "../include/OptionItem.h" +#include "../include/PlayerData.h" +#include "../include/Translate.h" +#include +#include + +//WGuiBase +PIXEL_TYPE WGuiBase::getColor(int type){ + switch(type){ + case WGuiColor::TEXT_BODY: + case WGuiColor::SCROLLBUTTON: + return ARGB(255,255,255,255); + case WGuiColor::SCROLLBAR: + return ARGB(150,50,50,50); + case WGuiColor::BACK_HEADER: + return ARGB(150,80,80,80); + default: + if(type < WGuiColor::BACK){ + if(hasFocus()) + return ARGB(255,255,255,0); + else + return ARGB(255,255,255,255); + } + else + return ARGB(150,50,50,50); + } + return ARGB(150,50,50,50); +} + + +void WGuiBase::renderBack(WGuiBase * it){ + if(!it) return; + WDecoStyled * styled = dynamic_cast(it); + if(styled) + styled->renderBack(styled->getDecorated()); + else + subBack(it); +} + + +//WGuiItem +void WGuiItem::Entering(u32 key){ + mFocus = true; +} +float WGuiItem::minWidth(){ + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + return mFont->GetStringWidth(_(displayValue).c_str())+4; +} +float WGuiItem::minHeight(){ + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + return mFont->GetHeight(); +} + +bool WGuiItem::Leaving(u32 key){ + mFocus = false; + return true; +} + +void WGuiItem::Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + DWORD oldcolor = mFont->GetColor(); + mFont->SetColor(getColor(WGuiColor::TEXT)); + float fH = (height-mFont->GetHeight())/2; + string trans = _(displayValue); + float fW = mFont->GetStringWidth(trans.c_str()); + float boxW = getWidth(); + float oldS = mFont->GetScale(); + if(fW > boxW){ + mFont->SetScale(boxW/fW); + } + mFont->DrawString(trans,x+(width/2),y+fH,JGETEXT_CENTER); + mFont->SetScale(oldS); + mFont->SetColor(oldcolor); +} + +WGuiItem::WGuiItem(string _display, u8 _mF){ + mFlags=_mF; + displayValue = _display; + mFocus = false; + width=SCREEN_WIDTH; + height=20; + x=0; + y=0; +} + +string WGuiItem::_(string input){ + if(mFlags & WGuiItem::NO_TRANSLATE) + return input; + return ::_(input); +} +bool WGuiItem::CheckUserInput(u32 key){ + if(mFocus && key == PSP_CTRL_CIRCLE){ + updateValue(); + return true; + } + return false; +} + +//WDecoStyled +void WDecoStyled::subBack(WGuiBase * item){ + if(!item) + return; + JRenderer * renderer = JRenderer::GetInstance(); + if(mStyle & DS_STYLE_BACKLESS) + return; + //TODO: if(mStyle & DS_STYLE_EDGED) Draw the edged box ala SimpleMenu + else{ //Draw standard style + WGuiSplit * split = dynamic_cast(item); + if(split && split->left->Visible() && split->right->Visible()){ + if(split->left) + 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()-2,split->getY()-2,split->right->getWidth(),split->getHeight(),2,split->right->getColor(WGuiColor::BACK)); + } + else{ + renderer->FillRoundRect(item->getX()-2,item->getY()-2,item->getWidth(),item->getHeight(),2,getColor(WGuiColor::BACK)); + } + } + +} + +PIXEL_TYPE WDecoStyled::getColor(int type){ + switch(type){ + case WGuiColor::BACK: + case WGuiColor::BACK_HEADER: + if(mStyle & DS_COLOR_DARK) + return ARGB(150,35,35,35); + else if(mStyle & DS_COLOR_BRIGHT) + return ARGB(150,80,80,80); + else if(mStyle & DS_STYLE_ALERT) + return ARGB(150,120,80,80); + else + return ARGB(150,50,50,50); + default: + return WGuiBase::getColor(type); + } + return ARGB(150,50,50,50); +} + +//WGuiHeader +void WGuiHeader::Render(){ + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + mFont->SetColor(getColor(WGuiColor::TEXT)); + + JRenderer * renderer = JRenderer::GetInstance(); + mFont->DrawString(_(displayValue).c_str(),x+width/2,y,JGETEXT_CENTER); +} + + +bool WGuiMenu::Leaving(u32 key){ + int nbitems = (int) items.size(); + if(key == buttonNext && currentItem < nbitems-1) + return false; + else if(key == buttonPrev && currentItem > 0) + return false; + + if(currentItem >= 0 && currentItem < nbitems) + if(!items[currentItem]->Leaving(key)) + return false; + + mFocus = false; + return true; +} +void WGuiMenu::Entering(u32 key){ + mFocus = true; + + //Try to force a selectable option. + if(currentItem == -1){ + for (size_t i = 0 ; i < items.size(); i++){ + if(items[i]->Selectable()) { + currentItem = i; + break; + } + } + } + + if(currentItem >= 0 && currentItem < (int) items.size()) + items[currentItem]->Entering(key); + return; +} + +void WGuiMenu::subBack(WGuiBase * item){ + if(!item) + return; + JRenderer * renderer = JRenderer::GetInstance(); + + WGuiSplit * split = dynamic_cast(item); + if(split && split->left->Visible() && split->right->Visible()){ + if(split->left) + subBack(split->left);//renderer->FillRoundRect(split->left->getX()-2,split->getY()-2,split->left->getWidth()-6,split->getHeight(),2,split->left->getColor(WGuiColor::BACK)); + if(split->right) + subBack(split->right);//renderer->FillRoundRect(split->right->getX()-2,split->getY()-2,split->right->getWidth(),split->getHeight(),2,split->right->getColor(WGuiColor::BACK)); + } + else + renderer->FillRoundRect(item->getX(),item->getY(),item->getWidth()-4,item->getHeight()-2,2,item->getColor(WGuiColor::BACK)); + +} +//WGuiList +WGuiList::WGuiList(string name, WSyncable * syncme): WGuiMenu(PSP_CTRL_DOWN,PSP_CTRL_UP,false,syncme){ + 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(size_t x=0;xconfirmChange(confirmed); + } +} +void WGuiList::Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + int listHeight=40; + int listSelectable=0; + int adjustedCurrent=0; + int start = 0, nowPos = 0, vHeight=0; + int nbitems = (int) items.size(); + + //List is empty. + 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); + return; + } + + //Force a selectable option. + if(currentItem == -1){ + for (int i = 0 ; i < nbitems; i++){ + if(items[i]->Selectable()) { + currentItem = i; + if(hasFocus()) + items[currentItem]->Entering(0); + break; + } + } + } + //Find out how large our list is, with all items and margin. + for (int pos=0;pos < nbitems; pos++){ + listHeight+=items[pos]->getHeight()+1; //What does the +1 do exactly ? + if(items[pos]->Selectable()){ + listSelectable++; + if(pos < currentItem) adjustedCurrent++; + } + } + + //Always fill screen + if(listHeight > SCREEN_HEIGHT) + { + for (start=currentItem;start > 0; start--){ + if(!items[start]->Visible()) + continue; + + vHeight += items[start]->getHeight()+5; + if(vHeight >= (SCREEN_HEIGHT-60)/2) + break; + } + vHeight = 0; + if(start >= 0) + for (nowPos=nbitems;nowPos > 1; nowPos--){ + if(!items[start]->Visible()) + continue; + vHeight += items[nowPos-1]->getHeight()+5; + } + + if(vHeight <= SCREEN_HEIGHT-40 && nowPos < start) + start = nowPos; + } + + vHeight = 0; + nowPos = 0; + + //Render items. + if(start >= 0) + { + //Render current underlay. + if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) + items[currentItem]->Underlay(); + + for (int pos=0;pos < nbitems; pos++){ + if(!items[pos]->Visible()) + continue; + + if(pos < start){ + vHeight += items[pos]->getHeight() + 5; + continue; + } + + items[pos]->setY(y+nowPos); + items[pos]->setX(x); + if(listHeight > SCREEN_HEIGHT && listSelectable > 1) + items[pos]->setWidth(width-10); + else + items[pos]->setWidth(width); + nowPos += items[pos]->getHeight() + 5; + renderBack(items[pos]); + items[pos]->Render(); + if(nowPos > SCREEN_HEIGHT) //Stop displaying things once we reach the bottom of the screen. + break; + } + + //Draw scrollbar + if(listHeight > SCREEN_HEIGHT && listSelectable > 1){ + 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-2,y-1,2,SCREEN_HEIGHT-y, + getColor(WGuiColor::SCROLLBAR)); + renderer->FillRoundRect(x+width-5,barPosition,5,barLength,2, + getColor(WGuiColor::SCROLLBUTTON)); + } + + //Render current overlay. + if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) + items[currentItem]->Overlay(); + } +} + +void WGuiList::setData(){ + for (size_t i = 0; i < items.size(); i++){ + items[i]->setData(); + } +} + +void WGuiList::ButtonPressed(int controllerId, int controlId){ + WGuiBase * it; + + if(!(it = Current())) + return; + + it->ButtonPressed(controllerId,controlId); +} + + +string WDecoEnum::lookupVal(int value){ + + if(edef == NULL){ + int id = getId(); + if(id != INVALID_ID){ + GameOptionEnum * goEnum = dynamic_cast(options.get(getId())); + if(goEnum) + edef = goEnum->def; + } + } + + if(edef){ + int idx = edef->findIndex(value); + if(idx != INVALID_ID) + return edef->values[idx].second; + } + + char buf[32]; + sprintf(buf,"%d",value); + return buf; +} + +void WDecoEnum::Render() +{ + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + mFont->SetColor(getColor(WGuiColor::TEXT)); + JRenderer * renderer = JRenderer::GetInstance(); + mFont->DrawString(_(getDisplay()).c_str(),getX(),getY()); + OptionInteger* opt = dynamic_cast(it); + if(opt) + mFont->DrawString(_(lookupVal(opt->value)).c_str(), getWidth() -10, getY(), JGETEXT_RIGHT); +} + +WDecoEnum::WDecoEnum(WGuiBase * _it, EnumDefinition *_edef) : WGuiDeco(_it) {edef = _edef;} +//WDecoCheat +WDecoCheat::WDecoCheat(WGuiBase * _it): WGuiDeco(_it){ + bVisible = (options[Options::ACTIVE_PROFILE].str == SECRET_PROFILE); +} +void WDecoCheat::Reload(){ + bVisible = (options[Options::ACTIVE_PROFILE].str == SECRET_PROFILE); +} +bool WDecoCheat::Visible(){ + if(bVisible && it && it->Visible()) + return true; + return false; +} +bool WDecoCheat::Selectable(){ + if(!it || !Visible()) + return false; + return it->Selectable(); +} +//WDecoConfirm + +WDecoConfirm::WDecoConfirm(JGuiListener * _listener, WGuiBase * _it): WGuiDeco(_it){ + listener = _listener; + confirm = "Confirm"; + cancel = "Cancel"; + confirmMenu = NULL; + bModal = false; + mState = OP_CONFIRMED; +} + +WDecoConfirm::~WDecoConfirm(){ + SAFE_DELETE(confirmMenu); +} + +void WDecoConfirm::Entering(u32 key){ + setFocus(true); + + if(it) + it->Entering(key); + + SAFE_DELETE(confirmMenu); + mState = OP_CONFIRMED; + confirmMenu = NEW SimpleMenu(444, listener,Constants::MENU_FONT, 50,170); + confirmMenu->Add(1,confirm.c_str()); + confirmMenu->Add(2,cancel.c_str()); +} + +bool WDecoConfirm::isModal(){ + if(bModal || (it && it->isModal())) + return true; + + return false; +} + +void WDecoConfirm::setModal(bool val){ + bModal = val; +} +void WDecoConfirm::setData(){ + if(!it) + return; + + it->setData(); +} + +bool WDecoConfirm::Leaving(u32 key){ + if(!it) + return true; + + //Choice must be confirmed. + if(mState == OP_UNCONFIRMED){ + if(!isModal()) + setModal(true); + if(!it->Changed()) + mState = OP_CONFIRMED; + else + mState = OP_CONFIRMING; + } + + if(mState == OP_CONFIRMED && it->Leaving(key)){ + setFocus(false); + setModal(false); + SAFE_DELETE(confirmMenu); + return true; + } + + return false; +} +bool WDecoConfirm::CheckUserInput(u32 key){ + if(hasFocus()){ + if (mState == OP_CONFIRMED && key == PSP_CTRL_CIRCLE) + mState = OP_UNCONFIRMED; + + if (mState != OP_CONFIRMING && it){ + if(it->CheckUserInput(key)) + return true; + } else if(confirmMenu && confirmMenu->CheckUserInput(key)) + return true; + } + return false; +} + +void WDecoConfirm::Update(float dt){ + if (hasFocus()){ + if (it && mState != OP_CONFIRMING) + it->Update(dt); + else + confirmMenu->Update(dt); + } +} + +void WDecoConfirm::Overlay(){ + if (confirmMenu && mState == OP_CONFIRMING) + confirmMenu->Render(); + + if(it) + it->Overlay(); +} + +void WDecoConfirm::ButtonPressed(int controllerId, int controlId){ + if(controllerId == 444){ + setModal(false); + switch(controlId){ + case 1: + mState = OP_CONFIRMED; + if(it) + it->confirmChange(true); + break; + case 2: + mState = OP_CONFIRMED; + if(it) + it->confirmChange(false); + break; + } + } + else + it->ButtonPressed(controllerId,controlId); +} + +WGuiButton::WGuiButton( WGuiBase* _it, int _controller, int _control, JGuiListener * jgl): WGuiDeco(_it) { + control = _control; + controller = _controller; + mListener = jgl; +} + +void WGuiButton::updateValue(){ + if(mListener) + mListener->ButtonPressed(controller, control); +} + +bool WGuiButton::CheckUserInput(u32 key){ + if (hasFocus() && key == PSP_CTRL_CIRCLE){ + updateValue(); + return true; + } + return false; +} + +PIXEL_TYPE WGuiButton::getColor(int type){ + if(type == WGuiColor::BACK && hasFocus()) + return it->getColor(WGuiColor::BACK_HEADER); + return it->getColor(type); +}; + +WGuiSplit::WGuiSplit(WGuiBase* _left, WGuiBase* _right) : WGuiItem("") { + right = _right; + left = _left; + bRight = false; + percentRight = 0.5f; + if(!left->Selectable()) + bRight = true; +} +WGuiSplit::~WGuiSplit(){ + SAFE_DELETE(left); + SAFE_DELETE(right); +} + +void WGuiSplit::setData(){ + left->setData(); + right->setData(); +} +void WGuiSplit::setX(float _x){ + x = _x; + left->setX(x); + right->setX(x+(1-percentRight)*width); +} +void WGuiSplit::setY(float _y){ + y = _y; + left->setY(y); + right->setY(y); +} +void WGuiSplit::setWidth(float _w){ + width = _w; + if(right->Visible()) + left->setWidth((1-percentRight)*width); + else + left->setWidth(width); + + right->setWidth(percentRight*width); +} +void WGuiSplit::setHeight(float _h){ + left->setHeight(_h); + right->setHeight(_h); + height = _h; +} +float WGuiSplit::getHeight(){ + float lH, rH; + lH = left->getHeight(); + rH = right->getHeight(); + if(lH > rH) + return lH; + + return rH; +} + +void WGuiSplit::Render(){ + if(right->Visible()) + right->Render(); + if(left->Visible()) + left->Render(); +} + +bool WGuiSplit::isModal(){ + if(bRight) + return right->isModal(); + + return left->isModal(); +} +void WGuiSplit::setModal(bool val){ + if(bRight) + return right->setModal(val); + + return left->setModal(val); +} + +bool WGuiSplit::CheckUserInput(u32 key){ + if(hasFocus()){ + if (!bRight){ + if(left->CheckUserInput(key)) + return true; + if(key == PSP_CTRL_RIGHT && !isModal() + && right->Selectable() && left->Leaving(PSP_CTRL_RIGHT)){ + bRight = !bRight; + right->Entering(PSP_CTRL_RIGHT); + return true; + } + } + else + { + if(right->CheckUserInput(key)) + return true; + if (key == PSP_CTRL_LEFT && !isModal() + && left->Selectable() && right->Leaving(PSP_CTRL_LEFT)){ + bRight = !bRight; + left->Entering(PSP_CTRL_LEFT); + return true; + } + } + } + + return false; +} + +void WGuiSplit::Update(float dt){ + if(bRight) + right->Update(dt); + else + left->Update(dt); +} + +void WGuiSplit::Entering(u32 key){ + mFocus = true; + if(bRight) + right->Entering(key); + else + left->Entering(key); +} +bool WGuiSplit::Leaving(u32 key){ + + if(bRight){ + if(right->Leaving(key)){ + mFocus = false; + return true; + } + } + else{ + if(left->Leaving(key)){ + mFocus = false; + return true; + } + } + + return false; +} +void WGuiSplit::Overlay(){ + if(bRight) + right->Overlay(); + else + left->Overlay(); +} +void WGuiSplit::Underlay(){ + if(bRight) + right->Underlay(); + else + left->Underlay(); +} +void WGuiSplit::ButtonPressed(int controllerId, int controlId) +{ + if(bRight) + right->ButtonPressed(controllerId, controlId); + else + left->ButtonPressed(controllerId, controlId); +} +void WGuiSplit::Reload(){ + left->Reload(); + right->Reload(); +} +void WGuiSplit::confirmChange(bool confirmed){ + right->confirmChange(confirmed); + left->confirmChange(confirmed); +} + +//WGuiMenu +WGuiMenu::WGuiMenu(u32 next = PSP_CTRL_RIGHT, u32 prev = PSP_CTRL_LEFT, bool m, WSyncable * syncme): WGuiItem(""){ + buttonNext = next; + buttonPrev = prev; + currentItem = -1; + mDPad = m; + sync = syncme; +} +WGuiMenu::~WGuiMenu(){ + for(vector::iterator it = items.begin();it!=items.end();it++) + SAFE_DELETE(*it); +} +void WGuiMenu::setData(){ + for(vector::iterator it = items.begin();it!=items.end();it++) + (*it)->setData(); +}; + +void WGuiMenu::Reload(){ + for(vector::iterator it = items.begin();it!=items.end();it++) + (*it)->Reload(); +}; + +void WGuiMenu::Render(){ + for(vector::iterator it = items.begin();it!=items.end();it++) + (*it)->Render(); +} +void WGuiMenu::confirmChange(bool confirmed){ + for(vector::iterator it = items.begin();it!=items.end();it++) + (*it)->confirmChange(confirmed); +} + +void WGuiMenu::ButtonPressed(int controllerId, int controlId){ + WGuiBase * it = Current(); + if(!it) return; + it->ButtonPressed(controllerId,controlId); +} + +WGuiBase * WGuiMenu::Current(){ + if(currentItem >= 0 && currentItem < (int) items.size()) + return items[currentItem]; + return NULL; +} +void WGuiMenu::Add(WGuiBase * it){ + if(it) + items.push_back(it); +} +bool WGuiMenu::CheckUserInput(u32 key){ + bool kidModal = false; + bool handledInput = false; + int nbitems = (int) items.size(); + JGE * mEngine = JGE::GetInstance(); + + if(!mEngine->GetButtonState(held)) //Key isn't held down. + held = 0; + + if(currentItem >= 0 && currentItem < nbitems) + kidModal = items[currentItem]->isModal(); + + if(!kidModal && hasFocus()){ + if (isButtonDir(key,-1)){ + held = buttonPrev; + duration = 0; + if(prevItem()) + return true; + } + else if(held == buttonPrev && duration > 1){ + duration = .92; + if(prevItem()) + return true; + } + else if (isButtonDir(key,1)){ + held = buttonNext; + duration = 0; + if(nextItem()) + return true; + } + else if(held == buttonNext && duration > 1){ + duration = .92; + if(nextItem()) + return true; + } + } + + if(currentItem >= 0 && currentItem < nbitems) + return items[currentItem]->CheckUserInput(key); + + return false; +} +void WGuiMenu::syncMove(){ + if(!sync) + return; + int i = currentItem - sync->getPos(); + + while(i < 0 && sync->prev()) + i = currentItem - sync->getPos(); + while(i > 0 && sync->next()) + i = currentItem - sync->getPos(); +} +bool WGuiMenu::isButtonDir(u32 key, int dir){ + if(!mDPad) + return ((dir > 0 && key == buttonNext) || (dir <= 0 && key == buttonPrev)); + + if(dir <= 0){ + switch(buttonPrev){ + case PSP_CTRL_LEFT: + if(key == PSP_CTRL_UP) + return true; + break; + case PSP_CTRL_UP: + if(key == PSP_CTRL_LEFT) + return true; + break; + } + return (key == buttonPrev); + }else { + switch(buttonNext){ + case PSP_CTRL_RIGHT: + if(key == PSP_CTRL_DOWN) + return true; + break; + case PSP_CTRL_DOWN: + if(key == PSP_CTRL_RIGHT) + return true; + break; + } + return (key == buttonNext); + } +} +void WGuiMenu::Update(float dt){ + int nbitems = (int) items.size(); + JGE * mEngine = JGE::GetInstance(); + + if(held) + duration += dt; + + if(currentItem >= 0 && currentItem < nbitems) + items[currentItem]->Update(dt); + + for (int i = 0 ; i < nbitems; i++){ + if(i != currentItem) + items[i]->Update(dt); + } +} + +bool WGuiMenu::nextItem(){ + int potential = currentItem; + int nbitems = (int) items.size(); + WGuiBase * now = NULL; + if(currentItem < nbitems && currentItem > -1) + now = items[currentItem]; + + 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 && (!now || now->Leaving(buttonNext))){ + currentItem = potential; + items[currentItem]->Entering(buttonNext); + + if(sync) + syncMove(); + return true; + } + } + if(sync) + syncMove(); + return false; +} + +bool WGuiMenu::prevItem(){ + int potential = currentItem; + WGuiBase * now = NULL; + if(currentItem < (int)items.size() && currentItem > -1) + now = items[currentItem]; + + if (potential > 0){ + potential--; + while(potential > 0 && items[potential]->Selectable() == false) + potential--; + if(potential < 0 || !items[potential]->Selectable()) + potential = -1; + else if(potential != currentItem && (!now || now->Leaving(buttonNext))){ + currentItem = potential; + items[currentItem]->Entering(buttonPrev); + if(sync) + syncMove(); + return true; + } + } + if(sync) + syncMove(); + return false; +} + +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(it->getY()+35); + it->setHeight(it->getHeight()-35); + WGuiMenu::Add(it); + } +} + +void WGuiTabMenu::Render(){ + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + JRenderer * renderer = JRenderer::GetInstance(); + + if (!items.size()) + return; + + int offset = x; + + for(vector::iterator it = items.begin();it!=items.end();it++){ + int w = mFont->GetStringWidth(_((*it)->getDisplay()).c_str()); + mFont->SetColor((*it)->getColor(WGuiColor::TEXT_TAB)); + renderer->FillRoundRect(offset+5,5,w + 5,25,2,(*it)->getColor(WGuiColor::BACK_TAB)); + mFont->DrawString(_((*it)->getDisplay()).c_str(),offset+10,10); + offset += w + 10 + 2; + } + + WGuiBase * c = Current(); + if(c) + c->Render(); +} + +void WGuiTabMenu::save(){ + confirmChange(true); + setData(); + ::options.save(); +} + + +//WGuiAward +void WGuiAward::Overlay(){ + JRenderer * r = JRenderer::GetInstance(); + JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT); + mFont->SetScale(.8); + mFont->SetColor(getColor(WGuiColor::TEXT)); + + string s = details; + if(s.size()){ + float fW = mFont->GetStringWidth(s.c_str()); + float fH = mFont->GetHeight(); + + if(fH < 16) + fH = 18; + JQuad * button = resources.RetrieveQuad("iconspsp.png", (float)4*32, 0, 32, 32,"",RETRIEVE_NORMAL); + + r->FillRoundRect(5,10,fW+32,fH+2,2,getColor(WGuiColor::BACK)); + if(button) + r->RenderQuad(button, 10,12,0,.5,.5); + mFont->DrawString(::_(s),30,16); + } + + mFont->SetScale(1); +} +void WGuiAward::Underlay(){ + 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-trophy->mHeight); + } + +} +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 + + myX += fM; + renderer->FillRoundRect(x-fM/2,y-fM,getWidth()-fM,fH-fM,fM,getColor(WGuiColor::BACK_TAB)); + 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, string _details): WGuiItem(name){ + id = _id; + text = _text; + height = 60; + details = _details; +} +WGuiAward::~WGuiAward(){ + GameOptionAward * goa = dynamic_cast(&options[id]); + if(goa) + goa->setViewed(true); +} +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, bool _thumb) : WGuiImage(wds){ + bThumb = _thumb; +}; +void WGuiCardImage::Render(){ + + JRenderer * renderer = JRenderer::GetInstance(); + + MTGCard * c = NULL; + Pos p(x+margin, y+margin, 1,0,255); + + if(!source || (c = source->getCard(mOffset.getPos())) == NULL){ + JQuad * q; + if(bThumb) + q = resources.GetQuad("back_thumb"); + else + q = resources.GetQuad("back"); + float scale = p.actZ * 257.f / q->mHeight; + renderer->RenderQuad(q,p.x,p.y,0,scale,scale); + }else{ + if(!c) + return; + if(bThumb){ + JQuad * q = NULL; + if(!options[Options::DISABLECARDS].number) + q = source->getThumb(mOffset.getPos()); + if(!q && (q = CardGui::alternateThumbQuad(c)) == NULL) + return; //TODO Some kind of error image. + renderer->RenderQuad(q,p.x,p.y); + } + else{ + JQuad * q = source->getImage(mOffset.getPos()); + if(!q || options[Options::DISABLECARDS].number) + CardGui::alternateRender(c,p); + else + CardGui::RenderBig(c,p); + } + } +} + +//WGuiCardDistort +WGuiCardDistort::WGuiCardDistort(WDataSource * wds, bool _thumb, WDataSource * _distort): WGuiCardImage(wds,_thumb){ + mesh = NEW hgeDistortionMesh(2,2); + distortSrc = NULL; +} +WGuiCardDistort::~WGuiCardDistort(){ + SAFE_DELETE(mesh); +} + +void WGuiCardDistort::Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * q = NULL; + + if(distortSrc) { + WDistort * dt = distortSrc->getDistort(mOffset.getPos()); + if(dt) + xy = *dt; + } + + if(!source){ + //Default to back. + if(bThumb) + q = resources.GetQuad("back_thumb"); + else + q = resources.GetQuad("back"); + }else { + MTGCard * c = source->getCard(mOffset.getPos()); + if(!c) + return; + + if(bThumb){ + q = source->getThumb(mOffset.getPos()); + if(!q || options[Options::DISABLECARDS].number) + q = CardGui::alternateThumbQuad(c); + } + else { + q = source->getImage(mOffset.getPos()); + if(!q || options[Options::DISABLECARDS].number) + q = CardGui::alternateThumbQuad(c); //TODO alternateX should render to texture. + } + } + if(!q) + return; + mesh->SetTexture(q->mTex); + float x0,y0,w0,h0; + q->GetTextureRect(&x0,&y0,&w0,&h0); + mesh->SetTextureRect(x0,y0,w0,h0); + mesh->Clear(ARGB(0xFF,0xFF,0xFF,0xFF)); + mesh->SetDisplacement(0, 0, xy[0],xy[1], HGEDISP_NODE); + mesh->SetDisplacement(1, 0, xy[2] - w0,xy[3], HGEDISP_NODE); + mesh->SetDisplacement(0, 1,xy[4],xy[5]-h0, HGEDISP_NODE); + mesh->SetDisplacement(1, 1, xy[6]-w0,xy[7]-h0, HGEDISP_NODE); + if(hasFocus()){ + mesh->SetColor(1,1,ARGB(255,200,200,200)); + mesh->SetColor(0,1,ARGB(255,200,200,200)); + mesh->SetColor(1,0,ARGB(255,200,200,200)); + mesh->SetColor(0,0,ARGB(255,255,255,200)); + }else{ + mesh->SetColor(1,1,ARGB(255,100,100,100)); + mesh->SetColor(0,1,ARGB(255,100,100,100)); + mesh->SetColor(1,0,ARGB(255,100,100,100)); + mesh->SetColor(0,0,ARGB(255,200,200,200)); + } + mesh->Render(0,0); + +} + +//WDistort +WDistort::WDistort(){ + for(int i=0;i<8;i++) + xy[i] = 0; +} + +float & WDistort::operator[](int p){ + return xy[p]; +} + +WDistort::WDistort(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4){ + xy[0] = x1; xy[1] = y1; + xy[2] = x2; xy[3] = y2; + xy[4] = x3; xy[5] = y3; + xy[6] = x4; xy[7] = y4; +} + +//WGuiListRow + +void WGuiListRow::Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + int listHeight=40; + int listSelectable=0; + int adjustedCurrent=0; + int start = 0, nowPos = 0, vHeight=0; + int nbitems = (int) items.size(); + + //List is empty. + 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); + return; + } + + //Force a selectable option. + if(currentItem == -1){ + for (int i = 0 ; i < nbitems; i++){ + if(items[i]->Selectable()) { + currentItem = i; + if(hasFocus()) + items[currentItem]->Entering(0); + break; + } + } + } + + vHeight = 0; + nowPos = 4; + float nowVPos = 4; + float tallestRow = 0; + int numRows = 1; + float cTallest = 0; + + //Render items. + if(start >= 0) + { + //Render current underlay. + if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) + items[currentItem]->Underlay(); + + for (int pos=0;pos < nbitems; pos++){ + if(!items[pos]->Visible()) + continue; + + items[pos]->setX(x+nowPos); + items[pos]->setY(y+nowVPos); + //items[pos]->setWidth(width/nbitems); + items[pos]->setWidth(items[pos]->minWidth()); + float temp = items[pos]->getHeight() + 3; + if(temp > tallestRow) + tallestRow = temp; + if(temp > cTallest) + cTallest = temp; + nowPos += items[pos]->getWidth() + 5; + renderBack(items[pos]); + if(x+nowPos+items[pos]->getWidth()+10 > SCREEN_WIDTH){ + nowPos = 0 + 20; //Indent newlines. + nowVPos += cTallest; + cTallest = 0; + numRows++; + } + items[pos]->Render(); + if(nowVPos > SCREEN_HEIGHT) + break; + } + + //Render current overlay. + if(currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) + items[currentItem]->Overlay(); + } + setHeight(tallestRow*numRows+10); +} +WGuiListRow::WGuiListRow(string n, WSyncable * s) : WGuiList(n,s) { + buttonNext = PSP_CTRL_RIGHT; + buttonPrev = PSP_CTRL_LEFT; + width = SCREEN_WIDTH; + height = 20; +} +//WGuiFilterUI +void WGuiFilters::Finish(){ + bFinished = true; + if(source){ + string src = getCode(); + source->clearFilters(); + if(src.size()){ + WCFilterFactory * wc = WCFilterFactory::GetInstance(); + source->addFilter(wc->Construct(src)); + } + if(!source->Size()) + source->clearFilters(); //TODO: Pop a "No results found" warning. + } +} +void WGuiFilters::ButtonPressed(int controllerId, int controlId){ + if(controllerId == -102){ + if(controlId == -10){ + WGuiListRow * wgl= NEW WGuiListRow(""); + wgl->Add(NEW WGuiFilterItem(this)); + list->Add(wgl); + }else if(controlId == -11){ + Finish(); + } + else{ + source->clearFilters(); + SAFE_DELETE(list); + buildList(); + } + return; + }else{ + if(list != NULL) + list->ButtonPressed(controllerId,controlId); + } +} +void WGuiFilters::buildList(){ + list = NEW WGuiList(""); + WGuiButton * l = NEW WGuiButton(NEW WGuiItem("Add Filter"),-102,-10,this); + WGuiButton * r = NEW WGuiButton(NEW WGuiItem("Done"),-102,-11,this); + WGuiButton * mid = NEW WGuiButton(NEW WGuiItem("Clear"),-102,-66,this); + WGuiSplit * sub = NEW WGuiSplit(mid,r); + WGuiSplit * wgs = NEW WGuiSplit(l,sub); + subMenu = NULL; + list->Add(NEW WGuiHeader(displayValue)); + list->Add(wgs); + list->Entering(0); +} +WGuiFilters::WGuiFilters(string header, WSrcCards * src) : WGuiItem(header) { + bFinished = false; + source = src; + buildList(); +} +string WGuiFilters::getCode(){ + if(!list) + return ""; + string res; + vector::iterator row, col; + for(row=list->items.begin();row!=list->items.end();row++){ + WGuiList * wgl = dynamic_cast(*row); + if(wgl){ + if(res.size()) + res += "|("; + else + res += "("; + for(col=wgl->items.begin();col!=wgl->items.end();col++){ + WGuiFilterItem * fi = dynamic_cast(*col); + if(fi){ + string gc = fi->getCode(); + if(res.size() && gc.size() && res[res.size()-1] != '(') + res += "&"; + res += gc; + } + } + res += ")"; + } + } + return res; +} +void WGuiFilters::Update(float dt){ + if(subMenu && !subMenu->closed) + subMenu->Update(dt); + if(list){ + list->Update(dt); + WGuiList * wgl = dynamic_cast(list->Current()); + if(!wgl) + return; + vector::iterator it; + bool bDeleted=false; + for(it=wgl->items.begin();it!=wgl->items.end();it++){ + WGuiFilterItem * wgfi = dynamic_cast(*it); + if(!wgfi || wgfi->mState != WGuiFilterItem::STATE_REMOVE) continue; + SAFE_DELETE(*it); + it = wgl->items.erase(it); + bDeleted = true; + } + if(bDeleted){ + wgl->Entering(0); + } + } +} +void WGuiFilters::Entering(u32 key){ + bFinished = false; + WGuiItem::Entering(key); +} +void WGuiFilters::Render(){ + if(!list) return; //Hurrah for paranoia. + JRenderer * r = JRenderer::GetInstance(); + float tX, tY; + tX = getX(); + tY = getY(); + r->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(128,0,0,0)); + list->setX(tX); list->setY(tY); + list->Render(); + + if(subMenu && !subMenu->closed) + subMenu->Render(); +} +bool WGuiFilters::CheckUserInput(u32 key){ + if(subMenu && !subMenu->closed && subMenu->CheckUserInput(key)) + return true; + if(key == PSP_CTRL_CROSS){//|| key == PSP_CTRL_START){ + //TODO Pop up a "Are you sure?" dialog. + return true; + } + if(list){ + return list->CheckUserInput(key); + } + return WGuiItem::CheckUserInput(key); +} +WGuiFilters::~WGuiFilters(){ + SAFE_DELETE(list); + SAFE_DELETE(subMenu); +} +void WGuiFilters::addColumn(){ + if(!list) + return; + WGuiList * wgl = dynamic_cast(list->Current()); + if(wgl){ + wgl->currentItem = wgl->items.size()-1; + wgl->Add(NEW WGuiFilterItem(this)); + } +} +bool WGuiFilters::isAvailableCode(string code){ +if(!list) return false; + WGuiList * wgl = dynamic_cast(list->Current()); + if(wgl){ + vector::iterator it; + for(it=wgl->items.begin();it!=wgl->items.end();it++){ + WGuiFilterItem * wgfi = dynamic_cast(*it); + if(!wgfi || wgfi->mState != WGuiFilterItem::STATE_FINISHED) continue; + if(wgfi->filterVal < 0 || (int)wgfi->args.size() < wgfi->filterVal) continue; + string s = wgfi->args[wgfi->filterVal].second; + if(s == code) + return false; + } + return true; + } + return false; //For some reason, we don't have any rows? +} +bool WGuiFilters::isAvailable(int type){ + if(!list) return false; + int colors = 0; + WGuiList * wgl = dynamic_cast(list->Current()); + if(wgl){ + vector::iterator it; + for(it=wgl->items.begin();it!=wgl->items.end();it++){ + WGuiFilterItem * wgfi = dynamic_cast(*it); + if(!wgfi || wgfi->mState != WGuiFilterItem::STATE_FINISHED) continue; + switch(type){ + case WGuiFilterItem::FILTER_BASIC: + return true; + case WGuiFilterItem::FILTER_COLOR: + if(wgfi->filterType == type) + colors++; + break; + default: + if(wgfi->filterType == type) + return false; + } + } + if(colors >= 5) + return false; + return true; + } + return false; //For some reason, we don't have any rows? +} +//WGuiFilterItem +WGuiFilterItem::WGuiFilterItem(WGuiFilters * parent): WGuiItem("Cards..."){ + filterType = -1; filterVal = -1; mState = 0; + mParent = parent; mNew = true; +}; +void WGuiFilterItem::updateValue(){ + bool delMenu = true; + if(!mParent) + return; + switch(mState){ + case STATE_CANCEL: + mState = STATE_UNSET; + break; + case STATE_FINISHED: + case STATE_UNSET: + SAFE_DELETE(mParent->subMenu); + mState = STATE_CHOOSE_TYPE; + mParent->subMenu = NEW SimpleMenu(-1234,this,Constants::MENU_FONT,20,20,"Filter By..."); + if(mParent->isAvailable(FILTER_SET)){ + mParent->subMenu->Add(FILTER_SET,"Set"); + delMenu = false; + } + if(mParent->isAvailable(FILTER_COLOR)){ + mParent->subMenu->Add(FILTER_COLOR,"Color"); + delMenu = false; + } + if(mParent->isAvailable(FILTER_TYPE)){ + mParent->subMenu->Add(FILTER_TYPE,"Type"); + delMenu = false; + } + if(mParent->isAvailable(FILTER_RARITY)){ + mParent->subMenu->Add(FILTER_RARITY,"Rarity"); + delMenu = false; + }if(mParent->isAvailable(FILTER_BASIC)){ + mParent->subMenu->Add(FILTER_BASIC,"Ability"); + delMenu = false; + } + if(!mNew) + mParent->subMenu->Add(-2,"Remove"); + mParent->subMenu->Add(-1,"Cancel"); + if(delMenu){ + SAFE_DELETE(mParent->subMenu); + mState = STATE_FINISHED; + } + break; + case STATE_CHOOSE_TYPE: + SAFE_DELETE(mParent->subMenu); + args.clear(); + mState = STATE_CHOOSE_VAL; + mParent->subMenu = NEW SimpleMenu(-1234,this,Constants::MENU_FONT,20,20,"Filter:"); + if(filterType == FILTER_TYPE){ + addArg("Artifact","t:Artifact;"); + addArg("Artifact Creature","t:Artifact;&t:Creature;"); + addArg("Creature","t:Creature;"); + addArg("Enchantment","t:Enchantment;"); + addArg("Instant","t:Instant;"); + addArg("Land","t:Land;"); + addArg("Legendary","t:Legendary;"); + addArg("Sorcery","t:Sorcery;"); + }else if(filterType == FILTER_RARITY){ + addArg("Mythic","r:m;"); + addArg("Rare","r:r;"); + addArg("Uncommon","r:u;"); + addArg("Common","r:c;"); + }else if(filterType == FILTER_COLOR){ + addArg("White","c:w;"); + addArg("Blue","c:u;"); + addArg("Red","c:r;"); + addArg("Green","c:g;"); + addArg("Black","c:b;"); + }else if(filterType == FILTER_BASIC){ + char buf[512]; + for(int i=0;igetName(),buf); + } + } + mParent->subMenu->Add(-1,"Cancel"); + break; + case STATE_CHOOSE_VAL: + mState = STATE_FINISHED; + if(mNew && mParent) + mParent->addColumn(); + mNew = false; + if(filterVal > -1 && filterVal < (int) args.size()) + displayValue = args[filterVal].first; + SAFE_DELETE(mParent->subMenu); + break; + } +} +void WGuiFilterItem::addArg(string display, string code){ + if(!mParent || !mParent->subMenu || !mParent->isAvailableCode(code)) + return; + mParent->subMenu->Add((int)args.size(),display.c_str()); + args.push_back(pair(display,code)); +} + +void WGuiFilterItem::ButtonPressed(int controllerId, int controlId){ + if(!mParent) return; + + switch(mState){ + case STATE_CHOOSE_TYPE: + if(controlId == -1){ + mParent->subMenu->Close(); + mState = STATE_CANCEL; return; + }else if(controlId == -2){ + mParent->subMenu->Close(); + mState = STATE_REMOVE; return; + } + filterType = controlId; + break; + case STATE_CHOOSE_VAL: + if(controlId == -1){ + mParent->subMenu->Close(); + mState = STATE_UNSET; return; + }else if(controlId == -2){ + mParent->subMenu->Close(); + mState = STATE_REMOVE; return; + } + filterVal = controlId; + break; + } + updateValue(); +} + +bool WGuiFilterItem::isModal(){ + switch(mState){ + case STATE_UNSET: + case STATE_REMOVE: + case STATE_CANCEL: + case STATE_FINISHED: + return false; + } + return true; +} + +string WGuiFilterItem::getCode(){ + if(mState != STATE_FINISHED || filterVal < 0 || filterVal > (int) args.size()) + return ""; + return args[filterVal].second; +} \ No newline at end of file diff --git a/projects/mtg/template.vcproj b/projects/mtg/template.vcproj index 3be0b4c90..f7837461b 100644 --- a/projects/mtg/template.vcproj +++ b/projects/mtg/template.vcproj @@ -628,10 +628,6 @@ RelativePath=".\src\Rules.cpp" > - - @@ -688,10 +684,22 @@ RelativePath=".\src\WCachedResource.cpp" > + + + + + + @@ -993,10 +1001,6 @@ RelativePath=".\include\Rules.h" > - - @@ -1057,10 +1061,22 @@ RelativePath=".\include\WCachedResource.h" > + + + + + +