Browse Source

Detect and link animated texture frames

master
Nico de Poel 3 years ago
parent
commit
b0f7e971e8
  1. 49
      texture.cpp

49
texture.cpp

@ -170,7 +170,7 @@ static void analyze_texture(unsigned char* texBytes, int numBytes, const Color p
desaturate(outTexture.dominantColor.channel, outTexture.dominantColor.channel); desaturate(outTexture.dominantColor.channel, outTexture.dominantColor.channel);
} }
bool process_textures(const world_t* world, TextureList& outTextures) // TODO: return TextureDescriptor structs, including average texture color
bool process_textures(const world_t* world, TextureList& outTextures)
{ {
using spaces_type = rectpack2D::empty_spaces<false>; using spaces_type = rectpack2D::empty_spaces<false>;
using rect_type = rectpack2D::output_rect_t<spaces_type>; using rect_type = rectpack2D::output_rect_t<spaces_type>;
@ -259,6 +259,8 @@ bool process_textures(const world_t* world, TextureList& outTextures) // TODO: r
printf("Constructing texture atlas...\n"); printf("Constructing texture atlas...\n");
std::unordered_map<std::string, std::unordered_map<int, int>> animationFrames;
// Try to construct the texture atlas, see what we get // Try to construct the texture atlas, see what we get
for (int texNum = 0; texNum < world->mipheader.numtex; ++texNum) for (int texNum = 0; texNum < world->mipheader.numtex; ++texNum)
{ {
@ -269,10 +271,6 @@ bool process_textures(const world_t* world, TextureList& outTextures) // TODO: r
continue; continue;
} }
char* outName = miptex->name;
if (*outName == '*' || *outName == '+')
outName++;
TextureDescriptor tex = { 0 }; TextureDescriptor tex = { 0 };
for (int mipLevel = 0; mipLevel < 4; ++mipLevel) for (int mipLevel = 0; mipLevel < 4; ++mipLevel)
@ -290,14 +288,33 @@ bool process_textures(const world_t* world, TextureList& outTextures) // TODO: r
tex.w = (u_char)rectangle.w; tex.w = (u_char)rectangle.w;
tex.h = (u_char)rectangle.h; tex.h = (u_char)rectangle.h;
u_short x = (rectangle.x / 2) + outTim.imgXoffs; // Divide by 2 to get the coordinate in 16-bit pixel units u_short x = (rectangle.x / 2) + outTim.imgXoffs; // Divide by 2 to get the coordinate in 16-bit pixel units
u_short y = rectangle.y + outTim.imgYoffs; u_short y = rectangle.y + outTim.imgYoffs;
tex.ps1tex.tpage = getTPage(outTim.format, 0, x, y); tex.ps1tex.tpage = getTPage(outTim.format, 0, x, y);
tex.uoffs = (u_char)((x % 64) << (2 - outTim.format)); tex.uoffs = (u_char)((x % 64) << (2 - outTim.format));
tex.voffs = (u_char)(y & 0xFF); tex.voffs = (u_char)(y & 0xFF);
// TODO: animated textures
if (miptex->name[0] == '+')
{
// Animated texture
int frameNum = miptex->name[1] - '0';
if (frameNum >= 0 && frameNum <= 9)
{
std::string animName = &miptex->name[2];
animationFrames[animName][frameNum] = texNum;
}
else
{
frameNum = miptex->name[1] - 'a';
if (frameNum >= 0 && frameNum <= 9)
{
std::string animName = std::string(&miptex->name[2]) + "_alt";
animationFrames[animName][frameNum] = texNum;
}
}
}
} }
} }
@ -307,6 +324,24 @@ bool process_textures(const world_t* world, TextureList& outTextures) // TODO: r
outTextures.push_back(tex); outTextures.push_back(tex);
} }
// Link animated texture frames together
for (auto animIter = animationFrames.cbegin(); animIter != animationFrames.cend(); ++animIter)
{
const auto& frames = animIter->second;
for (auto frameIter = frames.cbegin(); frameIter != frames.cend(); ++frameIter)
{
int frameNum = frameIter->first;
int texNum = frameIter->second;
auto& texture = outTextures[texNum];
const auto& nextFrameIter = frames.find(frameNum + 1);
if (nextFrameIter != frames.cend())
texture.ps1tex.nextframe = nextFrameIter->second;
else
texture.ps1tex.nextframe = frames.find(0)->second;
}
}
sprintf_s(path, _MAX_PATH, "atlas-%s.tim", world->name); sprintf_s(path, _MAX_PATH, "atlas-%s.tim", world->name);
tim::ExportFile(path, &outTim); tim::ExportFile(path, &outTim);

Loading…
Cancel
Save