static void AddCheatParam(uint32 A, uint64 V, unsigned int bytelen, bool bigendian) { char name[256]; CHEAT_printf("Name: "); GetString(name,256); CHEAT_printf("Address [$%08x]: ", A); A=GetUI(A); CHEAT_printf("Byte length [%d]: ", bytelen); bytelen = GetUI(bytelen); if(bytelen > 1) { CHEAT_printf("Big endian? [%c]: ", bigendian ? 'Y' : 'N'); bigendian = GetYN(bigendian); } else bigendian = 0; CHEAT_printf("Value [%llu]: ", V); V=GetUI(V); CHEAT_printf("Add cheat \"%s\" for address $%08x with value %llu?",name,(unsigned int)A,(unsigned long long)V); if(GetYN(0)) { if(MDFNI_AddCheat(name,A,V,0, 'R', bytelen, bigendian)) CHEAT_puts("Cheat added."); else CHEAT_puts("Error adding cheat."); } }
static void AddCheatParam(uint32 A, uint64 V, unsigned int bytelen, bool bigendian) { MemoryPatch patch; patch.addr = A; patch.val = V; patch.length = bytelen; patch.bigendian = bigendian; patch.type = 'R'; patch.status = true; patch = GetCheatFields(patch); CHEAT_printf("Add cheat \"%s\" for address $%08x with value %llu?", patch.name.c_str(), (unsigned int)patch.addr, (unsigned long long)patch.val); if(GetYN(true)) { try { MDFNI_AddCheat(patch); } catch(std::exception &e) { CHEAT_printf("Error adding cheat: %s", e.what()); return; } CHEAT_puts("Cheat added."); } }
static void AddCheatGGPAR(int which) { uint16 A; uint8 V; int C; int type; char name[256], code[256]; printf("Name: "); GetString(name, 256); printf("Code: "); GetString(code, 256); printf("Add cheat \"%s\" for code \"%s\"?", name, code); if (GetYN(0)) { if (which) { if (!FCEUI_DecodePAR(code, &A, &V, &C, &type)) { puts("Invalid Game Genie code."); return; } } else { if (!FCEUI_DecodeGG(code, &A, &V, &C)) { puts("Invalid Game Genie code."); return; } type = 1; } if (FCEUI_AddCheat(name, A, V, C, type)) puts("Cheat added."); else puts("Error adding cheat."); } }
static void AddCheatGGPAR(int which) { uint32 A; uint8 V; uint8 C; char type; char name[256],code[256]; CHEAT_printf("Name: "); GetString(name,256); CHEAT_printf("Code: "); GetString(code,256); CHEAT_printf("Add cheat \"%s\" for code \"%s\"?",name,code); if(GetYN(0)) { if(which) { if(!MDFNI_DecodePAR(code,&A,&V,&C,&type)) { CHEAT_puts("Invalid Game Genie code."); return; } } else { if(!strcmp(CurGame->shortname, "gb")) { if(!MDFNI_DecodeGBGG(code, &A, &V, &C, &type)) { CHEAT_puts("Invalid Game Genie code."); return; } } else { if(!MDFNI_DecodeGG(code,&A,&V,&C, &type)) { CHEAT_puts("Invalid Game Genie code."); return; } } } if(MDFNI_AddCheat(name,A,V,C,type, 1, 0)) CHEAT_puts("Cheat added."); else CHEAT_puts("Error adding cheat."); } }
static void AddCheatParam(uint32 A, uint8 V) { char name[256]; printf("Name: "); GetString(name, 256); printf("Address [$%04x]: ", (unsigned int)A); A = GetH16(A); printf("Value [%03d]: ", (unsigned int)V); V = Get8(V); printf("Add cheat \"%s\" for address $%04x with value %03d?", name, (unsigned int)A, (unsigned int)V); if (GetYN(0)) { if (FCEUI_AddCheat(name, A, V, -1, 0)) puts("Cheat added."); else puts("Error adding cheat."); } }
static void DoSearch(void* data) { static int v1=0,v2=0; static int method=0; const char *m[6]={"O==V1 && C==V2","O==V1 && |O-C|==V2","|O-C|==V2","O!=C","Value decreased","Value increased"}; CHEAT_puts(""); CHEAT_printf("Search Filter:"); method = ShowShortList(m,6,method); if(method<=1) { CHEAT_printf("V1 [%03d]: ",v1); v1=GetUI(v1); } if(method<=2) { CHEAT_printf("V2 [%03d]: ",v2); v2=GetUI(v2); } CHEAT_printf("Byte length(1-8)[%1d]: ", searchbytelen); searchbytelen = GetUI(searchbytelen); if(searchbytelen > 1) { CHEAT_printf("Big endian? [%c]: ", searchbigendian ? 'Y' : 'N'); searchbigendian = GetYN(searchbigendian); } else searchbigendian = 0; MDFNI_CheatSearchEnd(method, v1, v2, searchbytelen, searchbigendian); CHEAT_puts("Search completed."); }
static void AddCodeCheat(void* data) { const CheatFormatStruct* cf = (CheatFormatStruct*)data; char name[256],code[256]; MemoryPatch patch; unsigned iter = 0; while(1) { if(iter == 0) CHEAT_printf("%s Code: ", cf->FullName); else CHEAT_printf("%s Code(part %u): ", cf->FullName, iter + 1); GetString(code, 256); if(code[0] == 0) { CHEAT_printf("Aborted."); return; } try { if(!cf->DecodeCheat(std::string(code), &patch)) break; iter++; } catch(std::exception &e) { CHEAT_printf("Decode error: %s", e.what()); } } if(patch.name.size() == 0) patch.name = std::string(code); CHEAT_printf("Name[%s]: ", patch.name.c_str()); GetString(name, 256); if(name[0] != 0) patch.name = std::string(name); patch.status = true; CHEAT_printf("Add cheat?"); if(GetYN(true)) { try { MDFNI_AddCheat(patch); } catch(std::exception &e) { CHEAT_printf("Error adding cheat: %s", e.what()); return; } CHEAT_puts("Cheat added."); } }
static MemoryPatch GetCheatFields(const MemoryPatch &pin) { MemoryPatch patch = pin; char buf[256]; const bool support_read_subst = CurGame->InstallReadPatch && CurGame->RemoveReadPatches; CHEAT_printf("Name [%s]: ", patch.name.c_str()); GetString(buf, 256); if(buf[0] != 0) patch.name = std::string(buf); CHEAT_printf("Available types:"); CHEAT_printf(" R - Replace/RAM write(high-level)."); CHEAT_printf(" A - Addition/RAM read->add->write(high-level)."); CHEAT_printf(" T - Transfer/RAM copy(high-level)."); if(support_read_subst) { CHEAT_printf(" S - Subsitute on reads."); CHEAT_printf(" C - Substitute on reads, with compare."); } for(;;) { CHEAT_printf("Type [%c]: ", patch.type); patch.type = toupper(CHEAT_getchar(patch.type)); if(patch.type == 'R' || patch.type == 'A' || patch.type == 'T') break; if(support_read_subst && (patch.type == 'S' || patch.type == 'C')) break; } if(patch.type == 'T') { CHEAT_printf("Source address [$%08x]: ", (unsigned int)patch.copy_src_addr); patch.copy_src_addr = GetUI(patch.copy_src_addr); CHEAT_printf("Source address inc [%u]: ", patch.copy_src_addr_inc); patch.copy_src_addr_inc = GetUI(patch.copy_src_addr_inc); CHEAT_printf("Dest address [$%08x]: ", (unsigned int)patch.addr); patch.addr = GetUI(patch.addr); CHEAT_printf("Dest address inc [%u]: ", patch.mltpl_addr_inc); patch.mltpl_addr_inc = GetUI(patch.mltpl_addr_inc); CHEAT_printf("Count [%u]: ", patch.mltpl_count); patch.mltpl_count = GetUI(patch.mltpl_count); } else { CHEAT_printf("Address [$%08x]: ", (unsigned int)patch.addr); patch.addr = GetUI(patch.addr); } if(patch.type == 'S' || patch.type == 'C') patch.length = 1; // TODO in the future for GBA: support lengths other than 1 in core. else { do { if(patch.type == 'T') { //if(patch.length == 1 && patch.copy_src_addr_inc == 1 && patch.mltpl_addr_inc == 1) // break; //if((patch.copy_src_addr_inc == patch.mltpl_addr_inc) && patch.copy_src_addr_inc >= 1 && patch.copy_src_addr_inc <= 8) // CHEAT_printf("Transfer unit byte length should probably be \"%u\".", patch.copy_src_addr_inc); CHEAT_printf("Transfer unit byte length(1-8) [%u]: ", patch.length); } else CHEAT_printf("Byte length(1-8) [%u]: ", patch.length); patch.length = GetUI(patch.length); } while(patch.length < 1 || patch.length > 8); } if(patch.length > 1 && (patch.type != 'S' && patch.type != 'C')) { CHEAT_printf("Big endian? [%c]: ", patch.bigendian ? 'Y' : 'N'); patch.bigendian = GetYN(patch.bigendian); } else patch.bigendian = false; if(patch.type != 'T') { CHEAT_printf("Value [%03llu]: ", (unsigned long long)patch.val); patch.val = GetUI(patch.val); } // T type loop stuff is handled up above. if((patch.type != 'C' && patch.type != 'S' && patch.type != 'T') && patch.mltpl_count != 1) { CHEAT_printf("Loop count [%u]: ", patch.mltpl_count); patch.mltpl_count = GetUI(patch.mltpl_count); CHEAT_printf("Loop address inc [%u]: ", patch.mltpl_addr_inc); patch.mltpl_addr_inc = GetUI(patch.mltpl_addr_inc); CHEAT_printf("Loop value inc [%u]: ", patch.mltpl_val_inc); patch.mltpl_val_inc = GetUI(patch.mltpl_val_inc); } if(patch.type == 'C') { CHEAT_printf("Compare [%03lld]: ", patch.compare); patch.compare = GetUI(patch.compare); } if((patch.type != 'C' && patch.type != 'S') && patch.conditions.size()) { CHEAT_printf("Conditions: %s", patch.conditions.c_str()); // Just informational for now. //CHEAT_printf("Conditions [%s]: ", ); //patch.conditions = GetString(); } CHEAT_printf("Enable? "); patch.status = GetYN(patch.status); return(patch); }
static void ModifyCheat(int num) { char *name; char buf[256]; uint32 A; uint64 V; uint64 compare; char type; int status; unsigned int bytelen; bool bigendian; MDFNI_GetCheat(num, &name, &A, &V, &compare, &status, &type, &bytelen, &bigendian); CHEAT_printf("Name [%s]: ",name); GetString(buf,256); /* This obviously doesn't allow for cheats with no names. Bah. Who wants nameless cheats anyway... */ if(buf[0]) name=buf; // Change name when MDFNI_SetCheat() is called. else name=0; // Don't change name when MDFNI_SetCheat() is called. CHEAT_printf("Address [$%08x]: ",(unsigned int)A); A=GetUI(A); CHEAT_printf("Byte length [%d]: ", bytelen); bytelen = GetUI(bytelen); if(bytelen > 1) { CHEAT_printf("Big endian? [%c]: ", bigendian ? 'Y' : 'N'); bigendian = GetYN(bigendian); } else bigendian = 0; CHEAT_printf("Value [%03lld]: ",(unsigned int)V); V=GetUI(V); do { CHEAT_printf("Type('R'=replace,'S'=Read Substitute(or 'C' with compare)) [%c]: ",type); type = toupper(CHEAT_getchar(type)); } while(type != 'R' && type !='S' && type !='C'); if(type == 'C') { CHEAT_printf("Compare [%03lld]: ",compare); compare = GetUI(compare); } CHEAT_printf("Enable? "); status = GetYN(status); MDFNI_SetCheat(num, name, A, V, compare, status, type, bytelen, bigendian); }