Brought the tilemap class mostly in line with Essential's CustomTilemap wrt animations, though at the cost of backwards compatibility.

(This could be rescued by per-tile animation lentghs in tilemap.vert, but this should suffice for now.)
This commit is contained in:
Aeodyn 2020-07-14 19:34:38 +00:00 committed by Roza
parent 647d5339f4
commit 050da27ca0
12 changed files with 322 additions and 80 deletions

View file

@ -742,13 +742,23 @@ static void mriBindingExecute() {
char **argv = 0;
ruby_sysinit(&argc, &argv);
ruby_setup();
RUBY_INIT_STACK;
ruby_init();
rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
#else
ruby_init();
rb_eval_string("$KCODE='U'");
#endif
#ifdef JIT
const char* rboptions[] = {"", "--disable-gems", "--jit-verbose=1", "--jit-max-cache=100", "--jit-min-calls=100000", "-e "};
void* node = ruby_process_options(6, const_cast<char**>(rboptions));
int state;
bool valid = ruby_executable_node(node, &state);
state = ruby_exec_node(node);
#endif
#if defined(EASY_POKE) && !defined(__WIN32__)
char *tmpdir = getenv("TMPDIR");
if (tmpdir)

View file

@ -85,12 +85,17 @@ RB_METHOD(tilemapInitialize) {
/* Construct object */
t = new Tilemap(viewport);
setPrivateData(self, t);
rb_iv_set(self, "viewport", viewportObj);
setPrivateData(self, t);
t->initDynAttribs();
wrapProperty(self, &t->getAutotiles(), "autotiles", TilemapAutotilesType);
wrapProperty(self, &t->getColor(), "color", ColorType);
wrapProperty(self, &t->getTone(), "tone", ToneType);
VALUE autotilesObj = rb_iv_get(self, "autotiles");
VALUE ary = rb_ary_new2(7);
@ -137,11 +142,17 @@ DEF_PROP_OBJ_REF(Tilemap, Table, MapData, "map_data")
DEF_PROP_OBJ_REF(Tilemap, Table, FlashData, "flash_data")
DEF_PROP_OBJ_REF(Tilemap, Table, Priorities, "priorities")
DEF_PROP_OBJ_VAL(Tilemap, Color, Color, "color")
DEF_PROP_OBJ_VAL(Tilemap, Tone, Tone, "tone")
DEF_PROP_B(Tilemap, Visible)
DEF_PROP_I(Tilemap, OX)
DEF_PROP_I(Tilemap, OY)
DEF_PROP_I(Tilemap, Opacity)
DEF_PROP_I(Tilemap, BlendType)
void tilemapBindingInit() {
VALUE klass = rb_define_class("TilemapAutotiles", rb_cObject);
#if RAPI_FULL > 187
@ -173,4 +184,9 @@ void tilemapBindingInit() {
INIT_PROP_BIND(Tilemap, Visible, "visible");
INIT_PROP_BIND(Tilemap, OX, "ox");
INIT_PROP_BIND(Tilemap, OY, "oy");
INIT_PROP_BIND(Tilemap, Opacity, "opacity");
INIT_PROP_BIND(Tilemap, BlendType, "blend_type");
INIT_PROP_BIND(Tilemap, Color, "color");
INIT_PROP_BIND(Tilemap, Tone, "tone");
}

View file

@ -13,6 +13,7 @@ embedded_shaders = [
'simpleColor.frag',
'simpleAlpha.frag',
'simpleAlphaUni.frag',
'tilemap.frag',
'flashMap.frag',
'minimal.vert',
'simple.vert',

33
shader/tilemap.frag Normal file
View file

@ -0,0 +1,33 @@
uniform sampler2D v_texture;
uniform lowp vec4 tone;
uniform lowp float opacity;
uniform lowp vec4 color;
in vec2 v_texCoord;
const vec3 lumaF = vec3(.299, .587, .114);
out vec4 fragColor;
void main() {
/* Sample source color */
vec4 frag = texture(v_texture, v_texCoord);
/* Apply gray */
float luma = dot(frag.rgb, lumaF);
frag.rgb = mix(frag.rgb, vec3(luma), tone.w);
/* Apply tone */
frag.rgb += tone.rgb;
/* Apply opacity */
frag.a *= opacity;
/* Apply color */
frag.rgb = mix(frag.rgb, color.rgb, color.a);
fragColor = frag;
}

View file

@ -4,23 +4,36 @@ uniform mat4 projMat;
uniform vec2 texSizeInv;
uniform vec2 translation;
uniform float aniIndex;
uniform highp int aniIndex;
attribute vec2 position;
attribute vec2 texCoord;
varying vec2 v_texCoord;
const float atAreaW = 96.0;
const float atAreaH = 128.0*7.0;
const float atAniOffset = 32.0*3.0;
const int nAutotiles = 7;
const float tileW = 32.0;
const float tileH = 32.0;
const float autotileW = 3.0*tileW;
const float autotileH = 4.0*tileW;
const float atAreaW = autotileW;
const float atAreaH = autotileH*nAutotiles;
const float atAniOffsetX = 3.0*tileW;
const float atAniOffsetY = tileH;
uniform lowp int atFrames[nAutotiles];
void main()
{
vec2 tex = texCoord;
lowp uint atIndex = uint(tex.y / autotileH);
lowp float pred = float(tex.x <= atAreaW && tex.y <= atAreaH);
tex.x += aniIndex * atAniOffset * pred;
lowp uint pred = uint(tex.x <= atAreaW && tex.y <= atAreaH);
lowp uint frame = uint(aniIndex % atFrames[atIndex]);
lowp uint col = frame % 8;
lowp uint row = frame / 8;
tex.x += atAniOffsetX * (col * pred);
tex.y += atAniOffsetY * (row * pred);
gl_Position = projMat * vec4(position + translation, 0, 1);

View file

@ -90,6 +90,7 @@ typedef void (APIENTRYP _PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
typedef void (APIENTRYP _PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
typedef void (APIENTRYP _PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef void (APIENTRYP _PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
typedef void (APIENTRYP _PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (APIENTRYP _PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
/* Vertex attribute */
@ -174,6 +175,7 @@ typedef void (APIENTRYP _PFNGLRELEASESHADERCOMPILERPROC) (void);
GL_FUN(Uniform2f, _PFNGLUNIFORM2FPROC) \
GL_FUN(Uniform4f, _PFNGLUNIFORM4FPROC) \
GL_FUN(Uniform1i, _PFNGLUNIFORM1IPROC) \
GL_FUN(Uniform1iv, _PFNGLUNIFORM1IVPROC) \
GL_FUN(UniformMatrix4fv, _PFNGLUNIFORMMATRIX4FVPROC) \
/* Vertex attribute */ \
GL_FUN(BindAttribLocation, _PFNGLBINDATTRIBLOCATIONPROC) \

View file

@ -41,6 +41,7 @@
#include "simpleColor.frag.xxd"
#include "simpleAlpha.frag.xxd"
#include "simpleAlphaUni.frag.xxd"
#include "tilemap.frag.xxd"
#include "flashMap.frag.xxd"
#include "minimal.vert.xxd"
#include "simple.vert.xxd"
@ -515,16 +516,41 @@ void GrayShader::setGray(float value)
TilemapShader::TilemapShader()
{
INIT_SHADER(tilemap, simple, TilemapShader);
INIT_SHADER(tilemap, tilemap, TilemapShader);
ShaderBase::init();
GET_U(tone);
GET_U(color);
GET_U(opacity);
GET_U(aniIndex);
GET_U(atFrames);
}
void TilemapShader::setTone(const Vec4 &tone)
{
setVec4Uniform(u_tone, tone);
}
void TilemapShader::setColor(const Vec4 &color)
{
setVec4Uniform(u_color, color);
}
void TilemapShader::setOpacity(float value)
{
gl.Uniform1f(u_opacity, value);
}
void TilemapShader::setAniIndex(int value)
{
gl.Uniform1f(u_aniIndex, value);
gl.Uniform1i(u_aniIndex, value);
}
void TilemapShader::setATFrames(int values[7])
{
gl.Uniform1iv(u_atFrames, 7, values);
}

View file

@ -220,8 +220,14 @@ public:
void setAniIndex(int value);
void setTone(const Vec4 &value);
void setColor(const Vec4 &value);
void setOpacity(float value);
void setATFrames(int values[7]);
private:
GLint u_aniIndex;
GLint u_aniIndex, u_tone, u_color, u_opacity, u_atFrames;
};
class FlashMapShader : public ShaderBase

View file

@ -212,7 +212,7 @@ struct SpritePrivate
FloatRect pos = tex;
pos.x = chunkX;
Quad::setTexPosRect(vert, tex, pos);
Quad::setTexPosRect(vert, mirrored ? tex.hFlipped() : tex, pos);
vert += 4;
}

View file

@ -40,14 +40,16 @@ typedef std::vector<Column> ColumnVec;
/* Buffer between autotile area and tileset */
static const int atBuffer = 32;
/* Autotile area width */
static const int atAreaW = 96*4;
static const int atAreaW = 32*3*8;
/* Autotile area height */
static const int atAreaH = 128*7 + atBuffer;
/* Autotile area */
static const int atArea = atAreaW * atAreaH;
static const int atAreaH = 32*4*7 + atBuffer;
static const int tilesetW = 256;
static const int tsLaneW = tilesetW / 2;
static const int tilesetW = 32*8;
static const int tsLaneW = tilesetW / 1;
static const int underAtLanes = atAreaW / tsLaneW + !!(atAreaW % tsLaneW);
/* Autotile area */
static const int atArea = underAtLanes * tsLaneW * atAreaH;
static int freeArea(int width, int height)
{
@ -56,7 +58,7 @@ static int freeArea(int width, int height)
Vec2i minSize(int tilesetH, int maxAtlasSize)
{
int width = atAreaW;
int width = underAtLanes * tsLaneW;
int height = atAreaH;
const int tsArea = tilesetW * tilesetH;
@ -81,10 +83,10 @@ Vec2i minSize(int tilesetH, int maxAtlasSize)
static ColumnVec calcSrcCols(int tilesetH)
{
ColumnVec cols;
cols.reserve(2);
// cols.reserve(2);
cols.push_back(Column(0, 0, tilesetH));
cols.push_back(Column(tsLaneW, 0, tilesetH));
// cols.push_back(Column(tsLaneW, 0, tilesetH));
return cols;
}
@ -92,21 +94,19 @@ static ColumnVec calcSrcCols(int tilesetH)
static ColumnVec calcDstCols(int atlasW, int atlasH)
{
ColumnVec cols;
cols.reserve(3);
cols.reserve(underAtLanes);
/* Columns below the autotile area */
const int underAt = atlasH - atAreaH;
for (int i = 0; i < 3; ++i)
for (int i = 0; i < underAtLanes; ++i)
cols.push_back(Column(i*tsLaneW, atAreaH, underAt));
if (atlasW <= atAreaW)
return cols;
const int remCols = atlasW / tsLaneW - underAtLanes;
const int remCols = (atlasW - atAreaW) / tsLaneW;
for (int i = 0; i < remCols; ++i)
cols.push_back(Column(i*tsLaneW + atAreaW, 0, atlasH));
if (remCols > 0)
for (int i = 0; i < remCols; ++i)
cols.push_back(Column((underAtLanes+i)*tsLaneW, 0, atlasH));
return cols;
}
@ -178,17 +178,17 @@ Vec2i tileToAtlasCoor(int tileX, int tileY, int tilesetH, int atlasH)
int longlaneH = atlasH;
int shortlaneH = longlaneH - atAreaH;
int longlaneOffset = shortlaneH * 3;
int longlaneOffset = shortlaneH * underAtLanes;
int laneIdx = 0;
int atlasY = 0;
/* Check if we're inside the 2nd lane */
if (laneX >= tsLaneW)
{
laneY += tilesetH;
laneX -= tsLaneW;
}
// if (laneX >= tsLaneW)
// {
// laneY += tilesetH;
// laneX -= tsLaneW;
// }
if (laneY < longlaneOffset)
{
@ -200,7 +200,7 @@ Vec2i tileToAtlasCoor(int tileX, int tileY, int tilesetH, int atlasH)
{
/* Right of autotile area */
int _y = laneY - longlaneOffset;
laneIdx = 3 + _y / longlaneH;
laneIdx = underAtLanes + _y / longlaneH;
atlasY = _y % longlaneH;
}

View file

@ -58,10 +58,12 @@ static const int autotileH = 4 * 32;
static const int autotileCount = 7;
static const int atAreaW = autotileW * 4;
static const int atFrames = 8;
static const int atFrameDur = 15;
static const int atAreaW = autotileW * atFrames;
static const int atAreaH = autotileH * autotileCount;
static const int tsLaneW = tilesetW / 2;
static const int tsLaneW = tilesetW / 1;
/* Map viewport size */
static const int viewpW = 21;
@ -155,15 +157,19 @@ static const size_t zlayersMax = viewpH + 5;
*/
/* Autotile animation */
static const uint8_t atAnimation[16*4] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
// static const uint8_t atAnimation[16*8] =
// {
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
// 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
// 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
// 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
// 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
// 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
// 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
// };
static elementsN(atAnimation);
// static elementsN(atAnimation);
/* Flash tiles pulsing opacity */
static const uint8_t flashAlpha[] =
@ -256,6 +262,12 @@ struct TilemapPrivate
/* Indices of animated autotiles */
std::vector<uint8_t> animatedATs;
/* Whether each autotile is 3x4 or not */
bool smallATs[autotileCount] = {false};
/* The number of frames for each autotile */
int nATFrames[autotileCount] = {1};
} atlas;
/* Map viewport position */
@ -279,8 +291,7 @@ struct TilemapPrivate
bool animated;
/* Animation state */
uint8_t frameIdx;
uint8_t aniIdx;
uint32_t aniIdx;
} tiles;
FlashMap flashMap;
@ -322,6 +333,13 @@ struct TilemapPrivate
/* Draw prepare call */
sigc::connection prepareCon;
NormValue opacity;
BlendType blendType;
Color *color;
Tone *tone;
EtcTemps tmp;
TilemapPrivate(Viewport *viewport)
: viewport(viewport),
tileset(0),
@ -334,7 +352,12 @@ struct TilemapPrivate
buffersDirty(false),
mapViewportDirty(false),
zOrderDirty(false),
tilemapReady(false)
tilemapReady(false),
opacity(255),
blendType(BlendNormal),
color(&tmp.color),
tone(&tmp.tone)
{
memset(autotiles, 0, sizeof(autotiles));
@ -342,7 +365,6 @@ struct TilemapPrivate
atlas.efTilesetH = 0;
tiles.animated = false;
tiles.frameIdx = 0;
tiles.aniIdx = 0;
/* Init tile buffers */
@ -432,8 +454,18 @@ struct TilemapPrivate
usableATs.push_back(i);
if (autotiles[i]->width() > autotileW)
if (autotiles[i]->height() == 32)
{
atlas.smallATs[i] = true;
atlas.nATFrames[i] = autotiles[i]->width()/32;
animatedATs.push_back(i);
}
else
{
atlas.nATFrames[i] = autotiles[i]->width()/autotileW;
if (atlas.nATFrames[i] > 1)
animatedATs.push_back(i);
}
}
tiles.animated = !animatedATs.empty();
@ -509,23 +541,35 @@ struct TilemapPrivate
const uint8_t atInd = atlas.usableATs[i];
Bitmap *autotile = autotiles[atInd];
int blitW = std::min(autotile->width(), atAreaW);
int blitH = std::min(autotile->height(), atAreaH);
int atW = autotile->width();
int atH = autotile->height();
int blitW = std::min(atW, atAreaW);
int blitH = std::min(atH, autotileH);
GLMeta::blitSource(autotile->getGLTypes());
if (blitW <= autotileW && tiles.animated)
if (atW <= autotileW && tiles.animated && !atlas.smallATs[atInd])
{
/* Static autotile */
for (int j = 0; j < 4; ++j)
for (int j = 0; j < atFrames; ++j)
GLMeta::blitRectangle(IntRect(0, 0, blitW, blitH),
Vec2i(autotileW*j, atInd*autotileH));
}
else
{
/* Animated autotile */
GLMeta::blitRectangle(IntRect(0, 0, blitW, blitH),
Vec2i(0, atInd*autotileH));
if (atlas.smallATs[atInd])
{
int frames = atW/32;
for (int j = 0; j < atFrames*autotileH/32; ++j)
{
GLMeta::blitRectangle(IntRect(32*(j % frames), 0, 32, 32),
Vec2i(autotileW*(j % atFrames), atInd*autotileH + 32*(j / atFrames)));
}
}
else
GLMeta::blitRectangle(IntRect(0, 0, blitW, blitH),
Vec2i(0, atInd*autotileH));
}
}
@ -627,28 +671,42 @@ struct TilemapPrivate
{
/* Which autotile [0-7] */
int atInd = tileInd / 48 - 1;
/* Which tile pattern of the autotile [0-47] */
int subInd = tileInd % 48;
const StaticRect *pieceRect = &autotileRects[subInd*4];
/* Iterate over the 4 tile pieces */
for (int i = 0; i < 4; ++i)
if (!atlas.smallATs[atInd])
{
FloatRect posRect(x*32, y*32, 16, 16);
atSelectSubPos(posRect, i);
/* Which tile pattern of the autotile [0-47] */
int subInd = tileInd % 48;
FloatRect texRect = pieceRect[i];
const StaticRect *pieceRect = &autotileRects[subInd*4];
/* Adjust to atlas coordinates */
texRect.y += atInd * autotileH;
/* Iterate over the 4 tile pieces */
for (int i = 0; i < 4; ++i)
{
FloatRect posRect(x*32, y*32, 16, 16);
atSelectSubPos(posRect, i);
FloatRect texRect = pieceRect[i];
/* Adjust to atlas coordinates */
texRect.y += atInd * autotileH;
SVertex v[4];
Quad::setTexPosRect(v, texRect, posRect);
/* Iterate over 4 vertices */
for (size_t j = 0; j < 4; ++j)
array->push_back(v[j]);
}
}
else
{
FloatRect posRect(x*32, y*32, 32, 32);
FloatRect texRect(0.5f, atInd * autotileH + 0.5f, 31, 31);
SVertex v[4];
Quad::setTexPosRect(v, texRect, posRect);
/* Iterate over 4 vertices */
for (size_t i = 0; i < 4; ++i)
array->push_back(v[i]);
for (size_t j = 0; j < 4; ++j)
array->push_back(v[j]);
}
}
@ -677,6 +735,8 @@ struct TilemapPrivate
else
{
int layerInd = y + prio;
if (layerInd >= zlayersMax)
return;
targetArray = &zlayerVert[layerInd];
}
@ -714,8 +774,30 @@ struct TilemapPrivate
{
clearQuadArrays();
for (int x = 0; x < viewpW; ++x)
for (int y = 0; y < viewpH; ++y)
int ox = viewpPos.x;
int oy = viewpPos.y;
int mapW = mapData->xSize();
int mapH = mapData->ySize();
int minX = 0;
int minY = 0;
if (ox < 0)
minX = -ox;
if (oy < 0)
minY = -oy;
// There could be off-by-one issues in these couple sections.
int maxX = viewpW;
int maxY = viewpH;
if (ox + maxX >= mapW)
maxX = mapW - ox - 1;
if (oy + maxY >= mapH)
maxY = mapH - oy - 1;
if ((minX > maxX) || (minY > maxY))
return;
for (int x = minX; x <= maxX; ++x)
for (int y = minY; y <= maxY; ++y)
for (int z = 0; z < mapData->zSize(); ++z)
handleTile(x, y, z);
}
@ -766,11 +848,16 @@ struct TilemapPrivate
void bindShader(ShaderBase *&shaderVar)
{
if (tiles.animated)
if (tiles.animated || color->hasEffect() || tone->hasEffect() || opacity != 255)
{
TilemapShader &tilemapShader = shState->shaders().tilemap;
tilemapShader.bind();
tilemapShader.setAniIndex(tiles.frameIdx);
tilemapShader.applyViewportProj();
tilemapShader.setTone(tone->norm);
tilemapShader.setColor(color->norm);
tilemapShader.setOpacity(opacity.norm);
tilemapShader.setAniIndex(tiles.aniIdx / atFrameDur);
tilemapShader.setATFrames(atlas.nATFrames);
shaderVar = &tilemapShader;
}
else
@ -974,11 +1061,16 @@ void GroundLayer::draw()
if (p->groundVert.size() == 0)
return;
if (!p->opacity)
return;
ShaderBase *shader;
p->bindShader(shader);
p->bindAtlas(*shader);
glState.blendMode.pushSet(p->blendType);
GLMeta::vaoBind(p->tiles.vao);
shader->setTranslation(p->dispPos);
@ -987,6 +1079,8 @@ void GroundLayer::draw()
GLMeta::vaoUnbind(p->tiles.vao);
p->flashMap.draw(flashAlpha[p->flashAlphaIdx] / 255.f, p->dispPos);
glState.blendMode.pop();
}
void GroundLayer::drawInt()
@ -1029,12 +1123,16 @@ void ZLayer::draw()
p->bindShader(shader);
p->bindAtlas(*shader);
glState.blendMode.pushSet(p->blendType);
GLMeta::vaoBind(p->tiles.vao);
shader->setTranslation(p->dispPos);
drawInt();
GLMeta::vaoUnbind(p->tiles.vao);
glState.blendMode.pop();
}
void ZLayer::drawInt()
@ -1125,10 +1223,7 @@ void Tilemap::update()
if (!p->tiles.animated)
return;
p->tiles.frameIdx = atAnimation[p->tiles.aniIdx];
if (++p->tiles.aniIdx >= atAnimationN)
p->tiles.aniIdx = 0;
++p->tiles.aniIdx;
}
Tilemap::Autotiles &Tilemap::getAutotiles()
@ -1147,6 +1242,11 @@ DEF_ATTR_RD_SIMPLE(Tilemap, Visible, bool, p->visible)
DEF_ATTR_RD_SIMPLE(Tilemap, OX, int, p->origin.x)
DEF_ATTR_RD_SIMPLE(Tilemap, OY, int, p->origin.y)
DEF_ATTR_RD_SIMPLE(Tilemap, BlendType, int, p->blendType)
DEF_ATTR_SIMPLE(Tilemap, Opacity, int, p->opacity)
DEF_ATTR_SIMPLE(Tilemap, Color, Color&, *p->color)
DEF_ATTR_SIMPLE(Tilemap, Tone, Tone&, *p->tone)
void Tilemap::setTileset(Bitmap *value)
{
guardDisposed();
@ -1250,6 +1350,31 @@ void Tilemap::setOY(int value)
p->mapViewportDirty = true;
}
void Tilemap::setBlendType(int value)
{
guardDisposed();
switch (value)
{
default :
case BlendNormal :
p->blendType = BlendNormal;
return;
case BlendAddition :
p->blendType = BlendAddition;
return;
case BlendSubstraction :
p->blendType = BlendSubstraction;
return;
}
}
void Tilemap::initDynAttribs()
{
p->color = new Color;
p->tone = new Tone;
}
void Tilemap::releaseResources()
{
delete p;

View file

@ -30,6 +30,9 @@ class Viewport;
class Bitmap;
class Table;
struct Color;
struct Tone;
struct TilemapPrivate;
class Tilemap : public Disposable
@ -66,6 +69,13 @@ public:
DECL_ATTR( OX, int )
DECL_ATTR( OY, int )
DECL_ATTR( Opacity, int )
DECL_ATTR( BlendType, int )
DECL_ATTR( Color, Color& )
DECL_ATTR( Tone, Tone& )
void initDynAttribs();
private:
TilemapPrivate *p;
Autotiles atProxy;