fceux/drivers/win/cheat.cpp

707 lines
22 KiB
C++

/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Ben Parnell
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common.h"
#include "cheat.h"
#include "memview.h"
#include "debugger.h"
#include "..\..\fceu.h"
#include "..\..\cart.h"
HWND hCheat; //mbg merge 7/19/06 had to add
int CheatWindow,CheatStyle; //mbg merge 7/19/06 had to add
#define GGLISTSIZE 128 //hopefully this is enough for all cases
int selcheat;
int ChtPosX,ChtPosY;
static HFONT hFont,hNewFont;
static int scrollindex;
static int scrollnum;
static int scrollmax;
int lbfocus=0;
int searchdone;
static int knownvalue=0;
int GGaddr, GGcomp, GGval;
char GGcode[10];
int GGlist[GGLISTSIZE];
static int dontupdateGG; //this eliminates recursive crashing
HWND hGGConv;
void EncodeGG(char *str, int a, int v, int c);
void ListGGAddresses();
uint16 StrToU16(char *s) {
unsigned int ret=0;
sscanf(s,"%4x",&ret);
return ret;
}
uint8 StrToU8(char *s) {
unsigned int ret=0;
sscanf(s,"%2x",&ret);
return ret;
}
char *U16ToStr(uint16 a) {
static char str[5];
sprintf(str,"%04X",a);
return str;
}
char *U8ToStr(uint8 a) {
static char str[3];
sprintf(str,"%02X",a);
return str;
}
static HWND hwndLB;
//int RedoCheatsCallB(char *name, uint32 a, uint8 v, int s) { //bbit edited: this commented out line was changed to the below for the new fceud
int RedoCheatsCallB(char *name, uint32 a, uint8 v, int compare,int s,int type,void*data) {
char str[259] = { 0 };
//strcpy(str,(s?"* ":" "));
//strcat(str,name);
if(name[0] == 0)sprintf(str,"%s%04X=%02X",s?"* ":" ",(int)a,(int)v);
else sprintf(str,"%s%s",s?"* ":" ",name);
SendDlgItemMessage(hwndLB,101,LB_ADDSTRING,0,(LPARAM)(LPSTR)str);
return 1;
}
void RedoCheatsLB(HWND hwndDlg) {
SendDlgItemMessage(hwndDlg,101,LB_RESETCONTENT,0,0);
hwndLB=hwndDlg;
FCEUI_ListCheats(RedoCheatsCallB,0);
}
int ShowResultsCallB(uint32 a, uint8 last, uint8 current) {
char temp[16];
sprintf(temp,"$%04X: %02X | %02X",(unsigned int)a,last,current);
SendDlgItemMessage(hwndLB,106,LB_ADDSTRING,0,(LPARAM)(LPSTR)temp);
return 1;
}
void ShowResults(HWND hwndDlg) {
int n=FCEUI_CheatSearchGetCount();
int t;
char str[20];
scrollnum=n;
scrollindex=-32768;
hwndLB=hwndDlg;
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,0,0);
FCEUI_CheatSearchGetRange(0,16,ShowResultsCallB);
t=-32768+n-17;
if (t<-32768) t=-32768;
scrollmax=t;
SendDlgItemMessage(hwndDlg,107,SBM_SETRANGE,-32768,t);
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,-32768,1);
sprintf(str,"%d Possibilities",n);
SetDlgItemText(hwndDlg,203,str);
}
void EnableCheatButtons(HWND hwndDlg, int enable) {
EnableWindow(GetDlgItem(hwndDlg,105),enable);
EnableWindow(GetDlgItem(hwndDlg,305),enable);
EnableWindow(GetDlgItem(hwndDlg,306),enable);
EnableWindow(GetDlgItem(hwndDlg,307),enable);
EnableWindow(GetDlgItem(hwndDlg,308),enable);
EnableWindow(GetDlgItem(hwndDlg,309),enable);
}
extern void StopSound(void);
BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
LOGFONT lf;
RECT wrect;
char str[259] = { 0 },str2[259] = { 0 };
char *name;
uint32 a;
uint8 v;
int s;
switch (uMsg) {
case WM_INITDIALOG:
StopSound();
SetWindowPos(hwndDlg,0,ChtPosX,ChtPosY,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER);
//setup font
hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
GetObject(hFont, sizeof(LOGFONT), &lf);
strcpy(lf.lfFaceName,"Courier");
hNewFont = CreateFontIndirect(&lf);
SendDlgItemMessage(hwndDlg,102,WM_SETFONT,(WPARAM)hNewFont,FALSE);
SendDlgItemMessage(hwndDlg,103,WM_SETFONT,(WPARAM)hNewFont,FALSE);
SendDlgItemMessage(hwndDlg,105,WM_SETFONT,(WPARAM)hNewFont,FALSE);
SendDlgItemMessage(hwndDlg,106,WM_SETFONT,(WPARAM)hNewFont,FALSE);
SendDlgItemMessage(hwndDlg,108,WM_SETFONT,(WPARAM)hNewFont,FALSE);
SendDlgItemMessage(hwndDlg,109,WM_SETFONT,(WPARAM)hNewFont,FALSE);
SendDlgItemMessage(hwndDlg,110,WM_SETFONT,(WPARAM)hNewFont,FALSE);
//text limits
SendDlgItemMessage(hwndDlg,102,EM_SETLIMITTEXT,4,0);
SendDlgItemMessage(hwndDlg,103,EM_SETLIMITTEXT,2,0);
SendDlgItemMessage(hwndDlg,104,EM_SETLIMITTEXT,256,0);
SendDlgItemMessage(hwndDlg,105,EM_SETLIMITTEXT,2,0);
SendDlgItemMessage(hwndDlg,108,EM_SETLIMITTEXT,2,0);
SendDlgItemMessage(hwndDlg,109,EM_SETLIMITTEXT,2,0);
SendDlgItemMessage(hwndDlg,110,EM_SETLIMITTEXT,2,0);
//disable or enable buttons
EnableWindow(GetDlgItem(hwndDlg,105),FALSE);
EnableWindow(GetDlgItem(hwndDlg,302),FALSE);
EnableWindow(GetDlgItem(hwndDlg,303),FALSE);
if (scrollnum) {
EnableCheatButtons(hwndDlg,TRUE);
ShowResults(hwndDlg);
sprintf(str,"%d Possibilities",(int)FCEUI_CheatSearchGetCount());
SetDlgItemText(hwndDlg,203,str);
}
else EnableCheatButtons(hwndDlg,FALSE);
//misc setup
RedoCheatsLB(hwndDlg);
searchdone=0;
SetDlgItemText(hwndDlg,105,(LPTSTR)U8ToStr(knownvalue));
break;
case WM_NCACTIVATE:
if ((CheatStyle) && (scrollnum)) {
if ((!wParam) && (searchdone)) {
searchdone=0;
FCEUI_CheatSearchSetCurrentAsOriginal();
}
ShowResults(hwndDlg);
}
break;
case WM_CLOSE:
case WM_QUIT:
CheatWindow=0;
hCheat = 0;
if (CheatStyle) DestroyWindow(hwndDlg);
else EndDialog(hwndDlg,0);
DeleteObject(hFont);
DeleteObject(hNewFont);
if (searchdone) FCEUI_CheatSearchSetCurrentAsOriginal();
break;
case WM_MOVE:
GetWindowRect(hwndDlg,&wrect);
ChtPosX = wrect.left;
ChtPosY = wrect.top;
break;
case WM_VSCROLL:
if (scrollnum > 16) {
StopSound();
switch (LOWORD(wParam)) {
case SB_TOP:
scrollindex=-32768;
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,16,0);
FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+16,ShowResultsCallB);
break;
case SB_BOTTOM:
scrollindex=scrollmax;
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,16,0);
FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+16,ShowResultsCallB);
break;
case SB_LINEUP:
if (scrollindex > -32768) {
scrollindex--;
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,16,0);
FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+16,ShowResultsCallB);
}
break;
case SB_PAGEUP:
scrollindex-=17;
if(scrollindex<-32768) scrollindex=-32768;
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,16,0);
FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+16,ShowResultsCallB);
break;
case SB_LINEDOWN:
if (scrollindex<scrollmax) {
scrollindex++;
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,0,0);
FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+16,ShowResultsCallB);
}
break;
case SB_PAGEDOWN:
scrollindex+=17;
if (scrollindex>scrollmax) scrollindex=scrollmax;
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,0,0);
FCEUI_CheatSearchGetRange(scrollindex+32768,scrollindex+32768+16,ShowResultsCallB);
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
scrollindex=(short int)HIWORD(wParam);
SendDlgItemMessage(hwndDlg,107,SBM_SETPOS,scrollindex,1);
SendDlgItemMessage(hwndDlg,106,LB_RESETCONTENT,0,0);
FCEUI_CheatSearchGetRange(32768+scrollindex,32768+scrollindex+16,ShowResultsCallB);
break;
}
}
break;
case WM_VKEYTOITEM:
if (lbfocus) {
int real;
real=SendDlgItemMessage(hwndDlg,106,LB_GETCURSEL,0,0);
switch (LOWORD(wParam)) {
case VK_UP:
// mmmm....recursive goodness
if (real == 0) SendMessage(hwndDlg,WM_VSCROLL,SB_LINEUP,0);
return -1;
break;
case VK_DOWN:
if (real == 16) {
SendMessage(hwndDlg,WM_VSCROLL,SB_LINEDOWN,0);
SendDlgItemMessage(hwndDlg,106,LB_SETCURSEL,real,0);
}
return -1;
break;
case VK_PRIOR:
SendMessage(hwndDlg,WM_VSCROLL,SB_PAGEUP,0);
break;
case VK_NEXT:
SendMessage(hwndDlg,WM_VSCROLL,SB_PAGEDOWN,0);
break;
case VK_HOME:
SendMessage(hwndDlg,WM_VSCROLL,SB_TOP,0);
break;
case VK_END:
SendMessage(hwndDlg,WM_VSCROLL,SB_BOTTOM,0);
break;
}
return -2;
}
break;
case WM_COMMAND:
switch (HIWORD(wParam)) {
case BN_CLICKED:
switch (LOWORD(wParam)) {
case 301: //Add
GetDlgItemText(hwndDlg,102,str,5);
a=StrToU16(str);
GetDlgItemText(hwndDlg,103,str,3);
v=StrToU8(str);
GetDlgItemText(hwndDlg,104,str,256);
// if (FCEUI_AddCheat(str,a,v)) { //bbit edited: replaced this with the line below
if (FCEUI_AddCheat(str,a,v,-1,1)) {
if(str[0] == 0)sprintf(str,"%04X=%02X",(int)a,(int)v); //bbit edited: added this line to give your cheat a name if you didn't supply one
strcpy(str2,"* ");
strcat(str2,str);
SendDlgItemMessage(hwndDlg,101,LB_ADDSTRING,0,(LPARAM)(LPSTR)str2);
selcheat = (SendDlgItemMessage(hwndDlg,101,LB_GETCOUNT,0,0) - 1);
SendDlgItemMessage(hwndDlg,101,LB_SETCURSEL,selcheat,0);
SetDlgItemText(hwndDlg,102,(LPTSTR)U16ToStr(a));
SetDlgItemText(hwndDlg,103,(LPTSTR)U8ToStr(v));
EnableWindow(GetDlgItem(hwndDlg,302),TRUE);
EnableWindow(GetDlgItem(hwndDlg,303),TRUE);
}
if(hMemView)UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well
break;
case 302: //Delete
if (selcheat >= 0) {
FCEUI_DelCheat(selcheat);
SendDlgItemMessage(hwndDlg,101,LB_DELETESTRING,selcheat,0);
selcheat=-1;
SetDlgItemText(hwndDlg,102,(LPTSTR)"");
SetDlgItemText(hwndDlg,103,(LPTSTR)"");
SetDlgItemText(hwndDlg,104,(LPTSTR)"");
}
EnableWindow(GetDlgItem(hwndDlg,302),FALSE);
EnableWindow(GetDlgItem(hwndDlg,303),FALSE);
if(hMemView)UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well
break;
case 303: //Update
if (selcheat < 0) break;
GetDlgItemText(hwndDlg,102,str,5);
a=StrToU16(str);
GetDlgItemText(hwndDlg,103,str,3);
v=StrToU8(str);
GetDlgItemText(hwndDlg,104,str,256);
// FCEUI_SetCheat(selcheat,str,a,v,-1); //bbit edited: replaced this with the line below
FCEUI_SetCheat(selcheat,str,a,v,-1,-1,1);
// FCEUI_GetCheat(selcheat,&name,&a,&v,&s); //bbit edited: replaced this with the line below
FCEUI_GetCheat(selcheat,&name,&a,&v,NULL,&s,NULL);
strcpy(str2,(s?"* ":" "));
if(str[0] == 0)sprintf(str,"%04X=%02X",(int)a,(int)v); //bbit edited: added this line to give your cheat a name if you didn't supply one
strcat(str2,str);
SendDlgItemMessage(hwndDlg,101,LB_DELETESTRING,selcheat,0);
SendDlgItemMessage(hwndDlg,101,LB_INSERTSTRING,selcheat,(LPARAM)(LPSTR)str2);
SendDlgItemMessage(hwndDlg,101,LB_SETCURSEL,selcheat,0);
SetDlgItemText(hwndDlg,102,(LPTSTR)U16ToStr(a));
SetDlgItemText(hwndDlg,103,(LPTSTR)U8ToStr(v));
if(hMemView)UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well
break;
case 304: //Reset
FCEUI_CheatSearchBegin();
ShowResults(hwndDlg);
EnableCheatButtons(hwndDlg,TRUE);
break;
case 305: //Known Value
searchdone=1;
GetDlgItemText(hwndDlg,105,str,3);
knownvalue=StrToU8(str);
FCEUI_CheatSearchEnd(4,knownvalue,0);
ShowResults(hwndDlg);
break;
case 306: //Equal
searchdone=1;
FCEUI_CheatSearchEnd(2,0,0);
ShowResults(hwndDlg);
break;
case 307: //Not Equal
searchdone=1;
if (IsDlgButtonChecked(hwndDlg,401) == BST_CHECKED) {
GetDlgItemText(hwndDlg,108,str,3);
FCEUI_CheatSearchEnd(2,0,StrToU8(str));
}
else FCEUI_CheatSearchEnd(3,0,0);
ShowResults(hwndDlg);
break;
case 308: //Greater Than
searchdone=1;
if (IsDlgButtonChecked(hwndDlg,402) == BST_CHECKED) {
GetDlgItemText(hwndDlg,109,str,3);
FCEUI_CheatSearchEnd(7,0,StrToU8(str));
}
else FCEUI_CheatSearchEnd(5,0,0);
ShowResults(hwndDlg);
break;
case 309: //Less Than
searchdone=1;
if (IsDlgButtonChecked(hwndDlg,403) == BST_CHECKED) {
GetDlgItemText(hwndDlg,110,str,3);
FCEUI_CheatSearchEnd(8,0,StrToU8(str));
}
else FCEUI_CheatSearchEnd(6,0,0);
ShowResults(hwndDlg);
break;
}
break;
case LBN_DBLCLK:
switch (LOWORD(wParam)) { //disable/enable cheat
case 101:
// FCEUI_GetCheat(selcheat,&name,&a,&v,&s); //bbit edited: replaced this with the line below
FCEUI_GetCheat(selcheat,&name,&a,&v,NULL,&s,NULL);
// FCEUI_SetCheat(selcheat,0,-1,-1,s^=1);//bbit edited: replaced this with the line below
FCEUI_SetCheat(selcheat,0,-1,-1,-1,s^=1,1);
if(name[0] == 0)sprintf(str,"%s%04X=%02X",s?"* ":" ",(unsigned int)a,(unsigned int)v);
else sprintf(str,"%s%s",s?"* ":" ",name);
//strcpy(str,(s?"* ":" "));
//strcat(str,name);
SendDlgItemMessage(hwndDlg,101,LB_DELETESTRING,selcheat,0);
SendDlgItemMessage(hwndDlg,101,LB_INSERTSTRING,selcheat,(LPARAM)(LPSTR)str);
SendDlgItemMessage(hwndDlg,101,LB_SETCURSEL,selcheat,0);
UpdateColorTable();
break;
}
break;
case LBN_SELCHANGE:
switch (LOWORD(wParam)) {
case 101:
selcheat = SendDlgItemMessage(hwndDlg,101,LB_GETCURSEL,0,0);
if (selcheat < 0) break;
FCEUI_GetCheat(selcheat,&name,&a,&v,NULL,&s,NULL);
SetDlgItemText(hwndDlg,104,(LPTSTR)name);
SetDlgItemText(hwndDlg,102,(LPTSTR)U16ToStr(a));
SetDlgItemText(hwndDlg,103,(LPTSTR)U8ToStr(v));
EnableWindow(GetDlgItem(hwndDlg,302),TRUE);
EnableWindow(GetDlgItem(hwndDlg,303),TRUE);
break;
case 106:
lbfocus=1;
SendDlgItemMessage(hwndDlg,106,LB_GETTEXT,SendDlgItemMessage(hwndDlg,106,LB_GETCURSEL,0,0),(LPARAM)(LPCTSTR)str);
strcpy(str2,str+1);
str2[4] = 0;
SetDlgItemText(hwndDlg,102,(LPTSTR)str2);
strcpy(str2,str+13);
SetDlgItemText(hwndDlg,103,(LPTSTR)str2);
break;
}
break;
case LBN_SELCANCEL:
switch(LOWORD(wParam)) {
case 101:
EnableWindow(GetDlgItem(hwndDlg,302),FALSE);
EnableWindow(GetDlgItem(hwndDlg,303),FALSE);
break;
case 106:
lbfocus=0;
break;
}
break;
}
break;
}
return 0;
}
void ConfigCheats(HWND hParent) {
if (!GI) {
FCEUD_PrintError("You must have a game loaded before you can manipulate cheats.");
return;
}
if (GI->type==GIT_NSF) {
FCEUD_PrintError("Sorry, you can't cheat with NSFs.");
return;
}
if (!CheatWindow) {
selcheat=-1;
CheatWindow=1;
if (CheatStyle) hCheat = CreateDialog(fceu_hInstance,"CHEATCONSOLE",NULL,CheatConsoleCallB);
else DialogBox(fceu_hInstance,"CHEATCONSOLE",hParent,CheatConsoleCallB);
}
}
BOOL CALLBACK GGConvCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
char str[100];
int i;
switch(uMsg) {
case WM_INITDIALOG:
//todo: set text limits
break;
case WM_CREATE:
break;
case WM_PAINT:
break;
case WM_CLOSE:
case WM_QUIT:
DestroyWindow(hGGConv);
hGGConv = 0;
break;
case WM_COMMAND:
switch(HIWORD(wParam)) {
case EN_UPDATE:
if(dontupdateGG)break;
dontupdateGG = 1;
switch(LOWORD(wParam)){ //lets find out what edit control got changed
case 1000: //The Game Genie Code - in this case decode it.
GetDlgItemText(hGGConv,1000,GGcode,9);
if((strlen(GGcode) != 8) && (strlen(GGcode) != 6))break;
FCEUI_DecodeGG(GGcode, (uint16 *)&GGaddr, (uint8 *)&GGval, &GGcomp);
sprintf(str,"%04X",GGaddr);
SetDlgItemText(hGGConv,1001,str);
if(GGcomp != -1)
sprintf(str,"%02X",GGcomp);
else str[0] = 0;
SetDlgItemText(hGGConv,1002,str);
sprintf(str,"%02X",GGval);
SetDlgItemText(hGGConv,1003,str);
//ListGGAddresses();
break;
case 1001:
case 1002:
case 1003:
GetDlgItemText(hGGConv,1001,str,5);
if(strlen(str) != 4) break;
GetDlgItemText(hGGConv,1003,str,5);
if(strlen(str) != 2) {GGval = -1; break;}
GGaddr = GetEditHex(hGGConv,1001);
GGval = GetEditHex(hGGConv,1003);
GetDlgItemText(hGGConv,1002,str,5);
if(strlen(str) != 2) GGcomp = -1;
else GGcomp = GetEditHex(hGGConv,1002);
EncodeGG(GGcode, GGaddr, GGval, GGcomp);
SetDlgItemText(hGGConv,1000,GGcode);
//ListGGAddresses();
break;
}
ListGGAddresses();
dontupdateGG = 0;
break;
case BN_CLICKED:
switch (LOWORD(wParam)) {
case 1005: //Add Cheat
//ConfigCheats(fceu_hInstance);
if(GGaddr < 0x8000)GGaddr += 0x8000;
if (FCEUI_AddCheat(GGcode,GGaddr,GGval,GGcomp,1) && (hCheat != 0)) {
strcpy(str,"* ");
strcat(str,GGcode);
SendDlgItemMessage(hCheat,101,LB_ADDSTRING,0,(LPARAM)(LPSTR)str);
selcheat = (SendDlgItemMessage(hCheat,101,LB_GETCOUNT,0,0) - 1);
SendDlgItemMessage(hCheat,101,LB_SETCURSEL,selcheat,0);
SetDlgItemText(hCheat,102,(LPTSTR)U16ToStr(GGaddr));
SetDlgItemText(hCheat,103,(LPTSTR)U8ToStr(GGval));
EnableWindow(GetDlgItem(hCheat,302),TRUE);
EnableWindow(GetDlgItem(hCheat,303),TRUE);
}
}
break;
case LBN_DBLCLK:
switch (LOWORD(wParam)) {
case 1004:
i = SendDlgItemMessage(hwndDlg,1004,LB_GETCURSEL,0,0);
ChangeMemViewFocus(2,GGlist[i],-1);
break;
}
break;
}
break;
case WM_MOUSEMOVE:
break;
case WM_HSCROLL:
break;
}
return FALSE;
}
//The code in this function is a modified version
//of Chris Covell's work - I'd just like to point that out
void EncodeGG(char *str, int a, int v, int c){
uint8 num[8];
static char lets[16]={'A','P','Z','L','G','I','T','Y','E','O','X','U','K','S','V','N'};
int i;
if(a > 0x8000)a-=0x8000;
num[0]=(v&7)+((v>>4)&8);
num[1]=((v>>4)&7)+((a>>4)&8);
num[2]=((a>>4)&7);
num[3]=(a>>12)+(a&8);
num[4]=(a&7)+((a>>8)&8);
num[5]=((a>>8)&7);
if (c == -1){
num[5]+=v&8;
for(i = 0;i < 6;i++)str[i] = lets[num[i]];
str[6] = 0;
} else {
num[2]+=8;
num[5]+=c&8;
num[6]=(c&7)+((c>>4)&8);
num[7]=((c>>4)&7)+(v&8);
for(i = 0;i < 8;i++)str[i] = lets[num[i]];
str[8] = 0;
}
return;
}
void ListGGAddresses(){
uint32 i, j = 0; //mbg merge 7/18/06 changed from int
char str[20];
SendDlgItemMessage(hGGConv,1004,LB_RESETCONTENT,0,0);
//also enable/disable the add GG button here
GetDlgItemText(hGGConv,1000,GGcode,9);
if((GGaddr < 0) || ((strlen(GGcode) != 8) && (strlen(GGcode) != 6)))EnableWindow(GetDlgItem(hGGConv,1005),FALSE);
else EnableWindow(GetDlgItem(hGGConv,1005),TRUE);
for(i = 0;i < PRGsize[0];i+=0x2000){
if((PRGptr[0][i+(GGaddr&0x1FFF)] == GGcomp) || (GGcomp == -1)){
GGlist[j] = i+(GGaddr&0x1FFF)+0x10;
if(++j > GGLISTSIZE)return;
sprintf(str,"%06X",i+(GGaddr&0x1FFF)+0x10);
SendDlgItemMessage(hGGConv,1004,LB_ADDSTRING,0,(LPARAM)(LPSTR)str);
}
}
}
//A different model for this could be to have everything
//set in the INITDIALOG message based on the internal
//variables, and have this simply call that.
void SetGGConvFocus(int address,int compare){
char str[10];
if(!hGGConv)DoGGConv();
GGaddr = address;
GGcomp = compare;
dontupdateGG = 1; //little hack to fix a nasty bug
sprintf(str,"%04X",address);
SetDlgItemText(hGGConv,1001,str);
dontupdateGG = 0;
sprintf(str,"%02X",GGcomp);
SetDlgItemText(hGGConv,1002,str);
if(GGval < 0)SetDlgItemText(hGGConv,1000,"");
else {
EncodeGG(GGcode, GGaddr, GGval, GGcomp);
SetDlgItemText(hGGConv,1000,GGcode);
}
SetFocus(GetDlgItem(hGGConv,1003));
return;
}
void DoGGConv(){
if(hGGConv)return;
hGGConv = CreateDialog(fceu_hInstance,"GGCONV",NULL,GGConvCallB);
return;
}