aboutsummaryrefslogtreecommitdiff
path: root/source/nds
diff options
context:
space:
mode:
authorNebuleon Fumika2012-12-22 22:16:55 -0500
committerNebuleon Fumika2012-12-22 22:16:55 -0500
commita194b850037c03f5fb3ac1ecc9f7a99f73b84104 (patch)
treee741bc4898e81b568552a8ae91867fd6a2ed3523 /source/nds
parente7f7d0282a7126f9e1095481b39c43e3e24909bf (diff)
downloadsnesemu-a194b850037c03f5fb3ac1ecc9f7a99f73b84104.tar.gz
snesemu-a194b850037c03f5fb3ac1ecc9f7a99f73b84104.tar.bz2
snesemu-a194b850037c03f5fb3ac1ecc9f7a99f73b84104.zip
Preliminary Snes9x-based cheat code support. Not tested, because the file selection interface freezes when it gets to the folder containing Mightymo's cheat files, whereas it did not do this before with the converted Mightymo cheats. (335 files -> 679, though.)
Diffstat (limited to 'source/nds')
-rw-r--r--source/nds/bdf_font.c1
-rw-r--r--source/nds/cheats3.cpp206
-rw-r--r--source/nds/draw.c1
-rw-r--r--source/nds/entry.cpp9
-rw-r--r--source/nds/gcheat.c574
-rw-r--r--source/nds/gcheat.h47
-rw-r--r--source/nds/gui.c93
-rw-r--r--source/nds/gui.h72
8 files changed, 173 insertions, 830 deletions
diff --git a/source/nds/bdf_font.c b/source/nds/bdf_font.c
index b1e7ccd..773403a 100644
--- a/source/nds/bdf_font.c
+++ b/source/nds/bdf_font.c
@@ -18,6 +18,7 @@
*/
//v1.1
+#include "port.h"
#include <string.h>
#include "ds2_types.h"
#include "ds2_malloc.h"
diff --git a/source/nds/cheats3.cpp b/source/nds/cheats3.cpp
deleted file mode 100644
index bdb5545..0000000
--- a/source/nds/cheats3.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/* cheats3.cpp
- *
- * Copyright (C) 2010 dking <dking024@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licens e as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include "snes9x.h"
-#include "cheats.h"
-#include "memmap.h"
-#include "gcheat.h"
-
-extern SCheatData Cheat;
-
-int S9xAddCheat_ex (unsigned int address, unsigned char* cheat_dat, unsigned int cheat_dat_len,
- unsigned int cheat_cell_num, unsigned int part_id, unsigned int str_num)
-{
- if(cheat_cell_num < MAX_CHEATS_T)
- {
- Cheat.c[cheat_cell_num].address = address;
- Cheat.c[cheat_cell_num].enabled = FALSE;
-
- if(cheat_dat_len > 1)
- memcpy(Cheat.c[cheat_cell_num].name, cheat_dat, cheat_dat_len);
- else
- Cheat.c[cheat_cell_num].byte = cheat_dat[0];
-
- Cheat.c[cheat_cell_num].total_part = 0; //default are sub-part
- Cheat.c[cheat_cell_num].part_id = part_id;
- Cheat.c[cheat_cell_num].part_len = cheat_dat_len;
- Cheat.c[cheat_cell_num].cheat_type = 0; //default are sub-part
- Cheat.c[cheat_cell_num].name_id = str_num;
-
- return 0;
- }
-
- return -1;
-}
-
-void S9xAddCheat_ov(unsigned int cheat_cell_num, unsigned int total_part)
-{
- if(cheat_cell_num < MAX_CHEATS_T)
- {
- Cheat.c[cheat_cell_num].total_part = total_part; //default are sub-part
- Cheat.c[cheat_cell_num].cheat_type = 0x80;
- }
-}
-
-static unsigned int S9xGetSub_id(unsigned int start, unsigned int sub_part)
-{
- unsigned int i, m, n;
-
- if(0 == sub_part)
- return start;
-
- if((start+1) >= g_cheat_cell_num)
- return start;
-
- m = 0;
- for(i= start; i < g_cheat_cell_num; )
- {
- n = Cheat.c[i].total_part;
- i += n;
- m += 1;
- if(m == sub_part) break;
- }
-
- return i;
-}
-
-unsigned int S9xGetCheat_nameid(unsigned int start, unsigned int part)
-{
-#if 0
- unsigned int m, n, i;
- unsigned int ret;
- unsigned int cell_num;
-
- cell_num = g_cheat_cell_num;
-
- ret = Cheat.c[start].name_id;
- if((start+1) >= cell_num)
- return ret;
-
- m = 0;
- for(i = start; i < cell_num; ) {
- if(m == part) break;
- n = Cheat.c[i].total_part;
- i += n;
- m += 1;
- }
-
- if(i < cell_num)
- ret = Cheat.c[i].name_id;
-
- return ret;
-#else
- unsigned int i;
-
- i = S9xGetSub_id(start, part);
- return Cheat.c[i].name_id;
-#endif
-}
-
-void S9xCheat_switch(unsigned int start, unsigned int sub_part, unsigned int enable)
-{
- unsigned int i, m, n;
-
- if((start+1) >= g_cheat_cell_num)
- return;
-
- i = S9xGetSub_id(start, sub_part);
- m = Cheat.c[i].total_part;
- for(n = 0; n < m; n++)
- Cheat.c[i+n].enabled = enable;
-}
-
-static inline void S9xApplyCheat_ex(unsigned int start, unsigned int num)
-{
- unsigned int i, m;
- unsigned int address, len;
-
- for(i = 0; i < num; i++)
- {
- address = Cheat.c[start+i].address;
- len = Cheat.c[start+i].part_len;
-
- int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK;
- unsigned char *ptr = Memory.Map [block];
-
- if(1 == len)
- {
- if (ptr >= (uint8 *) CMemory::MAP_LAST)
- *(ptr + (address & 0xffff)) = Cheat.c[start+i].byte;
- else
- S9xSetByte (Cheat.c[start+i].byte, address);
- }
- else
- {
- for(m= 0; m < len; m++)
- {
- if (ptr >= (uint8 *) CMemory::MAP_LAST)
- *(ptr + (address & 0xffff)) = Cheat.c[start+i].name[m];
- else
- S9xSetByte (Cheat.c[start+i].name[m], address);
- }
- }
- }
-}
-
-void S9xApplyCheats_ex(void)
-{
- unsigned int i, m, n;
-
- if (Settings.ApplyCheats)
- {
- for(i= 0; i < g_cheat_cell_num; i++)
- {
- m = Cheat.c[i].total_part;
- if(Cheat.c[i].enabled)
- S9xApplyCheat_ex(i, m);
- i += m;
- }
- }
-}
-
-#if 1
-extern "C" void dump_mem(unsigned char* addr, unsigned int len);
-
-void S9x_dumpcheat(unsigned int id)
-{
- cprintf("\nid %d------------\n", id);
- cprintf("total %d; part %d\n", Cheat.c[id].total_part, Cheat.c[id].part_id);
- cprintf("address: %08x; data: %d\n", Cheat.c[id].address, Cheat.c[id].part_len);
- if(Cheat.c[id].part_len == 1)
- cprintf("data: %02x\n", Cheat.c[id].byte);
- else
- dump_mem((unsigned char*)Cheat.c[id].name, Cheat.c[id].part_len);
- cprintf(" ------\n");
-}
-#endif
-
-void S9xCheat_Disable(void)
-{
- Settings.ApplyCheats = FALSE;
-}
-
-void S9xCheat_Enable(void)
-{
- Settings.ApplyCheats = TRUE;
-}
-
diff --git a/source/nds/draw.c b/source/nds/draw.c
index b6c3f9b..9d1b8ec 100644
--- a/source/nds/draw.c
+++ b/source/nds/draw.c
@@ -22,6 +22,7 @@
* draw.cpp
* basic program to draw some graphic
******************************************************************************/
+#include "port.h"
#include <string.h>
#include <stdio.h>
#include "ds2_malloc.h"
diff --git a/source/nds/entry.cpp b/source/nds/entry.cpp
index 467461b..ea5f6ce 100644
--- a/source/nds/entry.cpp
+++ b/source/nds/entry.cpp
@@ -97,7 +97,8 @@ void S9xExit ()
S9xSetSoundMute (TRUE);
S9xDeinitDisplay ();
Memory.SaveSRAM (S9xGetFilename (".srm"));
- S9xSaveCheatFile (S9xGetFilename (".cht"));
+ // S9xSaveCheatFile (S9xGetFilename (".chb")); // cheat binary file
+ // Do this when loading a cheat file!
Memory.Deinit ();
S9xDeinitAPU ();
@@ -258,7 +259,6 @@ const char *S9xGetSnapshotDirectory ()
return ((const char*)DEFAULT_RTS_DIR);
}
-
const char *S9xGetFilename (const char *ex)
{
static char filename [PATH_MAX + 1];
@@ -391,7 +391,7 @@ void init_sfc_setting(void)
Settings.ServerName [0] = 0;
Settings.Port = NP_DEFAULT_PORT;
#endif
- Settings.ApplyCheats = FALSE;
+ Settings.ApplyCheats = TRUE;
Settings.TurboMode = FALSE;
Settings.TurboSkipFrames = 40;
Settings.StretchScreenshots = 1;
@@ -457,8 +457,7 @@ int load_gamepak(char* file)
Memory.LoadSRAM (S9xGetFilename (".srm"));
// mdelay(50); // Delete this delay
- //S9xLoadCheatFile (S9xGetFilename (".cht"));
- S9xCheat_Disable();
+ S9xLoadCheatFile (S9xGetFilename (".chb")); // cheat binary file, as opposed to text
#ifdef _NETPLAY_SUPPORT
if (strlen (Settings.ServerName) == 0)
diff --git a/source/nds/gcheat.c b/source/nds/gcheat.c
index 062ce9d..648bfda 100644
--- a/source/nds/gcheat.c
+++ b/source/nds/gcheat.c
@@ -1,9 +1,9 @@
/* gcheat.c
*
- * Copyright (C) 2010 dking <dking024@gmail.com>
+ * Copyright (C) 2012 GBAtemp user Nebuleon.
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licens e as
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
@@ -17,511 +17,111 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "port.h"
#include "string.h"
#include "fs_api.h"
#include "ds2_malloc.h"
#include "gcheat.h"
#include "charsets.h"
+#include "cheats.h"
-#define MAX_SFCCHEAT_NAME 24
+extern struct SCheatData Cheat;
-
-//GCHEAT_STRUCT gcheat[MAX_CHEATS];
-unsigned int g_cheat_cell_num;
-unsigned int g_cheat_num;
-
-#define SKIP_SPACE(pt) while(' ' == *pt) pt++
-
-static unsigned char* check_is_cht(unsigned char *str)
-{
- unsigned char *pt, *pt1;
-
- if(*str == '\0') return NULL;
-
- pt = str;
- while(*pt == ' ') pt++; //Skip leading space
- if(*pt != '[') return NULL; //valid entry should be:[string]
-
- pt1 = strrchr(str, ']');
- if(pt1 == NULL) return NULL;
-
- while(*(--pt1) == ' ');
- *(pt1+1) = '\0'; //Cut trailing space between string and ']'
-
- while(*(++pt) == ' '); //Cut space between '[' and string
-
- return pt;
-}
-
-static unsigned int sscanf_hex_value(unsigned char* str, unsigned int *value)
-{
- unsigned char *pt;
- unsigned int tmp;
- unsigned char ch;
- unsigned int len;
-
- pt = str;
- len = 0;
- tmp = 0;
- while(*pt && len < 8)
- {
- ch = *pt;
- if(ch >= 'a' && ch <= 'f') ch = ch - 'a' + 0xa;
- else if(ch >= 'A' && ch <= 'F') ch = ch - 'A' + 0xa;
- else if(ch >= '0' && ch <= '9') ch = ch - '0';
- else if(ch == ' ') continue;
- else break;
-
- tmp = (tmp << 4) | ch;
- pt++;
- len += 1;
- }
-
- *value = tmp;
- return len;
-}
-
-/*
-* Convert the src string to UTF8 coding dst string, and cut to length
-*/
-int string2utf8(unsigned char *src, unsigned char* dst, unsigned int length)
+// Reads a cheat text file in BSNES's format.
+int NDSSFCLoadCheatFile(const char* filename)
{
- unsigned char *pt;
- unsigned char ch;
- unsigned short ucode;
- unsigned int type;
- unsigned int len;
+ FILE* fp = fopen(filename, "r");
+ if (fp == NULL)
+ return -1;
- len = 0;
- type = 0;
- pt = src;
- while(*pt)
+ S9xDeleteCheats();
+
+ // The construction is "a","b","c" <newline>.
+ // a is ignored. In BSNES, it decides whether the code is enabled.
+ // b is a series of codes separated by +. Each of the codes is in the form
+ // accepted by the Game Genie, Pro Action Replay, or the GoldFinger.
+ // c is the cheat's description.
+ char line[256], code[24];
+ char *description, *codes_ptr;
+ uint32 address;
+ uint8 byte;
+ uint8 bytes [3];
+ bool8 sram;
+ uint8 num_bytes;
+
+ while (fgets(line, sizeof(line), fp))
{
- pt = utf8decode(pt, &ucode);
- if(ucode < 0x4e00) {
- if(ucode == 0 || ucode > 0x7F) {
- type = 1;
- break;
- }
- } else if(ucode > 0x9FCF) {
- type = 1;
- break;
+ char* ptr = &line[0];
+ // Ignore a.
+ while (*ptr && *ptr != ',')
+ ptr++;
+ // If there was no comma, declare a bad file.
+ if (*ptr == '\0') {
+ fclose(fp);
+ return -2;
}
- else
- len++;
-
- if(len >= 3) break; //There is enough UTF8, so it is, to save time(>_*)
- }
+ *ptr++; // Past the comma
+
+ if (*ptr && *ptr == '"')
+ ptr++; // Starting quote of b.
+ codes_ptr = ptr; // Save this for later.
+ while (*ptr && *ptr != ',')
+ ptr++;
+ // If there was no comma, declare a bad file.
+ if (*ptr == '\0') {
+ fclose(fp);
+ return -2;
+ }
+ *ptr++; // Past the comma
+ *(ptr - 1) = '\0'; // End the codes there
+
+ uint32 i = 0;
+ description = ptr; // Skip starting " in description
+ while (*description && *description == '"')
+ description++;
+ ptr = description;
+ while (*ptr && !(*ptr == '\r' || *ptr == '\n' || *ptr == '"') && i < MAX_SFCCHEAT_NAME - 1) {
+ ptr++; // Remove trailing newline/quote in description
+ i++; // Clip the cheat name to MAX_SFCCHEAT_NAME chars
+ }
+ *ptr = '\0';
- if(type == 0) //UTF8
- {
- while(*src)
- {
- ch = *src++;
- *dst++ = ch;
+ uint32 n = 0, c;
+ // n is the number of cheat codes. Beware of MAX_CHEATS_T.
- if(ch < 0x80) {
- if(length > 1) length -= 1;
- else break;
- } else if (ch < 0xe0) { /* U-00000080 - U-000007FF, 2 bytes */
- if(length > 2) length -= 2;
- else break;
- *dst++ = *src++;
- } else if (ch < 0xf0) { /* U-00000800 - U-0000FFFF, 3 bytes */
- if(length > 3) length -= 3;
- else break;
- *dst++ = *src++;
- *dst++ = *src++;
- } else if (ch < 0xf5) { /* U-00010000 - U-001FFFFF, 4 bytes */
- if(length > 4) length -= 4;
- else break;
- *dst++ = *src++;
- *dst++ = *src++;
- *dst++ = *src++;
- } else {
- break;
+ // List of cheat codes having the same description.
+ ptr = codes_ptr;
+ while (*ptr && !(*ptr == ',' || *ptr == '"')) {
+ if (n >= MAX_CHEATS_T) {
+ fclose(fp);
+ return 0;
}
- }
- *dst = '\0';
- }
- else //assume it is GBK code
- {
- //GBK to UTF8
- while(*src)
- {
- ch = *src;
- if(ch < 0x80)
- {
- if(length > 1) length -= 1;
- else break;
-
- *dst++= ch;
- src ++;
+ i = 0;
+ while (*ptr && *ptr != '+' && i < sizeof(code) - 1)
+ code[i++] = *ptr++;
+ code[i] = '\0';
+ if (!S9xGameGenieToRaw (code, &address, &byte)) {
+ S9xAddCheat (FALSE, TRUE, address, byte);
+ strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME);
+ }
+ else if (!S9xProActionReplayToRaw (code, &address, &byte)) {
+ S9xAddCheat (FALSE, TRUE, address, byte);
+ strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME);
}
- else
+ else if (!S9xGoldFingerToRaw (code, &address, &sram, &num_bytes, bytes))
{
- ucode = charsets_gbk_to_ucs(src);
-
- if (ucode < 0x800) //2 bytes
- {
- if(length > 2) length -= 2;
- else break;
-
- *dst++ = 0xC0 | ((ucode >> 6) & 0x1F);
- *dst++ = 0x80 | (ucode & 0x3F);
- }
- else //3 bytes
- {
- if(length > 3) length -= 3;
- else break;
-
- *dst++ = 0xE0 | (ucode >> 12);
- *dst++ = 0x80 | ((ucode >>6) & 0x3F);
- *dst++ = 0x80 | (ucode & 0x3F);
+ for (c = 0; c < num_bytes; c++) {
+ S9xAddCheat (FALSE, TRUE, address + c, bytes[c]);
+ strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, 22);
}
-
- src += 2;
}
- }
- *dst = '\0';
- }
-
- return 0;
-}
-
-int load_cheatname(const char* filename, unsigned int string_num, unsigned int string_len, MSG_TABLE* mssg_table)
-{
- FILE *fp;
- unsigned char current_line[256];
- unsigned char current_line_tmp[256];
- int len, m;
- unsigned char** indexp;
- unsigned char* msg;
- unsigned char* pt;
-
- mssg_table->msg_index = (unsigned char**)malloc(string_num*4);
- if(NULL == mssg_table->msg_index)
- return -1;
-
- string_len = string_len + string_len/2;
- mssg_table->msg_pool = (unsigned char*)malloc((string_len+31)&(~31));
- if(NULL == mssg_table->msg_pool) {
- free((void*)mssg_table->msg_index);
- return -1;
- }
-
- fp = fopen(filename, "r");
- if(fp == NULL) {
- free((void*)mssg_table->msg_index);
- free((void*)mssg_table->msg_pool);
- return -1;
- }
-
- len = 0;
- m= 0;
- indexp = mssg_table->msg_index;
- msg = mssg_table->msg_pool;
- while(fgets(current_line, 256, fp))
- {
- unsigned int str_len;
-
- if((pt = check_is_cht(current_line)) != NULL)
- {
- if(!strcasecmp(pt, "gameinfo"))
- continue;
-
- string2utf8(pt, current_line_tmp, 255);
-
- str_len = strlen(current_line_tmp);
- strncpy(msg+len, current_line_tmp, str_len);
-
- indexp[m++] = msg+len;
- len += str_len;
- msg[len] = '\0';
- len += 1;
-
- if(len >= string_len) break;
- if(m >= string_num) break;
-
- while(fgets(current_line, 256, fp))
- {
- str_len = strlen(current_line);
- if(str_len < 4) break;
-
- if((pt = strchr(current_line, '=')) == NULL) //valid cheat item
- break;
-
- *pt = '\0';
- pt = current_line;
-
- string2utf8(pt, current_line_tmp, 255);
-
- str_len = strlen(current_line_tmp);
- strncpy(msg+len, current_line_tmp, str_len);
-
- indexp[m++] = msg+len;
- len += str_len;
- msg[len] = '\0';
- len += 1;
-
- if(len >= string_len) break;
- if(m >= string_num) break;
+ else {
+ fclose(fp);
+ return -3; // Bad cheat format
}
-
- if(len >= string_len) break;
- if(m >= string_num) break;
- }
- }
-
- mssg_table -> msg_num = m;
- fclose(fp);
-
-#if 0
-cprintf("string_len %d; len %d\n", string_len, len);
-for(m= 0; m<mssg_table -> msg_num; m++)
-{
-cprintf("msg%d:%s\n", m, indexp[m]);
-}
-#endif
-
- return 0;
-}
-
-#define MAX_CHEAT_DATE_LEN (MAX_SFCCHEAT_NAME/2) //other part hold the saved data
-
-/*
-* Load cheat file
-*/
-int load_cheatfile(const char* filename, unsigned int *string_num, unsigned int *string_len,
- GCHEAT_STRUCT *gcheat)
-{
- FILE *cheats_file;
- unsigned char current_line[256];
- unsigned char current_line_tmp[256];
- unsigned int current_line_len;
- unsigned char *pt;
- int gcheat_num;
-
- unsigned int str_num;
- unsigned int str_len;
- unsigned int cheat_cell_num;
- int flag;
-
- cheats_file = fopen(filename, "r");
- if(NULL == cheats_file)
- return -1;
- g_cheat_cell_num = 0;
- g_cheat_num = 0;
- cheat_cell_num = 0;
- gcheat_num = 0;
- str_num = 0;
- str_len = 0;
- flag = 0;
-
- while(fgets(current_line, 256, cheats_file))
- {
- if((pt = check_is_cht(current_line)) == NULL) //Check valid cht cheat
- continue;
-
- if(!strcasecmp(pt, "gameinfo")) //maybe file end
- continue;
-
- gcheat[gcheat_num].name_id = str_num;
- gcheat[gcheat_num].item_id = cheat_cell_num;
- gcheat[gcheat_num].item_num = 0;
-
- string2utf8(pt, current_line_tmp, CHEAT_NAME_LENGTH);
- strcpy(gcheat[gcheat_num].name_shot, current_line_tmp); //store a cut name shot
- //Initialize other parameter of gcheat
- gcheat[gcheat_num].active = 0;
- gcheat[gcheat_num].sub_active = 0;
-
- current_line_len = strlen(pt);
- str_len += current_line_len +1;
- str_num++;
-
- //Cheat items
- while(fgets(current_line, 256, cheats_file) != NULL)
- {
- if(strlen(current_line) < 4)
- break;
-
- if((pt = strchr(current_line, '=')) == NULL) //No valid content
- break;
-
- //one sub item each pass
- unsigned int first_part; //first part of a cheat item
- unsigned int first_part_id;
- unsigned int sub_part_id;
- unsigned int hex_len;
-
- unsigned int cheat_addr;
- unsigned char cheat_dat[MAX_CHEAT_DATE_LEN];
- unsigned int cheat_dat_len;
- unsigned int str_num_saved;
-
- str_num_saved = str_num;
- str_len += pt - current_line +1;
- str_num++;
-
- first_part = 1;
- first_part_id = cheat_cell_num;
- sub_part_id = 0;
-
- //skip name part
- pt += 1;
- current_line_len = strlen(pt);
-
- //data part
- while(1)
- {
- //fill current_line buffer as full as possible
- if(current_line_len < (MAX_CHEAT_DATE_LEN*3+8))
- { //the data length can fill a cheat cell
- if(NULL == strchr(pt, 0x0A)) { //this line not end
- memmove(current_line, pt, current_line_len+1);
- fgets(current_line+current_line_len, 256-current_line_len, cheats_file);
- pt = current_line;
- current_line_len = strlen(pt);
- }
- }
-#if 0
-cprintf("------\n");
-cprintf("new %d:[%s]\n", current_line_len, pt);
-dump_mem(pt, strlen(pt));
-cprintf("\n------\n");
-#endif
- //get address
- if(first_part)
- {
- hex_len = sscanf_hex_value(pt, &cheat_addr);
- if(0 == hex_len) {
- goto load_cheatfile_error;
- }
-
- pt += hex_len;
- current_line_len -= hex_len +1;
- // strict to follow the formate
- if(',' != *pt++ || '\0' == *pt || 0x0D == *pt || 0x0A == *pt) {
- goto load_cheatfile_error;
- }
-
- if(cheat_addr < 0x10000)
- cheat_addr |= 0x7e0000;
- else {
- cheat_addr &= 0xffff;
- cheat_addr |= 0x7f0000;
- }
- }
-
- //get data
- unsigned int tmp, m;
-
- m = 0;
- cheat_dat_len = 0;
- while(m++ < MAX_CHEAT_DATE_LEN)
- {
- hex_len = sscanf_hex_value(pt, &tmp);
- if(0 == hex_len) break;
-
- cheat_dat[cheat_dat_len++] = (unsigned char)tmp;
-
- pt += hex_len;
- current_line_len -= hex_len +1;
- if(',' == *pt) pt++;
- }
-
- //In first part, get data error
- if(0 == cheat_dat_len) {
- if(0 == sub_part_id)
- goto load_cheatfile_error;
- }
- else {
- //record data
- flag = S9xAddCheat_ex(cheat_addr, cheat_dat, cheat_dat_len, cheat_cell_num++, sub_part_id++, str_num_saved);
- if(0 != flag) {
- cheat_cell_num -= sub_part_id;
- break;
- }
- }
-
- if(0 == *pt || 0x0D == *pt || 0x0A == *pt) break; //a line over
-
- first_part = 0;
- if(';' == *pt) first_part = 1, pt += 1; //other address of the cheat cell
- else cheat_addr += cheat_dat_len; //more data
- } //data part
-
- //have no enough cheat_cell struct to store cheat
- if(0 != flag) break;
-
- S9xAddCheat_ov(first_part_id, sub_part_id);
- gcheat[gcheat_num].item_num += 1;
- } //Cheat items
-
- if(0 != flag) break;
-
- gcheat_num += 1;
- if(gcheat_num >= MAX_CHEATS)
- break;
- }
-
- g_cheat_cell_num = cheat_cell_num;
- g_cheat_num = gcheat_num;
- *string_num = str_num;
- *string_len = str_len;
- fclose(cheats_file);
-
-#if 0
-cprintf("g_cheat_num %d; g_cheat_cell_num %d\n", g_cheat_num, g_cheat_cell_num);
-
-int i;
-for(i= 0; i < g_cheat_cell_num; i++)
-S9x_dumpcheat(i);
-
-for(i= 0; i < g_cheat_num; i++)
-{
- cprintf("cheat %d\n", i);
- cprintf("item num %d; item id %d\n", gcheat[i].item_num, gcheat[i].item_id);
-}
-#endif
-
- return 0;
-
-load_cheatfile_error:
- fclose(cheats_file);
- return -1;
-}
-
-void gcheat_Managment(GCHEAT_STRUCT *gcheat)
-{
- unsigned int i, enable, m, en_flag;
- unsigned int active, item_id, sub_active, item_num;
-
- //no cheat
- if(0 == g_cheat_num || 0 == g_cheat_cell_num) {
- S9xCheat_Disable();
- return;
- }
-
- enable = 0;
- for(i = 0; i < g_cheat_num; i++)
- {
- active = gcheat[i].active & 0x1;
- item_id = gcheat[i].item_id;
- item_num = gcheat[i].item_num;
- sub_active = gcheat[i].sub_active;
-
- for(m = 0; m < item_num; m++)
- {
- en_flag = sub_active == m ? active : 0;
- S9xCheat_switch(item_id, m, en_flag);
}
-
- if(active) enable = 1;
}
- if(enable)
- S9xCheat_Enable();
+ fclose(fp);
+ return 0;
}
-
diff --git a/source/nds/gcheat.h b/source/nds/gcheat.h
index e5131f6..3c9e440 100644
--- a/source/nds/gcheat.h
+++ b/source/nds/gcheat.h
@@ -15,51 +15,24 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GCHEAT_H__
-#define __GCHEAT_H__
+ */
+
+#ifndef __GCHEAT_H__
+#define __GCHEAT_H__
#ifdef __cplusplus
extern "C" {
#endif
-
-#define CHEAT_NAME_LENGTH (32)
-#define MAX_CHEATS_PAGE 10
-#define CHEATS_PER_PAGE 4
-#define MAX_CHEATS (MAX_CHEATS_PAGE * CHEATS_PER_PAGE)
-//Support EMU Cheat(emulator cheat) code
-typedef struct
-{
- u32 name_id; //name ID in another table
- u32 active; //status
- u16 item_num; //sub-item number
- u16 sub_active;
- u32 item_id; //There is another struct array to store the cheat data
- char name_shot[CHEAT_NAME_LENGTH];
- u32 reserved;
-} GCHEAT_STRUCT;
+#include "cheats.h"
-typedef struct
-{
- unsigned char** msg_index;
- unsigned char* msg_pool;
- unsigned int msg_num;
-} MSG_TABLE;
-
-extern GCHEAT_STRUCT gcheat[MAX_CHEATS];
-extern unsigned int g_cheat_cell_num;
-extern unsigned int g_cheat_num;
+#define CHEATS_PER_PAGE 4
+#define MAX_CHEATS_PAGE (MAX_CHEATS_T / CHEATS_PER_PAGE)
-extern int load_cheatfile(const char* filename, unsigned int *string_num,
- unsigned int *string_len, GCHEAT_STRUCT *gcheat);
-extern int load_cheatname(const char* filename, unsigned int string_num,
- unsigned int string_len, MSG_TABLE* mssg_table);
-extern void gcheat_Managment(GCHEAT_STRUCT *gcheat);
+extern int NDSSFCLoadCheatFile(const char* filename);
#ifdef __cplusplus
}
#endif
-
-#endif //__GCHEAT_H__
+
+#endif //__GCHEAT_H__
diff --git a/source/nds/gui.c b/source/nds/gui.c
index 4a04efc..84f522f 100644
--- a/source/nds/gui.c
+++ b/source/nds/gui.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <sys/stat.h>
+#include "port.h"
#include "ds2_types.h"
#include "ds2io.h"
#include "ds2_malloc.h"
@@ -35,6 +36,8 @@
#include "bitmap.h"
#include "gcheat.h"
+extern struct SCheatData Cheat;
+
char main_path[MAX_PATH];
char rom_path[MAX_PATH];
char gamepak_name[MAX_PATH];
@@ -69,7 +72,7 @@ char *language_options[] = { (char *) &lang[0], (char *) &lang[1], (char *) &lan
EMU_CONFIG emu_config;
//game configure file's header
-#define GAME_CONFIG_HEADER "GSFC1.0"
+#define GAME_CONFIG_HEADER "GSFC1.1" // 1.1 removed cheat names
#define GAME_CONFIG_HEADER_SIZE 7
GAME_CONFIG game_config;
@@ -110,7 +113,7 @@ static unsigned int savestate_index;
NULL, \
&cheat_format_ptr[number], \
enable_disable_options, \
- &(game_config.cheats_flag[number].active), \
+ &(Cheat.c[number].enabled), \
2, \
NULL, \
line_number, \
@@ -1656,8 +1659,8 @@ u32 menu(u16 *screen)
u32 first_load = 0;
char tmp_filename[MAX_FILE];
char line_buffer[512];
- char cheat_format_str[MAX_CHEATS][41*4];
- char *cheat_format_ptr[MAX_CHEATS];
+ char cheat_format_str[MAX_CHEATS_T][41*4];
+ char *cheat_format_ptr[MAX_CHEATS_T];
MENU_TYPE *current_menu;
MENU_OPTION_TYPE *current_option;
@@ -2214,19 +2217,18 @@ u32 menu(u16 *screen)
unsigned char **dynamic_cheat_pt = NULL;
unsigned int dynamic_cheat_active;
int dynamic_cheat_scroll_value= 0;
- MSG_TABLE cheat_msg= {NULL, NULL};
void cheat_menu_init()
{
- for(i = 0; i < MAX_CHEATS; i++)
+ for(i = 0; i < MAX_CHEATS_T; i++)
{
- if(i >= g_cheat_num)
+ if(i >= Cheat.num_cheats)
{
sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_NON_LOAD], i);
}
else
{
- sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_LOADED], i, game_config.cheats_flag[i].name_shot);
+ sprintf(cheat_format_str[i], msg[MSG_CHEAT_MENU_LOADED], i, Cheat.c[i].name);
}
cheat_format_ptr[i]= cheat_format_str[i];
@@ -2237,13 +2239,11 @@ u32 menu(u16 *screen)
void cheat_menu_end()
{
- if(!first_load)
- gcheat_Managment(game_config.cheats_flag);
}
void dynamic_cheat_key()
{
- unsigned int m, n;
+ unsigned int m, n;
switch(gui_action)
{
@@ -2455,11 +2455,12 @@ u32 menu(u16 *screen)
unsigned int nums;
nums = (CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1;
- if(gui_action == CURSOR_SELECT && nums < g_cheat_num)
+ if(gui_action == CURSOR_SELECT && nums < Cheat.num_cheats)
{
unsigned int m;
- nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num;
+ // nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num;
+ // REVISIT [Neb]
if(dynamic_cheat_options)
{
@@ -2497,7 +2498,8 @@ u32 menu(u16 *screen)
dynamic_cheat_options[0].action_function = NULL;
dynamic_cheat_options[0].passive_function = NULL;
dynamic_cheat_options[0].sub_menu = &cheats_menu;
- dynamic_cheat_options[0].display_string = (char**)(dynamic_cheat_pt + game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].name_id);
+ // dynamic_cheat_options[0].display_string = (char**)(dynamic_cheat_pt + game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].name_id);
+ // REVISIT [Neb]
dynamic_cheat_options[0].options = NULL;
dynamic_cheat_options[0].current_option = NULL;
dynamic_cheat_options[0].num_options = 0;
@@ -2505,13 +2507,15 @@ u32 menu(u16 *screen)
dynamic_cheat_options[0].line_number = 0;
dynamic_cheat_options[0].option_type = SUBMENU_TYPE;
- m = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_id;
+ // m = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_id;
+ // REVISIT [Neb]
for(i= 0; i < nums; i++)
{
dynamic_cheat_options[i+1].action_function = dynamic_cheat_action;
dynamic_cheat_options[i+1].passive_function = NULL;
dynamic_cheat_options[i+1].sub_menu = NULL;
- dynamic_cheat_options[i+1].display_string = (char**)(dynamic_cheat_pt + S9xGetCheat_nameid(m, i, g_cheat_cell_num));
+ // dynamic_cheat_options[i+1].display_string = (char**)(dynamic_cheat_pt + S9xGetCheat_nameid(m, i, g_cheat_cell_num));
+ // REVISIT [Neb]
dynamic_cheat_options[i+1].options = NULL;
dynamic_cheat_options[i+1].current_option = NULL;
dynamic_cheat_options[i+1].num_options = 2;
@@ -2520,10 +2524,11 @@ u32 menu(u16 *screen)
dynamic_cheat_options[i+1].option_type = ACTION_TYPE;
}
- dynamic_cheat_active = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) +
- current_option_num -1].active & 0x1;
- dynamic_cheat_active |= game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) +
- current_option_num -1].sub_active << 16;
+ // dynamic_cheat_active = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) +
+ // current_option_num -1].active & 0x1;
+ // dynamic_cheat_active |= game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) +
+ // current_option_num -1].sub_active << 16;
+ // REVISIT [Neb]
//Initial srollable options
int k;
@@ -2585,7 +2590,8 @@ u32 menu(u16 *screen)
unsigned int m, k;
m = cheats_menu.focus_option-1;
- game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + m].sub_active = dynamic_cheat_active >> 16;
+ // game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + m].sub_active = dynamic_cheat_active >> 16;
+ // REVISIT [Neb]
k = SUBMENU_ROW_NUM +1;
for(m= 0; m<k; m++)
@@ -2612,44 +2618,25 @@ u32 menu(u16 *screen)
if(load_file(file_ext, tmp_filename, DEFAULT_CHEAT_DIR) != -1)
{
- if(NULL != cheat_msg.msg_index) free((void*)cheat_msg.msg_index);
- if(NULL != cheat_msg.msg_pool) free((void*)cheat_msg.msg_pool);
-
- sprintf(line_buffer, "%s/%s", DEFAULT_CHEAT_DIR, tmp_filename);
-
- flag = load_cheatfile(line_buffer, &string_num, &string_len, game_config.cheats_flag);
+ strcpy(line_buffer, DEFAULT_CHEAT_DIR);
+ strcat(line_buffer, "/");
+ strcat(line_buffer, tmp_filename);
+ flag = NDSSFCLoadCheatFile(line_buffer);
if(0 != flag)
{ //load cheat file failure
- game_config.cheat_str_num = 0;
- game_config.cheat_str_size = 0;
- game_config.cheat_filename[0] = '\0';
- g_cheat_num = 0;
+ S9xDeleteCheats();
cheat_menu_init();
return;
}
- flag = load_cheatname(line_buffer, string_num, string_len, &cheat_msg);
- if(0 != flag)
- { //load cheat string information failure
- game_config.cheat_str_num = 0;
- game_config.cheat_str_size = 0;
- game_config.cheat_filename[0] = '\0';
- g_cheat_num = 0;
+ strcpy(line_buffer, (char *) S9xGetFilename (".chb"));
- cheat_menu_init();
- return;
- }
-
- game_config.cheat_str_num = string_num;
- game_config.cheat_str_size = string_len;
- strcpy(game_config.cheat_filename, line_buffer);
+ S9xSaveCheatFile (line_buffer); // cheat binary
- dynamic_cheat_msg = cheat_msg.msg_pool;
- dynamic_cheat_pt = cheat_msg.msg_index;;
menu_cheat_page = 0;
cheat_menu_init();
- }
+ }
}
void save_screen_snapshot()
@@ -3593,7 +3580,7 @@ u32 menu(u16 *screen)
for(i = 0; i < CHEATS_PER_PAGE; i++)
{
cheats_options[i+1].display_string = &cheat_format_ptr[(CHEATS_PER_PAGE * menu_cheat_page) + i];
- cheats_options[i+1].current_option = &(game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + i].active);
+ cheats_options[i+1].current_option = &(Cheat.c[(CHEATS_PER_PAGE * menu_cheat_page) + i].enabled);
}
}
@@ -4257,14 +4244,6 @@ void init_game_config(void)
game_config.gamepad_config_menu = BUTTON_ID_TOUCH;
memcpy(game_config.gamepad_config_map, gamepad_config_map_init, sizeof(gamepad_config_map_init));
- for(i = 0; i < MAX_CHEATS; i++)
- {
- game_config.cheats_flag[i].active = 0;
- game_config.cheats_flag[i].name_shot[0] = '\0';
- }
-
- memset(game_config.cheat_filename, 0x0, MAX_PATH);
-
game_config.backward = 0; //time backward disable
game_config.backward_time = 2; //time backward granularity 1s
diff --git a/source/nds/gui.h b/source/nds/gui.h
index e845994..3b222d1 100644
--- a/source/nds/gui.h
+++ b/source/nds/gui.h
@@ -15,47 +15,43 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GUI_H__
-#define __GUI_H__
+ */
+
+#ifndef __GUI_H__
+#define __GUI_H__
#include "ds2_types.h"
#include "fs_api.h"
#include "gcheat.h"
-
+
#define MAX_GAMEPAD_MAP 16
-
+
#ifdef __cplusplus
extern "C" {
#endif
-
-//
-struct _EMU_CONFIG
-{
- u32 language;
+
+//
+struct _EMU_CONFIG
+{
+ u32 language;
char rom_file[256];
char rom_path[256];
char latest_file[5][512];
-};
-
-struct _GAME_CONFIG
-{
+};
+
+struct _GAME_CONFIG
+{
u32 clock_speed_number;
u32 frameskip_type;
u32 frameskip_value;
u32 graphic;
- u32 enable_audio;
- u32 gamepad_config_menu;
+ u32 enable_audio;
+ u32 gamepad_config_menu;
u32 backward;
u32 backward_time;
- u32 reserve[32];
+ u32 reserve[32];
u32 gamepad_config_map[MAX_GAMEPAD_MAP];
- GCHEAT_STRUCT cheats_flag[MAX_CHEATS];
- char cheat_filename[MAX_PATH];
- unsigned int cheat_str_num;
- unsigned int cheat_str_size;
-};
+};
typedef enum
{
@@ -98,28 +94,28 @@ extern char main_path[MAX_PATH];
extern char rom_path[MAX_PATH];
extern u32 game_enable_audio;
-
-/******************************************************************************
- ******************************************************************************/ extern char g_default_rom_dir[MAX_PATH];
-extern char DEFAULT_RTS_DIR[MAX_PATH];
-extern char DEFAULT_CFG_DIR[MAX_PATH];
-extern char DEFAULT_SS_DIR[MAX_PATH];
-extern char DEFAULT_CHEAT_DIR[MAX_PATH];
+
+/******************************************************************************
+ ******************************************************************************/ extern char g_default_rom_dir[MAX_PATH];
+extern char DEFAULT_RTS_DIR[MAX_PATH];
+extern char DEFAULT_CFG_DIR[MAX_PATH];
+extern char DEFAULT_SS_DIR[MAX_PATH];
+extern char DEFAULT_CHEAT_DIR[MAX_PATH];
typedef struct _EMU_CONFIG EMU_CONFIG;
typedef struct _GAME_CONFIG GAME_CONFIG;
-
-extern EMU_CONFIG emu_config;
-extern GAME_CONFIG game_config;
-/******************************************************************************
- ******************************************************************************/
-extern void gui_init(u32 lang_id);
+extern EMU_CONFIG emu_config;
+extern GAME_CONFIG game_config;
+
+/******************************************************************************
+ ******************************************************************************/
+extern void gui_init(u32 lang_id);
extern u32 menu(u16 *original_screen);
extern void game_disableAudio();
#ifdef __cplusplus
}
#endif
-
-#endif //__GUI_H__
+
+#endif //__GUI_H__