diff --git a/source/cheatmenu.cpp b/source/cheatmenu.cpp new file mode 100644 index 00000000..8aa84820 --- /dev/null +++ b/source/cheatmenu.cpp @@ -0,0 +1,164 @@ +#include +#include +#include + +#include "libwiigui/gui.h" +#include "libwiigui/gui_customoptionbrowser.h" +#include "prompts/PromptWindows.h" +#include "language/gettext.h" +#include "fatmounter.h" +#include "menu.h" +#include "filelist.h" +#include "sys.h" +#include "gct.h" + +/*** Extern functions ***/ +extern void ResumeGui(); +extern void HaltGui(); + +/*** Extern variables ***/ +extern GuiWindow * mainWindow; + +/**************************************************************************** + * CheatMenu + ***************************************************************************/ +int CheatMenu(const char * gameID) +{ + int choice = 0; + bool exit = false; + int ret = 1; + + GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume); + GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume); + + char imgPath[100]; + snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); + GuiImageData btnOutline(imgPath, button_dialogue_box_png); + snprintf(imgPath, sizeof(imgPath), "%ssettings_background.png", CFG.theme_path); + GuiImageData settingsbg(imgPath, settings_background_png); + + GuiTrigger trigA; + trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + GuiTrigger trigB; + trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); + + GuiImage settingsbackground(&settingsbg); + + GuiText backBtnTxt(tr("Back") , 22, (GXColor){THEME.prompttxt_r, THEME.prompttxt_g, THEME.prompttxt_b, 255}); + backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30); + GuiImage backBtnImg(&btnOutline); + GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, 160, 400, &trigA, &btnSoundOver, &btnClick,1); + backBtn.SetLabel(&backBtnTxt); + backBtn.SetTrigger(&trigB); + + GuiText createBtnTxt("Create" , 22, (GXColor){THEME.prompttxt_r, THEME.prompttxt_g, THEME.prompttxt_b, 255}); + createBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30); + GuiImage createBtnImg(&btnOutline); + GuiButton createBtn(&createBtnImg,&createBtnImg, 2, 3, -140, 400, &trigA, &btnSoundOver, &btnClick,1); + createBtn.SetLabel(&createBtnTxt); + + GCTCheats c; + + char txtfilename[30]; + snprintf(txtfilename,sizeof(txtfilename),"%s%s.txt",Settings.TxtCheatcodespath,gameID); + + int check = c.openTxtfile(txtfilename); + switch(check) + { + case -1: WindowPrompt("Error","Cheatfile empty",tr("OK"),NULL,NULL,NULL); + break; + case 0: WindowPrompt("Error","No Cheatfile found",tr("OK"),NULL,NULL,NULL); + break; + case 1: //WindowPrompt("Opened File","File found for Game","Okay",NULL,NULL,NULL); + int cntcheats = c.getCnt()+1; + customOptionList options2(cntcheats); + GuiCustomOptionBrowser optionBrowser2(400, 280, &options2, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 150); + optionBrowser2.SetPosition(0, 90); + optionBrowser2.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + optionBrowser2.SetClickable(true); + optionBrowser2.SetScrollbar(1); + + GuiText titleTxt(c.getGameName().c_str(), 28, (GXColor){0, 0, 0, 255}); + titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + titleTxt.SetMaxWidth(350, GuiText::SCROLL); + titleTxt.SetPosition(12,40); + + //options2.SetName(0, "%s",c.getCheatComment(0).c_str()); + for(int i = 0; i <= cntcheats; i++) + { + options2.SetName(i+1, "%s",c.getCheatName(i).c_str()); + options2.SetValue(i+1, "OFF"); + } + + HaltGui(); + GuiWindow w(screenwidth, screenheight); + w.Append(&settingsbackground); + w.Append(&titleTxt); + w.Append(&backBtn); + w.Append(&createBtn); + w.Append(&optionBrowser2); + mainWindow->Append(&w); + ResumeGui(); + + while(!exit) + { + VIDEO_WaitVSync (); + + ret = optionBrowser2.GetClickedOption(); + if (ret) + { + const char *tt = options2.GetValue(ret); + if (strncmp(tt,"ON",2) == 0) + { + options2.SetValue(ret,"%s","OFF"); + } + else if (strncmp(tt,"OFF",2) == 0) + { + options2.SetValue(ret,"%s","ON"); + } + } + + if(createBtn.GetState() == STATE_CLICKED) + { + createBtn.ResetState(); + if (cntcheats > 0) + { + int selectednrs[30]; + int x = 0; + for(int i = 0; i <= cntcheats; i++) + { + const char *tt = options2.GetValue(i+1); + if (strncmp(tt,"ON",2) == 0) + { + selectednrs[x] = i; + x++; + //WindowPrompt("Selected Cheat",c.getCheatName(i).c_str(),"Okay",NULL,NULL,NULL); + } + } + + string chtpath = Settings.Cheatcodespath; + string gctfname = chtpath + c.getGameID() + ".gct"; + c.createGCT(selectednrs,x,gctfname.c_str()); + WindowPrompt("GCT File created",NULL,tr("OK"),NULL,NULL,NULL); + exit = true; + break; + } else WindowPrompt("Error","Couldnīt create GCT file",tr("OK"),NULL,NULL,NULL); + + } + + if(backBtn.GetState() == STATE_CLICKED) + { + backBtn.ResetState(); + exit = true; + break; + } +} +HaltGui(); +mainWindow->Remove(&w); +ResumeGui(); + +break; +} + +return choice; +} diff --git a/source/cheatmenu.h b/source/cheatmenu.h new file mode 100644 index 00000000..d087d9c6 --- /dev/null +++ b/source/cheatmenu.h @@ -0,0 +1,13 @@ +/**************************************************************************** + * Cheat Menu + * USB Loader GX 2009 + * + * cheatmenu.h + ***************************************************************************/ + +#ifndef _CHEATMENU_H_ +#define _CHEATMENU_H_ + +int CheatMenu(const char * gameID); + +#endif diff --git a/source/filelist.h b/source/filelist.h index 1dd016e9..a72212fd 100644 --- a/source/filelist.h +++ b/source/filelist.h @@ -433,6 +433,7 @@ extern const u32 pegi_16_png_size; extern const u8 pegi_18_png[]; extern const u32 pegi_18_png_size; - +extern const u8 ocarina_png[]; +extern const u32 ocarina_png_size; #endif diff --git a/source/gct.cpp b/source/gct.cpp new file mode 100644 index 00000000..1ade4a7c --- /dev/null +++ b/source/gct.cpp @@ -0,0 +1,325 @@ +#include "gct.h" + +GCTCheats::GCTCheats(void) +{ + iCntCheats = 0; +} + +GCTCheats::~GCTCheats(void) +{ +} + +int GCTCheats::getCnt() +{ + return iCntCheats; +} + +string GCTCheats::getGameName(void) +{ + return sGameTitle; +} + +string GCTCheats::getGameID(void) +{ + return sGameID; +} + +string GCTCheats::getCheat(int nr) +{ + if (nr <= (iCntCheats-1)) + { + return sCheats[nr]; + } + else + { + return OUTOFRANGE;//"Error: CheatNr out of range"; + } +} + +string GCTCheats::getCheatName(int nr) +{ + if (nr <= (iCntCheats-1)) + { + return sCheatName[nr]; + } + else + { + return "Error: CheatNr out of range"; + } +} + +string GCTCheats::getCheatComment(int nr) +{ + if (nr <= (iCntCheats-1)) + { + return sCheatComment[nr]; + } + else + { + return "Error: CheatNr out of range"; + } +} + +int GCTCheats::createGCT(int nr,const char * filename) +{ + ofstream filestr; + filestr.open(filename); + + if (filestr.fail()) + return 0; + + //Reversed Header and Footer + char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde}; + char footer[] = { 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + string buf = getCheat(nr); + filestr.write(header,sizeof(header)); + + int x = 0; + long int li; + int len = buf.size(); + + while (x < len) + { + string temp = buf.substr(x,2); + li = strtol(temp.c_str(),NULL,16); + temp = li; + filestr.write(temp.c_str(),1); + x +=2; + } + filestr.write(footer,sizeof(footer)); + + filestr.close(); + return 1; +} + +int GCTCheats::createGCT(const char * chtbuffer,const char * filename) +{ + ofstream filestr; + filestr.open(filename); + + if (filestr.fail()) + return 0; + + //Reversed Header and Footer + char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde}; + char footer[] = { 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + string buf = chtbuffer; + filestr.write(header,sizeof(header)); + + int x = 0; + long int li; + int len = buf.size(); + + while (x < len) + { + string temp = buf.substr(x,2); + li = strtol(temp.c_str(),NULL,16); + temp = li; + filestr.write(temp.c_str(),1); + x +=2; + } + + filestr.write(footer,sizeof(footer)); + + filestr.close(); + +return 1; +} + +int GCTCheats::createGCT(int nr[],int cnt,const char * filename) +{ + + ofstream filestr; + filestr.open(filename); + + if (filestr.fail()) + return 0; + + //Reversed Header and Footer + char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde}; + char footer[] = { 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + filestr.write(header,sizeof(header)); + + int c = 0; + while (c != cnt) + { + int actnr = nr[c]; + string buf = getCheat(actnr); + long int li; + int len = buf.size(); + int x = 0; + + while (x < len) + { + string temp = buf.substr(x,2); + li = strtol(temp.c_str(),NULL,16); + temp = li; + filestr.write(temp.c_str(),1); + x +=2; + } + c++; + } + +filestr.write(footer,sizeof(footer)); +filestr.close(); +return 1; +} + +int GCTCheats::openTxtfile(const char * filename) +{ + ifstream filestr; + int i = 0; + string str; + filestr.open(filename); + + if (filestr.fail()) + return 0; + + filestr.seekg(0,ios_base::end); + int size = filestr.tellg(); + if (size <= 0) return -1; + filestr.seekg(0,ios_base::beg); + + getline(filestr,sGameID); + getline(filestr,sGameTitle); + filestr.ignore(); + + while(!filestr.eof()) + { + getline(filestr,sCheatName[i]); + string cheatdata; + bool emptyline = false; + bool isComment = false; + + do + { + getline(filestr,str,'\n'); + //cheatdata.append(str); + + if (str == "") + { + emptyline = true; + break; + } + + if (str.size() <= 16 || str.size() > 17 ) + { + isComment = true; + printf ("%i",str.size()); + } + + if (!isComment) + { + cheatdata.append(str); + size_t found=cheatdata.find(' '); + cheatdata.replace(found,1,""); + } else + { + sCheatComment[i] = str; + } + + if (filestr.eof()) break; + } while(!emptyline); + + sCheats[i] = cheatdata; + i++; +} +iCntCheats = i; +filestr.close(); +return 1; +} + + +/*int GCTCheats::openTxtfile(const char * filename) +{ + ifstream filestr; + int i = 0; + string str; + filestr.open(filename); + + if (filestr.fail()) + return 0; + + filestr.seekg(0,ios_base::end); + int size = filestr.tellg(); + if (size <= 0) return -1; + filestr.seekg(0,ios_base::beg); + + getline(filestr,sGameID); + getline(filestr,sGameTitle); + filestr.ignore(); + + while(!filestr.eof()) + { + getline(filestr,sCheatName[i]); + string cheatdata; + bool emptyline = false; + + do + { + getline(filestr,str,'\n'); + cheatdata.append(str); + + if (str == "") + { + emptyline = true; + break; + } + + size_t found=cheatdata.find(' '); + cheatdata.replace(found,1,""); + + if (filestr.eof()) break; + } while(!emptyline); + + sCheats[i] = cheatdata; + i++; +} +iCntCheats = i; +filestr.close(); +return 1; +}*/ + +struct GCTCheats::chtentries GCTCheats::getCheatList(void) +{ + + struct GCTCheats::chtentries cheatlist; + int i = 0; + cheatlist.sGameID = sGameID; + cheatlist.sGameTitle = sGameTitle; + + while (i < iCntCheats) + { + cheatlist.sCheatName[i] = sCheatName[i]; + cheatlist.sCheats[i] = sCheats[i]; + i++; + } + return cheatlist; +} + +struct GCTCheats::chtentries GCTCheats::getCheatList(const char * filename) +{ + openTxtfile(filename); + struct GCTCheats::chtentries cheatlist; + int i = 0; + cheatlist.sGameID = sGameID; + cheatlist.sGameTitle = sGameTitle; + cheatlist.iCntCheats = iCntCheats; + + while (i < iCntCheats) + { + cheatlist.sCheatName[i] = sCheatName[i]; + cheatlist.sCheats[i] = sCheats[i]; + i++; + } + return cheatlist; +} + +int GCTCheats::download_txtcheat(int id) +{ +//ToDo +return 1; +} diff --git a/source/gct.h b/source/gct.h new file mode 100644 index 00000000..53b141e8 --- /dev/null +++ b/source/gct.h @@ -0,0 +1,111 @@ +/* + * gct.h + * Class to handle Ocarina TXT Cheatfiles + * WIP: Actually itīs needed to call fatInitDefault() or the file will not be found + * and no Comments supported for now + */ + +#ifndef _GCT_H +#define _GCT_H + +#include +#include +#include + +#define OUTOFRANGE "Error:Range" +#define MAXCHEATS 40 +#define GCT_PATH "sd:/codes/" +#define GECKOSITE "http://www.usbgecko.com/codes/codes/" + +using namespace std; + +struct chtentrie +{ + string sGameID; + string sGameTitle; + string sCheatName[MAXCHEATS]; + string sCheats[MAXCHEATS]; + string sCheatComment[MAXCHEATS]; + int iCntCheats; +}; + +//!Handles Ocarina TXT Cheatfiles +class GCTCheats +{ +private: + chtentrie ccc; + string sGameID; + string sGameTitle; + string sCheatName[MAXCHEATS]; + string sCheats[MAXCHEATS]; + string sCheatComment[MAXCHEATS]; + int iCntCheats; + +public: + +struct chtentries +{ + string sGameID; + string sGameTitle; + string sCheatName[MAXCHEATS]; + string sCheats[MAXCHEATS]; + int iCntCheats; +}; + + //!Constructor + GCTCheats(void); + //!Destructor + ~GCTCheats(void); + //!Open txt file with cheats + //!\param filename name of TXT file + //!\return error code + int openTxtfile(const char * filename); + //!Creates GCT file for one cheat + //!\param nr selected Cheat Numbers + //!\param filename name of GCT file + //!\return error code + int createGCT(int nr,const char * filename); + //!Creates GCT file from a buffer + //!\param chtbuffer buffer that holds the cheat data + //!\param filename name of GCT file + //!\return error code + int createGCT(const char * chtbuffer,const char * filename); + //!Creates GCT file + //!\param nr[] array of selected Cheat Numbers + //!\param cnt size of array + //!\param filename name of GCT file + //!\return error code + int createGCT(int nr[],int cnt,const char * filename); + //!Gets Count cheats + //!\return Count cheats + int getCnt(); + //!Gets Game Name + //!\return Game Name + string getGameName(void); + //!Gets GameID + //!\return GameID + string getGameID(void); + //!Gets cheat data + //!\return cheat data + string getCheat(int nr); + //!Gets Cheat Name + //!\return Cheat Name + string getCheatName(int nr); + //!Gets Cheat Comment + //!\return Cheat Comment + string getCheatComment(int nr); + //!Gets Cheat List + //!\return struct chtentrie + //struct chtentrie getCheatList2(void); + //!Gets Cheat List + //!\return struct chtentries + struct chtentries getCheatList(void); + //!Gets Cheat List from file + //!\param filename name of TXT file + //!\return struct chtentries + struct chtentries getCheatList(const char * filename); + + int download_txtcheat(int id); +}; + +#endif /* _GCT_H */ diff --git a/source/images/ocarina.png b/source/images/ocarina.png new file mode 100644 index 00000000..b44f945f Binary files /dev/null and b/source/images/ocarina.png differ diff --git a/source/menu.cpp b/source/menu.cpp index 13a5246d..8d7f3180 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -27,6 +27,7 @@ #include "mload/mload.h" #include "patches/patchcode.h" #include "network/networkops.h" +#include "cheatmenu.h" #include "menu.h" #include "audio.h" #include "input.h" diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index a0b3e701..7aa791b8 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -8,6 +8,7 @@ #include "libwiigui/gui_customoptionbrowser.h" #include "prompts/PromptWindows.h" #include "settings/SettingsPrompts.h" +#include "cheatmenu.h" #include "fatmounter.h" #include "menu.h" #include "filelist.h" @@ -1199,7 +1200,8 @@ int MenuSettings() options2.SetName(3, "%s", tr("titles.txt Path")); options2.SetName(4, "%s", tr("Updatepath")); options2.SetName(5, "%s", tr("Cheatcodes Path")); - options2.SetName(6, "%s", tr("Dol Path")); + options2.SetName(6, "%s", tr("TXTCheatcodes Path")); + options2.SetName(7, "%s", tr("Dol Path")); for(int i = 0; i <= MAXOPTIONS; i++) options2.SetValue(i, NULL); w.Append(&optionBrowser2); optionBrowser2.SetClickable(true); @@ -1221,7 +1223,8 @@ int MenuSettings() options2.SetValue(3, "%s", Settings.titlestxt_path); options2.SetValue(4, "%s", Settings.update_path); options2.SetValue(5, "%s", Settings.Cheatcodespath); - options2.SetValue(6, "%s", Settings.dolpath); + options2.SetValue(6, "%s", Settings.TxtCheatcodespath); + options2.SetValue(7, "%s", Settings.dolpath); if(backBtn.GetState() == STATE_CLICKED) { @@ -1450,6 +1453,28 @@ int MenuSettings() break; case 6: if ( Settings.godmode == 1) + { + w.Remove(&optionBrowser2); + w.Remove(&backBtn); + char entered[43] = ""; + strncpy(entered, Settings.TxtCheatcodespath, sizeof(entered)); + int result = OnScreenKeyboard(entered,43,0); + w.Append(&optionBrowser2); + w.Append(&backBtn); + if ( result == 1 ) + { + int len = (strlen(entered)-1); + if(entered[len] !='/') + strncat (entered, "/", 1); + strncpy(Settings.TxtCheatcodespath, entered, sizeof(Settings.TxtCheatcodespath)); + WindowPrompt("TxtCheatcodespathchanged",0,tr("OK"),0,0,0); + } + } + else + WindowPrompt(0,tr("Console should be unlocked to modify it."),tr("OK"),0,0,0); + break; + case 7: + if ( Settings.godmode == 1) { w.Remove(&optionBrowser2); w.Remove(&backBtn); @@ -1738,6 +1763,8 @@ int GameSettings(struct discHdr * header) char imgPath[100]; + snprintf(imgPath, sizeof(imgPath), "%socarina.png", CFG.theme_path); + GuiImageData btnOcarina(imgPath, ocarina_png); snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); GuiImageData btnOutline(imgPath, button_dialogue_box_png); snprintf(imgPath, sizeof(imgPath), "%sgamesettings_background.png", CFG.theme_path); @@ -1792,6 +1819,12 @@ int GameSettings(struct discHdr * header) deleteBtn.SetScale(0.9); deleteBtn.SetLabel(&deleteBtnTxt); + GuiImage GCTBtnImg(&btnOcarina); + if (Settings.wsprompt == yes){ + GCTBtnImg.SetWidescreen(CFG.widescreen);} + GuiButton GCTBtn(&GCTBtnImg,&GCTBtnImg, ALIGN_RIGHT, ALIGN_TOP, 0, 80, &trigA, &btnSoundOver, &btnClick,1); + GCTBtn.SetScale(0.5); + GuiCustomOptionBrowser optionBrowser3(396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, 1, 200); optionBrowser3.SetPosition(0, 90); optionBrowser3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); @@ -1804,8 +1837,9 @@ int GameSettings(struct discHdr * header) w.Append(&saveBtn); w.Append(&cancelBtn); w.Append(&optionBrowser3); - - mainWindow->Append(&w); + w.Append(&GCTBtn); + + mainWindow->Append(&w); struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); @@ -2052,6 +2086,12 @@ int GameSettings(struct discHdr * header) } } + + if (GCTBtn.GetState() == STATE_CLICKED) { + char ID[7]; + snprintf (ID,sizeof(ID),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); + CheatMenu(ID); + } } HaltGui(); diff --git a/source/settings/cfg.c b/source/settings/cfg.c index 560eaa19..5fea6fd1 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -219,6 +219,7 @@ void CFG_Default(int widescreen) // -1 = non forced Mode snprintf(Settings.oggload_path, sizeof(Settings.oggload_path), "%s/config/backgroundmusic/", bootDevice); snprintf(Settings.update_path, sizeof(Settings.update_path), "%s/apps/usbloader_gx/", bootDevice); snprintf(Settings.Cheatcodespath, sizeof(Settings.Cheatcodespath), "%s/codes/", bootDevice); + snprintf(Settings.TxtCheatcodespath, sizeof(Settings.TxtCheatcodespath), "%s/txtcodes/", bootDevice); snprintf(Settings.dolpath, sizeof(Settings.dolpath), "%s/", bootDevice); sprintf(Settings.ogg_path, "notset"); @@ -488,6 +489,10 @@ void path_set(char *name, char *val) strcopy(Settings.Cheatcodespath, val, sizeof(Settings.Cheatcodespath)); return; } + if (strcmp(name, "TxtCheatcodespath") == 0) { + strcopy(Settings.TxtCheatcodespath, val, sizeof(Settings.TxtCheatcodespath)); + return; + } if (strcmp(name, "oggload_path") == 0) { strcopy(Settings.oggload_path, val, sizeof(Settings.oggload_path)); return; diff --git a/source/settings/cfg.h b/source/settings/cfg.h index f111c10c..56839e17 100644 --- a/source/settings/cfg.h +++ b/source/settings/cfg.h @@ -348,6 +348,7 @@ struct SSettings { char dolpath[150]; char update_path[150]; char Cheatcodespath[100]; + char TxtCheatcodespath[100]; short error002; int titlesOverride; // db_titles char db_url[200];