diff --git a/README.md b/README.md index c29b444c6..598663493 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,5 @@ You can build it by just running `make`. Configuring =========== -At the moment, the software looks for a file named "systems.cfg" in the directory it is run from. An example is included, though at the moment only one system should be defined. +At the moment, the software looks for a file named "systems.cfg" in the directory it is run from. An example is included. + diff --git a/mame/fakemamegame.zip b/mame/fakemamegame.zip new file mode 100644 index 000000000..e69de29bb diff --git a/src/GameData.cpp b/src/GameData.cpp index 29ba78ba7..0de2fef29 100644 --- a/src/GameData.cpp +++ b/src/GameData.cpp @@ -17,11 +17,11 @@ std::string GameData::getName() std::string GameData::getValidPath() { - //a quick and dirty way to insert a backslash before spaces + //a quick and dirty way to insert a backslash before most characters that would mess up a bash path std::string path = mPath; for(unsigned int i = 0; i < path.length(); i++) { - if(path[i] == *" ") + if(path[i] == *" " || path[i] == *"'" || path[i] == *"\"" || path[i] == *"\\") { path.insert(i, "\\"); i++; diff --git a/src/InputManager.cpp b/src/InputManager.cpp index ef0bb9a38..029858210 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -56,6 +56,7 @@ void InputManager::processEvent(SDL_Event* event) //catch emergency quit event if(event->key.keysym.sym == SDLK_F4) { + //I have no idea if SDL will delete this event, but we're quitting, so I don't think it really matters SDL_Event* quit = new SDL_Event(); quit->type = SDL_QUIT; SDL_PushEvent(quit); diff --git a/src/Renderer_draw.cpp b/src/Renderer_draw.cpp index abae50881..5f9332eeb 100644 --- a/src/Renderer_draw.cpp +++ b/src/Renderer_draw.cpp @@ -29,7 +29,8 @@ void Renderer::drawText(std::string text, int x, int y, int color) if(!font) loadFonts(); - //SDL_Color sdlcolor = (SDL_Color)color; //SDL_MapRGB(//{(char)color, (char)(*(&color + 1)), (char)(*(&color + 2))}; + //SDL_Color is a struct of four bytes, with the first three being colors. An int is four bytes. + //So, we can just pretend the int is an SDL_Color. SDL_Color* sdlcolor = (SDL_Color*)&color; SDL_Surface* textSurf = TTF_RenderText_Blended(font, text.c_str(), *sdlcolor); diff --git a/src/SystemData.cpp b/src/SystemData.cpp index f26f54311..f498e9d6c 100644 --- a/src/SystemData.cpp +++ b/src/SystemData.cpp @@ -4,6 +4,8 @@ #include #include +std::vector SystemData::sSystemVector; + namespace fs = boost::filesystem; SystemData::SystemData(std::string name, std::string startPath, std::string extension, std::string command) @@ -103,15 +105,17 @@ std::string SystemData::getName() return mName; } -//creates system files from information located in a config file -std::vector SystemData::loadConfig(std::string path) + + + +//creates systems from information located in a config file +void SystemData::loadConfig(std::string path) { + deleteSystems(); + std::cout << "Loading system config file \"" << path << "\"...\n"; - std::vector returnVec; - std::ifstream file(path.c_str()); - if(file.is_open()) { std::string line; @@ -120,8 +124,8 @@ std::vector SystemData::loadConfig(std::string path) { std::getline(file, line); - //skip blank lines - if(line.empty()) + //skip blank lines and comments + if(line.empty() || line[0] == *"#") continue; //find the name (left of the equals sign) and the value (right of the equals sign) @@ -141,6 +145,7 @@ std::vector SystemData::loadConfig(std::string path) if(lineValid) { + //map the value to the appropriate variable if(varName == "NAME") sysName = varValue; else if(varName == "PATH") @@ -155,21 +160,30 @@ std::vector SystemData::loadConfig(std::string path) //we have all our variables - create the system object if(!sysName.empty() && !sysPath.empty() &&!sysExtension.empty() && !sysCommand.empty()) { - returnVec.push_back(new SystemData(sysName, sysPath, sysExtension, sysCommand)); + sSystemVector.push_back(new SystemData(sysName, sysPath, sysExtension, sysCommand)); //reset the variables for the next block (should there be one) - sysName = ""; sysPath = ""; sysExtension = ""; + sysName = ""; sysPath = ""; sysExtension = ""; sysCommand = ""; } }else{ std::cerr << "Error reading config file \"" << path << "\" - no equals sign found on line \"" << line << "\"!\n"; - return returnVec; + return; } } }else{ std::cerr << "Error - could not load config file \"" << path << "\"!\n"; - return returnVec; + return; } - std::cout << "Finished loading config file - created " << returnVec.size() << " systems.\n"; - return returnVec; + std::cout << "Finished loading config file - created " << sSystemVector.size() << " systems.\n"; + return; +} + +void SystemData::deleteSystems() +{ + for(unsigned int i = 0; i < sSystemVector.size(); i++) + { + delete sSystemVector.at(i); + } + sSystemVector.clear(); } diff --git a/src/SystemData.h b/src/SystemData.h index dd954a4e9..12451b953 100644 --- a/src/SystemData.h +++ b/src/SystemData.h @@ -18,7 +18,11 @@ public: void buildGameList(); void launchGame(unsigned int i); - static std::vector loadConfig(std::string path); + //static std::vector loadConfig(std::string path); + static void deleteSystems(); + static void loadConfig(std::string path); + + static std::vector sSystemVector; private: std::string mName; std::string mStartPath; diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index ae618d272..d5cca07be 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -1,17 +1,16 @@ #include "GuiGameList.h" #include "../InputManager.h" #include -#include -GuiGameList::GuiGameList(SystemData* system) +GuiGameList::GuiGameList() { - mSystem = system; + std::cout << "Creating GuiGameList\n"; mList = new GuiList(); - updateList(); - addChild(mList); + setSystemId(0); + Renderer::registerComponent(this); InputManager::registerComponent(this); } @@ -19,9 +18,25 @@ GuiGameList::GuiGameList(SystemData* system) GuiGameList::~GuiGameList() { Renderer::unregisterComponent(this); + delete mList; + InputManager::unregisterComponent(this); } +void GuiGameList::setSystemId(int id) +{ + //make sure the id is within range + if(id >= (int)SystemData::sSystemVector.size()) + id -= SystemData::sSystemVector.size(); + if(id < 0) + id += SystemData::sSystemVector.size(); + + mSystemId = id; + mSystem = SystemData::sSystemVector.at(mSystemId); + + updateList(); +} + void GuiGameList::onRender() { Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF); @@ -31,11 +46,21 @@ void GuiGameList::onRender() void GuiGameList::onInput(InputManager::InputButton button, bool keyDown) { - if(button == InputManager::BUTTON1 && keyDown) + if(button == InputManager::BUTTON1 && mSystem->getGameCount() > 0) { - SDL_EnableKeyRepeat(0, 0); - mSystem->launchGame(mList->getSelection()); - SDL_EnableKeyRepeat(500, 100); + //SDL_EnableKeyRepeat(0, 0); + if(!keyDown) + mSystem->launchGame(mList->getSelection()); + //SDL_EnableKeyRepeat(500, 100); + } + + if(button == InputManager::RIGHT && keyDown) + { + setSystemId(mSystemId + 1); + } + if(button == InputManager::LEFT && keyDown) + { + setSystemId(mSystemId - 1); } } @@ -46,6 +71,7 @@ void GuiGameList::updateList() for(unsigned int i = 0; i < mSystem->getGameCount(); i++) { GameData* game = mSystem->getGame(i); + mList->addObject(game->getName(), game); } } diff --git a/src/components/GuiGameList.h b/src/components/GuiGameList.h index 78aa357d9..ddc78d1eb 100644 --- a/src/components/GuiGameList.h +++ b/src/components/GuiGameList.h @@ -10,15 +10,17 @@ class GuiGameList : GuiComponent { public: - GuiGameList(SystemData* system); + GuiGameList(); ~GuiGameList(); void updateList(); + void setSystemId(int id); void onRender(); void onInput(InputManager::InputButton button, bool keyDown); private: SystemData* mSystem; + int mSystemId; GuiList* mList; }; diff --git a/src/components/GuiList.cpp b/src/components/GuiList.cpp index 7973a1c6e..2a9597539 100644 --- a/src/components/GuiList.cpp +++ b/src/components/GuiList.cpp @@ -17,16 +17,20 @@ void GuiList::onRender() const int cutoff = 40; const int entrySize = 40; + int startEntry = 0; + //number of entries that can fit on the screen simultaniously int screenCount = (Renderer::getScreenHeight() - cutoff) / entrySize; screenCount -= 1; - int startEntry = mSelection - (screenCount * 0.5); - if(startEntry < 0) - startEntry = 0; - if(startEntry >= (int)mNameVector.size() - screenCount) - startEntry = mNameVector.size() - screenCount; - + if((int)mNameVector.size() >= screenCount) + { + startEntry = mSelection - (screenCount * 0.5); + if(startEntry < 0) + startEntry = 0; + if(startEntry >= (int)mNameVector.size() - screenCount) + startEntry = mNameVector.size() - screenCount; + } int y = cutoff; int color = 0xFF0000; @@ -37,7 +41,11 @@ void GuiList::onRender() return; } - for(int i = startEntry; i < startEntry + screenCount; i++) + int listCutoff = startEntry + screenCount; + if(listCutoff > (int)mNameVector.size()) + listCutoff = mNameVector.size(); + + for(int i = startEntry; i < listCutoff; i++) { if(mSelection == i) { @@ -77,6 +85,7 @@ void GuiList::clear() { mNameVector.clear(); mPointerVector.clear(); + mSelection = 0; } std::string GuiList::getSelectedName() diff --git a/src/main.cpp b/src/main.cpp index 74ec198d5..bc243e446 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,9 +34,8 @@ int main() //GuiTitleScreen* testGui = new GuiTitleScreen(); - //test systemData - SystemData* testSystem = SystemData::loadConfig("./systems.cfg").at(0); - GuiGameList* testGui = new GuiGameList(testSystem); + SystemData::loadConfig("./systems.cfg"); + GuiGameList* testGui = new GuiGameList(); bool running = true; @@ -65,7 +64,7 @@ int main() } delete testGui; - delete testSystem; + SystemData::deleteSystems(); std::cout << "EmulationStation cleanly shutting down...\n"; diff --git a/systems.cfg b/systems.cfg index c7730a411..2b3faa515 100644 --- a/systems.cfg +++ b/systems.cfg @@ -2,3 +2,14 @@ NAME=Super Nintendo Entertainment System PATH=./snes/ EXTENSION=.smc COMMAND=retroarch -L ~/libretro-pocketsnes.so %ROM% + +NAME=MAME +PATH=./mame/ +EXTENSION=.zip +COMMAND=echo %ROM% + +# This is just a dud to test error handling. Also, comment support! Woo! +NAME=Fake System +PATH=./fakedir/ +EXTENSION=.fake +COMMAND=this will never be called