Stub out more of the sprite bindings for binding-sandbox

This commit is contained in:
刘皓 2025-02-05 22:30:04 -05:00
parent 44da7c5f9c
commit 1e42180fa2
No known key found for this signature in database
GPG key ID: 7901753DB465B711
8 changed files with 314 additions and 1 deletions

View file

@ -77,6 +77,19 @@ namespace mkxp_sandbox {
return sb()->bind<struct coro>()()(argc, argv, self);
}
static VALUE dispose(VALUE self) {
Bitmap *bitmap = get_private_data<Bitmap>(self);
if (bitmap != NULL) {
bitmap->dispose();
}
return SANDBOX_NIL;
}
static VALUE disposed(VALUE self) {
Bitmap *bitmap = get_private_data<Bitmap>(self);
return bitmap == NULL || bitmap->isDisposed() ? SANDBOX_TRUE : SANDBOX_FALSE;
}
static VALUE clear(VALUE self) {
GFX_GUARD_EXC(get_private_data<Bitmap>(self)->clear());
return SANDBOX_NIL;
@ -182,6 +195,8 @@ namespace mkxp_sandbox {
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Bitmap", sb()->rb_cObject());
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
SANDBOX_AWAIT(rb_define_method, klass, "dispose", (VALUE (*)(ANYARGS))dispose, 0);
SANDBOX_AWAIT(rb_define_method, klass, "disposed?", (VALUE (*)(ANYARGS))disposed, 0);
SANDBOX_AWAIT(rb_define_method, klass, "clear", (VALUE (*)(ANYARGS))clear, 0);
SANDBOX_AWAIT(rb_define_method, klass, "fill_rect", (VALUE (*)(ANYARGS))fill_rect, -1);
SANDBOX_AWAIT(rb_define_method, klass, "draw_text", (VALUE (*)(ANYARGS))draw_text, -1);

View file

@ -44,6 +44,10 @@ namespace mkxp_sandbox {
return SANDBOX_NIL;
}
static VALUE todo_number(int32_t argc, wasm_ptr_t argv, VALUE self) {
return sb()->bind<struct rb_ll2inum>()()(0);
}
VALUE module;
void operator()() {
@ -53,6 +57,8 @@ namespace mkxp_sandbox {
SANDBOX_AWAIT(rb_define_module_function, module, "freeze", (VALUE (*)(ANYARGS))todo, -1);
SANDBOX_AWAIT(rb_define_module_function, module, "transition", (VALUE (*)(ANYARGS))todo, -1);
SANDBOX_AWAIT(rb_define_module_function, module, "frame_reset", (VALUE (*)(ANYARGS))todo, -1);
SANDBOX_AWAIT(rb_define_module_function, module, "frame_count", (VALUE (*)(ANYARGS))todo_number, -1);
SANDBOX_AWAIT(rb_define_module_function, module, "frame_count=", (VALUE (*)(ANYARGS))todo, -1);
}
}
)

View file

@ -33,6 +33,151 @@ namespace mkxp_sandbox {
SANDBOX_DEF_ALLOC(sprite_type)
SANDBOX_DEF_DFREE(Sprite)
static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_COROUTINE(coro,
Sprite *sprite;
VALUE viewport_obj;
Viewport *viewport;
ID id;
VALUE klass;
VALUE obj;
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
viewport_obj = SANDBOX_NIL;
viewport = NULL;
if (argc > 0) {
viewport_obj = *(VALUE *)(**sb() + argv);
if (viewport_obj != SANDBOX_NIL) {
viewport = get_private_data<Viewport>(viewport_obj);
}
}
GFX_LOCK
sprite = new Sprite(viewport);
SANDBOX_AWAIT(rb_iv_set, self, "viewport", viewport_obj);
set_private_data(self, sprite);
sprite->initDynAttribs();
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Rect");
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
SANDBOX_AWAIT_AND_SET(obj, rb_class_new_instance, 0, NULL, klass);
set_private_data(obj, &sprite->getSrcRect());
SANDBOX_AWAIT(rb_iv_set, self, "src_rect", obj);
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
SANDBOX_AWAIT_AND_SET(obj, rb_class_new_instance, 0, NULL, klass);
set_private_data(obj, &sprite->getColor());
SANDBOX_AWAIT(rb_iv_set, self, "color", obj);
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Tone");
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
SANDBOX_AWAIT_AND_SET(obj, rb_class_new_instance, 0, NULL, klass);
set_private_data(obj, &sprite->getTone());
SANDBOX_AWAIT(rb_iv_set, self, "tone", obj);
GFX_UNLOCK
}
return SANDBOX_NIL;
}
)
return sb()->bind<struct coro>()()(argc, argv, self);
}
static VALUE dispose(VALUE self) {
Sprite *sprite = get_private_data<Sprite>(self);
if (sprite != NULL) {
sprite->dispose();
}
return SANDBOX_NIL;
}
static VALUE disposed(VALUE self) {
Sprite *sprite = get_private_data<Sprite>(self);
return sprite == NULL || sprite->isDisposed() ? SANDBOX_TRUE : SANDBOX_FALSE;
}
static VALUE get_bitmap(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "bitmap");
}
static VALUE set_bitmap(VALUE self, VALUE value) {
SANDBOX_COROUTINE(coro,
VALUE operator()(VALUE self, VALUE value) {
BOOST_ASIO_CORO_REENTER (this) {
GFX_GUARD_EXC(get_private_data<Sprite>(self)->setBitmap(get_private_data<Bitmap>(value)));
SANDBOX_AWAIT(rb_iv_set, self, "bitmap", value);
}
return value;
}
)
return sb()->bind<struct coro>()()(self, value);
}
static VALUE get_src_rect(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "src_rect");
}
static VALUE set_src_rect(VALUE self, VALUE value) {
SANDBOX_COROUTINE(coro,
VALUE operator()(VALUE self, VALUE value) {
BOOST_ASIO_CORO_REENTER (this) {
GFX_GUARD_EXC(get_private_data<Sprite>(self)->setSrcRect(*get_private_data<Rect>(value)));
SANDBOX_AWAIT(rb_iv_set, self, "src_rect", value);
}
return value;
}
)
return sb()->bind<struct coro>()()(self, value);
}
static VALUE get_color(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "color");
}
static VALUE set_color(VALUE self, VALUE value) {
SANDBOX_COROUTINE(coro,
VALUE operator()(VALUE self, VALUE value) {
BOOST_ASIO_CORO_REENTER (this) {
GFX_GUARD_EXC(get_private_data<Sprite>(self)->setColor(*get_private_data<Color>(value)));
SANDBOX_AWAIT(rb_iv_set, self, "color", value);
}
return value;
}
)
return sb()->bind<struct coro>()()(self, value);
}
static VALUE get_tone(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(self, "tone");
}
static VALUE set_tone(VALUE self, VALUE value) {
SANDBOX_COROUTINE(coro,
VALUE operator()(VALUE self, VALUE value) {
BOOST_ASIO_CORO_REENTER (this) {
GFX_GUARD_EXC(get_private_data<Sprite>(self)->setTone(*get_private_data<Tone>(value)));
SANDBOX_AWAIT(rb_iv_set, self, "tone", value);
}
return value;
}
)
return sb()->bind<struct coro>()()(self, value);
}
static VALUE todo(int32_t argc, wasm_ptr_t argv, VALUE self) {
return SANDBOX_NIL;
}
@ -44,7 +189,17 @@ namespace mkxp_sandbox {
sprite_type = sb()->rb_data_type("Sprite", NULL, dfree, NULL, NULL, 0, 0, 0);
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Sprite", sb()->rb_cObject());
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
SANDBOX_AWAIT(rb_define_method, klass, "bitmap=", (VALUE (*)(ANYARGS))todo, -1);
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
SANDBOX_AWAIT(rb_define_method, klass, "dispose", (VALUE (*)(ANYARGS))dispose, 0);
SANDBOX_AWAIT(rb_define_method, klass, "disposed?", (VALUE (*)(ANYARGS))disposed, 0);
SANDBOX_AWAIT(rb_define_method, klass, "bitmap", (VALUE (*)(ANYARGS))get_bitmap, 0);
SANDBOX_AWAIT(rb_define_method, klass, "bitmap=", (VALUE (*)(ANYARGS))set_bitmap, 1);
SANDBOX_AWAIT(rb_define_method, klass, "src_rect", (VALUE (*)(ANYARGS))get_src_rect, 0);
SANDBOX_AWAIT(rb_define_method, klass, "src_rect=", (VALUE (*)(ANYARGS))set_src_rect, 1);
SANDBOX_AWAIT(rb_define_method, klass, "color", (VALUE (*)(ANYARGS))get_color, 0);
SANDBOX_AWAIT(rb_define_method, klass, "color=", (VALUE (*)(ANYARGS))set_color, 1);
SANDBOX_AWAIT(rb_define_method, klass, "tone", (VALUE (*)(ANYARGS))get_tone, 0);
SANDBOX_AWAIT(rb_define_method, klass, "tone=", (VALUE (*)(ANYARGS))set_tone, 1);
}
}
)

View file

@ -22,6 +22,7 @@
#ifndef MKXPZ_SANDBOX_TABLE_BINDING_H
#define MKXPZ_SANDBOX_TABLE_BINDING_H
#include <algorithm>
#include "sandbox.h"
#include "table.h"
#include "binding-util.h"
@ -34,6 +35,78 @@ namespace mkxp_sandbox {
SANDBOX_DEF_DFREE(Table)
SANDBOX_DEF_LOAD(Table)
static VALUE get(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_COROUTINE(coro,
Table *table;
VALUE value;
int32_t x;
int32_t y;
int32_t z;
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
table = get_private_data<Table>(self);
y = z = 0;
SANDBOX_AWAIT_AND_SET(x, rb_num2int, ((VALUE *)(**sb() + argv))[0]);
if (argc >= 2) {
SANDBOX_AWAIT_AND_SET(y, rb_num2int, ((VALUE *)(**sb() + argv))[1]);
if (argc >= 3) {
SANDBOX_AWAIT_AND_SET(z, rb_num2int, ((VALUE *)(**sb() + argv))[2]);
// TODO: throw error if too many arguments
}
}
if (x < 0 || x >= table->xSize() || y < 0 || y >= table->ySize() || z < 0 || z >= table->zSize()) {
value = SANDBOX_NIL;
} else {
SANDBOX_AWAIT_AND_SET(value, rb_ll2inum, table->get(x, y, z));
}
}
return value;
}
)
return sb()->bind<struct coro>()()(argc, argv, self);
}
static VALUE set(int32_t argc, wasm_ptr_t argv, VALUE self) {
SANDBOX_COROUTINE(coro,
Table *table;
int32_t x;
int32_t y;
int32_t z;
int16_t v;
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
BOOST_ASIO_CORO_REENTER (this) {
table = get_private_data<Table>(self);
y = z = 0;
// TODO: throw error if too few arguments
SANDBOX_AWAIT_AND_SET(x, rb_num2int, ((VALUE *)(**sb() + argv))[0]);
if (argc >= 3) {
SANDBOX_AWAIT_AND_SET(y, rb_num2int, ((VALUE *)(**sb() + argv))[1]);
if (argc >= 4) {
SANDBOX_AWAIT_AND_SET(z, rb_num2int, ((VALUE *)(**sb() + argv))[2]);
}
}
SANDBOX_AWAIT_AND_SET(v, rb_num2int, ((VALUE *)(**sb() + argv))[std::min(argc, 4) - 1]);
table->set(v, x, y, z);
return ((VALUE *)(**sb() + argv))[std::min(argc, 4) - 1];
}
return SANDBOX_UNDEF;
}
)
return sb()->bind<struct coro>()()(argc, argv, self);
}
VALUE klass;
void operator()() {
@ -42,6 +115,8 @@ namespace mkxp_sandbox {
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Table", sb()->rb_cObject());
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
SANDBOX_AWAIT(rb_define_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1);
SANDBOX_AWAIT(rb_define_method, klass, "[]", (VALUE (*)(ANYARGS))get, -1);
SANDBOX_AWAIT(rb_define_method, klass, "[]=", (VALUE (*)(ANYARGS))set, -1);
}
}
)

View file

@ -74,6 +74,19 @@ namespace mkxp_sandbox {
return sb()->bind<struct coro>()()(argc, argv, self);
}
static VALUE dispose(VALUE self) {
Window *window = get_private_data<Window>(self);
if (window != NULL) {
window->dispose();
}
return SANDBOX_NIL;
}
static VALUE disposed(VALUE self) {
Window *window = get_private_data<Window>(self);
return window == NULL || window->isDisposed() ? SANDBOX_TRUE : SANDBOX_FALSE;
}
static VALUE update(VALUE self) {
GFX_GUARD_EXC(get_private_data<Window>(self)->update();)
return SANDBOX_NIL;
@ -328,6 +341,8 @@ namespace mkxp_sandbox {
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
SANDBOX_AWAIT(rb_define_method, klass, "update", (VALUE (*)(ANYARGS))update, 0);
SANDBOX_AWAIT(rb_define_method, klass, "dispose", (VALUE (*)(ANYARGS))dispose, 0);
SANDBOX_AWAIT(rb_define_method, klass, "disposed?", (VALUE (*)(ANYARGS))disposed, 0);
SANDBOX_AWAIT(rb_define_method, klass, "windowskin=", (VALUE (*)(ANYARGS))todo, -1);
SANDBOX_AWAIT(rb_define_method, klass, "contents", (VALUE (*)(ANYARGS))get_contents, 0);
SANDBOX_AWAIT(rb_define_method, klass, "contents=", (VALUE (*)(ANYARGS))set_contents, 1);

View file

@ -256,6 +256,7 @@ if get_option('retro') == true
'src/audio/vorbissource.cpp',
'src/crypto/rgssad.cpp',
'src/display/bitmap.cpp',
'src/display/sprite.cpp',
'src/display/viewport.cpp',
'src/display/window.cpp',
'src/display/gl/scene.cpp',

View file

@ -596,7 +596,9 @@ Bitmap::Bitmap(const char *filename)
handler.gif->width, handler.gif->height, glState.caps.maxTexSize, glState.caps.maxTexSize);
}
#endif // MKXPZ_RETRO
p = new BitmapPrivate(this);
#ifndef MKXPZ_RETRO
p->selfHires = hiresBitmap;

View file

@ -29,12 +29,14 @@
#include "etc-internal.h"
#include "util.h"
#ifndef MKXPZ_RETRO
#include "gl-util.h"
#include "quad.h"
#include "transform.h"
#include "shader.h"
#include "glstate.h"
#include "quadarray.h"
#endif // MKXPZ_RETRO
#include <math.h>
#ifndef M_PI
@ -51,8 +53,10 @@ struct SpritePrivate
sigslot::connection bitmapDispCon;
#ifndef MKXPZ_RETRO
Quad quad;
Transform trans;
#endif // MKXPZ_RETRO
Rect *srcRect;
sigslot::connection srcRectCon;
@ -94,7 +98,9 @@ struct SpritePrivate
bool active;
/* qArray needs updating */
bool dirty;
#ifndef MKXPZ_RETRO
SimpleQuadArray qArray;
#endif // MKXPZ_RETRO
} wave;
EtcTemps tmp;
@ -156,7 +162,11 @@ struct SpritePrivate
return;
/* Calculate effective (normalized) bush depth */
#ifdef MKXPZ_RETRO
float texBushDepth = bushDepth - // TODO
#else
float texBushDepth = (bushDepth / trans.getScale().y) -
#endif // MKXPZ_RETRO
(srcRect->y + srcRect->height) +
bitmap->height();
@ -183,6 +193,7 @@ struct SpritePrivate
rect.w = clamp<int>(rect.w, 0, bmSize.x-rect.x);
rect.h = clamp<int>(rect.h, 0, bmSize.y-rect.y);
#ifndef MKXPZ_RETRO
if (bmSizeHires.x && bmSizeHires.y && bmSize.x && bmSize.y)
{
FloatRect rectHires(rect.x * bmSizeHires.x / bmSize.x,
@ -197,6 +208,7 @@ struct SpritePrivate
}
quad.setPosRect(FloatRect(0, 0, rect.w, rect.h));
#endif // MKXPZ_RETRO
recomputeBushDepth();
wave.dirty = true;
@ -233,21 +245,28 @@ struct SpritePrivate
/* If sprite is zoomed/rotated, just opt out for now
* for simplicity's sake */
#ifndef MKXPZ_RETRO
const Vec2 &scale = trans.getScale();
if (scale.x != 1 || scale.y != 1 || trans.getRotation() != 0)
{
isVisible = true;
return;
}
#endif // MKXPZ_RETRO
IntRect self;
#ifndef MKXPZ_RETRO
self.setPos(trans.getPositionI() - (trans.getOriginI() + sceneOrig));
#endif // MKXPZ_RETRO
self.w = bitmap->width();
self.h = bitmap->height();
#ifndef MKXPZ_RETRO
isVisible = SDL_HasIntersection(&self, &sceneRect);
#endif // MKXPZ_RETRO
}
#ifndef MKXPZ_RETRO
void emitWaveChunk(SVertex *&vert, float phase, int width,
float zoomY, int chunkY, int chunkLength)
{
@ -331,12 +350,15 @@ struct SpritePrivate
wave.qArray.commit();
}
#endif // MKXPZ_RETRO
void prepare()
{
if (wave.dirty)
{
#ifndef MKXPZ_RETRO
updateWave();
#endif // MKXPZ_RETRO
wave.dirty = false;
}
@ -357,6 +379,7 @@ Sprite::~Sprite()
}
DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap*, p->bitmap)
#ifndef MKXPZ_RETRO
DEF_ATTR_RD_SIMPLE(Sprite, X, int, p->trans.getPosition().x)
DEF_ATTR_RD_SIMPLE(Sprite, Y, int, p->trans.getPosition().y)
DEF_ATTR_RD_SIMPLE(Sprite, OX, int, p->trans.getOrigin().x)
@ -364,6 +387,7 @@ DEF_ATTR_RD_SIMPLE(Sprite, OY, int, p->trans.getOrigin().y)
DEF_ATTR_RD_SIMPLE(Sprite, ZoomX, float, p->trans.getScale().x)
DEF_ATTR_RD_SIMPLE(Sprite, ZoomY, float, p->trans.getScale().y)
DEF_ATTR_RD_SIMPLE(Sprite, Angle, float, p->trans.getRotation())
#endif // MKXPZ_RETRO
DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored)
DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth)
DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType)
@ -412,7 +436,9 @@ void Sprite::setBitmap(Bitmap *bitmap)
*p->srcRect = bitmap->rect();
p->onSrcRectChange();
#ifndef MKXPZ_RETRO
p->quad.setPosRect(p->srcRect->toFloatRect());
#endif // MKXPZ_RETRO
p->wave.dirty = true;
}
@ -421,20 +447,24 @@ void Sprite::setX(int value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getPosition().x == value)
return;
p->trans.setPosition(Vec2(value, getY()));
#endif // MKXPZ_RETRO
}
void Sprite::setY(int value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getPosition().y == value)
return;
p->trans.setPosition(Vec2(getX(), value));
#endif // MKXPZ_RETRO
if (rgssVer >= 2)
{
@ -447,40 +477,48 @@ void Sprite::setOX(int value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getOrigin().x == value)
return;
p->trans.setOrigin(Vec2(value, getOY()));
#endif // MKXPZ_RETRO
}
void Sprite::setOY(int value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getOrigin().y == value)
return;
p->trans.setOrigin(Vec2(getOX(), value));
#endif // MKXPZ_RETRO
}
void Sprite::setZoomX(float value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getScale().x == value)
return;
p->trans.setScale(Vec2(value, getZoomY()));
#endif // MKXPZ_RETRO
}
void Sprite::setZoomY(float value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getScale().y == value)
return;
p->trans.setScale(Vec2(getZoomX(), value));
#endif // MKXPZ_RETRO
p->recomputeBushDepth();
if (rgssVer >= 2)
@ -491,10 +529,12 @@ void Sprite::setAngle(float value)
{
guardDisposed();
#ifndef MKXPZ_RETRO
if (p->trans.getRotation() == value)
return;
p->trans.setRotation(value);
#endif // MKXPZ_RETRO
}
void Sprite::setMirror(bool mirrored)
@ -616,6 +656,7 @@ void Sprite::draw()
if (emptyFlashFlag)
return;
#ifndef MKXPZ_RETRO
ShaderBase *base;
bool renderEffect = p->color->hasEffect() ||
@ -802,13 +843,16 @@ void Sprite::draw()
TEX::setSmooth(false);
glState.blendMode.pop();
#endif // MKXPZ_RETRO
}
void Sprite::onGeometryChange(const Scene::Geometry &geo)
{
/* Offset at which the sprite will be drawn
* relative to screen origin */
#ifndef MKXPZ_RETRO
p->trans.setGlobalOffset(geo.offset());
#endif // MKXPZ_RETRO
p->sceneRect.setSize(geo.rect.size());
p->sceneOrig = geo.orig;