Fixed a few crashes, better support for higan

Fixed AudioManager/InputManager unsigned vs signed comparison warnings.
Fixed a FolderData sorting crash (I can't believe nobody's reported
this).
Fixed a GuiTheme crash for empty paths.
Added the %ROM_RAW% tag, for the unescaped ROM name - useful for higan
on windows.
SystemData will now add folders that end in EXTENSION as GameDatas, and
not recurse through them.  Also useful for higan.
This commit is contained in:
Aloshi 2013-05-27 12:13:38 -05:00
parent 6d499d4e3a
commit 80e33849b5
7 changed files with 44 additions and 30 deletions

View file

@ -97,10 +97,12 @@ The COMMAND is the shell command ES will execute to start your emulator. As it i
The following "tags" are replaced by ES in COMMANDs:
`%ROM%` - Replaced with absolute path to the selected ROM.
`%ROM%` - Replaced with absolute path to the selected ROM, with most Bash special characters escaped with a backslash.
`%BASENAME%` - Replaced with the "base" name of the path to the selected ROM. For example, a path of "/foo/bar.rom", this tag would be "bar". This tag is useful for setting up AdvanceMAME.
`%ROM_RAW%` - Replaced with the unescaped absolute path to the selected ROM. If your emulator is picky about paths, you might want to use this instead of %ROM%, but enclosed in quotes.
gamelist.xml
============

View file

@ -22,7 +22,7 @@ void AudioManager::mixAudio(void *unused, Uint8 *stream, int len)
{
//calculate rest length of current sample
Uint32 restLength = (sound->getLength() - sound->getPosition());
if (restLength > len) {
if (restLength > (Uint32)len) {
//if stream length is smaller than smaple lenght, clip it
restLength = len;
}

View file

@ -37,7 +37,9 @@ bool filesort(FileData* file1, FileData* file2)
std::string name1 = file1->getName();
std::string name2 = file2->getName();
for(unsigned int i = 0; i < name1.length(); i++)
//min of name1/name2 .length()s
unsigned int count = name1.length() > name2.length() ? name2.length() : name1.length();
for(unsigned int i = 0; i < count; i++)
{
if(toupper(name1[i]) != toupper(name2[i]))
{

View file

@ -22,6 +22,7 @@ std::string GameData::getBashPath()
{
//a quick and dirty way to insert a backslash before most characters that would mess up a bash path
std::string path = mPath;
const char* invalidChars = " '\"\\!$^&*(){}[]?;<>";
for(unsigned int i = 0; i < path.length(); i++)
{

View file

@ -72,7 +72,7 @@ std::vector<InputDevice> InputManager::getInputDevices() const
if (GetRawInputDeviceList(deviceList, &nrOfDevices, sizeof(RAWINPUTDEVICELIST)) != -1)
{
//loop through input devices
for (int i = 0; i < nrOfDevices; i++)
for (unsigned int i = 0; i < nrOfDevices; i++)
{
//get device name
char * rawName = new char[2048];

View file

@ -77,6 +77,7 @@ void SystemData::launchGame(Window* window, GameData* game)
command = strreplace(command, "%ROM%", game->getBashPath());
command = strreplace(command, "%BASENAME%", game->getBaseName());
command = strreplace(command, "%ROM_RAW%", game->getPath());
LOG(LogInfo) << " " << command;
std::cout << "==============================================\n";
@ -120,7 +121,37 @@ void SystemData::populateFolder(FolderData* folder)
if(filePath.stem().string().empty())
continue;
if(fs::is_directory(filePath))
//this is a little complicated because we allow a list of extensions to be defined (delimited with a space)
//we first get the extension of the file itself:
std::string extension = filePath.extension().string();
std::string chkExt;
size_t extPos = 0;
//folders *can* also match the extension and be added as games - this is mostly just to support higan
//see issue #75: https://github.com/Aloshi/EmulationStation/issues/75
bool isGame = false;
do {
//now we loop through every extension in the list
size_t cpos = extPos;
extPos = mSearchExtension.find(" ", extPos);
chkExt = mSearchExtension.substr(cpos, ((extPos == std::string::npos) ? mSearchExtension.length() - cpos: extPos - cpos));
//if it matches, add it
if(chkExt == extension)
{
GameData* newGame = new GameData(this, filePath.string(), filePath.stem().string());
folder->pushFileData(newGame);
isGame = true;
break;
}else if(extPos != std::string::npos) //if not, add one to the "next position" marker to skip the space when reading the next extension
{
extPos++;
}
} while(extPos != std::string::npos && chkExt != "" && chkExt.find(".") != std::string::npos);
//add directories that also do not match an extension as folders
if(!isGame && fs::is_directory(filePath))
{
FolderData* newFolder = new FolderData(this, filePath.string(), filePath.stem().string());
populateFolder(newFolder);
@ -130,31 +161,6 @@ void SystemData::populateFolder(FolderData* folder)
delete newFolder;
else
folder->pushFileData(newFolder);
}else{
//this is a little complicated because we allow a list of extensions to be defined (delimited with a space)
//we first get the extension of the file itself:
std::string extension = filePath.extension().string();
std::string chkExt;
size_t extPos = 0;
do {
//now we loop through every extension in the list
size_t cpos = extPos;
extPos = mSearchExtension.find(" ", extPos);
chkExt = mSearchExtension.substr(cpos, ((extPos == std::string::npos) ? mSearchExtension.length() - cpos: extPos - cpos));
//if it matches, add it
if(chkExt == extension)
{
GameData* newGame = new GameData(this, filePath.string(), filePath.stem().string());
folder->pushFileData(newGame);
break;
}else if(extPos != std::string::npos) //if not, add one to the "next position" marker to skip the space when reading the next extension
{
extPos++;
}
} while(extPos != std::string::npos && chkExt != "" && chkExt.find(".") != std::string::npos);
}
}
}

View file

@ -332,6 +332,9 @@ Gui* GuiTheme::createElement(pugi::xml_node data, Gui* parent)
//expands a file path (./ becomes the directory of this theme file, ~/ becomes $HOME/)
std::string GuiTheme::expandPath(std::string path)
{
if(path.empty())
return "";
if(path[0] == '~')
path = getHomePath() + path.substr(1, path.length() - 1);
else if(path[0] == '.')