gba: handle libmeteor aborts. Final Fantasy 5 (J) now crashes instead of drifting off into the sunset

This commit is contained in:
goyuken 2012-11-20 15:52:36 +00:00
parent 00469301e5
commit 83f74f1290
5 changed files with 42 additions and 37 deletions

View File

@ -68,8 +68,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
/// core callback to print meaningful (or meaningless) log messages
/// </summary>
/// <param name="msg">message to be printed</param>
/// <param name="abort">true if emulation should be aborted</param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void MessageCallback(string msg);
public delegate void MessageCallback(string msg, bool abort);
/// <summary>
/// set callback for log messages. this can (and should) be called first

View File

@ -40,33 +40,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
LagCount++;
}
public int Frame
public int Frame { get; private set; }
public int LagCount { get; set; }
public bool IsLagFrame { get; private set; }
public string SystemId { get { return "GBA"; } }
public bool DeterministicEmulation { get { return true; } }
public void ResetFrameCounter()
{
get;
private set;
Frame = 0;
LagCount = 0;
}
public int LagCount
{
get;
set;
}
public bool IsLagFrame
{
get;
private set;
}
public string SystemId
{
get { return "GBA"; }
}
public bool DeterministicEmulation
{
get { return true; }
}
#region saveram
public byte[] ReadSaveRam()
{
@ -83,11 +69,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
public bool SaveRamModified { get { return false; } set { } }
public void ResetFrameCounter()
{
Frame = 0;
LagCount = 0;
}
#endregion
#region savestates
@ -138,12 +120,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
get { return null; }
}
/// <summary>like libsnes, the library is single-instance</summary>
static GBA attachedcore;
/// <summary>hold pointer to message callback so it won't get GCed</summary>
LibMeteor.MessageCallback messagecallback;
/// <summary>hold pointer to input callback so it won't get GCed</summary>
LibMeteor.InputCallback inputcallback;
LibMeteor.Buttons GetInput()
{
// libmeteor bitflips everything itself, so 0 == off, 1 == on
IsLagFrame = false;
LibMeteor.Buttons ret = 0;
if (Controller["Up"]) ret |= LibMeteor.Buttons.BTN_UP;
@ -159,13 +145,20 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
return ret;
}
void PrintMessage(string msg, bool abort)
{
if (!abort)
Console.Write(msg.Replace("\n", "\r\n"));
else
throw new Exception("libmeteor abort:\n " + msg);
}
void Init()
{
if (attachedcore != null)
attachedcore.Dispose();
messagecallback = (str) => Console.Write(str.Replace("\n","\r\n"));
messagecallback = PrintMessage;
inputcallback = GetInput;
LibMeteor.libmeteor_setmessagecallback(messagecallback);
LibMeteor.libmeteor_setkeycallback(inputcallback);
@ -192,6 +185,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
disposed = true;
videohandle.Free();
soundhandle.Free();
// guarantee crash if it gets accessed
LibMeteor.libmeteor_setbuffers(IntPtr.Zero, 240 * 160 * 4, IntPtr.Zero, 4);
messagecallback = null;
inputcallback = null;
LibMeteor.libmeteor_setmessagecallback(messagecallback);
LibMeteor.libmeteor_setkeycallback(inputcallback);
}
}
@ -225,7 +224,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
uint nbytes = LibMeteor.libmeteor_emptysound();
samples = soundbuffer;
nsamp = (int)(nbytes / 4);
}
public void DiscardSamples()

View File

@ -4,9 +4,9 @@
#define EXPORT extern "C" __declspec(dllexport)
void (*messagecallback)(const char *msg) = NULL;
void (*messagecallback)(const char *msg, int abort) = NULL;
EXPORT void libmeteor_setmessagecallback(void (*callback)(const char *msg))
EXPORT void libmeteor_setmessagecallback(void (*callback)(const char *msg, int abort))
{
messagecallback = callback;
print_bizhawk("libmeteor message stream operational.");
@ -15,12 +15,17 @@ EXPORT void libmeteor_setmessagecallback(void (*callback)(const char *msg))
void print_bizhawk(const char *msg)
{
if (messagecallback)
messagecallback(msg);
messagecallback(msg, 0);
}
void print_bizhawk(std::string &msg)
{
if (messagecallback)
messagecallback(msg.c_str());
messagecallback(msg.c_str(), 0);
}
void abort_bizhawk(const char *msg)
{
if (messagecallback)
messagecallback(msg, 1);
}
uint16_t (*keycallback)() = NULL;

View File

@ -28,6 +28,7 @@
// from cinterface.cpp
void print_bizhawk(const char *msg);
void print_bizhawk(std::string &msg);
void abort_bizhawk(const char *msg);
void keyupdate_bizhawk();
#if 0
@ -52,7 +53,7 @@ void keyupdate_bizhawk();
<< IOS_ADD << ::AMeteor::_cpu.Reg(15) << "\n[r15] = " << IOS_ADD \
<< ::AMeteor::_memory.Read32(::AMeteor::_cpu.Reg(15)) \
<< "\nFlag T : " << ::AMeteor::_cpu.ICpsr().thumb << std::endl; \
print_bizhawk(_zisrny.str().c_str()); \
abort_bizhawk(_zisrny.str().c_str()); \
}
#else