Prevent relevant functions from stepping over Graphics.update when threading

This commit is contained in:
Struma 2021-06-04 14:29:45 -04:00 committed by Roza
parent f5d7f79cde
commit 63b40053ac
17 changed files with 762 additions and 609 deletions

View file

@ -314,6 +314,19 @@ raiseRbExc(exc); \
} \ } \
} }
#define GFX_GUARD_EXC(exp) \
{\
GFX_LOCK; \
try {\
exp \
} catch (const Exception &exc) {\
GFX_UNLOCK; \
raiseRbExc(exc); \
}\
GFX_UNLOCK;\
}
template <class C> template <class C>
static inline VALUE objectLoad(int argc, VALUE *argv, VALUE self) { static inline VALUE objectLoad(int argc, VALUE *argv, VALUE self) {
const char *data; const char *data;
@ -437,6 +450,10 @@ return self; \
* FIXME: Getter assumes prop is disposable, * FIXME: Getter assumes prop is disposable,
* because self.disposed? is not checked in this case. * because self.disposed? is not checked in this case.
* Should make this more clear */ * Should make this more clear */
// --------------
// Do not wait for Graphics.update
// --------------
#if RAPI_FULL > 187 #if RAPI_FULL > 187
#define DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \ #define DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) { \ RB_METHOD(Klass##Get##PropName) { \
@ -546,4 +563,80 @@ _rb_define_method(klass, prop_name_s, Klass##Get##PropName); \
_rb_define_method(klass, prop_name_s "=", Klass##Set##PropName); \ _rb_define_method(klass, prop_name_s "=", Klass##Set##PropName); \
} }
// --------------
// Wait for Graphics.update
// --------------
#if RAPI_FULL > 187
#define DEF_GFX_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) { \
RB_UNUSED_PARAM; \
return rb_iv_get(self, prop_iv); \
} \
RB_METHOD(Klass##Set##PropName) { \
RB_UNUSED_PARAM; \
rb_check_argc(argc, 1); \
Klass *k = getPrivateData<Klass>(self); \
VALUE propObj = *argv; \
PropKlass *prop; \
if (NIL_P(propObj)) \
prop = 0; \
else \
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
GFX_GUARD_EXC(k->set##PropName(prop);) \
rb_iv_set(self, prop_iv, propObj); \
return propObj; \
}
#else
#define DEF_GFX_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv) \
DEF_PROP_OBJ_REF(Klass, PropKlass, PropName, prop_iv)
#endif
/* Object property which is copied by value, not reference */
#if RAPI_FULL > 187
#define DEF_GFX_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
RB_METHOD(Klass##Get##PropName) { \
RB_UNUSED_PARAM; \
checkDisposed<Klass>(self); \
return rb_iv_get(self, prop_iv); \
} \
RB_METHOD(Klass##Set##PropName) { \
rb_check_argc(argc, 1); \
Klass *k = getPrivateData<Klass>(self); \
VALUE propObj = *argv; \
PropKlass *prop; \
prop = getPrivateDataCheck<PropKlass>(propObj, PropKlass##Type); \
GFX_GUARD_EXC(k->set##PropName(*prop);) \
return propObj; \
}
#else
#define DEF_GFX_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv) \
DEF_PROP_OBJ_VAL(Klass, PropKlass, PropName, prop_iv)
#endif
#define DEF_GFX_PROP(Klass, type, PropName, arg_fun, value_fun) \
RB_METHOD(Klass##Get##PropName) { \
RB_UNUSED_PARAM; \
Klass *k = getPrivateData<Klass>(self); \
type value = 0; \
GUARD_EXC(value = k->get##PropName();) \
return value_fun(value); \
} \
RB_METHOD(Klass##Set##PropName) { \
rb_check_argc(argc, 1); \
Klass *k = getPrivateData<Klass>(self); \
type value; \
rb_##arg_fun##_arg(*argv, &value); \
GFX_GUARD_EXC(k->set##PropName(value);) \
return *argv; \
}
#define DEF_GFX_PROP_I(Klass, PropName) \
DEF_GFX_PROP(Klass, int, PropName, int, rb_fix_new)
#define DEF_GFX_PROP_F(Klass, PropName) \
DEF_GFX_PROP(Klass, double, PropName, float, rb_float_new)
#define DEF_GFX_PROP_B(Klass, PropName) \
DEF_GFX_PROP(Klass, bool, PropName, bool, rb_bool_new)
#endif // BINDING_UTIL_H #endif // BINDING_UTIL_H

View file

@ -26,6 +26,7 @@
#include "exception.h" #include "exception.h"
#include "font.h" #include "font.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "graphics.h"
#if RAPI_FULL > 187 #if RAPI_FULL > 187
DEF_TYPE(Bitmap); DEF_TYPE(Bitmap);
@ -57,17 +58,19 @@ RB_METHOD(bitmapInitialize) {
char *filename; char *filename;
rb_get_args(argc, argv, "z", &filename RB_ARG_END); rb_get_args(argc, argv, "z", &filename RB_ARG_END);
GUARD_EXC(b = new Bitmap(filename);) GFX_GUARD_EXC(b = new Bitmap(filename);)
} else { } else {
int width, height; int width, height;
rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END); rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END);
GUARD_EXC(b = new Bitmap(width, height);) GFX_GUARD_EXC(b = new Bitmap(width, height);)
} }
setPrivateData(self, b); setPrivateData(self, b);
bitmapInitProps(b, self); bitmapInitProps(b, self);
GFX_UNLOCK;
return self; return self;
} }
@ -123,7 +126,7 @@ RB_METHOD(bitmapBlt) {
src = getPrivateDataCheck<Bitmap>(srcObj, BitmapType); src = getPrivateDataCheck<Bitmap>(srcObj, BitmapType);
srcRect = getPrivateDataCheck<Rect>(srcRectObj, RectType); srcRect = getPrivateDataCheck<Rect>(srcRectObj, RectType);
GUARD_EXC(b->blt(x, y, *src, srcRect->toIntRect(), opacity);); GFX_GUARD_EXC(b->blt(x, y, *src, srcRect->toIntRect(), opacity););
return self; return self;
} }
@ -146,7 +149,7 @@ RB_METHOD(bitmapStretchBlt) {
destRect = getPrivateDataCheck<Rect>(destRectObj, RectType); destRect = getPrivateDataCheck<Rect>(destRectObj, RectType);
srcRect = getPrivateDataCheck<Rect>(srcRectObj, RectType); srcRect = getPrivateDataCheck<Rect>(srcRectObj, RectType);
GUARD_EXC(b->stretchBlt(destRect->toIntRect(), *src, srcRect->toIntRect(), GFX_GUARD_EXC(b->stretchBlt(destRect->toIntRect(), *src, srcRect->toIntRect(),
opacity);); opacity););
return self; return self;
@ -167,7 +170,7 @@ RB_METHOD(bitmapFillRect) {
rect = getPrivateDataCheck<Rect>(rectObj, RectType); rect = getPrivateDataCheck<Rect>(rectObj, RectType);
color = getPrivateDataCheck<Color>(colorObj, ColorType); color = getPrivateDataCheck<Color>(colorObj, ColorType);
GUARD_EXC(b->fillRect(rect->toIntRect(), color->norm);); GFX_GUARD_EXC(b->fillRect(rect->toIntRect(), color->norm););
} else { } else {
int x, y, width, height; int x, y, width, height;
@ -176,7 +179,7 @@ RB_METHOD(bitmapFillRect) {
color = getPrivateDataCheck<Color>(colorObj, ColorType); color = getPrivateDataCheck<Color>(colorObj, ColorType);
GUARD_EXC(b->fillRect(x, y, width, height, color->norm);); GFX_GUARD_EXC(b->fillRect(x, y, width, height, color->norm););
} }
return self; return self;
@ -186,8 +189,8 @@ RB_METHOD(bitmapClear) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->clear();) GFX_GUARD_EXC(b->clear();)
return self; return self;
} }
@ -219,7 +222,7 @@ RB_METHOD(bitmapSetPixel) {
color = getPrivateDataCheck<Color>(colorObj, ColorType); color = getPrivateDataCheck<Color>(colorObj, ColorType);
GUARD_EXC(b->setPixel(x, y, *color);); GFX_GUARD_EXC(b->setPixel(x, y, *color););
return self; return self;
} }
@ -231,7 +234,7 @@ RB_METHOD(bitmapHueChange) {
rb_get_args(argc, argv, "i", &hue RB_ARG_END); rb_get_args(argc, argv, "i", &hue RB_ARG_END);
GUARD_EXC(b->hueChange(hue);); GFX_GUARD_EXC(b->hueChange(hue););
return self; return self;
} }
@ -257,7 +260,7 @@ RB_METHOD(bitmapDrawText) {
rect = getPrivateDataCheck<Rect>(rectObj, RectType); rect = getPrivateDataCheck<Rect>(rectObj, RectType);
GUARD_EXC(b->drawText(rect->toIntRect(), str, align);); GFX_GUARD_EXC(b->drawText(rect->toIntRect(), str, align););
} else { } else {
int x, y, width, height; int x, y, width, height;
@ -272,7 +275,7 @@ RB_METHOD(bitmapDrawText) {
&align RB_ARG_END); &align RB_ARG_END);
} }
GUARD_EXC(b->drawText(x, y, width, height, str, align);); GFX_GUARD_EXC(b->drawText(x, y, width, height, str, align););
} }
return self; return self;
@ -300,7 +303,7 @@ RB_METHOD(bitmapTextSize) {
return wrapObject(rect, RectType); return wrapObject(rect, RectType);
} }
DEF_PROP_OBJ_VAL(Bitmap, Font, Font, "font") DEF_GFX_PROP_OBJ_VAL(Bitmap, Font, Font, "font")
RB_METHOD(bitmapGradientFillRect) { RB_METHOD(bitmapGradientFillRect) {
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
@ -320,7 +323,7 @@ RB_METHOD(bitmapGradientFillRect) {
color1 = getPrivateDataCheck<Color>(color1Obj, ColorType); color1 = getPrivateDataCheck<Color>(color1Obj, ColorType);
color2 = getPrivateDataCheck<Color>(color2Obj, ColorType); color2 = getPrivateDataCheck<Color>(color2Obj, ColorType);
GUARD_EXC(b->gradientFillRect(rect->toIntRect(), color1->norm, color2->norm, GFX_GUARD_EXC(b->gradientFillRect(rect->toIntRect(), color1->norm, color2->norm,
vertical);); vertical););
} else { } else {
int x, y, width, height; int x, y, width, height;
@ -331,7 +334,7 @@ RB_METHOD(bitmapGradientFillRect) {
color1 = getPrivateDataCheck<Color>(color1Obj, ColorType); color1 = getPrivateDataCheck<Color>(color1Obj, ColorType);
color2 = getPrivateDataCheck<Color>(color2Obj, ColorType); color2 = getPrivateDataCheck<Color>(color2Obj, ColorType);
GUARD_EXC(b->gradientFillRect(x, y, width, height, color1->norm, GFX_GUARD_EXC(b->gradientFillRect(x, y, width, height, color1->norm,
color2->norm, vertical);); color2->norm, vertical););
} }
@ -349,13 +352,13 @@ RB_METHOD(bitmapClearRect) {
rect = getPrivateDataCheck<Rect>(rectObj, RectType); rect = getPrivateDataCheck<Rect>(rectObj, RectType);
GUARD_EXC(b->clearRect(rect->toIntRect());); GFX_GUARD_EXC(b->clearRect(rect->toIntRect()););
} else { } else {
int x, y, width, height; int x, y, width, height;
rb_get_args(argc, argv, "iiii", &x, &y, &width, &height RB_ARG_END); rb_get_args(argc, argv, "iiii", &x, &y, &width, &height RB_ARG_END);
GUARD_EXC(b->clearRect(x, y, width, height);); GFX_GUARD_EXC(b->clearRect(x, y, width, height););
} }
return self; return self;
@ -366,7 +369,9 @@ RB_METHOD(bitmapBlur) {
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GFX_LOCK;
b->blur(); b->blur();
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -377,7 +382,9 @@ RB_METHOD(bitmapRadialBlur) {
int angle, divisions; int angle, divisions;
rb_get_args(argc, argv, "ii", &angle, &divisions RB_ARG_END); rb_get_args(argc, argv, "ii", &angle, &divisions RB_ARG_END);
GFX_LOCK;
b->radialBlur(angle, divisions); b->radialBlur(angle, divisions);
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -389,7 +396,7 @@ RB_METHOD(bitmapGetRawData) {
int size = b->width() * b->height() * 4; int size = b->width() * b->height() * 4;
VALUE ret = rb_str_new(0, size); VALUE ret = rb_str_new(0, size);
GUARD_EXC(b->getRaw(RSTRING_PTR(ret), size);); GFX_GUARD_EXC(b->getRaw(RSTRING_PTR(ret), size););
return ret; return ret;
} }
@ -403,7 +410,7 @@ RB_METHOD(bitmapSetRawData) {
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->replaceRaw(RSTRING_PTR(str), RSTRING_LEN(str));); GFX_GUARD_EXC(b->replaceRaw(RSTRING_PTR(str), RSTRING_LEN(str)););
return self; return self;
} }
@ -417,11 +424,7 @@ RB_METHOD(bitmapSaveToFile) {
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
try { GFX_GUARD_EXC(b->saveToFile(RSTRING_PTR(str)););
b->saveToFile(RSTRING_PTR(str));
} catch (const Exception &e) {
raiseRbExc(e);
}
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -465,7 +468,7 @@ RB_METHOD(bitmapSetPlaying){
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC((play) ? b->play() : b->stop();); GFX_GUARD_EXC((play) ? b->play() : b->stop(););
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -476,7 +479,7 @@ RB_METHOD(bitmapPlay){
rb_check_argc(argc, 0); rb_check_argc(argc, 0);
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->play();); GFX_GUARD_EXC(b->play(););
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -487,7 +490,7 @@ RB_METHOD(bitmapStop){
rb_check_argc(argc, 0); rb_check_argc(argc, 0);
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->stop();); GFX_GUARD_EXC(b->stop(););
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -501,7 +504,7 @@ RB_METHOD(bitmapGotoStop){
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->gotoAndStop(frame);); GFX_GUARD_EXC(b->gotoAndStop(frame););
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -515,7 +518,7 @@ RB_METHOD(bitmapGotoPlay){
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->gotoAndPlay(frame);); GFX_GUARD_EXC(b->gotoAndPlay(frame););
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -560,7 +563,7 @@ RB_METHOD(bitmapAddFrame){
int ret; int ret;
GUARD_EXC(ret = b->addFrame(*src, pos);); GFX_GUARD_EXC(ret = b->addFrame(*src, pos););
return INT2NUM(ret); return INT2NUM(ret);
} }
@ -580,7 +583,7 @@ RB_METHOD(bitmapRemoveFrame){
if (pos < 0) pos = 0; if (pos < 0) pos = 0;
} }
GUARD_EXC(b->removeFrame(pos);); GFX_GUARD_EXC(b->removeFrame(pos););
return RUBY_Qnil; return RUBY_Qnil;
} }
@ -592,7 +595,7 @@ RB_METHOD(bitmapNextFrame){
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->nextFrame();); GFX_GUARD_EXC(b->nextFrame(););
return INT2NUM(b->currentFrameI()); return INT2NUM(b->currentFrameI());
} }
@ -604,7 +607,7 @@ RB_METHOD(bitmapPreviousFrame){
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->previousFrame();); GFX_GUARD_EXC(b->previousFrame(););
return INT2NUM(b->currentFrameI()); return INT2NUM(b->currentFrameI());
} }
@ -617,7 +620,7 @@ RB_METHOD(bitmapSetFPS){
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC( GFX_GUARD_EXC(
if (RB_TYPE_P(fps, RUBY_T_FLOAT)) { if (RB_TYPE_P(fps, RUBY_T_FLOAT)) {
b->setAnimationFPS(RFLOAT_VALUE(fps)); b->setAnimationFPS(RFLOAT_VALUE(fps));
} }
@ -650,7 +653,8 @@ RB_METHOD(bitmapSetLooping){
rb_get_args(argc, argv, "b", &loop RB_ARG_END); rb_get_args(argc, argv, "b", &loop RB_ARG_END);
Bitmap *b = getPrivateData<Bitmap>(self); Bitmap *b = getPrivateData<Bitmap>(self);
GUARD_EXC(b->setLooping(loop););
GFX_GUARD_EXC(b->setLooping(loop););
return rb_bool_new(loop); return rb_bool_new(loop);
} }
@ -678,7 +682,8 @@ RB_METHOD(bitmapSnapToBitmap) {
Bitmap *newbitmap = 0; Bitmap *newbitmap = 0;
int pos = (position == RUBY_Qnil) ? -1 : NUM2INT(position); int pos = (position == RUBY_Qnil) ? -1 : NUM2INT(position);
GUARD_EXC(newbitmap = new Bitmap(*b, pos););
GFX_GUARD_EXC(newbitmap = new Bitmap(*b, pos););
VALUE ret = rb_obj_alloc(rb_class_of(self)); VALUE ret = rb_obj_alloc(rb_class_of(self));
@ -705,11 +710,11 @@ RB_METHOD(bitmapInitializeCopy) {
Bitmap *orig = getPrivateData<Bitmap>(origObj); Bitmap *orig = getPrivateData<Bitmap>(origObj);
Bitmap *b = 0; Bitmap *b = 0;
GUARD_EXC(b = new Bitmap(*orig););
GFX_GUARD_EXC(b = new Bitmap(*orig););
bitmapInitProps(b, self); bitmapInitProps(b, self);
b->setFont(orig->getFont()); b->setFont(orig->getFont());
setPrivateData(self, b); setPrivateData(self, b);
return self; return self;

View file

@ -24,6 +24,7 @@
#include "disposable.h" #include "disposable.h"
#include "binding-util.h" #include "binding-util.h"
#include "graphics.h"
/* 'Children' are disposables that are disposed together /* 'Children' are disposables that are disposed together
* with their parent. Currently this is only used by Viewport * with their parent. Currently this is only used by Viewport
@ -31,6 +32,7 @@
inline void inline void
disposableAddChild(VALUE disp, VALUE child) disposableAddChild(VALUE disp, VALUE child)
{ {
GFX_LOCK;
if (NIL_P(disp) || NIL_P(child)) { if (NIL_P(disp) || NIL_P(child)) {
return; return;
} }
@ -50,11 +52,13 @@ disposableAddChild(VALUE disp, VALUE child)
if (!exists) if (!exists)
rb_ary_push(children, child); rb_ary_push(children, child);
GFX_UNLOCK;
} }
inline void inline void
disposableRemoveChild(VALUE disp, VALUE child) disposableRemoveChild(VALUE disp, VALUE child)
{ {
GFX_LOCK;
if (NIL_P(disp) || NIL_P(child)) { if (NIL_P(disp) || NIL_P(child)) {
return; return;
} }
@ -68,7 +72,7 @@ disposableRemoveChild(VALUE disp, VALUE child)
return; return;
rb_funcall(children, rb_intern("delete_at"), 1, index); rb_funcall(children, rb_intern("delete_at"), 1, index);
GFX_UNLOCK;
} }
inline void inline void
@ -102,7 +106,9 @@ RB_METHOD(disposableDispose)
if (rgssVer == 1) if (rgssVer == 1)
disposableDisposeChildren(self); disposableDisposeChildren(self);
GFX_LOCK;
d->dispose(); d->dispose();
GFX_UNLOCK;
return Qnil; return Qnil;
} }

View file

@ -31,34 +31,44 @@
RB_METHOD(graphicsDelta) { RB_METHOD(graphicsDelta) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
GFX_LOCK;
return ULL2NUM(shState->graphics().getDelta()); VALUE ret = ULL2NUM(shState->graphics().getDelta());
GFX_UNLOCK;
return ret;
} }
RB_METHOD(graphicsUpdate) RB_METHOD(graphicsUpdate)
{ {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
#if RAPI_MAJOR >= 2 #if RAPI_MAJOR >= 2
rb_thread_call_without_gvl([](void*) -> void* {shState->graphics().update(); return 0;}, 0, 0, 0); rb_thread_call_without_gvl([](void*) -> void* {
GFX_LOCK;
shState->graphics().update();
GFX_UNLOCK;
return 0;
}, 0, 0, 0);
#else #else
shState->graphics().update(); shState->graphics().update();
#endif #endif
return Qnil; return Qnil;
} }
RB_METHOD(graphicsAverageFrameRate) RB_METHOD(graphicsAverageFrameRate)
{ {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
GFX_LOCK;
return rb_float_new(shState->graphics().averageFrameRate()); VALUE ret = rb_float_new(shState->graphics().averageFrameRate());
GFX_UNLOCK;
return ret;
} }
RB_METHOD(graphicsFreeze) RB_METHOD(graphicsFreeze)
{ {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
GFX_LOCK;
shState->graphics().freeze(); shState->graphics().freeze();
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -73,7 +83,7 @@ RB_METHOD(graphicsTransition)
rb_get_args(argc, argv, "|izi", &duration, &filename, &vague RB_ARG_END); rb_get_args(argc, argv, "|izi", &duration, &filename, &vague RB_ARG_END);
GUARD_EXC( shState->graphics().transition(duration, filename, vague); ) GFX_GUARD_EXC( shState->graphics().transition(duration, filename, vague); )
return Qnil; return Qnil;
} }
@ -82,7 +92,9 @@ RB_METHOD(graphicsFrameReset)
{ {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
GFX_LOCK;
shState->graphics().frameReset(); shState->graphics().frameReset();
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -98,7 +110,9 @@ RB_METHOD(graphics##Set##PropName) \
RB_UNUSED_PARAM; \ RB_UNUSED_PARAM; \
int value; \ int value; \
rb_get_args(argc, argv, "i", &value RB_ARG_END); \ rb_get_args(argc, argv, "i", &value RB_ARG_END); \
GFX_LOCK; \
shState->graphics().set##PropName(value); \ shState->graphics().set##PropName(value); \
GFX_UNLOCK; \
return rb_fix_new(value); \ return rb_fix_new(value); \
} }
@ -113,7 +127,9 @@ RB_METHOD(graphics##Set##PropName) \
RB_UNUSED_PARAM; \ RB_UNUSED_PARAM; \
bool value; \ bool value; \
rb_get_args(argc, argv, "b", &value RB_ARG_END); \ rb_get_args(argc, argv, "b", &value RB_ARG_END); \
GFX_LOCK; \
shState->graphics().set##PropName(value); \ shState->graphics().set##PropName(value); \
GFX_UNLOCK; \
return rb_bool_new(value); \ return rb_bool_new(value); \
} }
@ -128,7 +144,9 @@ RB_METHOD(graphics##Set##PropName) \
RB_UNUSED_PARAM; \ RB_UNUSED_PARAM; \
double value; \ double value; \
rb_get_args(argc, argv, "f", &value RB_ARG_END); \ rb_get_args(argc, argv, "f", &value RB_ARG_END); \
GFX_LOCK; \
shState->graphics().set##PropName(value); \ shState->graphics().set##PropName(value); \
GFX_UNLOCK; \
return rb_float_new(value); \ return rb_float_new(value); \
} }
@ -153,11 +171,15 @@ RB_METHOD(graphicsWait)
int duration; int duration;
rb_get_args(argc, argv, "i", &duration RB_ARG_END); rb_get_args(argc, argv, "i", &duration RB_ARG_END);
#if RAPI_MAJOR >= 2 #if RAPI_MAJOR >= 2
rb_thread_call_without_gvl([](void* d) -> void* {shState->graphics().wait(*(int*)d); return 0;}, (int*)&duration, 0, 0); rb_thread_call_without_gvl([](void* d) -> void* {
GFX_LOCK;
shState->graphics().wait(*(int*)d);
GFX_UNLOCK;
return 0;
}, (int*)&duration, 0, 0);
#else #else
shState->graphics().wait(duration); shState->graphics().wait(duration);
#endif #endif
return Qnil; return Qnil;
} }
@ -168,7 +190,9 @@ RB_METHOD(graphicsFadeout)
int duration; int duration;
rb_get_args(argc, argv, "i", &duration RB_ARG_END); rb_get_args(argc, argv, "i", &duration RB_ARG_END);
GFX_LOCK;
shState->graphics().fadeout(duration); shState->graphics().fadeout(duration);
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -180,7 +204,9 @@ RB_METHOD(graphicsFadein)
int duration; int duration;
rb_get_args(argc, argv, "i", &duration RB_ARG_END); rb_get_args(argc, argv, "i", &duration RB_ARG_END);
GFX_LOCK;
shState->graphics().fadein(duration); shState->graphics().fadein(duration);
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -192,7 +218,8 @@ RB_METHOD(graphicsSnapToBitmap)
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
Bitmap *result = 0; Bitmap *result = 0;
GUARD_EXC( result = shState->graphics().snapToBitmap(); );
GFX_GUARD_EXC( result = shState->graphics().snapToBitmap(); );
VALUE obj = wrapObject(result, BitmapType); VALUE obj = wrapObject(result, BitmapType);
bitmapInitProps(result, obj); bitmapInitProps(result, obj);
@ -207,7 +234,9 @@ RB_METHOD(graphicsResizeScreen)
int width, height; int width, height;
rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END); rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END);
GFX_LOCK;
shState->graphics().resizeScreen(width, height); shState->graphics().resizeScreen(width, height);
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -216,7 +245,9 @@ RB_METHOD(graphicsReset)
{ {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
GFX_LOCK;
shState->graphics().reset(); shState->graphics().reset();
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -243,14 +274,7 @@ RB_METHOD(graphicsPlayMovie)
void graphicsScreenshotInternal(const char *filename) void graphicsScreenshotInternal(const char *filename)
{ {
try GFX_GUARD_EXC(shState->graphics().screenshot(filename););
{
shState->graphics().screenshot(filename);
}
catch(const Exception &e)
{
raiseRbExc(e);
}
} }
RB_METHOD(graphicsScreenshot) RB_METHOD(graphicsScreenshot)
@ -260,8 +284,12 @@ RB_METHOD(graphicsScreenshot)
VALUE filename; VALUE filename;
rb_scan_args(argc, argv, "1", &filename); rb_scan_args(argc, argv, "1", &filename);
SafeStringValue(filename); SafeStringValue(filename);
#if RAPI_MAJOR >= 2 #if RAPI_MAJOR >= 2
rb_thread_call_without_gvl([](void* fn) -> void* {graphicsScreenshotInternal((const char*)fn); return 0;}, (void*)filename, 0, 0); rb_thread_call_without_gvl([](void* fn) -> void* {
graphicsScreenshotInternal((const char*)fn);
return 0;
}, (void*)filename, 0, 0);
#else #else
graphicsScreenshotInternal(RSTRING_PTR(filename)); graphicsScreenshotInternal(RSTRING_PTR(filename));
#endif #endif

View file

@ -36,25 +36,27 @@ RB_METHOD(planeInitialize) {
setPrivateData(self, p); setPrivateData(self, p);
GFX_LOCK;
p->initDynAttribs(); p->initDynAttribs();
wrapProperty(self, &p->getColor(), "color", ColorType); wrapProperty(self, &p->getColor(), "color", ColorType);
wrapProperty(self, &p->getTone(), "tone", ToneType); wrapProperty(self, &p->getTone(), "tone", ToneType);
GFX_UNLOCK;
return self; return self;
} }
DEF_PROP_OBJ_REF(Plane, Bitmap, Bitmap, "bitmap") DEF_GFX_PROP_OBJ_REF(Plane, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ_VAL(Plane, Color, Color, "color") DEF_GFX_PROP_OBJ_VAL(Plane, Color, Color, "color")
DEF_PROP_OBJ_VAL(Plane, Tone, Tone, "tone") DEF_GFX_PROP_OBJ_VAL(Plane, Tone, Tone, "tone")
DEF_PROP_I(Plane, OX) DEF_GFX_PROP_I(Plane, OX)
DEF_PROP_I(Plane, OY) DEF_GFX_PROP_I(Plane, OY)
DEF_PROP_I(Plane, Opacity) DEF_GFX_PROP_I(Plane, Opacity)
DEF_PROP_I(Plane, BlendType) DEF_GFX_PROP_I(Plane, BlendType)
DEF_PROP_F(Plane, ZoomX) DEF_GFX_PROP_F(Plane, ZoomX)
DEF_PROP_F(Plane, ZoomY) DEF_GFX_PROP_F(Plane, ZoomY)
void planeBindingInit() { void planeBindingInit() {
VALUE klass = rb_define_class("Plane", rb_cObject); VALUE klass = rb_define_class("Plane", rb_cObject);

View file

@ -24,6 +24,7 @@
#include "scene.h" #include "scene.h"
#include "binding-util.h" #include "binding-util.h"
#include "graphics.h"
template<class C> template<class C>
RB_METHOD(sceneElementGetZ) RB_METHOD(sceneElementGetZ)
@ -46,7 +47,7 @@ RB_METHOD(sceneElementSetZ)
int z; int z;
rb_get_args(argc, argv, "i", &z RB_ARG_END); rb_get_args(argc, argv, "i", &z RB_ARG_END);
GUARD_EXC( se->setZ(z); ); GFX_GUARD_EXC( se->setZ(z); );
return rb_fix_new(z); return rb_fix_new(z);
} }
@ -72,7 +73,7 @@ RB_METHOD(sceneElementSetVisible)
bool visible; bool visible;
rb_get_args(argc, argv, "b", &visible RB_ARG_END); rb_get_args(argc, argv, "b", &visible RB_ARG_END);
GUARD_EXC( se->setVisible(visible); ); GFX_GUARD_EXC( se->setVisible(visible); );
return rb_bool_new(visible); return rb_bool_new(visible);
} }

View file

@ -1,23 +1,23 @@
/* /*
** sprite-binding.cpp ** sprite-binding.cpp
** **
** This file is part of mkxp. ** This file is part of mkxp.
** **
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com> ** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** **
** mkxp is free software: you can redistribute it and/or modify ** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or ** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** mkxp is distributed in the hope that it will be useful, ** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>. ** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "binding-types.h" #include "binding-types.h"
#include "binding-util.h" #include "binding-util.h"
@ -35,103 +35,105 @@ DEF_ALLOCFUNC(Sprite);
#endif #endif
RB_METHOD(spriteInitialize) { RB_METHOD(spriteInitialize) {
Sprite *s = viewportElementInitialize<Sprite>(argc, argv, self); GFX_LOCK;
Sprite *s = viewportElementInitialize<Sprite>(argc, argv, self);
setPrivateData(self, s);
setPrivateData(self, s);
/* Wrap property objects */
s->initDynAttribs(); /* Wrap property objects */
s->initDynAttribs();
wrapProperty(self, &s->getSrcRect(), "src_rect", RectType);
wrapProperty(self, &s->getColor(), "color", ColorType); wrapProperty(self, &s->getSrcRect(), "src_rect", RectType);
wrapProperty(self, &s->getTone(), "tone", ToneType); wrapProperty(self, &s->getColor(), "color", ColorType);
wrapProperty(self, &s->getTone(), "tone", ToneType);
return self;
GFX_UNLOCK;
return self;
} }
DEF_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, "bitmap") DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, "bitmap")
DEF_PROP_OBJ_VAL(Sprite, Rect, SrcRect, "src_rect") DEF_GFX_PROP_OBJ_VAL(Sprite, Rect, SrcRect, "src_rect")
DEF_PROP_OBJ_VAL(Sprite, Color, Color, "color") DEF_GFX_PROP_OBJ_VAL(Sprite, Color, Color, "color")
DEF_PROP_OBJ_VAL(Sprite, Tone, Tone, "tone") DEF_GFX_PROP_OBJ_VAL(Sprite, Tone, Tone, "tone")
DEF_PROP_I(Sprite, X) DEF_GFX_PROP_I(Sprite, X)
DEF_PROP_I(Sprite, Y) DEF_GFX_PROP_I(Sprite, Y)
DEF_PROP_I(Sprite, OX) DEF_GFX_PROP_I(Sprite, OX)
DEF_PROP_I(Sprite, OY) DEF_GFX_PROP_I(Sprite, OY)
DEF_PROP_I(Sprite, BushDepth) DEF_GFX_PROP_I(Sprite, BushDepth)
DEF_PROP_I(Sprite, BushOpacity) DEF_GFX_PROP_I(Sprite, BushOpacity)
DEF_PROP_I(Sprite, Opacity) DEF_GFX_PROP_I(Sprite, Opacity)
DEF_PROP_I(Sprite, BlendType) DEF_GFX_PROP_I(Sprite, BlendType)
DEF_PROP_I(Sprite, WaveAmp) DEF_GFX_PROP_I(Sprite, WaveAmp)
DEF_PROP_I(Sprite, WaveLength) DEF_GFX_PROP_I(Sprite, WaveLength)
DEF_PROP_I(Sprite, WaveSpeed) DEF_GFX_PROP_I(Sprite, WaveSpeed)
DEF_PROP_F(Sprite, ZoomX) DEF_GFX_PROP_F(Sprite, ZoomX)
DEF_PROP_F(Sprite, ZoomY) DEF_GFX_PROP_F(Sprite, ZoomY)
DEF_PROP_F(Sprite, Angle) DEF_GFX_PROP_F(Sprite, Angle)
DEF_PROP_F(Sprite, WavePhase) DEF_GFX_PROP_F(Sprite, WavePhase)
DEF_PROP_B(Sprite, Mirror) DEF_GFX_PROP_B(Sprite, Mirror)
RB_METHOD(spriteWidth) { RB_METHOD(spriteWidth) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
Sprite *s = getPrivateData<Sprite>(self); Sprite *s = getPrivateData<Sprite>(self);
int value = 0; int value = 0;
GUARD_EXC(value = s->getWidth();) GUARD_EXC(value = s->getWidth();)
return rb_fix_new(value); return rb_fix_new(value);
} }
RB_METHOD(spriteHeight) { RB_METHOD(spriteHeight) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
Sprite *s = getPrivateData<Sprite>(self); Sprite *s = getPrivateData<Sprite>(self);
int value = 0; int value = 0;
GUARD_EXC(value = s->getHeight();) GUARD_EXC(value = s->getHeight();)
return rb_fix_new(value); return rb_fix_new(value);
} }
void spriteBindingInit() { void spriteBindingInit() {
VALUE klass = rb_define_class("Sprite", rb_cObject); VALUE klass = rb_define_class("Sprite", rb_cObject);
#if RAPI_FULL > 187 #if RAPI_FULL > 187
rb_define_alloc_func(klass, classAllocate<&SpriteType>); rb_define_alloc_func(klass, classAllocate<&SpriteType>);
#else #else
rb_define_alloc_func(klass, SpriteAllocate); rb_define_alloc_func(klass, SpriteAllocate);
#endif #endif
disposableBindingInit<Sprite>(klass); disposableBindingInit<Sprite>(klass);
flashableBindingInit<Sprite>(klass); flashableBindingInit<Sprite>(klass);
viewportElementBindingInit<Sprite>(klass); viewportElementBindingInit<Sprite>(klass);
_rb_define_method(klass, "initialize", spriteInitialize); _rb_define_method(klass, "initialize", spriteInitialize);
INIT_PROP_BIND(Sprite, Bitmap, "bitmap"); INIT_PROP_BIND(Sprite, Bitmap, "bitmap");
INIT_PROP_BIND(Sprite, SrcRect, "src_rect"); INIT_PROP_BIND(Sprite, SrcRect, "src_rect");
INIT_PROP_BIND(Sprite, X, "x"); INIT_PROP_BIND(Sprite, X, "x");
INIT_PROP_BIND(Sprite, Y, "y"); INIT_PROP_BIND(Sprite, Y, "y");
INIT_PROP_BIND(Sprite, OX, "ox"); INIT_PROP_BIND(Sprite, OX, "ox");
INIT_PROP_BIND(Sprite, OY, "oy"); INIT_PROP_BIND(Sprite, OY, "oy");
INIT_PROP_BIND(Sprite, ZoomX, "zoom_x"); INIT_PROP_BIND(Sprite, ZoomX, "zoom_x");
INIT_PROP_BIND(Sprite, ZoomY, "zoom_y"); INIT_PROP_BIND(Sprite, ZoomY, "zoom_y");
INIT_PROP_BIND(Sprite, Angle, "angle"); INIT_PROP_BIND(Sprite, Angle, "angle");
INIT_PROP_BIND(Sprite, Mirror, "mirror"); INIT_PROP_BIND(Sprite, Mirror, "mirror");
INIT_PROP_BIND(Sprite, BushDepth, "bush_depth"); INIT_PROP_BIND(Sprite, BushDepth, "bush_depth");
INIT_PROP_BIND(Sprite, Opacity, "opacity"); INIT_PROP_BIND(Sprite, Opacity, "opacity");
INIT_PROP_BIND(Sprite, BlendType, "blend_type"); INIT_PROP_BIND(Sprite, BlendType, "blend_type");
INIT_PROP_BIND(Sprite, Color, "color"); INIT_PROP_BIND(Sprite, Color, "color");
INIT_PROP_BIND(Sprite, Tone, "tone"); INIT_PROP_BIND(Sprite, Tone, "tone");
_rb_define_method(klass, "width", spriteWidth); _rb_define_method(klass, "width", spriteWidth);
_rb_define_method(klass, "height", spriteHeight); _rb_define_method(klass, "height", spriteHeight);
INIT_PROP_BIND(Sprite, BushOpacity, "bush_opacity"); INIT_PROP_BIND(Sprite, BushOpacity, "bush_opacity");
INIT_PROP_BIND(Sprite, WaveAmp, "wave_amp"); INIT_PROP_BIND(Sprite, WaveAmp, "wave_amp");
INIT_PROP_BIND(Sprite, WaveLength, "wave_length"); INIT_PROP_BIND(Sprite, WaveLength, "wave_length");
INIT_PROP_BIND(Sprite, WaveSpeed, "wave_speed"); INIT_PROP_BIND(Sprite, WaveSpeed, "wave_speed");
INIT_PROP_BIND(Sprite, WavePhase, "wave_phase"); INIT_PROP_BIND(Sprite, WavePhase, "wave_phase");
} }

View file

@ -1,23 +1,23 @@
/* /*
** tilemap-binding.cpp ** tilemap-binding.cpp
** **
** This file is part of mkxp. ** This file is part of mkxp.
** **
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com> ** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** **
** mkxp is free software: you can redistribute it and/or modify ** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or ** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** mkxp is distributed in the hope that it will be useful, ** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>. ** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "bitmap.h" #include "bitmap.h"
#include "table.h" #include "table.h"
@ -35,33 +35,34 @@ DEF_TYPE_CUSTOMFREE(TilemapAutotiles, RUBY_TYPED_NEVER_FREE);
#endif #endif
RB_METHOD(tilemapAutotilesSet) { RB_METHOD(tilemapAutotilesSet) {
Tilemap::Autotiles *a = getPrivateData<Tilemap::Autotiles>(self); Tilemap::Autotiles *a = getPrivateData<Tilemap::Autotiles>(self);
int i; int i;
VALUE bitmapObj; VALUE bitmapObj;
rb_get_args(argc, argv, "io", &i, &bitmapObj RB_ARG_END); rb_get_args(argc, argv, "io", &i, &bitmapObj RB_ARG_END);
Bitmap *bitmap = getPrivateDataCheck<Bitmap>(bitmapObj, BitmapType); Bitmap *bitmap = getPrivateDataCheck<Bitmap>(bitmapObj, BitmapType);
a->set(i, bitmap); GFX_LOCK;
a->set(i, bitmap);
VALUE ary = rb_iv_get(self, "array");
rb_ary_store(ary, i, bitmapObj); VALUE ary = rb_iv_get(self, "array");
rb_ary_store(ary, i, bitmapObj);
return self; GFX_UNLOCK;
return self;
} }
RB_METHOD(tilemapAutotilesGet) { RB_METHOD(tilemapAutotilesGet) {
int i; int i;
rb_get_args(argc, argv, "i", &i RB_ARG_END); rb_get_args(argc, argv, "i", &i RB_ARG_END);
if (i < 0 || i > 6) if (i < 0 || i > 6)
return Qnil; return Qnil;
VALUE ary = rb_iv_get(self, "array"); VALUE ary = rb_iv_get(self, "array");
return rb_ary_entry(ary, i); return rb_ary_entry(ary, i);
} }
#if RAPI_FULL > 187 #if RAPI_FULL > 187
@ -71,122 +72,126 @@ DEF_ALLOCFUNC(Tilemap);
#endif #endif
RB_METHOD(tilemapInitialize) { RB_METHOD(tilemapInitialize) {
Tilemap *t; Tilemap *t;
/* Get parameters */ /* Get parameters */
VALUE viewportObj = Qnil; VALUE viewportObj = Qnil;
Viewport *viewport = 0; Viewport *viewport = 0;
rb_get_args(argc, argv, "|o", &viewportObj RB_ARG_END); rb_get_args(argc, argv, "|o", &viewportObj RB_ARG_END);
if (!NIL_P(viewportObj)) if (!NIL_P(viewportObj))
viewport = getPrivateDataCheck<Viewport>(viewportObj, ViewportType); viewport = getPrivateDataCheck<Viewport>(viewportObj, ViewportType);
/* Construct object */ GFX_LOCK;
t = new Tilemap(viewport); /* Construct object */
t = new Tilemap(viewport);
rb_iv_set(self, "viewport", viewportObj);
rb_iv_set(self, "viewport", viewportObj);
setPrivateData(self, t);
setPrivateData(self, t);
t->initDynAttribs();
t->initDynAttribs();
wrapProperty(self, &t->getAutotiles(), "autotiles", TilemapAutotilesType);
wrapProperty(self, &t->getAutotiles(), "autotiles", TilemapAutotilesType);
wrapProperty(self, &t->getColor(), "color", ColorType);
wrapProperty(self, &t->getTone(), "tone", ToneType); wrapProperty(self, &t->getColor(), "color", ColorType);
wrapProperty(self, &t->getTone(), "tone", ToneType);
VALUE autotilesObj = rb_iv_get(self, "autotiles");
VALUE autotilesObj = rb_iv_get(self, "autotiles");
VALUE ary = rb_ary_new2(7);
for (int i = 0; i < 7; ++i) VALUE ary = rb_ary_new2(7);
rb_ary_push(ary, Qnil); for (int i = 0; i < 7; ++i)
rb_ary_push(ary, Qnil);
rb_iv_set(autotilesObj, "array", ary);
rb_iv_set(autotilesObj, "array", ary);
/* Circular reference so both objects are always
* alive at the same time */ /* Circular reference so both objects are always
rb_iv_set(autotilesObj, "tilemap", self); * alive at the same time */
rb_iv_set(autotilesObj, "tilemap", self);
return self;
GFX_UNLOCK;
return self;
} }
RB_METHOD(tilemapGetAutotiles) { RB_METHOD(tilemapGetAutotiles) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
checkDisposed<Tilemap>(self); checkDisposed<Tilemap>(self);
return rb_iv_get(self, "autotiles"); return rb_iv_get(self, "autotiles");
} }
RB_METHOD(tilemapUpdate) { RB_METHOD(tilemapUpdate) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
Tilemap *t = getPrivateData<Tilemap>(self); Tilemap *t = getPrivateData<Tilemap>(self);
t->update(); GFX_LOCK;
t->update();
return Qnil; GFX_UNLOCK;
return Qnil;
} }
RB_METHOD(tilemapGetViewport) { RB_METHOD(tilemapGetViewport) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
checkDisposed<Tilemap>(self); checkDisposed<Tilemap>(self);
return rb_iv_get(self, "viewport"); return rb_iv_get(self, "viewport");
} }
DEF_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, "tileset") DEF_GFX_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, "tileset")
DEF_PROP_OBJ_REF(Tilemap, Table, MapData, "map_data") DEF_GFX_PROP_OBJ_REF(Tilemap, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(Tilemap, Table, FlashData, "flash_data") DEF_GFX_PROP_OBJ_REF(Tilemap, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(Tilemap, Table, Priorities, "priorities") DEF_GFX_PROP_OBJ_REF(Tilemap, Table, Priorities, "priorities")
DEF_PROP_OBJ_VAL(Tilemap, Color, Color, "color") DEF_GFX_PROP_OBJ_VAL(Tilemap, Color, Color, "color")
DEF_PROP_OBJ_VAL(Tilemap, Tone, Tone, "tone") DEF_GFX_PROP_OBJ_VAL(Tilemap, Tone, Tone, "tone")
DEF_PROP_B(Tilemap, Visible) DEF_GFX_PROP_B(Tilemap, Visible)
DEF_PROP_I(Tilemap, OX) DEF_GFX_PROP_I(Tilemap, OX)
DEF_PROP_I(Tilemap, OY) DEF_GFX_PROP_I(Tilemap, OY)
DEF_PROP_I(Tilemap, Opacity) DEF_GFX_PROP_I(Tilemap, Opacity)
DEF_PROP_I(Tilemap, BlendType) DEF_GFX_PROP_I(Tilemap, BlendType)
void tilemapBindingInit() { void tilemapBindingInit() {
VALUE klass = rb_define_class("TilemapAutotiles", rb_cObject); VALUE klass = rb_define_class("TilemapAutotiles", rb_cObject);
#if RAPI_FULL > 187 #if RAPI_FULL > 187
rb_define_alloc_func(klass, classAllocate<&TilemapAutotilesType>); rb_define_alloc_func(klass, classAllocate<&TilemapAutotilesType>);
#endif #endif
_rb_define_method(klass, "[]=", tilemapAutotilesSet); _rb_define_method(klass, "[]=", tilemapAutotilesSet);
_rb_define_method(klass, "[]", tilemapAutotilesGet); _rb_define_method(klass, "[]", tilemapAutotilesGet);
klass = rb_define_class("Tilemap", rb_cObject); klass = rb_define_class("Tilemap", rb_cObject);
#if RAPI_FULL > 187 #if RAPI_FULL > 187
rb_define_alloc_func(klass, classAllocate<&TilemapType>); rb_define_alloc_func(klass, classAllocate<&TilemapType>);
#else #else
rb_define_alloc_func(klass, TilemapAllocate); rb_define_alloc_func(klass, TilemapAllocate);
#endif #endif
disposableBindingInit<Tilemap>(klass); disposableBindingInit<Tilemap>(klass);
_rb_define_method(klass, "initialize", tilemapInitialize); _rb_define_method(klass, "initialize", tilemapInitialize);
_rb_define_method(klass, "autotiles", tilemapGetAutotiles); _rb_define_method(klass, "autotiles", tilemapGetAutotiles);
_rb_define_method(klass, "update", tilemapUpdate); _rb_define_method(klass, "update", tilemapUpdate);
_rb_define_method(klass, "viewport", tilemapGetViewport); _rb_define_method(klass, "viewport", tilemapGetViewport);
INIT_PROP_BIND(Tilemap, Tileset, "tileset"); INIT_PROP_BIND(Tilemap, Tileset, "tileset");
INIT_PROP_BIND(Tilemap, MapData, "map_data"); INIT_PROP_BIND(Tilemap, MapData, "map_data");
INIT_PROP_BIND(Tilemap, FlashData, "flash_data"); INIT_PROP_BIND(Tilemap, FlashData, "flash_data");
INIT_PROP_BIND(Tilemap, Priorities, "priorities"); INIT_PROP_BIND(Tilemap, Priorities, "priorities");
INIT_PROP_BIND(Tilemap, Visible, "visible"); INIT_PROP_BIND(Tilemap, Visible, "visible");
INIT_PROP_BIND(Tilemap, OX, "ox"); INIT_PROP_BIND(Tilemap, OX, "ox");
INIT_PROP_BIND(Tilemap, OY, "oy"); INIT_PROP_BIND(Tilemap, OY, "oy");
INIT_PROP_BIND(Tilemap, Opacity, "opacity"); INIT_PROP_BIND(Tilemap, Opacity, "opacity");
INIT_PROP_BIND(Tilemap, BlendType, "blend_type"); INIT_PROP_BIND(Tilemap, BlendType, "blend_type");
INIT_PROP_BIND(Tilemap, Color, "color"); INIT_PROP_BIND(Tilemap, Color, "color");
INIT_PROP_BIND(Tilemap, Tone, "tone"); INIT_PROP_BIND(Tilemap, Tone, "tone");
} }

View file

@ -1,23 +1,23 @@
/* /*
** tilemapvx-binding.cpp ** tilemapvx-binding.cpp
** **
** This file is part of mkxp. ** This file is part of mkxp.
** **
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com> ** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
** **
** mkxp is free software: you can redistribute it and/or modify ** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or ** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** mkxp is distributed in the hope that it will be useful, ** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>. ** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "bitmap.h" #include "bitmap.h"
#include "sharedstate.h" #include "sharedstate.h"
@ -39,132 +39,135 @@ DEF_ALLOCFUNC(TilemapVX);
#endif #endif
RB_METHOD(tilemapVXInitialize) { RB_METHOD(tilemapVXInitialize) {
TilemapVX *t; TilemapVX *t;
/* Get parameters */ GFX_LOCK;
VALUE viewportObj = Qnil; /* Get parameters */
Viewport *viewport = 0; VALUE viewportObj = Qnil;
Viewport *viewport = 0;
rb_get_args(argc, argv, "|o", &viewportObj RB_ARG_END);
rb_get_args(argc, argv, "|o", &viewportObj RB_ARG_END);
if (!NIL_P(viewportObj))
viewport = getPrivateDataCheck<Viewport>(viewportObj, ViewportType); if (!NIL_P(viewportObj))
viewport = getPrivateDataCheck<Viewport>(viewportObj, ViewportType);
/* Construct object */
t = new TilemapVX(viewport); /* Construct object */
t = new TilemapVX(viewport);
setPrivateData(self, t);
setPrivateData(self, t);
rb_iv_set(self, "viewport", viewportObj);
rb_iv_set(self, "viewport", viewportObj);
wrapProperty(self, &t->getBitmapArray(), "bitmap_array", BitmapArrayType,
rb_const_get(rb_cObject, rb_intern("Tilemap"))); wrapProperty(self, &t->getBitmapArray(), "bitmap_array", BitmapArrayType,
rb_const_get(rb_cObject, rb_intern("Tilemap")));
VALUE autotilesObj = rb_iv_get(self, "bitmap_array");
VALUE autotilesObj = rb_iv_get(self, "bitmap_array");
VALUE ary = rb_ary_new2(9);
for (int i = 0; i < 9; ++i) VALUE ary = rb_ary_new2(9);
rb_ary_push(ary, Qnil); for (int i = 0; i < 9; ++i)
rb_ary_push(ary, Qnil);
rb_iv_set(autotilesObj, "array", ary);
rb_iv_set(autotilesObj, "array", ary);
/* Circular reference so both objects are always
* alive at the same time */ /* Circular reference so both objects are always
rb_iv_set(autotilesObj, "tilemap", self); * alive at the same time */
rb_iv_set(autotilesObj, "tilemap", self);
return self;
GFX_UNLOCK;
return self;
} }
RB_METHOD(tilemapVXGetBitmapArray) { RB_METHOD(tilemapVXGetBitmapArray) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
checkDisposed<TilemapVX>(self); checkDisposed<TilemapVX>(self);
return rb_iv_get(self, "bitmap_array"); return rb_iv_get(self, "bitmap_array");
} }
RB_METHOD(tilemapVXUpdate) { RB_METHOD(tilemapVXUpdate) {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
TilemapVX *t = getPrivateData<TilemapVX>(self); TilemapVX *t = getPrivateData<TilemapVX>(self);
t->update(); t->update();
return Qnil; return Qnil;
} }
DEF_PROP_OBJ_REF(TilemapVX, Viewport, Viewport, "viewport") DEF_GFX_PROP_OBJ_REF(TilemapVX, Viewport, Viewport, "viewport")
DEF_PROP_OBJ_REF(TilemapVX, Table, MapData, "map_data") DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(TilemapVX, Table, FlashData, "flash_data") DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(TilemapVX, Table, Flags, "flags") DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, Flags, "flags")
DEF_PROP_B(TilemapVX, Visible) DEF_GFX_PROP_B(TilemapVX, Visible)
DEF_PROP_I(TilemapVX, OX) DEF_GFX_PROP_I(TilemapVX, OX)
DEF_PROP_I(TilemapVX, OY) DEF_GFX_PROP_I(TilemapVX, OY)
RB_METHOD(tilemapVXBitmapsSet) { RB_METHOD(tilemapVXBitmapsSet) {
TilemapVX::BitmapArray *a = getPrivateData<TilemapVX::BitmapArray>(self); TilemapVX::BitmapArray *a = getPrivateData<TilemapVX::BitmapArray>(self);
int i; int i;
VALUE bitmapObj; VALUE bitmapObj;
rb_get_args(argc, argv, "io", &i, &bitmapObj RB_ARG_END); rb_get_args(argc, argv, "io", &i, &bitmapObj RB_ARG_END);
Bitmap *bitmap = getPrivateDataCheck<Bitmap>(bitmapObj, BitmapType); Bitmap *bitmap = getPrivateDataCheck<Bitmap>(bitmapObj, BitmapType);
a->set(i, bitmap); GFX_LOCK;
a->set(i, bitmap);
VALUE ary = rb_iv_get(self, "array");
rb_ary_store(ary, i, bitmapObj); VALUE ary = rb_iv_get(self, "array");
rb_ary_store(ary, i, bitmapObj);
return self; GFX_UNLOCK;
return self;
} }
RB_METHOD(tilemapVXBitmapsGet) { RB_METHOD(tilemapVXBitmapsGet) {
int i; int i;
rb_get_args(argc, argv, "i", &i RB_ARG_END); rb_get_args(argc, argv, "i", &i RB_ARG_END);
if (i < 0 || i > 8) if (i < 0 || i > 8)
return Qnil; return Qnil;
VALUE ary = rb_iv_get(self, "array"); VALUE ary = rb_iv_get(self, "array");
return rb_ary_entry(ary, i); return rb_ary_entry(ary, i);
} }
void tilemapVXBindingInit() { void tilemapVXBindingInit() {
VALUE klass = rb_define_class("Tilemap", rb_cObject); VALUE klass = rb_define_class("Tilemap", rb_cObject);
#if RAPI_FULL > 187 #if RAPI_FULL > 187
rb_define_alloc_func(klass, classAllocate<&TilemapVXType>); rb_define_alloc_func(klass, classAllocate<&TilemapVXType>);
#else #else
rb_define_alloc_func(klass, TilemapVXAllocate); rb_define_alloc_func(klass, TilemapVXAllocate);
#endif #endif
disposableBindingInit<TilemapVX>(klass); disposableBindingInit<TilemapVX>(klass);
_rb_define_method(klass, "initialize", tilemapVXInitialize); _rb_define_method(klass, "initialize", tilemapVXInitialize);
_rb_define_method(klass, "bitmaps", tilemapVXGetBitmapArray); _rb_define_method(klass, "bitmaps", tilemapVXGetBitmapArray);
_rb_define_method(klass, "update", tilemapVXUpdate); _rb_define_method(klass, "update", tilemapVXUpdate);
INIT_PROP_BIND(TilemapVX, Viewport, "viewport"); INIT_PROP_BIND(TilemapVX, Viewport, "viewport");
INIT_PROP_BIND(TilemapVX, MapData, "map_data"); INIT_PROP_BIND(TilemapVX, MapData, "map_data");
INIT_PROP_BIND(TilemapVX, FlashData, "flash_data"); INIT_PROP_BIND(TilemapVX, FlashData, "flash_data");
INIT_PROP_BIND(TilemapVX, Visible, "visible"); INIT_PROP_BIND(TilemapVX, Visible, "visible");
INIT_PROP_BIND(TilemapVX, OX, "ox"); INIT_PROP_BIND(TilemapVX, OX, "ox");
INIT_PROP_BIND(TilemapVX, OY, "oy"); INIT_PROP_BIND(TilemapVX, OY, "oy");
if (rgssVer == 3) { if (rgssVer == 3) {
INIT_PROP_BIND(TilemapVX, Flags, "flags"); INIT_PROP_BIND(TilemapVX, Flags, "flags");
} else { } else {
INIT_PROP_BIND(TilemapVX, Flags, "passages"); INIT_PROP_BIND(TilemapVX, Flags, "passages");
} }
klass = rb_define_class_under(klass, "BitmapArray", rb_cObject); klass = rb_define_class_under(klass, "BitmapArray", rb_cObject);
#if RAPI_FULL > 187 #if RAPI_FULL > 187
rb_define_alloc_func(klass, classAllocate<&BitmapArrayType>); rb_define_alloc_func(klass, classAllocate<&BitmapArrayType>);
#endif #endif
_rb_define_method(klass, "[]=", tilemapVXBitmapsSet); _rb_define_method(klass, "[]=", tilemapVXBitmapsSet);
_rb_define_method(klass, "[]", tilemapVXBitmapsGet); _rb_define_method(klass, "[]", tilemapVXBitmapsGet);
} }

View file

@ -1,23 +1,23 @@
/* /*
** viewport-binding.cpp ** viewport-binding.cpp
** **
** This file is part of mkxp. ** This file is part of mkxp.
** **
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com> ** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
** **
** mkxp is free software: you can redistribute it and/or modify ** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or ** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** mkxp is distributed in the hope that it will be useful, ** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>. ** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "binding-types.h" #include "binding-types.h"
#include "binding-util.h" #include "binding-util.h"
@ -34,70 +34,72 @@ DEF_ALLOCFUNC(Viewport);
#endif #endif
RB_METHOD(viewportInitialize) { RB_METHOD(viewportInitialize) {
Viewport *v; Viewport *v;
if (argc == 0 && rgssVer >= 3) { if (argc == 0 && rgssVer >= 3) {
v = new Viewport(); GFX_LOCK;
} else if (argc == 1) { v = new Viewport();
/* The rect arg is only used to init the viewport, } else if (argc == 1) {
* and does NOT replace its 'rect' property */ /* The rect arg is only used to init the viewport,
VALUE rectObj; * and does NOT replace its 'rect' property */
Rect *rect; VALUE rectObj;
Rect *rect;
rb_get_args(argc, argv, "o", &rectObj RB_ARG_END);
rb_get_args(argc, argv, "o", &rectObj RB_ARG_END);
rect = getPrivateDataCheck<Rect>(rectObj, RectType);
rect = getPrivateDataCheck<Rect>(rectObj, RectType);
v = new Viewport(rect);
} else { GFX_LOCK;
int x, y, width, height; v = new Viewport(rect);
} else {
rb_get_args(argc, argv, "iiii", &x, &y, &width, &height RB_ARG_END); int x, y, width, height;
v = new Viewport(x, y, width, height); rb_get_args(argc, argv, "iiii", &x, &y, &width, &height RB_ARG_END);
} GFX_LOCK;
v = new Viewport(x, y, width, height);
setPrivateData(self, v); }
/* Wrap property objects */ setPrivateData(self, v);
v->initDynAttribs();
/* Wrap property objects */
wrapProperty(self, &v->getRect(), "rect", RectType); v->initDynAttribs();
wrapProperty(self, &v->getColor(), "color", ColorType);
wrapProperty(self, &v->getTone(), "tone", ToneType); wrapProperty(self, &v->getRect(), "rect", RectType);
wrapProperty(self, &v->getColor(), "color", ColorType);
/* 'elements' holds all SceneElements that become children wrapProperty(self, &v->getTone(), "tone", ToneType);
* of this viewport, so we can dispose them when the viewport
* is disposed */ /* 'elements' holds all SceneElements that become children
rb_iv_set(self, "elements", rb_ary_new()); * of this viewport, so we can dispose them when the viewport
* is disposed */
return self; rb_iv_set(self, "elements", rb_ary_new());
GFX_UNLOCK;
return self;
} }
DEF_PROP_OBJ_VAL(Viewport, Rect, Rect, "rect") DEF_GFX_PROP_OBJ_VAL(Viewport, Rect, Rect, "rect")
DEF_PROP_OBJ_VAL(Viewport, Color, Color, "color") DEF_GFX_PROP_OBJ_VAL(Viewport, Color, Color, "color")
DEF_PROP_OBJ_VAL(Viewport, Tone, Tone, "tone") DEF_GFX_PROP_OBJ_VAL(Viewport, Tone, Tone, "tone")
DEF_PROP_I(Viewport, OX) DEF_GFX_PROP_I(Viewport, OX)
DEF_PROP_I(Viewport, OY) DEF_GFX_PROP_I(Viewport, OY)
void viewportBindingInit() { void viewportBindingInit() {
VALUE klass = rb_define_class("Viewport", rb_cObject); VALUE klass = rb_define_class("Viewport", rb_cObject);
#if RAPI_FULL > 187 #if RAPI_FULL > 187
rb_define_alloc_func(klass, classAllocate<&ViewportType>); rb_define_alloc_func(klass, classAllocate<&ViewportType>);
#else #else
rb_define_alloc_func(klass, ViewportAllocate); rb_define_alloc_func(klass, ViewportAllocate);
#endif #endif
disposableBindingInit<Viewport>(klass); disposableBindingInit<Viewport>(klass);
flashableBindingInit<Viewport>(klass); flashableBindingInit<Viewport>(klass);
sceneElementBindingInit<Viewport>(klass); sceneElementBindingInit<Viewport>(klass);
_rb_define_method(klass, "initialize", viewportInitialize); _rb_define_method(klass, "initialize", viewportInitialize);
INIT_PROP_BIND(Viewport, Rect, "rect"); INIT_PROP_BIND(Viewport, Rect, "rect");
INIT_PROP_BIND(Viewport, OX, "ox"); INIT_PROP_BIND(Viewport, OX, "ox");
INIT_PROP_BIND(Viewport, OY, "oy"); INIT_PROP_BIND(Viewport, OY, "oy");
INIT_PROP_BIND(Viewport, Color, "color"); INIT_PROP_BIND(Viewport, Color, "color");
INIT_PROP_BIND(Viewport, Tone, "tone"); INIT_PROP_BIND(Viewport, Tone, "tone");
} }

View file

@ -27,6 +27,7 @@
#include "binding-util.h" #include "binding-util.h"
#include "binding-types.h" #include "binding-types.h"
#include "debugwriter.h" #include "debugwriter.h"
#include "graphics.h"
#include "sceneelement-binding.h" #include "sceneelement-binding.h"
#include "disposable-binding.h" #include "disposable-binding.h"
@ -62,7 +63,7 @@ RB_METHOD(viewportElementSetViewport)
disposableAddChild(viewportObj, self); disposableAddChild(viewportObj, self);
} }
GUARD_EXC( ve->setViewport(viewport); ); GFX_GUARD_EXC( ve->setViewport(viewport); );
rb_iv_set(self, "viewport", viewportObj); rb_iv_set(self, "viewport", viewportObj);
@ -87,13 +88,14 @@ viewportElementInitialize(int argc, VALUE *argv, VALUE self)
disposableAddChild(viewportObj, self); disposableAddChild(viewportObj, self);
} }
GFX_LOCK;
/* Construct object */ /* Construct object */
C *ve = new C(viewport); C *ve = new C(viewport);
/* Set property objects */ /* Set property objects */
rb_iv_set(self, "viewport", viewportObj); rb_iv_set(self, "viewport", viewportObj);
GFX_UNLOCK;
return ve; return ve;
} }

View file

@ -31,6 +31,7 @@ DEF_ALLOCFUNC(Window);
#endif #endif
RB_METHOD(windowInitialize) { RB_METHOD(windowInitialize) {
GFX_LOCK;
Window *w = viewportElementInitialize<Window>(argc, argv, self); Window *w = viewportElementInitialize<Window>(argc, argv, self);
setPrivateData(self, w); setPrivateData(self, w);
@ -39,6 +40,7 @@ RB_METHOD(windowInitialize) {
wrapProperty(self, &w->getCursorRect(), "cursor_rect", RectType); wrapProperty(self, &w->getCursorRect(), "cursor_rect", RectType);
GFX_UNLOCK;
return self; return self;
} }
@ -47,28 +49,28 @@ RB_METHOD(windowUpdate) {
Window *w = getPrivateData<Window>(self); Window *w = getPrivateData<Window>(self);
GUARD_EXC(w->update();); GFX_GUARD_EXC(w->update(););
return Qnil; return Qnil;
} }
DEF_PROP_OBJ_REF(Window, Bitmap, Windowskin, "windowskin") DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_REF(Window, Bitmap, Contents, "contents") DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Contents, "contents")
DEF_PROP_OBJ_VAL(Window, Rect, CursorRect, "cursor_rect") DEF_GFX_PROP_OBJ_VAL(Window, Rect, CursorRect, "cursor_rect")
DEF_PROP_B(Window, Stretch) DEF_GFX_PROP_B(Window, Stretch)
DEF_PROP_B(Window, Active) DEF_GFX_PROP_B(Window, Active)
DEF_PROP_B(Window, Pause) DEF_GFX_PROP_B(Window, Pause)
DEF_PROP_I(Window, X) DEF_GFX_PROP_I(Window, X)
DEF_PROP_I(Window, Y) DEF_GFX_PROP_I(Window, Y)
DEF_PROP_I(Window, Width) DEF_GFX_PROP_I(Window, Width)
DEF_PROP_I(Window, Height) DEF_GFX_PROP_I(Window, Height)
DEF_PROP_I(Window, OX) DEF_GFX_PROP_I(Window, OX)
DEF_PROP_I(Window, OY) DEF_GFX_PROP_I(Window, OY)
DEF_PROP_I(Window, Opacity) DEF_GFX_PROP_I(Window, Opacity)
DEF_PROP_I(Window, BackOpacity) DEF_GFX_PROP_I(Window, BackOpacity)
DEF_PROP_I(Window, ContentsOpacity) DEF_GFX_PROP_I(Window, ContentsOpacity)
void windowBindingInit() { void windowBindingInit() {
VALUE klass = rb_define_class("Window", rb_cObject); VALUE klass = rb_define_class("Window", rb_cObject);

View file

@ -25,6 +25,7 @@
#include "windowvx.h" #include "windowvx.h"
#include "bitmap.h" #include "bitmap.h"
#include "graphics.h"
#if RAPI_FULL > 187 #if RAPI_FULL > 187
DEF_TYPE_CUSTOMNAME(WindowVX, "Window"); DEF_TYPE_CUSTOMNAME(WindowVX, "Window");
@ -37,6 +38,7 @@ void bitmapInitProps(Bitmap *b, VALUE self);
RB_METHOD(windowVXInitialize) { RB_METHOD(windowVXInitialize) {
WindowVX *w; WindowVX *w;
GFX_LOCK;
if (rgssVer >= 3) { if (rgssVer >= 3) {
int x, y, width, height; int x, y, width, height;
x = y = width = height = 0; x = y = width = height = 0;
@ -63,6 +65,7 @@ RB_METHOD(windowVXInitialize) {
bitmapInitProps(contents, contentsObj); bitmapInitProps(contents, contentsObj);
rb_iv_set(self, "contents", contentsObj); rb_iv_set(self, "contents", contentsObj);
GFX_UNLOCK;
return self; return self;
} }
@ -71,7 +74,9 @@ RB_METHOD(windowVXUpdate) {
WindowVX *w = getPrivateData<WindowVX>(self); WindowVX *w = getPrivateData<WindowVX>(self);
GFX_LOCK;
w->update(); w->update();
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -82,8 +87,10 @@ RB_METHOD(windowVXMove) {
int x, y, width, height; int x, y, width, height;
rb_get_args(argc, argv, "iiii", &x, &y, &width, &height RB_ARG_END); rb_get_args(argc, argv, "iiii", &x, &y, &width, &height RB_ARG_END);
GFX_LOCK;
w->move(x, y, width, height); w->move(x, y, width, height);
GFX_UNLOCK;
return Qnil; return Qnil;
} }
@ -103,28 +110,28 @@ RB_METHOD(windowVXIsClosed) {
return rb_bool_new(w->isClosed()); return rb_bool_new(w->isClosed());
} }
DEF_PROP_OBJ_REF(WindowVX, Bitmap, Windowskin, "windowskin") DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, Windowskin, "windowskin")
DEF_PROP_OBJ_REF(WindowVX, Bitmap, Contents, "contents") DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, Contents, "contents")
DEF_PROP_OBJ_VAL(WindowVX, Rect, CursorRect, "cursor_rect") DEF_GFX_PROP_OBJ_VAL(WindowVX, Rect, CursorRect, "cursor_rect")
DEF_PROP_OBJ_VAL(WindowVX, Tone, Tone, "tone") DEF_GFX_PROP_OBJ_VAL(WindowVX, Tone, Tone, "tone")
DEF_PROP_I(WindowVX, X) DEF_GFX_PROP_I(WindowVX, X)
DEF_PROP_I(WindowVX, Y) DEF_GFX_PROP_I(WindowVX, Y)
DEF_PROP_I(WindowVX, OX) DEF_GFX_PROP_I(WindowVX, OX)
DEF_PROP_I(WindowVX, OY) DEF_GFX_PROP_I(WindowVX, OY)
DEF_PROP_I(WindowVX, Width) DEF_GFX_PROP_I(WindowVX, Width)
DEF_PROP_I(WindowVX, Height) DEF_GFX_PROP_I(WindowVX, Height)
DEF_PROP_I(WindowVX, Padding) DEF_GFX_PROP_I(WindowVX, Padding)
DEF_PROP_I(WindowVX, PaddingBottom) DEF_GFX_PROP_I(WindowVX, PaddingBottom)
DEF_PROP_I(WindowVX, Opacity) DEF_GFX_PROP_I(WindowVX, Opacity)
DEF_PROP_I(WindowVX, BackOpacity) DEF_GFX_PROP_I(WindowVX, BackOpacity)
DEF_PROP_I(WindowVX, ContentsOpacity) DEF_GFX_PROP_I(WindowVX, ContentsOpacity)
DEF_PROP_I(WindowVX, Openness) DEF_GFX_PROP_I(WindowVX, Openness)
DEF_PROP_B(WindowVX, Active) DEF_GFX_PROP_B(WindowVX, Active)
DEF_PROP_B(WindowVX, ArrowsVisible) DEF_GFX_PROP_B(WindowVX, ArrowsVisible)
DEF_PROP_B(WindowVX, Pause) DEF_GFX_PROP_B(WindowVX, Pause)
void windowVXBindingInit() { void windowVXBindingInit() {
VALUE klass = rb_define_class("Window", rb_cObject); VALUE klass = rb_define_class("Window", rb_cObject);

View file

@ -762,7 +762,7 @@ int Bitmap::height() const
bool Bitmap::isMega() const{ bool Bitmap::isMega() const{
guardDisposed(); guardDisposed();
return p->megaSurface || p->animation.enabled; return p->megaSurface;
} }
bool Bitmap::isAnimated() const { bool Bitmap::isAnimated() const {

View file

@ -45,6 +45,7 @@
#include <SDL_timer.h> #include <SDL_timer.h>
#include <SDL_video.h> #include <SDL_video.h>
#include <SDL_mutex.h> #include <SDL_mutex.h>
#include <SDL_thread.h>
#ifdef MKXPZ_STEAM #ifdef MKXPZ_STEAM
#include "steamshim_child.h" #include "steamshim_child.h"
@ -609,25 +610,18 @@ struct GraphicsPrivate {
return ret; return ret;
} }
void lockResources() { void setLock() {
SDL_LockMutex(glResourceLock); SDL_LockMutex(glResourceLock);
SDL_GL_MakeCurrent(threadData->window, glCtx); SDL_GL_MakeCurrent(threadData->window, threadData->glContext);
} }
void unlockResources() { void releaseLock() {
SDL_UnlockMutex(glResourceLock); SDL_UnlockMutex(glResourceLock);
} }
}; };
#define GRAPHICS_THREAD_LOCK(exp) \
p->lockResources(); \
{ \
exp \
}
Graphics::Graphics(RGSSThreadData *data) { Graphics::Graphics(RGSSThreadData *data) {
p = new GraphicsPrivate(data); p = new GraphicsPrivate(data);
// To appease people who don't want players to have // To appease people who don't want players to have
// emulator-like speedups // emulator-like speedups
// Nothing stops anybody from building with this // Nothing stops anybody from building with this
@ -660,8 +654,8 @@ unsigned long long Graphics::lastUpdate() {
return p->last_update; return p->last_update;
} }
void Graphics::update() {GRAPHICS_THREAD_LOCK( void Graphics::update() {
p->last_update = shState->runTime(); p->last_update = shState->runTime();
p->checkShutDownReset(); p->checkShutDownReset();
p->checkSyncLock(); p->checkSyncLock();
@ -691,9 +685,9 @@ void Graphics::update() {GRAPHICS_THREAD_LOCK(
p->checkResize(); p->checkResize();
p->redrawScreen(); p->redrawScreen();
)} }
void Graphics::freeze() {GRAPHICS_THREAD_LOCK( void Graphics::freeze() {
p->frozen = true; p->frozen = true;
p->checkShutDownReset(); p->checkShutDownReset();
@ -701,9 +695,9 @@ void Graphics::freeze() {GRAPHICS_THREAD_LOCK(
/* Capture scene into frozen buffer */ /* Capture scene into frozen buffer */
p->compositeToBuffer(p->frozenScene); p->compositeToBuffer(p->frozenScene);
)} }
void Graphics::transition(int duration, const char *filename, int vague) {GRAPHICS_THREAD_LOCK( void Graphics::transition(int duration, const char *filename, int vague) {
p->checkSyncLock(); p->checkSyncLock();
if (!p->frozen) if (!p->frozen)
@ -804,9 +798,9 @@ void Graphics::transition(int duration, const char *filename, int vague) {GRAPHI
delete transMap; delete transMap;
p->frozen = false; p->frozen = false;
)} }
void Graphics::frameReset() {GRAPHICS_THREAD_LOCK(p->fpsLimiter.resetFrameAdjust();)} void Graphics::frameReset() {p->fpsLimiter.resetFrameAdjust();}
static void guardDisposed() {} static void guardDisposed() {}
@ -814,7 +808,7 @@ DEF_ATTR_RD_SIMPLE(Graphics, FrameRate, int, p->frameRate)
DEF_ATTR_SIMPLE(Graphics, FrameCount, int, p->frameCount) DEF_ATTR_SIMPLE(Graphics, FrameCount, int, p->frameCount)
void Graphics::setFrameRate(int value) {GRAPHICS_THREAD_LOCK( void Graphics::setFrameRate(int value) {
p->frameRate = clamp(value, 10, 120); p->frameRate = clamp(value, 10, 120);
if (p->threadData->config.syncToRefreshrate) if (p->threadData->config.syncToRefreshrate)
@ -825,20 +819,20 @@ void Graphics::setFrameRate(int value) {GRAPHICS_THREAD_LOCK(
p->fpsLimiter.setDesiredFPS(p->frameRate); p->fpsLimiter.setDesiredFPS(p->frameRate);
shState->input().recalcRepeat((unsigned int)p->frameRate); shState->input().recalcRepeat((unsigned int)p->frameRate);
)} }
double Graphics::averageFrameRate() { double Graphics::averageFrameRate() {
return p->averageFPS(); return p->averageFPS();
} }
void Graphics::wait(int duration) {GRAPHICS_THREAD_LOCK( void Graphics::wait(int duration) {
for (int i = 0; i < duration; ++i) { for (int i = 0; i < duration; ++i) {
p->checkShutDownReset(); p->checkShutDownReset();
p->redrawScreen(); p->redrawScreen();
} }
)} }
void Graphics::fadeout(int duration) {GRAPHICS_THREAD_LOCK( void Graphics::fadeout(int duration) {
FBO::unbind(); FBO::unbind();
float curr = p->brightness; float curr = p->brightness;
@ -861,9 +855,9 @@ void Graphics::fadeout(int duration) {GRAPHICS_THREAD_LOCK(
update(); update();
} }
} }
)} }
void Graphics::fadein(int duration) {GRAPHICS_THREAD_LOCK( void Graphics::fadein(int duration) {
FBO::unbind(); FBO::unbind();
float curr = p->brightness; float curr = p->brightness;
@ -886,17 +880,15 @@ void Graphics::fadein(int duration) {GRAPHICS_THREAD_LOCK(
update(); update();
} }
} }
)} }
Bitmap *Graphics::snapToBitmap() { Bitmap *Graphics::snapToBitmap() {
Bitmap *bitmap = new Bitmap(width(), height()); Bitmap *bitmap = new Bitmap(width(), height());
p->compositeToBuffer(bitmap->getGLTypes());
GRAPHICS_THREAD_LOCK( /* Taint entire bitmap */
p->compositeToBuffer(bitmap->getGLTypes()); bitmap->taintArea(IntRect(0, 0, width(), height()));
/* Taint entire bitmap */
bitmap->taintArea(IntRect(0, 0, width(), height()));
);
return bitmap; return bitmap;
} }
@ -904,7 +896,7 @@ int Graphics::width() const { return p->scRes.x; }
int Graphics::height() const { return p->scRes.y; } int Graphics::height() const { return p->scRes.y; }
void Graphics::resizeScreen(int width, int height) {GRAPHICS_THREAD_LOCK( void Graphics::resizeScreen(int width, int height) {
// width = clamp(width, 1, 640); // width = clamp(width, 1, 640);
// height = clamp(height, 1, 480); // height = clamp(height, 1, 480);
@ -929,19 +921,19 @@ void Graphics::resizeScreen(int width, int height) {GRAPHICS_THREAD_LOCK(
p->threadData->rqWindowAdjust.set(); p->threadData->rqWindowAdjust.set();
shState->eThread().requestWindowResize(width, height); shState->eThread().requestWindowResize(width, height);
update(); update();
)} }
void Graphics::playMovie(const char *filename) { void Graphics::playMovie(const char *filename) {
Debug() << "Graphics.playMovie(" << filename << ") not implemented"; Debug() << "Graphics.playMovie(" << filename << ") not implemented";
} }
void Graphics::screenshot(const char *filename) {GRAPHICS_THREAD_LOCK( void Graphics::screenshot(const char *filename) {
p->threadData->rqWindowAdjust.wait(); p->threadData->rqWindowAdjust.wait();
Bitmap *ss = snapToBitmap(); Bitmap *ss = snapToBitmap();
ss->saveToFile(filename); ss->saveToFile(filename);
ss->dispose(); ss->dispose();
delete ss; delete ss;
)} }
DEF_ATTR_RD_SIMPLE(Graphics, Brightness, int, p->brightness) DEF_ATTR_RD_SIMPLE(Graphics, Brightness, int, p->brightness)
@ -955,7 +947,7 @@ void Graphics::setBrightness(int value) {
p->screen.setBrightness(value / 255.0); p->screen.setBrightness(value / 255.0);
} }
void Graphics::reset() {GRAPHICS_THREAD_LOCK( void Graphics::reset() {
/* Dispose all live Disposables */ /* Dispose all live Disposables */
IntruListLink<Disposable> *iter; IntruListLink<Disposable> *iter;
@ -973,35 +965,35 @@ void Graphics::reset() {GRAPHICS_THREAD_LOCK(
setFrameRate(DEF_FRAMERATE); setFrameRate(DEF_FRAMERATE);
setBrightness(255); setBrightness(255);
)} }
void Graphics::center() {GRAPHICS_THREAD_LOCK( void Graphics::center() {
if (getFullscreen()) if (getFullscreen())
return; return;
p->threadData->rqWindowAdjust.reset(); p->threadData->rqWindowAdjust.reset();
p->threadData->ethread->requestWindowCenter(); p->threadData->ethread->requestWindowCenter();
)} }
bool Graphics::getFullscreen() const { bool Graphics::getFullscreen() const {
return p->threadData->ethread->getFullscreen(); return p->threadData->ethread->getFullscreen();
} }
void Graphics::setFullscreen(bool value) {GRAPHICS_THREAD_LOCK( void Graphics::setFullscreen(bool value) {
p->threadData->ethread->requestFullscreenMode(value); p->threadData->ethread->requestFullscreenMode(value);
)} }
bool Graphics::getShowCursor() const { bool Graphics::getShowCursor() const {
return p->threadData->ethread->getShowCursor(); return p->threadData->ethread->getShowCursor();
} }
void Graphics::setShowCursor(bool value) {GRAPHICS_THREAD_LOCK( void Graphics::setShowCursor(bool value) {
p->threadData->ethread->requestShowCursor(value); p->threadData->ethread->requestShowCursor(value);
)} }
double Graphics::getScale() const { return (double)p->scSize.y / p->scRes.y; } double Graphics::getScale() const { return (double)p->scSize.y / p->scRes.y; }
void Graphics::setScale(double factor) {GRAPHICS_THREAD_LOCK( void Graphics::setScale(double factor) {
p->threadData->rqWindowAdjust.wait(); p->threadData->rqWindowAdjust.wait();
factor = clamp(factor, 0.5, 2.0); factor = clamp(factor, 0.5, 2.0);
@ -1014,7 +1006,7 @@ void Graphics::setScale(double factor) {GRAPHICS_THREAD_LOCK(
p->threadData->rqWindowAdjust.set(); p->threadData->rqWindowAdjust.set();
shState->eThread().requestWindowResize(widthpx, heightpx); shState->eThread().requestWindowResize(widthpx, heightpx);
update(); update();
)} }
bool Graphics::getFrameskip() const { return p->useFrameSkip; } bool Graphics::getFrameskip() const { return p->useFrameSkip; }
@ -1048,13 +1040,12 @@ void Graphics::repaintWait(const AtomicFlag &exitCond, bool checkReset) {
GLMeta::blitEnd(); GLMeta::blitEnd();
} }
void Graphics::lockResources(bool lock) { void Graphics::lock() {
if (lock) { p->setLock();
p->lockResources(); }
return;
} void Graphics::unlock() {
p->releaseLock();
p->unlockResources();
} }
void Graphics::addDisposable(Disposable *d) { p->dispList.append(d->link); } void Graphics::addDisposable(Disposable *d) { p->dispList.append(d->link); }

View file

@ -78,7 +78,8 @@ public:
void repaintWait(const AtomicFlag &exitCond, void repaintWait(const AtomicFlag &exitCond,
bool checkReset = true); bool checkReset = true);
void lockResources(bool lock); void lock();
void unlock();
private: private:
Graphics(RGSSThreadData *data); Graphics(RGSSThreadData *data);
@ -93,10 +94,7 @@ private:
GraphicsPrivate *p; GraphicsPrivate *p;
}; };
#define GFX_BLOCK(exp) \ #define GFX_LOCK shState->graphics().lock()
shState->graphics().lockResources(true); \ #define GFX_UNLOCK shState->graphics().unlock()
{ \
exp \
}
#endif // GRAPHICS_H #endif // GRAPHICS_H

View file

@ -147,9 +147,11 @@ HTTPResponse HTTPRequest::get() {
else { else {
int err = result.error(); int err = result.error();
const char *errname = httpErrorNames[err]; const char *errname = httpErrorNames[err];
delete client;
throw Exception(Exception::MKXPError, "Failed to GET %s (%i: %s)", destination.c_str(), err, errname); throw Exception(Exception::MKXPError, "Failed to GET %s (%i: %s)", destination.c_str(), err, errname);
} }
delete client;
return ret; return ret;
} }
@ -192,8 +194,10 @@ HTTPResponse HTTPRequest::post(StringMap &postData) {
else { else {
int err = result.error(); int err = result.error();
const char *errname = httpErrorNames[err]; const char *errname = httpErrorNames[err];
delete client;
throw Exception(Exception::MKXPError, "Failed to POST %s (%i: %s)", destination.c_str(), err, errname); throw Exception(Exception::MKXPError, "Failed to POST %s (%i: %s)", destination.c_str(), err, errname);
} }
delete client;
return ret; return ret;
} }
@ -231,7 +235,9 @@ HTTPResponse HTTPRequest::post(const char *body, const char *content_type) {
} }
else { else {
int err = result.error(); int err = result.error();
delete client;
throw Exception(Exception::MKXPError, "Failed to POST %s (%i: %s)", destination.c_str(), err, httpErrorNames[err]); throw Exception(Exception::MKXPError, "Failed to POST %s (%i: %s)", destination.c_str(), err, httpErrorNames[err]);
} }
delete client;
return ret; return ret;
} }