Use the first frame from animated textures instead of discarding

This commit is contained in:
Soggy_Pancake 2026-03-21 22:20:18 -07:00
parent 5d459c0ff9
commit dbba7bc2a5

View file

@ -333,16 +333,17 @@ void AbstractTexturePack::loadName()
void AbstractTexturePack::checkTexSize() {
BufferedImage* img = getImageResource(L"dirt.png", true);
if (img != NULL) {
texSize = 16;
if (img != nullptr) {
int width = img->getWidth();
int height = img->getHeight();
if (width != height) {
if (width != height || width <= 0 || height <= 0) {
app.DebugPrintf("Warning: Texture pack contains texture with bad size: %d x %d\n", width, height);
} else
__debugbreak();
}
else
texSize = width;
delete img;
} else {
texSize = 16;
}
}
@ -443,7 +444,7 @@ wstring AbstractTexturePack::getAnimationString(const wstring &textureName, cons
wstring animationDefinitionFile = textureName + L".txt";
bool requiresFallback = !hasFile(L"\\" + textureName + L".png", false);
wstring result = L"";
InputStream *fileStream = getResource(L"\\" + path + animationDefinitionFile, requiresFallback);
@ -496,7 +497,7 @@ struct UV {
};
BufferedImage* AbstractTexturePack::getBedTex(std::wstring name) {
if (bedTexCache.get() == nullptr) {
BufferedImage* bedtex = getImageResource(L"assets/minecraft/textures/entity/bed/red.png", true);
if (bedtex != nullptr) {
@ -517,7 +518,7 @@ BufferedImage* AbstractTexturePack::getBedTex(std::wstring name) {
// hardcoded in java and no way to load it here, I hate hardcoding this but its what I got
UV feetEnd, feetEndStubL, feetEndStubR,
feetSide, feetSideStub,
feetSide, feetSideStub,
headSide, headSideStub,
headEnd, headEndStubL, headEndStubR,
feetFace, headFace;
@ -822,10 +823,10 @@ void AbstractTexturePack::generateStitched(unordered_map<wstring, Icon*> texture
terrainAtlas = std::make_unique<BufferedImage>(resW, resH, 0);
atlas = terrainAtlas.get();
atlasPixels = reinterpret_cast<Pixel*>(atlas->getData());
for (auto &i : texturesByName) {
auto preStitched = static_cast<StitchedTexture*>(i.second);
int x = preStitched->getU0() * resW;
int y = preStitched->getV0() * resH;
int width = (preStitched->getU1() * resW) - x;
@ -845,41 +846,36 @@ void AbstractTexturePack::generateStitched(unordered_map<wstring, Icon*> texture
int imgW = srcImg->getWidth();
int imgH = srcImg->getHeight();
if (imgW != texSize || imgH != texSize) {
app.DebugPrintf("Texture %ls is wrong size! skipping\n", i.first.c_str());
delete srcImg;
continue;
if (imgH % texSize == 0) {
app.DebugPrintf("Texture %ls is animated! using first frame\n", i.first.c_str());
srcImg = srcImg->getSubimage(0, 0, texSize, texSize);
imgW = imgH = texSize;
}
else {
app.DebugPrintf("Texture %ls is wrong size! skipping\n", i.first.c_str());
delete srcImg;
srcImg = grabFromDefault(i, defaultPixels, { defaultAtlas->getWidth(), defaultAtlas->getHeight() });
imgW = srcImg->getWidth();
imgH = srcImg->getHeight();
}
}
texPixels = reinterpret_cast<Pixel*>(srcImg->getData());
for (int j = 0; j < imgH * imgW; j++) {
Pixel* src = &texPixels[j];
Pixel* dst = &atlasPixels[(x + j % imgW) + (resW * (y + j / imgH))];
// int imgx = j % imgW; // debugging vars
// int imgy = j / imgH;
// int dstx = x + imgx;
// int dsty = y + imgy;
//unsigned char tmp = src->r; // unblue everything for saving, unsure why they are flipped
//src->r = src->b;
//src->b = tmp;
dst->raw = src->raw;
dst->raw = src->raw;
}
delete srcImg;
}
/*
for (int i = 0; i < resH * resW; i++) { // Magenta test
auto pix = &atlasPixels[i];
pix->r = 255;
pix->g = 0;
pix->b = 255;
pix->a = 255;
}*/
delete defaultAtlas;
// Uncomment these two lines and the unblue section above if you are debugging autostitching of the atlas!
@ -921,9 +917,18 @@ void AbstractTexturePack::generateStitched(unordered_map<wstring, Icon*> texture
int imgW = srcImg->getWidth();
int imgH = srcImg->getHeight();
if (imgW != texSize || imgH != texSize) {
app.DebugPrintf("Texture %ls is wrong size! skipping\n", i.first.c_str());
delete srcImg;
continue;
if (imgH % texSize == 0) {
app.DebugPrintf("Texture %ls is animated! using first frame\n", i.first.c_str());
srcImg = srcImg->getSubimage(0, 0, texSize, texSize);
imgW = imgH = texSize;
}
else {
app.DebugPrintf("Texture %ls is wrong size! skipping\n", i.first.c_str());
delete srcImg;
srcImg = grabFromDefault(i, defaultPixels, { defaultAtlas->getWidth(), defaultAtlas->getHeight() });
imgW = srcImg->getWidth();
imgH = srcImg->getHeight();
}
}
@ -932,10 +937,6 @@ void AbstractTexturePack::generateStitched(unordered_map<wstring, Icon*> texture
for (int j = 0; j < imgH * imgW; j++) {
Pixel* src = &texPixels[j];
Pixel* dst = &atlasPixels[(x + j % imgW) + (resW * (y + j / imgH))];
// int imgx = j % imgW; // debugging vars
// int imgy = j / imgH;
// int dstx = x + imgx;
// int dsty = y + imgy;
//unsigned char tmp = src->r; // unblue everything for saving, unsure why they are flipped
//src->r = src->b;
@ -958,8 +959,8 @@ void AbstractTexturePack::generateStitched(unordered_map<wstring, Icon*> texture
BufferedImage *AbstractTexturePack::getImageResource(const wstring& File, bool filenameHasExtension /*= false*/, bool bTitleUpdateTexture /*=false*/, const wstring &drive /*=L""*/)
{
const char *pchTexture=wstringtofilename(File);
app.DebugPrintf("AbstractTexturePack::getImageResource - %s, drive is %s\n",pchTexture, wstringtofilename(drive));
std::string pchTexture=wstringtofilename(File);
app.DebugPrintf("AbstractTexturePack::getImageResource - %s, drive is %s\n", pchTexture.c_str(), wstringtofilename(drive).c_str());
return new BufferedImage(TexturePack::getResource(L"/" + File),filenameHasExtension,bTitleUpdateTexture,drive);
}
@ -972,12 +973,12 @@ void AbstractTexturePack::loadDefaultUI()
// Load new skin
const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string
WCHAR szResourceLocator[ LOCATOR_SIZE ];
WCHAR szResourceLocator[LOCATOR_SIZE];
swprintf(szResourceLocator, LOCATOR_SIZE, L"section://%X,%ls#%ls", c_ModuleHandle, L"media", L"media/skin_Minecraft.xur");
swprintf(szResourceLocator, LOCATOR_SIZE,L"section://%X,%ls#%ls",c_ModuleHandle,L"media", L"media/skin_Minecraft.xur");
XuiFreeVisuals(L"");
app.LoadSkin(szResourceLocator,nullptr);//L"TexturePack");
app.LoadSkin(szResourceLocator, nullptr);//L"TexturePack");
//CXuiSceneBase::GetInstance()->SetVisualPrefix(L"TexturePack");
CXuiSceneBase::GetInstance()->SkinChanged(CXuiSceneBase::GetInstance()->m_hObj);
#else
@ -996,25 +997,25 @@ void AbstractTexturePack::loadDefaultColourTable()
// Load the file
#ifdef __PS3__
// need to check if it's a BD build, so pass in the name
File coloursFile(AbstractTexturePack::getPath(true,app.GetBootedFromDiscPatch()?"colours.col":nullptr).append(L"res/colours.col"));
File coloursFile(AbstractTexturePack::getPath(true, app.GetBootedFromDiscPatch() ? "colours.col" : nullptr).append(L"res/colours.col"));
#else
File coloursFile(AbstractTexturePack::getPath(true).append(L"res/colours.col"));
#endif
if(coloursFile.exists())
if (coloursFile.exists())
{
DWORD dwLength = coloursFile.length();
byteArray data(static_cast<unsigned int>(dwLength));
FileInputStream fis(coloursFile);
fis.read(data,0,dwLength);
fis.read(data, 0, dwLength);
fis.close();
if(m_colourTable != nullptr) delete m_colourTable;
if (m_colourTable != nullptr) delete m_colourTable;
m_colourTable = new ColourTable(data.data, dwLength);
delete [] data.data;
delete[] data.data;
}
else
{
@ -1030,36 +1031,36 @@ void AbstractTexturePack::loadDefaultHTMLColourTable()
const ULONG_PTR c_ModuleHandle = (ULONG_PTR)GetModuleHandle(nullptr);
const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string
WCHAR szResourceLocator[ LOCATOR_SIZE ];
WCHAR szResourceLocator[LOCATOR_SIZE];
// Try and load the HTMLColours.col based off the common XML first, before the deprecated xuiscene_colourtable
wsprintfW(szResourceLocator,L"section://%X,%s#%s",c_ModuleHandle,L"media", L"media/HTMLColours.col");
BYTE *data;
wsprintfW(szResourceLocator, L"section://%X,%s#%s", c_ModuleHandle, L"media", L"media/HTMLColours.col");
BYTE* data;
UINT dataLength;
if(XuiResourceLoadAll(szResourceLocator, &data, &dataLength) == S_OK)
if (XuiResourceLoadAll(szResourceLocator, &data, &dataLength) == S_OK)
{
m_colourTable->loadColoursFromData(data,dataLength);
m_colourTable->loadColoursFromData(data, dataLength);
XuiFree(data);
}
else
{
wsprintfW(szResourceLocator,L"section://%X,%s#%s",c_ModuleHandle,L"media", L"media/");
wsprintfW(szResourceLocator, L"section://%X,%s#%s", c_ModuleHandle, L"media", L"media/");
HXUIOBJ hScene;
HRESULT hr = XuiSceneCreate(szResourceLocator,L"xuiscene_colourtable.xur", nullptr, &hScene);
HRESULT hr = XuiSceneCreate(szResourceLocator, L"xuiscene_colourtable.xur", nullptr, &hScene);
if(HRESULT_SUCCEEDED(hr))
if (HRESULT_SUCCEEDED(hr))
{
loadHTMLColourTableFromXuiScene(hScene);
}
}
#else
if(app.hasArchiveFile(L"HTMLColours.col"))
if (app.hasArchiveFile(L"HTMLColours.col"))
{
byteArray textColours = app.getArchiveFile(L"HTMLColours.col");
m_colourTable->loadColoursFromData(textColours.data,textColours.length);
m_colourTable->loadColoursFromData(textColours.data, textColours.length);
delete [] textColours.data;
delete[] textColours.data;
}
#endif
}
@ -1070,11 +1071,11 @@ void AbstractTexturePack::loadHTMLColourTableFromXuiScene(HXUIOBJ hObj)
HXUIOBJ child;
HRESULT hr = XuiElementGetFirstChild(hObj, &child);
while(HRESULT_SUCCEEDED(hr) && child != nullptr)
while (HRESULT_SUCCEEDED(hr) && child != nullptr)
{
LPCWSTR childName;
XuiElementGetId(child,&childName);
m_colourTable->setColour(childName,XuiTextElementGetText(child));
XuiElementGetId(child, &childName);
m_colourTable->setColour(childName, XuiTextElementGetText(child));
//eMinecraftTextColours colourIndex = eTextColor_NONE;
//for(int i = 0; i < (int)eTextColor_MAX; i++)
@ -1098,7 +1099,7 @@ void AbstractTexturePack::loadHTMLColourTableFromXuiScene(HXUIOBJ hObj)
void AbstractTexturePack::loadUI()
{
loadColourTable();
#ifdef _XBOX
CXuiSceneBase::GetInstance()->SkinChanged(CXuiSceneBase::GetInstance()->m_hObj);
#endif
@ -1115,22 +1116,22 @@ wstring AbstractTexturePack::getXuiRootPath()
// Load new skin
const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string
WCHAR szResourceLocator[ LOCATOR_SIZE ];
WCHAR szResourceLocator[LOCATOR_SIZE];
swprintf(szResourceLocator, LOCATOR_SIZE,L"section://%X,%ls#%ls",c_ModuleHandle,L"media", L"media/");
swprintf(szResourceLocator, LOCATOR_SIZE, L"section://%X,%ls#%ls", c_ModuleHandle, L"media", L"media/");
return szResourceLocator;
}
PBYTE AbstractTexturePack::getPackIcon(DWORD &dwImageBytes)
PBYTE AbstractTexturePack::getPackIcon(DWORD& dwImageBytes)
{
if(m_iconSize == 0 || m_iconData == nullptr) loadIcon();
if (m_iconSize == 0 || m_iconData == nullptr) loadIcon();
dwImageBytes = m_iconSize;
return m_iconData;
}
PBYTE AbstractTexturePack::getPackComparison(DWORD &dwImageBytes)
PBYTE AbstractTexturePack::getPackComparison(DWORD& dwImageBytes)
{
if(m_comparisonSize == 0 || m_comparisonData == nullptr) loadComparison();
if (m_comparisonSize == 0 || m_comparisonData == nullptr) loadComparison();
dwImageBytes = m_comparisonSize;
return m_comparisonData;