diff --git a/game/assets/patches/patch_data.txt b/game/assets/patches/patch_data.txt
index 77e902b..04cf358 100644
--- a/game/assets/patches/patch_data.txt
+++ b/game/assets/patches/patch_data.txt
@@ -13,8 +13,8 @@
# * The X and Y destination coordinates will be multiplied by 16.
# * The texture doesn't have to be 16x16, all of it will be patched on to terrain.png.
-#terrain|4|5|grass_side_transparent.png
-#grass_sides_tint|true
+terrain|4|5|grass_side_transparent.png
+grass_sides_tint|true
# Stop now to ignore the below commands. They're for a patch I'm working on that I don't want to release yet.
stop_now
diff --git a/platforms/windows/projects/Client/Client.vcxproj b/platforms/windows/projects/Client/Client.vcxproj
index 9d2fe2d..2582f9a 100644
--- a/platforms/windows/projects/Client/Client.vcxproj
+++ b/platforms/windows/projects/Client/Client.vcxproj
@@ -317,6 +317,7 @@
+
@@ -414,6 +415,7 @@
+
diff --git a/platforms/windows/projects/Client/Client.vcxproj.filters b/platforms/windows/projects/Client/Client.vcxproj.filters
index c26469b..8f32a16 100644
--- a/platforms/windows/projects/Client/Client.vcxproj.filters
+++ b/platforms/windows/projects/Client/Client.vcxproj.filters
@@ -371,6 +371,9 @@
Header Files\Renderer
+
+ Header Files\GUI\Components
+
@@ -658,5 +661,8 @@
Source Files\Renderer
+
+ Source Files\GUI\Components
+
\ No newline at end of file
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 8e8b399..438edf0 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -85,6 +85,7 @@ add_library(reminecraftpe-core STATIC
client/gui/components/TextInputBox.cpp
client/gui/components/SmallButton.cpp
client/gui/components/WorldSelectionList.cpp
+ client/gui/components/OptionList.cpp
client/gui/Gui.cpp
client/gui/GuiComponent.cpp
client/model/PolygonQuad.cpp
diff --git a/source/client/gui/components/AvailableGamesList.cpp b/source/client/gui/components/AvailableGamesList.cpp
index c770473..8d335a5 100644
--- a/source/client/gui/components/AvailableGamesList.cpp
+++ b/source/client/gui/components/AvailableGamesList.cpp
@@ -23,7 +23,7 @@ bool AvailableGamesList::isSelectedItem(int i)
return m_selectedIndex == i;
}
-void AvailableGamesList::renderBackground()
+void AvailableGamesList::renderBackground(float f)
{
}
diff --git a/source/client/gui/components/AvailableGamesList.hpp b/source/client/gui/components/AvailableGamesList.hpp
index 682e236..c803241 100644
--- a/source/client/gui/components/AvailableGamesList.hpp
+++ b/source/client/gui/components/AvailableGamesList.hpp
@@ -17,7 +17,7 @@ public:
AvailableGamesList(Minecraft*, int, int, int, int, int);
int getNumberOfItems() override;
bool isSelectedItem(int i) override;
- void renderBackground() override;
+ void renderBackground(float f) override;
void renderItem(int, int, int, int, Tesselator& t) override;
void selectItem(int, bool) override;
diff --git a/source/client/gui/components/OptionList.cpp b/source/client/gui/components/OptionList.cpp
new file mode 100644
index 0000000..f67003b
--- /dev/null
+++ b/source/client/gui/components/OptionList.cpp
@@ -0,0 +1,347 @@
+/********************************************************************
+ Minecraft: Pocket Edition - Decompilation Project
+ Copyright (C) 2023 iProgramInCpp
+
+ The following code is licensed under the BSD 1 clause license.
+ SPDX-License-Identifier: BSD-1-Clause
+ ********************************************************************/
+
+#include "OptionList.hpp"
+#include "client/options/Options.hpp"
+#include "client/renderer/PatchManager.hpp"
+#include "client/renderer/FoliageColor.hpp"
+#include "client/renderer/GrassColor.hpp"
+
+#define C_OPTION_ITEM_HEIGHT (18)
+
+#define C_ON_OFF_SWITCH_WIDTH (28)
+#define C_ON_OFF_SWITCH_HEIGHT (16)
+
+#define C_DISTANCE_SWITCH_WIDTH (60)
+#define C_DISTANCE_SWITCH_HEIGHT (16)
+
+BooleanOptionItem::BooleanOptionItem(bool* pValue, const std::string& text)
+{
+ m_text = text;
+ m_pValue = pValue;
+}
+
+void BooleanOptionItem::onClick(OptionList* pList, int mouseX, int mouseY)
+{
+ if (m_bDisabled)
+ return;
+
+ int itemX = pList->field_18 / 2 - (C_SCROLLED_LIST_ITEM_WIDTH - 4) / 2;
+
+ if (mouseX <= itemX + C_SCROLLED_LIST_ITEM_WIDTH - C_ON_OFF_SWITCH_WIDTH - 6)
+ return;
+
+ // Toggle the value
+ toggleState(pList);
+}
+
+void BooleanOptionItem::render(OptionList* pList, int x, int y)
+{
+ pList->drawString(
+ pList->m_pMinecraft->m_pFont,
+ m_text,
+ x + 22,
+ y + (C_OPTION_ITEM_HEIGHT - 8) / 2 - 2,
+ m_bDisabled ? 0x777777 : 0xCCCCCC);
+
+ pList->drawOnOffSwitch(
+ x + C_SCROLLED_LIST_ITEM_WIDTH - C_ON_OFF_SWITCH_WIDTH - 6,
+ y + (C_OPTION_ITEM_HEIGHT - C_ON_OFF_SWITCH_HEIGHT) / 2 - 2,
+ *m_pValue,
+ m_bDisabled);
+}
+
+void BooleanOptionItem::toggleState(OptionList* pList)
+{
+ *m_pValue ^= 1;
+}
+
+RenderOptionItem::RenderOptionItem(bool* pValue, const std::string& text) :
+ BooleanOptionItem(pValue, text)
+{
+}
+
+void RenderOptionItem::toggleState(OptionList* pList)
+{
+ BooleanOptionItem::toggleState(pList);
+ pList->m_pMinecraft->m_pLevelRenderer->allChanged();
+}
+
+
+AORenderOptionItem::AORenderOptionItem(bool* pValue, const std::string& text) :
+ RenderOptionItem(pValue, text)
+{
+}
+
+void AORenderOptionItem::toggleState(OptionList* pList)
+{
+ BooleanOptionItem::toggleState(pList);
+ Minecraft::useAmbientOcclusion = *m_pValue;
+ pList->m_pMinecraft->m_pLevelRenderer->allChanged();
+}
+
+HeaderOptionItem::HeaderOptionItem(const std::string& text)
+{
+ m_text = text;
+}
+
+void HeaderOptionItem::render(OptionList* pList, int x, int y)
+{
+ pList->drawString(
+ pList->m_pMinecraft->m_pFont,
+ m_text,
+ x + 2,
+ y + (C_OPTION_ITEM_HEIGHT - 8) / 2 - 2,
+ 0xFFFFFF);
+}
+
+DistanceOptionItem::DistanceOptionItem(int* pValue, const std::string& text)
+{
+ m_text = text;
+ m_pValue = pValue;
+}
+
+void DistanceOptionItem::onClick(OptionList* pList, int mouseX, int mouseY)
+{
+ int itemX = pList->field_18 / 2 - (C_SCROLLED_LIST_ITEM_WIDTH - 4) / 2;
+
+ if (mouseX <= itemX + C_SCROLLED_LIST_ITEM_WIDTH - C_DISTANCE_SWITCH_WIDTH - 6)
+ return;
+
+ int oldValue = *m_pValue;
+ *m_pValue = (oldValue + 1) % RD_COUNT;
+
+ // If the old render distance was bigger than the current one
+ if (oldValue < *m_pValue)
+ pList->m_pMinecraft->m_pLevelRenderer->allChanged();
+}
+
+void DistanceOptionItem::render(OptionList* pList, int x, int y)
+{
+ pList->drawString(
+ pList->m_pMinecraft->m_pFont,
+ m_text,
+ x + 22,
+ y + (C_OPTION_ITEM_HEIGHT - 8) / 2 - 2,
+ 0xCCCCCC);
+
+ const char* distanceText = "???";
+ switch (*m_pValue)
+ {
+ case RD_EXTREME: distanceText = "EXTREME"; break;
+ case RD_FAR: distanceText = "FAR"; break;
+ case RD_NORMAL: distanceText = "NORMAL"; break;
+ case RD_SHORT: distanceText = "SHORT"; break;
+ }
+
+ std::string distanceTextStr(distanceText);
+
+ x += C_SCROLLED_LIST_ITEM_WIDTH - C_DISTANCE_SWITCH_WIDTH - 6;
+ y += (C_OPTION_ITEM_HEIGHT - C_DISTANCE_SWITCH_HEIGHT) / 2 - 2;
+
+ pList->fill(x + 0, y + 0, x + C_DISTANCE_SWITCH_WIDTH - 0, y + C_DISTANCE_SWITCH_HEIGHT - 0, 0xFF444444);
+ pList->fill(x + 1, y + 1, x + C_DISTANCE_SWITCH_WIDTH - 1, y + C_DISTANCE_SWITCH_HEIGHT - 1, 0xFF111111);
+ pList->drawCenteredString(
+ pList->m_pMinecraft->m_pFont,
+ distanceTextStr,
+ x + C_DISTANCE_SWITCH_WIDTH / 2,
+ y + (C_DISTANCE_SWITCH_HEIGHT - 8) / 2,
+ 0xFFFFFF
+ );
+}
+
+OptionList::OptionList(Minecraft* pMinecraft, int width, int height, int something, int something2) :
+ ScrolledSelectionList(pMinecraft, width, height, something, something2, C_OPTION_ITEM_HEIGHT)
+{
+ m_selectedItem = -1;
+}
+
+OptionList::~OptionList()
+{
+ clear();
+}
+
+int OptionList::getNumberOfItems()
+{
+ return int (m_items.size());
+}
+
+// b appears to be unused
+void OptionList::selectItem(int index, bool b)
+{
+ if (index >= 0 && index < getNumberOfItems())
+ {
+ if (!m_items[index]->maySelect())
+ return;
+ }
+
+ m_selectedItem = index;
+}
+
+bool OptionList::isSelectedItem(int index)
+{
+ return m_selectedItem == index;
+}
+
+void OptionList::drawOnOffSwitch(int x, int y, bool state, bool disabled)
+{
+ // Draws a simplistic On/Off switch.
+
+ uint32_t
+ edgeColor = 0xFF444444,
+ backdropEnabled = 0xFFAAAAAA,
+ backdropDisabled = 0xFF333333,
+ leverOn = 0xFFFFFFFF,
+ leverOff = 0xFF888888;
+
+ if (disabled)
+ {
+ edgeColor = 0xFF222222;
+ backdropEnabled = 0xFF555555;
+ backdropDisabled = 0xFF191919,
+ leverOn = 0xFF7F7F7F,
+ leverOff = 0xFF444444;
+ }
+
+ // Draw edges
+ fill(x + 0, y + 0, x + C_ON_OFF_SWITCH_WIDTH - 0, y + C_ON_OFF_SWITCH_HEIGHT - 0, edgeColor);
+
+ // Draw backdrop
+ fill(x + 1, y + 1, x + C_ON_OFF_SWITCH_WIDTH - 1, y + C_ON_OFF_SWITCH_HEIGHT - 1, state ? backdropEnabled : backdropDisabled);
+
+ if (state)
+ // Draw ON position
+ fill(x + C_ON_OFF_SWITCH_WIDTH / 2 + 2, y + 1, x + C_ON_OFF_SWITCH_WIDTH - 1, y + C_ON_OFF_SWITCH_HEIGHT - 1, leverOn);
+ else
+ // Draw OFF position
+ fill(x + 1, y + 1, x + C_ON_OFF_SWITCH_WIDTH / 2 - 2, y + C_ON_OFF_SWITCH_HEIGHT - 1, leverOff);
+}
+
+void OptionList::renderItem(int index, int x, int y, int height, Tesselator& t)
+{
+ Font* f = m_pMinecraft->m_pFont;
+ OptionItem* pItem = m_items[index];
+
+ pItem->render(this, x, y);
+}
+
+void OptionList::renderBackground(float f)
+{
+ if (!m_pMinecraft->isLevelGenerated())
+ m_pMinecraft->m_pScreen->renderMenuBackground(f);
+}
+
+void OptionList::renderHoleBackground(float a, float b, int c, int d)
+{
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_TEXTURE_2D);
+
+ Tesselator& t = Tesselator::instance;
+ t.begin();
+ t.color(0x202020, 0xC0);
+ t.vertexUV(0.0f, b, 0.0f, 0.0f, b / 32.0f);
+ t.vertexUV(float(field_18), b, 0.0f, field_18 / 32.0f, b / 32.0f);
+ t.vertexUV(float(field_18), a, 0.0f, field_18 / 32.0f, a / 32.0f);
+ t.vertexUV(0.0f, a, 0.0f, 0.0f, a / 32.0f);
+ t.draw();
+
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+}
+
+void OptionList::renderScrollBackground()
+{
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_TEXTURE_2D);
+
+ Tesselator& t = Tesselator::instance;
+ t.begin();
+ t.color(0x202020, 0x90);
+ t.vertexUV(field_24, field_10, 0.0f, field_24 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
+ t.vertexUV(field_20, field_10, 0.0f, field_20 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
+ t.vertexUV(field_20, field_C, 0.0f, field_20 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
+ t.vertexUV(field_24, field_C, 0.0f, field_24 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
+ t.draw();
+
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+}
+
+void OptionList::onClickItem(int index, int mouseX, int mouseY)
+{
+ if (index >= getNumberOfItems())
+ index = -1;
+
+ selectItem(index, false);
+
+ if (index >= 0)
+ m_items[index]->onClick(this, mouseX, mouseY);
+}
+
+void OptionList::clear()
+{
+ for (std::vector::iterator iter = m_items.begin();
+ iter != m_items.end();
+ ++iter)
+ {
+ delete (*iter);
+ }
+
+ m_items.clear();
+}
+
+void OptionList::initDefaultMenu()
+{
+ Options* pOptions = m_pMinecraft->getOptions();
+
+ int currentIndex = -1;
+
+#define HEADER(text) do { m_items.push_back(new HeaderOptionItem(text)); currentIndex++; } while (0)
+#define OPTION(type, name, text) do { m_items.push_back(new type ## OptionItem(&pOptions->name, text)); currentIndex++; } while (0)
+
+ int idxLM = -1;
+ int idxGrass = -1, idxBiome = -1;
+
+ HEADER("Video");
+ {
+ OPTION(Distance, m_iViewDistance, "View distance");
+ OPTION(AORender, m_bAmbientOcclusion, "Smooth lighting");
+ OPTION(Render, m_bFancyGraphics, "Fancy graphics");
+ OPTION(Boolean, m_bAnaglyphs, "3d Anaglyphs");
+ OPTION(Boolean, m_bDebugText, "Debug text");
+ OPTION(Boolean, m_bFlyCheat, "Flight hax");
+ OPTION(Boolean, m_bDontRenderGui, "Hide GUI");
+ OPTION(Boolean, m_bBlockOutlines, "Block outlines");
+ OPTION(Boolean, m_bViewBobbing, "View bobbing");
+ OPTION(Render, m_bFancyGrass, "Fancy grass"); idxGrass = currentIndex; // renders colored grass side overlay
+ OPTION(Render, m_bBiomeColors, "Biome colors"); idxBiome = currentIndex; // colors the grass based on the current biome
+ }
+
+ HEADER("Controls");
+ {
+ OPTION(Boolean, m_bAutoJump, "Auto jump");
+ OPTION(Boolean, m_bInvertMouse, "Invert Y-axis");
+ }
+
+ HEADER("Multiplayer");
+ {
+ OPTION(Boolean, m_bServerVisibleDefault, "Local server multiplayer"); idxLM = currentIndex;
+ }
+
+#ifdef __EMSCRIPTEN
+ m_items[idxLM]->setDisabled(true);
+#endif
+
+ if (!GetPatchManager()->IsGrassSidesTinted())
+ m_items[idxGrass]->setDisabled(true);
+
+ if (!GrassColor::isAvailable() || !FoliageColor::isAvailable())
+ m_items[idxBiome]->setDisabled(true);
+}
diff --git a/source/client/gui/components/OptionList.hpp b/source/client/gui/components/OptionList.hpp
new file mode 100644
index 0000000..0c95573
--- /dev/null
+++ b/source/client/gui/components/OptionList.hpp
@@ -0,0 +1,118 @@
+/********************************************************************
+ Minecraft: Pocket Edition - Decompilation Project
+ Copyright (C) 2023 iProgramInCpp
+
+ The following code is licensed under the BSD 1 clause license.
+ SPDX-License-Identifier: BSD-1-Clause
+ ********************************************************************/
+
+#pragma once
+
+#include "ScrolledSelectionList.hpp"
+
+class Options;
+class OptionList;
+
+// Abstract class - actual options will inherit from it
+class OptionItem
+{
+public:
+ OptionItem() {}
+ virtual ~OptionItem() {}
+ virtual void onClick(OptionList*, int mouseX, int mouseY) = 0;
+ virtual void render(OptionList*, int x, int y) = 0;
+ virtual bool maySelect() { return true; }
+ virtual void setDisabled(bool b) { };
+};
+
+class BooleanOptionItem : public OptionItem
+{
+public:
+ BooleanOptionItem(bool* pValue, const std::string& text);
+ void onClick(OptionList*, int mouseX, int mouseY) override;
+ void render(OptionList*, int x, int y) override;
+ void setDisabled(bool b) override { m_bDisabled = b; }
+
+ virtual void toggleState(OptionList*);
+
+protected:
+ friend class AORenderOptionItem;
+
+ std::string m_text;
+ bool* m_pValue; // Reference to the value to be modified by this item
+ bool m_bDisabled;
+};
+
+// An option item that controls the view distance.
+class DistanceOptionItem : public OptionItem
+{
+ enum
+ {
+ RD_EXTREME,
+ RD_FAR,
+ RD_NORMAL,
+ RD_SHORT,
+ RD_COUNT,
+ };
+
+public:
+ DistanceOptionItem(int* pValue, const std::string& text);
+ void onClick(OptionList*, int mouseX, int mouseY) override;
+ void render(OptionList*, int x, int y) override;
+
+protected:
+ std::string m_text;
+ int* m_pValue; // Reference to the value to be modified by this item
+};
+
+class RenderOptionItem : public BooleanOptionItem
+{
+public:
+ RenderOptionItem(bool* pValue, const std::string& text);
+ void toggleState(OptionList*) override;
+};
+
+class AORenderOptionItem : public RenderOptionItem
+{
+public:
+ AORenderOptionItem(bool* pValue, const std::string& text);
+ void toggleState(OptionList*) override;
+};
+
+class HeaderOptionItem : public OptionItem
+{
+public:
+ HeaderOptionItem(const std::string& text);
+ void render(OptionList*, int x, int y) override;
+ bool maySelect() override { return false; }
+ void onClick(OptionList*, int mouseX, int mouseY) {}
+
+private:
+ std::string m_text;
+};
+
+class OptionList : public ScrolledSelectionList
+{
+public:
+ OptionList(Minecraft*, int, int, int, int);
+ ~OptionList();
+
+ // Inherited from ScrolledSelectionList
+ int getNumberOfItems() override;
+ void selectItem(int, bool) override;
+ bool isSelectedItem(int) override;
+ void renderItem(int, int, int, int, Tesselator&) override;
+ void renderBackground(float) override;
+ void renderHoleBackground(float, float, int, int) override;
+ void onClickItem(int index, int mouseX, int mouseY) override;
+ void renderScrollBackground() override;
+
+ void clear();
+ void initDefaultMenu();
+ void drawOnOffSwitch(int x, int y, bool state, bool disabled = false);
+
+private:
+ int m_selectedItem;
+ std::vector m_items;
+};
+
diff --git a/source/client/gui/components/ScrolledSelectionList.cpp b/source/client/gui/components/ScrolledSelectionList.cpp
index bcb053f..1267623 100644
--- a/source/client/gui/components/ScrolledSelectionList.cpp
+++ b/source/client/gui/components/ScrolledSelectionList.cpp
@@ -6,9 +6,11 @@
SPDX-License-Identifier: BSD-1-Clause
********************************************************************/
+// @TODO: Add keyboard based control
+
#include "ScrolledSelectionList.hpp"
-#define C_ITEM_WIDTH (220)
+#define C_ITEM_WIDTH C_SCROLLED_LIST_ITEM_WIDTH
ScrolledSelectionList::ScrolledSelectionList(Minecraft* minecraft, int a3, int a4, int a5, int a6, int a7) :
m_pMinecraft(minecraft),
@@ -76,14 +78,29 @@ void ScrolledSelectionList::capYPosition()
field_34 = maxY;
}
-void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
+void ScrolledSelectionList::onClickItem(int index, int mouseX, int mouseY)
{
- renderBackground();
+ selectItem(index, false);
+}
+void ScrolledSelectionList::renderScrollBackground()
+{
+ Tesselator& t = Tesselator::instance;
+ t.begin();
+ t.color(0x202020);
+ t.vertexUV(field_24, field_10, 0.0f, field_24 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
+ t.vertexUV(field_20, field_10, 0.0f, field_20 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
+ t.vertexUV(field_20, field_C, 0.0f, field_20 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
+ t.vertexUV(field_24, field_C, 0.0f, field_24 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
+ t.draw();
+}
+
+void ScrolledSelectionList::checkInput(int mouseX, int mouseY)
+{
int nItems = getNumberOfItems();
if (Mouse::isButtonDown(BUTTON_LEFT))
{
- if (float(mouseY) >= field_C && float(mouseY) <= field_10 && mouseY != field_28)
+ if (float(mouseY) >= field_C && float(mouseY) <= field_10 && abs(mouseY - field_28) > 5)
{
int field_2C_old = field_2C;
@@ -120,7 +137,7 @@ void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
{
if (transformY(mouseY) / m_itemHeight >= 0 && m_itemHeight > abs(field_3C - mouseY))
{
- selectItem(transformY(mouseY) / m_itemHeight, false);
+ onClickItem(transformY(mouseY) / m_itemHeight, mouseX, mouseY);
field_38 = 0.0f;
}
}
@@ -129,6 +146,16 @@ void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
field_2C = -1;
field_34 -= field_38;
}
+}
+
+void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
+{
+ renderBackground(f);
+
+ int nItems = getNumberOfItems();
+ Tesselator& t = Tesselator::instance;
+
+ checkInput(mouseX, mouseY);
field_30 = float(mouseY);
field_38 *= 0.75f;
@@ -140,14 +167,7 @@ void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- Tesselator& t = Tesselator::instance;
- t.begin();
- t.color(0x202020);
- t.vertexUV(field_24, field_10, 0.0f, field_24 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
- t.vertexUV(field_20, field_10, 0.0f, field_20 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
- t.vertexUV(field_20, field_C, 0.0f, field_20 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
- t.vertexUV(field_24, field_C, 0.0f, field_24 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
- t.draw();
+ renderScrollBackground();
int itemX = field_18 / 2 - (C_ITEM_WIDTH - 4) / 2;
int scrollY = int(field_C + 4 - float(int(field_34)));
@@ -155,6 +175,12 @@ void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
if (field_45)
renderHeader(itemX, scrollY, t);
+ // Note, X/Y are the lower left's X/Y coordinates, not the upper left's.
+ int lowerY = Minecraft::height - int(field_10 / Gui::InvGuiScale);
+ int upperY = Minecraft::height - int(field_C / Gui::InvGuiScale);
+ glScissor(0, lowerY, Minecraft::width, upperY - lowerY);
+ glEnable(GL_SCISSOR_TEST);
+
for (int i = 0; i < nItems; i++)
{
float itemY = float(field_48 + scrollY + i * m_itemHeight);
@@ -187,6 +213,7 @@ void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
renderItem(i, itemX, int(itemY), int(m_itemHeight - 4.0f), t);
}
+ glDisable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
renderHoleBackground(0.0f, field_C, 255, 255);
diff --git a/source/client/gui/components/ScrolledSelectionList.hpp b/source/client/gui/components/ScrolledSelectionList.hpp
index bc24481..3c97986 100644
--- a/source/client/gui/components/ScrolledSelectionList.hpp
+++ b/source/client/gui/components/ScrolledSelectionList.hpp
@@ -11,6 +11,8 @@
#include "../GuiComponent.hpp"
#include "client/app/Minecraft.hpp"
+#define C_SCROLLED_LIST_ITEM_WIDTH (220)
+
class ScrolledSelectionList : public GuiComponent
{
public:
@@ -24,17 +26,19 @@ public:
virtual int getMaxPosition();
virtual void renderItem(int, int, int, int, Tesselator&) = 0;
virtual void renderHeader(int, int, Tesselator&);
- virtual void renderBackground() = 0;
+ virtual void renderBackground(float) = 0;
virtual void renderDecorations(int, int);
virtual void clickedHeader(int x, int y);
virtual int getItemAtPosition(int x, int y);
virtual void capYPosition();
virtual void render(int mouseX, int mouseY, float f);
virtual void renderHoleBackground(float, float, int, int);
+ virtual void checkInput(int mouseX, int mouseY);
+ virtual void onClickItem(int index, int mouseX, int mouseY);
+ virtual void renderScrollBackground();
void setRenderHeader(bool, int);
-
// @NOTE: This is inlined.
inline int getItemAtYPositionRaw(int y)
{
diff --git a/source/client/gui/screens/OptionsScreen.cpp b/source/client/gui/screens/OptionsScreen.cpp
index 7fc5190..23928c8 100644
--- a/source/client/gui/screens/OptionsScreen.cpp
+++ b/source/client/gui/screens/OptionsScreen.cpp
@@ -10,6 +10,67 @@
#include "StartMenuScreen.hpp"
#include "PauseScreen.hpp"
+#ifndef OLD_OPTIONS_SCREEN
+
+OptionsScreen::OptionsScreen() :
+ m_backButton(100, "Done")
+{
+}
+
+OptionsScreen::~OptionsScreen()
+{
+ SAFE_DELETE(m_pList);
+}
+
+void OptionsScreen::init()
+{
+ if (m_pList)
+ SAFE_DELETE(m_pList);
+
+ m_pList = new OptionList(m_pMinecraft, m_width, m_height, 28, m_height - 28);
+ m_pList->initDefaultMenu();
+
+ m_backButton.m_width = 100;
+ m_backButton.m_height = 20;
+
+ m_backButton.m_xPos = (m_width - m_backButton.m_width) / 2;
+ m_backButton.m_yPos = m_height - m_backButton.m_height - (28 - m_backButton.m_height) / 2;
+
+ m_buttons.push_back(&m_backButton);
+ m_buttonTabList.push_back(&m_backButton);
+}
+
+void OptionsScreen::render(int mouseX, int mouseY, float f)
+{
+ if (!m_pList)
+ return;
+
+ m_pList->render(mouseX, mouseY, f);
+
+ Screen::render(mouseX, mouseY, f);
+
+ drawCenteredString(m_pFont, "Options", m_width / 2, 10, 0xFFFFFF);
+}
+
+void OptionsScreen::removed()
+{
+
+}
+
+void OptionsScreen::buttonClicked(Button* pButton)
+{
+ if (pButton->m_buttonId == 100)
+ {
+ if (m_pMinecraft->isLevelGenerated())
+ m_pMinecraft->setScreen(new PauseScreen);
+ else
+ m_pMinecraft->setScreen(new StartMenuScreen);
+ }
+}
+
+
+#else
+
#include "client/renderer/PatchManager.hpp"
#include "client/renderer/GrassColor.hpp"
#include "client/renderer/FoliageColor.hpp"
@@ -99,7 +160,7 @@ void OptionsScreen::updateTexts()
{
m_fancyGrassButton.m_bEnabled = false;
}
- if (!GrassColor::isAvailable() && !FoliageColor::isAvailable())
+ if (!GrassColor::isAvailable() || !FoliageColor::isAvailable())
{
m_biomeColorsButton.m_bEnabled = false;
}
@@ -310,3 +371,5 @@ void OptionsScreen::buttonClicked(Button* pButton)
}
#endif
+
+#endif
diff --git a/source/client/gui/screens/OptionsScreen.hpp b/source/client/gui/screens/OptionsScreen.hpp
index 730439a..023dc7d 100644
--- a/source/client/gui/screens/OptionsScreen.hpp
+++ b/source/client/gui/screens/OptionsScreen.hpp
@@ -10,6 +10,28 @@
#include "../Screen.hpp"
+#ifndef OLD_OPTIONS_SCREEN
+
+#include "../components/OptionList.hpp"
+
+class OptionsScreen : public Screen
+{
+public:
+ OptionsScreen();
+ ~OptionsScreen();
+ void init() override;
+ void render(int, int, float) override;
+ void removed() override;
+ void buttonClicked(Button* pButton) override;
+
+private:
+ OptionList* m_pList;
+
+ Button m_backButton;
+};
+
+#else
+
class OptionsScreen : public Screen
{
public:
@@ -42,3 +64,4 @@ private:
#endif
};
+#endif
diff --git a/source/common/Utils.hpp b/source/common/Utils.hpp
index 5b0a12b..b7dbbac 100644
--- a/source/common/Utils.hpp
+++ b/source/common/Utils.hpp
@@ -38,6 +38,10 @@
#endif
#endif
+#ifdef _MSC_VER
+#pragma warning (disable : 4068)
+#endif
+
#if defined(_WIN32)
#ifndef _XBOX // assume we're on a normal Windows device
diff --git a/source/world/entity/Player.hpp b/source/world/entity/Player.hpp
index 9910fc0..99a741a 100644
--- a/source/world/entity/Player.hpp
+++ b/source/world/entity/Player.hpp
@@ -8,6 +8,7 @@
#pragma once
+#include "common/Utils.hpp"
#include "thirdparty/raknet/RakNetTypes.h"
#include "world/item/Inventory.hpp"
#include "world/entity/Mob.hpp"
diff --git a/source/world/level/Level.cpp b/source/world/level/Level.cpp
index 7cee7b4..9ffb2f2 100644
--- a/source/world/level/Level.cpp
+++ b/source/world/level/Level.cpp
@@ -467,7 +467,7 @@ void Level::updateLight(const LightLayer& ll, int a, int b, int c, int d, int e,
{
static int nUpdateLevels;
- if ((m_pDimension->field_E && &ll == &LightLayer::Sky) || !m_bUpdateLights)
+ if ((m_pDimension->field_E && &ll == &LightLayer::Sky) || !m_bUpdateLights)
return;
nUpdateLevels++;