usbloadergx/source/settings/CGameSettings.cpp

388 lines
8.4 KiB
C++

/****************************************************************************
* Copyright (C) 2010
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CGameSettings.h"
#include "FileOperations/fileops.h"
CGameSettings GameSettings;
const char * VideoMap[] =
{
"system",
"game",
"patch",
"pal50",
"pal60",
"ntsc",
NULL
};
const char * LanguageMap[] =
{
"console",
"japanese",
"english",
"german",
"french",
"spanish",
"italian",
"dutch",
"schinese",
"tchinese",
"korean",
NULL
};
CGameSettings::CGameSettings()
{
}
CGameSettings::~CGameSettings()
{
}
GameCFG * CGameSettings::GetGameCFG(const char * id)
{
if(!id)
return NULL;
for(u32 i = 0; i < GameList.size(); ++i)
{
if(strncmp(id, GameList[i].id, 6) == 0)
{
return &GameList[i];
}
}
return NULL;
}
bool CGameSettings::AddGame(const GameCFG & NewGame)
{
for(u32 i = 0; i < GameList.size(); ++i)
{
if(strncmp(NewGame.id, GameList[i].id, 6) == 0)
{
memcpy(&GameList[i], &NewGame, sizeof(GameCFG));
return true;
}
}
GameList.push_back(NewGame);
return true;
}
bool CGameSettings::RemoveAll()
{
GameList.clear();
std::vector<GameCFG>().swap(GameList);
return Save();
}
bool CGameSettings::Remove(const char * id)
{
if(!id)
return false;
for(u32 i = 0; i < GameList.size(); ++i)
{
if(strncmp(id, GameList[i].id, 6) == 0)
{
GameList.erase(GameList.begin()+i);
break;
}
}
return true;
}
bool CGameSettings::Load(const char * path)
{
char line[1024];
char filepath[300];
snprintf(filepath, sizeof(filepath), "%sGXGameSettings.cfg", path);
ConfigPath = filepath;
FILE *file = fopen(filepath, "r");
if (!file) return false;
while (fgets(line, sizeof(line), file))
{
if (line[0] == '#')
continue;
this->ParseLine(line);
}
fclose(file);
return true;
}
bool CGameSettings::Save()
{
char filepath[300];
strcpy(filepath, ConfigPath.c_str());
char * ptr = strrchr(filepath, '/');
if(ptr)
ptr[0] = 0;
CreateSubfolder(filepath);
FILE * f = fopen(ConfigPath.c_str(), "w");
if (!f) return false;
fprintf(f, "# USB Loader settings file\n");
fprintf(f, "# note: this file is automatically generated\n");
fprintf(f, "# Num Games: %d\n", GameList.size());
for (u32 i = 0; i < GameList.size(); ++i)
{
fprintf(f, "game:%s = ", GameList[i].id);
fprintf(f, "video:%s; ", VideoMap[GameList[i].video]);
fprintf(f, "language:%s; ", LanguageMap[GameList[i].language]);
fprintf(f, "ocarina:%d; ", GameList[i].ocarina);
fprintf(f, "vipatch:%d; ", GameList[i].vipatch);
fprintf(f, "ios:%d; ", GameList[i].ios);
fprintf(f, "parentalcontrol:%d; ", GameList[i].parentalcontrol);
fprintf(f, "errorfix002:%d; ", GameList[i].errorfix002);
fprintf(f, "iosreloadblock:%d; ", GameList[i].iosreloadblock);
fprintf(f, "patchcountrystrings:%d; ", GameList[i].patchcountrystrings);
fprintf(f, "loadalternatedol:%d; ", GameList[i].loadalternatedol);
fprintf(f, "alternatedolstart:%d; ", GameList[i].alternatedolstart);
fprintf(f, "alternatedolname:%s; ", GameList[i].alternatedolname);
fprintf(f, "returnTo:%d;\n", GameList[i].returnTo);
}
fprintf(f, "# END\n");
fclose(f);
return true;
}
bool CGameSettings::SetSetting(GameCFG & game, char *name, char *value)
{
int i = 0;
if (strcmp(name, "video") == 0)
{
for(i = 0; VideoMap[i] != NULL; ++i)
{
if(strcasecmp(value, VideoMap[i]) == 0)
{
game.video = i;
break;
}
}
return true;
}
else if(strcmp(name, "language") == 0)
{
for(i = 0; LanguageMap[i] != NULL; ++i)
{
if(strcasecmp(value, LanguageMap[i]) == 0)
{
game.language = i;
break;
}
}
return true;
}
else if(strcmp(name, "ocarina") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.ocarina = i;
}
return true;
}
else if(strcmp(name, "vipatch") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.vipatch = i;
}
return true;
}
else if(strcmp(name, "ios") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.ios = i;
}
return true;
}
else if(strcmp(name, "parentalcontrol") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.parentalcontrol = i;
}
return true;
}
else if(strcmp(name, "errorfix002") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.errorfix002 = i;
}
return true;
}
else if(strcmp(name, "iosreloadblock") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.iosreloadblock = i;
}
return true;
}
else if(strcmp(name, "loadalternatedol") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.loadalternatedol = i;
}
return true;
}
else if(strcmp(name, "alternatedolstart") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.alternatedolstart = i;
}
return true;
}
else if(strcmp(name, "patchcountrystrings") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.patchcountrystrings = i;
}
return true;
}
else if(strcmp(name, "alternatedolname") == 0)
{
snprintf(game.alternatedolname, sizeof(game.alternatedolname), value);
return true;
}
else if(strcmp(name, "returnTo") == 0)
{
if (sscanf(value, "%d", &i) == 1)
{
game.returnTo = i;
}
return true;
}
return false;
}
bool CGameSettings::ReadGameID(const char * src, char * GameID, int size)
{
if(strncasecmp(src, "game:", 5) != 0)
return false;
char * ptr = strchr(src, ':');
if(!ptr)
return false;
ptr++;
int i = 0;
for(i = 0; i < size; i++, ptr++)
{
if(*ptr == ' ' || *ptr == '\0')
break;
GameID[i] = *ptr;
}
GameID[i] = 0;
return true;
}
void CGameSettings::ParseLine(char *line)
{
char name[1024], value[1024];
char GameID[8];
if(!ReadGameID(line, GameID, 6))
return;
if(strlen(GameID) != 6)
return;
GameCFG NewCFG;
memset(&NewCFG, 0, sizeof(GameCFG));
strcpy(NewCFG.id, GameID);
char * LinePtr = strchr(line, '=');
while(LinePtr != NULL)
{
LinePtr++;
char * eq = strchr(LinePtr, ':');
if (!eq) break;
this->TrimLine(name, LinePtr, sizeof(name));
this->TrimLine(value, eq + 1, sizeof(value));
SetSetting(NewCFG, name, value);
LinePtr = strchr(LinePtr, ';');
}
AddGame(NewCFG);
}
void CGameSettings::TrimLine(char *dest, const char *src, int size)
{
while (*src == ' ')
src++;
int i = 0;
for(i = 0; i < size; i++, src++)
{
if(*src == ':' || *src == ';' || *src == '\n' ||
*src == '\r' || *src == '\0')
break;
dest[i] = *src;
}
dest[i] = '\0';
}