aboutsummaryrefslogtreecommitdiff
path: root/source/nds
diff options
context:
space:
mode:
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.c576
-rw-r--r--source/nds/gcheat.h47
-rw-r--r--source/nds/gui.c227
-rw-r--r--source/nds/gui.h72
8 files changed, 202 insertions, 937 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..d0ada43 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,113 @@
* 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 = '\0'; // End the codes there
+ *ptr++; // Past the comma
+
+ 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 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 (Cheat.num_cheats >= 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 == '+' || *ptr == ',' || *ptr == '"') && i < sizeof(code) - 1)
+ code[i++] = *ptr++;
+ if (*ptr)
+ ptr++; // Go past the + , or "
+ code[i] = '\0';
+ if (!S9xGameGenieToRaw (code, &address, &byte)) {
+ S9xAddCheat (FALSE, FALSE, address, byte);
+ strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME);
+ }
+ else if (!S9xProActionReplayToRaw (code, &address, &byte)) {
+ S9xAddCheat (FALSE, FALSE, 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, FALSE, address + c, bytes[c]);
+ strncpy (Cheat.c[Cheat.num_cheats - 1].name, description, MAX_SFCCHEAT_NAME);
}
-
- 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 d818602..979d99c 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;
@@ -108,9 +111,9 @@ static unsigned int savestate_index;
action_function, \
passive_function, \
NULL, \
- &cheat_format_ptr[number], \
+ &cheat_data_ptr[number], \
enable_disable_options, \
- &(game_config.cheats_flag[number].active), \
+ &(Cheat.c[number].enabled), \
2, \
NULL, \
line_number, \
@@ -1656,8 +1659,9 @@ 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_data_str[MAX_CHEATS_T][5];
+ // ^ Holds the index inside Cheat, as a number in an ASCIIZ string
+ char* cheat_data_ptr[MAX_CHEATS_T];
MENU_TYPE *current_menu;
MENU_OPTION_TYPE *current_option;
@@ -2214,22 +2218,13 @@ 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)
- {
- 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);
- }
-
- cheat_format_ptr[i]= cheat_format_str[i];
+ sprintf(cheat_data_str[i], "%d", i);
+ cheat_data_ptr[i] = &cheat_data_str[i][0];
}
reload_cheats_page();
@@ -2237,13 +2232,22 @@ u32 menu(u16 *screen)
void cheat_menu_end()
{
- if(!first_load)
- gcheat_Managment(game_config.cheats_flag);
+ // Honour current cheat selections.
+ uint32 i;
+ for (i = 0; i < Cheat.num_cheats; i++) {
+ if (Cheat.c[i].enabled)
+ S9xApplyCheat(i);
+ else
+ S9xRemoveCheat(i);
+ }
+ // Save current cheat selections to the cheat binary file.
+ strcpy(line_buffer, (char *) S9xGetFilename (".chb"));
+ S9xSaveCheatFile (line_buffer); // cheat binary
}
void dynamic_cheat_key()
{
- unsigned int m, n;
+ unsigned int m, n;
switch(gui_action)
{
@@ -2452,97 +2456,13 @@ u32 menu(u16 *screen)
void cheat_option_action()
{
- unsigned int nums;
-
- nums = (CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1;
- if(gui_action == CURSOR_SELECT && nums < g_cheat_num)
- {
- unsigned int m;
-
- nums = game_config.cheats_flag[(CHEATS_PER_PAGE * menu_cheat_page) + current_option_num -1].item_num;
-
- if(dynamic_cheat_options)
- {
- free((void*)dynamic_cheat_options);
- dynamic_cheat_options = NULL;
- }
-
- if(dynamic_cheat_menu)
- {
- free((void*)dynamic_cheat_menu);
- dynamic_cheat_menu = NULL;
- }
-
- dynamic_cheat_options = (MENU_OPTION_TYPE*)malloc(sizeof(MENU_OPTION_TYPE)*(nums+1));
- if(dynamic_cheat_options == NULL) return;
-
- dynamic_cheat_menu = (MENU_TYPE*)malloc(sizeof(MENU_TYPE));
- if(dynamic_cheat_menu == NULL)
- {
- free((void*)dynamic_cheat_options);
- dynamic_cheat_options = NULL;
- return;
- }
-
- //menu
- dynamic_cheat_menu->init_function = NULL;
- dynamic_cheat_menu->passive_function = dynamic_cheat_menu_passive;
- dynamic_cheat_menu->key_function = dynamic_cheat_key;
- dynamic_cheat_menu->end_function = dynamic_cheat_menu_end;
- dynamic_cheat_menu->options = dynamic_cheat_options;
- dynamic_cheat_menu->num_options = nums+1;
- dynamic_cheat_menu->focus_option = 0;
- dynamic_cheat_menu->screen_focus = 0;
- //back option
- 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].options = NULL;
- dynamic_cheat_options[0].current_option = NULL;
- dynamic_cheat_options[0].num_options = 0;
- dynamic_cheat_options[0].help_string = NULL;
- 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;
- 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].options = NULL;
- dynamic_cheat_options[i+1].current_option = NULL;
- dynamic_cheat_options[i+1].num_options = 2;
- dynamic_cheat_options[i+1].help_string = NULL;
- dynamic_cheat_options[i+1].line_number = i+1;
- 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;
-
- //Initial srollable options
- int k;
-
- draw_hscroll_init(down_screen_addr, 50, 9, 180, COLOR_TRANS,
- COLOR_ACTIVE_ITEM, *dynamic_cheat_options[0].display_string);
-
- if(nums>5) nums = SUBMENU_ROW_NUM;
- for(k= 0; k < nums; k++)
- {
- draw_hscroll_init(down_screen_addr, 23, 40 + k*27, 200,
- COLOR_TRANS, COLOR_INACTIVE_ITEM, *dynamic_cheat_options[k+1].display_string);
- }
- dynamic_cheat_scroll_value= 0;
-
- choose_menu(dynamic_cheat_menu);
- }
}
+#define CHEAT_NUMBER_X 26
+#define CHEAT_DESC_X 52
+#define CHEAT_DESC_SX 163
+#define CHEAT_ACTIVE_X 225
+
void cheat_option_passive()
{
unsigned short color;
@@ -2557,27 +2477,33 @@ u32 menu(u16 *screen)
//sprintf("%A") will have problem ?
strcpy(tmp_buf, *(display_option->display_string));
- pt = strrchr(tmp_buf, ':');
- if(pt != NULL)
- sprintf(pt+1, "%s", *((u32*)(((u32 *)display_option->options)[*(display_option->current_option)])));
+ // This is the number of the cheat to display
- strcpy(line_buffer, tmp_buf);
- pt = strrchr(line_buffer, ')');
- *pt = '\0';
- pt = strchr(line_buffer, '(');
+ int i = atoi(tmp_buf);
- len = BDF_cut_string(pt+1, 0, 2);
- if(len > 90)
- {
- len = BDF_cut_string(pt+1, 90, 1);
- *(pt+1+len) = '\0';
- strcat(line_buffer, "...");
- }
+ sprintf(line_buffer, "%d.", i + 1);
+ PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_NUMBER_X, 40 + display_option-> line_number*27);
- pt = strrchr(tmp_buf, ')');
- strcat(line_buffer, pt);
+ if (i >= Cheat.num_cheats) {
+ PRINT_STRING_BG(down_screen_addr, msg[MSG_CHEAT_MENU_NON_LOAD], color, COLOR_TRANS, CHEAT_DESC_X, 40 + display_option-> line_number*27);
+ }
+ else {
+ strcpy(line_buffer, Cheat.c[i].name);
+ len = BDF_cut_string(line_buffer, 0, 2);
+ if(len > CHEAT_DESC_SX)
+ {
+ len = BDF_cut_string(line_buffer, CHEAT_DESC_SX, 1);
+ line_buffer[len] = '\0';
+ strcat(line_buffer, "...");
+ }
+ PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_DESC_X, 40 + display_option-> line_number*27);
- PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, 26, 40 + display_option-> line_number*27);
+ if (Cheat.c[i].enabled)
+ strcpy(line_buffer, "+");
+ else
+ strcpy(line_buffer, "-");
+ PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_ACTIVE_X, 40 + display_option-> line_number*27);
+ }
}
void dynamic_cheat_menu_end()
@@ -2585,7 +2511,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 +2539,24 @@ 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 = NDSSFCLoadCheatFile(line_buffer);
- flag = load_cheatfile(line_buffer, &string_num, &string_len, game_config.cheats_flag);
- 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;
-
- cheat_menu_init();
- return;
- }
+ strcpy(line_buffer, (char *) S9xGetFilename (".chb"));
+ S9xSaveCheatFile (line_buffer); // cheat binary
- 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;
+ { //load cheat file failure
+ S9xDeleteCheats();
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);
-
- 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()
@@ -3592,8 +3499,8 @@ 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].display_string = &cheat_data_ptr[(CHEATS_PER_PAGE * menu_cheat_page) + i];
+ cheats_options[i+1].current_option = &(Cheat.c[(CHEATS_PER_PAGE * menu_cheat_page) + i].enabled);
}
}
@@ -4258,14 +4165,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__