Implement F12 game reset (MRI only)

Can be disabled with "enableReset=false".

While at it, also replace the flakey volatile bool flags
with proper atomics.
This commit is contained in:
Jonas Kulla 2014-08-24 07:36:19 +02:00
parent 3a2e560139
commit d223d83cbf
23 changed files with 343 additions and 60 deletions

View file

@ -97,6 +97,15 @@ DEF_FADE( me )
DEF_PLAY_STOP( se )
RB_METHOD(audioReset)
{
RB_UNUSED_PARAM;
shState->audio().reset();
return Qnil;
}
#define BIND_PLAY_STOP(entity) \
_rb_define_module_function(module, #entity "_play", audio_##entity##Play); \
@ -129,4 +138,6 @@ audioBindingInit()
}
BIND_PLAY_STOP( se )
_rb_define_module_function(module, "__reset__", audioReset);
}

View file

@ -27,6 +27,7 @@
#include "util.h"
#include "debugwriter.h"
#include "graphics.h"
#include "audio.h"
#include "boost-hash.h"
#include <ruby.h>
@ -44,11 +45,13 @@ extern const char module_rpg3[];
static void mriBindingExecute();
static void mriBindingTerminate();
static void mriBindingReset();
ScriptBinding scriptBindingImpl =
{
mriBindingExecute,
mriBindingTerminate
mriBindingTerminate,
mriBindingReset
};
ScriptBinding *scriptBinding = &scriptBindingImpl;
@ -213,12 +216,51 @@ RB_METHOD(mriDataDirectory)
return pathStr;
}
static VALUE rgssMainCb(VALUE block)
{
rb_funcall2(block, rb_intern("call"), 0, 0);
return Qnil;
}
static VALUE rgssMainRescue(VALUE arg, VALUE exc)
{
VALUE *excRet = (VALUE*) arg;
*excRet = exc;
return Qnil;
}
static void processReset()
{
shState->graphics().reset();
shState->audio().reset();
shState->rtData().rqReset.clear();
shState->graphics().repaintWait(shState->rtData().rqResetFinish,
false);
}
RB_METHOD(mriRgssMain)
{
RB_UNUSED_PARAM;
// TODO: Implement F12 reset
rb_yield(Qnil);
while (true)
{
VALUE exc = Qnil;
rb_rescue2((VALUE(*)(ANYARGS)) rgssMainCb, rb_block_proc(),
(VALUE(*)(ANYARGS)) rgssMainRescue, (VALUE) &exc,
rb_eException, (VALUE) 0);
if (NIL_P(exc))
break;
if (rb_obj_class(exc) == getRbData()->exc[Reset])
processReset();
else
rb_exc_raise(exc);
}
return Qnil;
}
@ -395,30 +437,39 @@ static void runRMXPScripts(BacktraceData &btData)
for (size_t i = 0; i < conf.preloadScripts.size(); ++i)
runCustomScript(conf.preloadScripts[i]);
for (long i = 0; i < scriptCount; ++i)
while (true)
{
VALUE script = rb_ary_entry(scriptArray, i);
VALUE scriptDecoded = rb_ary_entry(script, 3);
VALUE string = newStringUTF8(RSTRING_PTR(scriptDecoded),
RSTRING_LEN(scriptDecoded));
for (long i = 0; i < scriptCount; ++i)
{
VALUE script = rb_ary_entry(scriptArray, i);
VALUE scriptDecoded = rb_ary_entry(script, 3);
VALUE string = newStringUTF8(RSTRING_PTR(scriptDecoded),
RSTRING_LEN(scriptDecoded));
VALUE fname;
const char *scriptName = RSTRING_PTR(rb_ary_entry(script, 1));
char buf[512];
int len;
VALUE fname;
const char *scriptName = RSTRING_PTR(rb_ary_entry(script, 1));
char buf[512];
int len;
if (conf.useScriptNames)
len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName);
else
len = snprintf(buf, sizeof(buf), SCRIPT_SECTION_FMT, i);
if (conf.useScriptNames)
len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName);
else
len = snprintf(buf, sizeof(buf), SCRIPT_SECTION_FMT, i);
fname = newStringUTF8(buf, len);
btData.scriptNames.insert(buf, scriptName);
fname = newStringUTF8(buf, len);
btData.scriptNames.insert(buf, scriptName);
int state;
evalString(string, fname, &state);
if (state)
int state;
evalString(string, fname, &state);
if (state)
break;
}
VALUE exc = rb_gv_get("$!");
if (rb_obj_class(exc) != getRbData()->exc[Reset])
break;
processReset();
}
}
@ -520,10 +571,15 @@ static void mriBindingExecute()
ruby_cleanup(0);
shState->rtData().rqTermAck = true;
shState->rtData().rqTermAck.set();
}
static void mriBindingTerminate()
{
rb_raise(rb_eSystemExit, " ");
}
static void mriBindingReset()
{
rb_raise(getRbData()->exc[Reset], " ");
}

View file

@ -51,6 +51,8 @@ RbData::RbData()
for (size_t i = 0; i < ARRAY_SIZE(customExc); ++i)
exc[customExc[i].id] = rb_define_class(customExc[i].name, rb_eException);
exc[Reset] = rb_define_class(rgssVer >= 3 ? "RGSSReset" : "Reset", rb_eException);
exc[ErrnoENOENT] = rb_const_get(rb_const_get(rb_cObject, rb_intern("Errno")), rb_intern("ENOENT"));
exc[IOError] = rb_eIOError;
exc[TypeError] = rb_eTypeError;

View file

@ -29,6 +29,7 @@
enum RbException
{
RGSS = 0,
Reset,
PHYSFS,
SDL,
MKXP,

View file

@ -174,6 +174,15 @@ RB_METHOD(graphicsResizeScreen)
return Qnil;
}
RB_METHOD(graphicsReset)
{
RB_UNUSED_PARAM;
shState->graphics().reset();
return Qnil;
}
DEF_GRA_PROP_I(FrameRate)
DEF_GRA_PROP_I(FrameCount)
DEF_GRA_PROP_I(Brightness)
@ -196,6 +205,8 @@ void graphicsBindingInit()
_rb_define_module_function(module, "transition", graphicsTransition);
_rb_define_module_function(module, "frame_reset", graphicsFrameReset);
_rb_define_module_function(module, "__reset__", graphicsReset);
INIT_GRA_PROP_BIND( FrameRate, "frame_rate" );
INIT_GRA_PROP_BIND( FrameCount, "frame_count" );