mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-10 12:02:53 +02:00
Fix blitting, add optional position arg to Bitmap.snap_to_bitmap
This commit is contained in:
parent
077b7da204
commit
67c158e418
3 changed files with 51 additions and 29 deletions
|
@ -663,7 +663,7 @@ RB_METHOD(bitmapGetLooping){
|
||||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||||
|
|
||||||
bool ret;
|
bool ret;
|
||||||
GUARD_EXC(b->getLooping(););
|
GUARD_EXC(ret = b->getLooping(););
|
||||||
return rb_bool_new(ret);
|
return rb_bool_new(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,12 +671,14 @@ RB_METHOD(bitmapGetLooping){
|
||||||
RB_METHOD(bitmapSnapToBitmap) {
|
RB_METHOD(bitmapSnapToBitmap) {
|
||||||
RB_UNUSED_PARAM;
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
rb_check_argc(argc, 0);
|
VALUE position;
|
||||||
|
rb_scan_args(argc, argv, "01", &position);
|
||||||
|
|
||||||
Bitmap *b = getPrivateData<Bitmap>(self);
|
Bitmap *b = getPrivateData<Bitmap>(self);
|
||||||
|
|
||||||
Bitmap *newbitmap = 0;
|
Bitmap *newbitmap = 0;
|
||||||
GUARD_EXC(newbitmap = new Bitmap(*b, false););
|
int pos = (position == RUBY_Qnil) ? -1 : NUM2INT(position);
|
||||||
|
GUARD_EXC(newbitmap = new Bitmap(*b, pos););
|
||||||
|
|
||||||
VALUE ret = rb_obj_alloc(rb_class_of(self));
|
VALUE ret = rb_obj_alloc(rb_class_of(self));
|
||||||
|
|
||||||
|
|
|
@ -637,16 +637,29 @@ Bitmap::Bitmap(void *pixeldata, int width, int height)
|
||||||
p->addTaintedArea(rect());
|
p->addTaintedArea(rect());
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap::Bitmap(const Bitmap &other, bool copyAllFrames)
|
// frame is -2 for "any and all", -1 for "current", anything else for a specific frame
|
||||||
|
Bitmap::Bitmap(const Bitmap &other, int frame)
|
||||||
{
|
{
|
||||||
other.ensureNonMega();
|
other.ensureNonMega();
|
||||||
|
if (frame > -2) other.ensureAnimated();
|
||||||
|
|
||||||
p = new BitmapPrivate(this);
|
p = new BitmapPrivate(this);
|
||||||
|
|
||||||
if (!other.isAnimated() || !copyAllFrames) {
|
if (!other.isAnimated() || frame >= -1) {
|
||||||
other.ensureNotPlaying();
|
if (frame == -1) other.ensureNotPlaying();
|
||||||
p->gl = shState->texPool().request(other.width(), other.height());
|
p->gl = shState->texPool().request(other.width(), other.height());
|
||||||
blt(0, 0, other, rect());
|
|
||||||
|
GLMeta::blitBegin(p->gl);
|
||||||
|
// Blit just the current frame of the other animated bitmap
|
||||||
|
if (frame == -1) {
|
||||||
|
GLMeta::blitSource(other.getGLTypes());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto &frames = other.getFrames();
|
||||||
|
GLMeta::blitSource(frames[clamp(frame, 0, (int)frames.size() - 1)]);
|
||||||
|
}
|
||||||
|
GLMeta::blitRectangle(rect(), rect(), true);
|
||||||
|
GLMeta::blitEnd();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p->animation.enabled = true;
|
p->animation.enabled = true;
|
||||||
|
@ -657,10 +670,10 @@ Bitmap::Bitmap(const Bitmap &other, bool copyAllFrames)
|
||||||
p->animation.loop = other.getLooping();
|
p->animation.loop = other.getLooping();
|
||||||
|
|
||||||
char *tmp = new char[p->animation.width * p->animation.height * 4];
|
char *tmp = new char[p->animation.width * p->animation.height * 4];
|
||||||
for (const TEXFBO &frame : other.getFrames()) {
|
for (TEXFBO &sourceframe : other.getFrames()) {
|
||||||
TEXFBO copyframe;
|
TEXFBO newframe;
|
||||||
try {
|
try {
|
||||||
copyframe = shState->texPool().request(p->animation.width, p->animation.height);
|
newframe = shState->texPool().request(p->animation.width, p->animation.height);
|
||||||
} catch(const Exception &e) {
|
} catch(const Exception &e) {
|
||||||
for (TEXFBO &f : p->animation.frames)
|
for (TEXFBO &f : p->animation.frames)
|
||||||
shState->texPool().release(f);
|
shState->texPool().release(f);
|
||||||
|
@ -668,17 +681,17 @@ Bitmap::Bitmap(const Bitmap &other, bool copyAllFrames)
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: gotta see if I can copy textures directly from one TEXFBO to the other
|
GLMeta::blitBegin(newframe);
|
||||||
// I'm an idiot so I don't already know
|
GLMeta::blitSource(sourceframe);
|
||||||
FBO::bind(frame.fbo);
|
GLMeta::blitRectangle(rect(), rect(), true);
|
||||||
gl.ReadPixels(0,0,p->animation.width,p->animation.height,GL_RGBA,GL_UNSIGNED_BYTE,tmp);
|
GLMeta::blitEnd();
|
||||||
TEX::bind(copyframe.tex);
|
|
||||||
TEX::uploadImage(p->animation.width, p->animation.height, tmp, GL_RGBA);
|
|
||||||
|
|
||||||
p->animation.frames.push_back(copyframe);
|
p->animation.frames.push_back(newframe);
|
||||||
}
|
}
|
||||||
delete[] tmp;
|
delete[] tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->addTaintedArea(rect());
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap::~Bitmap()
|
Bitmap::~Bitmap()
|
||||||
|
@ -859,7 +872,7 @@ void Bitmap::stretchBlt(const IntRect &destRect,
|
||||||
{
|
{
|
||||||
/* Fast blit */
|
/* Fast blit */
|
||||||
GLMeta::blitBegin(getGLTypes());
|
GLMeta::blitBegin(getGLTypes());
|
||||||
GLMeta::blitSource(getGLTypes());
|
GLMeta::blitSource(source.getGLTypes());
|
||||||
GLMeta::blitRectangle(sourceRect, destRect);
|
GLMeta::blitRectangle(sourceRect, destRect);
|
||||||
GLMeta::blitEnd();
|
GLMeta::blitEnd();
|
||||||
}
|
}
|
||||||
|
@ -1770,7 +1783,7 @@ void Bitmap::setInitFont(Font *value)
|
||||||
p->font = value;
|
p->font = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEXFBO &Bitmap::getGLTypes()
|
TEXFBO &Bitmap::getGLTypes() const
|
||||||
{
|
{
|
||||||
return (p->animation.enabled) ? p->animation.currentFrame() : p->gl;
|
return (p->animation.enabled) ? p->animation.currentFrame() : p->gl;
|
||||||
}
|
}
|
||||||
|
@ -1801,6 +1814,14 @@ void Bitmap::ensureNonAnimated() const
|
||||||
GUARD_ANIMATED;
|
GUARD_ANIMATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bitmap::ensureAnimated() const
|
||||||
|
{
|
||||||
|
if (isDisposed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GUARD_UNANIMATED;
|
||||||
|
}
|
||||||
|
|
||||||
void Bitmap::ensureNotPlaying() const
|
void Bitmap::ensureNotPlaying() const
|
||||||
{
|
{
|
||||||
if (isDisposed())
|
if (isDisposed())
|
||||||
|
@ -1899,14 +1920,10 @@ int Bitmap::addFrame(Bitmap &source, int position)
|
||||||
p->surface = 0;
|
p->surface = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// FIXME: gotta see if I can copy textures directly from one TEXFBO to the other
|
GLMeta::blitBegin(newframe);
|
||||||
// I'm an idiot so I don't already know
|
GLMeta::blitSource(source.getGLTypes());
|
||||||
auto pixels = new char[source.width() * source.height() * 4];
|
GLMeta::blitRectangle(rect(), rect(), true);
|
||||||
FBO::bind(source.getGLTypes().fbo);
|
GLMeta::blitEnd();
|
||||||
gl.ReadPixels(0,0,source.width(),source.height(),GL_RGBA,GL_UNSIGNED_BYTE,pixels);
|
|
||||||
TEX::bind(newframe.tex);
|
|
||||||
TEX::uploadImage(newframe.width, newframe.height, pixels, GL_RGBA);
|
|
||||||
delete[] pixels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -42,7 +42,9 @@ public:
|
||||||
Bitmap(int width, int height);
|
Bitmap(int width, int height);
|
||||||
Bitmap(void *pixeldata, int width, int height);
|
Bitmap(void *pixeldata, int width, int height);
|
||||||
/* Clone constructor */
|
/* Clone constructor */
|
||||||
Bitmap(const Bitmap &other, bool copyAllFrames = true);
|
|
||||||
|
// frame is -2 for "any and all", -1 for "current", anything else for a specific frame
|
||||||
|
Bitmap(const Bitmap &other, int frame = -2);
|
||||||
~Bitmap();
|
~Bitmap();
|
||||||
|
|
||||||
int width() const;
|
int width() const;
|
||||||
|
@ -114,11 +116,12 @@ public:
|
||||||
void setInitFont(Font *value);
|
void setInitFont(Font *value);
|
||||||
|
|
||||||
/* <internal> */
|
/* <internal> */
|
||||||
TEXFBO &getGLTypes();
|
TEXFBO &getGLTypes() const;
|
||||||
SDL_Surface *surface() const;
|
SDL_Surface *surface() const;
|
||||||
SDL_Surface *megaSurface() const;
|
SDL_Surface *megaSurface() const;
|
||||||
void ensureNonMega() const;
|
void ensureNonMega() const;
|
||||||
void ensureNonAnimated() const;
|
void ensureNonAnimated() const;
|
||||||
|
void ensureAnimated() const;
|
||||||
|
|
||||||
// Animation functions
|
// Animation functions
|
||||||
void stop();
|
void stop();
|
||||||
|
|
Loading…
Add table
Reference in a new issue