diff --git a/projects/mtg/include/GameStateMenu.h b/projects/mtg/include/GameStateMenu.h index d49a2d54e..eb33378eb 100644 --- a/projects/mtg/include/GameStateMenu.h +++ b/projects/mtg/include/GameStateMenu.h @@ -20,6 +20,7 @@ class GameStateMenu: public GameState, public JGuiListener JTexture * bgTexture; JQuad * mBg; JQuad * mSplash; + JTexture * splashTex; float mCreditsYPos; int currentState; //JMusic * bgMusic; diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index 61fab540b..62810c5cb 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -23,6 +23,8 @@ class GameStateShop: public GameState, public JGuiListener JLBFont * itemFont; JTexture * altThumb[8]; JQuad * mBack; + JQuad * mBg; + JTexture * mBgTex; SimpleMenu * menu; int mStage; char starterBuffer[128], boosterBuffer[128]; diff --git a/projects/mtg/include/GuiPhaseBar.h b/projects/mtg/include/GuiPhaseBar.h index de7abd6f5..29ebe86ec 100644 --- a/projects/mtg/include/GuiPhaseBar.h +++ b/projects/mtg/include/GuiPhaseBar.h @@ -12,7 +12,6 @@ class GuiPhaseBar : public GuiLayer static const unsigned Phases = 12; protected: - JQuad* quad; Phase* phase; float angle; diff --git a/projects/mtg/include/ShopItem.h b/projects/mtg/include/ShopItem.h index ebadf974c..87739ed2f 100644 --- a/projects/mtg/include/ShopItem.h +++ b/projects/mtg/include/ShopItem.h @@ -59,6 +59,7 @@ class ShopItems:public JGuiController,public JGuiListener{ PriceList * pricelist; int mX, mY, mHeight; JLBFont* mFont; + JTexture * mBgAATex; JQuad * mBgAA; MTGAllCards * collection; SimpleMenu * dialog; diff --git a/projects/mtg/include/WCachedResource.h b/projects/mtg/include/WCachedResource.h index 276eba6f6..6f185336d 100644 --- a/projects/mtg/include/WCachedResource.h +++ b/projects/mtg/include/WCachedResource.h @@ -11,6 +11,7 @@ class WResource{ public: friend class WResourceManager; + friend struct WCacheSort; template friend class WCache; WResource(); @@ -64,8 +65,7 @@ public: void Refresh(); unsigned long size(); - bool isGood(); - bool isLocked(); + bool isGood(); bool Attempt(string filename, int submode, int & error); bool compare(JTexture * t) {return (t == texture);}; JTexture * Actual(); //Return this texture as is. Does not make a new one. diff --git a/projects/mtg/include/WResourceManager.h b/projects/mtg/include/WResourceManager.h index a89a6eb62..6ee0bcabb 100644 --- a/projects/mtg/include/WResourceManager.h +++ b/projects/mtg/include/WResourceManager.h @@ -13,6 +13,12 @@ #define TEXTURES_CACHE_MINSIZE 2000000 // Minimum size of the cache on the PSP. The program should complain if the cache ever gets smaller than this #define OPERATIONAL_SIZE 5000000 // Size required by Wagic for operational stuff. 3MB is not enough. The cache will usually try to take (Total Ram - Operational size) #define MIN_LINEAR_RAM 1000000 +#ifdef DEBUG_CACHE +#define MAX_CACHE_TIME 2000 //The threshold above which we try to prevent nowTime() from looping. +#else +#define MAX_CACHE_TIME 2000000000 +#endif + #define THUMBNAILS_OFFSET 100000000 #define OTHERS_OFFSET 2000000000 @@ -67,6 +73,10 @@ enum ENUM_CACHE_ERROR{ CACHE_ERROR_NOT_MANAGED, }; +struct WCacheSort{ + bool operator()(const WResource * l, const WResource * r); //Predicate for use in sorting. See flatten(). +}; + template class WCache{ public: @@ -84,7 +94,6 @@ public: void Refresh(); //Refreshes all cache items. unsigned int Flatten(); //Ensures that the times don't loop. Returns new lastTime. void Resize(unsigned long size, int items); //Sets new limits, then enforces them. Lock safe, so not a "hard limit". - protected: bool RemoveItem(cacheItem * item, bool force = true); //Removes an item, deleting it. if(force), ignores locks / permanent bool UnlinkCache(cacheItem * item); //Removes an item from our cache, does not delete it. Use with care. @@ -121,6 +130,7 @@ public: WResourceManager(); ~WResourceManager(); + void Unmiss(string filename); JQuad * RetrieveCard(MTGCard * card, int style = RETRIEVE_NORMAL,int submode = CACHE_NORMAL); JSample * RetrieveSample(string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); JTexture * RetrieveTexture(string filename, int style = RETRIEVE_NORMAL, int submode = CACHE_NORMAL); @@ -130,7 +140,6 @@ public: int RetrieveError(); void Release(JTexture * tex); - void Release(JQuad * quad); void Release(JSample * sample); bool RemoveOldest(); diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index ee6655a78..3931c2cb0 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -143,6 +143,7 @@ void GameApp::Create() jq->SetHotSpot(12, 12); jq = resources.RetrieveQuad("shadow.png", 0, 0, 16, 16,"shadow",RETRIEVE_MANAGE); jq->SetHotSpot(8, 8); + jq = resources.RetrieveQuad("phasebar.png",0,0,0,0,"phasebar",RETRIEVE_MANAGE); collection = NEW MTGAllCards(); @@ -223,7 +224,6 @@ void GameApp::Destroy() void GameApp::Update() { - if (systemError.size()) return; JGE* mEngine = JGE::GetInstance(); if (mEngine->GetButtonState(PSP_CTRL_START) && mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)) diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index 6e2365f48..4929912d1 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -125,7 +125,7 @@ void GameStateDeckViewer::Start() } //Grab a texture in VRAM. - pspIconsTexture = resources.RetrieveTexture("iconspsp.png"); + pspIconsTexture = resources.RetrieveTexture("iconspsp.png", RETRIEVE_LOCK); char buf[512]; for (int i=0; i < 8; i++){ @@ -183,9 +183,6 @@ void GameStateDeckViewer::End() SAFE_DELETE(menu); resources.Release(pspIconsTexture); - for (int i=0; i < 8; i++){ - resources.Release(pspIcons[i]); - } SAFE_DELETE(myCollection); SAFE_DELETE(myDeck); SAFE_DELETE(pricelist); diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index ec1b9e448..5f43ba4b8 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -270,7 +270,6 @@ void GameStateMenu::End() JRenderer::GetInstance()->EnableVSync(false); resources.Release(bgTexture); - resources.Release(mBg); SAFE_DELETE(mGuiController); } @@ -292,12 +291,16 @@ void GameStateMenu::Update(float dt) //Force default, if necessary. if(options[Options::ACTIVE_PROFILE].str == "") options[Options::ACTIVE_PROFILE].str = "Default"; + + //Release splash texture + resources.Release(splashTex); + splashTex = NULL; + mSplash = NULL; //check for deleted collection / first-timer std::ifstream file(options.profileFile(PLAYER_COLLECTION).c_str()); if(file){ file.close(); - resources.Release(mSplash); currentState = MENU_STATE_MAJOR_MAINMENU | MENU_STATE_MINOR_NONE; }else{ currentState = MENU_STATE_MAJOR_FIRST_TIME | MENU_STATE_MINOR_NONE; @@ -409,8 +412,10 @@ void GameStateMenu::Render() renderer->ClearScreen(ARGB(0,0,0,0)); JLBFont * mFont = resources.GetJLBFont(Constants::MENU_FONT); if ((currentState & MENU_STATE_MAJOR) == MENU_STATE_MAJOR_LOADING_CARDS){ - if(!mSplash) - mSplash = resources.RetrieveQuad("splash.jpg"); + if(!splashTex){ + splashTex = resources.RetrieveTexture("splash.jpg",RETRIEVE_LOCK); + mSplash = resources.RetrieveTempQuad("splash.jpg"); + } if (mSplash){ renderer->RenderQuad(mSplash,0,0); }else{ diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index b961d88e1..f44f54db5 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -39,9 +39,14 @@ void GameStateShop::Start() altThumb[5] = resources.RetrieveTexture("white_thumb.jpg", RETRIEVE_LOCK); 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); + if(mBgTex) + mBg = resources.RetrieveQuad("shop.jpg"); + else + mBg = NULL; menuFont = resources.GetJLBFont(Constants::MENU_FONT); itemFont = resources.GetJLBFont(Constants::MAIN_FONT); @@ -123,6 +128,9 @@ void GameStateShop::load(){ void GameStateShop::End() { JRenderer::GetInstance()->EnableVSync(false); + resources.Release(mBgTex); + mBgTex = NULL; + mBg = NULL; //Release alternate thumbnails. for(int i=0;i<8;i++){ @@ -166,7 +174,7 @@ void GameStateShop::Render() //Erase JRenderer * r = JRenderer::GetInstance(); r->ClearScreen(ARGB(0,0,0,0)); - JQuad * mBg = resources.RetrieveQuad("shop.jpg"); + if (mBg) r->RenderQuad(mBg,0,0); if (shop) diff --git a/projects/mtg/src/GuiBackground.cpp b/projects/mtg/src/GuiBackground.cpp index 1eedb9561..ab77498c9 100644 --- a/projects/mtg/src/GuiBackground.cpp +++ b/projects/mtg/src/GuiBackground.cpp @@ -4,23 +4,14 @@ GuiBackground::GuiBackground() { - JTexture* texture = resources.GetTexture("backdrop.jpg"); - if (texture) - quad = NEW JQuad(texture, 0, 0, 480, 255); - else - { - quad = NULL; - GameApp::systemError = "Error loading background texture : " __FILE__; - } } GuiBackground::~GuiBackground() { - delete(quad); } void GuiBackground::Render() { JRenderer* renderer = JRenderer::GetInstance(); - renderer->RenderQuad(quad, 0, 18); + renderer->RenderQuad(resources.RetrieveTempQuad("backdrop.jpg"), 0, 18); } diff --git a/projects/mtg/src/GuiFrame.cpp b/projects/mtg/src/GuiFrame.cpp index 30578ef74..655bb9590 100644 --- a/projects/mtg/src/GuiFrame.cpp +++ b/projects/mtg/src/GuiFrame.cpp @@ -6,44 +6,31 @@ GuiFrame::GuiFrame() { if (resources.GetTexture("wood.png")) wood = resources.RetrieveQuad("wood.png", 0, 0, SCREEN_WIDTH, 28); - else - { + else{ wood = NULL; GameApp::systemError += "Can't load wood texture : " __FILE__ "\n"; } - if (resources.GetTexture("gold.png")) - { - gold1 = resources.RetrieveQuad("gold.png", 0, 0, SCREEN_WIDTH, 6, "gold1"); - gold2 = resources.RetrieveQuad("gold.png", 0, 6, SCREEN_WIDTH, 6, "gold2"); - } - else - { - gold1 = gold2 = NULL; - GameApp::systemError += "Can't load gold texture : " __FILE__ "\n"; - } - if (resources.GetTexture("goldglow.png")) - goldGlow = resources.RetrieveQuad("goldglow.png", 1, 1, SCREEN_WIDTH - 2, 18); - else - { - goldGlow = NULL; - GameApp::systemError += "Can't load gold glow texture : " __FILE__ "\n"; + + goldGlow = gold1 = gold2 = NULL; + if (resources.GetTexture("gold.png")){ + gold1 = resources.RetrieveQuad("gold.png", 0, 0, SCREEN_WIDTH, 6, "gold1"); + gold2 = resources.RetrieveQuad("gold.png", 0, 6, SCREEN_WIDTH, 6, "gold2"); + if (resources.GetTexture("goldglow.png")) + goldGlow = resources.RetrieveQuad("goldglow.png", 1, 1, SCREEN_WIDTH - 2, 18); + if (gold2){ + gold2->SetColor(ARGB(127, 255, 255, 255)); + gold2->SetHFlip(true); } + } step = 0.0; - if (gold2){ - gold2->SetColor(ARGB(127, 255, 255, 255)); - gold2->SetHFlip(true); - } + } GuiFrame::~GuiFrame() { - resources.Release(gold2); - resources.Release(gold1); - resources.Release(wood); - resources.Release(goldGlow); } void GuiFrame::Render() @@ -51,15 +38,21 @@ void GuiFrame::Render() JRenderer* renderer = JRenderer::GetInstance(); float sized = step / 4; if (sized > SCREEN_WIDTH) sized -= SCREEN_WIDTH; renderer->RenderQuad(wood, 0, 0); - renderer->RenderQuad(gold1, -sized, 16); - renderer->RenderQuad(gold1, -sized + 479, 16); + if(gold1){ + renderer->RenderQuad(gold1, -sized, 16); + renderer->RenderQuad(gold1, -sized + 479, 16); + + if(goldGlow){ + goldGlow->SetColor(ARGB((100+(rand()%50)), 255, 255, 255)); + renderer->RenderQuad(goldGlow, -sized, 9); + renderer->RenderQuad(goldGlow, -sized + 480, 9); + } - goldGlow->SetColor(ARGB((100+(rand()%50)), 255, 255, 255)); - renderer->RenderQuad(goldGlow, -sized, 9); - renderer->RenderQuad(goldGlow, -sized + 480, 9); - - renderer->RenderQuad(gold2, step / 2, 16); - renderer->RenderQuad(gold2, step / 2 - 479, 16); + if(gold2){ + renderer->RenderQuad(gold2, step / 2, 16); + renderer->RenderQuad(gold2, step / 2 - 479, 16); + } + } } void GuiFrame::Update(float dt) diff --git a/projects/mtg/src/GuiPhaseBar.cpp b/projects/mtg/src/GuiPhaseBar.cpp index 5babbd710..c835f992a 100644 --- a/projects/mtg/src/GuiPhaseBar.cpp +++ b/projects/mtg/src/GuiPhaseBar.cpp @@ -23,19 +23,19 @@ static int colors[] = GuiPhaseBar::GuiPhaseBar() : phase(GameObserver::GetInstance()->phaseRing->getCurrentPhase()), angle(0.0f) { - JTexture* texture = resources.GetTexture("phasebar.png"); - if (texture) - quad = NEW JQuad(texture, 0, 0, Width, Height); + JQuad * quad; + if ((quad = resources.GetQuad("phasebar")) != NULL){ + quad->mHeight = Height; + quad->mWidth = Width; + } else - { - quad = NULL; - GameApp::systemError = "Error loading phasebar texture : " __FILE__; - } + { + GameApp::systemError = "Error loading phasebar texture : " __FILE__; + } } GuiPhaseBar::~GuiPhaseBar() { - delete(quad); } void GuiPhaseBar::Update(float dt) @@ -49,6 +49,7 @@ void GuiPhaseBar::Render() static const float CENTER = SCREEN_HEIGHT_F / 2 + 10; JRenderer* renderer = JRenderer::GetInstance(); GameObserver * g = GameObserver::GetInstance(); + JQuad * quad = resources.GetQuad("phasebar"); unsigned p = (phase->id + Phases - 4) * (Width+1); float scale; float start = CENTER + (Width / 2) * angle * ICONSCALE / (M_PI / 6) - ICONSCALE * Width / 4; diff --git a/projects/mtg/src/ShopItem.cpp b/projects/mtg/src/ShopItem.cpp index 1effd29fb..b46eb0a85 100644 --- a/projects/mtg/src/ShopItem.cpp +++ b/projects/mtg/src/ShopItem.cpp @@ -107,9 +107,8 @@ int ShopItem::updateCount(DeckDataWrapper * ddw){ ShopItem::~ShopItem(){ OutputDebugString("delete shopitem\n"); - if(mRelease){ - resources.Release(thumb); - } + if(thumb) + resources.Release(thumb->mTex); SAFE_DELETE(mesh); } @@ -219,9 +218,12 @@ ShopItems::ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y myCollection = NEW DeckDataWrapper(NEW MTGDeck(options.profileFile(PLAYER_COLLECTION).c_str(), _collection)); showCardList = true; - mBgAA = resources.RetrieveQuad("shop_aliasing.png"); - if(mBgAA) + mBgAA = NULL; + mBgAATex = resources.RetrieveTexture("shop_aliasing.png",RETRIEVE_LOCK); + if(mBgAATex){ + mBgAA = resources.RetrieveQuad("shop_aliasing.png"); mBgAA->SetTextureRect(0,0,250,120); + } } @@ -453,7 +455,7 @@ ShopItems::~ShopItems(){ SAFE_DELETE(dialog); safeDeleteDisplay(); SAFE_DELETE(myCollection); - resources.Release(mBgAA); + resources.Release(mBgAATex); } ostream& ShopItem::toString(ostream& out) const diff --git a/projects/mtg/src/SimpleMenu.cpp b/projects/mtg/src/SimpleMenu.cpp index e17559c7c..61aaddf58 100644 --- a/projects/mtg/src/SimpleMenu.cpp +++ b/projects/mtg/src/SimpleMenu.cpp @@ -184,12 +184,6 @@ void SimpleMenu::Close() } void SimpleMenu::destroy(){ - resources.Release(SimpleMenu::spadeR); - resources.Release(SimpleMenu::spadeL); - resources.Release(SimpleMenu::side); - resources.Release(SimpleMenu::spadeRTex); - resources.Release(SimpleMenu::spadeLTex); - resources.Release(SimpleMenu::sideTex); SAFE_DELETE(SimpleMenu::jewel); SAFE_DELETE(SimpleMenu::stars); SAFE_DELETE(SimpleMenu::jewelTex); diff --git a/projects/mtg/src/WCachedResource.cpp b/projects/mtg/src/WCachedResource.cpp index 84283de59..c1d72601e 100644 --- a/projects/mtg/src/WCachedResource.cpp +++ b/projects/mtg/src/WCachedResource.cpp @@ -84,18 +84,6 @@ 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){ if(quad == NULL) return false; @@ -273,8 +261,8 @@ bool WCachedTexture::Attempt(string filename, int submode, int & error){ if(submode & TEXTURE_SUB_5551) format = GU_PSM_5551; - if(!realname.size()){ - error = CACHE_ERROR_404; + if(!realname.size()){ //realname should not be empty, even if file 404s. + error = CACHE_ERROR_BAD; return false; } @@ -344,7 +332,6 @@ bool WCachedSample::Attempt(string filename, int submode, int & error){ error = CACHE_ERROR_404; else error = CACHE_ERROR_BAD; - return false; } diff --git a/projects/mtg/src/WResourceManager.cpp b/projects/mtg/src/WResourceManager.cpp index 003c57907..fff2beaab 100644 --- a/projects/mtg/src/WResourceManager.cpp +++ b/projects/mtg/src/WResourceManager.cpp @@ -7,9 +7,9 @@ #include #include #include +#include #include "../include/WResourceManager.h" - int idCounter = OTHERS_OFFSET; WResourceManager resources; @@ -60,7 +60,7 @@ void WResourceManager::DebugRender(){ - sprintf(buf,"Total Size: %lu (%lu cached, %lu managed)",Size(),SizeCached(),SizeManaged()); + sprintf(buf,"Time: %u. Total Size: %lu (%lu cached, %lu managed). ",lastTime,Size(),SizeCached(),SizeManaged()); font->DrawString(buf, SCREEN_WIDTH-10,SCREEN_HEIGHT-15,JGETEXT_RIGHT); #ifdef DEBUG_CACHE @@ -125,7 +125,7 @@ unsigned int WResourceManager::CountManaged(){ } unsigned int WResourceManager::nowTime(){ - if(lastTime == 65535) + if(lastTime > MAX_CACHE_TIME) FlattenTimes(); return ++lastTime; @@ -336,25 +336,17 @@ void WResourceManager::Release(JTexture * tex){ textureWCache.Release(tex); } -void WResourceManager::Release(JQuad * quad){ - if(!quad) - return; - +void WResourceManager::Unmiss(string filename){ map::iterator it; - for(it = textureWCache.cache.begin();it!=textureWCache.cache.end();it++){ - if(it->second && it->second->ReleaseQuad(quad)) - break; - } - - if(it != textureWCache.cache.end() && it->second) - textureWCache.RemoveItem(it->second,false); //won't remove locked. + int id = textureWCache.makeID(0,filename,CACHE_NORMAL); + textureWCache.RemoveMiss(id); } + void WResourceManager::ClearUnlocked(){ textureWCache.ClearUnlocked(); sampleWCache.ClearUnlocked(); psiWCache.ClearUnlocked(); } - bool WResourceManager::Cleanup(){ int check = 0; @@ -1037,10 +1029,9 @@ cacheItem * WCache::Get(int id, string filename, int sty if(style != RETRIEVE_MANAGE){ it = cache.find(lookup); //Well, we've found something... - if(it != cache.end()) { - if (!it->second) - mError = CACHE_ERROR_404; - return it->second; //A hit. + if(it != cache.end()){ + mError = CACHE_ERROR_NONE; //We found an entry in cache, so not an error. + return it->second; //A hit, or maybe a miss. } } @@ -1143,23 +1134,35 @@ bool WCache::Cleanup(){ return true; } +bool WCacheSort::operator()(const WResource * l, const WResource * r){ + if(!l || !r) + return false; + return (l->lastTime < r->lastTime); +} + template unsigned int WCache::Flatten(){ - unsigned int youngest = (unsigned int) 65535; + vector items; unsigned int oldest = 0; + unsigned int lastSet = 0; + + if(!cache.size()) + return 0; for (typename map::iterator it = cache.begin(); it != cache.end(); ++it){ if(!it->second) continue; - if(it->second->lastTime < youngest) youngest = it->second->lastTime; - if(it->second->lastTime > oldest) oldest = it->second->lastTime; + items.push_back(it->second); } - for (typename map::iterator it = cache.begin(); it != cache.end(); ++it){ - if(!it->second) continue; - it->second->lastTime -= youngest; + sort(items.begin(), items.end(), WCacheSort()); + + for (typename vector::iterator it = items.begin(); it != items.end(); ++it){ + assert((*it) && (*it)->lastTime > lastSet); + lastSet = (*it)->lastTime; + (*it)->lastTime = ++oldest; } - return (oldest - youngest); + return oldest + 1; } template