diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index 1fa59b821..ba1886665 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -889,7 +889,7 @@ void MinecraftServer::overwriteHellBordersForNewWorldSize(ServerLevel* level, #endif -void MinecraftServer::setProgress(consstd::t std::wstring& status, +void MinecraftServer::setProgress(const std::wstring& status, int progress) { progressStatus = status; this->progress = progress; @@ -1176,8 +1176,7 @@ Level* MinecraftServer::getCommandSenderWorld() { return levels[0]; } int MinecraftServer::getSpawnProtectionRadius() { return 16; } -bool MinecraftServer::isUnderSpawnProtection(Level* level, int x, int y, - int zstd::, +bool MinecraftServer::isUnderSpawnProtection(Level* level, int x, int y, int z, std::shared_ptr player) { if (level->dimension->id != 0) return false; // if (getPlayers()->getOps()->empty()) return false; @@ -1776,7 +1775,7 @@ void MinecraftServer::tick() { // } } -void MinecraftServer::handleConsoleInput(consstd::t std::wstring& msg, +void MinecraftServer::handleConsoleInput(const std::wstring& msg, ConsoleInputSource* source) { consoleInput.push_back(new ConsoleInput(msg, source)); } @@ -1816,11 +1815,9 @@ File* MinecraftServer::getFile(const std::wstring& name) { void MinecraftServer::info(const std::wstring& string) {} -void MinecraftServer::warn(consstd::t std::wstring& std::string) {} -std:: +void MinecraftServer::warn(const std::wstring& string) {} - std::wstring - MinecraftServer::getConsoleName() { +std::wstring MinecraftServer::getConsoleName() { return L"CONSOLE"; } diff --git a/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp index 7b903fc4b..17986a24e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp @@ -49,8 +49,7 @@ void HorseRenderer::renderModel(std::shared_ptr mob, float wp, true); // Ensure that any extra layers of texturing are disabled after // rendering this horse - assert(0 && "TODO: implement TextureBind(layer, idx) properly"); - // RenderManager.TextureBind(1, -1); + RenderManager.TextureBind(-1); } } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 0470caac5..d058b198c 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -415,15 +415,110 @@ void Textures::bindTexture(ResourceLocation* resource) { } } +// 4jcraft: brought over from smartcmd/MinecraftConsoles in TU19 merge void Textures::bindTextureLayers(ResourceLocation* resource) { assert(resource->isPreloaded()); + // Hack: 4JLibs on Windows does not currently reproduce Minecraft's layered + // horse texture path reliably. Merge the layers on the CPU and bind the + // cached result as a normal single texture instead. + std::wstring cacheKey = L"%layered%"; int layers = resource->getTextureCount(); - for (int i = 0; i < layers; i++) { - assert(0 && "todo: implement 2-argument TextureBind"); - RenderManager.TextureBind(i, loadTexture(resource->getTexture(i))); + cacheKey += std::to_wstring(resource->getTexture(i)); + cacheKey += L"/"; } + + int id = -1; + bool inMap = (idMap.find(cacheKey) != idMap.end()); + if (inMap) { + id = idMap[cacheKey]; + } else { + // Cache by layer signature so the merge cost is only paid once per + // horse texture combination. + intArray mergedPixels; + int mergedWidth = 0; + int mergedHeight = 0; + bool hasMergedPixels = false; + + for (int i = 0; i < layers; i++) { + TEXTURE_NAME textureName = resource->getTexture(i); + if (textureName == static_cast<_TEXTURE_NAME>(-1)) { + continue; + } + + wstring resourceName = wstring(preLoaded[textureName]) + L".png"; + BufferedImage* image = readImage(textureName, resourceName); + if (image == nullptr) { + continue; + } + + int width = image->getWidth(); + int height = image->getHeight(); + intArray layerPixels = loadTexturePixels(image); + delete image; + + if (!hasMergedPixels) { + mergedWidth = width; + mergedHeight = height; + mergedPixels = intArray(width * height); + memcpy(mergedPixels.data, layerPixels.data, + width * height * sizeof(int)); + hasMergedPixels = true; + } else if (width == mergedWidth && height == mergedHeight) { + for (int p = 0; p < width * height; p++) { + int dst = mergedPixels[p]; + int src = layerPixels[p]; + + float srcAlpha = ((src >> 24) & 0xff) / 255.0f; + if (srcAlpha <= 0.0f) { + continue; + } + + float dstAlpha = ((dst >> 24) & 0xff) / 255.0f; + float outAlpha = srcAlpha + dstAlpha * (1.0f - srcAlpha); + if (outAlpha <= 0.0f) { + mergedPixels[p] = 0; + continue; + } + + float srcFactor = srcAlpha / outAlpha; + float dstFactor = (dstAlpha * (1.0f - srcAlpha)) / outAlpha; + + int outA = static_cast(outAlpha * 255.0f + 0.5f); + int outR = static_cast( + (((src >> 16) & 0xff) * srcFactor) + + (((dst >> 16) & 0xff) * dstFactor) + 0.5f); + int outG = static_cast( + (((src >> 8) & 0xff) * srcFactor) + + (((dst >> 8) & 0xff) * dstFactor) + 0.5f); + int outB = + static_cast(((src & 0xff) * srcFactor) + + ((dst & 0xff) * dstFactor) + 0.5f); + mergedPixels[p] = + (outA << 24) | (outR << 16) | (outG << 8) | outB; + } + } + + delete[] layerPixels.data; + } + + if (hasMergedPixels) { + BufferedImage* mergedImage = new BufferedImage( + mergedWidth, mergedHeight, BufferedImage::TYPE_INT_ARGB); + memcpy(mergedImage->getData(), mergedPixels.data, + mergedWidth * mergedHeight * sizeof(int)); + delete[] mergedPixels.data; + id = getTexture(mergedImage, C4JRender::TEXTURE_FORMAT_RxGyBzAw, + false); + } else { + id = 0; + } + + idMap[cacheKey] = id; + } + + RenderManager.TextureBind(id); } void Textures::bind(int id) { diff --git a/Minecraft.Client/UI/Font.cpp b/Minecraft.Client/UI/Font.cpp index 4ea8f151b..190c5cdad 100644 --- a/Minecraft.Client/UI/Font.cpp +++ b/Minecraft.Client/UI/Font.cpp @@ -3,14 +3,15 @@ #include "Font.h" #include "../GameState/Options.h" #include "../Rendering/Tesselator.h" +#include "../Textures/ResourceLocation.h" #include "../../Minecraft.World/IO/Streams/IntBuffer.h" #include "../../Minecraft.World/Headers/net.minecraft.h" #include "../../Minecraft.World/Util/StringHelpers.h" #include "../../Minecraft.World/Util/Random.h" Font::Font(Options* options, const std::wstring& name, Textures* textures, - bool enforceUnicode, TEXTURE_NAME textureName, int cols, int rows, - int charWidth, int charHeight, + bool enforceUnicode, ResourceLocation* textureLocation, int cols, + int rows, int charWidth, int charHeight, unsigned short charMap[] /* = nullptr */) : textures(textures) { int charC = cols * rows; // Number of characters in the font @@ -29,7 +30,7 @@ Font::Font(Options* options, const std::wstring& name, Textures* textures, m_rows = rows; m_charWidth = charWidth; m_charHeight = charHeight; - m_textureName = textureName; + m_textureLocation = textureLocation; // Build character map if (charMap != NULL) { @@ -41,7 +42,8 @@ Font::Font(Options* options, const std::wstring& name, Textures* textures, random = new Random(); // Load the image - BufferedImage* img = textures->readImage(m_textureName, name); + BufferedImage* img = + textures->readImage(textureLocation->getTexture(), name); /* - 4J - TODO try { @@ -182,7 +184,7 @@ std::wstring Font::reorderBidi(const std::wstring& str) { void Font::draw(const std::wstring& str, bool dropShadow) { // Bind the texture - textures->bindTexture(m_textureName); + textures->bindTexture(m_textureLocation); bool noise = false; std::wstring cleanStr = sanitize(str); diff --git a/Minecraft.Client/UI/Font.h b/Minecraft.Client/UI/Font.h index fcfe83359..24de389a1 100644 --- a/Minecraft.Client/UI/Font.h +++ b/Minecraft.Client/UI/Font.h @@ -1,7 +1,9 @@ #pragma once + class IntBuffer; class Options; class Textures; +class ResourceLocation; class Font { private: @@ -22,17 +24,18 @@ private: bool enforceUnicodeSheet; // use unicode sheet for ascii bool bidirectional; // use bidi to flip strings - int m_cols; // Number of columns in font sheet - int m_rows; // Number of rows in font sheet - int m_charWidth; // Maximum character width - int m_charHeight; // Maximum character height - TEXTURE_NAME m_textureName; // Texture + int m_cols; // Number of columns in font sheet + int m_rows; // Number of rows in font sheet + int m_charWidth; // Maximum character width + int m_charHeight; // Maximum character height + ResourceLocation* m_textureLocation; // Texture std::map m_charMap; public: Font(Options* options, const std::wstring& name, Textures* textures, - bool enforceUnicode, TEXTURE_NAME textureName, int cols, int rows, - int charWidth, int charHeight, unsigned short charMap[] = NULL); + bool enforceUnicode, ResourceLocation* textureLocation, int cols, + int rows, int charWidth, int charHeight, + unsigned short charMap[] = NULL); #ifndef _XBOX // 4J Stu - This dtor clashes with one in xui! We never delete these anyway // so take it out for now. Can go back when we have got rid of XUI diff --git a/Minecraft.Client/UI/Screens/ChatScreen.cpp b/Minecraft.Client/UI/Screens/ChatScreen.cpp index ed49913b2..371ac6b47 100644 --- a/Minecraft.Client/UI/Screens/ChatScreen.cpp +++ b/Minecraft.Client/UI/Screens/ChatScreen.cpp @@ -5,7 +5,7 @@ #include "../../../Minecraft.World/Util/StringHelpers.h" const std::wstring ChatScreen::allowedChars = - SharedConstants::readAcceptableChars(); + SharedConstants::acceptableLetters; ChatScreen::ChatScreen() { frame = 0; } diff --git a/Minecraft.Client/UI/SimpleIcon.cpp b/Minecraft.Client/UI/SimpleIcon.cpp index c22921ae9..a01014cb7 100644 --- a/Minecraft.Client/UI/SimpleIcon.cpp +++ b/Minecraft.Client/UI/SimpleIcon.cpp @@ -1,11 +1,11 @@ +#pragma once #include "../Platform/stdafx.h" -#include "SimpleIcon.h" +#include "../Textures/Stitching/StitchedTexture.h" -SimpleIcon::SimpleIcon(const std::wstring& name, float U0, float V0, float U1, - float V1) - : StitchedTexture(name) { - u0 = U0; - u1 = U1; - v0 = V0; - v1 = V1; -} +// 4J Added this class to store the uv data that we have pre-calculated and +// loaded from a file +class SimpleIcon : public StitchedTexture { +public: + SimpleIcon(const std::wstring& name, const std::wstring& filename, float u0, + float v0, float u1, float v1); +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/SimpleIcon.h b/Minecraft.Client/UI/SimpleIcon.h index 9daa31844..33d5b5057 100644 --- a/Minecraft.Client/UI/SimpleIcon.h +++ b/Minecraft.Client/UI/SimpleIcon.h @@ -1,11 +1,11 @@ -#pragma once +#include "../Platform/stdafx.h" +#include "SimpleIcon.h" -#include "../Textures/Stitching/StitchedTexture.h" - -// 4J Added this class to store the uv data that we have pre-calculated and -// loaded from a file -class SimpleIcon : public StitchedTexture { -public: - SimpleIcon(const std::wstring& name, float u0, float v0, float u1, - float v1); -}; \ No newline at end of file +SimpleIcon::SimpleIcon(const std::wstring& name, const std::wstring& filename, + float U0, float V0, float U1, float V1) + : StitchedTexture(name, filename) { + u0 = U0; + u1 = U1; + v0 = V0; + v1 = V1; +}