diff --git a/Makefile b/Makefile index c5a8d38..3458e7a 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ C_SOURCES = source/unzip/explode.c source/unzip/unreduce.c \ source/unzip/unshrink.c source/unzip/unzip.c \ source/nds/bdf_font.c source/nds/bitmap.c \ source/nds/draw.c source/nds/ds2_main.c source/nds/gcheat.c \ - source/nds/gui.c source/nds/dma_adj.c + source/nds/gui.c source/nds/dma_adj.c source/nds/cheatgrp.c CPP_SOURCES = source/apu.cpp source/apudebug.cpp source/c4.cpp \ source/c4emu.cpp source/cheats2.cpp source/cheats.cpp \ source/clip.cpp source/cpu.cpp source/cpuexec.cpp \ diff --git a/source/cheats.h b/source/cheats.h index 2f3252e..2b2687b 100644 --- a/source/cheats.h +++ b/source/cheats.h @@ -101,8 +101,7 @@ struct SCheat uint32 address; uint8 byte; uint8 saved_byte; - // bool8 enabled; - u32 enabled; // THIS IS A TOTAL HACK FOR THE NDSSFC GUI, YOU HAVE BEEN WARNED [Neb] + bool8 enabled; bool8 saved; char name[MAX_SFCCHEAT_NAME]; }; diff --git a/source/nds/cheatgrp.c b/source/nds/cheatgrp.c new file mode 100644 index 0000000..75513e8 --- /dev/null +++ b/source/nds/cheatgrp.c @@ -0,0 +1,100 @@ +/* cheatgrp.c + * + * Copyright (C) 2013 GBAtemp user Nebuleon. + * + * This program is free software; you can redistribute it and/or + * 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. + * + * 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 "cheatgrp.h" +#include "string.h" +#include "ds2_malloc.h" + +extern struct SCheatData Cheat; + +/* + * Obtains the names of cheat groups currently defined in the Snes9x cheat + * data. + * Cheats are grouped by name, because multipart codes share the same name + * when loaded. + * This function only handles consecutive codes with the same name. If two + * runs of codes have the same name, two identically-named groups will be + * written. Enabling or disabling either of these groups will also enable + * or disable the other if using NDSSFCEnableCheatGroup or + * NDSSFCDisableCheatGroup. + * OUT: NamePointers, an array of MAX_CHEATS_T + 1 pointers which are updated + * by this function. All pointers beyond the last group name are updated + * to point to NULL. + * NameMemory, an array of MAX_CHEATS_T * MAX_SFCCHEAT_NAME char values + * which is updated to hold the names of the groups. + */ +void NDSSFCGetCheatGroups (char** NamePointers, char* NameMemory) +{ + unsigned int NameIndex = 0, cheat; + char* dst = NameMemory; + for (cheat = 0; cheat < Cheat.num_cheats; cheat++) + { + if (cheat == 0 || strcmp(Cheat.c [cheat].name, Cheat.c [cheat - 1].name) != 0) + { + memcpy(dst, Cheat.c [cheat].name, MAX_SFCCHEAT_NAME * sizeof (char)); + NamePointers[NameIndex] = dst; + dst += MAX_SFCCHEAT_NAME; + NameIndex++; + } + } + for (; NameIndex < MAX_CHEATS_T + 1; NameIndex++) + { + NamePointers[NameIndex] = NULL; + } +} + +void NDSSFCEnableCheatGroup (char* GroupName) +{ + uint32 cheat; + for (cheat = 0; cheat < Cheat.num_cheats; cheat++) + { + if (strcmp(Cheat.c [cheat].name, GroupName) == 0) + { + S9xEnableCheat (cheat); + } + } +} + +void NDSSFCDisableCheatGroup (char* GroupName) +{ + uint32 cheat; + for (cheat = 0; cheat < Cheat.num_cheats; cheat++) + { + if (strcmp(Cheat.c [cheat].name, GroupName) == 0) + { + S9xDisableCheat (cheat); + } + } +} + +bool8 NDSSFCIsCheatGroupEnabled (char* GroupName) +{ + bool8 NameFound = FALSE; + uint32 cheat; + for (cheat = 0; cheat < Cheat.num_cheats; cheat++) + { + if (strcmp(Cheat.c [cheat].name, GroupName) == 0) + { + if (!Cheat.c [cheat].enabled) + return FALSE; + NameFound = TRUE; + } + } + return NameFound; +} diff --git a/source/nds/cheatgrp.h b/source/nds/cheatgrp.h new file mode 100644 index 0000000..d84549a --- /dev/null +++ b/source/nds/cheatgrp.h @@ -0,0 +1,27 @@ +/* cheatgrp.h + * + * Copyright (C) 2013 GBAtemp user Nebuleon. + * + * This program is free software; you can redistribute it and/or + * 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. + * + * 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 "port.h" +#include "cheats.h" + +extern void NDSSFCGetCheatGroups (char** NamePointers, char* NameMemory); +extern void NDSSFCEnableCheatGroup (char* GroupName); +extern void NDSSFCDisableCheatGroup (char* GroupName); +extern bool8 NDSSFCIsCheatGroupEnabled (char* GroupName); + diff --git a/source/nds/gui.c b/source/nds/gui.c index e5486d8..84d5bf6 100644 --- a/source/nds/gui.c +++ b/source/nds/gui.c @@ -37,6 +37,7 @@ #include "message.h" #include "bitmap.h" #include "gcheat.h" +#include "cheatgrp.h" extern struct SCheatData Cheat; @@ -138,11 +139,11 @@ const uint8 DIRECTION_DOWN_DISPLAY[] = {0xE2, 0x86, 0x93, 0x00}; NULL, \ &cheat_data_ptr[number], \ NULL /* enable_disable_options */, \ - &(Cheat.c[number].enabled), \ + NULL, \ 2, \ NULL, \ line_number, \ - STRING_SELECTION_TYPE | ACTION_TYPE \ + ACTION_TYPE \ } \ #define ACTION_OPTION(action_function, passive_function, display_string, \ @@ -1719,6 +1720,10 @@ u32 menu(u16 *screen, bool8 FirstInvocation) // ^ Holds the index inside Cheat, as a number in an ASCIIZ string char* cheat_data_ptr[MAX_CHEATS_T]; + // For cheat groups + char* cheat_group_name_ptr[MAX_CHEATS_T + 1]; + char cheat_group_names[MAX_CHEATS_T * MAX_SFCCHEAT_NAME]; + MENU_TYPE *current_menu = NULL; MENU_OPTION_TYPE *current_option = NULL; MENU_OPTION_TYPE *display_option = NULL; @@ -2250,6 +2255,8 @@ u32 menu(u16 *screen, bool8 FirstInvocation) cheat_data_ptr[i] = &cheat_data_str[i][0]; } + NDSSFCGetCheatGroups(cheat_group_name_ptr, cheat_group_names); + reload_cheats_page(); } @@ -2481,6 +2488,16 @@ u32 menu(u16 *screen, bool8 FirstInvocation) void cheat_option_action() { + char tmp_buf[512]; + strcpy(tmp_buf, *(current_option->display_string)); + int i = atoi(tmp_buf); + // 'i' is the cheat group index. + if (cheat_group_name_ptr[i] == NULL) + return; + if (NDSSFCIsCheatGroupEnabled (cheat_group_name_ptr[i])) + NDSSFCDisableCheatGroup (cheat_group_name_ptr[i]); + else + NDSSFCEnableCheatGroup (cheat_group_name_ptr[i]); } #define CHEAT_NUMBER_X 23 @@ -2508,11 +2525,11 @@ u32 menu(u16 *screen, bool8 FirstInvocation) 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); - if (i >= Cheat.num_cheats) { + if (cheat_group_name_ptr[i] == NULL) { PRINT_STRING_BG(down_screen_addr, msg[MSG_CHEAT_ELEMENT_NOT_LOADED], color, COLOR_TRANS, CHEAT_DESC_X, 40 + display_option-> line_number*27); } else { - strcpy(line_buffer, Cheat.c[i].name); + strcpy(line_buffer, cheat_group_name_ptr[i]); len = BDF_cut_string(line_buffer, 0, 2); if(len > CHEAT_DESC_SX) { @@ -2522,7 +2539,7 @@ u32 menu(u16 *screen, bool8 FirstInvocation) } PRINT_STRING_BG(down_screen_addr, line_buffer, color, COLOR_TRANS, CHEAT_DESC_X, 40 + display_option-> line_number*27); - if (Cheat.c[i].enabled) + if (NDSSFCIsCheatGroupEnabled (cheat_group_name_ptr[i])) strcpy(line_buffer, "+"); else strcpy(line_buffer, "-"); @@ -3504,7 +3521,6 @@ u32 menu(u16 *screen, bool8 FirstInvocation) for(i = 0; i < CHEATS_PER_PAGE; i++) { 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); } }