snes9x/macosx/mac-cheat.mm

552 lines
18 KiB
Plaintext
Executable File

/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
***********************************************************************************/
#include "port.h"
#include "cheats.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include "mac-prefix.h"
#include "mac-dialog.h"
#include "mac-os.h"
#include "mac-stringtools.h"
#include "mac-cheat.h"
#define kDataBrowser 'BRSR'
#define kCmCheckBox 'CHK_'
#define kCmAddress 'ADDR'
#define kCmValue 'VALU'
#define kCmDescription 'DESC'
#define kNewButton 'NEW_'
#define kDelButton 'DEL_'
#define kAllButton 'ALL_'
extern SCheatData Cheat;
typedef struct
{
uint32 id;
uint32 address;
uint8 value;
bool8 valid;
bool8 enabled;
char description[22];
} CheatItem;
static WindowRef wRef;
static HIViewRef dbRef;
static CheatItem citem[MAC_MAX_CHEATS];
static uint32 numofcheats;
static void InitCheatItems (void);
static void ImportCheatItems (void);
static void DetachCheatItems (void);
static void AddCheatItem (void);
static void DeleteCheatItem (void);
static void EnableAllCheatItems (void);
static void DBItemNotificationCallBack (HIViewRef, DataBrowserItemID, DataBrowserItemNotification);
static OSStatus CheatEventHandler (EventHandlerCallRef, EventRef, void *);
static void InitCheatItems (void)
{
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
citem[i].id = i + 1;
citem[i].valid = false;
citem[i].enabled = false;
citem[i].address = 0;
citem[i].value = 0;
sprintf(citem[i].description, "Cheat %03" PRIu32, citem[i].id);
}
}
static void ImportCheatItems (void)
{
int cheat_num = std::min((int)Cheat.g.size(), MAC_MAX_CHEATS);
for (unsigned int i = 0; i < cheat_num; i++)
{
citem[i].valid = true;
citem[i].enabled = Cheat.g[i].enabled;
citem[i].address = Cheat.g[i].c[0].address; // mac dialog only supports one cheat per group at the moment
citem[i].value = Cheat.g[i].c[0].byte;
strncpy(citem[i].description, Cheat.g[i].name, 21);
citem[i].description[21] = '\0';
}
}
static void DetachCheatItems (void)
{
S9xDeleteCheats();
for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
{
if (citem[i].valid)
{
char code[10];
snprintf(code, 10, "%x=%x", citem[i].address, citem[i].value);
int index = S9xAddCheatGroup(citem[i].description, code);
if(citem[i].enabled && index >= 0)
S9xEnableCheatGroup(index);
}
}
}
void ConfigureCheat (void)
{
if (!cartOpen)
return;
// OSStatus err;
// IBNibRef nibRef;
//
// err = CreateNibReference(kMacS9XCFString, &nibRef);
// if (err == noErr)
// {
// err = CreateWindowFromNib(nibRef, CFSTR("CheatEntry"), &wRef);
// if (err == noErr)
// {
// DataBrowserCallbacks callbacks;
// EventHandlerRef eref;
// EventHandlerUPP eUPP;
// EventTypeSpec events[] = { { kEventClassCommand, kEventCommandProcess },
// { kEventClassCommand, kEventCommandUpdateStatus },
// { kEventClassWindow, kEventWindowClose } };
// HIViewRef ctl, root;
// HIViewID cid;
//
// root = HIViewGetRoot(wRef);
// cid.id = 0;
// cid.signature = kDataBrowser;
// HIViewFindByID(root, cid, &dbRef);
//
// #ifdef MAC_PANTHER_SUPPORT
// if (systemVersion < 0x1040)
// {
// HISize minSize;
// Rect rct;
//
// GetWindowBounds(wRef, kWindowContentRgn, &rct);
// minSize.width = (float) (rct.right - rct.left);
// minSize.height = (float) (rct.bottom - rct.top );
// err = SetWindowResizeLimits(wRef, &minSize, NULL);
// }
// #endif
//
// callbacks.version = kDataBrowserLatestCallbacks;
// err = InitDataBrowserCallbacks(&callbacks);
// callbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP(DBClientDataCallback);
// callbacks.u.v1.itemCompareCallback = NewDataBrowserItemCompareUPP(DBCompareCallBack);
// callbacks.u.v1.itemNotificationCallback = NewDataBrowserItemNotificationUPP(DBItemNotificationCallBack);
// err = SetDataBrowserCallbacks(dbRef, &callbacks);
//
// if (systemVersion >= 0x1040)
// err = DataBrowserChangeAttributes(dbRef, kDataBrowserAttributeListViewAlternatingRowColors, kDataBrowserAttributeNone);
//
// InitCheatItems();
// ImportCheatItems();
//
// DataBrowserItemID *id;
//
// id = new DataBrowserItemID[MAC_MAX_CHEATS];
// if (!id)
// QuitWithFatalError(@"cheat 01");
//
// numofcheats = 0;
//
// for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
// {
// if (citem[i].valid)
// {
// id[numofcheats] = citem[i].id;
// numofcheats++;
// }
// }
//
// if (numofcheats)
// err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, numofcheats, id, kDataBrowserItemNoProperty);
//
// delete [] id;
//
// cid.signature = kNewButton;
// HIViewFindByID(root, cid, &ctl);
// if (numofcheats == MAC_MAX_CHEATS)
// err = DeactivateControl(ctl);
// else
// err = ActivateControl(ctl);
//
// cid.signature = kAllButton;
// HIViewFindByID(root, cid, &ctl);
// if (numofcheats == 0)
// err = DeactivateControl(ctl);
// else
// err = ActivateControl(ctl);
//
// cid.signature = kDelButton;
// HIViewFindByID(root, cid, &ctl);
// err = DeactivateControl(ctl);
//
// eUPP = NewEventHandlerUPP(CheatEventHandler);
// err = InstallWindowEventHandler(wRef, eUPP, GetEventTypeCount(events), events, (void *) wRef, &eref);
//
// err = SetKeyboardFocus(wRef, dbRef, kControlFocusNextPart);
//
// MoveWindowPosition(wRef, kWindowCheatEntry, true);
// ShowWindow(wRef);
// err = RunAppModalLoopForWindow(wRef);
// HideWindow(wRef);
// SaveWindowPosition(wRef, kWindowCheatEntry);
//
// err = RemoveEventHandler(eref);
// DisposeEventHandlerUPP(eUPP);
//
// DisposeDataBrowserItemNotificationUPP(callbacks.u.v1.itemNotificationCallback);
// DisposeDataBrowserItemCompareUPP(callbacks.u.v1.itemCompareCallback);
// DisposeDataBrowserItemDataUPP(callbacks.u.v1.itemDataCallback);
//
// CFRelease(wRef);
//
// DetachCheatItems();
// }
//
// DisposeNibReference(nibRef);
// }
}
static void AddCheatItem (void)
{
// OSStatus err;
// HIViewRef ctl, root;
// HIViewID cid;
// DataBrowserItemID id[1];
// unsigned int i;
//
// if (numofcheats == MAC_MAX_CHEATS)
// return;
//
// for (i = 0; i < MAC_MAX_CHEATS; i++)
// if (citem[i].valid == false)
// break;
//
// if (i == MAC_MAX_CHEATS)
// return;
//
// numofcheats++;
// citem[i].valid = true;
// citem[i].enabled = false;
// citem[i].address = 0;
// citem[i].value = 0;
// sprintf(citem[i].description, "Cheat %03" PRIu32, citem[i].id);
//
// id[0] = citem[i].id;
// err = AddDataBrowserItems(dbRef, kDataBrowserNoItem, 1, id, kDataBrowserItemNoProperty);
// err = RevealDataBrowserItem(dbRef, id[0], kCmAddress, true);
//
// root = HIViewGetRoot(wRef);
// cid.id = 0;
//
// if (numofcheats == MAC_MAX_CHEATS)
// {
// cid.signature = kNewButton;
// HIViewFindByID(root, cid, &ctl);
// err = DeactivateControl(ctl);
// }
//
// if (numofcheats)
// {
// cid.signature = kAllButton;
// HIViewFindByID(root, cid, &ctl);
// err = ActivateControl(ctl);
// }
}
static void DeleteCheatItem (void)
{
// OSStatus err;
// HIViewRef ctl, root;
// HIViewID cid;
// Handle selectedItems;
// ItemCount selectionCount;
//
// selectedItems = NewHandle(0);
// if (!selectedItems)
// return;
//
// err = GetDataBrowserItems(dbRef, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems);
// selectionCount = (GetHandleSize(selectedItems) / sizeof(DataBrowserItemID));
//
// if (selectionCount == 0)
// {
// DisposeHandle(selectedItems);
// return;
// }
//
// err = RemoveDataBrowserItems(dbRef, kDataBrowserNoItem, selectionCount, (DataBrowserItemID *) *selectedItems, kDataBrowserItemNoProperty);
//
// for (unsigned int i = 0; i < selectionCount; i++)
// {
// citem[((DataBrowserItemID *) (*selectedItems))[i] - 1].valid = false;
// citem[((DataBrowserItemID *) (*selectedItems))[i] - 1].enabled = false;
// numofcheats--;
// }
//
// DisposeHandle(selectedItems);
//
// root = HIViewGetRoot(wRef);
// cid.id = 0;
//
// if (numofcheats < MAC_MAX_CHEATS)
// {
// cid.signature = kNewButton;
// HIViewFindByID(root, cid, &ctl);
// err = ActivateControl(ctl);
// }
//
// if (numofcheats == 0)
// {
// cid.signature = kAllButton;
// HIViewFindByID(root, cid, &ctl);
// err = DeactivateControl(ctl);
// }
}
static void EnableAllCheatItems (void)
{
// OSStatus err;
//
// for (unsigned int i = 0; i < MAC_MAX_CHEATS; i++)
// if (citem[i].valid)
// citem[i].enabled = true;
//
// err = UpdateDataBrowserItems(dbRef, kDataBrowserNoItem, kDataBrowserNoItem, NULL, kDataBrowserItemNoProperty, kCmCheckBox);
}
static OSStatus DBClientDataCallback (HIViewRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean changeValue)
{
// OSStatus err, result;
// CFStringRef str;
// Boolean r;
// uint32 address;
// uint8 value;
// char code[256];
//
// result = noErr;
//
// switch (property)
// {
// case kCmCheckBox:
// ThemeButtonValue buttonValue;
//
// if (changeValue)
// {
// err = GetDataBrowserItemDataButtonValue(itemData, &buttonValue);
// citem[itemID - 1].enabled = (buttonValue == kThemeButtonOn) ? true : false;
// }
// else
// err = SetDataBrowserItemDataButtonValue(itemData, citem[itemID - 1].enabled ? kThemeButtonOn : kThemeButtonOff);
//
// break;
//
// case kCmAddress:
// if (changeValue)
// {
// err = GetDataBrowserItemDataText(itemData, &str);
// r = CFStringGetCString(str, code, 256, CFStringGetSystemEncoding());
// CFRelease(str);
// if (r)
// {
// Boolean translated;
//
// if (S9xProActionReplayToRaw(code, address, value) == NULL)
// translated = true;
// else
// if (S9xGameGenieToRaw(code, address, value) == NULL)
// translated = true;
// else
// {
// translated = false;
// if (sscanf(code, "%" SCNx32, &address) != 1)
// address = 0;
// else
// address &= 0xFFFFFF;
// }
//
// citem[itemID - 1].address = address;
// sprintf(code, "%06" PRIX32, address);
// str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
//
// if (translated)
// {
// DataBrowserItemID id[1];
//
// citem[itemID - 1].value = value;
// id[0] = itemID;
// err = UpdateDataBrowserItems(browser, kDataBrowserNoItem, 1, id, kDataBrowserItemNoProperty, kCmValue);
// }
// }
// }
// else
// {
// sprintf(code, "%06" PRIX32, citem[itemID - 1].address);
// str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
// }
//
// break;
//
// case kCmValue:
// if (changeValue)
// {
// err = GetDataBrowserItemDataText(itemData, &str);
// r = CFStringGetCString(str, code, 256, CFStringGetSystemEncoding());
// CFRelease(str);
// if (r)
// {
// uint32 byte;
//
// if (sscanf(code, "%" SCNx32, &byte) == 1)
// citem[itemID - 1].value = (uint8) byte;
// else
// {
// citem[itemID - 1].value = 0;
// err = SetDataBrowserItemDataText(itemData, CFSTR("00"));
// }
// }
// }
// else
// {
// sprintf(code, "%02" PRIX8, citem[itemID - 1].value);
// str = CFStringCreateWithCString(kCFAllocatorDefault, code, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
// }
//
// break;
//
// case kCmDescription:
// if (changeValue)
// {
// code[0] = 0;
// err = GetDataBrowserItemDataText(itemData, &str);
// strcpy(code, GetMultiByteCharacters(str, 19));
// CFRelease(str);
//
// if (code[0] == 0)
// {
// code[0] = ' ';
// code[1] = 0;
// }
//
// strcpy(citem[itemID - 1].description, code);
// }
// else
// {
// str = CFStringCreateWithCString(kCFAllocatorDefault, citem[itemID - 1].description, CFStringGetSystemEncoding());
// err = SetDataBrowserItemDataText(itemData, str);
// CFRelease(str);
// }
//
// break;
//
// case kDataBrowserItemIsActiveProperty:
// err = SetDataBrowserItemDataBooleanValue(itemData, true);
// break;
//
// case kDataBrowserItemIsEditableProperty:
// err = SetDataBrowserItemDataBooleanValue(itemData, true);
// break;
//
// default:
// result = errDataBrowserPropertyNotSupported;
// }
//
// return (result);
return 0;
}
static OSStatus CheatEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
// OSStatus err, result = eventNotHandledErr;
// WindowRef tWindowRef;
//
// tWindowRef = (WindowRef) inUserData;
//
// switch (GetEventClass(inEvent))
// {
// case kEventClassWindow:
// switch (GetEventKind(inEvent))
// {
// case kEventWindowClose:
// QuitAppModalLoopForWindow(tWindowRef);
// result = noErr;
// break;
// }
//
// break;
//
// case kEventClassCommand:
// switch (GetEventKind(inEvent))
// {
// HICommand tHICommand;
//
// case kEventCommandUpdateStatus:
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
// if (err == noErr && tHICommand.commandID == 'clos')
// {
// UpdateMenuCommandStatus(true);
// result = noErr;
// }
//
// break;
//
// case kEventCommandProcess:
// err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &tHICommand);
// if (err == noErr)
// {
// switch (tHICommand.commandID)
// {
// case kNewButton:
// AddCheatItem();
// result = noErr;
// break;
//
// case kDelButton:
// DeleteCheatItem();
// result = noErr;
// break;
//
// case kAllButton:
// EnableAllCheatItems();
// result = noErr;
// }
// }
// }
// }
//
// return (result);
return 0;
}