diff --git a/Package/Environment/Common/Layouts/Default 16x9/Age.otf b/Package/Environment/Common/Layouts/Default 16x9/Age.otf deleted file mode 100644 index 5d76781..0000000 Binary files a/Package/Environment/Common/Layouts/Default 16x9/Age.otf and /dev/null differ diff --git a/Package/Environment/Common/Layouts/Default 16x9/Lato-Black.ttf b/Package/Environment/Common/Layouts/Default 16x9/Lato-Black.ttf new file mode 100644 index 0000000..a87109f Binary files /dev/null and b/Package/Environment/Common/Layouts/Default 16x9/Lato-Black.ttf differ diff --git a/Package/Environment/Common/Layouts/Default 16x9/Layout.xml b/Package/Environment/Common/Layouts/Default 16x9/Layout.xml index ccaedaf..10be7ab 100644 --- a/Package/Environment/Common/Layouts/Default 16x9/Layout.xml +++ b/Package/Environment/Common/Layouts/Default 16x9/Layout.xml @@ -1,14 +1,77 @@ - - - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/Package/Environment/Common/Layouts/Default 16x9/Splash.xml b/Package/Environment/Common/Layouts/Default 16x9/Splash.xml new file mode 100644 index 0000000..71953ce --- /dev/null +++ b/Package/Environment/Common/Layouts/Default 16x9/Splash.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Package/Environment/Common/Layouts/Default 16x9/background.png b/Package/Environment/Common/Layouts/Default 16x9/background.png deleted file mode 100644 index 5d5f7e6..0000000 Binary files a/Package/Environment/Common/Layouts/Default 16x9/background.png and /dev/null differ diff --git a/Package/Environment/Common/Layouts/Default 16x9/square.png b/Package/Environment/Common/Layouts/Default 16x9/square.png deleted file mode 100644 index de7cb82..0000000 Binary files a/Package/Environment/Common/Layouts/Default 16x9/square.png and /dev/null differ diff --git a/Package/Environment/Common/Layouts/Splash/Layout.xml b/Package/Environment/Common/Layouts/Splash/Layout.xml new file mode 100644 index 0000000..71953ce --- /dev/null +++ b/Package/Environment/Common/Layouts/Splash/Layout.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Package/Environment/Common/Layouts/Splash/logo.png b/Package/Environment/Common/Layouts/Splash/logo.png new file mode 100644 index 0000000..54bd5ac Binary files /dev/null and b/Package/Environment/Common/Layouts/Splash/logo.png differ diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 7fd6d4f..e079a9a 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -97,7 +97,11 @@ void Page::SetMenu(ScrollingList *s) { // todo: delete the old menu Menu = s; - Menu->AddComponentForNotifications(this); + + if(Menu) + { + Menu->AddComponentForNotifications(this); + } } bool Page::AddComponent(Component *c) @@ -127,7 +131,7 @@ bool Page::IsIdle() { bool idle = true; - if(!Menu->IsIdle()) + if(Menu && !Menu->IsIdle()) { idle = false; } @@ -146,7 +150,7 @@ bool Page::IsIdle() bool Page::IsHidden() { - bool hidden = Menu->IsHidden(); + bool hidden = (!Menu || Menu->IsHidden()); for(unsigned int i = 0; hidden && i < NUM_LAYERS; ++i) { @@ -161,7 +165,10 @@ bool Page::IsHidden() void Page::Start() { - Menu->TriggerEnterEvent(); + if(Menu) + { + Menu->TriggerEnterEvent(); + } if(LoadSoundChunk) { @@ -179,8 +186,10 @@ void Page::Start() void Page::Stop() { - Menu->TriggerExitEvent(); - + if(Menu) + { + Menu->TriggerExitEvent(); + } if(UnloadSoundChunk) { UnloadSoundChunk->Play(); @@ -204,7 +213,10 @@ Item *Page::GetSelectedItem() void Page::RemoveSelectedItem() { //todo: change method to RemoveItem() and pass in SelectedItem - Menu->RemoveSelectedItem(); + if(Menu) + { + Menu->RemoveSelectedItem(); + } SelectedItem = NULL; } @@ -216,8 +228,11 @@ void Page::Highlight() if(item) { - Menu->TriggerHighlightEvent(item); - Menu->SetScrollActive(ScrollActive); + if(Menu) + { + Menu->TriggerHighlightEvent(item); + Menu->SetScrollActive(ScrollActive); + } for(unsigned int i = 0; i < NUM_LAYERS; ++i) { @@ -252,18 +267,24 @@ void Page::SetScrolling(ScrollDirection direction) break; } - Menu->SetScrollDirection(menuDirection); + if(Menu) + { + Menu->SetScrollDirection(menuDirection); + } } void Page::PageScroll(ScrollDirection direction) { - if(direction == ScrollDirectionForward) + if(Menu) { - Menu->PageDown(); - } - if(direction == ScrollDirectionBack) - { - Menu->PageUp(); + if(direction == ScrollDirectionForward) + { + Menu->PageDown(); + } + if(direction == ScrollDirectionBack) + { + Menu->PageUp(); + } } } @@ -271,16 +292,20 @@ void Page::PageScroll(ScrollDirection direction) void Page::SetItems(std::vector *items) { std::vector *sprites = ComponentItemBindingBuilder::BuildCollectionItems(items); - - Menu->SetItems(sprites); + if(Menu) + { + Menu->SetItems(sprites); + } } void Page::Update(float dt) { - Menu->Update(dt); - + if(Menu) + { + Menu->Update(dt); + } if(SelectedItemChanged && !HasSoundedWhenActive && HighlightSoundChunk) { // skip the first sound being played (as it is part of the on-enter) @@ -317,7 +342,10 @@ void Page::Draw() (*it)->Draw(); } - Menu->Draw(i); + if(Menu) + { + Menu->Draw(i); + } } } @@ -329,7 +357,10 @@ const std::string& Page::GetCollectionName() const void Page::FreeGraphicsMemory() { Logger::Write(Logger::ZONE_DEBUG, "Page", "Free"); - Menu->FreeGraphicsMemory(); + if(Menu) + { + Menu->FreeGraphicsMemory(); + } if(LoadSoundChunk) LoadSoundChunk->Free(); if(UnloadSoundChunk) UnloadSoundChunk->Free(); @@ -349,7 +380,10 @@ void Page::AllocateGraphicsMemory() { FirstSoundPlayed = false; Logger::Write(Logger::ZONE_DEBUG, "Page", "Allocating graphics memory"); - Menu->AllocateGraphicsMemory(); + if(Menu) + { + Menu->AllocateGraphicsMemory(); + } if(LoadSoundChunk) LoadSoundChunk->Allocate(); if(UnloadSoundChunk) UnloadSoundChunk->Allocate(); @@ -368,7 +402,10 @@ void Page::AllocateGraphicsMemory() void Page::LaunchEnter() { - Menu->LaunchEnter(); + if(Menu) + { + Menu->LaunchEnter(); + } for(unsigned int i = 0; i < NUM_LAYERS; ++i) { @@ -381,7 +418,10 @@ void Page::LaunchEnter() void Page::LaunchExit() { - Menu->LaunchExit(); + if(Menu) + { + Menu->LaunchExit(); + } for(unsigned int i = 0; i < NUM_LAYERS; ++i) { diff --git a/RetroFE/Source/Graphics/PageBuilder.cpp b/RetroFE/Source/Graphics/PageBuilder.cpp index 3c5d7a8..28a8e9c 100644 --- a/RetroFE/Source/Graphics/PageBuilder.cpp +++ b/RetroFE/Source/Graphics/PageBuilder.cpp @@ -229,6 +229,8 @@ Page *PageBuilder::BuildPage() Logger::Write(Logger::ZONE_DEBUG, "Layout", "Created page"); } + Logger::Write(Logger::ZONE_INFO, "Layout", "Initialized"); + return page; } @@ -307,14 +309,12 @@ bool PageBuilder::BuildComponents(xml_node<> *layout, Page *page) { xml_node<> *menuXml = layout->first_node("menu"); - if(!menuXml) + if(menuXml) { - Logger::Write(Logger::ZONE_ERROR, "Layout", "Missing menu tag"); - return false; + ScrollingList *scrollingList = BuildMenu(menuXml); + page->SetMenu(scrollingList); } - ScrollingList *scrollingList = BuildMenu(menuXml); - page->SetMenu(scrollingList); for(xml_node<> *componentXml = layout->first_node("container"); componentXml; componentXml = componentXml->next_sibling("container")) { diff --git a/RetroFE/Source/Main.cpp b/RetroFE/Source/Main.cpp index e0bb07d..204a52c 100644 --- a/RetroFE/Source/Main.cpp +++ b/RetroFE/Source/Main.cpp @@ -18,7 +18,6 @@ #include "Database/CollectionDatabase.h" #include "Collection/CollectionInfoBuilder.h" #include "Collection/CollectionInfo.h" -#include "Database/DB.h" #include "Database/MamelistMetadata.h" #include "Execute/Launcher.h" #include "Utility/Log.h" @@ -49,26 +48,9 @@ int main(int argc, char *argv[]) return -1; } - DB db(Configuration::GetAbsolutePath() + "/cache.db"); + RetroFE p(config); - if(!db.Initialize()) - { - return -1; - } - - - CollectionDatabase *cdb = InitializeCollectionDatabase(db, config); - if(!cdb) - { - return -1; - } - - RetroFE p(*cdb, config); - - if(p.Initialize()) - { - p.Run(); - } + p.Run(); p.DeInitialize(); @@ -184,24 +166,3 @@ bool StartLogging() return true; } -CollectionDatabase *InitializeCollectionDatabase(DB &db, Configuration &config) -{ - CollectionDatabase *cdb = NULL; - std::string dbFile = (Configuration::GetAbsolutePath() + "/cache.db"); - std::ifstream infile(dbFile.c_str()); - - cdb = new CollectionDatabase(db, config); - - if(!cdb->Initialize()) - { - delete cdb; - cdb = NULL; - } - else if(!cdb->Import()) - { - delete cdb; - cdb = NULL; - } - - return cdb; -} \ No newline at end of file diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 6a80110..40d27eb 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -33,11 +33,15 @@ #ifdef WIN32 #include #include +#include #endif -RetroFE::RetroFE(CollectionDatabase &db, Configuration &c) - : Config(c) - , CollectionDB(db) +RetroFE::RetroFE(Configuration &c) + : Initialized(false) + , InitializeThread(NULL) + , Config(c) + , Db(NULL) + , CollectionDB(NULL) , Input(Config) , KeyInputDisable(0) , CurrentTime(0) @@ -49,41 +53,88 @@ RetroFE::~RetroFE() DeInitialize(); } +CollectionDatabase *RetroFE::InitializeCollectionDatabase(DB &db, Configuration &config) +{ + CollectionDatabase *cdb = NULL; + + std::string dbFile = (Configuration::GetAbsolutePath() + "/cache.db"); + std::ifstream infile(dbFile.c_str()); + + cdb = new CollectionDatabase(db, config); + + if(!cdb->Initialize()) + { + delete cdb; + cdb = NULL; + } + else if(!cdb->Import()) + { + delete cdb; + cdb = NULL; + } + + return cdb; +} + void RetroFE::Render() { SDL_LockMutex(SDL::GetMutex()); SDL_SetRenderDrawColor(SDL::GetRenderer(), 0x0, 0x0, 0x00, 0xFF); SDL_RenderClear(SDL::GetRenderer()); - Page *page = PageChain.back(); - - if(page) + if(PageChain.size() > 0) { - page->Draw(); - } + Page *page = PageChain.back(); + if(page) + { + page->Draw(); + } + } SDL_RenderPresent(SDL::GetRenderer()); SDL_UnlockMutex(SDL::GetMutex()); } -bool RetroFE::Initialize() +int RetroFE::Initialize(void *context) { + int retVal = 0; + RetroFE *instance = static_cast(context); + Logger::Write(Logger::ZONE_INFO, "RetroFE", "Initializing"); - - if(!Input.Initialize()) return false; - if(!SDL::Initialize(Config)) return false; - FC.Initialize(); - bool videoEnable = true; int videoLoop = 0; - Config.GetProperty("videoEnable", videoEnable); - Config.GetProperty("videoLoop", videoLoop); + if(!instance->Input.Initialize()) return -1; + + instance->Db = new DB(Configuration::GetAbsolutePath() + "/cache.db"); + + if(!instance->Db->Initialize()) + { + Logger::Write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize database"); + return -1; + } + + + instance->CollectionDB = instance->InitializeCollectionDatabase(*instance->Db, instance->Config); + + if(!instance->CollectionDB) + { + Logger::Write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize CollectionDB!"); + delete instance->Db; + return -1; + } + + + instance->FC.Initialize(); + + instance->Config.GetProperty("videoEnable", videoEnable); + instance->Config.GetProperty("videoLoop", videoLoop); VideoFactory::SetEnabled(videoEnable); VideoFactory::SetNumLoops(videoLoop); - return true; + instance->Initialized = true; + return 0; } void RetroFE::LaunchEnter() @@ -149,32 +200,59 @@ bool RetroFE::DeInitialize() delete page; PageChain.pop_back(); } + if(Db) + { + delete Db; + Db = NULL; + } + if(CollectionDB) + { + delete CollectionDB; + Db = NULL; + } + Initialized = false; //todo: handle video deallocation return retVal; } void RetroFE::Run() { + if(!SDL::Initialize(Config)) return; + + InitializeThread = SDL_CreateThread(Initialize, "RetroFEInit", (void *)this); + + if(!InitializeThread) + { + Logger::Write(Logger::ZONE_INFO, "RetroFE", "Could not initialize RetroFE"); + return; + } + int attractModeTime = 0; std::string firstCollection = "Main"; bool running = true; Item *nextPageItem = NULL; bool adminMode = false; - RETROFE_STATE state = RETROFE_IDLE; + RETROFE_STATE state = RETROFE_NEW; Config.GetProperty("attractModeTime", attractModeTime); Config.GetProperty("firstCollection", firstCollection); Attract.SetIdleTime(static_cast(attractModeTime)); - LoadPage(firstCollection); + + int initializeStatus = 0; + + // load the initial splash screen, unload it once it is complete + Page * page = LoadSplashPage(); + bool splashMode = true; + + Launcher l(*this, Config); while (running) { float lastTime = 0; float deltaTime = 0; - Page *page = PageChain.back(); - Launcher l(*this, Config); + page = PageChain.back(); if(!page) { @@ -182,12 +260,22 @@ void RetroFE::Run() running = false; break; } - // todo: This could be transformed to use the state design pattern. switch(state) { case RETROFE_IDLE: - state = ProcessUserInput(page); + if(page && !splashMode) + { + state = ProcessUserInput(page); + } + + if(Initialized && splashMode) + { + SDL_WaitThread(InitializeThread, &initializeStatus); + state = RETROFE_BACK_WAIT; + page->Stop(); + } + break; case RETROFE_NEXT_PAGE_REQUEST: @@ -219,7 +307,8 @@ void RetroFE::Run() PageChain.pop_back(); delete page; - page = PageChain.back(); + page = (splashMode) ? LoadPage(firstCollection) : PageChain.back(); + splashMode = false; CurrentTime = (float)SDL_GetTicks() / 1000; page->AllocateGraphicsMemory(); @@ -267,12 +356,16 @@ void RetroFE::Run() SDL_Delay(static_cast(sleepTime)); } - Attract.Update(deltaTime, *page); + if(page) + { + Attract.Update(deltaTime, *page); + page->Update(deltaTime); + } - page->Update(deltaTime); Render(); } } + } @@ -372,6 +465,30 @@ RetroFE::RETROFE_STATE RetroFE::ProcessUserInput(Page *page) } +void RetroFE::WaitToInitialize() +{ + Logger::Write(Logger::ZONE_INFO, "RetroFE", "Loading splash screen"); + + PageBuilder pb("splash", "", Config, &FC); + Page * page = pb.BuildPage(); + + while(!Initialized) + { + SDL_SetRenderDrawColor(SDL::GetRenderer(), 0x0, 0x0, 0x00, 0xFF); + SDL_RenderClear(SDL::GetRenderer()); +// image->Draw(); + //todo: decouple page from a collection + page->Draw(); + SDL_RenderPresent(SDL::GetRenderer()); + + SDL_Delay(2000); + } + + int status = 0; + delete page; + SDL_WaitThread(InitializeThread, &status); +} + Page *RetroFE::LoadPage(std::string collectionName) { @@ -405,14 +522,27 @@ Page *RetroFE::LoadPage(std::string collectionName) return page; } +Page *RetroFE::LoadSplashPage() +{ + PageBuilder pb("splash", "", Config, &FC); + std::vector *coll = new std::vector(); + Page * page = pb.BuildPage(); + page->SetItems(coll); + page->Start(); + PageChain.push_back(page); + + return page; +} + std::vector *RetroFE::GetCollection(std::string collectionName) { - std::vector *collection = new std::vector(); // the page will deallocate this once its done + // the page will deallocate this once its done + std::vector *collection = new std::vector(); MenuParser mp; - mp.GetMenuItems(&CollectionDB, collectionName, *collection); - CollectionDB.GetCollection(collectionName, *collection); + mp.GetMenuItems(CollectionDB, collectionName, *collection); + CollectionDB->GetCollection(collectionName, *collection); if(collection->size() == 0) { diff --git a/RetroFE/Source/RetroFE.h b/RetroFE/Source/RetroFE.h index 1e4a54a..c2054f1 100644 --- a/RetroFE/Source/RetroFE.h +++ b/RetroFE/Source/RetroFE.h @@ -5,6 +5,7 @@ #include "Collection/Item.h" #include "Control/UserInput.h" +#include "Database/DB.h" #include "Execute/AttractMode.h" #include "Graphics/FontCache.h" #include "Video/IVideo.h" @@ -19,9 +20,8 @@ class Page; class RetroFE { public: - RetroFE(CollectionDatabase &db, Configuration &c); + RetroFE(Configuration &c); virtual ~RetroFE(); - bool Initialize(); bool DeInitialize(); void Run(); void FreeGraphicsMemory(); @@ -29,6 +29,10 @@ public: void LaunchEnter(); void LaunchExit(); private: + bool Initialized; + SDL_Thread *InitializeThread; + static int Initialize(void *context); + enum RETROFE_STATE { RETROFE_IDLE, @@ -43,15 +47,19 @@ private: }; void Render(); + CollectionDatabase *InitializeCollectionDatabase(DB &db, Configuration &config); bool Back(bool &exit); void Quit(); + void WaitToInitialize(); Page *LoadPage(std::string collectionName); + Page *LoadSplashPage(); RETROFE_STATE ProcessUserInput(Page *page); void Update(float dt, bool scrollActive); std::string GetLayout(std::string collectionName); std::vector *GetCollection(std::string collectionName); Configuration &Config; - CollectionDatabase &CollectionDB; + DB *Db; + CollectionDatabase *CollectionDB; UserInput Input; std::list PageChain; float KeyInputDisable;