aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client')
-rw-r--r--Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp9
-rw-r--r--Minecraft.Client/Common/UI/IUIScene_CraftingMenu.h6
-rw-r--r--Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp9
-rw-r--r--Minecraft.Client/Common/UI/UIControl_TextInput.cpp26
-rw-r--r--Minecraft.Client/Common/UI/UIScene_Keyboard.cpp33
-rw-r--r--Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp5
-rw-r--r--Minecraft.Client/Font.cpp297
-rw-r--r--Minecraft.Client/Font.h6
-rw-r--r--Minecraft.Client/Gui.cpp126
-rw-r--r--Minecraft.Client/Options.cpp9
-rw-r--r--Minecraft.Client/Options.h1
-rw-r--r--Minecraft.Client/PlayerConnection.cpp6
-rw-r--r--Minecraft.Client/Windows64/KeyboardMouseInput.cpp7
-rw-r--r--Minecraft.Client/Windows64/KeyboardMouseInput.h2
-rw-r--r--Minecraft.Client/Windows64/Windows64_Minecraft.cpp34
-rw-r--r--Minecraft.Client/Windows64Media/DLC/Natural/Data/x32Data.pckbin2983911 -> 3015066 bytes
16 files changed, 369 insertions, 207 deletions
diff --git a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp
index 7502d6bf..fa9b280c 100644
--- a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp
+++ b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp
@@ -9,6 +9,7 @@
#include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
#include "..\..\MultiplayerLocalPlayer.h"
#include "..\..\Minecraft.h"
+#include "..\..\Options.h"
#ifdef __ORBIS__
#include <pad.h>
@@ -1677,7 +1678,13 @@ vector<HtmlString> *IUIScene_AbstractContainerMenu::GetItemDescription(Slot *slo
{
if(slot == nullptr) return nullptr;
- vector<HtmlString> *lines = slot->getItem()->getHoverText(nullptr, false);
+ bool advanced = false;
+ if (const Minecraft* pMinecraft = Minecraft::GetInstance())
+ {
+ if (pMinecraft->options)
+ advanced = pMinecraft->options->advancedTooltips;
+ }
+ vector<HtmlString> *lines = slot->getItem()->getHoverText(nullptr, advanced);
// Add rarity to first line
if (lines->size() > 0)
diff --git a/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.h b/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.h
index 03a58378..fa8d9bd1 100644
--- a/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.h
+++ b/Minecraft.Client/Common/UI/IUIScene_CraftingMenu.h
@@ -20,9 +20,9 @@ protected:
eGroupTab_Right
};
- static const int m_iMaxHSlotC = 12;
- static const int m_iMaxHCraftingSlotC = 10;
- static const int m_iMaxVSlotC = 17;
+ static const int m_iMaxHSlotC = 40;
+ static const int m_iMaxHCraftingSlotC = 40;
+ static const int m_iMaxVSlotC = 99;
static const int m_iMaxDisplayedVSlotC = 3;
static const int m_iIngredients3x3SlotC = 9;
static const int m_iIngredients2x2SlotC = 4;
diff --git a/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp
index 0b1e0df2..d7939d8c 100644
--- a/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp
+++ b/Minecraft.Client/Common/UI/IUIScene_TradingMenu.cpp
@@ -4,6 +4,7 @@
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
#include "..\..\..\Minecraft.World\net.minecraft.network.packet.h"
#include "..\..\Minecraft.h"
+#include "..\..\Options.h"
#include "..\..\MultiPlayerLocalPlayer.h"
#include "..\..\ClientConnection.h"
#include "IUIScene_TradingMenu.h"
@@ -368,7 +369,13 @@ void IUIScene_TradingMenu::setTradeItem(int index, shared_ptr<ItemInstance> item
vector<HtmlString> *IUIScene_TradingMenu::GetItemDescription(shared_ptr<ItemInstance> item)
{
- vector<HtmlString> *lines = item->getHoverText(nullptr, false);
+ bool advanced = false;
+ if (const Minecraft* pMinecraft = Minecraft::GetInstance())
+ {
+ if (pMinecraft->options)
+ advanced = pMinecraft->options->advancedTooltips;
+ }
+ vector<HtmlString> *lines = item->getHoverText(nullptr, advanced);
// Add rarity to first line
if (lines->size() > 0)
diff --git a/Minecraft.Client/Common/UI/UIControl_TextInput.cpp b/Minecraft.Client/Common/UI/UIControl_TextInput.cpp
index 8e679b7c..76f25afb 100644
--- a/Minecraft.Client/Common/UI/UIControl_TextInput.cpp
+++ b/Minecraft.Client/Common/UI/UIControl_TextInput.cpp
@@ -1,6 +1,7 @@
#include "stdafx.h"
#include "UI.h"
#include "UIControl_TextInput.h"
+#include "..\..\Screen.h"
UIControl_TextInput::UIControl_TextInput()
{
@@ -211,6 +212,31 @@ UIControl_TextInput::EDirectEditResult UIControl_TextInput::tickDirectEdit()
}
}
+ // Paste from clipboard
+ if (g_KBMInput.IsKeyPressed('V') && g_KBMInput.IsKeyDown(VK_CONTROL))
+ {
+ wstring pasted = Screen::getClipboard();
+ wstring sanitized;
+ sanitized.reserve(pasted.length());
+
+ for (wchar_t pc : pasted)
+ {
+ if (pc >= 0x20) // Keep printable characters
+ {
+ if (m_iCharLimit > 0 && (m_editBuffer.length() + sanitized.length()) >= (size_t)m_iCharLimit)
+ break;
+ sanitized += pc;
+ }
+ }
+
+ if (!sanitized.empty())
+ {
+ m_editBuffer.insert(m_iCursorPos, sanitized);
+ m_iCursorPos += (int)sanitized.length();
+ changed = true;
+ }
+ }
+
// Arrow keys, Home, End, Delete for cursor movement
if (g_KBMInput.IsKeyPressed(VK_LEFT) && m_iCursorPos > 0)
{
diff --git a/Minecraft.Client/Common/UI/UIScene_Keyboard.cpp b/Minecraft.Client/Common/UI/UIScene_Keyboard.cpp
index 2f2f9132..35edf17f 100644
--- a/Minecraft.Client/Common/UI/UIScene_Keyboard.cpp
+++ b/Minecraft.Client/Common/UI/UIScene_Keyboard.cpp
@@ -1,6 +1,7 @@
#include "stdafx.h"
#include "UI.h"
#include "UIScene_Keyboard.h"
+#include "..\..\Screen.h"
#ifdef _WINDOWS64
// Global buffer that stores the text entered in the native keyboard scene.
@@ -224,6 +225,38 @@ void UIScene_Keyboard::tick()
}
}
+ // Paste from clipboard
+ if (g_KBMInput.IsKeyPressed('V') && g_KBMInput.IsKeyDown(VK_CONTROL))
+ {
+ wstring pasted = Screen::getClipboard();
+ wstring sanitized;
+ sanitized.reserve(pasted.length());
+
+ for (wchar_t pc : pasted)
+ {
+ if (pc >= 0x20) // Keep printable characters
+ {
+ if (static_cast<int>(m_win64TextBuffer.length() + sanitized.length()) >= m_win64MaxChars)
+ break;
+ sanitized += pc;
+ }
+ }
+
+ if (!sanitized.empty())
+ {
+ if (m_bPCMode)
+ {
+ m_win64TextBuffer.insert(m_iCursorPos, sanitized);
+ m_iCursorPos += (int)sanitized.length();
+ }
+ else
+ {
+ m_win64TextBuffer += sanitized;
+ }
+ changed = true;
+ }
+ }
+
if (m_bPCMode)
{
// Arrow keys, Home, End, Delete for cursor movement
diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp
index b258d8c3..e9a85fa5 100644
--- a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp
+++ b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp
@@ -222,9 +222,8 @@ void UIScene_SettingsGraphicsMenu::handleSliderMove(F64 sliderId, F64 currentVal
const int fovValue = sliderValueToFov(value);
pMinecraft->gameRenderer->SetFovVal(static_cast<float>(fovValue));
app.SetGameSettings(m_iPad, eGameSetting_FOV, value);
- WCHAR tempString[256];
- swprintf(tempString, 256, L"FOV: %d", fovValue);
- m_sliderFOV.setLabel(tempString);
+ swprintf(TempString, 256, L"FOV: %d", fovValue);
+ m_sliderFOV.setLabel(TempString);
}
break;
diff --git a/Minecraft.Client/Font.cpp b/Minecraft.Client/Font.cpp
index db2a18c0..1040eaa0 100644
--- a/Minecraft.Client/Font.cpp
+++ b/Minecraft.Client/Font.cpp
@@ -45,46 +45,46 @@ Font::Font(Options *options, const wstring& name, Textures* textures, bool enfor
random = new Random();
// Load the image
- BufferedImage *img = textures->readImage(textureLocation->getTexture(), name);
+ BufferedImage *img = textures->readImage(textureLocation->getTexture(), name);
/* - 4J - TODO
try {
- img = ImageIO.read(Textures.class.getResourceAsStream(name));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ img = ImageIO.read(Textures.class.getResourceAsStream(name));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
*/
- int w = img->getWidth();
- int h = img->getHeight();
- intArray rawPixels(w * h);
- img->getRGB(0, 0, w, h, rawPixels, 0, w);
+ int w = img->getWidth();
+ int h = img->getHeight();
+ intArray rawPixels(w * h);
+ img->getRGB(0, 0, w, h, rawPixels, 0, w);
- for (int i = 0; i < charC; i++)
+ for (int i = 0; i < charC; i++)
{
- int xt = i % m_cols;
- int yt = i / m_cols;
+ int xt = i % m_cols;
+ int yt = i / m_cols;
- int x = 7;
- for (; x >= 0; x--)
+ int x = 7;
+ for (; x >= 0; x--)
{
- int xPixel = xt * 8 + x;
- bool emptyColumn = true;
- for (int y = 0; y < 8 && emptyColumn; y++)
+ int xPixel = xt * 8 + x;
+ bool emptyColumn = true;
+ for (int y = 0; y < 8 && emptyColumn; y++)
{
- int yPixel = (yt * 8 + y) * w;
+ int yPixel = (yt * 8 + y) * w;
bool emptyPixel = (rawPixels[xPixel + yPixel] >> 24) == 0; // Check the alpha value
- if (!emptyPixel) emptyColumn = false;
- }
- if (!emptyColumn)
+ if (!emptyPixel) emptyColumn = false;
+ }
+ if (!emptyColumn)
{
- break;
- }
- }
+ break;
+ }
+ }
- if (i == ' ') x = 4 - 2;
- charWidths[i] = x + 2;
- }
+ if (i == ' ') x = 4 - 2;
+ charWidths[i] = x + 2;
+ }
delete img;
@@ -130,6 +130,7 @@ Font::~Font()
}
#endif
+// Legacy helper used by renderCharacter() only.
void Font::renderStyleLine(float x0, float y0, float x1, float y1)
{
Tesselator* t = Tesselator::getInstance();
@@ -146,7 +147,20 @@ void Font::renderStyleLine(float x0, float y0, float x1, float y1)
t->end();
}
-void Font::addCharacterQuad(wchar_t c)
+void Font::addSolidQuad(float x0, float y0, float x1, float y1)
+{
+ Tesselator *t = Tesselator::getInstance();
+ t->tex(0.0f, 0.0f);
+ t->vertex(x0, y1, 0.0f);
+ t->tex(0.0f, 0.0f);
+ t->vertex(x1, y1, 0.0f);
+ t->tex(0.0f, 0.0f);
+ t->vertex(x1, y0, 0.0f);
+ t->tex(0.0f, 0.0f);
+ t->vertex(x0, y0, 0.0f);
+}
+
+void Font::emitCharacterGeometry(wchar_t c)
{
float xOff = c % m_cols * m_charWidth;
float yOff = c / m_cols * m_charHeight; // was m_charWidth — wrong when glyphs aren't square
@@ -180,52 +194,45 @@ void Font::addCharacterQuad(wchar_t c)
t->tex(xOff / fontWidth, yOff / fontHeight);
t->vertex(x0 + dx, y0, 0.0f);
}
-
- xPos += static_cast<float>(charWidths[c]);
}
-void Font::renderCharacter(wchar_t c)
+void Font::addCharacterQuad(wchar_t c)
{
- float xOff = c % m_cols * m_charWidth;
- float yOff = c / m_cols * m_charHeight; // was m_charWidth — wrong when glyphs aren't square
-
- float width = charWidths[c] - .01f;
float height = m_charHeight - .01f;
+ float x0 = xPos;
+ float y0 = yPos;
+ float y1 = yPos + height;
+ float advance = static_cast<float>(charWidths[c]);
- float fontWidth = m_cols * m_charWidth;
- float fontHeight = m_rows * m_charHeight;
+ emitCharacterGeometry(c);
- const float shear = m_italic ? (height * 0.25f) : 0.0f;
- float x0 = xPos, x1 = xPos + width + shear;
- float y0 = yPos, y1 = yPos + height;
+ if (m_underline)
+ {
+ addSolidQuad(x0, y1 - 1.0f, xPos + advance, y1);
+ }
+
+ if (m_strikethrough)
+ {
+ float mid = y0 + height * 0.5f;
+ addSolidQuad(x0, mid - 0.5f, xPos + advance, mid + 0.5f);
+ }
+
+ xPos += advance;
+}
+
+// Legacy helper used by drawLiteral() only.
+void Font::renderCharacter(wchar_t c)
+{
+ float height = m_charHeight - .01f;
+ float x0 = xPos;
+ float y0 = yPos;
+ float y1 = yPos + height;
Tesselator *t = Tesselator::getInstance();
t->begin();
- t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
- t->vertex(x0, y1, 0.0f);
- t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
- t->vertex(x1, y1, 0.0f);
- t->tex((xOff + width) / fontWidth, yOff / fontHeight);
- t->vertex(x1, y0, 0.0f);
- t->tex(xOff / fontWidth, yOff / fontHeight);
- t->vertex(x0, y0, 0.0f);
+ emitCharacterGeometry(c);
t->end();
- if (m_bold)
- {
- float dx = 1.0f;
- t->begin();
- t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
- t->vertex(x0 + dx, y1, 0.0f);
- t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
- t->vertex(x1 + dx, y1, 0.0f);
- t->tex((xOff + width) / fontWidth, yOff / fontHeight);
- t->vertex(x1 + dx, y0, 0.0f);
- t->tex(xOff / fontWidth, yOff / fontHeight);
- t->vertex(x0 + dx, y0, 0.0f);
- t->end();
- }
-
if (m_underline)
renderStyleLine(x0, y1 - 1.0f, xPos + static_cast<float>(charWidths[c]), y1);
@@ -240,8 +247,8 @@ void Font::renderCharacter(wchar_t c)
void Font::drawShadow(const wstring& str, int x, int y, int color)
{
- draw(str, x + 1, y + 1, color, true);
- draw(str, x, y, color, false);
+ draw(str, x + 1, y + 1, color, true);
+ draw(str, x, y, color, false);
}
void Font::drawShadowLiteral(const wstring& str, int x, int y, int color)
@@ -289,7 +296,7 @@ static bool isSectionFormatCode(wchar_t ca)
return l == L'l' || l == L'o' || l == L'n' || l == L'm' || l == L'r' || l == L'k';
}
-void Font::draw(const wstring &str, bool dropShadow)
+void Font::draw(const wstring &str, bool dropShadow, int initialColor)
{
// Bind the texture
textures->bindTexture(m_textureLocation);
@@ -297,8 +304,11 @@ void Font::draw(const wstring &str, bool dropShadow)
m_bold = m_italic = m_underline = m_strikethrough = false;
wstring cleanStr = sanitize(str);
+ int currentColor = initialColor;
+
Tesselator *t = Tesselator::getInstance();
t->begin();
+ t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255);
for (int i = 0; i < static_cast<int>(cleanStr.length()); ++i)
{
@@ -310,10 +320,8 @@ void Font::draw(const wstring &str, bool dropShadow)
wchar_t ca = cleanStr[i+1];
if (!isSectionFormatCode(ca))
{
- t->end();
- renderCharacter(167);
- renderCharacter(ca);
- t->begin();
+ addCharacterQuad(167);
+ addCharacterQuad(ca);
i += 1;
continue;
}
@@ -329,7 +337,12 @@ void Font::draw(const wstring &str, bool dropShadow)
else if (l == L'o') m_italic = true;
else if (l == L'n') m_underline = true;
else if (l == L'm') m_strikethrough = true;
- else if (l == L'r') m_bold = m_italic = m_underline = m_strikethrough = noise = false;
+ else if (l == L'r')
+ {
+ m_bold = m_italic = m_underline = m_strikethrough = noise = false;
+ currentColor = initialColor;
+ t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255);
+ }
else if (l == L'k') noise = true;
}
else
@@ -337,8 +350,8 @@ void Font::draw(const wstring &str, bool dropShadow)
noise = false;
if (colorN < 0 || colorN > 15) colorN = 15;
if (dropShadow) colorN += 16;
- int color = colors[colorN];
- glColor3f((color >> 16) / 255.0F, ((color >> 8) & 255) / 255.0F, (color & 255) / 255.0F);
+ currentColor = (initialColor & 0xff000000) | colors[colorN];
+ t->color(currentColor & 0x00ffffff, (currentColor >> 24) & 255);
}
i += 1;
continue;
@@ -371,11 +384,11 @@ void Font::draw(const wstring& str, int x, int y, int color, bool dropShadow)
if (dropShadow) // divide RGB by 4, preserve alpha
color = (color & 0xfcfcfc) >> 2 | (color & (-1 << 24));
- glColor4f((color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, (color & 255) / 255.0F, (color >> 24 & 255) / 255.0F);
+ glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
xPos = x;
yPos = y;
- draw(str, dropShadow);
+ draw(str, dropShadow, color);
}
}
@@ -422,9 +435,9 @@ wstring Font::sanitize(const wstring& str)
{
wstring sb = str;
- for (unsigned int i = 0; i < sb.length(); i++)
+ for (unsigned int i = 0; i < sb.length(); i++)
{
- if (CharacterExists(sb[i]))
+ if (CharacterExists(sb[i]))
{
sb[i] = MapCharacter(sb[i]);
}
@@ -433,8 +446,8 @@ wstring Font::sanitize(const wstring& str)
// If this character isn't supported, just show the first character (empty square box character)
sb[i] = 0;
}
- }
- return sb;
+ }
+ return sb;
}
int Font::MapCharacter(wchar_t c)
@@ -487,95 +500,95 @@ void Font::drawWordWrap(const wstring &string, int x, int y, int w, int col, boo
void Font::drawWordWrapInternal(const wstring& string, int x, int y, int w, int col, bool darken, int h)
{
- vector<wstring>lines = stringSplit(string,L'\n');
- if (lines.size() > 1)
+ vector<wstring>lines = stringSplit(string,L'\n');
+ if (lines.size() > 1)
{
- for ( auto& it : lines )
- {
+ for ( auto& it : lines )
+ {
// 4J Stu - Don't draw text that will be partially cutoff/overlap something it shouldn't
if( (y + this->wordWrapHeight(it, w)) > h) break;
- drawWordWrapInternal(it, x, y, w, col, h);
- y += this->wordWrapHeight(it, w);
- }
- return;
- }
- vector<wstring> words = stringSplit(string,L' ');
- unsigned int pos = 0;
- while (pos < words.size())
+ drawWordWrapInternal(it, x, y, w, col, h);
+ y += this->wordWrapHeight(it, w);
+ }
+ return;
+ }
+ vector<wstring> words = stringSplit(string,L' ');
+ unsigned int pos = 0;
+ while (pos < words.size())
{
- wstring line = words[pos++] + L" ";
- while (pos < words.size() && width(line + words[pos]) < w)
+ wstring line = words[pos++] + L" ";
+ while (pos < words.size() && width(line + words[pos]) < w)
{
- line += words[pos++] + L" ";
- }
- while (width(line) > w)
+ line += words[pos++] + L" ";
+ }
+ while (width(line) > w)
{
- int l = 0;
- while (width(line.substr(0, l + 1)) <= w)
+ int l = 0;
+ while (width(line.substr(0, l + 1)) <= w)
{
- l++;
- }
- if (trimString(line.substr(0, l)).length() > 0)
+ l++;
+ }
+ if (trimString(line.substr(0, l)).length() > 0)
{
- draw(line.substr(0, l), x, y, col);
- y += 8;
- }
- line = line.substr(l);
+ draw(line.substr(0, l), x, y, col);
+ y += 8;
+ }
+ line = line.substr(l);
// 4J Stu - Don't draw text that will be partially cutoff/overlap something it shouldn't
if( (y + 8) > h) break;
- }
+ }
// 4J Stu - Don't draw text that will be partially cutoff/overlap something it shouldn't
- if (trimString(line).length() > 0 && !( (y + 8) > h) )
+ if (trimString(line).length() > 0 && !( (y + 8) > h) )
{
- draw(line, x, y, col);
- y += 8;
- }
- }
+ draw(line, x, y, col);
+ y += 8;
+ }
+ }
}
int Font::wordWrapHeight(const wstring& string, int w)
{
- vector<wstring> lines = stringSplit(string,L'\n');
- if (lines.size() > 1)
+ vector<wstring> lines = stringSplit(string,L'\n');
+ if (lines.size() > 1)
{
- int h = 0;
- for ( auto& it : lines )
- {
- h += this->wordWrapHeight(it, w);
- }
- return h;
- }
+ int h = 0;
+ for ( auto& it : lines )
+ {
+ h += this->wordWrapHeight(it, w);
+ }
+ return h;
+ }
vector<wstring> words = stringSplit(string,L' ');
- unsigned int pos = 0;
- int y = 0;
- while (pos < words.size())
+ unsigned int pos = 0;
+ int y = 0;
+ while (pos < words.size())
{
- wstring line = words[pos++] + L" ";
- while (pos < words.size() && width(line + words[pos]) < w)
+ wstring line = words[pos++] + L" ";
+ while (pos < words.size() && width(line + words[pos]) < w)
{
- line += words[pos++] + L" ";
- }
- while (width(line) > w)
+ line += words[pos++] + L" ";
+ }
+ while (width(line) > w)
{
- int l = 0;
+ int l = 0;
while (width(line.substr(0, l + 1)) <= w)
{
- l++;
- }
- if (trimString(line.substr(0, l)).length() > 0)
+ l++;
+ }
+ if (trimString(line.substr(0, l)).length() > 0)
{
- y += 8;
- }
- line = line.substr(l);
- }
- if (trimString(line).length() > 0) {
- y += 8;
- }
- }
- if (y < 8) y += 8;
- return y;
+ y += 8;
+ }
+ line = line.substr(l);
+ }
+ if (trimString(line).length() > 0) {
+ y += 8;
+ }
+ }
+ if (y < 8) y += 8;
+ return y;
}
diff --git a/Minecraft.Client/Font.h b/Minecraft.Client/Font.h
index c78ea678..58bceb4c 100644
--- a/Minecraft.Client/Font.h
+++ b/Minecraft.Client/Font.h
@@ -38,7 +38,7 @@ private:
std::map<int, int> m_charMap;
public:
- Font(Options *options, const wstring& name, Textures* textures, bool enforceUnicode, ResourceLocation *textureLocation, int cols, int rows, int charWidth, int charHeight, unsigned short charMap[] = nullptr);
+ Font(Options *options, const wstring& name, Textures* textures, bool enforceUnicode, ResourceLocation *textureLocation, int cols, int rows, int charWidth, int charHeight, unsigned short charMap[] = nullptr);
#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
~Font();
@@ -48,6 +48,8 @@ public:
private:
void renderCharacter(wchar_t c); // 4J added
void addCharacterQuad(wchar_t c);
+ void addSolidQuad(float x0, float y0, float x1, float y1);
+ void emitCharacterGeometry(wchar_t c);
void renderStyleLine(float x0, float y0, float x1, float y1); // solid line for underline/strikethrough
public:
@@ -65,7 +67,7 @@ public:
private:
wstring reorderBidi(const wstring &str);
- void draw(const wstring &str, bool dropShadow);
+ void draw(const wstring &str, bool dropShadow, int baseColor);
void draw(const wstring& str, int x, int y, int color, bool dropShadow);
void drawLiteral(const wstring& str, int x, int y, int color); // no § parsing
int MapCharacter(wchar_t c); // 4J added
diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp
index f0d44319..5e3a954f 100644
--- a/Minecraft.Client/Gui.cpp
+++ b/Minecraft.Client/Gui.cpp
@@ -1070,111 +1070,146 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
lines.push_back(ClientConstants::VERSION_STRING);
lines.push_back(ClientConstants::BRANCH_STRING);
}
+
if (minecraft->options->renderDebug && minecraft->player != nullptr && minecraft->level != nullptr)
{
lines.push_back(minecraft->fpsString);
lines.push_back(L"E: " + std::to_wstring(minecraft->level->getAllEntities().size()));
int renderDistance = app.GetGameSettings(iPad, eGameSetting_RenderDistance);
+ // Calculate the chunk sections using 16 * (2n + 1)^2
lines.push_back(L"C: " + std::to_wstring(16 * (2 * renderDistance + 1) * (2 * renderDistance + 1)) + L" D: " + std::to_wstring(renderDistance));
lines.push_back(minecraft->gatherStats4());
+ // Dimension
wstring dimension = L"unknown";
switch (minecraft->player->dimension)
{
- case -1: dimension = L"minecraft:the_nether"; break;
- case 0: dimension = L"minecraft:overworld"; break;
- case 1: dimension = L"minecraft:the_end"; break;
+ case -1:
+ dimension = L"minecraft:the_nether";
+ break;
+ case 0:
+ dimension = L"minecraft:overworld";
+ break;
+ case 1:
+ dimension = L"minecraft:the_end";
+ break;
}
lines.push_back(dimension);
- lines.push_back(L"");
+ lines.push_back(L""); // Spacer
+
+ // Players block pos
int xBlockPos = Mth::floor(minecraft->player->x);
int yBlockPos = Mth::floor(minecraft->player->y);
int zBlockPos = Mth::floor(minecraft->player->z);
+
+ // Chunk player is in
int xChunkPos = xBlockPos >> 4;
int yChunkPos = yBlockPos >> 4;
int zChunkPos = zBlockPos >> 4;
+
+ // Players offset within the chunk
int xChunkOffset = xBlockPos & 15;
int yChunkOffset = yBlockPos & 15;
int zChunkOffset = zBlockPos & 15;
- WCHAR posString[44];
+ // Format the position like java with limited decumal places
+ WCHAR posString[44]; // Allows upto 7 digit positions (+-9_999_999)
swprintf(posString, 44, L"%.3f / %.5f / %.3f", minecraft->player->x, minecraft->player->y, minecraft->player->z);
lines.push_back(L"XYZ: " + std::wstring(posString));
lines.push_back(L"Block: " + std::to_wstring(xBlockPos) + L" " + std::to_wstring(yBlockPos) + L" " + std::to_wstring(zBlockPos));
lines.push_back(L"Chunk: " + std::to_wstring(xChunkOffset) + L" " + std::to_wstring(yChunkOffset) + L" " + std::to_wstring(zChunkOffset) + L" in " + std::to_wstring(xChunkPos) + L" " + std::to_wstring(yChunkPos) + L" " + std::to_wstring(zChunkPos));
+ // Wrap the yRot to 360 then adjust to (-180 to 180) range to match java
float yRotDisplay = fmod(minecraft->player->yRot, 360.0f);
if (yRotDisplay > 180.0f) yRotDisplay -= 360.0f;
if (yRotDisplay < -180.0f) yRotDisplay += 360.0f;
+ // Generate the angle string in the format "yRot / xRot" with one decimal place, similar to java edition
WCHAR angleString[16];
swprintf(angleString, 16, L"%.1f / %.1f", yRotDisplay, minecraft->player->xRot);
+ // Work out the named direction
int direction = Mth::floor(minecraft->player->yRot * 4.0f / 360.0f + 0.5) & 0x3;
const wchar_t* cardinals[] = { L"south", L"west", L"north", L"east" };
lines.push_back(L"Facing: " + std::wstring(cardinals[direction]) + L" (" + angleString + L")");
+ // We have to limit y to 256 as we don't get any information past that
if (minecraft->level != NULL && minecraft->level->hasChunkAt(xBlockPos, fmod(yBlockPos, 256), zBlockPos))
{
LevelChunk *chunkAt = minecraft->level->getChunkAt(xBlockPos, zBlockPos);
if (chunkAt != NULL)
{
- int skyLight = chunkAt->getBrightness(LightLayer::Sky, xChunkOffset, yChunkOffset, zChunkOffset);
+ int skyLight = chunkAt->getBrightness(LightLayer::Sky, xChunkOffset, yChunkOffset, zChunkOffset);
int blockLight = chunkAt->getBrightness(LightLayer::Block, xChunkOffset, yChunkOffset, zChunkOffset);
- int maxLight = fmax(skyLight, blockLight);
+ int maxLight = fmax(skyLight, blockLight);
lines.push_back(L"Light: " + std::to_wstring(maxLight) + L" (" + std::to_wstring(skyLight) + L" sky, " + std::to_wstring(blockLight) + L" block)");
+
lines.push_back(L"CH S: " + std::to_wstring(chunkAt->getHeightmap(xChunkOffset, zChunkOffset)));
+
Biome *biome = chunkAt->getBiome(xChunkOffset, zChunkOffset, minecraft->level->getBiomeSource());
lines.push_back(L"Biome: " + biome->m_name + L" (" + std::to_wstring(biome->id) + L")");
+
lines.push_back(L"Difficulty: " + std::to_wstring(minecraft->level->difficulty) + L" (Day " + std::to_wstring(minecraft->level->getGameTime() / Level::TICKS_PER_DAY) + L")");
}
}
- lines.push_back(L"");
+ // This is all LCE only stuff, it was never on java
+ lines.push_back(L""); // Spacer
lines.push_back(L"Seed: " + std::to_wstring(minecraft->level->getLevelData()->getSeed()));
- lines.push_back(minecraft->gatherStats1());
- lines.push_back(minecraft->gatherStats2());
- lines.push_back(minecraft->gatherStats3());
- }
-
-#ifdef _DEBUG
- if (minecraft->options->renderDebug && minecraft->player != nullptr && minecraft->level != nullptr && minecraft->level->dimension->id == 0)
- {
- wstring wfeature[eTerrainFeature_Count];
- wfeature[eTerrainFeature_Stronghold] = L"Stronghold: ";
- wfeature[eTerrainFeature_Mineshaft] = L"Mineshaft: ";
- wfeature[eTerrainFeature_Village] = L"Village: ";
- wfeature[eTerrainFeature_Ravine] = L"Ravine: ";
-
- // maxW in font units: physical width divided by font scale
- float maxW = (static_cast<float>(g_rScreenWidth) - debugLeft - 8) / fontScale;
- float maxWForContent = maxW - static_cast<float>(font->width(L"..."));
- bool truncated[eTerrainFeature_Count] = {};
-
- for (size_t i = 0; i < app.m_vTerrainFeatures.size(); i++)
+ lines.push_back(minecraft->gatherStats1()); // Time to autosave
+ lines.push_back(minecraft->gatherStats2()); // Empty currently - CPlatformNetworkManagerStub::GatherStats()
+ lines.push_back(minecraft->gatherStats3()); // RTT
+
+#ifdef _DEBUG // Only show terrain features in debug builds not release
+
+ // No point trying to render this when not in the overworld
+ if (minecraft->level->dimension->id == 0)
{
- FEATURE_DATA *pFeatureData = app.m_vTerrainFeatures[i];
- int type = pFeatureData->eTerrainFeature;
- if (type < eTerrainFeature_Stronghold || type > eTerrainFeature_Ravine) continue;
- if (truncated[type]) continue;
- wstring itemInfo = L"[" + std::to_wstring(pFeatureData->x * 16) + L", " + std::to_wstring(pFeatureData->z * 16) + L"] ";
- if (font->width(wfeature[type] + itemInfo) <= maxWForContent)
- wfeature[type] += itemInfo;
- else
+ wstring wfeature[eTerrainFeature_Count];
+ wfeature[eTerrainFeature_Stronghold] = L"Stronghold: ";
+ wfeature[eTerrainFeature_Mineshaft] = L"Mineshaft: ";
+ wfeature[eTerrainFeature_Village] = L"Village: ";
+ wfeature[eTerrainFeature_Ravine] = L"Ravine: ";
+
+ // maxW in font units: physical width divided by font scale
+ float maxW = (static_cast<float>(g_rScreenWidth) - debugLeft - 8) / fontScale;
+ float maxWForContent = maxW - static_cast<float>(font->width(L"..."));
+ bool truncated[eTerrainFeature_Count] = {};
+
+ for (size_t i = 0; i < app.m_vTerrainFeatures.size(); i++)
{
- wfeature[type] += L"...";
- truncated[type] = true;
+ FEATURE_DATA *pFeatureData = app.m_vTerrainFeatures[i];
+ int type = pFeatureData->eTerrainFeature;
+ if (type < eTerrainFeature_Stronghold || type > eTerrainFeature_Ravine) continue;
+ if (truncated[type]) continue;
+
+ wstring itemInfo = L"[" + std::to_wstring(pFeatureData->x * 16) + L", " + std::to_wstring(pFeatureData->z * 16) + L"] ";
+ if (font->width(wfeature[type] + itemInfo) <= maxWForContent)
+ {
+ wfeature[type] += itemInfo;
+ }
+ else
+ {
+ wfeature[type] += L"...";
+ truncated[type] = true;
+ }
}
- }
- lines.push_back(L"");
- for (int i = eTerrainFeature_Stronghold; i <= static_cast<int>(eTerrainFeature_Ravine); i++)
- lines.push_back(wfeature[i]);
- lines.push_back(L"");
- }
+ lines.push_back(L""); // Spacer
+ for (int i = eTerrainFeature_Stronghold; i <= static_cast<int>(eTerrainFeature_Ravine); i++)
+ {
+ lines.push_back(wfeature[i]);
+ }
+ lines.push_back(L""); // Spacer
+ }
#endif
+ }
+
+ // Disable the depth test so the text shows on top of the paperdoll
+ glDisable(GL_DEPTH_TEST);
+ // Loop through the lines and draw them all on screen
int yPos = debugTop;
for (const auto &line : lines)
{
@@ -1182,6 +1217,9 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
yPos += 10;
}
+ // Restore the depth test
+ glEnable(GL_DEPTH_TEST);
+
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/Minecraft.Client/Options.cpp b/Minecraft.Client/Options.cpp
index ebe1295a..60886597 100644
--- a/Minecraft.Client/Options.cpp
+++ b/Minecraft.Client/Options.cpp
@@ -170,6 +170,7 @@ void Options::init()
particles = 0;
fov = 0;
gamma = 0;
+ advancedTooltips = false;
}
Options::Options(Minecraft *minecraft, File workingDirectory)
@@ -451,8 +452,9 @@ void Options::load()
if (cmds[0] == L"fancyGraphics") fancyGraphics = cmds[1]==L"true";
if (cmds[0] == L"ao") ambientOcclusion = cmds[1]==L"true";
if (cmds[0] == L"clouds") renderClouds = cmds[1]==L"true";
- if (cmds[0] == L"skin") skin = cmds[1];
- if (cmds[0] == L"lastServer") lastMpIp = cmds[1];
+ if (cmds[0] == L"advancedTooltips") advancedTooltips = cmds[1]==L"false";
+ if (cmds[0] == L"skin") skin = cmds[1];
+ if (cmds[0] == L"lastServer") lastMpIp = cmds[1];
for (int i = 0; i < keyMappings_length; i++)
{
@@ -508,7 +510,8 @@ void Options::save()
dos.writeChars(L"fancyGraphics:" + wstring(fancyGraphics ? L"true" : L"false"));
dos.writeChars(ambientOcclusion ? L"ao:true" : L"ao:false");
dos.writeChars(renderClouds ? L"clouds:true" : L"clouds:false");
- dos.writeChars(L"skin:" + skin);
+ dos.writeChars(advancedTooltips ? L"advancedTooltips:true" : L"advancedTooltips:false");
+ dos.writeChars(L"skin:" + skin);
dos.writeChars(L"lastServer:" + lastMpIp);
for (int i = 0; i < keyMappings_length; i++)
diff --git a/Minecraft.Client/Options.h b/Minecraft.Client/Options.h
index 8be61ac6..29cd83ac 100644
--- a/Minecraft.Client/Options.h
+++ b/Minecraft.Client/Options.h
@@ -110,6 +110,7 @@ public:
int particles; // 0 is all, 1 is decreased and 2 is minimal
float fov;
float gamma;
+ bool advancedTooltips;
void init(); // 4J added
Options(Minecraft *minecraft, File workingDirectory);
diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp
index 6319b660..1fb7c398 100644
--- a/Minecraft.Client/PlayerConnection.cpp
+++ b/Minecraft.Client/PlayerConnection.cpp
@@ -1631,8 +1631,10 @@ bool PlayerConnection::isDisconnected()
void PlayerConnection::handleDebugOptions(shared_ptr<DebugOptionsPacket> packet)
{
- //Player player = dynamic_pointer_cast<Player>( player->shared_from_this() );
- player->SetDebugOptions(packet->m_uiVal);
+#ifdef _DEBUG
+ // Player player = dynamic_pointer_cast<Player>( player->shared_from_this() );
+ player->SetDebugOptions(packet->m_uiVal);
+#endif
}
void PlayerConnection::handleCraftItem(shared_ptr<CraftItemPacket> packet)
diff --git a/Minecraft.Client/Windows64/KeyboardMouseInput.cpp b/Minecraft.Client/Windows64/KeyboardMouseInput.cpp
index 54191ebc..be6efe90 100644
--- a/Minecraft.Client/Windows64/KeyboardMouseInput.cpp
+++ b/Minecraft.Client/Windows64/KeyboardMouseInput.cpp
@@ -234,6 +234,13 @@ bool KeyboardMouseInput::IsKeyReleased(int vkCode) const
return false;
}
+int KeyboardMouseInput::GetPressedKey() const
+{
+ for (int i = 0; i < MAX_KEYS; ++i)
+ if (m_keyPressed[i]) return i;
+ return 0;
+}
+
bool KeyboardMouseInput::IsMouseButtonDown(int button) const
{
if (button >= 0 && button < MAX_MOUSE_BUTTONS)
diff --git a/Minecraft.Client/Windows64/KeyboardMouseInput.h b/Minecraft.Client/Windows64/KeyboardMouseInput.h
index 5c406983..e8b5f588 100644
--- a/Minecraft.Client/Windows64/KeyboardMouseInput.h
+++ b/Minecraft.Client/Windows64/KeyboardMouseInput.h
@@ -56,6 +56,8 @@ public:
bool IsKeyPressed(int vkCode) const;
bool IsKeyReleased(int vkCode) const;
+ int GetPressedKey() const;
+
bool IsMouseButtonDown(int button) const;
bool IsMouseButtonPressed(int button) const;
bool IsMouseButtonReleased(int button) const;
diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp
index 81430ffc..fa5f4ccc 100644
--- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp
+++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp
@@ -36,6 +36,7 @@
//#include "NetworkManager.h"
#include "..\..\Minecraft.Client\Tesselator.h"
#include "..\..\Minecraft.Client\Options.h"
+#include "..\Gui.h"
#include "Sentient\SentientManager.h"
#include "..\..\Minecraft.World\IntCache.h"
#include "..\Textures.h"
@@ -107,6 +108,7 @@ int g_iScreenHeight = 1080;
// always matches the current window, even after a resize.
int g_rScreenWidth = 1920;
int g_rScreenHeight = 1080;
+static bool f3ComboUsed = false;
float g_iAspectRatio = static_cast<float>(g_iScreenWidth) / g_iScreenHeight;
static bool g_bResizeReady = false;
@@ -1774,17 +1776,37 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
}
// F3 toggles onscreen debug info
- if (g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DEBUG_INFO))
+ if (g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DEBUG_INFO)) f3ComboUsed = false;
+
+ // f3 combo
+ if (g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_DEBUG_INFO))
{
- if (const Minecraft* pMinecraft = Minecraft::GetInstance())
+ switch (g_KBMInput.GetPressedKey())
{
- if (pMinecraft->options)
- {
- pMinecraft->options->renderDebug = !pMinecraft->options->renderDebug;
- }
+ // advanced tooltips
+ case 'H':
+ if (pMinecraft->options && app.GetGameStarted())
+ {
+ pMinecraft->options->advancedTooltips = !pMinecraft->options->advancedTooltips;
+ pMinecraft->options->save();
+
+ const wstring msg = wstring(L"Advanced tooltips: ") + (pMinecraft->options->advancedTooltips ? L"shown" : L"hidden");
+ const int primaryPad = ProfileManager.GetPrimaryPad();
+ if (pMinecraft->gui) pMinecraft->gui->addMessage(msg, primaryPad);
+
+ f3ComboUsed = true;
+ }
+ break;
}
}
+ // no combo
+ if (g_KBMInput.IsKeyReleased(KeyboardMouseInput::KEY_DEBUG_INFO) && !f3ComboUsed)
+ if (pMinecraft->options)
+ pMinecraft->options->renderDebug = !pMinecraft->options->renderDebug;
+
+
+
#ifdef _DEBUG_MENUS_ENABLED
// F6 Open debug console
if (g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DEBUG_CONSOLE))
diff --git a/Minecraft.Client/Windows64Media/DLC/Natural/Data/x32Data.pck b/Minecraft.Client/Windows64Media/DLC/Natural/Data/x32Data.pck
index c5f592c4..5bb3ebfc 100644
--- a/Minecraft.Client/Windows64Media/DLC/Natural/Data/x32Data.pck
+++ b/Minecraft.Client/Windows64Media/DLC/Natural/Data/x32Data.pck
Binary files differ