2009-07-31 14:45:14 +02:00
|
|
|
/*
|
|
|
|
* gct.h
|
|
|
|
* Class to handle Ocarina TXT Cheatfiles
|
|
|
|
* nIxx
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
2009-10-14 19:20:24 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2009-07-31 14:45:14 +02:00
|
|
|
#include "gct.h"
|
|
|
|
|
|
|
|
#define ERRORRANGE "Error: CheatNr out of range"
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
GCTCheats::GCTCheats(void)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
iCntCheats = 0;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
GCTCheats::~GCTCheats(void)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
string sGameID = "";
|
|
|
|
string sGameTitle = "";
|
|
|
|
/*string sCheatName[MAXCHEATS];
|
|
|
|
string sCheats[MAXCHEATS];
|
|
|
|
string sCheatComment[MAXCHEATS];*/
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
int GCTCheats::getCnt()
|
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
return iCntCheats;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
string GCTCheats::getGameName(void)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
return sGameTitle;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
string GCTCheats::getGameID(void)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
return sGameID;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
string GCTCheats::getCheat(int nr)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
if (nr <= (iCntCheats - 1))
|
|
|
|
{
|
|
|
|
return sCheats[nr];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return ERRORRANGE;
|
|
|
|
}
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
string GCTCheats::getCheatName(int nr)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
if (nr <= (iCntCheats - 1))
|
|
|
|
{
|
|
|
|
return sCheatName[nr];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return ERRORRANGE;
|
|
|
|
}
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
string GCTCheats::getCheatComment(int nr)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
if (nr <= (iCntCheats - 1))
|
|
|
|
{
|
|
|
|
return sCheatComment[nr];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return ERRORRANGE;
|
|
|
|
}
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
int GCTCheats::createGCT(int nr, const char * filename)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2009-09-18 10:28:31 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
if (nr == 0) return 0;
|
2009-09-18 10:28:31 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
ofstream filestr;
|
|
|
|
filestr.open(filename);
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
if (filestr.fail()) return 0;
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
//Header and Footer
|
|
|
|
char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde };
|
|
|
|
char footer[] = { 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
string buf = getCheat(nr);
|
|
|
|
filestr.write(header, sizeof(header));
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
int x = 0;
|
|
|
|
long int li;
|
|
|
|
int len = buf.size();
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
while (x < len)
|
|
|
|
{
|
|
|
|
string temp = buf.substr(x, 2);
|
|
|
|
li = strtol(temp.c_str(), NULL, 16);
|
|
|
|
temp = li;
|
|
|
|
filestr.write(temp.c_str(), 1);
|
|
|
|
x += 2;
|
|
|
|
}
|
|
|
|
filestr.write(footer, sizeof(footer));
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
filestr.close();
|
|
|
|
return 1;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
int GCTCheats::createGCT(const char * chtbuffer, const char * filename)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2009-09-18 10:28:31 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
ofstream filestr;
|
|
|
|
filestr.open(filename);
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
if (filestr.fail()) return 0;
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
//Header and Footer
|
|
|
|
char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde };
|
|
|
|
char footer[] = { 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
string buf = chtbuffer;
|
|
|
|
filestr.write(header, sizeof(header));
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
int x = 0;
|
|
|
|
long int li;
|
|
|
|
int len = buf.size();
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
while (x < len)
|
|
|
|
{
|
|
|
|
string temp = buf.substr(x, 2);
|
|
|
|
li = strtol(temp.c_str(), NULL, 16);
|
|
|
|
temp = li;
|
|
|
|
filestr.write(temp.c_str(), 1);
|
|
|
|
x += 2;
|
|
|
|
}
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
filestr.write(footer, sizeof(footer));
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
filestr.close();
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
return 1;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
int GCTCheats::createGCT(int nr[], int cnt, const char * filename)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2009-07-31 14:45:14 +02:00
|
|
|
|
2011-07-26 00:28:22 +02:00
|
|
|
if (cnt == 0) return 0;
|
|
|
|
|
|
|
|
ofstream filestr;
|
|
|
|
filestr.open(filename);
|
|
|
|
|
|
|
|
if (filestr.fail()) return 0;
|
|
|
|
|
|
|
|
//Header and Footer
|
|
|
|
char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde };
|
|
|
|
char footer[] = { 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
|
|
|
|
|
|
filestr.write(header, sizeof(header));
|
|
|
|
|
|
|
|
int c = 0;
|
|
|
|
while (c != cnt)
|
|
|
|
{
|
|
|
|
int actnr = nr[c];
|
|
|
|
string buf = getCheat(actnr);
|
|
|
|
long int li;
|
|
|
|
int len = buf.size();
|
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
while (x < len)
|
|
|
|
{
|
|
|
|
string temp = buf.substr(x, 2);
|
|
|
|
li = strtol(temp.c_str(), NULL, 16);
|
|
|
|
temp = li;
|
|
|
|
filestr.write(temp.c_str(), 1);
|
|
|
|
x += 2;
|
|
|
|
}
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
|
|
|
|
filestr.write(footer, sizeof(footer));
|
|
|
|
filestr.close();
|
|
|
|
return 1;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
int GCTCheats::openTxtfile(const char * filename)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
ifstream filestr;
|
|
|
|
int i = 0;
|
|
|
|
string str;
|
|
|
|
filestr.open(filename);
|
|
|
|
|
|
|
|
if (filestr.fail()) return 0;
|
|
|
|
|
|
|
|
filestr.seekg(0, ios_base::end);
|
|
|
|
int size = filestr.tellg();
|
|
|
|
if (size <= 0) return -1;
|
|
|
|
filestr.seekg(0, ios_base::beg);
|
|
|
|
|
|
|
|
getline(filestr, sGameID);
|
|
|
|
if (sGameID[sGameID.length() - 1] == '\r') sGameID.erase(sGameID.length() - 1);
|
|
|
|
|
|
|
|
getline(filestr, sGameTitle);
|
|
|
|
if (sGameTitle[sGameTitle.length() - 1] == '\r') sGameTitle.erase(sGameTitle.length() - 1);
|
|
|
|
|
|
|
|
getline(filestr, sCheatName[i]); // skip first line if file uses CRLF
|
|
|
|
if (!sGameTitle[sGameTitle.length() - 1] == '\r') filestr.seekg(0, ios_base::beg);
|
|
|
|
|
|
|
|
while (!filestr.eof())
|
|
|
|
{
|
|
|
|
getline(filestr, sCheatName[i]); // '\n' delimiter by default
|
|
|
|
if (sCheatName[i][sCheatName[i].length() - 1] == '\r') sCheatName[i].erase(sCheatName[i].length() - 1);
|
|
|
|
|
|
|
|
string cheatdata;
|
|
|
|
bool emptyline = false;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
getline(filestr, str);
|
|
|
|
if (str[str.length() - 1] == '\r') str.erase(str.length() - 1);
|
|
|
|
|
|
|
|
if (str == "" || str[0] == '\r' || str[0] == '\n')
|
|
|
|
{
|
|
|
|
emptyline = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsCode(str))
|
|
|
|
{
|
|
|
|
// remove any garbage (comment) after code
|
|
|
|
while (str.size() > 17)
|
|
|
|
{
|
|
|
|
str.erase(str.length() - 1);
|
|
|
|
}
|
|
|
|
cheatdata.append(str);
|
|
|
|
size_t found = cheatdata.find(' ');
|
|
|
|
cheatdata.replace(found, 1, "");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//printf("%i",str.size());
|
|
|
|
sCheatComment[i] = str;
|
|
|
|
}
|
|
|
|
if (filestr.eof()) break;
|
|
|
|
|
|
|
|
} while (!emptyline);
|
|
|
|
|
|
|
|
sCheats[i] = cheatdata;
|
|
|
|
i++;
|
|
|
|
if (i == MAXCHEATS) break;
|
|
|
|
}
|
|
|
|
iCntCheats = i;
|
|
|
|
filestr.close();
|
|
|
|
return 1;
|
2009-07-31 14:45:14 +02:00
|
|
|
}
|
2009-09-16 06:05:50 +02:00
|
|
|
|
2010-09-24 02:48:03 +02:00
|
|
|
bool GCTCheats::IsCode(const std::string& str)
|
2010-09-19 01:16:05 +02:00
|
|
|
{
|
2011-07-26 00:28:22 +02:00
|
|
|
if (str[8] == ' ' && str.size() >= 17)
|
|
|
|
{
|
|
|
|
// accept strings longer than 17 in case there is a comment on the same line as the code
|
|
|
|
char part1[9];
|
|
|
|
char part2[9];
|
|
|
|
snprintf(part1, sizeof(part1), "%c%c%c%c%c%c%c%c", str[0], str[1], str[2], str[3], str[4], str[5], str[6],
|
|
|
|
str[7]);
|
|
|
|
snprintf(part2, sizeof(part2), "%c%c%c%c%c%c%c%c", str[9], str[10], str[11], str[12], str[13], str[14],
|
|
|
|
str[15], str[16]);
|
|
|
|
if ((strtok(part1, "0123456789ABCDEFabcdef") == NULL) && (strtok(part2, "0123456789ABCDEFabcdef") == NULL))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2009-09-16 06:05:50 +02:00
|
|
|
}
|