Add Chat / Pastes / Formatting (#682)
* Initial fixes for ContainerSetSlotPacket and CraftItemPacket * Chat: paste, history, § formatting, 1-9 block when open (Windows64) Made-with: Cursor * static_cast refactor
This commit is contained in:
@@ -1,14 +1,27 @@
|
||||
#include "stdafx.h"
|
||||
#include "ChatScreen.h"
|
||||
#include "ClientConnection.h"
|
||||
#include "Font.h"
|
||||
#include "MultiplayerLocalPlayer.h"
|
||||
#include "..\Minecraft.World\SharedConstants.h"
|
||||
#include "..\Minecraft.World\StringHelpers.h"
|
||||
#include "..\Minecraft.World\ChatPacket.h"
|
||||
|
||||
const wstring ChatScreen::allowedChars = SharedConstants::acceptableLetters;
|
||||
vector<wstring> ChatScreen::s_chatHistory;
|
||||
int ChatScreen::s_historyIndex = -1;
|
||||
wstring ChatScreen::s_historyDraft;
|
||||
|
||||
bool ChatScreen::isAllowedChatChar(wchar_t c)
|
||||
{
|
||||
return c >= 0x20 && (c == L'\u00A7' || allowedChars.empty() || allowedChars.find(c) != wstring::npos);
|
||||
}
|
||||
|
||||
ChatScreen::ChatScreen()
|
||||
{
|
||||
frame = 0;
|
||||
cursorIndex = 0;
|
||||
s_historyIndex = -1;
|
||||
}
|
||||
|
||||
void ChatScreen::init()
|
||||
@@ -24,6 +37,50 @@ void ChatScreen::removed()
|
||||
void ChatScreen::tick()
|
||||
{
|
||||
frame++;
|
||||
if (cursorIndex > static_cast<int>(message.length()))
|
||||
cursorIndex = static_cast<int>(message.length());
|
||||
}
|
||||
|
||||
void ChatScreen::handlePasteRequest()
|
||||
{
|
||||
wstring pasted = Screen::getClipboard();
|
||||
for (size_t i = 0; i < pasted.length() && static_cast<int>(message.length()) < SharedConstants::maxChatLength; i++)
|
||||
{
|
||||
if (isAllowedChatChar(pasted[i]))
|
||||
{
|
||||
message.insert(cursorIndex, 1, pasted[i]);
|
||||
cursorIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChatScreen::applyHistoryMessage()
|
||||
{
|
||||
message = s_historyIndex >= 0 ? s_chatHistory[s_historyIndex] : s_historyDraft;
|
||||
cursorIndex = static_cast<int>(message.length());
|
||||
}
|
||||
|
||||
void ChatScreen::handleHistoryUp()
|
||||
{
|
||||
if (s_chatHistory.empty()) return;
|
||||
if (s_historyIndex == -1)
|
||||
{
|
||||
s_historyDraft = message;
|
||||
s_historyIndex = static_cast<int>(s_chatHistory.size()) - 1;
|
||||
}
|
||||
else if (s_historyIndex > 0)
|
||||
s_historyIndex--;
|
||||
applyHistoryMessage();
|
||||
}
|
||||
|
||||
void ChatScreen::handleHistoryDown()
|
||||
{
|
||||
if (s_chatHistory.empty()) return;
|
||||
if (s_historyIndex < static_cast<int>(s_chatHistory.size()) - 1)
|
||||
s_historyIndex++;
|
||||
else
|
||||
s_historyIndex = -1;
|
||||
applyHistoryMessage();
|
||||
}
|
||||
|
||||
void ChatScreen::keyPressed(wchar_t ch, int eventKey)
|
||||
@@ -35,31 +92,67 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey)
|
||||
}
|
||||
if (eventKey == Keyboard::KEY_RETURN)
|
||||
{
|
||||
wstring msg = trimString(message);
|
||||
if (msg.length() > 0)
|
||||
wstring trim = trimString(message);
|
||||
if (trim.length() > 0)
|
||||
{
|
||||
wstring trim = trimString(message);
|
||||
if (!minecraft->handleClientSideCommand(trim))
|
||||
{
|
||||
minecraft->player->chat(trim);
|
||||
MultiplayerLocalPlayer* mplp = dynamic_cast<MultiplayerLocalPlayer*>(minecraft->player.get());
|
||||
if (mplp && mplp->connection)
|
||||
mplp->connection->send(shared_ptr<ChatPacket>(new ChatPacket(trim)));
|
||||
}
|
||||
if (s_chatHistory.empty() || s_chatHistory.back() != trim)
|
||||
{
|
||||
s_chatHistory.push_back(trim);
|
||||
if (s_chatHistory.size() > CHAT_HISTORY_MAX)
|
||||
s_chatHistory.erase(s_chatHistory.begin());
|
||||
}
|
||||
}
|
||||
minecraft->setScreen(NULL);
|
||||
return;
|
||||
}
|
||||
if (eventKey == Keyboard::KEY_BACK && message.length() > 0) message = message.substr(0, message.length() - 1);
|
||||
if (allowedChars.find(ch) >= 0 && message.length() < SharedConstants::maxChatLength)
|
||||
if (eventKey == Keyboard::KEY_UP) { handleHistoryUp(); return; }
|
||||
if (eventKey == Keyboard::KEY_DOWN) { handleHistoryDown(); return; }
|
||||
if (eventKey == Keyboard::KEY_LEFT)
|
||||
{
|
||||
message += ch;
|
||||
if (cursorIndex > 0)
|
||||
cursorIndex--;
|
||||
return;
|
||||
}
|
||||
if (eventKey == Keyboard::KEY_RIGHT)
|
||||
{
|
||||
if (cursorIndex < static_cast<int>(message.length()))
|
||||
cursorIndex++;
|
||||
return;
|
||||
}
|
||||
if (eventKey == Keyboard::KEY_BACK && cursorIndex > 0)
|
||||
{
|
||||
message.erase(cursorIndex - 1, 1);
|
||||
cursorIndex--;
|
||||
return;
|
||||
}
|
||||
if (isAllowedChatChar(ch) && static_cast<int>(message.length()) < SharedConstants::maxChatLength)
|
||||
{
|
||||
message.insert(cursorIndex, 1, ch);
|
||||
cursorIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChatScreen::render(int xm, int ym, float a)
|
||||
{
|
||||
fill(2, height - 14, width - 2, height - 2, 0x80000000);
|
||||
drawString(font, L"> " + message + (frame / 6 % 2 == 0 ? L"_" : L""), 4, height - 12, 0xe0e0e0);
|
||||
|
||||
const wstring prefix = L"> ";
|
||||
int x = 4;
|
||||
drawString(font, prefix, x, height - 12, 0xe0e0e0);
|
||||
x += font->width(prefix);
|
||||
wstring beforeCursor = message.substr(0, cursorIndex);
|
||||
wstring afterCursor = message.substr(cursorIndex);
|
||||
drawStringLiteral(font, beforeCursor, x, height - 12, 0xe0e0e0);
|
||||
x += font->widthLiteral(beforeCursor);
|
||||
if (frame / 6 % 2 == 0)
|
||||
drawString(font, L"_", x, height - 12, 0xe0e0e0);
|
||||
x += font->width(L"_");
|
||||
drawStringLiteral(font, afterCursor, x, height - 12, 0xe0e0e0);
|
||||
Screen::render(xm, ym, a);
|
||||
}
|
||||
|
||||
@@ -71,13 +164,15 @@ void ChatScreen::mouseClicked(int x, int y, int buttonNum)
|
||||
{
|
||||
if (message.length() > 0 && message[message.length()-1]!=L' ')
|
||||
{
|
||||
message += L" ";
|
||||
message = message.substr(0, cursorIndex) + L" " + message.substr(cursorIndex);
|
||||
cursorIndex++;
|
||||
}
|
||||
message += minecraft->gui->selectedName;
|
||||
unsigned int maxLength = SharedConstants::maxChatLength;
|
||||
if (message.length() > maxLength)
|
||||
size_t nameLen = minecraft->gui->selectedName.length();
|
||||
size_t insertLen = (message.length() + nameLen <= SharedConstants::maxChatLength) ? nameLen : (SharedConstants::maxChatLength - message.length());
|
||||
if (insertLen > 0)
|
||||
{
|
||||
message = message.substr(0, maxLength);
|
||||
message = message.substr(0, cursorIndex) + minecraft->gui->selectedName.substr(0, insertLen) + message.substr(cursorIndex);
|
||||
cursorIndex += static_cast<int>(insertLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -85,5 +180,4 @@ void ChatScreen::mouseClicked(int x, int y, int buttonNum)
|
||||
Screen::mouseClicked(x, y, buttonNum);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +1,33 @@
|
||||
#pragma once
|
||||
#include "Screen.h"
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
class ChatScreen : public Screen
|
||||
{
|
||||
protected:
|
||||
wstring message;
|
||||
int cursorIndex;
|
||||
void applyHistoryMessage();
|
||||
|
||||
private:
|
||||
int frame;
|
||||
static const size_t CHAT_HISTORY_MAX = 100;
|
||||
static std::vector<wstring> s_chatHistory;
|
||||
static int s_historyIndex;
|
||||
static wstring s_historyDraft;
|
||||
static const wstring allowedChars;
|
||||
static bool isAllowedChatChar(wchar_t c);
|
||||
|
||||
public:
|
||||
ChatScreen(); //4J added
|
||||
ChatScreen();
|
||||
virtual void init();
|
||||
virtual void removed();
|
||||
virtual void tick();
|
||||
private:
|
||||
static const wstring allowedChars;
|
||||
virtual void removed();
|
||||
virtual void tick();
|
||||
virtual void handlePasteRequest();
|
||||
virtual void handleHistoryUp();
|
||||
virtual void handleHistoryDown();
|
||||
|
||||
protected:
|
||||
void keyPressed(wchar_t ch, int eventKey);
|
||||
public:
|
||||
|
||||
@@ -1441,6 +1441,9 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||
|
||||
switch(packet->m_messageType)
|
||||
{
|
||||
case ChatPacket::e_ChatCustom:
|
||||
message = (packet->m_stringArgs.size() >= 1) ? packet->m_stringArgs[0] : L"";
|
||||
break;
|
||||
case ChatPacket::e_ChatBedOccupied:
|
||||
message = app.GetString(IDS_TILE_BED_OCCUPIED);
|
||||
break;
|
||||
|
||||
@@ -55,10 +55,16 @@ void UIComponent_Chat::handleTimerComplete(int id)
|
||||
float opacity = pGui->getOpacity(m_iPad, i);
|
||||
if( opacity > 0 )
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
// Chat drawn by Gui::render with color codes. Hides Iggy chat to avoid double chats.
|
||||
m_controlLabelBackground[i].setOpacity(0);
|
||||
m_labelChatText[i].setOpacity(0);
|
||||
m_labelChatText[i].setLabel(L"");
|
||||
#else
|
||||
m_controlLabelBackground[i].setOpacity(opacity);
|
||||
m_labelChatText[i].setOpacity(opacity);
|
||||
m_labelChatText[i].setLabel( pGui->getMessage(m_iPad,i) );
|
||||
|
||||
#endif
|
||||
anyVisible = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -753,10 +753,16 @@ void UIScene_HUD::handleTimerComplete(int id)
|
||||
float opacity = pGui->getOpacity(m_iPad, i);
|
||||
if( opacity > 0 )
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
// Chat drawn by Gui::render with color codes. Hides Iggy chat to avoid double chats.
|
||||
m_controlLabelBackground[i].setOpacity(0);
|
||||
m_labelChatText[i].setOpacity(0);
|
||||
m_labelChatText[i].setLabel(L"");
|
||||
#else
|
||||
m_controlLabelBackground[i].setOpacity(opacity);
|
||||
m_labelChatText[i].setOpacity(opacity);
|
||||
m_labelChatText[i].setLabel( pGui->getMessagesCount(m_iPad) ? pGui->getMessage(m_iPad,i) : L"" );
|
||||
|
||||
#endif
|
||||
anyVisible = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -21,6 +21,10 @@ Font::Font(Options *options, const wstring& name, Textures* textures, bool enfor
|
||||
enforceUnicodeSheet = false;
|
||||
bidirectional = false;
|
||||
xPos = yPos = 0.0f;
|
||||
m_bold = false;
|
||||
m_italic = false;
|
||||
m_underline = false;
|
||||
m_strikethrough = false;
|
||||
|
||||
// Set up member variables
|
||||
m_cols = cols;
|
||||
@@ -126,6 +130,22 @@ Font::~Font()
|
||||
}
|
||||
#endif
|
||||
|
||||
void Font::renderStyleLine(float x0, float y0, float x1, float y1)
|
||||
{
|
||||
Tesselator* t = Tesselator::getInstance();
|
||||
float u = 0.0f, v = 0.0f;
|
||||
t->begin();
|
||||
t->tex(u, v);
|
||||
t->vertex(x0, y1, 0.0f);
|
||||
t->tex(u, v);
|
||||
t->vertex(x1, y1, 0.0f);
|
||||
t->tex(u, v);
|
||||
t->vertex(x1, y0, 0.0f);
|
||||
t->tex(u, v);
|
||||
t->vertex(x0, y0, 0.0f);
|
||||
t->end();
|
||||
}
|
||||
|
||||
void Font::renderCharacter(wchar_t c)
|
||||
{
|
||||
float xOff = c % m_cols * m_charWidth;
|
||||
@@ -137,37 +157,47 @@ void Font::renderCharacter(wchar_t c)
|
||||
float fontWidth = m_cols * m_charWidth;
|
||||
float fontHeight = m_rows * m_charHeight;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
// 4J Stu - Changed to a quad so that we can use within a command buffer
|
||||
#if 1
|
||||
const float shear = m_italic ? (height * 0.25f) : 0.0f;
|
||||
float x0 = xPos, x1 = xPos + width + shear;
|
||||
float y0 = yPos, y1 = yPos + height;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->begin();
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(xPos, yPos + height, 0.0f);
|
||||
|
||||
t->vertex(x0, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(xPos + width, yPos + height, 0.0f);
|
||||
|
||||
t->vertex(x1, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, yOff / fontHeight);
|
||||
t->vertex(xPos + width, yPos, 0.0f);
|
||||
|
||||
t->vertex(x1, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->vertex(xPos, yPos, 0.0f);
|
||||
|
||||
t->vertex(x0, y0, 0.0f);
|
||||
t->end();
|
||||
#else
|
||||
t->begin(GL_TRIANGLE_STRIP);
|
||||
t->tex(xOff / 128.0F, yOff / 128.0F);
|
||||
t->vertex(xPos, yPos, 0.0f);
|
||||
t->tex(xOff / 128.0F, (yOff + 7.99f) / 128.0F);
|
||||
t->vertex(xPos, yPos + 7.99f, 0.0f);
|
||||
t->tex((xOff + width) / 128.0F, yOff / 128.0F);
|
||||
t->vertex(xPos + width, yPos, 0.0f);
|
||||
t->tex((xOff + width) / 128.0F, (yOff + 7.99f) / 128.0F);
|
||||
t->vertex(xPos + width, yPos + 7.99f, 0.0f);
|
||||
t->end();
|
||||
#endif
|
||||
|
||||
xPos += (float) charWidths[c];
|
||||
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);
|
||||
|
||||
if (m_strikethrough)
|
||||
{
|
||||
float mid = y0 + height * 0.5f;
|
||||
renderStyleLine(x0, mid - 0.5f, xPos + static_cast<float>(charWidths[c]), mid + 0.5f);
|
||||
}
|
||||
|
||||
xPos += static_cast<float>(charWidths[c]);
|
||||
}
|
||||
|
||||
void Font::drawShadow(const wstring& str, int x, int y, int color)
|
||||
@@ -176,6 +206,26 @@ void Font::drawShadow(const wstring& str, int x, int y, int color)
|
||||
draw(str, x, y, color, false);
|
||||
}
|
||||
|
||||
void Font::drawShadowLiteral(const wstring& str, int x, int y, int color)
|
||||
{
|
||||
int shadowColor = (color & 0xFCFCFC) >> 2 | (color & 0xFF000000);
|
||||
drawLiteral(str, x + 1, y + 1, shadowColor);
|
||||
drawLiteral(str, x, y, color);
|
||||
}
|
||||
|
||||
void Font::drawLiteral(const wstring& str, int x, int y, int color)
|
||||
{
|
||||
if (str.empty()) return;
|
||||
if ((color & 0xFC000000) == 0) color |= 0xFF000000;
|
||||
textures->bindTexture(m_textureLocation);
|
||||
glColor4f((color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, (color & 255) / 255.0F, (color >> 24 & 255) / 255.0F);
|
||||
xPos = static_cast<float>(x);
|
||||
yPos = static_cast<float>(y);
|
||||
wstring cleanStr = sanitize(str);
|
||||
for (size_t i = 0; i < cleanStr.length(); ++i)
|
||||
renderCharacter(cleanStr.at(i));
|
||||
}
|
||||
|
||||
void Font::drawShadowWordWrap(const wstring &str, int x, int y, int w, int color, int h)
|
||||
{
|
||||
drawWordWrapInternal(str, x + 1, y + 1, w, color, true, h);
|
||||
@@ -193,24 +243,38 @@ wstring Font::reorderBidi(const wstring &str)
|
||||
return str;
|
||||
}
|
||||
|
||||
static bool isSectionFormatCode(wchar_t ca)
|
||||
{
|
||||
if ((ca >= L'0' && ca <= L'9') || (ca >= L'a' && ca <= L'f') || (ca >= L'A' && ca <= L'F'))
|
||||
return true;
|
||||
wchar_t l = static_cast<wchar_t>(ca | 32);
|
||||
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)
|
||||
{
|
||||
// Bind the texture
|
||||
textures->bindTexture(m_textureLocation);
|
||||
|
||||
bool noise = false;
|
||||
m_bold = m_italic = m_underline = m_strikethrough = false;
|
||||
wstring cleanStr = sanitize(str);
|
||||
|
||||
for (int i = 0; i < (int)cleanStr.length(); ++i)
|
||||
for (int i = 0; i < static_cast<int>(cleanStr.length()); ++i)
|
||||
{
|
||||
// Map character
|
||||
wchar_t c = cleanStr.at(i);
|
||||
|
||||
if (c == 167 && i + 1 < cleanStr.length())
|
||||
{
|
||||
// 4J - following block was:
|
||||
// int colorN = L"0123456789abcdefk".indexOf(str.toLowerCase().charAt(i + 1));
|
||||
wchar_t ca = cleanStr[i+1];
|
||||
if (!isSectionFormatCode(ca))
|
||||
{
|
||||
renderCharacter(167);
|
||||
renderCharacter(ca);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
int colorN = 16;
|
||||
if(( ca >= L'0' ) && (ca <= L'9')) colorN = ca - L'0';
|
||||
else if(( ca >= L'a' ) && (ca <= L'f')) colorN = (ca - L'a') + 10;
|
||||
@@ -218,7 +282,13 @@ void Font::draw(const wstring &str, bool dropShadow)
|
||||
|
||||
if (colorN == 16)
|
||||
{
|
||||
noise = true;
|
||||
wchar_t l = static_cast<wchar_t>(ca | 32);
|
||||
if (l == L'l') m_bold = true;
|
||||
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'k') noise = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -280,20 +350,34 @@ int Font::width(const wstring& str)
|
||||
{
|
||||
wchar_t c = cleanStr.at(i);
|
||||
|
||||
if(c == 167)
|
||||
if (c == 167)
|
||||
{
|
||||
// Ignore the character used to define coloured text
|
||||
++i;
|
||||
if (i + 1 < cleanStr.length() && isSectionFormatCode(cleanStr[i+1]))
|
||||
++i;
|
||||
else
|
||||
{
|
||||
len += charWidths[167];
|
||||
if (i + 1 < cleanStr.length())
|
||||
len += charWidths[static_cast<unsigned>(cleanStr[++i])];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len += charWidths[c];
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int Font::widthLiteral(const wstring& str)
|
||||
{
|
||||
wstring cleanStr = sanitize(str);
|
||||
if (cleanStr == L"") return 0;
|
||||
int len = 0;
|
||||
for (size_t i = 0; i < cleanStr.length(); ++i)
|
||||
len += charWidths[static_cast<unsigned>(cleanStr.at(i))];
|
||||
return len;
|
||||
}
|
||||
|
||||
wstring Font::sanitize(const wstring& str)
|
||||
{
|
||||
wstring sb = str;
|
||||
@@ -467,7 +551,7 @@ void Font::setBidirectional(bool bidirectional)
|
||||
|
||||
bool Font::AllCharactersValid(const wstring &str)
|
||||
{
|
||||
for (int i = 0; i < (int)str.length(); ++i)
|
||||
for (int i = 0; i < static_cast<int>(str.length()); ++i)
|
||||
{
|
||||
wchar_t c = str.at(i);
|
||||
|
||||
@@ -512,15 +596,15 @@ void Font::renderFakeCB(IntBuffer *ib)
|
||||
float uo = (0.0f) / 128.0f;
|
||||
float vo = (0.0f) / 128.0f;
|
||||
|
||||
t->vertexUV((float)(0), (float)( 0 + s), (float)( 0), (float)( ix / 128.0f + uo), (float)( (iy + s) / 128.0f + vo));
|
||||
t->vertexUV((float)(0 + s), (float)( 0 + s), (float)( 0), (float)( (ix + s) / 128.0f + uo), (float)( (iy + s) / 128.0f + vo));
|
||||
t->vertexUV((float)(0 + s), (float)( 0), (float)( 0), (float)( (ix + s) / 128.0f + uo), (float)( iy / 128.0f + vo));
|
||||
t->vertexUV((float)(0), (float)( 0), (float)( 0), (float)( ix / 128.0f + uo), (float)( iy / 128.0f + vo));
|
||||
t->vertexUV(static_cast<float>(0), static_cast<float>(0 + s), static_cast<float>(0), static_cast<float>(ix / 128.0f + uo), static_cast<float>((iy + s) / 128.0f + vo));
|
||||
t->vertexUV(static_cast<float>(0 + s), static_cast<float>(0 + s), static_cast<float>(0), static_cast<float>((ix + s) / 128.0f + uo), static_cast<float>((iy + s) / 128.0f + vo));
|
||||
t->vertexUV(static_cast<float>(0 + s), static_cast<float>(0), static_cast<float>(0), static_cast<float>((ix + s) / 128.0f + uo), static_cast<float>(iy / 128.0f + vo));
|
||||
t->vertexUV(static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(ix / 128.0f + uo), static_cast<float>(iy / 128.0f + vo));
|
||||
// target.colorBlit(texture, x + xo, y, color, ix, iy,
|
||||
// charWidths[chars[i]], 8);
|
||||
t->end();
|
||||
|
||||
glTranslatef((float)charWidths[i], 0, 0);
|
||||
glTranslatef(static_cast<float>(charWidths[i]), 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -21,6 +21,12 @@ private:
|
||||
float xPos;
|
||||
float yPos;
|
||||
|
||||
// § format state (bold, italic, underline, strikethrough); set during draw(), reset by §r
|
||||
bool m_bold;
|
||||
bool m_italic;
|
||||
bool m_underline;
|
||||
bool m_strikethrough;
|
||||
|
||||
bool enforceUnicodeSheet; // use unicode sheet for ascii
|
||||
bool bidirectional; // use bidi to flip strings
|
||||
|
||||
@@ -41,9 +47,11 @@ public:
|
||||
|
||||
private:
|
||||
void renderCharacter(wchar_t c); // 4J added
|
||||
void renderStyleLine(float x0, float y0, float x1, float y1); // solid line for underline/strikethrough
|
||||
|
||||
public:
|
||||
void drawShadow(const wstring& str, int x, int y, int color);
|
||||
void drawShadowLiteral(const wstring& str, int x, int y, int color); // draw without interpreting § codes
|
||||
void drawShadowWordWrap(const wstring &str, int x, int y, int w, int color, int h); // 4J Added h param
|
||||
void draw(const wstring &str, int x, int y, int color);
|
||||
/**
|
||||
@@ -58,11 +66,13 @@ private:
|
||||
|
||||
void draw(const wstring &str, bool dropShadow);
|
||||
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
|
||||
bool CharacterExists(wchar_t c); // 4J added
|
||||
|
||||
public:
|
||||
int width(const wstring& str);
|
||||
int widthLiteral(const wstring& str); // width without skipping § codes (for chat input)
|
||||
wstring sanitize(const wstring& str);
|
||||
void drawWordWrap(const wstring &string, int x, int y, int w, int col, int h); // 4J Added h param
|
||||
|
||||
|
||||
@@ -971,15 +971,10 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
// 4J Stu - We have moved the chat text to a xui
|
||||
#if 0
|
||||
#if defined(_WINDOWS64)
|
||||
glPushMatrix();
|
||||
// 4J-PB we need to move this up a bit because we've moved the quick select
|
||||
//glTranslatef(0, ((float)screenHeight) - 48, 0);
|
||||
glTranslatef(0.0f, (float)(screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22) - 24.0f, 0.0f);
|
||||
// glScalef(1.0f / ssc.scale, 1.0f / ssc.scale, 1);
|
||||
glTranslatef(0.0f, static_cast<float>(screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22) - 24.0f, 0.0f);
|
||||
|
||||
// 4J-PB - we need gui messages for each of the possible 4 splitscreen players
|
||||
if(bDisplayGui)
|
||||
{
|
||||
int iPad=minecraft->player->GetXboxPad();
|
||||
@@ -993,23 +988,21 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
if (t < 0) t = 0;
|
||||
if (t > 1) t = 1;
|
||||
t = t * t;
|
||||
int alpha = (int) (255 * t);
|
||||
int alpha = static_cast<int>(255 * t);
|
||||
if (isChatting) alpha = 255;
|
||||
|
||||
if (alpha > 0)
|
||||
{
|
||||
int x = iSafezoneXHalf+2;
|
||||
int y = -((int)i) * 9;
|
||||
int y = -(static_cast<int>(i)) * 9;
|
||||
if(bTwoPlayerSplitscreen)
|
||||
{
|
||||
y+= iHeightOffset;
|
||||
}
|
||||
|
||||
wstring msg = guiMessages[iPad][i].string;
|
||||
// 4J-PB - fill the black bar across the whole screen, otherwise it looks odd due to the safe area
|
||||
this->fill(0, y - 1, screenWidth/fScaleFactorWidth, y + 8, (alpha / 2) << 24);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
font->drawShadow(msg, iSafezoneXHalf+4, y, 0xffffff + (alpha << 24));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,10 +48,10 @@ void GuiComponent::fill(int x0, int y0, int x1, int y1, int col)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(r, g, b, a);
|
||||
t->begin();
|
||||
t->vertex((float)(x0), (float)( y1), (float)( 0));
|
||||
t->vertex((float)(x1), (float)( y1), (float)( 0));
|
||||
t->vertex((float)(x1), (float)( y0), (float)( 0));
|
||||
t->vertex((float)(x0), (float)( y0), (float)( 0));
|
||||
t->vertex(static_cast<float>(x0), static_cast<float>(y1), static_cast<float>(0));
|
||||
t->vertex(static_cast<float>(x1), static_cast<float>(y1), static_cast<float>(0));
|
||||
t->vertex(static_cast<float>(x1), static_cast<float>(y0), static_cast<float>(0));
|
||||
t->vertex(static_cast<float>(x0), static_cast<float>(y0), static_cast<float>(0));
|
||||
t->end();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -77,11 +77,11 @@ void GuiComponent::fillGradient(int x0, int y0, int x1, int y1, int col1, int co
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->begin();
|
||||
t->color(r1, g1, b1, a1);
|
||||
t->vertex((float)(x1), (float)( y0), blitOffset);
|
||||
t->vertex((float)(x0), (float)( y0), blitOffset);
|
||||
t->vertex(static_cast<float>(x1), static_cast<float>(y0), blitOffset);
|
||||
t->vertex(static_cast<float>(x0), static_cast<float>(y0), blitOffset);
|
||||
t->color(r2, g2, b2, a2);
|
||||
t->vertex((float)(x0), (float)( y1), blitOffset);
|
||||
t->vertex((float)(x1), (float)( y1), blitOffset);
|
||||
t->vertex(static_cast<float>(x0), static_cast<float>(y1), blitOffset);
|
||||
t->vertex(static_cast<float>(x1), static_cast<float>(y1), blitOffset);
|
||||
t->end();
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
@@ -105,6 +105,11 @@ void GuiComponent::drawString(Font *font, const wstring& str, int x, int y, int
|
||||
font->drawShadow(str, x, y, color);
|
||||
}
|
||||
|
||||
void GuiComponent::drawStringLiteral(Font *font, const wstring& str, int x, int y, int color)
|
||||
{
|
||||
font->drawShadowLiteral(str, x, y, color);
|
||||
}
|
||||
|
||||
void GuiComponent::blit(int x, int y, int sx, int sy, int w, int h)
|
||||
{
|
||||
float us = 1 / 256.0f;
|
||||
@@ -117,20 +122,20 @@ void GuiComponent::blit(int x, int y, int sx, int sy, int w, int h)
|
||||
const float extraShift = 0.75f;
|
||||
|
||||
// 4J - subtracting extraShift (actual screen pixels, so need to compensate for physical & game width) from each x & y coordinate to compensate for centre of pixels in directx vs openGL
|
||||
float dx = ( extraShift * (float)Minecraft::GetInstance()->width ) / (float)Minecraft::GetInstance()->width_phys;
|
||||
float dx = ( extraShift * static_cast<float>(Minecraft::GetInstance()->width) ) / static_cast<float>(Minecraft::GetInstance()->width_phys);
|
||||
// 4J - Also factor in the scaling from gui coordinate space to the screen. This varies based on user-selected gui scale, and whether we are in a viewport mode or not
|
||||
dx /= Gui::currentGuiScaleFactor;
|
||||
float dy = extraShift / Gui::currentGuiScaleFactor;
|
||||
// Ensure that the x/y, width and height are actually pixel aligned at our current scale factor - in particular, for split screen mode with the default (3X)
|
||||
// scale, we have an overall scale factor of 3 * 0.5 = 1.5, and so any odd pixels won't align
|
||||
float fx = (floorf((float)x * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fy = (floorf((float)y * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fw = (floorf((float)w * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fh = (floorf((float)h * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fx = (floorf(static_cast<float>(x) * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fy = (floorf(static_cast<float>(y) * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fw = (floorf(static_cast<float>(w) * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
float fh = (floorf(static_cast<float>(h) * Gui::currentGuiScaleFactor)) / Gui::currentGuiScaleFactor;
|
||||
|
||||
t->vertexUV(fx + 0 - dx, fy + fh - dy, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + h) * vs));
|
||||
t->vertexUV(fx + fw - dx, fy + fh - dy, (float)( blitOffset), (float)( (sx + w) * us), (float)( (sy + h) * vs));
|
||||
t->vertexUV(fx + fw - dx, fy + 0 - dy, (float)( blitOffset), (float)( (sx + w) * us), (float)( (sy + 0) * vs));
|
||||
t->vertexUV(fx + 0 - dx, fy + 0 - dy, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + 0) * vs));
|
||||
t->vertexUV(fx + 0 - dx, fy + fh - dy, static_cast<float>(blitOffset), static_cast<float>((sx + 0) * us), static_cast<float>((sy + h) * vs));
|
||||
t->vertexUV(fx + fw - dx, fy + fh - dy, static_cast<float>(blitOffset), static_cast<float>((sx + w) * us), static_cast<float>((sy + h) * vs));
|
||||
t->vertexUV(fx + fw - dx, fy + 0 - dy, static_cast<float>(blitOffset), static_cast<float>((sx + w) * us), static_cast<float>((sy + 0) * vs));
|
||||
t->vertexUV(fx + 0 - dx, fy + 0 - dy, static_cast<float>(blitOffset), static_cast<float>((sx + 0) * us), static_cast<float>((sy + 0) * vs));
|
||||
t->end();
|
||||
}
|
||||
@@ -15,5 +15,6 @@ public:
|
||||
GuiComponent(); // 4J added
|
||||
void drawCenteredString(Font *font, const wstring& str, int x, int y, int color);
|
||||
void drawString(Font *font, const wstring& str, int x, int y, int color);
|
||||
void drawStringLiteral(Font* font, const wstring& str, int x, int y, int color);
|
||||
void blit(int x, int y, int sx, int sy, int w, int h);
|
||||
};
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "..\Minecraft.World\AABB.h"
|
||||
#include "..\Minecraft.World\Pos.h"
|
||||
#include "..\Minecraft.World\SharedConstants.h"
|
||||
#include "..\Minecraft.World\ChatPacket.h"
|
||||
#include "..\Minecraft.World\StringHelpers.h"
|
||||
#include "..\Minecraft.World\Socket.h"
|
||||
#include "..\Minecraft.World\Achievements.h"
|
||||
#include "..\Minecraft.World\net.minecraft.h"
|
||||
@@ -607,38 +609,26 @@ void PlayerConnection::handleSetCarriedItem(shared_ptr<SetCarriedItemPacket> pac
|
||||
|
||||
void PlayerConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||
{
|
||||
// 4J - TODO
|
||||
#if 0
|
||||
wstring message = packet->message;
|
||||
if (packet->m_stringArgs.empty()) return;
|
||||
wstring message = trimString(packet->m_stringArgs[0]);
|
||||
if (message.length() > SharedConstants::maxChatLength)
|
||||
{
|
||||
disconnect(L"Chat message too long");
|
||||
disconnect(DisconnectPacket::eDisconnect_None); // or a specific reason
|
||||
return;
|
||||
}
|
||||
message = message.trim();
|
||||
for (int i = 0; i < message.length(); i++)
|
||||
{
|
||||
if (SharedConstants.acceptableLetters.indexOf(message.charAt(i)) < 0 && (int) message.charAt(i) < 32)
|
||||
{
|
||||
disconnect(L"Illegal characters in chat");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (message.startsWith("/"))
|
||||
// Optional: validate characters (acceptableLetters)
|
||||
if (message.length() > 0 && message[0] == L'/')
|
||||
{
|
||||
handleCommand(message);
|
||||
} else {
|
||||
message = "<" + player.name + "> " + message;
|
||||
logger.info(message);
|
||||
server.players.broadcastAll(new ChatPacket(message));
|
||||
return;
|
||||
}
|
||||
wstring formatted = L"<" + player->name + L"> " + message;
|
||||
server->getPlayers()->broadcastAll(shared_ptr<ChatPacket>(new ChatPacket(formatted)));
|
||||
chatSpamTickCount += SharedConstants::TICKS_PER_SECOND;
|
||||
if (chatSpamTickCount > SharedConstants::TICKS_PER_SECOND * 10)
|
||||
{
|
||||
disconnect("disconnect.spam");
|
||||
disconnect(DisconnectPacket::eDisconnect_None); // spam
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PlayerConnection::handleCommand(const wstring& message)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Screen.h"
|
||||
#include "Button.h"
|
||||
#include "ChatScreen.h"
|
||||
#include "GuiParticles.h"
|
||||
#include "Tesselator.h"
|
||||
#include "Textures.h"
|
||||
@@ -42,13 +43,32 @@ void Screen::keyPressed(wchar_t eventCharacter, int eventKey)
|
||||
|
||||
wstring Screen::getClipboard()
|
||||
{
|
||||
// 4J - removed
|
||||
return NULL;
|
||||
#ifdef _WINDOWS64
|
||||
if (!OpenClipboard(NULL)) return wstring();
|
||||
HANDLE h = GetClipboardData(CF_UNICODETEXT);
|
||||
wstring out;
|
||||
if (h)
|
||||
{
|
||||
const wchar_t *p = reinterpret_cast<const wchar_t*>(GlobalLock(h));
|
||||
if (p) { out = p; GlobalUnlock(h); }
|
||||
}
|
||||
CloseClipboard();
|
||||
return out;
|
||||
#else
|
||||
return wstring();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::setClipboard(const wstring& str)
|
||||
{
|
||||
// 4J - removed
|
||||
#ifdef _WINDOWS64
|
||||
if (!OpenClipboard(NULL)) return;
|
||||
EmptyClipboard();
|
||||
size_t len = (str.length() + 1) * sizeof(wchar_t);
|
||||
HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, len);
|
||||
if (h) { memcpy(GlobalLock(h), str.c_str(), len); GlobalUnlock(h); SetClipboardData(CF_UNICODETEXT, h); }
|
||||
CloseClipboard();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::mouseClicked(int x, int y, int buttonNum)
|
||||
@@ -121,34 +141,88 @@ void Screen::updateEvents()
|
||||
}
|
||||
}
|
||||
|
||||
// Poll keyboard events
|
||||
// Only drain WM_CHAR when this screen wants text input (e.g. ChatScreen); otherwise we'd steal keys from the game
|
||||
if (dynamic_cast<ChatScreen*>(this) != nullptr)
|
||||
{
|
||||
wchar_t ch;
|
||||
while (g_KBMInput.ConsumeChar(ch))
|
||||
{
|
||||
if (ch >= 0x20)
|
||||
keyPressed(ch, -1);
|
||||
else if (ch == 0x08)
|
||||
keyPressed(0, Keyboard::KEY_BACK);
|
||||
else if (ch == 0x0D)
|
||||
keyPressed(0, Keyboard::KEY_RETURN);
|
||||
}
|
||||
}
|
||||
|
||||
// Arrow key repeat: deliver on first press (when key down and last==0) and while held (throttled)
|
||||
static DWORD s_arrowLastTime[2] = { 0, 0 };
|
||||
static bool s_arrowFirstRepeat[2] = { false, false };
|
||||
const DWORD ARROW_REPEAT_DELAY_MS = 250;
|
||||
const DWORD ARROW_REPEAT_INTERVAL_MS = 50;
|
||||
DWORD now = GetTickCount();
|
||||
|
||||
// Poll keyboard events (special keys that may not come through WM_CHAR, e.g. Escape, arrows)
|
||||
for (int vk = 0; vk < 256; vk++)
|
||||
{
|
||||
if (g_KBMInput.IsKeyPressed(vk))
|
||||
bool deliver = g_KBMInput.IsKeyPressed(vk);
|
||||
if (vk == VK_LEFT || vk == VK_RIGHT)
|
||||
{
|
||||
// Map Windows virtual key to the Keyboard constants used by Screen::keyPressed
|
||||
int mappedKey = -1;
|
||||
wchar_t ch = 0;
|
||||
if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE;
|
||||
else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN;
|
||||
else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK;
|
||||
else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP;
|
||||
else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN;
|
||||
else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT;
|
||||
else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT;
|
||||
else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT;
|
||||
else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB;
|
||||
else if (vk >= 'A' && vk <= 'Z')
|
||||
int idx = (vk == VK_LEFT) ? 0 : 1;
|
||||
if (!g_KBMInput.IsKeyDown(vk))
|
||||
{
|
||||
ch = (wchar_t)(vk - 'A' + L'a');
|
||||
if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = (wchar_t)vk;
|
||||
s_arrowLastTime[idx] = 0;
|
||||
s_arrowFirstRepeat[idx] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD last = s_arrowLastTime[idx];
|
||||
if (last == 0)
|
||||
deliver = true;
|
||||
else if (!deliver)
|
||||
{
|
||||
DWORD interval = s_arrowFirstRepeat[idx] ? ARROW_REPEAT_INTERVAL_MS : ARROW_REPEAT_DELAY_MS;
|
||||
if ((now - last) >= interval)
|
||||
{
|
||||
deliver = true;
|
||||
s_arrowFirstRepeat[idx] = true;
|
||||
}
|
||||
}
|
||||
if (deliver)
|
||||
s_arrowLastTime[idx] = now;
|
||||
}
|
||||
else if (vk >= '0' && vk <= '9') ch = (wchar_t)vk;
|
||||
else if (vk == VK_SPACE) ch = L' ';
|
||||
|
||||
if (mappedKey != -1) keyPressed(ch, mappedKey);
|
||||
else if (ch != 0) keyPressed(ch, -1);
|
||||
}
|
||||
// Escape: deliver when key is down so we don't miss it (IsKeyPressed can be one frame late)
|
||||
if (vk == VK_ESCAPE && g_KBMInput.IsKeyDown(VK_ESCAPE))
|
||||
deliver = true;
|
||||
if (!deliver) continue;
|
||||
|
||||
if (dynamic_cast<ChatScreen*>(this) != nullptr &&
|
||||
(vk >= 'A' && vk <= 'Z' || vk >= '0' && vk <= '9' || vk == VK_SPACE || vk == VK_RETURN || vk == VK_BACK))
|
||||
continue;
|
||||
// Map to Screen::keyPressed
|
||||
int mappedKey = -1;
|
||||
wchar_t ch = 0;
|
||||
if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE;
|
||||
else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN;
|
||||
else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK;
|
||||
else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP;
|
||||
else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN;
|
||||
else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT;
|
||||
else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT;
|
||||
else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT;
|
||||
else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB;
|
||||
else if (vk >= 'A' && vk <= 'Z')
|
||||
{
|
||||
ch = static_cast<wchar_t>(vk - 'A' + L'a');
|
||||
if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = static_cast<wchar_t>(vk);
|
||||
}
|
||||
else if (vk >= '0' && vk <= '9') ch = static_cast<wchar_t>(vk);
|
||||
else if (vk == VK_SPACE) ch = L' ';
|
||||
|
||||
if (mappedKey != -1) keyPressed(ch, mappedKey);
|
||||
else if (ch != 0) keyPressed(ch, -1);
|
||||
}
|
||||
#else
|
||||
/* 4J - TODO
|
||||
@@ -232,10 +306,10 @@ void Screen::renderDirtBackground(int vo)
|
||||
float s = 32;
|
||||
t->begin();
|
||||
t->color(0x404040);
|
||||
t->vertexUV((float)(0), (float)( height), (float)( 0), (float)( 0), (float)( height / s + vo));
|
||||
t->vertexUV((float)(width), (float)( height), (float)( 0), (float)( width / s), (float)( height / s + vo));
|
||||
t->vertexUV((float)(width), (float)( 0), (float)( 0), (float)( width / s), (float)( 0 + vo));
|
||||
t->vertexUV((float)(0), (float)( 0), (float)( 0), (float)( 0), (float)( 0 + vo));
|
||||
t->vertexUV(static_cast<float>(0), static_cast<float>(height), static_cast<float>(0), static_cast<float>(0), static_cast<float>(height / s + vo));
|
||||
t->vertexUV(static_cast<float>(width), static_cast<float>(height), static_cast<float>(0), static_cast<float>(width / s), static_cast<float>(height / s + vo));
|
||||
t->vertexUV(static_cast<float>(width), static_cast<float>(0), static_cast<float>(0), static_cast<float>(width / s), static_cast<float>(0 + vo));
|
||||
t->vertexUV(static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(0 + vo));
|
||||
t->end();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -36,9 +36,12 @@ protected:
|
||||
virtual void mouseReleased(int x, int y, int buttonNum);
|
||||
virtual void buttonClicked(Button *button);
|
||||
public:
|
||||
virtual void init(Minecraft *minecraft, int width, int height);
|
||||
virtual void init(Minecraft *minecraft, int width, int height);
|
||||
virtual void setSize(int width, int height);
|
||||
virtual void init();
|
||||
virtual void handlePasteRequest() {}
|
||||
virtual void handleHistoryUp() {}
|
||||
virtual void handleHistoryDown() {}
|
||||
virtual void updateEvents();
|
||||
virtual void mouseEvent();
|
||||
virtual void keyboardEvent();
|
||||
|
||||
@@ -257,8 +257,8 @@ bool KeyboardMouseInput::IsMouseButtonReleased(int button) const
|
||||
|
||||
void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
|
||||
{
|
||||
dx = (float)m_mouseDeltaAccumX;
|
||||
dy = (float)m_mouseDeltaAccumY;
|
||||
dx = static_cast<float>(m_mouseDeltaAccumX);
|
||||
dy = static_cast<float>(m_mouseDeltaAccumY);
|
||||
m_mouseDeltaAccumX = 0;
|
||||
m_mouseDeltaAccumY = 0;
|
||||
}
|
||||
@@ -375,12 +375,12 @@ float KeyboardMouseInput::GetMoveY() const
|
||||
|
||||
float KeyboardMouseInput::GetLookX(float sensitivity) const
|
||||
{
|
||||
return (float)m_mouseDeltaX * sensitivity;
|
||||
return static_cast<float>(m_mouseDeltaX) * sensitivity;
|
||||
}
|
||||
|
||||
float KeyboardMouseInput::GetLookY(float sensitivity) const
|
||||
{
|
||||
return (float)(-m_mouseDeltaY) * sensitivity;
|
||||
return static_cast<float>(-m_mouseDeltaY) * sensitivity;
|
||||
}
|
||||
|
||||
void KeyboardMouseInput::OnChar(wchar_t c)
|
||||
|
||||
@@ -143,4 +143,4 @@ private:
|
||||
|
||||
extern KeyboardMouseInput g_KBMInput;
|
||||
|
||||
#endif // _WINDOWS64
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#include "..\..\Minecraft.World\net.minecraft.world.level.tile.h"
|
||||
|
||||
#include "..\ClientConnection.h"
|
||||
#include "..\Minecraft.h"
|
||||
#include "..\ChatScreen.h"
|
||||
#include "KeyboardMouseInput.h"
|
||||
#include "..\User.h"
|
||||
#include "..\..\Minecraft.World\Socket.h"
|
||||
#include "..\..\Minecraft.World\ThreadName.h"
|
||||
@@ -572,14 +575,28 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_CHAR:
|
||||
// Buffer typed characters so UIScene_Keyboard can dispatch them to the Iggy Flash player
|
||||
if (wParam >= 0x20 || wParam == 0x08 || wParam == 0x0D) // printable chars + backspace + enter
|
||||
g_KBMInput.OnChar((wchar_t)wParam);
|
||||
g_KBMInput.OnChar(static_cast<wchar_t>(wParam));
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
int vk = (int)wParam;
|
||||
if (lParam & 0x40000000) break; // ignore auto-repeat
|
||||
int vk = static_cast<int>(wParam);
|
||||
if ((lParam & 0x40000000) && vk != VK_LEFT && vk != VK_RIGHT && vk != VK_BACK)
|
||||
break;
|
||||
#ifdef _WINDOWS64
|
||||
Minecraft* pm = Minecraft::GetInstance();
|
||||
ChatScreen* chat = pm && pm->screen ? dynamic_cast<ChatScreen*>(pm->screen) : nullptr;
|
||||
if (chat)
|
||||
{
|
||||
if (vk == 'V' && (GetKeyState(VK_CONTROL) & 0x8000))
|
||||
{ chat->handlePasteRequest(); break; }
|
||||
if ((vk == VK_UP || vk == VK_DOWN) && !(lParam & 0x40000000))
|
||||
{ if (vk == VK_UP) chat->handleHistoryUp(); else chat->handleHistoryDown(); break; }
|
||||
if (vk >= '1' && vk <= '9') // Prevent hotkey conflicts
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (vk == VK_SHIFT)
|
||||
vk = (MapVirtualKey((lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK_EX) == VK_RSHIFT) ? VK_RSHIFT : VK_LSHIFT;
|
||||
else if (vk == VK_CONTROL)
|
||||
@@ -592,7 +609,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
int vk = (int)wParam;
|
||||
int vk = static_cast<int>(wParam);
|
||||
if (vk == VK_SHIFT)
|
||||
vk = (MapVirtualKey((lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK_EX) == VK_RSHIFT) ? VK_RSHIFT : VK_LSHIFT;
|
||||
else if (vk == VK_CONTROL)
|
||||
@@ -1612,6 +1629,14 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
}
|
||||
}
|
||||
|
||||
// Open chat
|
||||
if (g_KBMInput.IsKeyPressed('T') && app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL)
|
||||
{
|
||||
g_KBMInput.ClearCharBuffer();
|
||||
pMinecraft->setScreen(new ChatScreen());
|
||||
SetFocus(g_hWnd);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// has the game defined profile data been changed (by a profile load)
|
||||
if(app.uiGameDefinedDataChangedBitmask!=0)
|
||||
|
||||
Reference in New Issue
Block a user