diff --git a/projects/mtg/bin/daily_build/template.exe b/projects/mtg/bin/daily_build/template.exe index 467f2f0bb..b92eb3ae1 100644 Binary files a/projects/mtg/bin/daily_build/template.exe and b/projects/mtg/bin/daily_build/template.exe differ diff --git a/projects/mtg/include/GuiCombat.h b/projects/mtg/include/GuiCombat.h index 3b45a1d64..227c66398 100644 --- a/projects/mtg/include/GuiCombat.h +++ b/projects/mtg/include/GuiCombat.h @@ -13,7 +13,7 @@ class GuiCombat : public GuiLayer GameObserver* go; DamagerDamaged* active; AttackerDamaged* activeAtk; - static JQuad* ok_quad; + static JTexture* ok_tex; Pos ok, enemy_avatar; vector attackers; DamagerDamaged* current; diff --git a/projects/mtg/include/ShopItem.h b/projects/mtg/include/ShopItem.h index 49b45c779..4e2604e5d 100644 --- a/projects/mtg/include/ShopItem.h +++ b/projects/mtg/include/ShopItem.h @@ -20,6 +20,7 @@ class hgeDistortionMesh; class ShopItem:public JGuiObject{ private: bool mHasFocus; + bool mRelease; JLBFont *mFont; string mText; float xy[8]; diff --git a/projects/mtg/include/WCachedResource.h b/projects/mtg/include/WCachedResource.h index c89f7308f..df15d522a 100644 --- a/projects/mtg/include/WCachedResource.h +++ b/projects/mtg/include/WCachedResource.h @@ -18,24 +18,47 @@ public: virtual void Nullify()=0; //For when our size is 0, so we don't free anything by mistake. virtual unsigned long size()=0; //Size of cached item in bytes. - virtual void Refresh(string filename)=0; //Basically calls Attempt(filename) and remaps in situ. virtual bool isGood()=0; //Return true if this has data. - virtual bool Attempt(string filename, int submode, int & error)=0; //Returns true if we've loaded our data and isGood(). + virtual bool isLocked(); //Is the resource locked? + virtual void lock(); //Lock it. + virtual void unlock(bool force = false); //Unlock it. Forcing a lock will also remove "permanent" status. -protected: - bool isLocked(); //Is the resource locked? bool isPermanent(); //Is the resource permanent? - void lock(); //Lock it. void deadbolt(); //Make it permanent. - void unlock(bool force = false); //Unlock it. Forcing a lock will also remove "permanent" status. void hit(); //Update resource's last used time. +protected: int loadedMode; //What submode settings were we loaded with? (For refresh) unsigned int lastTime; //When was the last time we were hit? unsigned char locks; //Remember to unlock when we're done using locked stuff, or else this'll be useless. }; -class WCachedTexture: public WResource{ +class WCachedResource: public WResource { +public: + friend class WResourceManager; + template friend class WCache; + + virtual void Refresh(string filename)=0; //Basically calls Attempt(filename) and remaps in situ. + virtual bool Attempt(string filename, int submode, int & error)=0; //Returns true if we've loaded our data and isGood(). +}; + + +class WTrackedQuad: public WResource { +public: + WTrackedQuad(string _resname); + ~WTrackedQuad(); + void Nullify(); + unsigned long size(); + bool isGood(); + + string resname; + JQuad * quad; +#ifdef DEBUG_CACHE + static int totalTracked; +#endif +}; + +class WCachedTexture: public WCachedResource{ public: friend class WResourceManager; template friend class WCache; @@ -44,23 +67,28 @@ public: void Refresh(string filename); unsigned long size(); - bool isGood(); + bool isGood(); + bool isLocked(); bool Attempt(string filename, int submode, int & error); bool compare(JTexture * t) {return (t == texture);}; void Nullify(); JTexture * Actual(); //Return this texture as is. Does not make a new one. JQuad * GetQuad(string resname); - JQuad * GetQuad(float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f,string resname=""); //Get us a new/existing quad. + + WTrackedQuad* GetTrackedQuad(float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f,string resname=""); //Get us a new/existing quad. + + JQuad * GetQuad(float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f,string resname=""); //Alias to GetTrackedQuad. JQuad * GetCard(float offX=0.0f, float offY=0.0f, float width=0.0f, float height=0.0f,string resname=""); //Same as above, but centered when new. + bool ReleaseQuad(JQuad* quad); //We're done with this quad, so delete and stop tracking. True if existed. protected: JTexture * texture; bool bVRAM; - map trackedQuads; + vector trackedQuads; }; -class WCachedParticles: public WResource{ +class WCachedParticles: public WCachedResource{ public: friend class WResourceManager; template friend class WCache; @@ -79,13 +107,12 @@ protected: hgeParticleSystemInfo * particles; }; -class WCachedSample: public WResource{ +class WCachedSample: public WCachedResource{ public: friend class WResourceManager; template friend class WCache; WCachedSample(); - ~WCachedSample(); - + ~WCachedSample(); void Nullify(); bool compare(JSample * s) {return (s == sample);}; unsigned long size(); @@ -98,4 +125,4 @@ protected: JSample * sample; }; -#endif +#endif \ No newline at end of file diff --git a/projects/mtg/include/WResourceManager.h b/projects/mtg/include/WResourceManager.h index 4aec4f888..d13312ebe 100644 --- a/projects/mtg/include/WResourceManager.h +++ b/projects/mtg/include/WResourceManager.h @@ -7,17 +7,28 @@ #include "MTGCard.h" #include "WCachedResource.h" -//Hard Limits. +//Soft limits. +#define HUGE_CACHE_LIMIT 10000000 +#define HUGE_CACHE_ITEMS 400 + #define LARGE_CACHE_LIMIT 5000000 -#define SMALL_CACHE_LIMIT 2000000 -#define MAX_CACHE_OBJECTS 200 +#define LARGE_CACHE_ITEMS 300 + +#define SMALL_CACHE_LIMIT 1000000 +#define SMALL_CACHE_ITEMS 200 + + +//Hard Limits. +#define MAX_CACHE_OBJECTS 400 #define MAX_CACHE_ATTEMPTS 10 #define MAX_CACHE_MISSES 200 +#define MAX_CACHED_SAMPLES 0 enum ENUM_WRES_INFO{ WRES_UNLOCKED = 0, //Resource is unlocked. WRES_MAX_LOCK = 250, //Maximum number of locks for a resource. WRES_PERMANENT = 251, //Resource is permanent (ie, managed) + WRES_UNDERLOCKED = 252, //Resource was released too many times. }; enum ENUM_RETRIEVE_STYLE{ @@ -166,8 +177,7 @@ public: //Wrapped from JSoundSystem. TODO: Privatize. JMusic * ssLoadMusic(const char *fileName); - void LargeCache(); - void SmallCache(); + void CacheForState(int state); void DebugRender(); @@ -183,7 +193,7 @@ private: WCache textureWCache; WCache sampleWCache; WCache psiWCache; - vector managedQuads; + vector managedQuads; //Statistics of record. unsigned int lastTime; diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index d989e98f1..a8c855634 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -248,6 +248,14 @@ void GameApp::Update() mCurrentState->End(); mCurrentState = mNextState; + + //Automate cache resizing. + for(int x=0;xResetPrivateVRAM(); renderer->EnableVSync(true); @@ -73,7 +71,6 @@ void GameStateDuel::Start() testSuite = NEW TestSuite(RESPATH"/test/_tests.txt",mParent->collection); #endif - mGamePhase = DUEL_STATE_CHOOSE_DECK1; credits = NEW Credits(); mFont = resources.GetJLBFont(Constants::MENU_FONT); @@ -218,7 +215,6 @@ void GameStateDuel::End() #if defined (WIN32) || defined (LINUX) OutputDebugString("Ending GamestateDuel\n"); #endif - resources.SmallCache(); SAFE_DELETE(deckmenu); JRenderer::GetInstance()->EnableVSync(false); if (mPlayers[0] && mPlayers[1]) mPlayers[0]->End(); diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index a71519e4a..7a640907b 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -119,6 +119,7 @@ void GameStateShop::load(){ void GameStateShop::End() { JRenderer::GetInstance()->EnableVSync(false); + resources.Release(mBg); resources.Release(bgTexture); SAFE_DELETE(shop); SAFE_DELETE(menu); diff --git a/projects/mtg/src/GuiCombat.cpp b/projects/mtg/src/GuiCombat.cpp index 962edb8b5..cbc618835 100644 --- a/projects/mtg/src/GuiCombat.cpp +++ b/projects/mtg/src/GuiCombat.cpp @@ -12,24 +12,23 @@ struct Left : public Exp { static inline bool test(DamagerDamaged* ref, DamagerD struct Right : public Exp { static inline bool test(DamagerDamaged* ref, DamagerDamaged* test) { return ref->y == test->y && ref->x < test->x && test->show; } }; -JQuad* GuiCombat::ok_quad = NULL; +JTexture* GuiCombat::ok_tex = NULL; GuiCombat::GuiCombat(GameObserver* go) : GuiLayer(), go(go), active(false), activeAtk(NULL), ok(SCREEN_WIDTH - MARGIN, 210, 1, 0, 255), enemy_avatar(SCREEN_WIDTH - MARGIN, TOP_LINE, 2, 0, 255), cursor_pos(NONE), step(DAMAGE) { - if(NULL == ok_quad) + if(NULL == ok_tex) { - ok_quad = resources.RetrieveQuad("Ok.png"); - if (ok_quad) ok_quad->SetHotSpot(28, 22); + ok_tex = resources.RetrieveTexture("Ok.png",RETRIEVE_LOCK); } } GuiCombat::~GuiCombat() { - if(ok_quad) - resources.Release(ok_quad); + if(ok_tex) + resources.Release(ok_tex); for (inner_iterator it = attackers.begin(); it != attackers.end(); ++it) { @@ -277,7 +276,11 @@ void GuiCombat::Render() } } } - if (ok_quad) ok.Render(ok_quad); + if (ok_tex) { + JQuad *ok_quad = resources.RetrieveTempQuad("Ok.png"); + ok_quad->SetHotSpot(28, 22); + ok.Render(ok_quad); + } renderer->DrawLine(0, SCREEN_HEIGHT / 2 + 10, SCREEN_WIDTH, SCREEN_HEIGHT / 2 + 10, ARGB(255, 255, 64, 0)); if (FIRST_STRIKE == step) { diff --git a/projects/mtg/src/GuiMana.cpp b/projects/mtg/src/GuiMana.cpp index d6ead1a68..94e937a15 100644 --- a/projects/mtg/src/GuiMana.cpp +++ b/projects/mtg/src/GuiMana.cpp @@ -41,6 +41,8 @@ ManaIcon::ManaIcon(int color, float x, float y) : Pos(x, y, 0.5, 0.0, 255), f(-1 if(!psi){ psi = NEW hgeParticleSystemInfo(); + if(!psi) + return; hgeParticleSystemInfo * defaults = resources.RetrievePSI("mana.psi",mq); if(defaults){ memcpy(psi,defaults,sizeof(hgeParticleSystemInfo)); @@ -50,7 +52,7 @@ ManaIcon::ManaIcon(int color, float x, float y) : Pos(x, y, 0.5, 0.0, 255), f(-1 //Default values for particle system! Cribbed from mana.psi //Really, we should just be loading that and then changing colors... - /*psi->nEmission = 114; + psi->nEmission = 114; psi->fLifetime = -1; psi->fParticleLifeMin = 1.1507937; psi->fParticleLifeMax = 1.4682540; @@ -60,7 +62,7 @@ ManaIcon::ManaIcon(int color, float x, float y) : Pos(x, y, 0.5, 0.0, 255), f(-1 psi->fSizeVar = 0.25396827; psi->fSpinStart = -5.5555553; psi->fAlphaVar = 0.77777779; - psi->sprite = mq;*/ + psi->sprite = mq; } switch(color){ @@ -91,7 +93,7 @@ ManaIcon::ManaIcon(int color, float x, float y) : Pos(x, y, 0.5, 0.0, 255), f(-1 } particleSys = NEW hgeParticleSystem(psi); - SAFE_DELETE(psi); //Not handled by cache, so kill it here. + SAFE_DELETE(psi); //This version of psi is not handled by cache, so kill it here. } else particleSys = NEW hgeParticleSystem(psi); //Cache will clean psi up later. @@ -212,7 +214,7 @@ void GuiMana::Update(float dt) if (it != manas.end()) { for (vector::iterator q = it; q != manas.end(); ++q) - SAFE_DELETE(*q); + SAFE_DELETE(*q); manas.erase(it, manas.end()); } } diff --git a/projects/mtg/src/GuiPlay.cpp b/projects/mtg/src/GuiPlay.cpp index 3f2245bbb..ee3c1cfaf 100644 --- a/projects/mtg/src/GuiPlay.cpp +++ b/projects/mtg/src/GuiPlay.cpp @@ -76,7 +76,8 @@ void GuiPlay::BattleField::EnstackAttacker(CardView* card) void GuiPlay::BattleField::EnstackBlocker(CardView* card) { GameObserver* game = GameObserver::GetInstance(); - if (card->card && card->card->defenser && card->card->defenser->view) card->x = card->card->defenser->view->x; + if (card->card && card->card->defenser && card->card->defenser->view) + card->x = card->card->defenser->view->x; card->y = baseY + (game->players[0] == card->card->controller() ? 20 + y : -20 - y); } void GuiPlay::BattleField::Update(float dt) diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 622ddc1d5..d80cac984 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -26,6 +26,8 @@ Player::~Player(){ SAFE_DELETE(manaPool); resources.Release(mAvatar); resources.Release(mAvatarTex); + mAvatar = NULL; + mAvatarTex = NULL; } const string Player::getDisplayName() const { @@ -59,7 +61,7 @@ Player * Player::opponent(){ HumanPlayer::HumanPlayer(MTGPlayerCards * deck, string file, string fileSmall) : Player(deck, file, fileSmall) { mAvatarTex = resources.RetrieveTexture("avatar.jpg",RETRIEVE_VRAM,TEXTURE_SUB_AVATAR); if (mAvatarTex) - mAvatar = resources.RetrieveQuad("avatar.jpg",0,0,35,50,"playerAvatar",RETRIEVE_NORMAL,TEXTURE_SUB_AVATAR); + mAvatar = resources.RetrieveQuad("avatar.jpg",0,0,35,50,"playerAvatar",RETRIEVE_VRAM,TEXTURE_SUB_AVATAR); else mAvatar = NULL; } diff --git a/projects/mtg/src/ShopItem.cpp b/projects/mtg/src/ShopItem.cpp index 70cebd15d..fbb7f9732 100644 --- a/projects/mtg/src/ShopItem.cpp +++ b/projects/mtg/src/ShopItem.cpp @@ -1,458 +1,466 @@ -#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, 20, 27,103,154,187,102,145,199,133,183}; - float ShopItems::_y1[] = {150,193,222,167,164,156,195,190,176,220,220}; - - float ShopItems::_x2[] = {103, 49, 73,135,183,213,138,181,231,171,225}; - float ShopItems::_y2[] = {155,180,218,166,166,154,195,186,177,225,216}; - - float ShopItems::_x3[] = { 48, 60, 10, 96,139,190, 81,146,189, 98,191}; - float ShopItems::_y3[] = {163,202,255,183,180,170,219,212,195,250,251}; - - float ShopItems::_x4[] = { 74, 88, 64,131,171,221,123,187,225,141,237}; - float ShopItems::_y4[] = {167,187,248,182,182,168,219,208,196,258,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; - - 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; - 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; - - thumb = resources.RetrieveCard(card,CACHE_THUMB); - - if (!thumb) thumb = CardGui::alternateThumbQuad(card); - - 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; - } -} - - -int ShopItem::updateCount(DeckDataWrapper * ddw){ - if (!card) return 0; - nameCount = ddw->countByName(card); - return nameCount; -} - -ShopItem::~ShopItem(){ - OutputDebugString("delete shopitem\n"); - SAFE_DELETE(mesh); -} - -const char * ShopItem::getText(){ - return mText.c_str(); -} - - -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->name).c_str(), nameCount ); - mText = buffer; - }else{ - mText = _(card->name).c_str(); - } - } - - JRenderer * renderer = JRenderer::GetInstance(); - //float x0 = mX; - //float y0 = mY - (mScale > 1 ? 4 : 0); - /* if (GetId()%2){ - float xs[] = {mX, mX, mX+230,mX+230}; - float ys[] = {mY-5+17,mY-5+19,mY-5+35,mY-5} ; - - renderer->FillPolygon(xs,ys,4,ARGB(200,0,0,0)); - x0 = mX + 230 -30; - mFont->DrawString(mText.c_str(), x0, mY + 8,JGETEXT_RIGHT); - - }else{ - float xs[] = {mX-5, mX-5, mX-5+230,mX-5+230,}; - float ys[] = {mY-5,mY-5+35,mY-5+17,mY-5+19} ; - renderer->FillPolygon(xs,ys,4,ARGB(128,0,0,0)); - mFont->DrawString(mText.c_str(), mX + 30, mY + 8); - }*/ - //renderer->FillRect(mX-5, mY-5,230,35, ); - - - if (mesh){ - mesh->Render(0,0); - //renderer->RenderQuad(thumb,x0,y0,0,mScale * 0.45,mScale * 0.45); - }else{ - //NOTHING - } - if (mHasFocus){ - if (card) quad = resources.RetrieveCard(card); - if (quad){ - quad->SetColor(ARGB(255,255,255,255)); - renderer->RenderQuad(quad,SCREEN_WIDTH - 105,SCREEN_HEIGHT/2 - 5,0, 0.9f,0.9f); - }else{ - if (card) CardGui::alternateRender(card,Pos(SCREEN_WIDTH - 105,SCREEN_HEIGHT/2 - 5,0.9f* 285/250, 0,255)); - - } - mFont->DrawString(mText.c_str(), SCREEN_WIDTH/2 - 50, SCREEN_HEIGHT - 16,JGETEXT_CENTER); - } -} - -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; -} - - - -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){ - while (u32 key = JGE::GetInstance()->ReadButton()) display->CheckUserInput(key); - 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,resources.GetJLBFont(Constants::MENU_FONT),SCREEN_WIDTH-300,SCREEN_HEIGHT/2,buffer); - dialog->Add(1,"Yes"); - dialog->Add(2,"No"); - } - else{ - dialog->Update(dt); - } - }else{ - 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 (JGE::GetInstance()->GetButtonClick(buttons[i])){ - showCardList = false; - } - } - if (JGE::GetInstance()->GetButtonClick(PSP_CTRL_TRIANGLE)){ - showCardList = !showCardList; - } - SAFE_DELETE(dialog); - JGuiController::Update(dt); - } - - } - -} - - -void ShopItems::Render(){ - JGuiController::Render(); - if (showPriceDialog==-1){ - - }else{ - if(dialog){ - dialog->Render(); - } - } - char credits[512]; - sprintf(credits,_("credits: %i").c_str(), playerdata->credits); - mFont->SetColor(ARGB(200,0,0,0)); - mFont->DrawString(credits, 5, SCREEN_HEIGHT - 13); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(credits, 5, SCREEN_HEIGHT - 15); - if (display) display->Render(); - - if (showCardList){ - JRenderer * r = JRenderer::GetInstance(); - 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]}; - - tempDeck->addRandomCards(1, sets,1,rare_or_mythic); - tempDeck->addRandomCards(3, sets,1,Constants::RARITY_U); - tempDeck->addRandomCards(11, sets,1,Constants::RARITY_C); - - //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,&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 (map::iterator it = tempDeck->cards.begin(); it!=tempDeck->cards.end(); it++){ - MTGCard * c = tempDeck->getCardById(it->first); - for (int j = 0; j < it->second; j++){ - MTGCardInstance * card = NEW MTGCardInstance(c, NULL); - displayCards[i] = card; - display->AddCard(card); - i++; - } - } - delete tempDeck; - } - 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; - } -} - - -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); -} - -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; -} +#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, 20, 27,103,154,187,102,145,199,133,183}; + float ShopItems::_y1[] = {150,193,222,167,164,156,195,190,176,220,220}; + + float ShopItems::_x2[] = {103, 49, 73,135,183,213,138,181,231,171,225}; + float ShopItems::_y2[] = {155,180,218,166,166,154,195,186,177,225,216}; + + float ShopItems::_x3[] = { 48, 60, 10, 96,139,190, 81,146,189, 98,191}; + float ShopItems::_y3[] = {163,202,255,183,180,170,219,212,195,250,251}; + + float ShopItems::_x4[] = { 74, 88, 64,131,171,221,123,187,225,141,237}; + float ShopItems::_y4[] = {167,187,248,182,182,168,219,208,196,258,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; + + thumb = resources.RetrieveCard(card,RETRIEVE_LOCK,TEXTURE_SUB_THUMB); + + 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; + } +} + + +int ShopItem::updateCount(DeckDataWrapper * ddw){ + if (!card) return 0; + nameCount = ddw->countByName(card); + return nameCount; +} + +ShopItem::~ShopItem(){ + OutputDebugString("delete shopitem\n"); + if(mRelease){ + resources.Release(thumb); + } + SAFE_DELETE(mesh); +} + +const char * ShopItem::getText(){ + return mText.c_str(); +} + + +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->name).c_str(), nameCount ); + mText = buffer; + }else{ + mText = _(card->name).c_str(); + } + } + + JRenderer * renderer = JRenderer::GetInstance(); + //float x0 = mX; + //float y0 = mY - (mScale > 1 ? 4 : 0); + /* if (GetId()%2){ + float xs[] = {mX, mX, mX+230,mX+230}; + float ys[] = {mY-5+17,mY-5+19,mY-5+35,mY-5} ; + + renderer->FillPolygon(xs,ys,4,ARGB(200,0,0,0)); + x0 = mX + 230 -30; + mFont->DrawString(mText.c_str(), x0, mY + 8,JGETEXT_RIGHT); + + }else{ + float xs[] = {mX-5, mX-5, mX-5+230,mX-5+230,}; + float ys[] = {mY-5,mY-5+35,mY-5+17,mY-5+19} ; + renderer->FillPolygon(xs,ys,4,ARGB(128,0,0,0)); + mFont->DrawString(mText.c_str(), mX + 30, mY + 8); + }*/ + //renderer->FillRect(mX-5, mY-5,230,35, ); + + + if (mesh){ + mesh->Render(0,0); + //renderer->RenderQuad(thumb,x0,y0,0,mScale * 0.45,mScale * 0.45); + }else{ + //NOTHING + } + if (mHasFocus){ + if (card) quad = resources.RetrieveCard(card); + if (quad){ + quad->SetColor(ARGB(255,255,255,255)); + renderer->RenderQuad(quad,SCREEN_WIDTH - 105,SCREEN_HEIGHT/2 - 5,0, 0.9f,0.9f); + }else{ + if (card) CardGui::alternateRender(card,Pos(SCREEN_WIDTH - 105,SCREEN_HEIGHT/2 - 5,0.9f* 285/250, 0,255)); + + } + mFont->DrawString(mText.c_str(), SCREEN_WIDTH/2 - 50, SCREEN_HEIGHT - 16,JGETEXT_CENTER); + } +} + +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; +} + + + +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){ + while (u32 key = JGE::GetInstance()->ReadButton()) display->CheckUserInput(key); + 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,resources.GetJLBFont(Constants::MENU_FONT),SCREEN_WIDTH-300,SCREEN_HEIGHT/2,buffer); + dialog->Add(1,"Yes"); + dialog->Add(2,"No"); + } + else{ + dialog->Update(dt); + } + }else{ + 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 (JGE::GetInstance()->GetButtonClick(buttons[i])){ + showCardList = false; + } + } + if (JGE::GetInstance()->GetButtonClick(PSP_CTRL_TRIANGLE)){ + showCardList = !showCardList; + } + SAFE_DELETE(dialog); + JGuiController::Update(dt); + } + + } + +} + + +void ShopItems::Render(){ + JGuiController::Render(); + if (showPriceDialog==-1){ + + }else{ + if(dialog){ + dialog->Render(); + } + } + char credits[512]; + sprintf(credits,_("credits: %i").c_str(), playerdata->credits); + mFont->SetColor(ARGB(200,0,0,0)); + mFont->DrawString(credits, 5, SCREEN_HEIGHT - 13); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(credits, 5, SCREEN_HEIGHT - 15); + if (display) display->Render(); + + if (showCardList){ + JRenderer * r = JRenderer::GetInstance(); + 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]}; + + tempDeck->addRandomCards(1, sets,1,rare_or_mythic); + tempDeck->addRandomCards(3, sets,1,Constants::RARITY_U); + tempDeck->addRandomCards(11, sets,1,Constants::RARITY_C); + + //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,&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 (map::iterator it = tempDeck->cards.begin(); it!=tempDeck->cards.end(); it++){ + MTGCard * c = tempDeck->getCardById(it->first); + for (int j = 0; j < it->second; j++){ + MTGCardInstance * card = NEW MTGCardInstance(c, NULL); + displayCards[i] = card; + display->AddCard(card); + i++; + } + } + delete tempDeck; + } + 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; + } +} + + +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); +} + +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; +} diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 355de280e..3506a8e74 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -15,7 +15,7 @@ TestSuiteAI::TestSuiteAI(TestSuite * _suite, int playerId):AIPlayer(_suite->buil mAvatarTex = resources.RetrieveTexture("baka.jpg",RETRIEVE_VRAM,TEXTURE_SUB_AVATAR); if(mAvatarTex) - mAvatar = resources.RetrieveQuad("baka.jpg", 0, 0, 35, 50,"bakaAvatar",RETRIEVE_NORMAL,TEXTURE_SUB_AVATAR); + mAvatar = resources.RetrieveQuad("baka.jpg", 0, 0, 35, 50,"bakaAvatar",RETRIEVE_VRAM,TEXTURE_SUB_AVATAR); else mAvatar = NULL; diff --git a/projects/mtg/src/WCachedResource.cpp b/projects/mtg/src/WCachedResource.cpp index d0f54aeb5..8dee30de1 100644 --- a/projects/mtg/src/WCachedResource.cpp +++ b/projects/mtg/src/WCachedResource.cpp @@ -9,8 +9,10 @@ #include "../include/GameOptions.h" #include "../include/WResourceManager.h" + //WResource WResource::~WResource(){ + OutputDebugString("~WResource()\n"); return; } WResource::WResource(){ @@ -40,8 +42,17 @@ void WResource::lock(){ void WResource::unlock(bool force){ if(force) locks = 0; - else if(locks > WRES_UNLOCKED && locks <= WRES_MAX_LOCK) - locks--; + else if(locks > WRES_UNLOCKED){ + if(locks <= WRES_MAX_LOCK) + locks--; + } + else +#ifdef DEBUG_CACHE + locks = WRES_UNDERLOCKED; +#else + locks = 0; +#endif + } void WResource::hit(){ @@ -66,12 +77,12 @@ WCachedTexture::~WCachedTexture(){ if(!trackedQuads.size()) return; - map::iterator it, nit; + vector::iterator it; + WTrackedQuad * tq = NULL; - for(it=trackedQuads.begin();it!=trackedQuads.end();it=nit){ - nit = it; - nit++; - trackedQuads.erase(it); + for(it=trackedQuads.begin();it!=trackedQuads.end();it++){ + tq = (*it); + SAFE_DELETE(tq); } trackedQuads.clear(); } @@ -79,29 +90,57 @@ WCachedTexture::~WCachedTexture(){ JTexture * WCachedTexture::Actual(){ return texture; } +bool WCachedTexture::isLocked(){ + if(locks != WRES_UNLOCKED) + return true; + + for(vector::iterator it=trackedQuads.begin();it!=trackedQuads.end();it++){ + if((*it)->isLocked()) + return true; + } + + return false; +} bool WCachedTexture::ReleaseQuad(JQuad* quad){ #ifdef DEBUG_CACHE - OutputDebugString("Quad released.\n"); -#endif + char buf[512]; - for(map::iterator i = trackedQuads.begin();i!=trackedQuads.end();i++){ - if(i->first == quad ){ - unlock(); - trackedQuads.erase(i); - return true; + sprintf(buf,"ReleaseQuad: %d.\n", (int) quad); + OutputDebugString(buf); +#endif + if(quad == NULL) + return false; + + WTrackedQuad * tq = NULL; + vector::iterator nit; + for(vector::iterator it = trackedQuads.begin();it!=trackedQuads.end();it=nit){ + nit = it; + nit++; + if((*it) && (*it)->quad == quad ){ + tq = (*it); + tq->unlock(); + + if(!tq->isLocked()){ + SAFE_DELETE(tq); + trackedQuads.erase(it); + } + + return true; //Returns true when found. } } return false; } -JQuad * WCachedTexture::GetQuad(float offX, float offY, float width, float height,string resname){ +WTrackedQuad * WCachedTexture::GetTrackedQuad(float offX, float offY, float width, float height,string resname){ if(texture == NULL) return NULL; - JQuad * jq = NULL; + bool allocated = false; + WTrackedQuad * tq = NULL; + JQuad * quad = NULL; - map::iterator it; + vector::iterator it; std::transform(resname.begin(),resname.end(),resname.begin(),::tolower); if(width == 0.0f || width > texture->mWidth) @@ -109,40 +148,67 @@ JQuad * WCachedTexture::GetQuad(float offX, float offY, float width, float heigh if(height == 0.0f || height > texture->mHeight) height = texture->mHeight; - for(it = trackedQuads.begin();it!=trackedQuads.end();it++){ - if(it->second == resname){ - jq = it->first; + if((*it) && (*it)->resname == resname){ + tq = (*it); + break; } } - if(jq == NULL){ - jq = NEW JQuad(texture,offX,offY,width,height); - if(!jq) { + if(tq == NULL){ + allocated = true; + tq = NEW WTrackedQuad(resname); + } + + if(tq == NULL) + return NULL; + + quad = tq->quad; + + if(quad == NULL){ + quad = NEW JQuad(texture,offX,offY,width,height); + if(!quad) { //Probably out of memory. Try again. resources.Cleanup(); - jq = NEW JQuad(texture,offX,offY,width,height); + quad = NEW JQuad(texture,offX,offY,width,height); } - if(!jq) + if(!quad){ + if(allocated && tq) + SAFE_DELETE(tq); return NULL; //Probably a crash. + } - trackedQuads[jq] = resname; - return jq; - }else{ + tq->quad = quad; + trackedQuads.push_back(tq); + return tq; + } + else{ //Update JQ's values to what we called this with. - jq->SetTextureRect(offX,offY,width,height); - return jq; + quad->SetTextureRect(offX,offY,width,height); + return tq; } return NULL; } + +JQuad * WCachedTexture::GetQuad(float offX, float offY, float width, float height,string resname){ + WTrackedQuad * tq = GetTrackedQuad(offX,offY,width,height,resname); + + if(tq) + return tq->quad; + + return NULL; +} + + JQuad * WCachedTexture::GetQuad(string resname){ - map::iterator it; + vector::iterator it; std::transform(resname.begin(),resname.end(),resname.begin(),::tolower); + for(it = trackedQuads.begin();it!=trackedQuads.end();it++){ - if(it->second == resname){ - return it->first; + if((*it) && (*it)->resname == resname){ + return (*it)->quad; } } @@ -181,9 +247,9 @@ void WCachedTexture::Refresh(string filename){ else SAFE_DELETE(old); - for(map::iterator it=trackedQuads.begin();it!=trackedQuads.end();it++){ - if(it->first) - it->first->mTex = texture; + for(vector::iterator it=trackedQuads.begin();it!=trackedQuads.end();it++){ + if((*it) && (*it)->quad) + (*it)->quad->mTex = texture; } } @@ -385,3 +451,35 @@ void WCachedParticles::Nullify(){ if(particles) particles = NULL; } + +//WTrackedQuad +void WTrackedQuad::Nullify() { + quad = NULL; +} + +#if defined DEBUG_CACHE +int WTrackedQuad::totalTracked = 0; +#endif + +unsigned long WTrackedQuad::size() { + return sizeof(JQuad); +} +bool WTrackedQuad::isGood(){ + return (quad != NULL); +} +WTrackedQuad::WTrackedQuad(string _resname) { +#if defined DEBUG_CACHE + OutputDebugString("WTrackedQuad().\n"); + totalTracked++; +#endif + quad = NULL; resname = _resname; +} +WTrackedQuad::~WTrackedQuad() { +#if defined DEBUG_CACHE + char buf[512]; + totalTracked--; + sprintf(buf,"~WTrackedQuad() {%d}. %d left.\n", (int) quad,totalTracked); + OutputDebugString(buf); +#endif + if(quad) SAFE_DELETE(quad); +} \ No newline at end of file diff --git a/projects/mtg/src/WResourceManager.cpp b/projects/mtg/src/WResourceManager.cpp index 198bb30b9..51a0e9e0c 100644 --- a/projects/mtg/src/WResourceManager.cpp +++ b/projects/mtg/src/WResourceManager.cpp @@ -41,9 +41,9 @@ void WResourceManager::DebugRender(){ if(textureWCache.totalSize > textureWCache.cacheSize) man = textureWCache.totalSize - textureWCache.cacheSize; - sprintf(buf,"Textures %u+%u (of %u) items (%u misses), Pixels: %lu+%lu (of %lu)", + sprintf(buf,"Textures %u+%u (of %u) items (%u misses), Pixels: %lu (of %lu) + %lu", textureWCache.cacheItems, textureWCache.managed.size(),textureWCache.maxCached, - misses,textureWCache.cacheSize,man,textureWCache.maxCacheSize); + misses,textureWCache.cacheSize,textureWCache.maxCacheSize,man); font->DrawString(buf, 10,5); @@ -54,6 +54,7 @@ void WResourceManager::DebugRender(){ #ifdef DEBUG_CACHE if(debugMessage.size()) font->DrawString(debugMessage.c_str(), SCREEN_WIDTH-10,SCREEN_HEIGHT-25,JGETEXT_RIGHT); + #endif } @@ -154,13 +155,19 @@ WResourceManager::WResourceManager(){ mFontMap.clear(); psiWCache.Resize(SMALL_CACHE_LIMIT,6); //Plenty of room for mana symbols, or whatever. - sampleWCache.Resize(SMALL_CACHE_LIMIT,0); //This guy only exists so we can track misses. + sampleWCache.Resize(SMALL_CACHE_LIMIT,MAX_CACHED_SAMPLES); textureWCache.Resize(LARGE_CACHE_LIMIT,MAX_CACHE_OBJECTS); lastTime = 0; } WResourceManager::~WResourceManager(){ LOG("==Destroying WResourceManager=="); RemoveAll(); + + for(vector::iterator it=managedQuads.begin();it!=managedQuads.end();it++){ + WManagedQuad* wm = *it; + SAFE_DELETE(wm); + } + managedQuads.clear(); LOG("==Successfully Destroyed WResourceManager=="); } @@ -172,23 +179,13 @@ JQuad * WResourceManager::RetrieveCard(MTGCard * card, int style, int submode){ string filename = card->getSetName(); filename += "/"; filename += card->getImageName(); - WCachedTexture * res = NULL; + JQuad * jq = RetrieveQuad(filename,0,0,0,0,filename,style,submode|TEXTURE_SUB_5551); - //Aliases. - if(style == RETRIEVE_VRAM){ - submode = submode | TEXTURE_SUB_VRAM; - style = RETRIEVE_LOCK; - } - else if(style == RETRIEVE_THUMB){ - submode = submode | TEXTURE_SUB_THUMB; - style = RETRIEVE_NORMAL; + if(jq){ + jq->SetHotSpot(jq->mTex->mWidth / 2, jq->mTex->mHeight / 2); + return jq; } - - res = textureWCache.Retrieve(filename,style,submode|TEXTURE_SUB_5551); //Force RGBA5650. JPG doesn't support transparency anyways. - - if(res) //A non-null result will always be good. - return res->GetCard(); - + return NULL; } @@ -199,10 +196,10 @@ int WResourceManager::CreateQuad(const string &quadName, const string &textureNa string resname = quadName; std::transform(resname.begin(),resname.end(),resname.begin(),::tolower); - vector::iterator it; + vector::iterator it; int pos = 0; for(it = managedQuads.begin();it!=managedQuads.end();it++,pos++){ - if(it->resname == resname) + if((*it)->resname == resname) return pos; } @@ -213,12 +210,14 @@ int WResourceManager::CreateQuad(const string &quadName, const string &textureNa return INVALID_ID; if(jtex){ - JQuad * jq = jtex->GetQuad(x,y,width,height,quadName); + WTrackedQuad * tq = jtex->GetTrackedQuad(x,y,width,height,quadName); - if(jq){ - WManagedQuad mq; - mq.resname = resname; - mq.texture = jtex; + if(tq){ + tq->deadbolt(); + WManagedQuad * mq; + mq = NEW WManagedQuad(); + mq->resname = resname; + mq->texture = jtex; managedQuads.push_back(mq); } @@ -232,9 +231,9 @@ JQuad * WResourceManager::GetQuad(const string &quadName){ string lookup = quadName; std::transform(lookup.begin(),lookup.end(),lookup.begin(),::tolower); - for(vector::iterator it=managedQuads.begin();it!=managedQuads.end();it++){ - if(it->resname == lookup) - return it->texture->GetQuad(lookup); + for(vector::iterator it=managedQuads.begin();it!=managedQuads.end();it++){ + if((*it)->resname == lookup) + return (*it)->texture->GetQuad(lookup); } return NULL; @@ -244,11 +243,11 @@ JQuad * WResourceManager::GetQuad(int id){ if(id < 0 || id >= (int) managedQuads.size()) return NULL; - WCachedTexture * jtex = managedQuads[id].texture; + WCachedTexture * jtex = managedQuads[id]->texture; if(!jtex) return NULL; - return jtex->GetQuad(managedQuads[id].resname); + return jtex->GetQuad(managedQuads[id]->resname); } JQuad * WResourceManager::RetrieveTempQuad(string filename){ @@ -265,12 +264,28 @@ JQuad * WResourceManager::RetrieveQuad(string filename, float offX, float offY, return jq; } + //Aliases. + if(style == RETRIEVE_VRAM){ + submode = submode | TEXTURE_SUB_VRAM; + style = RETRIEVE_LOCK; + } + else if(style == RETRIEVE_THUMB){ + submode = submode | TEXTURE_SUB_THUMB; + style = RETRIEVE_NORMAL; + } + //Resname defaults to filename. if(!resname.size()) resname = filename; //No quad, but we have a managed texture for this! - WCachedTexture * jtex = textureWCache.Retrieve(filename,style,submode); + WCachedTexture * jtex = NULL; + if(style == RETRIEVE_MANAGE) + jtex = textureWCache.Retrieve(filename,RETRIEVE_MANAGE,submode); + else if(style == RETRIEVE_EXISTING) + jtex = textureWCache.Retrieve(filename,RETRIEVE_EXISTING,submode); + else + jtex = textureWCache.Retrieve(filename,RETRIEVE_NORMAL,submode); //Somehow, jtex wasn't promoted. if(style == RETRIEVE_MANAGE && jtex && !jtex->isPermanent()) @@ -278,16 +293,26 @@ JQuad * WResourceManager::RetrieveQuad(string filename, float offX, float offY, //Make this quad, overwriting any similarly resname'd quads. if(jtex){ - jq = jtex->GetQuad(offX,offY,width,height,resname); - + WTrackedQuad * tq = jtex->GetTrackedQuad(offX,offY,width,height,resname); + + if(tq == NULL) + return NULL; + if(style == RETRIEVE_MANAGE && resname != ""){ - WManagedQuad mq; - mq.resname = resname; - mq.texture = jtex; + WManagedQuad * mq = NEW WManagedQuad(); + mq->resname = resname; + mq->texture = jtex; managedQuads.push_back(mq); } - return jq; + if(style == RETRIEVE_LOCK) + tq->lock(); + else if(style == RETRIEVE_UNLOCK) + tq->unlock(); + else if(style == RETRIEVE_MANAGE) + tq->deadbolt(); + + return tq->quad; } //Texture doesn't exist, so no quad. @@ -310,8 +335,9 @@ void WResourceManager::Release(JQuad * quad){ break; } - if(it != textureWCache.cache.end() && it->second) - textureWCache.RemoveItem(it->second,false); //won't remove locked. + //Releasing a quad doesn't release the associated texture-- it might be needed later. + //if(it != textureWCache.cache.end() && it->second) + // textureWCache.RemoveItem(it->second,false); //won't remove locked. } void WResourceManager::ClearMisses(){ @@ -444,6 +470,7 @@ hgeParticleSystemInfo * WResourceManager::RetrievePSI(string filename, JQuad * t JSample * WResourceManager::RetrieveSample(string filename, int style, int submode){ //Check cache. This just tracks misses. + return NULL; WCachedSample * tc = NULL; tc = sampleWCache.Get(filename,submode); @@ -747,23 +774,32 @@ int WResourceManager::LoadJLBFont(const string &fontName, int height){ else return itr->second; } -void WResourceManager::LargeCache(){ +void WResourceManager::CacheForState(int state){ #if (defined WIN32 || defined LINUX) && !defined DEBUG_CACHE + textureWCache.Resize(HUGE_CACHE_LIMIT,HUGE_CACHE_ITEMS); return; #else - //Does not check option so we can use large cache during - //deck editor, when it's pretty much always safe. - textureWCache.Resize(LARGE_CACHE_LIMIT,MAX_CACHE_OBJECTS); - textureWCache.Cleanup(); -#endif -} -void WResourceManager::SmallCache(){ -#if (defined WIN32 || defined LINUX) && !defined DEBUG_CACHE - return; -#else - if(options[Options::CACHESIZE].number == 0){ - textureWCache.Resize(SMALL_CACHE_LIMIT,MAX_CACHE_OBJECTS); - textureWCache.Cleanup();} + switch(state){ + //Default is not to change cache sizes. + case GAME_STATE_MENU: + case GAME_STATE_OPTIONS: + break; + //Duels use a smaller cache, so there's more room for game stuff. + case GAME_STATE_DUEL: + textureWCache.Resize(SMALL_CACHE_LIMIT,SMALL_CACHE_ITEMS); + sampleWCache.Resize(SMALL_CACHE_LIMIT,MAX_CACHED_SAMPLES); + Cleanup(); + break; + //Deck editor and shop are entirely cache safe, so give it near infinite resources. + case GAME_STATE_SHOP: + case GAME_STATE_DECK_VIEWER: + textureWCache.Resize(HUGE_CACHE_LIMIT,HUGE_CACHE_ITEMS); + break; + //Anything unknown, use large cache. + default: + textureWCache.Resize(LARGE_CACHE_LIMIT,LARGE_CACHE_ITEMS); + break; + } #endif } @@ -949,8 +985,6 @@ void WCache::Resize(unsigned long size, int items){ } template cacheItem* WCache::AttemptNew(string filename, int submode){ -// Cleanup(); - if(submode & CACHE_EXISTING){ //Should never get this far. mError = CACHE_ERROR_NOT_CACHED; return NULL; @@ -962,7 +996,7 @@ cacheItem* WCache::AttemptNew(string filename, int submo if(item == NULL || !item->Attempt(filename,submode,mError)){ //No such file. Fail. - if(mError == CACHE_ERROR_404){ + if(item && mError == CACHE_ERROR_404){ Delete(item); return NULL; } @@ -1001,8 +1035,10 @@ cacheItem* WCache::AttemptNew(string filename, int submo } else mError = CACHE_ERROR_NONE; - + + item->lock(); Cleanup(); + item->unlock(); return item; } @@ -1189,6 +1225,9 @@ cacheItem * WCache::Get(string id, int style, int submod cacheSize += isize; } + item->lock(); + Cleanup(); //Strictly enforce limits. + item->unlock(); return item; } @@ -1297,7 +1336,7 @@ bool WCache::RemoveMiss(string id){ template bool WCache::RemoveItem(cacheItem * item, bool force){ - typename map::iterator it = cache.end(); + typename map::iterator it; if(item == NULL) return false; //Use RemoveMiss to remove cache misses, not this. @@ -1351,7 +1390,11 @@ template bool WCache::Delete(cacheItem * item){ if(!item) return false; - +#ifdef DEBUG_CACHE + char buf[512]; + sprintf(buf,"Cache: Delete [%d]\n",(int)item); + //OutputDebugString(buf); +#endif if(maxCached == 0) item->Nullify(); @@ -1391,4 +1434,4 @@ bool WCache::Release(cacheActual* actual){ //Released! cache.erase(it); return true; -} +} \ No newline at end of file