Sprite: Implement wave effect (RGSS2)
This initial implementation emulates the way RMVX splits the sprite into "chunks" of about 8 pixels, which it then scrolls left/right on a vertical sine wave. It even replicates the weird behavior when wave_amp < 0, namely "shrinking" the src_rect horizontally. As with bush_opacity, this effect in combination with rotation will render differently from RMVX.
This commit is contained in:
parent
42b10fd2ee
commit
af9039f58d
|
@ -69,6 +69,39 @@ DEF_PROP_F(Sprite, Angle)
|
||||||
|
|
||||||
DEF_PROP_B(Sprite, Mirror)
|
DEF_PROP_B(Sprite, Mirror)
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
|
||||||
|
RB_METHOD(spriteWidth)
|
||||||
|
{
|
||||||
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
|
Sprite *s = getPrivateData<Sprite>(self);
|
||||||
|
|
||||||
|
int value;
|
||||||
|
GUARD_EXC( value = s->getWidth(); )
|
||||||
|
|
||||||
|
return rb_fix_new(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_METHOD(spriteHeight)
|
||||||
|
{
|
||||||
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
|
Sprite *s = getPrivateData<Sprite>(self);
|
||||||
|
|
||||||
|
int value;
|
||||||
|
GUARD_EXC( value = s->getHeight(); )
|
||||||
|
|
||||||
|
return rb_fix_new(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_PROP_I(Sprite, WaveAmp)
|
||||||
|
DEF_PROP_I(Sprite, WaveLength)
|
||||||
|
DEF_PROP_I(Sprite, WaveSpeed)
|
||||||
|
DEF_PROP_F(Sprite, WavePhase)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
spriteBindingInit()
|
spriteBindingInit()
|
||||||
{
|
{
|
||||||
|
@ -98,4 +131,14 @@ spriteBindingInit()
|
||||||
INIT_PROP_BIND( Sprite, BlendType, "blend_type" );
|
INIT_PROP_BIND( Sprite, BlendType, "blend_type" );
|
||||||
INIT_PROP_BIND( Sprite, Color, "color" );
|
INIT_PROP_BIND( Sprite, Color, "color" );
|
||||||
INIT_PROP_BIND( Sprite, Tone, "tone" );
|
INIT_PROP_BIND( Sprite, Tone, "tone" );
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
_rb_define_method(klass, "width", spriteWidth);
|
||||||
|
_rb_define_method(klass, "height", spriteHeight);
|
||||||
|
|
||||||
|
INIT_PROP_BIND( Sprite, WaveAmp, "wave_amp" );
|
||||||
|
INIT_PROP_BIND( Sprite, WaveLength, "wave_length" );
|
||||||
|
INIT_PROP_BIND( Sprite, WaveSpeed, "wave_speed" );
|
||||||
|
INIT_PROP_BIND( Sprite, WavePhase, "wave_phase" );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,35 @@ DEF_PROP_F(Sprite, Angle)
|
||||||
|
|
||||||
DEF_PROP_B(Sprite, Mirror)
|
DEF_PROP_B(Sprite, Mirror)
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
|
||||||
|
MRB_METHOD(spriteWidth)
|
||||||
|
{
|
||||||
|
Sprite *s = getPrivateData<Sprite>(mrb, self);
|
||||||
|
|
||||||
|
int value;
|
||||||
|
GUARD_EXC( value = s->getWidth(); )
|
||||||
|
|
||||||
|
return mrb_fixnum_value(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
MRB_METHOD(spriteHeight)
|
||||||
|
{
|
||||||
|
Sprite *s = getPrivateData<Sprite>(mrb, self);
|
||||||
|
|
||||||
|
int value;
|
||||||
|
GUARD_EXC( value = s->getHeight(); )
|
||||||
|
|
||||||
|
return mrb_fixnum_value(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_PROP_I(Sprite, WaveAmp)
|
||||||
|
DEF_PROP_I(Sprite, WaveLength)
|
||||||
|
DEF_PROP_I(Sprite, WaveSpeed)
|
||||||
|
DEF_PROP_F(Sprite, WavePhase)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
spriteBindingInit(mrb_state *mrb)
|
spriteBindingInit(mrb_state *mrb)
|
||||||
{
|
{
|
||||||
|
@ -95,5 +124,15 @@ spriteBindingInit(mrb_state *mrb)
|
||||||
INIT_PROP_BIND( Sprite, Color, "color" );
|
INIT_PROP_BIND( Sprite, Color, "color" );
|
||||||
INIT_PROP_BIND( Sprite, Tone, "tone" );
|
INIT_PROP_BIND( Sprite, Tone, "tone" );
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
mrb_define_method(mrb, klass, "width", spriteWidth, MRB_ARGS_NONE());
|
||||||
|
mrb_define_method(mrb, klass, "height", spriteHeight, MRB_ARGS_NONE());
|
||||||
|
|
||||||
|
INIT_PROP_BIND( Sprite, WaveAmp, "wave_amp" );
|
||||||
|
INIT_PROP_BIND( Sprite, WaveLength, "wave_length" );
|
||||||
|
INIT_PROP_BIND( Sprite, WaveSpeed, "wave_speed" );
|
||||||
|
INIT_PROP_BIND( Sprite, WavePhase, "wave_phase" );
|
||||||
|
#endif
|
||||||
|
|
||||||
mrb_define_method(mrb, klass, "inspect", inspectObject, MRB_ARGS_NONE());
|
mrb_define_method(mrb, klass, "inspect", inspectObject, MRB_ARGS_NONE());
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
flashAlpha = flashColor.w;
|
flashAlpha = flashColor.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update()
|
virtual void update()
|
||||||
{
|
{
|
||||||
if (!flashing)
|
if (!flashing)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -34,17 +34,41 @@
|
||||||
typedef uint32_t index_t;
|
typedef uint32_t index_t;
|
||||||
#define _GL_INDEX_TYPE GL_UNSIGNED_INT
|
#define _GL_INDEX_TYPE GL_UNSIGNED_INT
|
||||||
|
|
||||||
struct ColorQuadArray
|
/* A small hack to get mutable QuadArray constructors */
|
||||||
|
inline void initBufferBindings(Vertex *)
|
||||||
{
|
{
|
||||||
std::vector<Vertex> vertices;
|
glEnableVertexAttribArray(Shader::Color);
|
||||||
|
glEnableVertexAttribArray(Shader::Position);
|
||||||
|
glEnableVertexAttribArray(Shader::TexCoord);
|
||||||
|
|
||||||
|
glVertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset());
|
||||||
|
glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset());
|
||||||
|
glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void initBufferBindings(SVertex *)
|
||||||
|
{
|
||||||
|
glEnableVertexAttribArray(Shader::Position);
|
||||||
|
glEnableVertexAttribArray(Shader::TexCoord);
|
||||||
|
|
||||||
|
glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::posOffset());
|
||||||
|
glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::texPosOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class VertexType>
|
||||||
|
struct QuadArray
|
||||||
|
{
|
||||||
|
std::vector<VertexType> vertices;
|
||||||
|
|
||||||
VBO::ID vbo;
|
VBO::ID vbo;
|
||||||
VAO::ID vao;
|
VAO::ID vao;
|
||||||
|
|
||||||
int quadCount;
|
int quadCount;
|
||||||
|
GLsizeiptr vboSize;
|
||||||
|
|
||||||
ColorQuadArray()
|
QuadArray()
|
||||||
: quadCount(0)
|
: quadCount(0),
|
||||||
|
vboSize(-1)
|
||||||
{
|
{
|
||||||
vbo = VBO::gen();
|
vbo = VBO::gen();
|
||||||
vao = VAO::gen();
|
vao = VAO::gen();
|
||||||
|
@ -53,20 +77,16 @@ struct ColorQuadArray
|
||||||
VBO::bind(vbo);
|
VBO::bind(vbo);
|
||||||
shState->bindQuadIBO();
|
shState->bindQuadIBO();
|
||||||
|
|
||||||
glEnableVertexAttribArray(Shader::Color);
|
/* Call correct implementation here via overloading */
|
||||||
glEnableVertexAttribArray(Shader::Position);
|
VertexType *dummy = 0;
|
||||||
glEnableVertexAttribArray(Shader::TexCoord);
|
initBufferBindings(dummy);
|
||||||
|
|
||||||
glVertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset());
|
|
||||||
glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset());
|
|
||||||
glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset());
|
|
||||||
|
|
||||||
VAO::unbind();
|
VAO::unbind();
|
||||||
IBO::unbind();
|
IBO::unbind();
|
||||||
VBO::unbind();
|
VBO::unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
~ColorQuadArray()
|
~QuadArray()
|
||||||
{
|
{
|
||||||
VBO::del(vbo);
|
VBO::del(vbo);
|
||||||
VAO::del(vao);
|
VAO::del(vao);
|
||||||
|
@ -78,15 +98,36 @@ struct ColorQuadArray
|
||||||
quadCount = size;
|
quadCount = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
vertices.clear();
|
||||||
|
quadCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This needs to be called after the final 'append()' call
|
/* This needs to be called after the final 'append()' call
|
||||||
* and previous to the first 'draw()' call. */
|
* and previous to the first 'draw()' call. */
|
||||||
void commit()
|
void commit()
|
||||||
{
|
{
|
||||||
VBO::bind(vbo);
|
VBO::bind(vbo);
|
||||||
VBO::uploadData(vertices.size() * sizeof(Vertex), &vertices[0], GL_DYNAMIC_DRAW);
|
|
||||||
VBO::unbind();
|
|
||||||
|
|
||||||
shState->ensureQuadIBO(quadCount);
|
GLsizeiptr size = vertices.size() * sizeof(VertexType);
|
||||||
|
|
||||||
|
if (size > vboSize)
|
||||||
|
{
|
||||||
|
/* New data exceeds already allocated size.
|
||||||
|
* Reallocate VBO. */
|
||||||
|
VBO::uploadData(size, &vertices[0], GL_DYNAMIC_DRAW);
|
||||||
|
vboSize = size;
|
||||||
|
|
||||||
|
shState->ensureQuadIBO(quadCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* New data fits in allocated size */
|
||||||
|
VBO::uploadSubData(0, size, &vertices[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
VBO::unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(size_t offset, size_t count)
|
void draw(size_t offset, size_t count)
|
||||||
|
@ -110,4 +151,7 @@ struct ColorQuadArray
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QuadArray<Vertex> ColorQuadArray;
|
||||||
|
typedef QuadArray<SVertex> SimpleQuadArray;
|
||||||
|
|
||||||
#endif // QUADARRAY_H
|
#endif // QUADARRAY_H
|
||||||
|
|
194
src/sprite.cpp
194
src/sprite.cpp
|
@ -32,6 +32,9 @@
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "glstate.h"
|
#include "glstate.h"
|
||||||
|
#include "quadarray.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <SDL_rect.h>
|
#include <SDL_rect.h>
|
||||||
|
|
||||||
|
@ -63,6 +66,22 @@ struct SpritePrivate
|
||||||
Color *color;
|
Color *color;
|
||||||
Tone *tone;
|
Tone *tone;
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int amp;
|
||||||
|
int length;
|
||||||
|
int speed;
|
||||||
|
float phase;
|
||||||
|
|
||||||
|
/* Wave effect is active (amp != 0) */
|
||||||
|
bool active;
|
||||||
|
/* qArray needs updating */
|
||||||
|
bool dirty;
|
||||||
|
SimpleQuadArray qArray;
|
||||||
|
} wave;
|
||||||
|
#endif
|
||||||
|
|
||||||
EtcTemps tmp;
|
EtcTemps tmp;
|
||||||
|
|
||||||
sigc::connection prepareCon;
|
sigc::connection prepareCon;
|
||||||
|
@ -87,6 +106,13 @@ struct SpritePrivate
|
||||||
|
|
||||||
prepareCon = shState->prepareDraw.connect
|
prepareCon = shState->prepareDraw.connect
|
||||||
(sigc::mem_fun(this, &SpritePrivate::prepare));
|
(sigc::mem_fun(this, &SpritePrivate::prepare));
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
wave.amp = 0;
|
||||||
|
wave.length = 180;
|
||||||
|
wave.speed = 360;
|
||||||
|
wave.phase = 0.0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~SpritePrivate()
|
~SpritePrivate()
|
||||||
|
@ -117,6 +143,10 @@ struct SpritePrivate
|
||||||
|
|
||||||
quad.setPosRect(IntRect(0, 0, srcRect->width, srcRect->height));
|
quad.setPosRect(IntRect(0, 0, srcRect->width, srcRect->height));
|
||||||
recomputeBushDepth();
|
recomputeBushDepth();
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
wave.dirty = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSrcRectCon()
|
void updateSrcRectCon()
|
||||||
|
@ -141,6 +171,16 @@ struct SpritePrivate
|
||||||
if (!opacity)
|
if (!opacity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
if (wave.active)
|
||||||
|
{
|
||||||
|
/* Don't do expensive wave bounding box
|
||||||
|
* calculations */
|
||||||
|
isVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Compare sprite bounding box against the scene */
|
/* Compare sprite bounding box against the scene */
|
||||||
|
|
||||||
/* If sprite is zoomed/rotated, just opt out for now
|
/* If sprite is zoomed/rotated, just opt out for now
|
||||||
|
@ -161,8 +201,102 @@ struct SpritePrivate
|
||||||
isVisible = SDL_HasIntersection(&self, &sceneRect);
|
isVisible = SDL_HasIntersection(&self, &sceneRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
void emitWaveChunk(SVertex *&vert, float phase, int width,
|
||||||
|
float zoomY, int chunkY, int chunkLength)
|
||||||
|
{
|
||||||
|
float wavePos = phase + (chunkY / (float) wave.length) * M_PI * 2;
|
||||||
|
float chunkX = sin(wavePos) * wave.amp;
|
||||||
|
|
||||||
|
FloatRect tex(0, chunkY / zoomY, width, chunkLength / zoomY);
|
||||||
|
FloatRect pos = tex;
|
||||||
|
pos.x = chunkX;
|
||||||
|
|
||||||
|
Quad::setTexPosRect(vert, tex, pos);
|
||||||
|
vert += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateWave()
|
||||||
|
{
|
||||||
|
if (!bitmap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wave.amp == 0)
|
||||||
|
{
|
||||||
|
wave.active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wave.active = true;
|
||||||
|
|
||||||
|
int width = srcRect->width;
|
||||||
|
int height = srcRect->height;
|
||||||
|
float zoomY = trans.getScale().y;
|
||||||
|
|
||||||
|
if (wave.amp < -(width / 2))
|
||||||
|
{
|
||||||
|
wave.qArray.resize(0);
|
||||||
|
wave.qArray.commit();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RMVX does this, and I have no fucking clue why */
|
||||||
|
if (wave.amp < 0)
|
||||||
|
{
|
||||||
|
wave.qArray.resize(1);
|
||||||
|
|
||||||
|
int x = -wave.amp;
|
||||||
|
int w = width - x * 2;
|
||||||
|
|
||||||
|
FloatRect tex(x, srcRect->y, w, srcRect->height);
|
||||||
|
|
||||||
|
Quad::setTexPosRect(&wave.qArray.vertices[0], tex, tex);
|
||||||
|
wave.qArray.commit();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The length of the sprite as it appears on screen */
|
||||||
|
int visibleLength = height * zoomY;
|
||||||
|
|
||||||
|
/* First chunk length (aligned to 8 pixel boundary */
|
||||||
|
int firstLength = ((int) trans.getPosition().y) % 8;
|
||||||
|
|
||||||
|
/* Amount of full 8 pixel chunks in the middle */
|
||||||
|
int chunks = (visibleLength - firstLength) / 8;
|
||||||
|
|
||||||
|
/* Final chunk length */
|
||||||
|
int lastLength = (visibleLength - firstLength) % 8;
|
||||||
|
|
||||||
|
wave.qArray.resize(!!firstLength + chunks + !!lastLength);
|
||||||
|
SVertex *vert = &wave.qArray.vertices[0];
|
||||||
|
|
||||||
|
float phase = (wave.phase * M_PI) / 180.f;
|
||||||
|
|
||||||
|
if (firstLength > 0)
|
||||||
|
emitWaveChunk(vert, phase, width, zoomY, 0, firstLength);
|
||||||
|
|
||||||
|
for (int i = 0; i < chunks; ++i)
|
||||||
|
emitWaveChunk(vert, phase, width, zoomY, firstLength + i * 8, 8);
|
||||||
|
|
||||||
|
if (lastLength > 0)
|
||||||
|
emitWaveChunk(vert, phase, width, zoomY, firstLength + chunks * 8, lastLength);
|
||||||
|
|
||||||
|
wave.qArray.commit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
{
|
{
|
||||||
|
#ifdef RGSS2
|
||||||
|
if (wave.dirty)
|
||||||
|
{
|
||||||
|
updateWave();
|
||||||
|
wave.dirty = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -193,14 +327,21 @@ DEF_ATTR_RD_SIMPLE(Sprite, Angle, float, p->trans.getRotation())
|
||||||
DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored)
|
DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored)
|
||||||
DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth)
|
DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth)
|
||||||
DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType)
|
DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType)
|
||||||
DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width)
|
|
||||||
DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height)
|
|
||||||
|
|
||||||
DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity)
|
DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity)
|
||||||
DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity)
|
DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity)
|
||||||
DEF_ATTR_SIMPLE(Sprite, Color, Color*, p->color)
|
DEF_ATTR_SIMPLE(Sprite, Color, Color*, p->color)
|
||||||
DEF_ATTR_SIMPLE(Sprite, Tone, Tone*, p->tone)
|
DEF_ATTR_SIMPLE(Sprite, Tone, Tone*, p->tone)
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width)
|
||||||
|
DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height)
|
||||||
|
DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp)
|
||||||
|
DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length)
|
||||||
|
DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed)
|
||||||
|
DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase)
|
||||||
|
#endif
|
||||||
|
|
||||||
void Sprite::setBitmap(Bitmap *bitmap)
|
void Sprite::setBitmap(Bitmap *bitmap)
|
||||||
{
|
{
|
||||||
GUARD_DISPOSED
|
GUARD_DISPOSED
|
||||||
|
@ -218,6 +359,10 @@ void Sprite::setBitmap(Bitmap *bitmap)
|
||||||
*p->srcRect = bitmap->rect();
|
*p->srcRect = bitmap->rect();
|
||||||
p->onSrcRectChange();
|
p->onSrcRectChange();
|
||||||
p->quad.setPosRect(p->srcRect->toFloatRect());
|
p->quad.setPosRect(p->srcRect->toFloatRect());
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
p->wave.dirty = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::setSrcRect(Rect *rect)
|
void Sprite::setSrcRect(Rect *rect)
|
||||||
|
@ -252,6 +397,10 @@ void Sprite::setY(int value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p->trans.setPosition(Vec2(getX(), value));
|
p->trans.setPosition(Vec2(getX(), value));
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
p->wave.dirty = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::setOX(int value)
|
void Sprite::setOX(int value)
|
||||||
|
@ -293,6 +442,10 @@ void Sprite::setZoomY(float value)
|
||||||
|
|
||||||
p->trans.setScale(Vec2(getZoomX(), value));
|
p->trans.setScale(Vec2(getZoomX(), value));
|
||||||
p->recomputeBushDepth();
|
p->recomputeBushDepth();
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
p->wave.dirty = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::setAngle(float value)
|
void Sprite::setAngle(float value)
|
||||||
|
@ -346,6 +499,36 @@ void Sprite::setBlendType(int type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
|
||||||
|
#define DEF_WAVE_SETTER(Name, name, type) \
|
||||||
|
void Sprite::setWave##Name(type value) \
|
||||||
|
{ \
|
||||||
|
GUARD_DISPOSED; \
|
||||||
|
if (p->wave.name == value) \
|
||||||
|
return; \
|
||||||
|
p->wave.name = value; \
|
||||||
|
p->wave.dirty = true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_WAVE_SETTER(Amp, amp, int)
|
||||||
|
DEF_WAVE_SETTER(Length, length, int)
|
||||||
|
DEF_WAVE_SETTER(Speed, speed, int)
|
||||||
|
DEF_WAVE_SETTER(Phase, phase, float)
|
||||||
|
|
||||||
|
#undef DEF_WAVE_SETTER
|
||||||
|
|
||||||
|
/* Flashable */
|
||||||
|
void Sprite::update()
|
||||||
|
{
|
||||||
|
Flashable::update();
|
||||||
|
|
||||||
|
p->wave.phase += p->wave.speed / 180;
|
||||||
|
p->wave.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Disposable */
|
/* Disposable */
|
||||||
void Sprite::releaseResources()
|
void Sprite::releaseResources()
|
||||||
{
|
{
|
||||||
|
@ -407,7 +590,14 @@ void Sprite::draw()
|
||||||
|
|
||||||
p->bitmap->bindTex(*base);
|
p->bitmap->bindTex(*base);
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
if (p->wave.active)
|
||||||
|
p->wave.qArray.draw();
|
||||||
|
else
|
||||||
|
p->quad.draw();
|
||||||
|
#else
|
||||||
p->quad.draw();
|
p->quad.draw();
|
||||||
|
#endif
|
||||||
|
|
||||||
glState.blendMode.pop();
|
glState.blendMode.pop();
|
||||||
}
|
}
|
||||||
|
|
15
src/sprite.h
15
src/sprite.h
|
@ -41,9 +41,6 @@ public:
|
||||||
Sprite(Viewport *viewport = 0);
|
Sprite(Viewport *viewport = 0);
|
||||||
~Sprite();
|
~Sprite();
|
||||||
|
|
||||||
int getWidth() const;
|
|
||||||
int getHeight() const;
|
|
||||||
|
|
||||||
DECL_ATTR( Bitmap, Bitmap* )
|
DECL_ATTR( Bitmap, Bitmap* )
|
||||||
DECL_ATTR( SrcRect, Rect* )
|
DECL_ATTR( SrcRect, Rect* )
|
||||||
DECL_ATTR( X, int )
|
DECL_ATTR( X, int )
|
||||||
|
@ -61,6 +58,18 @@ public:
|
||||||
DECL_ATTR( Color, Color* )
|
DECL_ATTR( Color, Color* )
|
||||||
DECL_ATTR( Tone, Tone* )
|
DECL_ATTR( Tone, Tone* )
|
||||||
|
|
||||||
|
#ifdef RGSS2
|
||||||
|
int getWidth() const;
|
||||||
|
int getHeight() const;
|
||||||
|
|
||||||
|
DECL_ATTR( WaveAmp, int )
|
||||||
|
DECL_ATTR( WaveLength, int )
|
||||||
|
DECL_ATTR( WaveSpeed, int )
|
||||||
|
DECL_ATTR( WavePhase, float )
|
||||||
|
|
||||||
|
void update();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpritePrivate *p;
|
SpritePrivate *p;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue