Browsing multiple systems is now possible! Just press left or right.

Also, config files can have comments (lines that start wih #).
This commit is contained in:
Aloshi 2012-07-21 15:57:53 -05:00
parent 561e4a7f44
commit f368a1f4cd
12 changed files with 107 additions and 39 deletions

View file

@ -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.

0
mame/fakemamegame.zip Normal file
View file

View file

@ -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++;

View file

@ -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);

View file

@ -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);

View file

@ -4,6 +4,8 @@
#include <fstream>
#include <stdlib.h>
std::vector<SystemData*> 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*> 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<SystemData*> returnVec;
std::ifstream file(path.c_str());
if(file.is_open())
{
std::string line;
@ -120,8 +124,8 @@ std::vector<SystemData*> 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*> 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*> 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();
}

View file

@ -18,7 +18,11 @@ public:
void buildGameList();
void launchGame(unsigned int i);
static std::vector<SystemData*> loadConfig(std::string path);
//static std::vector<SystemData*> loadConfig(std::string path);
static void deleteSystems();
static void loadConfig(std::string path);
static std::vector<SystemData*> sSystemVector;
private:
std::string mName;
std::string mStartPath;

View file

@ -1,17 +1,16 @@
#include "GuiGameList.h"
#include "../InputManager.h"
#include <iostream>
#include <SDL/SDL.h>
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);
}
}

View file

@ -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;
};

View file

@ -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()

View file

@ -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";

View file

@ -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