Implement more of binding-sandbox

This commit is contained in:
刘皓 2025-01-22 11:52:10 -05:00
parent 4c9e68e066
commit 739185594e
No known key found for this signature in database
GPG key ID: 7901753DB465B711
14 changed files with 480 additions and 15 deletions

View file

@ -25,6 +25,8 @@
#include "binding-sandbox/core.h" #include "binding-sandbox/core.h"
#include "sandbox.h" #include "sandbox.h"
#define GFX_GUARD_EXC(exp) exp // TODO: implement
#define SANDBOX_DEF_ALLOC(rbtype) \ #define SANDBOX_DEF_ALLOC(rbtype) \
static VALUE alloc(VALUE _klass) { \ static VALUE alloc(VALUE _klass) { \
SANDBOX_COROUTINE(alloc, \ SANDBOX_COROUTINE(alloc, \
@ -78,6 +80,11 @@ namespace mkxp_sandbox {
// Given Ruby typed data `obj`, stores `ptr` into the private data field of `obj`. // Given Ruby typed data `obj`, stores `ptr` into the private data field of `obj`.
void set_private_data(VALUE obj, void *ptr); void set_private_data(VALUE obj, void *ptr);
// Given Ruby typed data `obj`, retrieves the private data field of `obj`.
template <typename T> 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. // Gets the length of a Ruby object.
SANDBOX_COROUTINE(get_length, SANDBOX_COROUTINE(get_length,
ID id; ID id;

View file

@ -33,6 +33,40 @@ namespace mkxp_sandbox {
SANDBOX_DEF_ALLOC(bitmap_type) SANDBOX_DEF_ALLOC(bitmap_type)
SANDBOX_DEF_DFREE(Bitmap) 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<struct coro>()()(argc, argv, self);
}
static VALUE clear(VALUE self) {
GFX_GUARD_EXC(get_private_data<Bitmap>(self)->clear());
return self;
}
VALUE klass; VALUE klass;
void operator()() { void operator()() {
@ -40,6 +74,8 @@ namespace mkxp_sandbox {
bitmap_type = sb()->rb_data_type("Bitmap", NULL, dfree, NULL, NULL, 0, 0, 0); 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_AND_SET(klass, rb_define_class, "Bitmap", sb()->rb_cObject());
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc); 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);
} }
} }
) )

View file

@ -33,10 +33,44 @@ namespace mkxp_sandbox {
SANDBOX_COROUTINE(etc_binding_init, SANDBOX_COROUTINE(etc_binding_init,
SANDBOX_COROUTINE(color_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_DFREE(Color)
SANDBOX_DEF_LOAD(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<struct coro>()()(argc, argv, self);
}
VALUE klass; VALUE klass;
void operator()() { void operator()() {
@ -44,6 +78,7 @@ namespace mkxp_sandbox {
color_type = sb()->rb_data_type("Color", NULL, dfree, NULL, NULL, 0, 0, 0); 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_AND_SET(klass, rb_define_class, "Color", sb()->rb_cObject());
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc); 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); SANDBOX_AWAIT(rb_define_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1);
} }
} }

View file

@ -23,12 +23,28 @@
#define MKXPZ_SANDBOX_SPRITE_BINDING_H #define MKXPZ_SANDBOX_SPRITE_BINDING_H
#include "sandbox.h" #include "sandbox.h"
#include "binding-util.h"
#include "sprite.h"
namespace mkxp_sandbox { namespace mkxp_sandbox {
static struct mkxp_sandbox::bindings::rb_data_type sprite_type;
SANDBOX_COROUTINE(sprite_binding_init, 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()() { void operator()() {
BOOST_ASIO_CORO_REENTER (this) { 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);
} }
} }
) )

View file

@ -23,12 +23,93 @@
#define MKXPZ_SANDBOX_WINDOW_BINDING_H #define MKXPZ_SANDBOX_WINDOW_BINDING_H
#include "sandbox.h" #include "sandbox.h"
#include "binding-util.h"
#include "window.h"
namespace mkxp_sandbox { namespace mkxp_sandbox {
static struct mkxp_sandbox::bindings::rb_data_type window_type;
SANDBOX_COROUTINE(window_binding_init, 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>(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<struct coro>()()(argc, argv, self);
}
static VALUE get_contents(VALUE self) {
return sb()->bind<struct rb_iv_get>()()(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<Window>(self)->setContents(value == SANDBOX_NIL ? NULL : get_private_data<Bitmap>(value)));
SANDBOX_AWAIT(rb_iv_set, self, "contents", value);
}
return self;
}
)
return sb()->bind<struct coro>()()(self, value);
}
static VALUE todo(int32_t argc, wasm_ptr_t argv, VALUE self) {
return self;
}
VALUE klass;
void operator()() { void operator()() {
BOOST_ASIO_CORO_REENTER (this) { 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);
} }
} }
) )

View file

@ -162,6 +162,7 @@ if get_option('retro') == true
include_directories('.'), include_directories('.'),
include_directories('src'), include_directories('src'),
include_directories('src/display'), include_directories('src/display'),
include_directories('src/display/gl'),
include_directories('src/etc'), include_directories('src/etc'),
include_directories('src/util'), include_directories('src/util'),
include_directories(retro_phase1), include_directories(retro_phase1),
@ -170,6 +171,11 @@ if get_option('retro') == true
], ],
sources: [ sources: [
'src/core.cpp', '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/etc.cpp',
'src/etc/table.cpp', 'src/etc/table.cpp',
'binding-sandbox/binding-util.cpp', 'binding-sandbox/binding-util.cpp',

View file

@ -60,6 +60,8 @@ ARG_HANDLERS = {
'unsigned long' => { primitive: :size }, 'unsigned long' => { primitive: :size },
'long long' => { primitive: :s64 }, 'long long' => { primitive: :s64 },
'unsigned long long' => { primitive: :u64 }, 'unsigned long long' => { primitive: :u64 },
'float' => { primitive: :f32 },
'double' => { primitive: :f64 },
'const char *' => { 'const char *' => {
keep: true, keep: true,
buf_size: 'std::strlen(ARG) + 1', buf_size: 'std::strlen(ARG) + 1',
@ -127,6 +129,8 @@ RET_HANDLERS = {
'unsigned long' => { primitive: :size }, 'unsigned long' => { primitive: :size },
'long long' => { primitive: :s64 }, 'long long' => { primitive: :s64 },
'unsigned long long' => { primitive: :u64 }, 'unsigned long long' => { primitive: :u64 },
'float' => { primitive: :f32 },
'double' => { primitive: :f64 },
'char *' => { primitive: :ptr }, 'char *' => { primitive: :ptr },
'const char *' => { primitive: :ptr }, 'const char *' => { primitive: :ptr },
} }

View file

@ -109,6 +109,8 @@ static bool init_sandbox() {
mkxp_retro::sandbox.reset(); mkxp_retro::sandbox.reset();
SharedState::initInstance(NULL);
try { try {
mkxp_retro::sandbox.reset(new struct sandbox(game_path)); mkxp_retro::sandbox.reset(new struct sandbox(game_path));
sb().run<struct main>(); sb().run<struct main>();

View file

@ -21,6 +21,7 @@
#include "bitmap.h" #include "bitmap.h"
#ifndef MKXPZ_RETRO
#include <SDL.h> #include <SDL.h>
#include <SDL_image.h> #include <SDL_image.h>
#include <SDL_ttf.h> #include <SDL_ttf.h>
@ -33,18 +34,25 @@
#include "gl-meta.h" #include "gl-meta.h"
#include "quad.h" #include "quad.h"
#include "quadarray.h" #include "quadarray.h"
#endif // MKXPZ_RETRO
#include "transform.h" #include "transform.h"
#include "exception.h" #include "exception.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "glstate.h" #include "glstate.h"
#ifndef MKXPZ_RETRO
#include "texpool.h" #include "texpool.h"
#include "shader.h" #include "shader.h"
#include "filesystem.h" #include "filesystem.h"
#endif // MKXPZ_RETRO
#include "font.h" #include "font.h"
#ifndef MKXPZ_RETRO
#include "eventthread.h" #include "eventthread.h"
#endif // MKXPZ_RETRO
#include "graphics.h" #include "graphics.h"
#ifndef MKXPZ_RETRO
#include "system.h" #include "system.h"
#endif // MKXPZ_RETRO
#include "util/util.h" #include "util/util.h"
#include "debugwriter.h" #include "debugwriter.h"
@ -163,7 +171,9 @@ struct BitmapPrivate
bool playing; bool playing;
bool needsReset; bool needsReset;
bool loop; bool loop;
#ifndef MKXPZ_RETRO
std::vector<TEXFBO> frames; std::vector<TEXFBO> frames;
#endif // MKXPZ_RETRO
float fps; float fps;
int lastFrame; int lastFrame;
double startTime, playTime; double startTime, playTime;
@ -173,6 +183,7 @@ struct BitmapPrivate
return floor(lastFrame + (playTime / (1 / fps))); return floor(lastFrame + (playTime / (1 / fps)));
} }
#ifndef MKXPZ_RETRO
unsigned int currentFrameI() { unsigned int currentFrameI() {
if (!playing || needsReset) return lastFrame; if (!playing || needsReset) return lastFrame;
int i = currentFrameIRaw(); int i = currentFrameIRaw();
@ -183,6 +194,7 @@ struct BitmapPrivate
int i = currentFrameI(); int i = currentFrameI();
return frames[i]; return frames[i];
} }
#endif // MKXPZ_RETRO
inline void play() { inline void play() {
playing = true; playing = true;
@ -190,17 +202,23 @@ struct BitmapPrivate
} }
inline void stop() { inline void stop() {
#ifndef MKXPZ_RETRO
lastFrame = currentFrameI(); lastFrame = currentFrameI();
#endif // MKXPZ_RETRO
playing = false; playing = false;
} }
inline void seek(int frame) { inline void seek(int frame) {
#ifndef MKXPZ_RETRO
lastFrame = clamp(frame, 0, (int)frames.size()); lastFrame = clamp(frame, 0, (int)frames.size());
#endif // MKXPZ_RETRO
} }
void updateTimer() { void updateTimer() {
if (needsReset) { if (needsReset) {
#ifndef MKXPZ_RETRO
lastFrame = currentFrameI(); lastFrame = currentFrameI();
#endif // MKXPZ_RETRO
playTime = 0; playTime = 0;
startTime = shState->runTime(); startTime = shState->runTime();
needsReset = false; needsReset = false;
@ -214,7 +232,9 @@ struct BitmapPrivate
sigslot::connection prepareCon; sigslot::connection prepareCon;
#ifndef MKXPZ_RETRO
TEXFBO gl; TEXFBO gl;
#endif // MKXPZ_RETRO
Font *font; Font *font;
@ -228,6 +248,7 @@ struct BitmapPrivate
* getPixel calls. Is invalidated any time the bitmap * getPixel calls. Is invalidated any time the bitmap
* is modified */ * is modified */
SDL_Surface *surface; SDL_Surface *surface;
#ifndef MKXPZ_RETRO
SDL_PixelFormat *format; SDL_PixelFormat *format;
/* The 'tainted' area describes which parts of the /* The 'tainted' area describes which parts of the
@ -237,6 +258,7 @@ struct BitmapPrivate
* in the texture and blit to it directly, saving * in the texture and blit to it directly, saving
* ourselves the expensive blending calculation */ * ourselves the expensive blending calculation */
pixman_region16_t tainted; pixman_region16_t tainted;
#endif // MKXPZ_RETRO
// For high-resolution texture replacement. // For high-resolution texture replacement.
Bitmap *selfHires; Bitmap *selfHires;
@ -251,7 +273,9 @@ struct BitmapPrivate
surface(0), surface(0),
assumingRubyGC(false) assumingRubyGC(false)
{ {
#ifndef MKXPZ_RETRO
format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888); format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
#endif // MKXPZ_RETRO
animation.width = 0; animation.width = 0;
animation.height = 0; animation.height = 0;
@ -265,20 +289,26 @@ struct BitmapPrivate
prepareCon = shState->prepareDraw.connect(&BitmapPrivate::prepare, this); prepareCon = shState->prepareDraw.connect(&BitmapPrivate::prepare, this);
#ifndef MKXPZ_RETRO
font = &shState->defaultFont(); font = &shState->defaultFont();
pixman_region_init(&tainted); pixman_region_init(&tainted);
#endif // MKXPZ_RETRO
} }
~BitmapPrivate() ~BitmapPrivate()
{ {
prepareCon.disconnect(); prepareCon.disconnect();
#ifndef MKXPZ_RETRO
SDL_FreeFormat(format); SDL_FreeFormat(format);
pixman_region_fini(&tainted); pixman_region_fini(&tainted);
#endif // MKXPZ_RETRO
} }
#ifndef MKXPZ_RETRO
TEXFBO &getGLTypes() { TEXFBO &getGLTypes() {
return (animation.enabled) ? animation.currentFrame() : gl; return (animation.enabled) ? animation.currentFrame() : gl;
} }
#endif // MKXPZ_RETRO
void prepare() void prepare()
{ {
@ -289,22 +319,28 @@ struct BitmapPrivate
void allocSurface() void allocSurface()
{ {
#ifndef MKXPZ_RETRO
surface = SDL_CreateRGBSurface(0, gl.width, gl.height, format->BitsPerPixel, surface = SDL_CreateRGBSurface(0, gl.width, gl.height, format->BitsPerPixel,
format->Rmask, format->Gmask, format->Rmask, format->Gmask,
format->Bmask, format->Amask); format->Bmask, format->Amask);
#endif // MKXPZ_RETRO
} }
void clearTaintedArea() void clearTaintedArea()
{ {
#ifndef MKXPZ_RETRO
pixman_region_fini(&tainted); pixman_region_fini(&tainted);
pixman_region_init(&tainted); pixman_region_init(&tainted);
#endif // MKXPZ_RETRO
} }
void addTaintedArea(const IntRect &rect) void addTaintedArea(const IntRect &rect)
{ {
#ifndef MKXPZ_RETRO
IntRect norm = normalizedRect(rect); IntRect norm = normalizedRect(rect);
pixman_region_union_rect pixman_region_union_rect
(&tainted, &tainted, norm.x, norm.y, norm.w, norm.h); (&tainted, &tainted, norm.x, norm.y, norm.w, norm.h);
#endif // MKXPZ_RETRO
} }
void substractTaintedArea(const IntRect &rect) void substractTaintedArea(const IntRect &rect)
@ -312,16 +348,21 @@ struct BitmapPrivate
if (!touchesTaintedArea(rect)) if (!touchesTaintedArea(rect))
return; return;
#ifndef MKXPZ_RETRO
pixman_region16_t m_reg; pixman_region16_t m_reg;
pixman_region_init_rect(&m_reg, rect.x, rect.y, rect.w, rect.h); pixman_region_init_rect(&m_reg, rect.x, rect.y, rect.w, rect.h);
pixman_region_subtract(&tainted, &m_reg, &tainted); pixman_region_subtract(&tainted, &m_reg, &tainted);
pixman_region_fini(&m_reg); pixman_region_fini(&m_reg);
#endif // MKXPZ_RETRO
} }
bool touchesTaintedArea(const IntRect &rect) bool touchesTaintedArea(const IntRect &rect)
{ {
#ifdef MKXPZ_RETRO
return false; // TODO: implement
#else
pixman_box16_t box; pixman_box16_t box;
box.x1 = rect.x; box.x1 = rect.x;
box.y1 = rect.y; box.y1 = rect.y;
@ -332,6 +373,7 @@ struct BitmapPrivate
pixman_region_contains_rectangle(&tainted, &box); pixman_region_contains_rectangle(&tainted, &box);
return result != PIXMAN_REGION_OUT; return result != PIXMAN_REGION_OUT;
#endif // MKXPZ_RETRO
} }
void bindTexture(ShaderBase &shader, bool substituteLoresSize = true) void bindTexture(ShaderBase &shader, bool substituteLoresSize = true)
@ -346,11 +388,14 @@ struct BitmapPrivate
Debug() << "BUG: High-res BitmapPrivate bindTexture for animations not implemented"; Debug() << "BUG: High-res BitmapPrivate bindTexture for animations not implemented";
} }
#ifndef MKXPZ_RETRO
TEXFBO cframe = animation.currentFrame(); TEXFBO cframe = animation.currentFrame();
TEX::bind(cframe.tex); TEX::bind(cframe.tex);
shader.setTexSize(Vec2i(cframe.width, cframe.height)); shader.setTexSize(Vec2i(cframe.width, cframe.height));
#endif // MKXPZ_RETRO
return; return;
} }
#ifndef MKXPZ_RETRO
TEX::bind(gl.tex); TEX::bind(gl.tex);
if (selfLores && substituteLoresSize) { if (selfLores && substituteLoresSize) {
shader.setTexSize(Vec2i(selfLores->width(), selfLores->height())); shader.setTexSize(Vec2i(selfLores->width(), selfLores->height()));
@ -358,17 +403,22 @@ struct BitmapPrivate
else { else {
shader.setTexSize(Vec2i(gl.width, gl.height)); shader.setTexSize(Vec2i(gl.width, gl.height));
} }
#endif // MKXPZ_RETRO
} }
void bindFBO() void bindFBO()
{ {
#ifndef MKXPZ_RETRO
FBO::bind((animation.enabled) ? animation.currentFrame().fbo : gl.fbo); FBO::bind((animation.enabled) ? animation.currentFrame().fbo : gl.fbo);
#endif // MKXPZ_RETRO
} }
void pushSetViewport(ShaderBase &shader) const void pushSetViewport(ShaderBase &shader) const
{ {
#ifndef MKXPZ_RETRO
glState.viewport.pushSet(IntRect(0, 0, gl.width, gl.height)); glState.viewport.pushSet(IntRect(0, 0, gl.width, gl.height));
shader.applyViewportProj(); shader.applyViewportProj();
#endif // MKXPZ_RETRO
} }
void popViewport() const void popViewport() const
@ -379,7 +429,9 @@ struct BitmapPrivate
void blitQuad(Quad &quad) void blitQuad(Quad &quad)
{ {
glState.blend.pushSet(false); glState.blend.pushSet(false);
#ifndef MKXPZ_RETRO
quad.draw(); quad.draw();
#endif // MKXPZ_RETRO
glState.blend.pop(); glState.blend.pop();
} }
@ -388,6 +440,7 @@ struct BitmapPrivate
{ {
bindFBO(); bindFBO();
#ifndef MKXPZ_RETRO
glState.scissorTest.pushSet(true); glState.scissorTest.pushSet(true);
glState.scissorBox.pushSet(normalizedRect(rect)); glState.scissorBox.pushSet(normalizedRect(rect));
glState.clearColor.pushSet(color); glState.clearColor.pushSet(color);
@ -397,8 +450,10 @@ struct BitmapPrivate
glState.clearColor.pop(); glState.clearColor.pop();
glState.scissorBox.pop(); glState.scissorBox.pop();
glState.scissorTest.pop(); glState.scissorTest.pop();
#endif // MKXPZ_RETRO
} }
#ifndef MKXPZ_RETRO
static void ensureFormat(SDL_Surface *&surf, Uint32 format) static void ensureFormat(SDL_Surface *&surf, Uint32 format)
{ {
if (surf->format->format == format) if (surf->format->format == format)
@ -408,12 +463,15 @@ struct BitmapPrivate
SDL_FreeSurface(surf); SDL_FreeSurface(surf);
surf = surfConv; surf = surfConv;
} }
#endif // MKXPZ_RETRO
void onModified(bool freeSurface = true) void onModified(bool freeSurface = true)
{ {
if (surface && freeSurface) if (surface && freeSurface)
{ {
#ifndef MKXPZ_RETRO
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
#endif // MKXPZ_RETRO
surface = 0; surface = 0;
} }
@ -421,6 +479,7 @@ struct BitmapPrivate
} }
}; };
#ifndef MKXPZ_RETRO
struct BitmapOpenHandler : FileSystem::OpenHandler struct BitmapOpenHandler : FileSystem::OpenHandler
{ {
// Non-GIF // Non-GIF
@ -487,12 +546,14 @@ struct BitmapOpenHandler : FileSystem::OpenHandler
return (surface || gif); return (surface || gif);
} }
}; };
#endif // MKXPZ_RETRO
Bitmap::Bitmap(const char *filename) Bitmap::Bitmap(const char *filename)
{ {
std::string hiresPrefix = "Hires/"; std::string hiresPrefix = "Hires/";
std::string filenameStd = filename; std::string filenameStd = filename;
Bitmap *hiresBitmap = nullptr; Bitmap *hiresBitmap = nullptr;
#ifndef MKXPZ_RETRO
// TODO: once C++20 is required, switch to filenameStd.starts_with(hiresPrefix) // TODO: once C++20 is required, switch to filenameStd.starts_with(hiresPrefix)
if (shState->config().enableHires && filenameStd.compare(0, hiresPrefix.size(), hiresPrefix) != 0) { if (shState->config().enableHires && filenameStd.compare(0, hiresPrefix.size(), hiresPrefix) != 0) {
// Look for a high-res version of the file. // Look for a high-res version of the file.
@ -632,6 +693,7 @@ Bitmap::Bitmap(const char *filename)
SDL_Surface *imgSurf = handler.surface; SDL_Surface *imgSurf = handler.surface;
initFromSurface(imgSurf, hiresBitmap, false); initFromSurface(imgSurf, hiresBitmap, false);
#endif // MKXPZ_RETRO
} }
Bitmap::Bitmap(int width, int height, bool isHires) Bitmap::Bitmap(int width, int height, bool isHires)
@ -641,6 +703,7 @@ Bitmap::Bitmap(int width, int height, bool isHires)
Bitmap *hiresBitmap = nullptr; Bitmap *hiresBitmap = nullptr;
#ifndef MKXPZ_RETRO
if (shState->config().enableHires && !isHires) { if (shState->config().enableHires && !isHires) {
// Create a high-res version as well. // Create a high-res version as well.
double scalingFactor = shState->config().textureScalingFactor; double scalingFactor = shState->config().textureScalingFactor;
@ -658,19 +721,23 @@ Bitmap::Bitmap(int width, int height, bool isHires)
delete hiresBitmap; delete hiresBitmap;
throw e; throw e;
} }
#endif // MKXPZ_RETRO
p = new BitmapPrivate(this); p = new BitmapPrivate(this);
#ifndef MKXPZ_RETRO
p->gl = tex; p->gl = tex;
p->selfHires = hiresBitmap; p->selfHires = hiresBitmap;
if (p->selfHires != nullptr) { if (p->selfHires != nullptr) {
p->gl.selfHires = &p->selfHires->getGLTypes(); p->gl.selfHires = &p->selfHires->getGLTypes();
} }
#endif // MKXPZ_RETRO
clear(); clear();
} }
Bitmap::Bitmap(void *pixeldata, int width, int height) Bitmap::Bitmap(void *pixeldata, int width, int height)
{ {
#ifndef MKXPZ_RETRO
SDL_Surface *surface = SDL_CreateRGBSurface(0, width, height, p->format->BitsPerPixel, SDL_Surface *surface = SDL_CreateRGBSurface(0, width, height, p->format->BitsPerPixel,
p->format->Rmask, p->format->Rmask,
p->format->Gmask, p->format->Gmask,
@ -703,7 +770,9 @@ Bitmap::Bitmap(void *pixeldata, int width, int height)
throw e; throw e;
} }
#endif // MKXPZ_RETRO
p = new BitmapPrivate(this); p = new BitmapPrivate(this);
#ifndef MKXPZ_RETRO
p->gl = tex; p->gl = tex;
TEX::bind(p->gl.tex); TEX::bind(p->gl.tex);
@ -711,6 +780,7 @@ Bitmap::Bitmap(void *pixeldata, int width, int height)
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
} }
#endif // MKXPZ_RETRO
p->addTaintedArea(rect()); p->addTaintedArea(rect());
} }
@ -730,6 +800,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame)
// TODO: Clean me up // TODO: Clean me up
if (!other.isAnimated() || frame >= -1) { if (!other.isAnimated() || frame >= -1) {
#ifndef MKXPZ_RETRO
try { try {
p->gl = shState->texPool().request(other.width(), other.height()); p->gl = shState->texPool().request(other.width(), other.height());
} catch (const Exception &e) { } catch (const Exception &e) {
@ -748,6 +819,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame)
} }
GLMeta::blitRectangle(rect(), rect()); GLMeta::blitRectangle(rect(), rect());
GLMeta::blitEnd(); GLMeta::blitEnd();
#endif // MKXPZ_RETRO
} }
else { else {
p->animation.enabled = true; p->animation.enabled = true;
@ -759,6 +831,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame)
p->animation.startTime = 0; p->animation.startTime = 0;
p->animation.loop = other.getLooping(); p->animation.loop = other.getLooping();
#ifndef MKXPZ_RETRO
for (TEXFBO &sourceframe : other.getFrames()) { for (TEXFBO &sourceframe : other.getFrames()) {
TEXFBO newframe; TEXFBO newframe;
try { try {
@ -775,6 +848,7 @@ Bitmap::Bitmap(const Bitmap &other, int frame)
p->animation.frames.push_back(newframe); p->animation.frames.push_back(newframe);
} }
#endif // MKXPZ_RETRO
} }
p->addTaintedArea(rect()); p->addTaintedArea(rect());
@ -784,15 +858,18 @@ Bitmap::Bitmap(TEXFBO &other)
{ {
Bitmap *hiresBitmap = nullptr; Bitmap *hiresBitmap = nullptr;
#ifndef MKXPZ_RETRO
if (other.selfHires != nullptr) { if (other.selfHires != nullptr) {
// Create a high-res version as well. // Create a high-res version as well.
hiresBitmap = new Bitmap(*other.selfHires); hiresBitmap = new Bitmap(*other.selfHires);
hiresBitmap->setLores(this); hiresBitmap->setLores(this);
} }
#endif // MKXPZ_RETRO
p = new BitmapPrivate(this); p = new BitmapPrivate(this);
p->selfHires = hiresBitmap; p->selfHires = hiresBitmap;
#ifndef MKXPZ_RETRO
try { try {
p->gl = shState->texPool().request(other.width, other.height); p->gl = shState->texPool().request(other.width, other.height);
} catch (const Exception &e) { } catch (const Exception &e) {
@ -811,6 +888,7 @@ Bitmap::Bitmap(TEXFBO &other)
GLMeta::blitRectangle(rect(), rect()); GLMeta::blitRectangle(rect(), rect());
GLMeta::blitEnd(); GLMeta::blitEnd();
} }
#endif // MKXPZ_RETRO
p->addTaintedArea(rect()); p->addTaintedArea(rect());
} }
@ -837,6 +915,7 @@ Bitmap::~Bitmap()
void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool forceMega) void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool forceMega)
{ {
#ifndef MKXPZ_RETRO
p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888); p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888);
if (imgSurf->w > glState.caps.maxTexSize || imgSurf->h > glState.caps.maxTexSize || forceMega) 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; throw e;
} }
#endif // MKXPZ_RETRO
p = new BitmapPrivate(this); p = new BitmapPrivate(this);
p->selfHires = hiresBitmap; p->selfHires = hiresBitmap;
#ifndef MKXPZ_RETRO
p->gl = tex; p->gl = tex;
if (p->selfHires != nullptr) { if (p->selfHires != nullptr) {
p->gl.selfHires = &p->selfHires->getGLTypes(); p->gl.selfHires = &p->selfHires->getGLTypes();
@ -877,6 +958,7 @@ void Bitmap::initFromSurface(SDL_Surface *imgSurf, Bitmap *hiresBitmap, bool for
SDL_FreeSurface(imgSurf); SDL_FreeSurface(imgSurf);
} }
#endif // MKXPZ_RETRO
p->addTaintedArea(rect()); p->addTaintedArea(rect());
} }
@ -885,6 +967,9 @@ int Bitmap::width() const
{ {
guardDisposed(); guardDisposed();
#ifdef MKXPZ_RETRO
return 32; // TODO: implement
#else
if (p->megaSurface) { if (p->megaSurface) {
return p->megaSurface->w; return p->megaSurface->w;
} }
@ -894,12 +979,16 @@ int Bitmap::width() const
} }
return p->gl.width; return p->gl.width;
#endif // MKXPZ_RETRO
} }
int Bitmap::height() const int Bitmap::height() const
{ {
guardDisposed(); guardDisposed();
#ifdef MKXPZ_RETRO
return 32; // TODO: implement
#else
if (p->megaSurface) if (p->megaSurface)
return p->megaSurface->h; return p->megaSurface->h;
@ -907,6 +996,7 @@ int Bitmap::height() const
return p->animation.height; return p->animation.height;
return p->gl.height; return p->gl.height;
#endif // MKXPZ_RETRO
} }
bool Bitmap::hasHires() const{ bool Bitmap::hasHires() const{
@ -1085,6 +1175,7 @@ void Bitmap::stretchBlt(IntRect destRect,
SDL_Surface *srcSurf = source.megaSurface(); SDL_Surface *srcSurf = source.megaSurface();
SDL_Surface *blitTemp = 0; SDL_Surface *blitTemp = 0;
bool touchesTaintedArea = p->touchesTaintedArea(destRect); bool touchesTaintedArea = p->touchesTaintedArea(destRect);
#ifndef MKXPZ_RETRO
bool unpack_subimage = srcSurf && gl.unpack_subimage; bool unpack_subimage = srcSurf && gl.unpack_subimage;
const bool scaleIsOne = sourceRect.w == destRect.w && sourceRect.h == destRect.h; const bool scaleIsOne = sourceRect.w == destRect.w && sourceRect.h == destRect.h;
@ -1317,6 +1408,7 @@ void Bitmap::stretchBlt(IntRect destRect,
if (blitTemp) if (blitTemp)
SDL_FreeSurface(blitTemp); SDL_FreeSurface(blitTemp);
#endif // MKXPZ_RETRO
p->addTaintedArea(destRect); p->addTaintedArea(destRect);
p->onModified(); p->onModified();
@ -1385,6 +1477,7 @@ void Bitmap::gradientFillRect(const IntRect &rect,
p->selfHires->gradientFillRect(IntRect(destX, destY, destWidth, destHeight), color1, color2, vertical); p->selfHires->gradientFillRect(IntRect(destX, destY, destWidth, destHeight), color1, color2, vertical);
} }
#ifndef MKXPZ_RETRO
SimpleColorShader &shader = shState->shaders().simpleColor; SimpleColorShader &shader = shState->shaders().simpleColor;
shader.bind(); shader.bind();
shader.setTranslation(Vec2i()); shader.setTranslation(Vec2i());
@ -1414,6 +1507,7 @@ void Bitmap::gradientFillRect(const IntRect &rect,
p->blitQuad(quad); p->blitQuad(quad);
p->popViewport(); p->popViewport();
#endif // MKXPZ_RETRO
p->addTaintedArea(rect); 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? // TODO: Is there some kind of blur radius that we need to handle for high-res mode?
#ifndef MKXPZ_RETRO
Quad &quad = shState->gpQuad(); Quad &quad = shState->gpQuad();
FloatRect rect(0, 0, width(), height()); FloatRect rect(0, 0, width(), height());
quad.setTexPosRect(rect, rect); quad.setTexPosRect(rect, rect);
@ -1495,6 +1590,7 @@ void Bitmap::blur()
glState.blend.pop(); glState.blend.pop();
shState->texPool().release(auxTex); shState->texPool().release(auxTex);
#endif // MKXPZ_RETRO
p->onModified(); p->onModified();
} }
@ -1521,6 +1617,7 @@ void Bitmap::radialBlur(int angle, int divisions)
float opacity = 1.0f / divisions; float opacity = 1.0f / divisions;
float baseAngle = -((float) angle / 2); float baseAngle = -((float) angle / 2);
#ifndef MKXPZ_RETRO
ColorQuadArray qArray; ColorQuadArray qArray;
qArray.resize(5); qArray.resize(5);
@ -1597,6 +1694,7 @@ void Bitmap::radialBlur(int angle, int divisions)
shState->texPool().release(p->gl); shState->texPool().release(p->gl);
p->gl = newTex; p->gl = newTex;
#endif // MKXPZ_RETRO
p->onModified(); p->onModified();
} }
@ -1613,17 +1711,20 @@ void Bitmap::clear()
p->bindFBO(); p->bindFBO();
#ifndef MKXPZ_RETRO
glState.clearColor.pushSet(Vec4()); glState.clearColor.pushSet(Vec4());
FBO::clear(); FBO::clear();
glState.clearColor.pop(); glState.clearColor.pop();
#endif // MKXPZ_RETRO
p->clearTaintedArea(); p->clearTaintedArea();
p->onModified(); p->onModified();
} }
#ifndef MKXPZ_RETRO
static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int y) static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int y)
{ {
size_t offset = x*form->BytesPerPixel + y*surf->pitch; 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); return *((uint32_t*) bytes);
} }
#endif // MKXPZ_RETRO
Color Bitmap::getPixel(int x, int y) const Color Bitmap::getPixel(int x, int y) const
{ {
@ -1689,6 +1791,7 @@ Color Bitmap::getPixel(int x, int y) const
{ {
p->allocSurface(); p->allocSurface();
#ifndef MKXPZ_RETRO
FBO::bind(p->gl.fbo); FBO::bind(p->gl.fbo);
glState.viewport.pushSet(IntRect(0, 0, width(), height())); 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); gl.ReadPixels(0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_BYTE, p->surface->pixels);
glState.viewport.pop(); glState.viewport.pop();
#endif // MKXPZ_RETRO
} }
#ifdef MKXPZ_RETRO
return Color(); // TODO: implement
#else
uint32_t pixel = getPixelAt(p->surface, p->format, x, y); uint32_t pixel = getPixelAt(p->surface, p->format, x, y);
return Color((pixel >> p->format->Rshift) & 0xFF, return Color((pixel >> p->format->Rshift) & 0xFF,
(pixel >> p->format->Gshift) & 0xFF, (pixel >> p->format->Gshift) & 0xFF,
(pixel >> p->format->Bshift) & 0xFF, (pixel >> p->format->Bshift) & 0xFF,
(pixel >> p->format->Ashift) & 0xFF); (pixel >> p->format->Ashift) & 0xFF);
#endif // MKXPZ_RETRO
} }
void Bitmap::setPixel(int x, int y, const Color &color) 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<double>(color.alpha, 0, 255) (uint8_t) clamp<double>(color.alpha, 0, 255)
}; };
#ifndef MKXPZ_RETRO
TEX::bind(p->gl.tex); TEX::bind(p->gl.tex);
TEX::uploadSubImage(x, y, 1, 1, &pixel, GL_RGBA); TEX::uploadSubImage(x, y, 1, 1, &pixel, GL_RGBA);
#endif // MKXPZ_RETRO
p->addTaintedArea(IntRect(x, y, 1, 1)); p->addTaintedArea(IntRect(x, y, 1, 1));
/* Setting just a single pixel is no reason to throw away the /* Setting just a single pixel is no reason to throw away the
* whole cached surface; we can just apply the same change */ * whole cached surface; we can just apply the same change */
#ifndef MKXPZ_RETRO
if (p->surface) if (p->surface)
{ {
uint32_t &surfPixel = getPixelAt(p->surface, p->format, x, y); uint32_t &surfPixel = getPixelAt(p->surface, p->format, x, y);
surfPixel = SDL_MapRGBA(p->format, pixel[0], pixel[1], pixel[2], pixel[3]); surfPixel = SDL_MapRGBA(p->format, pixel[0], pixel[1], pixel[2], pixel[3]);
} }
#endif // MKXPZ_RETRO
p->onModified(false); 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."; 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)) { if (!p->animation.enabled && (p->surface || p->megaSurface)) {
void *src = (p->megaSurface) ? p->megaSurface->pixels : p->surface->pixels; void *src = (p->megaSurface) ? p->megaSurface->pixels : p->surface->pixels;
memcpy(output, src, output_size); memcpy(output, src, output_size);
@ -1774,6 +1887,7 @@ bool Bitmap::getRaw(void *output, int output_size)
FBO::bind(getGLTypes().fbo); FBO::bind(getGLTypes().fbo);
gl.ReadPixels(0,0,width(),height(),GL_RGBA,GL_UNSIGNED_BYTE,output); gl.ReadPixels(0,0,width(),height(),GL_RGBA,GL_UNSIGNED_BYTE,output);
} }
#endif // MKXPZ_RETRO
return true; return true;
} }
@ -1794,8 +1908,10 @@ void Bitmap::replaceRaw(void *pixel_data, int size)
if (size != w*h*4) if (size != w*h*4)
throw Exception(Exception::MKXPError, "Replacement bitmap data is not large enough (given %i bytes, need %i)", size, requiredsize); 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::bind(getGLTypes().tex);
TEX::uploadImage(w, h, pixel_data, GL_RGBA); TEX::uploadImage(w, h, pixel_data, GL_RGBA);
#endif // MKXPZ_RETRO
taintArea(IntRect(0,0,w,h)); taintArea(IntRect(0,0,w,h));
p->onModified(); p->onModified();
@ -1815,12 +1931,14 @@ void Bitmap::saveToFile(const char *filename)
surf = (p->surface) ? p->surface : p->megaSurface; surf = (p->surface) ? p->surface : p->megaSurface;
} }
else { 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); surf = SDL_CreateRGBSurface(0, width(), height(),p->format->BitsPerPixel, p->format->Rmask,p->format->Gmask,p->format->Bmask,p->format->Amask);
if (!surf) if (!surf)
throw Exception(Exception::SDLError, "Failed to prepare bitmap for saving: %s", SDL_GetError()); throw Exception(Exception::SDLError, "Failed to prepare bitmap for saving: %s", SDL_GetError());
getRaw(surf->pixels, surf->w * surf->h * 4); getRaw(surf->pixels, surf->w * surf->h * 4);
#endif // MKXPZ_RETRO
} }
// Try and determine the intended image format from the filename extension // 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); std::string fn_normalized = shState->fileSystem().normalize(filename, 1, 1);
int rc; int rc;
switch (filetype) { switch (filetype) {
@ -1859,6 +1978,7 @@ void Bitmap::saveToFile(const char *filename)
SDL_FreeSurface(surf); SDL_FreeSurface(surf);
if (rc) throw Exception(Exception::SDLError, "%s", SDL_GetError()); if (rc) throw Exception(Exception::SDLError, "%s", SDL_GetError());
#endif // MKXPZ_RETRO
} }
void Bitmap::hueChange(int hue) void Bitmap::hueChange(int hue)
@ -1876,6 +1996,7 @@ void Bitmap::hueChange(int hue)
if ((hue % 360) == 0) if ((hue % 360) == 0)
return; return;
#ifndef MKXPZ_RETRO
TEXFBO newTex = shState->texPool().request(width(), height()); TEXFBO newTex = shState->texPool().request(width(), height());
FloatRect texRect(rect()); FloatRect texRect(rect());
@ -1901,6 +2022,7 @@ void Bitmap::hueChange(int hue)
shState->texPool().release(p->gl); shState->texPool().release(p->gl);
p->gl = newTex; p->gl = newTex;
#endif // MKXPZ_RETRO
p->onModified(); p->onModified();
} }
@ -1927,6 +2049,7 @@ static std::string fixupString(const char *str)
return s; return s;
} }
#ifndef MKXPZ_RETRO
static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_Color &c) static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_Color &c)
{ {
SDL_Surface *out = SDL_CreateRGBSurface 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); SDL_FreeSurface(in);
in = out; in = out;
} }
#endif // MKXPZ_RETRO
void Bitmap::drawText(const IntRect &rect, const char *str, int align) 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_MEGA;
GUARD_ANIMATED; GUARD_ANIMATED;
#ifndef MKXPZ_RETRO
if (hasHires()) { if (hasHires()) {
Font &loresFont = getFont(); Font &loresFont = getFont();
Font &hiresFont = p->selfHires->getFont(); Font &hiresFont = p->selfHires->getFont();
@ -2042,6 +2167,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
return; return;
} }
#endif // MKXPZ_RETRO
std::string fixed = fixupString(str); std::string fixed = fixupString(str);
str = fixed.c_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') if (str[0] == ' ' && str[1] == '\0')
return; return;
#ifndef MKXPZ_RETRO
TTF_Font *font = p->font->getSdlFont(); TTF_Font *font = p->font->getSdlFont();
const Color &fontColor = p->font->getColor(); const Color &fontColor = p->font->getColor();
const Color &outColor = p->font->getOutColor(); 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); Bitmap txtBitmap(txtSurf, nullptr, true);
bool smooth = squeeze != 1.0f; bool smooth = squeeze != 1.0f;
stretchBlt(destRect, txtBitmap, sourceRect, fontColor.alpha, smooth); stretchBlt(destRect, txtBitmap, sourceRect, fontColor.alpha, smooth);
#endif // MKXPZ_RETRO
} }
/* http://www.lemoda.net/c/utf8-to-ucs2/index.html */ /* 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? // TODO: High-res Bitmap textSize not implemented, but I think it's the same as low-res?
// Need to double-check this. // Need to double-check this.
#ifdef MKXPZ_RETRO
return IntRect(); // TODO: implement
#else
TTF_Font *font = p->font->getSdlFont(); TTF_Font *font = p->font->getSdlFont();
std::string fixed = fixupString(str); std::string fixed = fixupString(str);
@ -2218,6 +2349,7 @@ IntRect Bitmap::textSize(const char *str)
TTF_GlyphMetrics(font, ucs2, 0, 0, 0, 0, &w); TTF_GlyphMetrics(font, ucs2, 0, 0, 0, 0, &w);
return IntRect(0, 0, w, h); return IntRect(0, 0, w, h);
#endif // MKXPZ_RETRO
} }
DEF_ATTR_RD_SIMPLE(Bitmap, Font, Font&, *p->font) 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) void Bitmap::setFont(Font &value)
{ {
// High-res support handled in drawText, not here. // High-res support handled in drawText, not here.
#ifndef MKXPZ_RETRO
*p->font = value; *p->font = value;
#endif // MKXPZ_RETRO
} }
void Bitmap::setInitFont(Font *value) void Bitmap::setInitFont(Font *value)
{ {
if (hasHires()) { if (hasHires()) {
Font *hiresFont = p->selfHires->p->font; Font *hiresFont = p->selfHires->p->font;
#ifndef MKXPZ_RETRO
if (hiresFont && hiresFont != &shState->defaultFont()) if (hiresFont && hiresFont != &shState->defaultFont())
{ {
// Disable the illegal font size check when creating a high-res font. // Disable the illegal font size check when creating a high-res font.
hiresFont->setSize(hiresFont->getSize() * p->selfHires->width() / width(), false); hiresFont->setSize(hiresFont->getSize() * p->selfHires->width() / width(), false);
} }
#endif // MKXPZ_RETRO
} }
p->font = value; p->font = value;
} }
#ifndef MKXPZ_RETRO
TEXFBO &Bitmap::getGLTypes() const TEXFBO &Bitmap::getGLTypes() const
{ {
return p->getGLTypes(); return p->getGLTypes();
} }
#endif // MKXPZ_RETRO
SDL_Surface *Bitmap::surface() const SDL_Surface *Bitmap::surface() const
{ {
@ -2336,7 +2474,11 @@ bool Bitmap::isPlaying() const
if (p->animation.loop) if (p->animation.loop)
return true; return true;
#ifdef MKXPZ_RETRO
return false; // TODO: implement
#else
return p->animation.currentFrameIRaw() < p->animation.frames.size(); return p->animation.currentFrameIRaw() < p->animation.frames.size();
#endif // MKXPZ_RETRO
} }
void Bitmap::gotoAndStop(int frame) void Bitmap::gotoAndStop(int frame)
@ -2376,9 +2518,14 @@ int Bitmap::numFrames() const
} }
if (!p->animation.enabled) return 1; if (!p->animation.enabled) return 1;
#ifdef MKXPZ_RETRO
return 0; // TODO: implement
#else
return (int)p->animation.frames.size(); return (int)p->animation.frames.size();
#endif // MKXPZ_RETRO
} }
#ifndef MKXPZ_RETRO
int Bitmap::currentFrameI() const int Bitmap::currentFrameI() const
{ {
guardDisposed(); guardDisposed();
@ -2390,6 +2537,7 @@ int Bitmap::currentFrameI() const
if (!p->animation.enabled) return 0; if (!p->animation.enabled) return 0;
return p->animation.currentFrameI(); return p->animation.currentFrameI();
} }
#endif // MKXPZ_RETRO
int Bitmap::addFrame(Bitmap &source, int position) 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)", throw Exception(Exception::MKXPError, "Animations with varying dimensions are not supported (%ix%i vs %ix%i)",
source.width(), source.height(), width(), height()); source.width(), source.height(), width(), height());
#ifndef MKXPZ_RETRO
TEXFBO newframe = shState->texPool().request(source.width(), source.height()); TEXFBO newframe = shState->texPool().request(source.width(), source.height());
// Convert the bitmap into an animated bitmap if it isn't already one // 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(); GLMeta::blitEnd();
} }
#endif // MKXPZ_RETRO
int ret; int ret;
if (position < 0) { if (position < 0) {
#ifndef MKXPZ_RETRO
p->animation.frames.push_back(newframe); p->animation.frames.push_back(newframe);
#endif // MKXPZ_RETRO
#ifdef MKXPZ_RETRO
ret = 0; // TODO: implement
#else
ret = (int)p->animation.frames.size(); ret = (int)p->animation.frames.size();
#endif // MKXPZ_RETRO
} }
else { else {
#ifndef MKXPZ_RETRO
p->animation.frames.insert(p->animation.frames.begin() + clamp(position, 0, (int)p->animation.frames.size()), newframe); p->animation.frames.insert(p->animation.frames.begin() + clamp(position, 0, (int)p->animation.frames.size()), newframe);
#endif // MKXPZ_RETRO
ret = position; ret = position;
} }
@ -2467,6 +2625,7 @@ void Bitmap::removeFrame(int position) {
Debug() << "BUG: High-res Bitmap removeFrame not implemented"; 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)); 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]); shState->texPool().release(p->animation.frames[pos]);
p->animation.frames.erase(p->animation.frames.begin() + pos); p->animation.frames.erase(p->animation.frames.begin() + pos);
@ -2486,6 +2645,7 @@ void Bitmap::removeFrame(int position) {
FBO::bind(p->gl.fbo); FBO::bind(p->gl.fbo);
taintArea(rect()); taintArea(rect());
} }
#endif // MKXPZ_RETRO
} }
void Bitmap::nextFrame() void Bitmap::nextFrame()
@ -2499,11 +2659,13 @@ void Bitmap::nextFrame()
} }
stop(); stop();
#ifndef MKXPZ_RETRO
if ((uint32_t)p->animation.lastFrame >= p->animation.frames.size() - 1) { if ((uint32_t)p->animation.lastFrame >= p->animation.frames.size() - 1) {
if (!p->animation.loop) return; if (!p->animation.loop) return;
p->animation.lastFrame = 0; p->animation.lastFrame = 0;
return; return;
} }
#endif // MKXPZ_RETRO
p->animation.lastFrame++; p->animation.lastFrame++;
} }
@ -2524,7 +2686,9 @@ void Bitmap::previousFrame()
p->animation.lastFrame = 0; p->animation.lastFrame = 0;
return; return;
} }
#ifndef MKXPZ_RETRO
p->animation.lastFrame = (int)p->animation.frames.size() - 1; p->animation.lastFrame = (int)p->animation.frames.size() - 1;
#endif // MKXPZ_RETRO
return; return;
} }
@ -2547,6 +2711,7 @@ void Bitmap::setAnimationFPS(float FPS)
if (restart) p->animation.play(); if (restart) p->animation.play();
} }
#ifndef MKXPZ_RETRO
std::vector<TEXFBO> &Bitmap::getFrames() const std::vector<TEXFBO> &Bitmap::getFrames() const
{ {
if (hasHires()) { if (hasHires()) {
@ -2555,6 +2720,7 @@ std::vector<TEXFBO> &Bitmap::getFrames() const
return p->animation.frames; return p->animation.frames;
} }
#endif // MKXPZ_RETRO
float Bitmap::getAnimationFPS() const float Bitmap::getAnimationFPS() const
{ {
@ -2617,9 +2783,11 @@ void Bitmap::taintArea(const IntRect &rect)
p->addTaintedArea(rect); p->addTaintedArea(rect);
} }
#ifndef MKXPZ_RETRO
int Bitmap::maxSize(){ int Bitmap::maxSize(){
return glState.caps.maxTexSize; return glState.caps.maxTexSize;
} }
#endif // MKXPZ_RETRO
void Bitmap::assumeRubyGC() void Bitmap::assumeRubyGC()
{ {
@ -2632,6 +2800,7 @@ void Bitmap::releaseResources()
delete p->selfHires; delete p->selfHires;
} }
#ifndef MKXPZ_RETRO
if (p->megaSurface) if (p->megaSurface)
SDL_FreeSurface(p->megaSurface); SDL_FreeSurface(p->megaSurface);
else if (p->animation.enabled) { else if (p->animation.enabled) {
@ -2642,6 +2811,7 @@ void Bitmap::releaseResources()
} }
else else
shState->texPool().release(p->gl); shState->texPool().release(p->gl);
#endif // MKXPZ_RETRO
delete p; delete p;
} }

View file

@ -111,7 +111,12 @@ private:
GraphicsPrivate *p; GraphicsPrivate *p;
}; };
#define GFX_LOCK shState->graphics().lock() #ifdef MKXPZ_RETRO
#define GFX_UNLOCK shState->graphics().unlock() # 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 #endif // GRAPHICS_H

View file

@ -24,12 +24,12 @@
#include "sharedstate.h" #include "sharedstate.h"
#include "etc.h" #include "etc.h"
#include "util.h" #include "util.h"
#ifndef MKXPZ_RETRO
#include "quad.h" #include "quad.h"
#include "glstate.h" #include "glstate.h"
#endif // MKXPZ_RETRO
#include "graphics.h" #include "graphics.h"
#include <SDL_rect.h>
#include "sigslot/signal.hpp" #include "sigslot/signal.hpp"
struct ViewportPrivate struct ViewportPrivate
@ -80,14 +80,10 @@ struct ViewportPrivate
void recomputeOnScreen() void recomputeOnScreen()
{ {
SDL_Rect r1 = { screenRect.x, screenRect.y, isOnScreen = screenRect.x < rect->x + rect->width
screenRect.w, screenRect.h }; && rect->x < screenRect.x + screenRect.w
&& screenRect.y < rect->y + rect->height
SDL_Rect r2 = { rect->x, rect->y, && rect->y < screenRect.y + screenRect.h;
rect->width, rect->height };
SDL_Rect result;
isOnScreen = SDL_IntersectRect(&r1, &r2, &result);
} }
bool needsEffectRender(bool flashing) bool needsEffectRender(bool flashing)
@ -117,8 +113,12 @@ Viewport::Viewport()
: SceneElement(*shState->screen()), : SceneElement(*shState->screen()),
sceneLink(this) sceneLink(this)
{ {
#ifdef MKXPZ_RETRO
initViewport(0, 0, 640, 480); // TODO: use the actual viewport size
#else
const Graphics &graphics = shState->graphics(); const Graphics &graphics = shState->graphics();
initViewport(0, 0, graphics.width(), graphics.height()); initViewport(0, 0, graphics.width(), graphics.height());
#endif // MKXPZ_RETRO
} }
void Viewport::initViewport(int x, int y, int width, int height) void Viewport::initViewport(int x, int y, int width, int height)
@ -193,9 +193,11 @@ void Viewport::composite()
if (elements.getSize() == 0 && !renderEffect) if (elements.getSize() == 0 && !renderEffect)
return; return;
#ifndef MKXPZ_RETRO
/* Setup scissor */ /* Setup scissor */
glState.scissorTest.pushSet(true); glState.scissorTest.pushSet(true);
glState.scissorBox.pushSet(p->rect->toIntRect()); glState.scissorBox.pushSet(p->rect->toIntRect());
#endif // MKXPZ_RETRO
Scene::composite(); Scene::composite();
@ -205,8 +207,10 @@ void Viewport::composite()
scene->requestViewportRender scene->requestViewportRender
(p->color->norm, flashColor, p->tone->norm); (p->color->norm, flashColor, p->tone->norm);
#ifndef MKXPZ_RETRO
glState.scissorBox.pop(); glState.scissorBox.pop();
glState.scissorTest.pop(); glState.scissorTest.pop();
#endif // MKXPZ_RETRO
} }
/* SceneElement */ /* SceneElement */

View file

@ -26,6 +26,7 @@
#include "bitmap.h" #include "bitmap.h"
#include "etc.h" #include "etc.h"
#include "etc-internal.h" #include "etc-internal.h"
#ifndef MKXPZ_RETRO
#include "tilequad.h" #include "tilequad.h"
#include "gl-util.h" #include "gl-util.h"
@ -33,6 +34,7 @@
#include "quadarray.h" #include "quadarray.h"
#include "texpool.h" #include "texpool.h"
#include "glstate.h" #include "glstate.h"
#endif // MKXPZ_RETRO
#include "sigslot/signal.hpp" #include "sigslot/signal.hpp"
@ -118,6 +120,7 @@ static const uint8_t pauseAniAlpha[] =
static elementsN(pauseAniAlpha); static elementsN(pauseAniAlpha);
#ifndef MKXPZ_RETRO
/* Points to an array of quads which it doesn't own. /* Points to an array of quads which it doesn't own.
* Useful for setting alpha of quads stored inside * Useful for setting alpha of quads stored inside
* bigger arrays */ * bigger arrays */
@ -136,6 +139,7 @@ struct QuadChunk
vert[i].color.w = value; vert[i].color.w = value;
} }
}; };
#endif // MKXPZ_RETRO
/* Vocabulary: /* Vocabulary:
* *
@ -196,6 +200,7 @@ struct WindowPrivate
bool opacityDirty; bool opacityDirty;
bool baseTexDirty; bool baseTexDirty;
#ifndef MKXPZ_RETRO
ColorQuadArray baseQuadArray; ColorQuadArray baseQuadArray;
/* Used when opacity < 255 */ /* Used when opacity < 255 */
@ -205,6 +210,7 @@ struct WindowPrivate
QuadChunk backgroundVert; QuadChunk backgroundVert;
Quad baseTexQuad; Quad baseTexQuad;
#endif // MKXPZ_RETRO
struct WindowControls : public ViewportElement struct WindowControls : public ViewportElement
{ {
@ -233,6 +239,7 @@ struct WindowPrivate
WindowControls controlsElement; WindowControls controlsElement;
#ifndef MKXPZ_RETRO
ColorQuadArray controlsQuadArray; ColorQuadArray controlsQuadArray;
int controlsQuadCount; int controlsQuadCount;
@ -240,6 +247,7 @@ struct WindowPrivate
QuadChunk pauseAniVert; QuadChunk pauseAniVert;
QuadChunk cursorVert; QuadChunk cursorVert;
#endif // MKXPZ_RETRO
uint8_t cursorAniAlphaIdx; uint8_t cursorAniAlphaIdx;
uint8_t pauseAniAlphaIdx; uint8_t pauseAniAlphaIdx;
@ -272,9 +280,11 @@ struct WindowPrivate
{ {
refreshCursorRectCon(); refreshCursorRectCon();
#ifndef MKXPZ_RETRO
controlsQuadArray.resize(14); controlsQuadArray.resize(14);
cursorVert.count = 9; cursorVert.count = 9;
pauseAniVert.count = 1; pauseAniVert.count = 1;
#endif // MKXPZ_RETRO
prepareCon = shState->prepareDraw.connect prepareCon = shState->prepareDraw.connect
(&WindowPrivate::prepare, this); (&WindowPrivate::prepare, this);
@ -282,7 +292,9 @@ struct WindowPrivate
~WindowPrivate() ~WindowPrivate()
{ {
#ifndef MKXPZ_RETRO
shState->texPool().release(baseTex); shState->texPool().release(baseTex);
#endif // MKXPZ_RETRO
cursorRectCon.disconnect(); cursorRectCon.disconnect();
prepareCon.disconnect(); prepareCon.disconnect();
@ -333,6 +345,7 @@ struct WindowPrivate
cornerRects.bl = IntRect(0, h-16, 16, 16); cornerRects.bl = IntRect(0, h-16, 16, 16);
cornerRects.br = IntRect(w-16, h-16, 16, 16); cornerRects.br = IntRect(w-16, h-16, 16, 16);
#ifndef MKXPZ_RETRO
/* Required quad count */ /* Required quad count */
int count = 0; int count = 0;
@ -389,6 +402,7 @@ struct WindowPrivate
FloatRect texRect = FloatRect(0, 0, size.x, size.y); FloatRect texRect = FloatRect(0, 0, size.x, size.y);
baseTexQuad.setTexPosRect(texRect, texRect); baseTexQuad.setTexPosRect(texRect, texRect);
#endif // MKXPZ_RETRO
opacityDirty = true; opacityDirty = true;
baseTexDirty = true; baseTexDirty = true;
@ -396,10 +410,12 @@ struct WindowPrivate
void updateBaseAlpha() void updateBaseAlpha()
{ {
#ifndef MKXPZ_RETRO
/* This is always applied unconditionally */ /* This is always applied unconditionally */
backgroundVert.setAlpha(backOpacity.norm); backgroundVert.setAlpha(backOpacity.norm);
baseTexQuad.setColor(Vec4(1, 1, 1, opacity.norm)); baseTexQuad.setColor(Vec4(1, 1, 1, opacity.norm));
#endif // MKXPZ_RETRO
baseTexDirty = true; baseTexDirty = true;
} }
@ -407,6 +423,7 @@ struct WindowPrivate
void ensureBaseTexReady() void ensureBaseTexReady()
{ {
/* Make sure texture is big enough */ /* Make sure texture is big enough */
#ifndef MKXPZ_RETRO
int newW = baseTex.width; int newW = baseTex.width;
int newH = baseTex.height; int newH = baseTex.height;
bool resizeNeeded = false; bool resizeNeeded = false;
@ -427,12 +444,14 @@ struct WindowPrivate
shState->texPool().release(baseTex); shState->texPool().release(baseTex);
baseTex = shState->texPool().request(newW, newH); baseTex = shState->texPool().request(newW, newH);
#endif // MKXPZ_RETRO
baseTexDirty = true; baseTexDirty = true;
} }
void redrawBaseTex() void redrawBaseTex()
{ {
#ifndef MKXPZ_RETRO
/* Discard old buffer */ /* Discard old buffer */
TEX::bind(baseTex.tex); TEX::bind(baseTex.tex);
TEX::allocEmpty(baseTex.width, baseTex.height); TEX::allocEmpty(baseTex.width, baseTex.height);
@ -471,10 +490,12 @@ struct WindowPrivate
glState.blendMode.pop(); glState.blendMode.pop();
glState.viewport.pop(); glState.viewport.pop();
TEX::setSmooth(false); TEX::setSmooth(false);
#endif // MKXPZ_RETRO
} }
void buildControlsVert() void buildControlsVert()
{ {
#ifndef MKXPZ_RETRO
int i = 0; int i = 0;
Vertex *vert = controlsQuadArray.vertices.data(); Vertex *vert = controlsQuadArray.vertices.data();
@ -524,6 +545,7 @@ struct WindowPrivate
controlsQuadArray.commit(); controlsQuadArray.commit();
controlsQuadCount = i; controlsQuadCount = i;
#endif // MKXPZ_RETRO
} }
void prepare() void prepare()
@ -547,6 +569,7 @@ struct WindowPrivate
updateBaseQuadArray = true; updateBaseQuadArray = true;
} }
#ifndef MKXPZ_RETRO
if (updateBaseQuadArray) if (updateBaseQuadArray)
baseQuadArray.commit(); baseQuadArray.commit();
@ -564,6 +587,7 @@ struct WindowPrivate
baseTexDirty = false; baseTexDirty = false;
} }
} }
#endif // MKXPZ_RETRO
} }
void drawBase() void drawBase()
@ -574,6 +598,7 @@ struct WindowPrivate
if (size == Vec2i(0, 0)) if (size == Vec2i(0, 0))
return; return;
#ifndef MKXPZ_RETRO
SimpleAlphaShader &shader = shState->shaders().simpleAlpha; SimpleAlphaShader &shader = shState->shaders().simpleAlpha;
shader.bind(); shader.bind();
shader.applyViewportProj(); shader.applyViewportProj();
@ -595,6 +620,7 @@ struct WindowPrivate
TEX::setSmooth(false); TEX::setSmooth(false);
} }
#endif // MKXPZ_RETRO
} }
void drawControls() void drawControls()
@ -618,6 +644,7 @@ struct WindowPrivate
const IntRect windowRect(efPos, size); const IntRect windowRect(efPos, size);
const IntRect contentsRect(efPos + Vec2i(16), size - Vec2i(32)); const IntRect contentsRect(efPos + Vec2i(16), size - Vec2i(32));
#ifndef MKXPZ_RETRO
glState.scissorTest.pushSet(true); glState.scissorTest.pushSet(true);
glState.scissorBox.push(); glState.scissorBox.push();
glState.scissorBox.setIntersect(windowRect); glState.scissorBox.setIntersect(windowRect);
@ -652,10 +679,12 @@ struct WindowPrivate
glState.scissorBox.pop(); glState.scissorBox.pop();
glState.scissorTest.pop(); glState.scissorTest.pop();
#endif // MKXPZ_RETRO
} }
void updateControls() void updateControls()
{ {
#ifndef MKXPZ_RETRO
bool updateArray = false; bool updateArray = false;
if (active && cursorVert.vert) if (active && cursorVert.vert)
@ -680,6 +709,7 @@ struct WindowPrivate
if (updateArray) if (updateArray)
controlsQuadArray.commit(); controlsQuadArray.commit();
#endif // MKXPZ_RETRO
} }
void stepAnimations() void stepAnimations()
@ -746,7 +776,9 @@ void Window::setWindowskin(Bitmap *value)
return; return;
} }
#ifndef MKXPZ_RETRO
value->ensureNonMega(); value->ensureNonMega();
#endif // MKXPZ_RETRO
p->windowskinDispCon = value->wasDisposed.connect(&WindowPrivate::windowskinDisposal, p); 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); p->contentsDispCon = value->wasDisposed.connect(&WindowPrivate::contentsDisposal, p);
#ifndef MKXPZ_RETRO
value->ensureNonMega(); value->ensureNonMega();
p->contentsQuad.setTexPosRect(value->rect(), value->rect()); p->contentsQuad.setTexPosRect(value->rect(), value->rect());
#endif // MKXPZ_RETRO
} }
void Window::setStretch(bool value) void Window::setStretch(bool value)
@ -885,7 +919,9 @@ void Window::setContentsOpacity(int value)
return; return;
p->contentsOpacity = value; p->contentsOpacity = value;
#ifndef MKXPZ_RETRO
p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm)); p->contentsQuad.setColor(Vec4(1, 1, 1, p->contentsOpacity.norm));
#endif // MKXPZ_RETRO
} }
void Window::initDynAttribs() void Window::initDynAttribs()

View file

@ -21,22 +21,33 @@
#include "sharedstate.h" #include "sharedstate.h"
#include "scene.h"
#include "util.h" #include "util.h"
#ifndef MKXPZ_RETRO
#include "filesystem.h" #include "filesystem.h"
#endif // MKXPZ_RETRO
#include "graphics.h" #include "graphics.h"
#ifndef MKXPZ_RETRO
#include "input.h" #include "input.h"
#include "audio.h" #include "audio.h"
#endif // MKXPZ_RETRO
#include "glstate.h" #include "glstate.h"
#ifndef MKXPZ_RETRO
#include "shader.h" #include "shader.h"
#include "texpool.h" #include "texpool.h"
#endif // MKXPZ_RETRO
#include "font.h" #include "font.h"
#ifndef MKXPZ_RETRO
#include "eventthread.h" #include "eventthread.h"
#include "gl-util.h" #include "gl-util.h"
#include "global-ibo.h" #include "global-ibo.h"
#include "quad.h" #include "quad.h"
#endif // MKXPZ_RETRO
#include "binding.h" #include "binding.h"
#include "exception.h" #include "exception.h"
#ifndef MKXPZ_RETRO
#include "sharedmidistate.h" #include "sharedmidistate.h"
#endif // MKXPZ_RETRO
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
@ -63,9 +74,12 @@ static const char *gameArchExt()
struct SharedStatePrivate struct SharedStatePrivate
{ {
void *bindingData; void *bindingData;
#ifndef MKXPZ_RETRO
SDL_Window *sdlWindow; SDL_Window *sdlWindow;
#endif // MKXPZ_RETRO
Scene *screen; Scene *screen;
#ifndef MKXPZ_RETRO
FileSystem fileSystem; FileSystem fileSystem;
EventThread &eThread; EventThread &eThread;
@ -88,14 +102,17 @@ struct SharedStatePrivate
Font *defaultFont; Font *defaultFont;
TEX::ID globalTex; TEX::ID globalTex;
#endif // MKXPZ_RETRO
int globalTexW, globalTexH; int globalTexW, globalTexH;
bool globalTexDirty; bool globalTexDirty;
#ifndef MKXPZ_RETRO
TEXFBO gpTexFBO; TEXFBO gpTexFBO;
TEXFBO atlasTex; TEXFBO atlasTex;
Quad gpQuad; Quad gpQuad;
#endif // MKXPZ_RETRO
unsigned int stampCounter; unsigned int stampCounter;
@ -103,6 +120,7 @@ struct SharedStatePrivate
SharedStatePrivate(RGSSThreadData *threadData) SharedStatePrivate(RGSSThreadData *threadData)
: bindingData(0), : bindingData(0),
#ifndef MKXPZ_RETRO
sdlWindow(threadData->window), sdlWindow(threadData->window),
fileSystem(threadData->argv0, threadData->config.allowSymlinks), fileSystem(threadData->argv0, threadData->config.allowSymlinks),
eThread(*threadData->ethread), eThread(*threadData->ethread),
@ -114,6 +132,7 @@ struct SharedStatePrivate
audio(*threadData), audio(*threadData),
_glState(threadData->config), _glState(threadData->config),
fontState(threadData->config), fontState(threadData->config),
#endif // MKXPZ_RETRO
stampCounter(0) stampCounter(0)
{} {}
@ -122,6 +141,7 @@ struct SharedStatePrivate
startupTime = std::chrono::steady_clock::now(); startupTime = std::chrono::steady_clock::now();
#ifndef MKXPZ_RETRO
/* Shaders have been compiled in ShaderSet's constructor */ /* Shaders have been compiled in ShaderSet's constructor */
if (gl.ReleaseShaderCompiler) if (gl.ReleaseShaderCompiler)
gl.ReleaseShaderCompiler(); gl.ReleaseShaderCompiler();
@ -168,13 +188,16 @@ struct SharedStatePrivate
* no need to do it on startup */ * no need to do it on startup */
if (rgssVer <= 2) if (rgssVer <= 2)
midiState.initIfNeeded(threadData->config); midiState.initIfNeeded(threadData->config);
#endif // MKXPZ_RETRO
} }
~SharedStatePrivate() ~SharedStatePrivate()
{ {
#ifndef MKXPZ_RETRO
TEX::del(globalTex); TEX::del(globalTex);
TEXFBO::fini(gpTexFBO); TEXFBO::fini(gpTexFBO);
TEXFBO::fini(atlasTex); TEXFBO::fini(atlasTex);
#endif // MKXPZ_RETRO
} }
}; };
@ -184,6 +207,7 @@ void SharedState::initInstance(RGSSThreadData *threadData)
* SharedState depends on GlobalIBO existing, * SharedState depends on GlobalIBO existing,
* Font depends on SharedState existing */ * Font depends on SharedState existing */
#ifndef MKXPZ_RETRO
rgssVersion = threadData->config.rgssVersion; rgssVersion = threadData->config.rgssVersion;
_globalIBO = new GlobalIBO(); _globalIBO = new GlobalIBO();
@ -191,32 +215,45 @@ void SharedState::initInstance(RGSSThreadData *threadData)
SharedState::instance = 0; SharedState::instance = 0;
Font *defaultFont = 0; Font *defaultFont = 0;
#endif // MKXPZ_RETRO
try try
{ {
SharedState::instance = new SharedState(threadData); SharedState::instance = new SharedState(threadData);
#ifndef MKXPZ_RETRO
Font::initDefaults(instance->p->fontState); Font::initDefaults(instance->p->fontState);
defaultFont = new Font(); defaultFont = new Font();
#endif // MKXPZ_RETRO
} }
catch (const Exception &exc) catch (const Exception &exc)
{ {
#ifndef MKXPZ_RETRO
delete _globalIBO; delete _globalIBO;
#endif // MKXPZ_RETRO
delete SharedState::instance; delete SharedState::instance;
#ifndef MKXPZ_RETRO
delete defaultFont; delete defaultFont;
#endif // MKXPZ_RETRO
throw exc; throw exc;
} }
#ifndef MKXPZ_RETRO
SharedState::instance->p->defaultFont = defaultFont; SharedState::instance->p->defaultFont = defaultFont;
#endif // MKXPZ_RETRO
} }
void SharedState::finiInstance() void SharedState::finiInstance()
{ {
#ifndef MKXPZ_RETRO
delete SharedState::instance->p->defaultFont; delete SharedState::instance->p->defaultFont;
#endif // MKXPZ_RETRO
delete SharedState::instance; delete SharedState::instance;
#ifndef MKXPZ_RETRO
delete _globalIBO; delete _globalIBO;
#endif // MKXPZ_RETRO
} }
void SharedState::setScreen(Scene &screen) void SharedState::setScreen(Scene &screen)
@ -231,8 +268,11 @@ void SharedState::setScreen(Scene &screen)
} }
GSATT(void*, bindingData) GSATT(void*, bindingData)
#ifndef MKXPZ_RETRO
GSATT(SDL_Window*, sdlWindow) GSATT(SDL_Window*, sdlWindow)
#endif // MKXPZ_RETRO
GSATT(Scene*, screen) GSATT(Scene*, screen)
#ifndef MKXPZ_RETRO
GSATT(FileSystem&, fileSystem) GSATT(FileSystem&, fileSystem)
GSATT(EventThread&, eThread) GSATT(EventThread&, eThread)
GSATT(RGSSThreadData&, rtData) GSATT(RGSSThreadData&, rtData)
@ -246,6 +286,7 @@ GSATT(TexPool&, texPool)
GSATT(Quad&, gpQuad) GSATT(Quad&, gpQuad)
GSATT(SharedFontState&, fontState) GSATT(SharedFontState&, fontState)
GSATT(SharedMidiState&, midiState) GSATT(SharedMidiState&, midiState)
#endif // MKXPZ_RETRO
void SharedState::setBindingData(void *data) void SharedState::setBindingData(void *data)
{ {
@ -254,7 +295,9 @@ void SharedState::setBindingData(void *data)
void SharedState::ensureQuadIBO(size_t minSize) void SharedState::ensureQuadIBO(size_t minSize)
{ {
#ifndef MKXPZ_RETRO
_globalIBO->ensureSize(minSize); _globalIBO->ensureSize(minSize);
#endif // MKXPZ_RETRO
} }
GlobalIBO &SharedState::globalIBO() GlobalIBO &SharedState::globalIBO()
@ -264,6 +307,7 @@ GlobalIBO &SharedState::globalIBO()
void SharedState::bindTex() void SharedState::bindTex()
{ {
#ifndef MKXPZ_RETRO
TEX::bind(p->globalTex); TEX::bind(p->globalTex);
if (p->globalTexDirty) if (p->globalTexDirty)
@ -271,6 +315,7 @@ void SharedState::bindTex()
TEX::allocEmpty(p->globalTexW, p->globalTexH); TEX::allocEmpty(p->globalTexW, p->globalTexH);
p->globalTexDirty = false; p->globalTexDirty = false;
} }
#endif // MKXPZ_RETRO
} }
void SharedState::ensureTexSize(int minW, int minH, Vec2i &currentSizeOut) void SharedState::ensureTexSize(int minW, int minH, Vec2i &currentSizeOut)
@ -290,6 +335,7 @@ void SharedState::ensureTexSize(int minW, int minH, Vec2i &currentSizeOut)
currentSizeOut = Vec2i(p->globalTexW, p->globalTexH); currentSizeOut = Vec2i(p->globalTexW, p->globalTexH);
} }
#ifndef MKXPZ_RETRO
TEXFBO &SharedState::gpTexFBO(int minW, int minH) TEXFBO &SharedState::gpTexFBO(int minW, int minH)
{ {
bool needResize = false; bool needResize = false;
@ -344,30 +390,37 @@ void SharedState::releaseAtlasTex(TEXFBO &tex)
p->atlasTex = tex; p->atlasTex = tex;
} }
#endif // MKXPZ_RETRO
void SharedState::checkShutdown() void SharedState::checkShutdown()
{ {
#ifndef MKXPZ_RETRO
if (!p->rtData.rqTerm) if (!p->rtData.rqTerm)
return; return;
p->rtData.rqTermAck.set(); p->rtData.rqTermAck.set();
p->texPool.disable(); p->texPool.disable();
scriptBinding->terminate(); scriptBinding->terminate();
#endif // MKXPZ_RETRO
} }
void SharedState::checkReset() void SharedState::checkReset()
{ {
#ifndef MKXPZ_RETRO
if (!p->rtData.rqReset) if (!p->rtData.rqReset)
return; return;
p->rtData.rqReset.clear(); p->rtData.rqReset.clear();
scriptBinding->reset(); scriptBinding->reset();
#endif // MKXPZ_RETRO
} }
#ifndef MKXPZ_RETRO
Font &SharedState::defaultFont() const Font &SharedState::defaultFont() const
{ {
return *p->defaultFont; return *p->defaultFont;
} }
#endif // MKXPZ_RETRO
double SharedState::runTime() { double SharedState::runTime() {
if (!p) return 0; if (!p) return 0;
@ -387,14 +440,20 @@ SharedState::SharedState(RGSSThreadData *threadData)
try try
{ {
p->init(threadData); p->init(threadData);
#ifdef MKXPZ_RETRO
p->screen = new Scene(); // TODO: implement
#else
p->screen = p->graphics.getScreen(); p->screen = p->graphics.getScreen();
#endif // MKXPZ_RETRO
} }
catch (const Exception &exc) catch (const Exception &exc)
{ {
#ifndef MKXPZ_RETRO
// If the "error" was the user quitting the game before the path cache finished building, // If the "error" was the user quitting the game before the path cache finished building,
// then just return // then just return
if (rtData().rqTerm) if (rtData().rqTerm)
return; return;
#endif // MKXPZ_RETRO
delete p; delete p;
SharedState::instance = 0; SharedState::instance = 0;

View file

@ -37,12 +37,16 @@ public:
: disposed(false), : disposed(false),
link(this) link(this)
{ {
#ifndef MKXPZ_RETRO
shState->graphics().addDisposable(this); shState->graphics().addDisposable(this);
#endif // MKXPZ_RETRO
} }
virtual ~Disposable() virtual ~Disposable()
{ {
#ifndef MKXPZ_RETRO
shState->graphics().remDisposable(this); shState->graphics().remDisposable(this);
#endif // MKXPZ_RETRO
} }
void dispose() void dispose()