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
					
				
					 6 changed files with 346 additions and 21 deletions
				
			
		| 
						 | 
				
			
			@ -55,7 +55,7 @@ public:
 | 
			
		|||
		flashAlpha = flashColor.w;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void update()
 | 
			
		||||
	virtual void update()
 | 
			
		||||
	{
 | 
			
		||||
		if (!flashing)
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,17 +34,41 @@
 | 
			
		|||
typedef uint32_t index_t;
 | 
			
		||||
#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;
 | 
			
		||||
	VAO::ID vao;
 | 
			
		||||
 | 
			
		||||
	int quadCount;
 | 
			
		||||
	GLsizeiptr vboSize;
 | 
			
		||||
 | 
			
		||||
	ColorQuadArray()
 | 
			
		||||
	    : quadCount(0)
 | 
			
		||||
	QuadArray()
 | 
			
		||||
	    : quadCount(0),
 | 
			
		||||
	      vboSize(-1)
 | 
			
		||||
	{
 | 
			
		||||
		vbo = VBO::gen();
 | 
			
		||||
		vao = VAO::gen();
 | 
			
		||||
| 
						 | 
				
			
			@ -53,20 +77,16 @@ struct ColorQuadArray
 | 
			
		|||
		VBO::bind(vbo);
 | 
			
		||||
		shState->bindQuadIBO();
 | 
			
		||||
 | 
			
		||||
		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());
 | 
			
		||||
		/* Call correct implementation here via overloading */
 | 
			
		||||
		VertexType *dummy = 0;
 | 
			
		||||
		initBufferBindings(dummy);
 | 
			
		||||
 | 
			
		||||
		VAO::unbind();
 | 
			
		||||
		IBO::unbind();
 | 
			
		||||
		VBO::unbind();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~ColorQuadArray()
 | 
			
		||||
	~QuadArray()
 | 
			
		||||
	{
 | 
			
		||||
		VBO::del(vbo);
 | 
			
		||||
		VAO::del(vao);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,15 +98,36 @@ struct ColorQuadArray
 | 
			
		|||
		quadCount = size;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void clear()
 | 
			
		||||
	{
 | 
			
		||||
		vertices.clear();
 | 
			
		||||
		quadCount = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* This needs to be called after the final 'append()' call
 | 
			
		||||
	 * and previous to the first 'draw()' call. */
 | 
			
		||||
	void commit()
 | 
			
		||||
	{
 | 
			
		||||
		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)
 | 
			
		||||
| 
						 | 
				
			
			@ -110,4 +151,7 @@ struct ColorQuadArray
 | 
			
		|||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef QuadArray<Vertex> ColorQuadArray;
 | 
			
		||||
typedef QuadArray<SVertex> SimpleQuadArray;
 | 
			
		||||
 | 
			
		||||
#endif // QUADARRAY_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										194
									
								
								src/sprite.cpp
									
										
									
									
									
								
							
							
						
						
									
										194
									
								
								src/sprite.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -32,6 +32,9 @@
 | 
			
		|||
#include "transform.h"
 | 
			
		||||
#include "shader.h"
 | 
			
		||||
#include "glstate.h"
 | 
			
		||||
#include "quadarray.h"
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include <SDL_rect.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +66,22 @@ struct SpritePrivate
 | 
			
		|||
	Color *color;
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	sigc::connection prepareCon;
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +106,13 @@ struct SpritePrivate
 | 
			
		|||
 | 
			
		||||
		prepareCon = shState->prepareDraw.connect
 | 
			
		||||
		        (sigc::mem_fun(this, &SpritePrivate::prepare));
 | 
			
		||||
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
		wave.amp = 0;
 | 
			
		||||
		wave.length = 180;
 | 
			
		||||
		wave.speed = 360;
 | 
			
		||||
		wave.phase = 0.0;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~SpritePrivate()
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +143,10 @@ struct SpritePrivate
 | 
			
		|||
 | 
			
		||||
		quad.setPosRect(IntRect(0, 0, srcRect->width, srcRect->height));
 | 
			
		||||
		recomputeBushDepth();
 | 
			
		||||
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
		wave.dirty = true;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void updateSrcRectCon()
 | 
			
		||||
| 
						 | 
				
			
			@ -141,6 +171,16 @@ struct SpritePrivate
 | 
			
		|||
		if (!opacity)
 | 
			
		||||
			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 */
 | 
			
		||||
 | 
			
		||||
		/* If sprite is zoomed/rotated, just opt out for now
 | 
			
		||||
| 
						 | 
				
			
			@ -161,8 +201,102 @@ struct SpritePrivate
 | 
			
		|||
		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()
 | 
			
		||||
	{
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
		if (wave.dirty)
 | 
			
		||||
		{
 | 
			
		||||
			updateWave();
 | 
			
		||||
			wave.dirty = false;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		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, BushDepth, int,     p->bushDepth)
 | 
			
		||||
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, Opacity,     int,    p->opacity)
 | 
			
		||||
DEF_ATTR_SIMPLE(Sprite, Color,       Color*, p->color)
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
	GUARD_DISPOSED
 | 
			
		||||
| 
						 | 
				
			
			@ -218,6 +359,10 @@ void Sprite::setBitmap(Bitmap *bitmap)
 | 
			
		|||
	*p->srcRect = bitmap->rect();
 | 
			
		||||
	p->onSrcRectChange();
 | 
			
		||||
	p->quad.setPosRect(p->srcRect->toFloatRect());
 | 
			
		||||
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
	p->wave.dirty = true;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Sprite::setSrcRect(Rect *rect)
 | 
			
		||||
| 
						 | 
				
			
			@ -252,6 +397,10 @@ void Sprite::setY(int value)
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	p->trans.setPosition(Vec2(getX(), value));
 | 
			
		||||
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
	p->wave.dirty = true;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Sprite::setOX(int value)
 | 
			
		||||
| 
						 | 
				
			
			@ -293,6 +442,10 @@ void Sprite::setZoomY(float value)
 | 
			
		|||
 | 
			
		||||
	p->trans.setScale(Vec2(getZoomX(), value));
 | 
			
		||||
	p->recomputeBushDepth();
 | 
			
		||||
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
	p->wave.dirty = true;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
void Sprite::releaseResources()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -407,7 +590,14 @@ void Sprite::draw()
 | 
			
		|||
 | 
			
		||||
	p->bitmap->bindTex(*base);
 | 
			
		||||
 | 
			
		||||
#ifdef RGSS2
 | 
			
		||||
	if (p->wave.active)
 | 
			
		||||
		p->wave.qArray.draw();
 | 
			
		||||
	else
 | 
			
		||||
		p->quad.draw();
 | 
			
		||||
#else
 | 
			
		||||
	p->quad.draw();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	glState.blendMode.pop();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								src/sprite.h
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/sprite.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -41,9 +41,6 @@ public:
 | 
			
		|||
	Sprite(Viewport *viewport = 0);
 | 
			
		||||
	~Sprite();
 | 
			
		||||
 | 
			
		||||
	int getWidth()  const;
 | 
			
		||||
	int getHeight() const;
 | 
			
		||||
 | 
			
		||||
	DECL_ATTR( Bitmap,      Bitmap* )
 | 
			
		||||
	DECL_ATTR( SrcRect,     Rect*   )
 | 
			
		||||
	DECL_ATTR( X,           int     )
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +58,18 @@ public:
 | 
			
		|||
	DECL_ATTR( Color,       Color*  )
 | 
			
		||||
	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:
 | 
			
		||||
	SpritePrivate *p;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue