diff --git a/binding-sandbox/binding-util.h b/binding-sandbox/binding-util.h index c1e68a95..f748c636 100644 --- a/binding-sandbox/binding-util.h +++ b/binding-sandbox/binding-util.h @@ -25,6 +25,8 @@ #include "binding-sandbox/core.h" #include "sandbox.h" +#define GFX_GUARD_EXC(exp) exp // TODO: implement + #define SANDBOX_DEF_ALLOC(rbtype) \ static VALUE alloc(VALUE _klass) { \ SANDBOX_COROUTINE(alloc, \ @@ -78,6 +80,11 @@ namespace mkxp_sandbox { // Given Ruby typed data `obj`, stores `ptr` into the private data field of `obj`. void set_private_data(VALUE obj, void *ptr); + // Given Ruby typed data `obj`, retrieves the private data field of `obj`. + template inline T *get_private_data(VALUE obj) { + return *(T **)(**sb() + *(wasm_ptr_t *)(**sb() + sb()->rtypeddata_data(obj))); + } + // Gets the length of a Ruby object. SANDBOX_COROUTINE(get_length, ID id; diff --git a/binding-sandbox/bitmap-binding.h b/binding-sandbox/bitmap-binding.h index df9f37f3..d94b7b9a 100644 --- a/binding-sandbox/bitmap-binding.h +++ b/binding-sandbox/bitmap-binding.h @@ -33,6 +33,40 @@ namespace mkxp_sandbox { SANDBOX_DEF_ALLOC(bitmap_type) SANDBOX_DEF_DFREE(Bitmap) + static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { + SANDBOX_COROUTINE(coro, + Bitmap *bitmap; + wasm_ptr_t filename; + wasm_size_t width; + wasm_size_t height; + + VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + if (argc == 1) { + SANDBOX_AWAIT_AND_SET(filename, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + GFX_GUARD_EXC(bitmap = new Bitmap((const char *)(**sb() + filename));) + } else { + SANDBOX_AWAIT_AND_SET(width, rb_num2ulong, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_AND_SET(height, rb_num2ulong, ((VALUE *)(**sb() + argv))[1]); + GFX_GUARD_EXC(bitmap = new Bitmap(width, height);) + } + + set_private_data(self, bitmap); + //SANDBOX_AWAIT(init_props, bitmap, self); // TODO: implement + } + + return self; + } + ) + + return sb()->bind()()(argc, argv, self); + } + + static VALUE clear(VALUE self) { + GFX_GUARD_EXC(get_private_data(self)->clear()); + return self; + } + VALUE klass; void operator()() { @@ -40,6 +74,8 @@ namespace mkxp_sandbox { bitmap_type = sb()->rb_data_type("Bitmap", NULL, dfree, NULL, NULL, 0, 0, 0); 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, "clear", (VALUE (*)(ANYARGS))clear, 0); } } ) diff --git a/binding-sandbox/etc-binding.h b/binding-sandbox/etc-binding.h index b4a6e2ff..20ac7f85 100644 --- a/binding-sandbox/etc-binding.h +++ b/binding-sandbox/etc-binding.h @@ -33,10 +33,44 @@ namespace mkxp_sandbox { SANDBOX_COROUTINE(etc_binding_init, SANDBOX_COROUTINE(color_binding_init, - SANDBOX_DEF_ALLOC_WITH_INIT(color_type, new Color()) + SANDBOX_DEF_ALLOC(color_type) SANDBOX_DEF_DFREE(Color) SANDBOX_DEF_LOAD(Color) + static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { + SANDBOX_COROUTINE(coro, + Color *color; + double red; + double green; + double blue; + double alpha; + + VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + if (argc == 0) { + color = new Color(); + } else { + SANDBOX_AWAIT_AND_SET(red, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_AND_SET(green, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_AND_SET(blue, rb_num2dbl, ((VALUE *)(**sb() + argv))[2]); + if (argc <= 3) { + color = new Color(red, green, blue); + } else { + SANDBOX_AWAIT_AND_SET(alpha, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + color = new Color(red, green, blue, alpha); + } + } + + set_private_data(self, color); + } + + return self; + } + ) + + return sb()->bind()()(argc, argv, self); + } + VALUE klass; void operator()() { @@ -44,6 +78,7 @@ namespace mkxp_sandbox { color_type = sb()->rb_data_type("Color", NULL, dfree, NULL, NULL, 0, 0, 0); SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Color", 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_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1); } } diff --git a/binding-sandbox/sprite-binding.h b/binding-sandbox/sprite-binding.h index 6e705ec6..e29507fd 100644 --- a/binding-sandbox/sprite-binding.h +++ b/binding-sandbox/sprite-binding.h @@ -23,12 +23,28 @@ #define MKXPZ_SANDBOX_SPRITE_BINDING_H #include "sandbox.h" +#include "binding-util.h" +#include "sprite.h" namespace mkxp_sandbox { + static struct mkxp_sandbox::bindings::rb_data_type sprite_type; + SANDBOX_COROUTINE(sprite_binding_init, + SANDBOX_DEF_ALLOC(sprite_type) + SANDBOX_DEF_DFREE(Sprite) + + static VALUE todo(int32_t argc, wasm_ptr_t argv, VALUE self) { + return self; + } + + VALUE klass; + void operator()() { BOOST_ASIO_CORO_REENTER (this) { - SANDBOX_AWAIT(rb_define_class, "Sprite", sb()->rb_cObject()); + 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); } } ) diff --git a/binding-sandbox/window-binding.h b/binding-sandbox/window-binding.h index bb6677c6..5909c47b 100644 --- a/binding-sandbox/window-binding.h +++ b/binding-sandbox/window-binding.h @@ -23,12 +23,93 @@ #define MKXPZ_SANDBOX_WINDOW_BINDING_H #include "sandbox.h" +#include "binding-util.h" +#include "window.h" namespace mkxp_sandbox { + static struct mkxp_sandbox::bindings::rb_data_type window_type; + SANDBOX_COROUTINE(window_binding_init, + SANDBOX_DEF_ALLOC(window_type) + SANDBOX_DEF_DFREE(Window) + + static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { + SANDBOX_COROUTINE(coro, + Window *window; + VALUE viewport_obj; + Viewport *viewport; + VALUE klass; + + 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_obj); + } + } + + GFX_LOCK + window = new Window(viewport); + SANDBOX_AWAIT(rb_iv_set, self, "viewport", viewport_obj); + + set_private_data(self, window); + window->initDynAttribs(); + GFX_UNLOCK + } + + return self; + } + ) + + return sb()->bind()()(argc, argv, self); + } + + static VALUE get_contents(VALUE self) { + return sb()->bind()()(self, "contents"); + } + + static VALUE set_contents(VALUE self, VALUE value) { + SANDBOX_COROUTINE(coro, + VALUE operator()(VALUE self, VALUE value) { + BOOST_ASIO_CORO_REENTER (this) { + GFX_GUARD_EXC(get_private_data(self)->setContents(value == SANDBOX_NIL ? NULL : get_private_data(value))); + SANDBOX_AWAIT(rb_iv_set, self, "contents", value); + } + + return self; + } + ) + + return sb()->bind()()(self, value); + } + + static VALUE todo(int32_t argc, wasm_ptr_t argv, VALUE self) { + return self; + } + + VALUE klass; + void operator()() { BOOST_ASIO_CORO_REENTER (this) { - SANDBOX_AWAIT(rb_define_class, "Window", sb()->rb_cObject()); + window_type = sb()->rb_data_type("Window", NULL, dfree, NULL, NULL, 0, 0, 0); + SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Window", 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, "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); + SANDBOX_AWAIT(rb_define_method, klass, "stretch=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "cursor_rect=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "active=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "pause=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "x=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "y=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "width=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "height=", (VALUE (*)(ANYARGS))todo, -1); + SANDBOX_AWAIT(rb_define_method, klass, "z=", (VALUE (*)(ANYARGS))todo, -1); } } ) diff --git a/meson.build b/meson.build index 607ce136..b835abe5 100644 --- a/meson.build +++ b/meson.build @@ -162,6 +162,7 @@ if get_option('retro') == true include_directories('.'), include_directories('src'), include_directories('src/display'), + include_directories('src/display/gl'), include_directories('src/etc'), include_directories('src/util'), include_directories(retro_phase1), @@ -170,6 +171,11 @@ if get_option('retro') == true ], sources: [ 'src/core.cpp', + 'src/sharedstate.cpp', + 'src/display/bitmap.cpp', + 'src/display/viewport.cpp', + 'src/display/window.cpp', + 'src/display/gl/scene.cpp', 'src/etc/etc.cpp', 'src/etc/table.cpp', 'binding-sandbox/binding-util.cpp', diff --git a/retro/sandbox-bindgen.rb b/retro/sandbox-bindgen.rb index a0b5cd54..ae9405cd 100644 --- a/retro/sandbox-bindgen.rb +++ b/retro/sandbox-bindgen.rb @@ -60,6 +60,8 @@ ARG_HANDLERS = { 'unsigned long' => { primitive: :size }, 'long long' => { primitive: :s64 }, 'unsigned long long' => { primitive: :u64 }, + 'float' => { primitive: :f32 }, + 'double' => { primitive: :f64 }, 'const char *' => { keep: true, buf_size: 'std::strlen(ARG) + 1', @@ -127,6 +129,8 @@ RET_HANDLERS = { 'unsigned long' => { primitive: :size }, 'long long' => { primitive: :s64 }, 'unsigned long long' => { primitive: :u64 }, + 'float' => { primitive: :f32 }, + 'double' => { primitive: :f64 }, 'char *' => { primitive: :ptr }, 'const char *' => { primitive: :ptr }, } diff --git a/src/core.cpp b/src/core.cpp index e9e97e68..4173a802 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -109,6 +109,8 @@ static bool init_sandbox() { mkxp_retro::sandbox.reset(); + SharedState::initInstance(NULL); + try { mkxp_retro::sandbox.reset(new struct sandbox(game_path)); sb().run(); diff --git a/src/display/bitmap.cpp b/src/display/bitmap.cpp index cabfd6ff..2471e946 100644 --- a/src/display/bitmap.cpp +++ b/src/display/bitmap.cpp @@ -21,6 +21,7 @@ #include "bitmap.h" +#ifndef MKXPZ_RETRO #include #include #include @@ -33,18 +34,25 @@ #include "gl-meta.h" #include "quad.h" #include "quadarray.h" +#endif // MKXPZ_RETRO #include "transform.h" #include "exception.h" #include "sharedstate.h" #include "glstate.h" +#ifndef MKXPZ_RETRO #include "texpool.h" #include "shader.h" #include "filesystem.h" +#endif // MKXPZ_RETRO #include "font.h" +#ifndef MKXPZ_RETRO #include "eventthread.h" +#endif // MKXPZ_RETRO #include "graphics.h" +#ifndef MKXPZ_RETRO #include "system.h" +#endif // MKXPZ_RETRO #include "util/util.h" #include "debugwriter.h" @@ -163,7 +171,9 @@ struct BitmapPrivate bool playing; bool needsReset; bool loop; +#ifndef MKXPZ_RETRO std::vector frames; +#endif // MKXPZ_RETRO float fps; int lastFrame; double startTime, playTime; @@ -173,6 +183,7 @@ struct BitmapPrivate return floor(lastFrame + (playTime / (1 / fps))); } +#ifndef MKXPZ_RETRO unsigned int currentFrameI() { if (!playing || needsReset) return lastFrame; int i = currentFrameIRaw(); @@ -183,6 +194,7 @@ struct BitmapPrivate int i = currentFrameI(); return frames[i]; } +#endif // MKXPZ_RETRO inline void play() { playing = true; @@ -190,17 +202,23 @@ struct BitmapPrivate } inline void stop() { +#ifndef MKXPZ_RETRO lastFrame = currentFrameI(); +#endif // MKXPZ_RETRO playing = false; } inline void seek(int frame) { +#ifndef MKXPZ_RETRO lastFrame = clamp(frame, 0, (int)frames.size()); +#endif // MKXPZ_RETRO } void updateTimer() { if (needsReset) { +#ifndef MKXPZ_RETRO lastFrame = currentFrameI(); +#endif // MKXPZ_RETRO playTime = 0; startTime = shState->runTime(); needsReset = false; @@ -214,7 +232,9 @@ struct BitmapPrivate sigslot::connection prepareCon; +#ifndef MKXPZ_RETRO TEXFBO gl; +#endif // MKXPZ_RETRO Font *font; @@ -228,6 +248,7 @@ struct BitmapPrivate * getPixel calls. Is invalidated any time the bitmap * is modified */ SDL_Surface *surface; +#ifndef MKXPZ_RETRO SDL_PixelFormat *format; /* The 'tainted' area describes which parts of the @@ -237,6 +258,7 @@ struct BitmapPrivate * in the texture and blit to it directly, saving * ourselves the expensive blending calculation */ pixman_region16_t tainted; +#endif // MKXPZ_RETRO // For high-resolution texture replacement. Bitmap *selfHires; @@ -251,7 +273,9 @@ struct BitmapPrivate surface(0), assumingRubyGC(false) { +#ifndef MKXPZ_RETRO format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888); +#endif // MKXPZ_RETRO animation.width = 0; animation.height = 0; @@ -265,20 +289,26 @@ struct BitmapPrivate prepareCon = shState->prepareDraw.connect(&BitmapPrivate::prepare, this); +#ifndef MKXPZ_RETRO font = &shState->defaultFont(); pixman_region_init(&tainted); +#endif // MKXPZ_RETRO } ~BitmapPrivate() { prepareCon.disconnect(); +#ifndef MKXPZ_RETRO SDL_FreeFormat(format); pixman_region_fini(&tainted); +#endif // MKXPZ_RETRO } +#ifndef MKXPZ_RETRO TEXFBO &getGLTypes() { return (animation.enabled) ? animation.currentFrame() : gl; } +#endif // MKXPZ_RETRO void prepare() { @@ -289,22 +319,28 @@ struct BitmapPrivate void allocSurface() { +#ifndef MKXPZ_RETRO surface = SDL_CreateRGBSurface(0, gl.width, gl.height, format->BitsPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask); +#endif // MKXPZ_RETRO } void clearTaintedArea() { +#ifndef MKXPZ_RETRO pixman_region_fini(&tainted); pixman_region_init(&tainted); +#endif // MKXPZ_RETRO } void addTaintedArea(const IntRect &rect) { +#ifndef MKXPZ_RETRO IntRect norm = normalizedRect(rect); pixman_region_union_rect (&tainted, &tainted, norm.x, norm.y, norm.w, norm.h); +#endif // MKXPZ_RETRO } void substractTaintedArea(const IntRect &rect) @@ -312,16 +348,21 @@ struct BitmapPrivate if (!touchesTaintedArea(rect)) return; +#ifndef MKXPZ_RETRO pixman_region16_t m_reg; pixman_region_init_rect(&m_reg, rect.x, rect.y, rect.w, rect.h); pixman_region_subtract(&tainted, &m_reg, &tainted); pixman_region_fini(&m_reg); +#endif // MKXPZ_RETRO } bool touchesTaintedArea(const IntRect &rect) { +#ifdef MKXPZ_RETRO + return false; // TODO: implement +#else pixman_box16_t box; box.x1 = rect.x; box.y1 = rect.y; @@ -332,6 +373,7 @@ struct BitmapPrivate pixman_region_contains_rectangle(&tainted, &box); return result != PIXMAN_REGION_OUT; +#endif // MKXPZ_RETRO } void bindTexture(ShaderBase &shader, bool substituteLoresSize = true) @@ -346,11 +388,14 @@ struct BitmapPrivate Debug() << "BUG: High-res BitmapPrivate bindTexture for animations not implemented"; } +#ifndef MKXPZ_RETRO TEXFBO cframe = animation.currentFrame(); TEX::bind(cframe.tex); shader.setTexSize(Vec2i(cframe.width, cframe.height)); +#endif // MKXPZ_RETRO return; } +#ifndef MKXPZ_RETRO TEX::bind(gl.tex); if (selfLores && substituteLoresSize) { shader.setTexSize(Vec2i(selfLores->width(), selfLores->height())); @@ -358,17 +403,22 @@ struct BitmapPrivate else { shader.setTexSize(Vec2i(gl.width, gl.height)); } +#endif // MKXPZ_RETRO } void bindFBO() { +#ifndef MKXPZ_RETRO FBO::bind((animation.enabled) ? animation.currentFrame().fbo : gl.fbo); +#endif // MKXPZ_RETRO } void pushSetViewport(ShaderBase &shader) const { +#ifndef MKXPZ_RETRO glState.viewport.pushSet(IntRect(0, 0, gl.width, gl.height)); shader.applyViewportProj(); +#endif // MKXPZ_RETRO } void popViewport() const @@ -379,7 +429,9 @@ struct BitmapPrivate void blitQuad(Quad &quad) { glState.blend.pushSet(false); +#ifndef MKXPZ_RETRO quad.draw(); +#endif // MKXPZ_RETRO glState.blend.pop(); } @@ -388,6 +440,7 @@ struct BitmapPrivate { bindFBO(); +#ifndef MKXPZ_RETRO glState.scissorTest.pushSet(true); glState.scissorBox.pushSet(normalizedRect(rect)); glState.clearColor.pushSet(color); @@ -397,8 +450,10 @@ struct BitmapPrivate glState.clearColor.pop(); glState.scissorBox.pop(); glState.scissorTest.pop(); +#endif // MKXPZ_RETRO } +#ifndef MKXPZ_RETRO static void ensureFormat(SDL_Surface *&surf, Uint32 format) { if (surf->format->format == format) @@ -408,12 +463,15 @@ struct BitmapPrivate SDL_FreeSurface(surf); surf = surfConv; } +#endif // MKXPZ_RETRO void onModified(bool freeSurface = true) { if (surface && freeSurface) { +#ifndef MKXPZ_RETRO SDL_FreeSurface(surface); +#endif // MKXPZ_RETRO surface = 0; } @@ -421,6 +479,7 @@ struct BitmapPrivate } }; +#ifndef MKXPZ_RETRO struct BitmapOpenHandler : FileSystem::OpenHandler { // Non-GIF @@ -487,12 +546,14 @@ struct BitmapOpenHandler : FileSystem::OpenHandler return (surface || gif); } }; +#endif // MKXPZ_RETRO Bitmap::Bitmap(const char *filename) { std::string hiresPrefix = "Hires/"; std::string filenameStd = filename; Bitmap *hiresBitmap = nullptr; +#ifndef MKXPZ_RETRO // TODO: once C++20 is required, switch to filenameStd.starts_with(hiresPrefix) if (shState->config().enableHires && filenameStd.compare(0, hiresPrefix.size(), hiresPrefix) != 0) { // Look for a high-res version of the file. @@ -632,6 +693,7 @@ Bitmap::Bitmap(const char *filename) SDL_Surface *imgSurf = handler.surface; initFromSurface(imgSurf, hiresBitmap, false); +#endif // MKXPZ_RETRO } Bitmap::Bitmap(int width, int height, bool isHires) @@ -641,6 +703,7 @@ Bitmap::Bitmap(int width, int height, bool isHires) Bitmap *hiresBitmap = nullptr; +#ifndef MKXPZ_RETRO if (shState->config().enableHires && !isHires) { // Create a high-res version as well. double scalingFactor = shState->config().textureScalingFactor; @@ -658,19 +721,23 @@ Bitmap::Bitmap(int width, int height, bool isHires) delete hiresBitmap; throw e; } +#endif // MKXPZ_RETRO p = new BitmapPrivate(this); +#ifndef MKXPZ_RETRO p->gl = tex; p->selfHires = hiresBitmap; if (p->selfHires != nullptr) { p->gl.selfHires = &p->selfHires->getGLTypes(); } +#endif // MKXPZ_RETRO clear(); } Bitmap::Bitmap(void *pixeldata, int width, int height) { +#ifndef MKXPZ_RETRO SDL_Surface *surface = SDL_CreateRGBSurface(0, width, height, p->format->BitsPerPixel, p->format->Rmask, p->format->Gmask, @@ -703,7 +770,9 @@ Bitmap::Bitmap(void *pixeldata, int width, int height) throw e; } +#endif // MKXPZ_RETRO p = new BitmapPrivate(this); +#ifndef MKXPZ_RETRO p->gl = tex; TEX::bind(p->gl.tex); @@ -711,6 +780,7 @@ Bitmap::Bitmap(void *pixeldata, int width, int height) SDL_FreeSurface(surface); } +#endif // MKXPZ_RETRO p->addTaintedArea(rect()); } @@ -730,6 +800,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame) // TODO: Clean me up if (!other.isAnimated() || frame >= -1) { +#ifndef MKXPZ_RETRO try { p->gl = shState->texPool().request(other.width(), other.height()); } catch (const Exception &e) { @@ -748,6 +819,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame) } GLMeta::blitRectangle(rect(), rect()); GLMeta::blitEnd(); +#endif // MKXPZ_RETRO } else { p->animation.enabled = true; @@ -759,6 +831,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame) p->animation.startTime = 0; p->animation.loop = other.getLooping(); +#ifndef MKXPZ_RETRO for (TEXFBO &sourceframe : other.getFrames()) { TEXFBO newframe; try { @@ -775,6 +848,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame) p->animation.frames.push_back(newframe); } +#endif // MKXPZ_RETRO } p->addTaintedArea(rect()); @@ -784,15 +858,18 @@ Bitmap::Bitmap(TEXFBO &other) { Bitmap *hiresBitmap = nullptr; +#ifndef MKXPZ_RETRO if (other.selfHires != nullptr) { // Create a high-res version as well. hiresBitmap = new Bitmap(*other.selfHires); hiresBitmap->setLores(this); } +#endif // MKXPZ_RETRO p = new BitmapPrivate(this); p->selfHires = hiresBitmap; +#ifndef MKXPZ_RETRO try { p->gl = shState->texPool().request(other.width, other.height); } catch (const Exception &e) { @@ -811,6 +888,7 @@ Bitmap::Bitmap(TEXFBO &other) GLMeta::blitRectangle(rect(), rect()); GLMeta::blitEnd(); } +#endif // MKXPZ_RETRO p->addTaintedArea(rect()); } @@ -837,6 +915,7 @@ Bitmap::~Bitmap() void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool forceMega) { +#ifndef MKXPZ_RETRO p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888); if (imgSurf->w > glState.caps.maxTexSize || imgSurf->h > glState.caps.maxTexSize || forceMega) @@ -865,8 +944,10 @@ void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool for throw e; } +#endif // MKXPZ_RETRO p = new BitmapPrivate(this); p->selfHires = hiresBitmap; +#ifndef MKXPZ_RETRO p->gl = tex; if (p->selfHires != nullptr) { p->gl.selfHires = &p->selfHires->getGLTypes(); @@ -877,6 +958,7 @@ void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool for SDL_FreeSurface(imgSurf); } +#endif // MKXPZ_RETRO p->addTaintedArea(rect()); } @@ -885,6 +967,9 @@ int Bitmap::width() const { guardDisposed(); +#ifdef MKXPZ_RETRO + return 32; // TODO: implement +#else if (p->megaSurface) { return p->megaSurface->w; } @@ -894,12 +979,16 @@ int Bitmap::width() const } return p->gl.width; +#endif // MKXPZ_RETRO } int Bitmap::height() const { guardDisposed(); +#ifdef MKXPZ_RETRO + return 32; // TODO: implement +#else if (p->megaSurface) return p->megaSurface->h; @@ -907,6 +996,7 @@ int Bitmap::height() const return p->animation.height; return p->gl.height; +#endif // MKXPZ_RETRO } bool Bitmap::hasHires() const{ @@ -1085,6 +1175,7 @@ void Bitmap::stretchBlt(IntRect destRect, SDL_Surface *srcSurf = source.megaSurface(); SDL_Surface *blitTemp = 0; bool touchesTaintedArea = p->touchesTaintedArea(destRect); +#ifndef MKXPZ_RETRO bool unpack_subimage = srcSurf && gl.unpack_subimage; const bool scaleIsOne = sourceRect.w == destRect.w && sourceRect.h == destRect.h; @@ -1317,6 +1408,7 @@ void Bitmap::stretchBlt(IntRect destRect, if (blitTemp) SDL_FreeSurface(blitTemp); +#endif // MKXPZ_RETRO p->addTaintedArea(destRect); p->onModified(); @@ -1385,6 +1477,7 @@ void Bitmap::gradientFillRect(const IntRect &rect, p->selfHires->gradientFillRect(IntRect(destX, destY, destWidth, destHeight), color1, color2, vertical); } +#ifndef MKXPZ_RETRO SimpleColorShader &shader = shState->shaders().simpleColor; shader.bind(); shader.setTranslation(Vec2i()); @@ -1414,6 +1507,7 @@ void Bitmap::gradientFillRect(const IntRect &rect, p->blitQuad(quad); p->popViewport(); +#endif // MKXPZ_RETRO p->addTaintedArea(rect); @@ -1460,6 +1554,7 @@ void Bitmap::blur() // TODO: Is there some kind of blur radius that we need to handle for high-res mode? +#ifndef MKXPZ_RETRO Quad &quad = shState->gpQuad(); FloatRect rect(0, 0, width(), height()); quad.setTexPosRect(rect, rect); @@ -1495,6 +1590,7 @@ void Bitmap::blur() glState.blend.pop(); shState->texPool().release(auxTex); +#endif // MKXPZ_RETRO p->onModified(); } @@ -1521,6 +1617,7 @@ void Bitmap::radialBlur(int angle, int divisions) float opacity = 1.0f / divisions; float baseAngle = -((float) angle / 2); +#ifndef MKXPZ_RETRO ColorQuadArray qArray; qArray.resize(5); @@ -1597,6 +1694,7 @@ void Bitmap::radialBlur(int angle, int divisions) shState->texPool().release(p->gl); p->gl = newTex; +#endif // MKXPZ_RETRO p->onModified(); } @@ -1613,17 +1711,20 @@ void Bitmap::clear() p->bindFBO(); +#ifndef MKXPZ_RETRO glState.clearColor.pushSet(Vec4()); FBO::clear(); glState.clearColor.pop(); +#endif // MKXPZ_RETRO p->clearTaintedArea(); p->onModified(); } +#ifndef MKXPZ_RETRO static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int y) { size_t offset = x*form->BytesPerPixel + y*surf->pitch; @@ -1631,6 +1732,7 @@ static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int return *((uint32_t*) bytes); } +#endif // MKXPZ_RETRO Color Bitmap::getPixel(int x, int y) const { @@ -1689,6 +1791,7 @@ Color Bitmap::getPixel(int x, int y) const { p->allocSurface(); +#ifndef MKXPZ_RETRO FBO::bind(p->gl.fbo); glState.viewport.pushSet(IntRect(0, 0, width(), height())); @@ -1696,14 +1799,19 @@ Color Bitmap::getPixel(int x, int y) const gl.ReadPixels(0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_BYTE, p->surface->pixels); glState.viewport.pop(); +#endif // MKXPZ_RETRO } +#ifdef MKXPZ_RETRO + return Color(); // TODO: implement +#else uint32_t pixel = getPixelAt(p->surface, p->format, x, y); return Color((pixel >> p->format->Rshift) & 0xFF, (pixel >> p->format->Gshift) & 0xFF, (pixel >> p->format->Bshift) & 0xFF, (pixel >> p->format->Ashift) & 0xFF); +#endif // MKXPZ_RETRO } void Bitmap::setPixel(int x, int y, const Color &color) @@ -1739,19 +1847,23 @@ void Bitmap::setPixel(int x, int y, const Color &color) (uint8_t) clamp(color.alpha, 0, 255) }; +#ifndef MKXPZ_RETRO TEX::bind(p->gl.tex); TEX::uploadSubImage(x, y, 1, 1, &pixel, GL_RGBA); +#endif // MKXPZ_RETRO p->addTaintedArea(IntRect(x, y, 1, 1)); /* Setting just a single pixel is no reason to throw away the * whole cached surface; we can just apply the same change */ +#ifndef MKXPZ_RETRO if (p->surface) { uint32_t &surfPixel = getPixelAt(p->surface, p->format, x, y); surfPixel = SDL_MapRGBA(p->format, pixel[0], pixel[1], pixel[2], pixel[3]); } +#endif // MKXPZ_RETRO p->onModified(false); } @@ -1766,6 +1878,7 @@ bool Bitmap::getRaw(void *output, int output_size) Debug() << "GAME BUG: Game is calling getRaw on low-res Bitmap; you may want to patch the game to improve graphics quality."; } +#ifndef MKXPZ_RETRO if (!p->animation.enabled && (p->surface || p->megaSurface)) { void *src = (p->megaSurface) ? p->megaSurface->pixels : p->surface->pixels; memcpy(output, src, output_size); @@ -1774,6 +1887,7 @@ bool Bitmap::getRaw(void *output, int output_size) FBO::bind(getGLTypes().fbo); gl.ReadPixels(0,0,width(),height(),GL_RGBA,GL_UNSIGNED_BYTE,output); } +#endif // MKXPZ_RETRO return true; } @@ -1794,8 +1908,10 @@ void Bitmap::replaceRaw(void *pixel_data, int size) if (size != w*h*4) throw Exception(Exception::MKXPError, "Replacement bitmap data is not large enough (given %i bytes, need %i)", size, requiredsize); +#ifndef MKXPZ_RETRO TEX::bind(getGLTypes().tex); TEX::uploadImage(w, h, pixel_data, GL_RGBA); +#endif // MKXPZ_RETRO taintArea(IntRect(0,0,w,h)); p->onModified(); @@ -1815,12 +1931,14 @@ void Bitmap::saveToFile(const char *filename) surf = (p->surface) ? p->surface : p->megaSurface; } else { +#ifndef MKXPZ_RETRO surf = SDL_CreateRGBSurface(0, width(), height(),p->format->BitsPerPixel, p->format->Rmask,p->format->Gmask,p->format->Bmask,p->format->Amask); if (!surf) throw Exception(Exception::SDLError, "Failed to prepare bitmap for saving: %s", SDL_GetError()); getRaw(surf->pixels, surf->w * surf->h * 4); +#endif // MKXPZ_RETRO } // Try and determine the intended image format from the filename extension @@ -1841,6 +1959,7 @@ void Bitmap::saveToFile(const char *filename) } } +#ifndef MKXPZ_RETRO std::string fn_normalized = shState->fileSystem().normalize(filename, 1, 1); int rc; switch (filetype) { @@ -1859,6 +1978,7 @@ void Bitmap::saveToFile(const char *filename) SDL_FreeSurface(surf); if (rc) throw Exception(Exception::SDLError, "%s", SDL_GetError()); +#endif // MKXPZ_RETRO } void Bitmap::hueChange(int hue) @@ -1876,6 +1996,7 @@ void Bitmap::hueChange(int hue) if ((hue % 360) == 0) return; +#ifndef MKXPZ_RETRO TEXFBO newTex = shState->texPool().request(width(), height()); FloatRect texRect(rect()); @@ -1901,6 +2022,7 @@ void Bitmap::hueChange(int hue) shState->texPool().release(p->gl); p->gl = newTex; +#endif // MKXPZ_RETRO p->onModified(); } @@ -1927,6 +2049,7 @@ static std::string fixupString(const char *str) return s; } +#ifndef MKXPZ_RETRO static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_Color &c) { SDL_Surface *out = SDL_CreateRGBSurface @@ -2013,6 +2136,7 @@ static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_C SDL_FreeSurface(in); in = out; } +#endif // MKXPZ_RETRO void Bitmap::drawText(const IntRect &rect, const char *str, int align) { @@ -2021,6 +2145,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) GUARD_MEGA; GUARD_ANIMATED; +#ifndef MKXPZ_RETRO if (hasHires()) { Font &loresFont = getFont(); Font &hiresFont = p->selfHires->getFont(); @@ -2042,6 +2167,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) return; } +#endif // MKXPZ_RETRO std::string fixed = fixupString(str); str = fixed.c_str(); @@ -2052,6 +2178,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) if (str[0] == ' ' && str[1] == '\0') return; +#ifndef MKXPZ_RETRO TTF_Font *font = p->font->getSdlFont(); const Color &fontColor = p->font->getColor(); const Color &outColor = p->font->getOutColor(); @@ -2144,6 +2271,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) Bitmap txtBitmap(txtSurf, nullptr, true); bool smooth = squeeze != 1.0f; stretchBlt(destRect, txtBitmap, sourceRect, fontColor.alpha, smooth); +#endif // MKXPZ_RETRO } /* http://www.lemoda.net/c/utf8-to-ucs2/index.html */ @@ -2200,6 +2328,9 @@ IntRect Bitmap::textSize(const char *str) // TODO: High-res Bitmap textSize not implemented, but I think it's the same as low-res? // Need to double-check this. +#ifdef MKXPZ_RETRO + return IntRect(); // TODO: implement +#else TTF_Font *font = p->font->getSdlFont(); std::string fixed = fixupString(str); @@ -2218,6 +2349,7 @@ IntRect Bitmap::textSize(const char *str) TTF_GlyphMetrics(font, ucs2, 0, 0, 0, 0, &w); return IntRect(0, 0, w, h); +#endif // MKXPZ_RETRO } DEF_ATTR_RD_SIMPLE(Bitmap, Font, Font&, *p->font) @@ -2225,27 +2357,33 @@ DEF_ATTR_RD_SIMPLE(Bitmap, Font, Font&, *p->font) void Bitmap::setFont(Font &value) { // High-res support handled in drawText, not here. +#ifndef MKXPZ_RETRO *p->font = value; +#endif // MKXPZ_RETRO } void Bitmap::setInitFont(Font *value) { if (hasHires()) { Font *hiresFont = p->selfHires->p->font; +#ifndef MKXPZ_RETRO if (hiresFont && hiresFont != &shState->defaultFont()) { // Disable the illegal font size check when creating a high-res font. hiresFont->setSize(hiresFont->getSize() * p->selfHires->width() / width(), false); } +#endif // MKXPZ_RETRO } p->font = value; } +#ifndef MKXPZ_RETRO TEXFBO &Bitmap::getGLTypes() const { return p->getGLTypes(); } +#endif // MKXPZ_RETRO SDL_Surface *Bitmap::surface() const { @@ -2336,7 +2474,11 @@ bool Bitmap::isPlaying() const if (p->animation.loop) return true; +#ifdef MKXPZ_RETRO + return false; // TODO: implement +#else return p->animation.currentFrameIRaw() < p->animation.frames.size(); +#endif // MKXPZ_RETRO } void Bitmap::gotoAndStop(int frame) @@ -2376,9 +2518,14 @@ int Bitmap::numFrames() const } if (!p->animation.enabled) return 1; +#ifdef MKXPZ_RETRO + return 0; // TODO: implement +#else return (int)p->animation.frames.size(); +#endif // MKXPZ_RETRO } +#ifndef MKXPZ_RETRO int Bitmap::currentFrameI() const { guardDisposed(); @@ -2390,6 +2537,7 @@ int Bitmap::currentFrameI() const if (!p->animation.enabled) return 0; return p->animation.currentFrameI(); } +#endif // MKXPZ_RETRO int Bitmap::addFrame(Bitmap &source, int position) { @@ -2410,6 +2558,7 @@ int Bitmap::addFrame(Bitmap &source, int position) throw Exception(Exception::MKXPError, "Animations with varying dimensions are not supported (%ix%i vs %ix%i)", source.width(), source.height(), width(), height()); +#ifndef MKXPZ_RETRO TEXFBO newframe = shState->texPool().request(source.width(), source.height()); // Convert the bitmap into an animated bitmap if it isn't already one @@ -2444,14 +2593,23 @@ int Bitmap::addFrame(Bitmap &source, int position) GLMeta::blitEnd(); } +#endif // MKXPZ_RETRO int ret; if (position < 0) { +#ifndef MKXPZ_RETRO p->animation.frames.push_back(newframe); +#endif // MKXPZ_RETRO +#ifdef MKXPZ_RETRO + ret = 0; // TODO: implement +#else ret = (int)p->animation.frames.size(); +#endif // MKXPZ_RETRO } else { +#ifndef MKXPZ_RETRO p->animation.frames.insert(p->animation.frames.begin() + clamp(position, 0, (int)p->animation.frames.size()), newframe); +#endif // MKXPZ_RETRO ret = position; } @@ -2467,6 +2625,7 @@ void Bitmap::removeFrame(int position) { Debug() << "BUG: High-res Bitmap removeFrame not implemented"; } +#ifndef MKXPZ_RETRO int pos = (position < 0) ? (int)p->animation.frames.size() - 1 : clamp(position, 0, (int)(p->animation.frames.size() - 1)); shState->texPool().release(p->animation.frames[pos]); p->animation.frames.erase(p->animation.frames.begin() + pos); @@ -2486,6 +2645,7 @@ void Bitmap::removeFrame(int position) { FBO::bind(p->gl.fbo); taintArea(rect()); } +#endif // MKXPZ_RETRO } void Bitmap::nextFrame() @@ -2499,11 +2659,13 @@ void Bitmap::nextFrame() } stop(); +#ifndef MKXPZ_RETRO if ((uint32_t)p->animation.lastFrame >= p->animation.frames.size() - 1) { if (!p->animation.loop) return; p->animation.lastFrame = 0; return; } +#endif // MKXPZ_RETRO p->animation.lastFrame++; } @@ -2524,7 +2686,9 @@ void Bitmap::previousFrame() p->animation.lastFrame = 0; return; } +#ifndef MKXPZ_RETRO p->animation.lastFrame = (int)p->animation.frames.size() - 1; +#endif // MKXPZ_RETRO return; } @@ -2547,6 +2711,7 @@ void Bitmap::setAnimationFPS(float FPS) if (restart) p->animation.play(); } +#ifndef MKXPZ_RETRO std::vector &Bitmap::getFrames() const { if (hasHires()) { @@ -2555,6 +2720,7 @@ std::vector &Bitmap::getFrames() const return p->animation.frames; } +#endif // MKXPZ_RETRO float Bitmap::getAnimationFPS() const { @@ -2617,9 +2783,11 @@ void Bitmap::taintArea(const IntRect &rect) p->addTaintedArea(rect); } +#ifndef MKXPZ_RETRO int Bitmap::maxSize(){ return glState.caps.maxTexSize; } +#endif // MKXPZ_RETRO void Bitmap::assumeRubyGC() { @@ -2632,6 +2800,7 @@ void Bitmap::releaseResources() delete p->selfHires; } +#ifndef MKXPZ_RETRO if (p->megaSurface) SDL_FreeSurface(p->megaSurface); else if (p->animation.enabled) { @@ -2642,6 +2811,7 @@ void Bitmap::releaseResources() } else shState->texPool().release(p->gl); +#endif // MKXPZ_RETRO delete p; } diff --git a/src/display/graphics.h b/src/display/graphics.h index ac5ab558..b5a6e7e0 100644 --- a/src/display/graphics.h +++ b/src/display/graphics.h @@ -111,7 +111,12 @@ private: GraphicsPrivate *p; }; -#define GFX_LOCK shState->graphics().lock() -#define GFX_UNLOCK shState->graphics().unlock() +#ifdef MKXPZ_RETRO +# define GFX_LOCK // TODO +# define GFX_UNLOCK // TODO +#else +# define GFX_LOCK shState->graphics().lock() +# define GFX_UNLOCK shState->graphics().unlock() +#endif // MKXPZ_RETRO #endif // GRAPHICS_H diff --git a/src/display/viewport.cpp b/src/display/viewport.cpp index 29b3219e..d2f1bea3 100644 --- a/src/display/viewport.cpp +++ b/src/display/viewport.cpp @@ -24,12 +24,12 @@ #include "sharedstate.h" #include "etc.h" #include "util.h" +#ifndef MKXPZ_RETRO #include "quad.h" #include "glstate.h" +#endif // MKXPZ_RETRO #include "graphics.h" -#include - #include "sigslot/signal.hpp" struct ViewportPrivate @@ -80,14 +80,10 @@ struct ViewportPrivate void recomputeOnScreen() { - SDL_Rect r1 = { screenRect.x, screenRect.y, - screenRect.w, screenRect.h }; - - SDL_Rect r2 = { rect->x, rect->y, - rect->width, rect->height }; - - SDL_Rect result; - isOnScreen = SDL_IntersectRect(&r1, &r2, &result); + isOnScreen = screenRect.x < rect->x + rect->width + && rect->x < screenRect.x + screenRect.w + && screenRect.y < rect->y + rect->height + && rect->y < screenRect.y + screenRect.h; } bool needsEffectRender(bool flashing) @@ -117,8 +113,12 @@ Viewport::Viewport() : SceneElement(*shState->screen()), sceneLink(this) { +#ifdef MKXPZ_RETRO + initViewport(0, 0, 640, 480); // TODO: use the actual viewport size +#else const Graphics &graphics = shState->graphics(); initViewport(0, 0, graphics.width(), graphics.height()); +#endif // MKXPZ_RETRO } void Viewport::initViewport(int x, int y, int width, int height) @@ -193,9 +193,11 @@ void Viewport::composite() if (elements.getSize() == 0 && !renderEffect) return; +#ifndef MKXPZ_RETRO /* Setup scissor */ glState.scissorTest.pushSet(true); glState.scissorBox.pushSet(p->rect->toIntRect()); +#endif // MKXPZ_RETRO Scene::composite(); @@ -205,8 +207,10 @@ void Viewport::composite() scene->requestViewportRender (p->color->norm, flashColor, p->tone->norm); +#ifndef MKXPZ_RETRO glState.scissorBox.pop(); glState.scissorTest.pop(); +#endif // MKXPZ_RETRO } /* SceneElement */ diff --git a/src/display/window.cpp b/src/display/window.cpp index 8d35670e..438994ee 100644 --- a/src/display/window.cpp +++ b/src/display/window.cpp @@ -26,6 +26,7 @@ #include "bitmap.h" #include "etc.h" #include "etc-internal.h" +#ifndef MKXPZ_RETRO #include "tilequad.h" #include "gl-util.h" @@ -33,6 +34,7 @@ #include "quadarray.h" #include "texpool.h" #include "glstate.h" +#endif // MKXPZ_RETRO #include "sigslot/signal.hpp" @@ -118,6 +120,7 @@ static const uint8_t pauseAniAlpha[] = static elementsN(pauseAniAlpha); +#ifndef MKXPZ_RETRO /* Points to an array of quads which it doesn't own. * Useful for setting alpha of quads stored inside * bigger arrays */ @@ -136,6 +139,7 @@ struct QuadChunk vert[i].color.w = value; } }; +#endif // MKXPZ_RETRO /* Vocabulary: * @@ -196,6 +200,7 @@ struct WindowPrivate bool opacityDirty; bool baseTexDirty; +#ifndef MKXPZ_RETRO ColorQuadArray baseQuadArray; /* Used when opacity < 255 */ @@ -205,6 +210,7 @@ struct WindowPrivate QuadChunk backgroundVert; Quad baseTexQuad; +#endif // MKXPZ_RETRO struct WindowControls : public ViewportElement { @@ -233,6 +239,7 @@ struct WindowPrivate WindowControls controlsElement; +#ifndef MKXPZ_RETRO ColorQuadArray controlsQuadArray; int controlsQuadCount; @@ -240,6 +247,7 @@ struct WindowPrivate QuadChunk pauseAniVert; QuadChunk cursorVert; +#endif // MKXPZ_RETRO uint8_t cursorAniAlphaIdx; uint8_t pauseAniAlphaIdx; @@ -272,9 +280,11 @@ struct WindowPrivate { refreshCursorRectCon(); +#ifndef MKXPZ_RETRO controlsQuadArray.resize(14); cursorVert.count = 9; pauseAniVert.count = 1; +#endif // MKXPZ_RETRO prepareCon = shState->prepareDraw.connect (&WindowPrivate::prepare, this); @@ -282,7 +292,9 @@ struct WindowPrivate ~WindowPrivate() { +#ifndef MKXPZ_RETRO shState->texPool().release(baseTex); +#endif // MKXPZ_RETRO cursorRectCon.disconnect(); prepareCon.disconnect(); @@ -333,6 +345,7 @@ struct WindowPrivate cornerRects.bl = IntRect(0, h-16, 16, 16); cornerRects.br = IntRect(w-16, h-16, 16, 16); +#ifndef MKXPZ_RETRO /* Required quad count */ int count = 0; @@ -389,6 +402,7 @@ struct WindowPrivate FloatRect texRect = FloatRect(0, 0, size.x, size.y); baseTexQuad.setTexPosRect(texRect, texRect); +#endif // MKXPZ_RETRO opacityDirty = true; baseTexDirty = true; @@ -396,10 +410,12 @@ struct WindowPrivate void updateBaseAlpha() { +#ifndef MKXPZ_RETRO /* This is always applied unconditionally */ backgroundVert.setAlpha(backOpacity.norm); baseTexQuad.setColor(Vec4(1, 1, 1, opacity.norm)); +#endif // MKXPZ_RETRO baseTexDirty = true; } @@ -407,6 +423,7 @@ struct WindowPrivate void ensureBaseTexReady() { /* Make sure texture is big enough */ +#ifndef MKXPZ_RETRO int newW = baseTex.width; int newH = baseTex.height; bool resizeNeeded = false; @@ -427,12 +444,14 @@ struct WindowPrivate shState->texPool().release(baseTex); baseTex = shState->texPool().request(newW, newH); +#endif // MKXPZ_RETRO baseTexDirty = true; } void redrawBaseTex() { +#ifndef MKXPZ_RETRO /* Discard old buffer */ TEX::bind(baseTex.tex); TEX::allocEmpty(baseTex.width, baseTex.height); @@ -471,10 +490,12 @@ struct WindowPrivate glState.blendMode.pop(); glState.viewport.pop(); TEX::setSmooth(false); +#endif // MKXPZ_RETRO } void buildControlsVert() { +#ifndef MKXPZ_RETRO int i = 0; Vertex *vert = controlsQuadArray.vertices.data(); @@ -524,6 +545,7 @@ struct WindowPrivate controlsQuadArray.commit(); controlsQuadCount = i; +#endif // MKXPZ_RETRO } void prepare() @@ -547,6 +569,7 @@ struct WindowPrivate updateBaseQuadArray = true; } +#ifndef MKXPZ_RETRO if (updateBaseQuadArray) baseQuadArray.commit(); @@ -564,6 +587,7 @@ struct WindowPrivate baseTexDirty = false; } } +#endif // MKXPZ_RETRO } void drawBase() @@ -574,6 +598,7 @@ struct WindowPrivate if (size == Vec2i(0, 0)) return; +#ifndef MKXPZ_RETRO SimpleAlphaShader &shader = shState->shaders().simpleAlpha; shader.bind(); shader.applyViewportProj(); @@ -595,6 +620,7 @@ struct WindowPrivate TEX::setSmooth(false); } +#endif // MKXPZ_RETRO } void drawControls() @@ -618,6 +644,7 @@ struct WindowPrivate const IntRect windowRect(efPos, size); const IntRect contentsRect(efPos + Vec2i(16), size - Vec2i(32)); +#ifndef MKXPZ_RETRO glState.scissorTest.pushSet(true); glState.scissorBox.push(); glState.scissorBox.setIntersect(windowRect); @@ -652,10 +679,12 @@ struct WindowPrivate glState.scissorBox.pop(); glState.scissorTest.pop(); +#endif // MKXPZ_RETRO } void updateControls() { +#ifndef MKXPZ_RETRO bool updateArray = false; if (active && cursorVert.vert) @@ -680,6 +709,7 @@ struct WindowPrivate if (updateArray) controlsQuadArray.commit(); +#endif // MKXPZ_RETRO } void stepAnimations() @@ -746,7 +776,9 @@ void Window::setWindowskin(Bitmap *value) return; } +#ifndef MKXPZ_RETRO value->ensureNonMega(); +#endif // MKXPZ_RETRO p->windowskinDispCon = value->wasDisposed.connect(&WindowPrivate::windowskinDisposal, p); } @@ -771,9 +803,11 @@ void Window::setContents(Bitmap *value) p->contentsDispCon = value->wasDisposed.connect(&WindowPrivate::contentsDisposal, p); +#ifndef MKXPZ_RETRO value->ensureNonMega(); p->contentsQuad.setTexPosRect(value->rect(), value->rect()); +#endif // MKXPZ_RETRO } void Window::setStretch(bool value) @@ -885,7 +919,9 @@ void Window::setContentsOpacity(int value) return; p->contentsOpacity = value; +#ifndef MKXPZ_RETRO p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm)); +#endif // MKXPZ_RETRO } void Window::initDynAttribs() diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index 83af9534..fd03dd36 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -21,22 +21,33 @@ #include "sharedstate.h" +#include "scene.h" #include "util.h" +#ifndef MKXPZ_RETRO #include "filesystem.h" +#endif // MKXPZ_RETRO #include "graphics.h" +#ifndef MKXPZ_RETRO #include "input.h" #include "audio.h" +#endif // MKXPZ_RETRO #include "glstate.h" +#ifndef MKXPZ_RETRO #include "shader.h" #include "texpool.h" +#endif // MKXPZ_RETRO #include "font.h" +#ifndef MKXPZ_RETRO #include "eventthread.h" #include "gl-util.h" #include "global-ibo.h" #include "quad.h" +#endif // MKXPZ_RETRO #include "binding.h" #include "exception.h" +#ifndef MKXPZ_RETRO #include "sharedmidistate.h" +#endif // MKXPZ_RETRO #include #include @@ -63,9 +74,12 @@ static const char *gameArchExt() struct SharedStatePrivate { void *bindingData; +#ifndef MKXPZ_RETRO SDL_Window *sdlWindow; +#endif // MKXPZ_RETRO Scene *screen; +#ifndef MKXPZ_RETRO FileSystem fileSystem; EventThread &eThread; @@ -88,14 +102,17 @@ struct SharedStatePrivate Font *defaultFont; TEX::ID globalTex; +#endif // MKXPZ_RETRO int globalTexW, globalTexH; bool globalTexDirty; +#ifndef MKXPZ_RETRO TEXFBO gpTexFBO; TEXFBO atlasTex; Quad gpQuad; +#endif // MKXPZ_RETRO unsigned int stampCounter; @@ -103,6 +120,7 @@ struct SharedStatePrivate SharedStatePrivate(RGSSThreadData *threadData) : bindingData(0), +#ifndef MKXPZ_RETRO sdlWindow(threadData->window), fileSystem(threadData->argv0, threadData->config.allowSymlinks), eThread(*threadData->ethread), @@ -114,6 +132,7 @@ struct SharedStatePrivate audio(*threadData), _glState(threadData->config), fontState(threadData->config), +#endif // MKXPZ_RETRO stampCounter(0) {} @@ -122,6 +141,7 @@ struct SharedStatePrivate startupTime = std::chrono::steady_clock::now(); +#ifndef MKXPZ_RETRO /* Shaders have been compiled in ShaderSet's constructor */ if (gl.ReleaseShaderCompiler) gl.ReleaseShaderCompiler(); @@ -168,13 +188,16 @@ struct SharedStatePrivate * no need to do it on startup */ if (rgssVer <= 2) midiState.initIfNeeded(threadData->config); +#endif // MKXPZ_RETRO } ~SharedStatePrivate() { +#ifndef MKXPZ_RETRO TEX::del(globalTex); TEXFBO::fini(gpTexFBO); TEXFBO::fini(atlasTex); +#endif // MKXPZ_RETRO } }; @@ -184,6 +207,7 @@ void SharedState::initInstance(RGSSThreadData *threadData) * SharedState depends on GlobalIBO existing, * Font depends on SharedState existing */ +#ifndef MKXPZ_RETRO rgssVersion = threadData->config.rgssVersion; _globalIBO = new GlobalIBO(); @@ -191,32 +215,45 @@ void SharedState::initInstance(RGSSThreadData *threadData) SharedState::instance = 0; Font *defaultFont = 0; +#endif // MKXPZ_RETRO try { SharedState::instance = new SharedState(threadData); +#ifndef MKXPZ_RETRO Font::initDefaults(instance->p->fontState); defaultFont = new Font(); +#endif // MKXPZ_RETRO } catch (const Exception &exc) { +#ifndef MKXPZ_RETRO delete _globalIBO; +#endif // MKXPZ_RETRO delete SharedState::instance; +#ifndef MKXPZ_RETRO delete defaultFont; +#endif // MKXPZ_RETRO throw exc; } +#ifndef MKXPZ_RETRO SharedState::instance->p->defaultFont = defaultFont; +#endif // MKXPZ_RETRO } void SharedState::finiInstance() { +#ifndef MKXPZ_RETRO delete SharedState::instance->p->defaultFont; +#endif // MKXPZ_RETRO delete SharedState::instance; +#ifndef MKXPZ_RETRO delete _globalIBO; +#endif // MKXPZ_RETRO } void SharedState::setScreen(Scene &screen) @@ -231,8 +268,11 @@ void SharedState::setScreen(Scene &screen) } GSATT(void*, bindingData) +#ifndef MKXPZ_RETRO GSATT(SDL_Window*, sdlWindow) +#endif // MKXPZ_RETRO GSATT(Scene*, screen) +#ifndef MKXPZ_RETRO GSATT(FileSystem&, fileSystem) GSATT(EventThread&, eThread) GSATT(RGSSThreadData&, rtData) @@ -246,6 +286,7 @@ GSATT(TexPool&, texPool) GSATT(Quad&, gpQuad) GSATT(SharedFontState&, fontState) GSATT(SharedMidiState&, midiState) +#endif // MKXPZ_RETRO void SharedState::setBindingData(void *data) { @@ -254,7 +295,9 @@ void SharedState::setBindingData(void *data) void SharedState::ensureQuadIBO(size_t minSize) { +#ifndef MKXPZ_RETRO _globalIBO->ensureSize(minSize); +#endif // MKXPZ_RETRO } GlobalIBO &SharedState::globalIBO() @@ -264,6 +307,7 @@ GlobalIBO &SharedState::globalIBO() void SharedState::bindTex() { +#ifndef MKXPZ_RETRO TEX::bind(p->globalTex); if (p->globalTexDirty) @@ -271,6 +315,7 @@ void SharedState::bindTex() TEX::allocEmpty(p->globalTexW, p->globalTexH); p->globalTexDirty = false; } +#endif // MKXPZ_RETRO } void SharedState::ensureTexSize(int minW, int minH, Vec2i ¤tSizeOut) @@ -290,6 +335,7 @@ void SharedState::ensureTexSize(int minW, int minH, Vec2i ¤tSizeOut) currentSizeOut = Vec2i(p->globalTexW, p->globalTexH); } +#ifndef MKXPZ_RETRO TEXFBO &SharedState::gpTexFBO(int minW, int minH) { bool needResize = false; @@ -344,30 +390,37 @@ void SharedState::releaseAtlasTex(TEXFBO &tex) p->atlasTex = tex; } +#endif // MKXPZ_RETRO void SharedState::checkShutdown() { +#ifndef MKXPZ_RETRO if (!p->rtData.rqTerm) return; p->rtData.rqTermAck.set(); p->texPool.disable(); scriptBinding->terminate(); +#endif // MKXPZ_RETRO } void SharedState::checkReset() { +#ifndef MKXPZ_RETRO if (!p->rtData.rqReset) return; p->rtData.rqReset.clear(); scriptBinding->reset(); +#endif // MKXPZ_RETRO } +#ifndef MKXPZ_RETRO Font &SharedState::defaultFont() const { return *p->defaultFont; } +#endif // MKXPZ_RETRO double SharedState::runTime() { if (!p) return 0; @@ -387,14 +440,20 @@ SharedState::SharedState(RGSSThreadData *threadData) try { p->init(threadData); +#ifdef MKXPZ_RETRO + p->screen = new Scene(); // TODO: implement +#else p->screen = p->graphics.getScreen(); +#endif // MKXPZ_RETRO } catch (const Exception &exc) { +#ifndef MKXPZ_RETRO // If the "error" was the user quitting the game before the path cache finished building, // then just return if (rtData().rqTerm) return; +#endif // MKXPZ_RETRO delete p; SharedState::instance = 0; diff --git a/src/util/disposable.h b/src/util/disposable.h index 5795cf74..0e3cb939 100644 --- a/src/util/disposable.h +++ b/src/util/disposable.h @@ -37,12 +37,16 @@ public: : disposed(false), link(this) { +#ifndef MKXPZ_RETRO shState->graphics().addDisposable(this); +#endif // MKXPZ_RETRO } virtual ~Disposable() { +#ifndef MKXPZ_RETRO shState->graphics().remDisposable(this); +#endif // MKXPZ_RETRO } void dispose()