Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions cheats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,28 @@ void cheats_toggle()
}
}

const char *cheats_get_name(int idx)
{
if (idx < 0 || idx >= cheats_available()) return NULL;
return cheats[idx].name;
}

bool cheats_get_enabled(int idx)
{
if (idx < 0 || idx >= cheats_available()) return false;
return cheats[idx].enabled;
}

int cheats_get_selected()
{
return iSelectedEntry;
}

void cheats_set_selected(int idx)
{
if (idx >= 0 && idx < cheats_available()) iSelectedEntry = idx;
}

int cheats_loaded()
{
return loaded;
Expand Down
8 changes: 8 additions & 0 deletions cheats.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef CHEATS_H
#define CHEATS_H

#include <stdbool.h>
#include <stdint.h>

void cheats_init(const char *rom_path, uint32_t romcrc);
int cheats_available();
void cheats_scan(int mode);
Expand All @@ -9,6 +12,11 @@ void cheats_print();
void cheats_toggle();
int cheats_loaded();

const char *cheats_get_name(int idx);
bool cheats_get_enabled(int idx);
int cheats_get_selected();
void cheats_set_selected(int idx);

void cheats_init_arcade(int unit_size, int max_active);
void cheats_add_arcade(const char *name, const char *cheatData, int cheatSize);
void cheats_finalize_arcade();
Expand Down
2 changes: 2 additions & 0 deletions input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "frame_timer.h"
#include "scaler.h"
#include "file_io.h"
#include "support/zaparoo/cheat_cmd.h"
#include "support/zaparoo/alt_launcher.h"

#define NUMDEV 30
Expand Down Expand Up @@ -6238,6 +6239,7 @@ int input_test(int getchar)
printf("MiSTer_cmd: %s\n", cmd);
if (!strncmp(cmd, "fb_cmd", 6)) video_cmd(cmd);
else if (!strncmp(cmd, "video_mode ", 11)) video_mode_cmd(cmd + 11);
else if (!strncmp(cmd, "cheat ", 6)) zaparoo_cheat_cmd(cmd + 6);
else if (!strncmp(cmd, "load_core ", 10))
{
if(isXmlName(cmd)) xml_load(cmd + 10);
Expand Down
140 changes: 140 additions & 0 deletions support/zaparoo/cheat_cmd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include "cheat_cmd.h"

#include <ctype.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include "cheats.h"

enum
{
CHEAT_CMD_OK = 0,
CHEAT_CMD_NO_CHEATS = -1,
CHEAT_CMD_NOT_FOUND = -2,
CHEAT_CMD_LOAD_FAILED = -3
};

static const char *skip_space(const char *s)
{
while (*s && isspace((unsigned char)*s)) s++;
return s;
}

static bool parse_token(const char **cmd, char *token, size_t token_size)
{
const char *s = skip_space(*cmd);
size_t len = 0;

while (s[len] && !isspace((unsigned char)s[len])) len++;
if (!len || len >= token_size) return false;

memcpy(token, s, len);
token[len] = 0;
*cmd = s + len;
return true;
}

static const char *cheat_cmd_status(int status)
{
switch (status)
{
case CHEAT_CMD_OK: return "ok";
case CHEAT_CMD_NO_CHEATS: return "no cheats loaded";
case CHEAT_CMD_NOT_FOUND: return "not found";
case CHEAT_CMD_LOAD_FAILED: return "load failed";
default: return "error";
}
}

static int find_cheat_by_name(const char *name)
{
if (!name || !*name) return -1;

for (int i = 0; i < cheats_available(); i++)
{
const char *cheat_name = cheats_get_name(i);
if (cheat_name && !strcmp(cheat_name, name)) return i;
}

return -1;
}

static int toggle_index(int idx)
{
if (!cheats_available()) return CHEAT_CMD_NO_CHEATS;
if (idx < 0 || idx >= cheats_available()) return CHEAT_CMD_NOT_FOUND;

bool was_enabled = cheats_get_enabled(idx);
int old_entry = cheats_get_selected();
cheats_set_selected(idx);
cheats_toggle();
cheats_set_selected(old_entry);

return (cheats_get_enabled(idx) != was_enabled) ? CHEAT_CMD_OK : CHEAT_CMD_LOAD_FAILED;
}

static int set_index_enabled(int idx, bool enabled)
{
if (!cheats_available()) return CHEAT_CMD_NO_CHEATS;
if (idx < 0 || idx >= cheats_available()) return CHEAT_CMD_NOT_FOUND;
if (cheats_get_enabled(idx) == enabled) return CHEAT_CMD_OK;

return toggle_index(idx);
}

static int clear_enabled()
{
if (!cheats_available()) return CHEAT_CMD_NO_CHEATS;

int status = CHEAT_CMD_OK;
for (int i = 0; i < cheats_available(); i++)
{
if (cheats_get_enabled(i))
{
int res = toggle_index(i);
if (res != CHEAT_CMD_OK) status = res;
}
}

return status;
}

void zaparoo_cheat_cmd(const char *cmd)
{
char action[16];

if (!parse_token(&cmd, action, sizeof(action)))
{
printf("MiSTer_cmd cheat: missing command\n");
return;
}

if (!strcmp(action, "clear"))
{
int status = clear_enabled();
printf("MiSTer_cmd cheat clear: %s\n", cheat_cmd_status(status));
return;
}

const char *name = skip_space(cmd);
if (!*name)
{
printf("MiSTer_cmd cheat %s: missing name\n", action);
return;
}

int idx = find_cheat_by_name(name);
int status;
if (!strcmp(action, "on")) status = set_index_enabled(idx, true);
else if (!strcmp(action, "off")) status = set_index_enabled(idx, false);
else if (!strcmp(action, "toggle")) status = toggle_index(idx);
else
{
printf("MiSTer_cmd cheat: unknown command '%s'\n", action);
return;
}

printf("MiSTer_cmd cheat %s '%s': %s\n", action, name, cheat_cmd_status(status));
}
3 changes: 3 additions & 0 deletions support/zaparoo/cheat_cmd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void zaparoo_cheat_cmd(const char *cmd);
5 changes: 5 additions & 0 deletions support/zaparoo/main_capabilities.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extern "C" __attribute__((used))
const char zaparoo_main_capabilities[] =
"ZAPAROO_MAIN_CAPABILITIES:"
"{\"schema\":1,\"id\":\"zaparoo-main\",\"version\":\"" VDATE "\","
"\"capabilities\":{\"cheat_cmd\":1}}";