void mCheatRemoveSet(struct mCheatDevice* device, struct mCheatSet* cheats) { size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { if (*mCheatSetsGetPointer(&device->cheats, i) == cheats) { break; } } if (i == mCheatSetsSize(&device->cheats)) { return; } mCheatSetsShift(&device->cheats, i, 1); cheats->remove(cheats, device); }
void retro_cheat_set(unsigned index, bool enabled, const char* code) { UNUSED(index); UNUSED(enabled); struct mCheatDevice* device = core->cheatDevice(core); struct mCheatSet* cheatSet = NULL; if (mCheatSetsSize(&device->cheats)) { cheatSet = *mCheatSetsGetPointer(&device->cheats, 0); } else { cheatSet = device->createSet(device, NULL); mCheatAddSet(device, cheatSet); } // Convert the super wonky unportable libretro format to something normal char realCode[] = "XXXXXXXX XXXXXXXX"; size_t len = strlen(code) + 1; // Include null terminator size_t i, pos; for (i = 0, pos = 0; i < len; ++i) { if (isspace((int) code[i]) || code[i] == '+') { realCode[pos] = ' '; } else { realCode[pos] = code[i]; } if ((pos == 13 && (realCode[pos] == ' ' || !realCode[pos])) || pos == 17) { realCode[pos] = '\0'; mCheatAddLine(cheatSet, realCode, 0); pos = 0; continue; } ++pos; } }
void mCheatDeviceClear(struct mCheatDevice* device) { size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i); mCheatSetDeinit(set); } mCheatSetsClear(&device->cheats); }
void mCheatDeviceDeinit(struct mCPUComponent* component) { struct mCheatDevice* device = (struct mCheatDevice*) component; size_t i; for (i = mCheatSetsSize(&device->cheats); i--;) { struct mCheatSet* cheats = *mCheatSetsGetPointer(&device->cheats, i); cheats->remove(cheats, device); } }
void mCheatDeviceInit(void* cpu, struct mCPUComponent* component) { UNUSED(cpu); struct mCheatDevice* device = (struct mCheatDevice*) component; size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { struct mCheatSet* cheats = *mCheatSetsGetPointer(&device->cheats, i); cheats->add(cheats, device); } }
void GBFrameEnded(struct GB* gb) { GBSramClean(gb, gb->video.frameCounter); if (gb->cpu->components && gb->cpu->components[CPU_COMPONENT_CHEAT_DEVICE]) { struct mCheatDevice* device = (struct mCheatDevice*) gb->cpu->components[CPU_COMPONENT_CHEAT_DEVICE]; size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { struct mCheatSet* cheats = *mCheatSetsGetPointer(&device->cheats, i); mCheatRefresh(device, cheats); } } }
bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { static const char lineStart[3] = "# "; static const char lineEnd = '\n'; struct StringList directives; StringListInit(&directives, 4); size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i); set->dumpDirectives(set, &directives); if (!set->enabled) { static const char* disabledDirective = "!disabled\n"; vf->write(vf, disabledDirective, strlen(disabledDirective)); } size_t d; for (d = 0; d < StringListSize(&directives); ++d) { char directive[64]; ssize_t len = snprintf(directive, sizeof(directive) - 1, "!%s\n", *StringListGetPointer(&directives, d)); if (len > 1) { vf->write(vf, directive, (size_t) len > sizeof(directive) ? sizeof(directive) : len); } } vf->write(vf, lineStart, 2); if (set->name) { vf->write(vf, set->name, strlen(set->name)); } vf->write(vf, &lineEnd, 1); size_t c; for (c = 0; c < StringListSize(&set->lines); ++c) { const char* line = *StringListGetPointer(&set->lines, c); vf->write(vf, line, strlen(line)); vf->write(vf, &lineEnd, 1); } } size_t d; for (d = 0; d < StringListSize(&directives); ++d) { free(*StringListGetPointer(&directives, d)); } StringListClear(&directives); StringListDeinit(&directives); return true; }