gba: make core go into zombie mode if libmeteor aborts, instead of crashing. this makes it easy to pick apart failures using the in-program debugging tools (memory view, tracelog once i add it)
This commit is contained in:
parent
ee9e67d023
commit
5b3de57fca
|
@ -37,7 +37,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
||||||
{
|
{
|
||||||
Controller.UpdateControls(Frame++);
|
Controller.UpdateControls(Frame++);
|
||||||
IsLagFrame = true;
|
IsLagFrame = true;
|
||||||
LibMeteor.libmeteor_frameadvance();
|
if (!coredead)
|
||||||
|
LibMeteor.libmeteor_frameadvance();
|
||||||
if (IsLagFrame)
|
if (IsLagFrame)
|
||||||
LagCount++;
|
LagCount++;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +176,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
||||||
LibMeteor.MessageCallback messagecallback;
|
LibMeteor.MessageCallback messagecallback;
|
||||||
/// <summary>hold pointer to input callback so it won't get GCed</summary>
|
/// <summary>hold pointer to input callback so it won't get GCed</summary>
|
||||||
LibMeteor.InputCallback inputcallback;
|
LibMeteor.InputCallback inputcallback;
|
||||||
|
/// <summary>true if libmeteor aborted</summary>
|
||||||
|
bool coredead = false;
|
||||||
|
|
||||||
LibMeteor.Buttons GetInput()
|
LibMeteor.Buttons GetInput()
|
||||||
{
|
{
|
||||||
|
@ -194,14 +197,85 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region messagecallbacks
|
||||||
|
|
||||||
void PrintMessage(string msg, bool abort)
|
void PrintMessage(string msg, bool abort)
|
||||||
{
|
{
|
||||||
if (!abort)
|
Console.Write(msg.Replace("\n", "\r\n"));
|
||||||
Console.Write(msg.Replace("\n", "\r\n"));
|
if (abort)
|
||||||
else
|
StopCore(msg);
|
||||||
throw new Exception("libmeteor abort:\n " + msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StopCore(string msg)
|
||||||
|
{
|
||||||
|
coredead = true;
|
||||||
|
Console.WriteLine("Core stopped.");
|
||||||
|
for (int i = 0; i < soundbuffer.Length; i++)
|
||||||
|
soundbuffer[i] = 0;
|
||||||
|
|
||||||
|
var gz = new System.IO.Compression.GZipStream(
|
||||||
|
new MemoryStream(Convert.FromBase64String(dispfont), false),
|
||||||
|
System.IO.Compression.CompressionMode.Decompress);
|
||||||
|
byte[] font = new byte[2048];
|
||||||
|
gz.Read(font, 0, 2048);
|
||||||
|
gz.Dispose();
|
||||||
|
|
||||||
|
// cores aren't supposed to have bad dependencies like System.Drawing, right?
|
||||||
|
|
||||||
|
int scx = 0;
|
||||||
|
int scy = 0;
|
||||||
|
|
||||||
|
foreach (char c in msg)
|
||||||
|
{
|
||||||
|
if (scx == 240 || c == '\n')
|
||||||
|
{
|
||||||
|
scy += 8;
|
||||||
|
scx = 0;
|
||||||
|
}
|
||||||
|
if (scy == 160)
|
||||||
|
break;
|
||||||
|
if (c == '\r' || c == '\n')
|
||||||
|
continue;
|
||||||
|
if (c < 256 && c != ' ')
|
||||||
|
{
|
||||||
|
int fpos = c * 8;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if ((font[fpos] >> i & 1) != 0)
|
||||||
|
videobuffer[(scy + j) * 240 + scx + i] = unchecked((int)0xffff0000);
|
||||||
|
else
|
||||||
|
videobuffer[(scy + j) * 240 + scx + i] = unchecked((int)0xff000000);
|
||||||
|
}
|
||||||
|
fpos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scx += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const string dispfont =
|
||||||
|
"H4sICAInrFACAGZvby5yYXcARVU9q9RAFL2gjK8IT+0GDGoh1oGFGHDYQvwL2hoQroXhsdUqGGbxZ/gD" +
|
||||||
|
"bKys7BRhIZVYLgurIghvG3ksCPKKJfGcm1nfSTJn750792smWUmIr9++/vjmdYzDZlhuh1guFotpfiRH" +
|
||||||
|
"+dQ4n+aLxfOj/MgUR7mID8GLDMN2CftBgj54oEGG5ZuPH98sh93P3afJZHIzqGrw0e+/7LPs+OqVvuu7" +
|
||||||
|
"7vTZJb8J223Y+MtZHvLsstwuqlAVt+E1eh+DV0JU+s3mx3q9luCChjoIsVgI7Wg2kAHBQ1mkqPu6EBhk" +
|
||||||
|
"feYFcM5F0B0d9A74WtX2QvRtdU0SrBp6kaZpKIJ7XI341oV66sVp4TOtJS/L/IN+k8pnQkCbZb4QPEVB" +
|
||||||
|
"nYYhKB16JHZwbsZRDuBEDWsnEnQeTzSIz60CyHWV6cg19LOXjfb1TqKb1pSrzE0VHBUOvIed8ia3dZGb" +
|
||||||
|
"c96JM0ZhfgzPBPCbkWEPEs/4j+fO1kd2HM55Q0bf4PdmCW15E/HdFI1M7Dg/Z1xN64InguxqpGn6kkvF" +
|
||||||
|
"GaJ0Z32/6jrRkxjntFciMB79mTwPM5NLm0ffWac3iCb7kbx0XbfqzzqhEGBPLe2i9TVKmxGtiGPFIm1N" +
|
||||||
|
"tNj+ppMLDDl7Ywh1q62gPEUKlJX1Yw3k1uTo2P9sCseQW3Y80B4QLznrNwaOnbMGUDK9SNOvVgxt9vQH" +
|
||||||
|
"gj51IPn7SdlRFDt4MoarIGvKwyoFd6tV34CtAWTLRySiAZF5Oq5DcHvyAvuO8/FtLgZrRNcf9tlp8l/4" +
|
||||||
|
"sc64HPuhMnLmR/Z3jA/9cbAzexVj2CU59SPYD+rJyU6VfsiIh5NtL+j+/b7cyzmOu+op1wXrjzHXG2Ow" +
|
||||||
|
"Qikba6pbgwL0P7J4y89XDRsY7ZxEXLcmkydP/zz9NVv74P2N4yLVVaT8wIxDNv9NaRtG1pM5kinLVqKY" +
|
||||||
|
"ERndzXhOgOicGNe1yPLp5NUXnezAm99//3ymoX0xodQvsMKoE5GH18fr3aPx+v5ivPwFbt1KIx9VffYM" +
|
||||||
|
"g30GyUkPbV1zJgGzJpt+sWAxGEWSHwH4izg/hwAeBjEMw0GPweTDfNLyUWzSqdroXN+L9L1z1Gy3tsKe" +
|
||||||
|
"7Zbzpj/oOE+9P8iq5j/Nj/HUQK+S4omkuMJIaqD3g5+xQ2KwvIcEKshXE3YJNkfgjbg7/8YNLbV0Lqo6" +
|
||||||
|
"AFEaQqJmPlM7n+l9VeDHJTm57wGJPtjRwhg53+LD1DRnMvNFO9q3q9WqFfncnq6+tm7mszbzM4QziERe" +
|
||||||
|
"h7+LyO+zz8AYfQGerdf+P27cOBYaeUubt1RNU138q4wg74qiuFeGKjQA5BwOgxABACX8A6+GHm0ACAAA";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
if (attachedcore != null)
|
if (attachedcore != null)
|
||||||
|
@ -273,7 +347,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
||||||
{
|
{
|
||||||
uint nbytes = LibMeteor.libmeteor_emptysound();
|
uint nbytes = LibMeteor.libmeteor_emptysound();
|
||||||
samples = soundbuffer;
|
samples = soundbuffer;
|
||||||
nsamp = (int)(nbytes / 4);
|
if (!coredead)
|
||||||
|
nsamp = (int)(nbytes / 4);
|
||||||
|
else
|
||||||
|
nsamp = 738;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DiscardSamples()
|
public void DiscardSamples()
|
||||||
|
|
Binary file not shown.
|
@ -26,6 +26,7 @@ void abort_bizhawk(const char *msg)
|
||||||
{
|
{
|
||||||
if (messagecallback)
|
if (messagecallback)
|
||||||
messagecallback(msg, 1);
|
messagecallback(msg, 1);
|
||||||
|
AMeteor::Stop(); // makes it easy to pick apart what happened
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t (*keycallback)() = NULL;
|
uint16_t (*keycallback)() = NULL;
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace AMeteor
|
||||||
|
|
||||||
if (dispstat & 0x2) // if we were H-Blanking
|
if (dispstat & 0x2) // if we were H-Blanking
|
||||||
{
|
{
|
||||||
debug("hblank end");
|
//debug("hblank end");
|
||||||
// we are not anymore, we're on next line
|
// we are not anymore, we're on next line
|
||||||
dispstat ^= 0x2;
|
dispstat ^= 0x2;
|
||||||
// call me when we are H-Blanking again
|
// call me when we are H-Blanking again
|
||||||
|
@ -96,7 +96,7 @@ namespace AMeteor
|
||||||
}
|
}
|
||||||
else // if we were not H-Blanking
|
else // if we were not H-Blanking
|
||||||
{
|
{
|
||||||
debug("hblank vcount : " << std::dec << vcount);
|
//debug("hblank vcount : " << std::dec << vcount);
|
||||||
// now, we are
|
// now, we are
|
||||||
dispstat |= 0x2;
|
dispstat |= 0x2;
|
||||||
// call me when we are not H-Blanking anymore
|
// call me when we are not H-Blanking anymore
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace AMeteor
|
||||||
|
|
||||||
void Timer::TimeEvent ()
|
void Timer::TimeEvent ()
|
||||||
{
|
{
|
||||||
debug("Timer" << (int)m_num << " overflow");
|
//debug("Timer" << (int)m_num << " overflow");
|
||||||
SOUND.TimerOverflow(m_num);
|
SOUND.TimerOverflow(m_num);
|
||||||
|
|
||||||
m_count = 65536 - m_reload;
|
m_count = 65536 - m_reload;
|
||||||
|
|
Loading…
Reference in New Issue