43 m_numPatternX = m_numPatternY = m_numPatternZ = 0;
44 m_animationPhases = 0;
112 fin->
addU8(m_realSize);
114 fin->
addU8(m_layers);
115 fin->
addU8(m_numPatternX);
116 fin->
addU8(m_numPatternY);
117 fin->
addU8(m_numPatternZ);
118 fin->
addU8(m_animationPhases);
121 if(m_animationPhases > 1 && m_animator !=
nullptr) {
126 for(
int i: m_spritesIndex) {
138 m_category = category;
140 int count = 0, attr = -1;
183 if(attr > 0 && attr <= 15)
220 m_displacement.
x = fin->
getU16();
221 m_displacement.
y = fin->
getU16();
223 m_displacement.
x = 8;
224 m_displacement.
y = 8;
226 m_attribs.
set(attr,
true);
233 m_attribs.
set(attr, light);
244 m_attribs.
set(attr, market);
248 m_elevation = fin->
getU16();
249 m_attribs.
set(attr, m_elevation);
262 m_attribs.
set(attr,
true);
269 m_id, m_category, count, attr));
272 uint8 groupCount = hasFrameGroups ? fin->
getU8() : 1;
274 m_animationPhases = 0;
275 int totalSpritesCount = 0;
277 for(
int i = 0; i < groupCount; ++i) {
280 frameGroupType = fin->
getU8();
284 m_size =
Size(width, height);
285 if(width > 1 || height > 1) {
286 m_realSize = fin->
getU8();
287 m_exactSize = std::min<int>(m_realSize, std::max<int>(width * 32, height * 32));
292 m_layers = fin->
getU8();
293 m_numPatternX = fin->
getU8();
294 m_numPatternY = fin->
getU8();
296 m_numPatternZ = fin->
getU8();
300 int groupAnimationsPhases = fin->
getU8();
301 m_animationPhases += groupAnimationsPhases;
305 m_animator->
unserialize(groupAnimationsPhases, fin);
308 int totalSprites = m_size.
area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * groupAnimationsPhases;
310 if((totalSpritesCount+totalSprites) > 4096)
313 m_spritesIndex.resize((totalSpritesCount+totalSprites));
314 for(
int j = totalSpritesCount; j < (totalSpritesCount+totalSprites); j++)
317 totalSpritesCount += totalSprites;
320 m_textures.resize(m_animationPhases);
321 m_texturesFramesRects.resize(m_animationPhases);
322 m_texturesFramesOriginRects.resize(m_animationPhases);
323 m_texturesFramesOffsets.resize(m_animationPhases);
331 if(m_spritesIndex.empty())
334 ImagePtr image(
new Image(
Size(32 * m_size.
width() * m_layers * m_numPatternX, 32 * m_size.
height() * m_animationPhases * m_numPatternY * m_numPatternZ)));
335 for(
int z = 0;
z < m_numPatternZ; ++
z) {
336 for(
int y = 0; y < m_numPatternY; ++y) {
337 for(
int x = 0; x < m_numPatternX; ++x) {
338 for(
int l = 0; l < m_layers; ++l) {
339 for(
int a = 0; a < m_animationPhases; ++a) {
340 for(
int w = 0; w < m_size.
width(); ++w) {
341 for(
int h = 0; h < m_size.
height(); ++h) {
342 image->blit(
Point(32 * (m_size.
width() - w - 1 + m_size.
width() * x + m_size.
width() * m_numPatternX * l),
343 32 * (m_size.
height() - h - 1 + m_size.
height() * y + m_size.
height() * m_numPatternY * a + m_size.
height() * m_numPatternY * m_animationPhases *
z)),
353 image->savePNG(fileName);
359 if(node2->tag() ==
"opacity")
360 m_opacity = node2->value<
float>();
361 else if(node2->tag() ==
"notprewalkable")
363 else if(node2->tag() ==
"image")
364 m_customImage = node2->value();
365 else if(node2->tag() ==
"full-ground") {
366 if(node2->value<
bool>())
379 if(animationPhase >= m_animationPhases)
382 const TexturePtr& texture = getTexture(animationPhase);
386 uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
387 if(frameIndex >= m_texturesFramesRects[animationPhase].size())
393 if(scaleFactor != 1.0f) {
394 textureRect = m_texturesFramesOriginRects[animationPhase][frameIndex];
396 textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex];
397 textureRect = m_texturesFramesRects[animationPhase][frameIndex];
400 Rect screenRect(dest + (textureOffset - m_displacement - (m_size.
toPoint() -
Point(1, 1)) * 32) * scaleFactor,
401 textureRect.
size() * scaleFactor);
403 bool useOpacity = m_opacity < 1.0f;
420 const TexturePtr& ThingType::getTexture(
int animationPhase)
422 TexturePtr& animationPhaseTexture = m_textures[animationPhase];
423 if(!animationPhaseTexture) {
424 bool useCustomImage =
false;
425 if(animationPhase == 0 && !m_customImage.empty())
426 useCustomImage =
true;
429 int textureLayers = 1;
430 int numLayers = m_layers;
437 int indexSize = textureLayers * m_numPatternX * m_numPatternY * m_numPatternZ;
438 Size textureSize = getBestTextureDimension(m_size.
width(), m_size.
height(), indexSize);
446 m_texturesFramesRects[animationPhase].resize(indexSize);
447 m_texturesFramesOriginRects[animationPhase].resize(indexSize);
448 m_texturesFramesOffsets[animationPhase].resize(indexSize);
450 for(
int z = 0;
z < m_numPatternZ; ++
z) {
451 for(
int y = 0; y < m_numPatternY; ++y) {
452 for(
int x = 0; x < m_numPatternX; ++x) {
453 for(
int l = 0; l < numLayers; ++l) {
455 int frameIndex = getTextureIndex(l % textureLayers, x, y,
z);
459 if(!useCustomImage) {
460 for(
int h = 0; h < m_size.
height(); ++h) {
461 for(
int w = 0; w < m_size.
width(); ++w) {
462 uint spriteIndex = getSpriteIndex(w, h, spriteMask ? 1 : l, x, y,
z, animationPhase);
467 spriteImage->overwriteMask(maskColors[l - 1]);
472 fullImage->blit(framePos + spritePos, spriteImage);
481 uint8 *p = fullImage->getPixel(fx,fy);
483 drawRect.setTop (std::min<int>(fy, (
int)drawRect.top()));
484 drawRect.setLeft (std::min<int>(fx, (
int)drawRect.left()));
485 drawRect.setBottom(std::max<int>(fy, (
int)drawRect.bottom()));
486 drawRect.setRight (std::max<int>(fx, (
int)drawRect.right()));
491 m_texturesFramesRects[animationPhase][frameIndex] = drawRect;
493 m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos;
501 return animationPhaseTexture;
504 Size ThingType::getBestTextureDimension(
int w,
int h,
int count)
518 int numSprites = w*h*count;
519 assert(numSprites <= MAX*MAX);
523 Size bestDimension =
Size(MAX, MAX);
524 for(
int i=w;i<=MAX;i<<=1) {
525 for(
int j=h;j<=MAX;j<<=1) {
526 Size candidateDimension =
Size(i, j);
527 if(candidateDimension.
area() < numSprites)
529 if((candidateDimension.
area() < bestDimension.
area()) ||
530 (candidateDimension.
area() == bestDimension.
area() && candidateDimension.
width() + candidateDimension.
height() < bestDimension.
width() + bestDimension.
height()))
531 bestDimension = candidateDimension;
535 return bestDimension;
538 uint ThingType::getSpriteIndex(
int w,
int h,
int l,
int x,
int y,
int z,
int a) {
540 ((((((a % m_animationPhases)
546 * m_size.
width() + w;
547 assert(index < m_spritesIndex.size());
551 uint ThingType::getTextureIndex(
int l,
int x,
int y,
int z) {
552 return ((l * m_numPatternZ +
z)
562 getTexture(animationPhase);
563 int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
564 Size size = m_texturesFramesOriginRects[animationPhase][frameIndex].size() - m_texturesFramesOffsets[animationPhase][frameIndex].toSize();