/* * gct.h * Class to handle Ocarina TXT Cheatfiles * nIxx */ #include #include #include #include #include "gct.h" #define ERRORRANGE "Error: CheatNr out of range" GCTCheats::GCTCheats( void ) { iCntCheats = 0; } GCTCheats::~GCTCheats( void ) { string sGameID = ""; string sGameTitle = ""; /*string sCheatName[MAXCHEATS]; string sCheats[MAXCHEATS]; string sCheatComment[MAXCHEATS];*/ } int GCTCheats::getCnt() { return iCntCheats; } string GCTCheats::getGameName( void ) { return sGameTitle; } string GCTCheats::getGameID( void ) { return sGameID; } string GCTCheats::getCheat( int nr ) { if ( nr <= ( iCntCheats - 1 ) ) { return sCheats[nr]; } else { return ERRORRANGE; } } string GCTCheats::getCheatName( int nr ) { if ( nr <= ( iCntCheats - 1 ) ) { return sCheatName[nr]; } else { return ERRORRANGE; } } string GCTCheats::getCheatComment( int nr ) { if ( nr <= ( iCntCheats - 1 ) ) { return sCheatComment[nr]; } else { return ERRORRANGE; } } int GCTCheats::createGCT( int nr, const char * filename ) { if ( nr == 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}; string buf = getCheat( nr ); filestr.write( header, sizeof( header ) ); int x = 0; long int li; int len = buf.size(); 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 ) ); filestr.close(); return 1; } int GCTCheats::createGCT( const char * chtbuffer, const char * filename ) { 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}; string buf = chtbuffer; filestr.write( header, sizeof( header ) ); int x = 0; long int li; int len = buf.size(); 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 ) ); filestr.close(); return 1; } int GCTCheats::createGCT( int nr[], int cnt, const char * filename ) { 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; } int GCTCheats::openTxtfile( const char * filename ) { 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; } bool GCTCheats::IsCode( const std::string& str ) { 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; }