2018-11-15 23:31:39 +00:00
|
|
|
/*****************************************************************************\
|
|
|
|
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.
|
|
|
|
\*****************************************************************************/
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
/***********************************************************************************
|
|
|
|
SNES9X for Mac OS (c) Copyright John Stiles
|
|
|
|
|
|
|
|
Snes9x for Mac OS X
|
|
|
|
|
2011-04-10 13:44:28 +00:00
|
|
|
(c) Copyright 2001 - 2011 zones
|
2010-09-25 15:46:12 +00:00
|
|
|
(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
|
2019-05-24 01:18:53 +00:00
|
|
|
(c) Copyright 2019 Michael Donald Buckley
|
2010-09-25 15:46:12 +00:00
|
|
|
***********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#include "snes9x.h"
|
|
|
|
#include "memmap.h"
|
|
|
|
#include "apu.h"
|
|
|
|
#include "snapshot.h"
|
|
|
|
#include "cheats.h"
|
|
|
|
#include "movie.h"
|
|
|
|
#include "display.h"
|
|
|
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
|
|
|
#include "mac-prefix.h"
|
|
|
|
#include "mac-audio.h"
|
|
|
|
#include "mac-cart.h"
|
|
|
|
#include "mac-dialog.h"
|
|
|
|
#include "mac-file.h"
|
|
|
|
#include "mac-os.h"
|
|
|
|
#include "mac-screenshot.h"
|
|
|
|
#include "mac-stringtools.h"
|
|
|
|
#include "mac-snes9x.h"
|
|
|
|
|
|
|
|
extern wchar_t macRecordWChar[MOVIE_MAX_METADATA];
|
|
|
|
|
|
|
|
|
|
|
|
void SNES9X_Go (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
running = true;
|
|
|
|
}
|
|
|
|
|
2019-07-14 03:42:21 +00:00
|
|
|
bool8 SNES9X_OpenCart (NSURL *inRef)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
NSURL *cartRef;
|
2019-09-02 17:20:32 +00:00
|
|
|
const char *filename = inRef.path.UTF8String;
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
SNES9X_SaveSRAM();
|
|
|
|
S9xResetSaveTimer(false);
|
|
|
|
S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!inRef)
|
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
cartRef = NavOpenROMImage();
|
|
|
|
if (!cartRef)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
|
|
|
cartOpen = false;
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2019-07-14 03:42:21 +00:00
|
|
|
cartRef = inRef;
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
spcFileCount = pngFileCount = 0;
|
|
|
|
|
2019-07-14 03:42:21 +00:00
|
|
|
CheckSaveFolder(cartRef);
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
Settings.ForceLoROM = (romDetect == kLoROMForce );
|
|
|
|
Settings.ForceHiROM = (romDetect == kHiROMForce );
|
|
|
|
Settings.ForceHeader = (headerDetect == kHeaderForce );
|
|
|
|
Settings.ForceNoHeader = (headerDetect == kNoHeaderForce );
|
|
|
|
Settings.ForceInterleaved = (interleaveDetect == kInterleaveForce );
|
|
|
|
Settings.ForceInterleaved2 = (interleaveDetect == kInterleave2Force );
|
|
|
|
Settings.ForceInterleaveGD24 = (interleaveDetect == kInterleaveGD24 );
|
|
|
|
Settings.ForceNotInterleaved = (interleaveDetect == kNoInterleaveForce);
|
|
|
|
Settings.ForcePAL = (videoDetect == kPALForce );
|
|
|
|
Settings.ForceNTSC = (videoDetect == kNTSCForce );
|
|
|
|
|
2023-03-08 18:23:32 +00:00
|
|
|
GFX.InfoString = "";
|
2010-09-25 15:46:12 +00:00
|
|
|
GFX.InfoStringTimeout = 0;
|
|
|
|
|
|
|
|
S9xResetSaveTimer(true);
|
|
|
|
|
|
|
|
SNES9X_InitSound();
|
|
|
|
|
|
|
|
if (Memory.LoadROM(filename))
|
|
|
|
{
|
|
|
|
cartOpen = true;
|
|
|
|
|
|
|
|
SNES9X_LoadSRAM();
|
|
|
|
|
|
|
|
ChangeTypeAndCreator(filename, 'CART', '~9X~');
|
|
|
|
|
|
|
|
ApplyNSRTHeaderControllers();
|
|
|
|
|
|
|
|
for (int a = 0; a < MAC_MAX_PLAYERS; a++)
|
|
|
|
for (int b = 0; b < 12; b++)
|
|
|
|
autofireRec[a].nextTime[b] = 0;
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cartOpen = false;
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-25 20:58:25 +00:00
|
|
|
bool8 SNES9X_OpenMultiCart (NSURL *cart1FileURL, NSURL *cart2FileURL)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
|
|
|
Boolean r;
|
|
|
|
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
SNES9X_SaveSRAM();
|
|
|
|
S9xResetSaveTimer(false);
|
|
|
|
S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
|
|
|
|
}
|
|
|
|
|
|
|
|
spcFileCount = pngFileCount = 0;
|
|
|
|
|
|
|
|
Settings.ForceHeader = (headerDetect == kHeaderForce );
|
|
|
|
Settings.ForceNoHeader = (headerDetect == kNoHeaderForce);
|
|
|
|
Settings.ForcePAL = (videoDetect == kPALForce );
|
|
|
|
Settings.ForceNTSC = (videoDetect == kNTSCForce );
|
|
|
|
|
2023-03-08 18:23:32 +00:00
|
|
|
GFX.InfoString = "";
|
2010-09-25 15:46:12 +00:00
|
|
|
GFX.InfoStringTimeout = 0;
|
|
|
|
|
|
|
|
S9xResetSaveTimer(true);
|
|
|
|
|
|
|
|
SNES9X_InitSound();
|
|
|
|
|
2023-03-25 20:58:25 +00:00
|
|
|
if (Memory.LoadMultiCart(cart1FileURL.path.UTF8String, cart2FileURL.path.UTF8String))
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
|
|
|
cartOpen = true;
|
|
|
|
|
|
|
|
SNES9X_LoadSRAM();
|
|
|
|
|
2023-03-25 20:58:25 +00:00
|
|
|
ChangeTypeAndCreator(cart1FileURL.path.UTF8String, 'CART', '~9X~');
|
|
|
|
|
|
|
|
if (cart2FileURL != nil)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
2023-03-25 20:58:25 +00:00
|
|
|
ChangeTypeAndCreator(cart2FileURL.path.UTF8String, 'CART', '~9X~');
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ApplyNSRTHeaderControllers();
|
|
|
|
|
|
|
|
for (int a = 0; a < MAC_MAX_PLAYERS; a++)
|
|
|
|
for (int b = 0; b < 12; b++)
|
|
|
|
autofireRec[a].nextTime[b] = 0;
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cartOpen = false;
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SNES9X_LoadSRAM (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
2023-03-08 18:23:32 +00:00
|
|
|
Memory.LoadSRAM(S9xGetFilename(".srm", SRAM_DIR).c_str());
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SNES9X_SaveSRAM (void)
|
|
|
|
{
|
2023-03-08 18:23:32 +00:00
|
|
|
std::string sramFilename;
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
sramFilename = S9xGetFilename(".srm", SRAM_DIR);
|
2023-03-08 18:23:32 +00:00
|
|
|
Memory.SaveSRAM(sramFilename.c_str());
|
|
|
|
ChangeTypeAndCreator(sramFilename.c_str(), 'SRAM', '~9X~');
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SNES9X_Reset (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
SNES9X_SaveSRAM();
|
|
|
|
S9xReset();
|
|
|
|
SNES9X_LoadSRAM();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SNES9X_SoftReset (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
SNES9X_SaveSRAM();
|
|
|
|
S9xSoftReset();
|
|
|
|
SNES9X_LoadSRAM();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_Freeze (void)
|
|
|
|
{
|
|
|
|
int which;
|
|
|
|
const char *filename;
|
|
|
|
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
MacStopSound();
|
|
|
|
|
|
|
|
which = PromptFreezeDefrost(true);
|
|
|
|
|
|
|
|
if (which >= 0)
|
|
|
|
{
|
|
|
|
filename = S9xGetFreezeFilename(which);
|
|
|
|
|
2019-05-24 01:18:53 +00:00
|
|
|
unlink(filename);
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
S9xFreezeGame(filename);
|
|
|
|
ChangeTypeAndCreator(filename, 'SAVE', '~9X~');
|
2019-05-24 01:18:53 +00:00
|
|
|
WriteThumbnailToExtendedAttribute(filename, 128, 120);
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
SNES9X_Go();
|
|
|
|
|
|
|
|
MacStartSound();
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MacStartSound();
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_Defrost (void)
|
|
|
|
{
|
|
|
|
int which;
|
|
|
|
const char *filename;
|
|
|
|
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
MacStopSound();
|
|
|
|
|
|
|
|
which = PromptFreezeDefrost(false);
|
|
|
|
|
|
|
|
if (which >= 0)
|
|
|
|
{
|
|
|
|
filename = S9xGetFreezeFilename(which);
|
|
|
|
S9xUnfreezeGame(filename);
|
|
|
|
|
|
|
|
SNES9X_Go();
|
|
|
|
|
|
|
|
MacStartSound();
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MacStartSound();
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_FreezeTo (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
NSURL *url = NavFreezeTo();
|
|
|
|
if (url != nil)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
2019-09-02 17:20:32 +00:00
|
|
|
const char *filename = url.path.UTF8String;
|
2019-05-24 01:18:53 +00:00
|
|
|
unlink(filename);
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
S9xFreezeGame(filename);
|
2019-05-24 01:18:53 +00:00
|
|
|
ChangeTypeAndCreator(filename, 'SAVE', '~9X~');;
|
|
|
|
WriteThumbnailToExtendedAttribute(filename, 128, 120);
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_DefrostFrom (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
NSURL *url = NavDefrostFrom();
|
|
|
|
if (url != nil)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
2019-09-02 17:20:32 +00:00
|
|
|
const char *filename = url.path.UTF8String;
|
2010-09-25 15:46:12 +00:00
|
|
|
S9xUnfreezeGame(filename);
|
|
|
|
|
|
|
|
SNES9X_Go();
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_RecordMovie (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
NSURL *url = NavRecordMovieTo();
|
|
|
|
if (url != nil)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
2019-09-02 17:20:32 +00:00
|
|
|
const char *filename = url.path.UTF8String;
|
2019-05-24 01:18:53 +00:00
|
|
|
unlink(filename);
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
int r;
|
|
|
|
uint8 opt = 0, mask = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i <= 4; i++)
|
|
|
|
if (macRecordFlag & (1 << i))
|
|
|
|
mask |= (1 << i);
|
|
|
|
|
|
|
|
if (macRecordFlag & (1 << 5))
|
|
|
|
opt |= MOVIE_OPT_FROM_RESET;
|
|
|
|
else
|
|
|
|
opt |= MOVIE_OPT_FROM_SNAPSHOT;
|
|
|
|
|
2020-07-21 21:20:26 +00:00
|
|
|
r = S9xMovieCreate(filename, mask, opt, macRecordWChar, (int)wcslen(macRecordWChar));
|
2010-09-25 15:46:12 +00:00
|
|
|
if (r == SUCCESS)
|
|
|
|
{
|
|
|
|
ChangeTypeAndCreator(filename, 'SMOV', '~9X~');
|
|
|
|
|
|
|
|
if ((macRecordFlag & (1 << 5)) == 0)
|
|
|
|
{
|
2019-05-24 01:18:53 +00:00
|
|
|
WriteThumbnailToExtendedAttribute(filename, 128, 120);
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SNES9X_Go();
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_PlayMovie (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
NSURL *url = NavPlayMovieFrom();
|
|
|
|
if (url != nil)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
2019-09-02 17:20:32 +00:00
|
|
|
const char *filename = url.path.UTF8String;
|
2010-09-25 15:46:12 +00:00
|
|
|
int r;
|
|
|
|
|
|
|
|
r = S9xMovieOpen(filename, macPlayFlag & 1);
|
|
|
|
if (r == SUCCESS)
|
|
|
|
{
|
|
|
|
SNES9X_Go();
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 SNES9X_QTMovieRecord (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
2019-07-14 03:42:21 +00:00
|
|
|
NSURL *url = NavQTMovieRecordTo();
|
|
|
|
if (url != nil)
|
2010-09-25 15:46:12 +00:00
|
|
|
{
|
|
|
|
macQTRecord = true;
|
|
|
|
SNES9X_Go();
|
|
|
|
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macQTRecord = false;
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SNES9X_Quit (void)
|
|
|
|
{
|
|
|
|
if (cartOpen)
|
|
|
|
{
|
|
|
|
SNES9X_SaveSRAM();
|
2011-01-24 14:27:57 +00:00
|
|
|
S9xResetSaveTimer(false);
|
2010-09-25 15:46:12 +00:00
|
|
|
S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SNES9X_InitSound (void)
|
|
|
|
{
|
2019-02-27 17:02:22 +00:00
|
|
|
S9xInitSound(0);
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|