snes-fix bug where loading more than one snes rom would wreck the emulator

This commit is contained in:
zeromus 2012-09-05 23:16:08 +00:00
parent b0e3a332d8
commit ade89fe798
3 changed files with 28 additions and 18 deletions

View File

@ -144,33 +144,43 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public unsafe class LibsnesCore : IEmulator, IVideoProvider, ISoundProvider public unsafe class LibsnesCore : IEmulator, IVideoProvider, ISoundProvider
{ {
bool disposed = false;
public void Dispose() public void Dispose()
{ {
if (disposed) return;
disposed = true;
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_video_refresh(null);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_poll(null);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(null);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(null);
LibsnesDll.snes_term(); LibsnesDll.snes_term();
_gc_snes_video_refresh.Free();
_gc_snes_input_poll.Free();
_gc_snes_input_state.Free();
_gc_snes_audio_sample.Free();
} }
//we can only have one active snes core at a time, due to libsnes being so static.
//so we'll track the current one here and detach the previous one whenever a new one is booted up.
static LibsnesCore CurrLibsnesCore;
public LibsnesCore(byte[] romData) public LibsnesCore(byte[] romData)
{ {
//attach this core as the current
if(CurrLibsnesCore != null)
CurrLibsnesCore.Dispose();
CurrLibsnesCore = this;
LibsnesDll.snes_init(); LibsnesDll.snes_init();
var vidcb = new LibsnesDll.snes_video_refresh_t(snes_video_refresh); vidcb = new LibsnesDll.snes_video_refresh_t(snes_video_refresh);
_gc_snes_video_refresh = GCHandle.Alloc(vidcb);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_video_refresh(vidcb); BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_video_refresh(vidcb);
var pollcb = new LibsnesDll.snes_input_poll_t(snes_input_poll); pollcb = new LibsnesDll.snes_input_poll_t(snes_input_poll);
_gc_snes_input_poll = GCHandle.Alloc(pollcb);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_poll(pollcb); BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_poll(pollcb);
var inputcb = new LibsnesDll.snes_input_state_t(snes_input_state); inputcb = new LibsnesDll.snes_input_state_t(snes_input_state);
_gc_snes_input_state = GCHandle.Alloc(inputcb);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(inputcb); BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(inputcb);
var soundcb = new LibsnesDll.snes_audio_sample_t(snes_audio_sample); soundcb = new LibsnesDll.snes_audio_sample_t(snes_audio_sample);
_gc_snes_audio_sample = GCHandle.Alloc(soundcb);
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(soundcb); BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(soundcb);
// start up audio resampler // start up audio resampler
@ -188,7 +198,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
SetupMemoryDomains(romData); SetupMemoryDomains(romData);
} }
GCHandle _gc_snes_input_state; //must keep references to these so that they wont get garbage collected
LibsnesDll.snes_video_refresh_t vidcb;
LibsnesDll.snes_input_poll_t pollcb;
LibsnesDll.snes_input_state_t inputcb;
LibsnesDll.snes_audio_sample_t soundcb;
ushort snes_input_state(int port, int device, int index, int id) ushort snes_input_state(int port, int device, int index, int id)
{ {
//Console.WriteLine("{0} {1} {2} {3}", port, device, index, id); //Console.WriteLine("{0} {1} {2} {3}", port, device, index, id);
@ -219,12 +234,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
} }
GCHandle _gc_snes_input_poll;
void snes_input_poll() void snes_input_poll()
{ {
} }
GCHandle _gc_snes_video_refresh;
void snes_video_refresh(int* data, int width, int height) void snes_video_refresh(int* data, int width, int height)
{ {
vidWidth = width; vidWidth = width;

Binary file not shown.

View File

@ -127,9 +127,6 @@ void snes_set_cartridge_basename(const char *basename) {
} }
void snes_init(void) { void snes_init(void) {
//zero 04-sep-2012 - reset harder
new(&interface) Interface();
SNES::interface = &interface; SNES::interface = &interface;
SNES::system.init(); SNES::system.init();
SNES::input.connect(SNES::Controller::Port1, SNES::Input::Device::Joypad); SNES::input.connect(SNES::Controller::Port1, SNES::Input::Device::Joypad);