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); }