* Initial commit.

:)
This commit is contained in:
iProgramInCpp
2023-07-30 22:22:02 +03:00
commit 9642818a88
613 changed files with 151754 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
#include "ChatScreen.hpp"
// @NOTE: This is unused.
void ChatScreen::buttonClicked(Button* pButton)
{
}
void ChatScreen::init()
{
m_pMinecraft->platform()->showDialog(AppPlatform::DLG_CHAT);
m_pMinecraft->platform()->createUserInput();
}
void ChatScreen::render(int mouseX, int mouseY, float f)
{
int userInputStatus = m_pMinecraft->platform()->getUserInputStatus();
if (userInputStatus < 0)
return;
if (userInputStatus == 1)
{
std::vector<std::string> userInput = m_pMinecraft->platform()->getUserInput();
if (userInput.size() >= 1)
{
// @NOTE: No sending multiplayer chats. Weird
m_pMinecraft->m_gui.addMessage(userInput[0]);
}
}
m_pMinecraft->setScreen(nullptr);
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Screen.hpp"
class ChatScreen : public Screen
{
public:
void buttonClicked(Button*) override;
void init() override;
void render(int mouseX, int mouseY, float f) override;
};

View File

@@ -0,0 +1,67 @@
#include "ConfirmScreen.hpp"
ConfirmScreen::ConfirmScreen(Screen* pScreen, const std::string& line1, const std::string& line2, int x) :
m_btnOK (0, 0, 0, "Ok"),
m_btnCancel(1, 0, 0, "Cancel"),
m_textLine1(line1),
m_textLine2(line2),
m_pScreen(pScreen),
field_40(x)
{
}
ConfirmScreen::ConfirmScreen(Screen* pScreen, const std::string& line1, const std::string& line2, const std::string& ok, const std::string& cancel, int x) :
m_btnOK (0, 0, 0, ok),
m_btnCancel(1, 0, 0, cancel),
m_textLine1(line1),
m_textLine2(line2),
m_pScreen(pScreen),
field_40(x)
{
}
// @NOTE: potential memory leak if pScreen is set and not destroyed!
void ConfirmScreen::buttonClicked(Button* pButton)
{
postResult(pButton->field_30 == 0);
}
bool ConfirmScreen::handleBackEvent(bool b)
{
if (!b)
postResult(false);
return true;
}
void ConfirmScreen::init()
{
m_btnOK.m_xPos = m_width / 2 - 4 - 120;
m_btnCancel.m_xPos = m_width / 2 + 4;
m_btnCancel.m_yPos = m_btnOK.m_yPos = m_height / 6 + 72;
m_btnOK.m_width = m_btnCancel.m_width = 120;
m_btnOK.m_height = m_btnCancel.m_height = 24;
m_buttons.push_back(&m_btnOK);
m_buttons.push_back(&m_btnCancel);
m_buttonTabList.push_back(&m_btnOK);
m_buttonTabList.push_back(&m_btnCancel);
}
void ConfirmScreen::render(int mouseX, int mouseY, float f)
{
renderBackground();
drawCenteredString(m_pFont, m_textLine1, m_width / 2, 50, 0xFFFFFF);
drawCenteredString(m_pFont, m_textLine2, m_width / 2, 70, 0xFFFFFF);
Screen::render(mouseX, mouseY, f);
}
void ConfirmScreen::postResult(bool b)
{
m_pScreen->confirmResult(b, field_40);
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include "Screen.hpp"
#include "SmallButton.hpp"
class ConfirmScreen : public Screen
{
public:
ConfirmScreen(Screen* pScreen, const std::string& line1, const std::string& line2, int x);
ConfirmScreen(Screen* pScreen, const std::string& line1, const std::string& line2, const std::string& ok, const std::string& cancel, int x);
void buttonClicked(Button* pButton) override;
bool handleBackEvent(bool b) override;
void init() override;
void render(int mouseX, int mouseY, float f) override;
virtual void postResult(bool b);
private:
Screen* m_pScreen = nullptr;
int field_40 = 0;
std::string m_textLine1;
std::string m_textLine2;
SmallButton m_btnOK;
SmallButton m_btnCancel;
};

View File

@@ -0,0 +1,23 @@
#include "DeleteWorldScreen.hpp"
#include "SelectWorldScreen.hpp"
DeleteWorldScreen::DeleteWorldScreen(const LevelSummary& level) :
ConfirmScreen(nullptr,
"Are you sure you want to delete this world?",
"'" + level.field_18 + "' will be lost forever!",
"Delete", "Cancel", 0),
m_level(level)
{
// highlight the cancel button so the user will have to do 1 extra action to delete their world
m_tabButtonIndex = 1;
}
void DeleteWorldScreen::postResult(bool b)
{
if (b)
{
m_pMinecraft->getLevelSource()->deleteLevel(m_level.field_0);
}
m_pMinecraft->setScreen(new SelectWorldScreen);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "ConfirmScreen.hpp"
class DeleteWorldScreen : public ConfirmScreen
{
public:
DeleteWorldScreen(const LevelSummary& level);
void postResult(bool b) override;
private:
LevelSummary m_level;
};

View File

@@ -0,0 +1,186 @@
#include "IngameBlockSelectionScreen.hpp"
#include "ItemRenderer.hpp"
#define C_SLOTS_HEIGHT ((C_MAX_INVENTORY_ITEMS + 8) / 9)
std::string g_sNotAvailableInDemoVersion = "Not available in the demo version";
int IngameBlockSelectionScreen::getSelectedSlot(int x, int y)
{
int bottom = m_height - 151;
int left = m_width / 2 - 87;
if (y < bottom)
return -1;
if (x < left)
return -1;
int idx = (x - left) / 20;
if (idx > 8)
return -1;
return idx + 36 - 9 * ((y - bottom) / 22);
}
int IngameBlockSelectionScreen::getSlotPosX(int x)
{
return m_width / 2 - 88 + 20 * x;
}
int IngameBlockSelectionScreen::getSlotPosY(int y)
{
return m_height - 63 - 22 * y;
}
bool IngameBlockSelectionScreen::isAllowed(int slot)
{
if (slot < 0 || slot > C_MAX_INVENTORY_ITEMS-1)
return false;
#ifdef DEMO
return slot > 17;
#endif
return true;
}
void IngameBlockSelectionScreen::init()
{
Inventory* pInv = m_pMinecraft->m_pLocalPlayer->m_pInventory;
for (int i = 9; i < C_MAX_HOTBAR_ITEMS + C_MAX_INVENTORY_ITEMS; i++)
{
if (pInv->getSelectionSlotItemId(i) == pInv->getSelectedItemId())
{
m_selectedSlot = i - 9;
break;
}
}
if (!isAllowed(m_selectedSlot))
m_selectedSlot = 27;
}
void IngameBlockSelectionScreen::renderSlot(int index, int x, int y, float f)
{
int item = m_pMinecraft->m_pLocalPlayer->m_pInventory->getSelectionSlotItemId(index);
if (item < 0)
return;
ItemInstance inst(item, 2, 0);
ItemRenderer::renderGuiItem(m_pMinecraft->m_pFont, m_pMinecraft->m_pTextures, &inst, x, y, item);
}
void IngameBlockSelectionScreen::renderSlots()
{
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/gui.png");
for (int y = 0; y != -22 * C_SLOTS_HEIGHT; y -= 22)
blit(m_width / 2 - 182 / 2, m_height - 66 + y, 0, 0, 182, 22, 0, 0);
if (m_selectedSlot >= 0)
blit(m_width / 2 - 92 + 20 * (m_selectedSlot % 9), m_height - 67 - 22 * (m_selectedSlot / 9), 0, 22, 24, 22, 0, 0);
for (int y = 0, index = 9; y < C_SLOTS_HEIGHT; y++)
{
int posY = getSlotPosY(y);
for (int x = 0; x < 9; x++)
{
int posX = getSlotPosX(x);
renderSlot(index++, posX, posY, 0.0f);
}
}
}
void IngameBlockSelectionScreen::renderDemoOverlay()
{
fill(getSlotPosX(0) - 3, getSlotPosY(1) - 3, getSlotPosX(9), getSlotPosY(-1), 0xA0000000);
int x = (getSlotPosX(4) + getSlotPosX(5)) / 2;
int y = (getSlotPosY(0) + getSlotPosY(1)) / 2 + 5;
drawCenteredString(m_pMinecraft->m_pFont, g_sNotAvailableInDemoVersion, x, y, 0xFFFFFFFF);
}
void IngameBlockSelectionScreen::render(int x, int y, float f)
{
Screen::render(x, y, f);
glDisable(GL_DEPTH_TEST);
fill(0, 0, m_width, m_height, 0x80000000);
glEnable(GL_BLEND);
renderSlots();
#ifdef DEMO
renderDemoOverlay();
#endif
glEnable(GL_DEPTH_TEST);
}
void IngameBlockSelectionScreen::mouseClicked(int x, int y, int type)
{
// not a left click
if (type != 1)
return;
int slot = getSelectedSlot(x, y);
if (isAllowed(slot))
m_selectedSlot = slot;
}
void IngameBlockSelectionScreen::mouseReleased(int x, int y, int type)
{
// not a left click
if (type != 1)
return;
int slot = getSelectedSlot(x, y);
if (isAllowed(slot) && slot == m_selectedSlot)
selectSlotAndClose();
}
void IngameBlockSelectionScreen::selectSlotAndClose()
{
Inventory* pInv = m_pMinecraft->m_pLocalPlayer->m_pInventory;
int item = pInv->getSelectionSlotItemId(m_selectedSlot + 9);
int idx = 0;
// @TODO: Fix gotos
#ifdef ENH_ENABLE_9TH_SLOT
#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 1)
#else
#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 2)
#endif
if (item == pInv->getSelectionSlotItemId(0))
{
label_4:
if (!idx)
goto label_5;
}
else while (++idx != MAX_ITEMS)
{
if (item == pInv->getSelectionSlotItemId(idx))
goto label_4;
}
while (true)
{
int item = pInv->getSelectionSlotItemId(idx - 1);
pInv->setSelectionSlotItemId(idx, item);
if (idx == 1)
break;
--idx;
}
label_5:
pInv->setSelectionSlotItemId(0, item);
pInv->selectSlot(0);
// @TODO: SoundEngine
m_pMinecraft->setScreen(nullptr);
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Screen.hpp"
class IngameBlockSelectionScreen : public Screen
{
public:
int getSelectedSlot(int x, int y);
int getSlotPosX(int x);
int getSlotPosY(int y);
bool isAllowed(int slot);
void renderSlots();
void renderDemoOverlay();
void renderSlot(int index, int x, int y, float f);
void selectSlotAndClose();
virtual void init() override;
virtual void render(int x, int y, float f) override;
virtual void mouseClicked(int x, int y, int type) override;
virtual void mouseReleased(int x, int y, int type) override;
private:
int m_selectedSlot = 0;
};

View File

@@ -0,0 +1,61 @@
#include "InvalidLicenseScreen.hpp"
InvalidLicenseScreen::InvalidLicenseScreen(int error, bool bHasQuitButton) :
m_error(error),
m_btnOk (1, "Ok"),
m_btnBuy(2, "Buy"),
m_bHasQuitButton(bHasQuitButton)
{
if (bHasQuitButton)
m_btnOk.field_18 = "Quit";
}
void InvalidLicenseScreen::buttonClicked(Button* pButton)
{
if (pButton->field_30 == m_btnOk.field_30)
{
m_pMinecraft->quit();
}
if (pButton->field_30 == m_btnBuy.field_30)
{
m_pMinecraft->platform()->buyGame();
}
}
void InvalidLicenseScreen::init()
{
field_E4 = m_height / 3;
if (m_bHasQuitButton)
field_E4 -= 24;
if (m_error > 1)
{
char str[20] = { 0 };
sprintf(str, "%d", m_error);
m_textLine1 = "License verification failed (error " + std::string(str) + ")";
m_textLine2 = "Try again later.";
}
m_btnOk.m_xPos = m_btnBuy.m_xPos = (m_width - m_btnOk.m_width) / 2;
m_btnOk.m_yPos = field_E4 + 60;
m_btnBuy.m_yPos = field_E4 + 88;
m_buttons.push_back(&m_btnOk);
m_buttons.push_back(&m_btnBuy);
m_buttonTabList.push_back(&m_btnOk);
m_buttonTabList.push_back(&m_btnBuy);
}
void InvalidLicenseScreen::tick()
{
}
void InvalidLicenseScreen::render(int mouseX, int mouseY, float f)
{
renderDirtBackground(0);
drawCenteredString(m_pMinecraft->m_pFont, m_textLine1, m_width / 2, field_E4, 0xFFFFFF);
drawCenteredString(m_pMinecraft->m_pFont, m_textLine2, m_width / 2, field_E4 + 24, 0xFFFFFF);
Screen::render(mouseX, mouseY, f);
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include "Screen.hpp"
class InvalidLicenseScreen : public Screen
{
public:
InvalidLicenseScreen(int error, bool bHasQuitButton);
void buttonClicked(Button* pButton) override;
void init() override;
void tick() override;
void render(int mouseX, int mouseY, float f) override;
private:
int m_error;
std::string m_textLine1;
std::string m_textLine2;
Button m_btnOk;
Button m_btnBuy;
bool m_bHasQuitButton;
int field_E4 = 0;
};

View File

@@ -0,0 +1,155 @@
#include "JoinGameScreen.hpp"
#include "ProgressScreen.hpp"
#include "StartMenuScreen.hpp"
JoinGameScreen::JoinGameScreen() :
m_btnJoin(2, "Join Game"),
m_btnBack(3, "Back")
{
}
JoinGameScreen::~JoinGameScreen()
{
if (m_pAvailableGamesList)
delete m_pAvailableGamesList;
}
void JoinGameScreen::buttonClicked(Button* pButton)
{
if (pButton->field_30 == m_btnJoin.field_30)
{
if (isIndexValid(m_pAvailableGamesList->m_selectedIndex))
{
m_pMinecraft->joinMultiplayer(m_pAvailableGamesList->m_games[m_pAvailableGamesList->m_selectedIndex]);
m_pMinecraft->setScreen(new ProgressScreen);
m_btnJoin.m_bEnabled = false;
m_btnBack.m_bEnabled = false;
}
}
if (pButton->field_30 == m_btnBack.field_30)
{
m_pMinecraft->setScreen(new StartMenuScreen);
}
}
bool JoinGameScreen::handleBackEvent(bool b)
{
if (!b)
{
m_pMinecraft->cancelLocateMultiplayer();
m_pMinecraft->setScreen(new StartMenuScreen);
}
return true;
}
void JoinGameScreen::init()
{
m_btnBack.m_yPos = m_btnJoin.m_yPos = m_height - 26;
m_btnBack.m_width = m_btnJoin.m_width = 120;
m_btnJoin.m_xPos = m_width / 2 - 124;
m_btnBack.m_xPos = m_width / 2 + 4;
m_buttons.push_back(&m_btnJoin);
m_buttons.push_back(&m_btnBack);
m_pMinecraft->m_pRakNetInstance->clearServerList();
m_pAvailableGamesList = new AvailableGamesList(m_pMinecraft, m_width, m_height, 24, m_height - 30, 28);
m_buttonTabList.push_back(&m_btnJoin);
m_buttonTabList.push_back(&m_btnBack);
}
bool JoinGameScreen::isInGameScreen()
{
return false;
}
void JoinGameScreen::render(int mouseX, int mouseY, float f)
{
renderBackground();
m_pAvailableGamesList->render(mouseX, mouseY, f);
Screen::render(mouseX, mouseY, f);
drawCenteredString(m_pMinecraft->m_pFont, "Scanning for Games...", m_width / 2, 8, 0xFFFFFFFF);
}
void JoinGameScreen::tick()
{
std::vector<PingedCompatibleServer> *serverList, serverListFiltered;
serverList = m_pMinecraft->m_pRakNetInstance->getServerList();
for (const PingedCompatibleServer& pcs : *serverList)
{
if (pcs.m_name.GetLength())
serverListFiltered.push_back(pcs);
}
if (serverListFiltered.size() != m_pAvailableGamesList->m_games.size())
{
PingedCompatibleServer selectedItem;
if (isIndexValid(m_pAvailableGamesList->m_selectedIndex))
{
selectedItem = m_pAvailableGamesList->m_games[m_pAvailableGamesList->m_selectedIndex];
m_pAvailableGamesList->m_games = serverListFiltered;
m_pAvailableGamesList->selectItem(-1, false);
// relocate the new list item, if possible
for (int i = 0; i < int(serverListFiltered.size()); i++)
{
if (serverListFiltered[i].m_address == selectedItem.m_address)
{
m_pAvailableGamesList->selectItem(i, false);
break;
}
}
}
else
{
m_pAvailableGamesList->m_games = serverListFiltered;
m_pAvailableGamesList->selectItem(-1, false);
}
}
else if (!serverListFiltered.empty())
{
// Update the names of the items already in the available games list.
// @BUG: What would happen if the filtered server list removes an IP and adds another all in the same tick?
std::vector<PingedCompatibleServer>* pGames = &m_pAvailableGamesList->m_games;
for (int i = int(pGames->size() - 1); i >= 0; i--)
{
int j = 0;
for (; j < int(serverListFiltered.size()); j++)
{
if (serverListFiltered[j].m_address == (*pGames)[i].m_address)
break;
}
if (j == serverListFiltered.size())
continue;
(*pGames)[i].m_name = serverListFiltered[j].m_name;
}
}
m_btnJoin.m_bEnabled = isIndexValid(m_pAvailableGamesList->m_selectedIndex);
}
bool JoinGameScreen::isIndexValid(int idx)
{
if (!m_pAvailableGamesList)
return false;
if (idx < 0)
return false;
if (idx >= m_pAvailableGamesList->getNumberOfItems())
return false;
return true;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Screen.hpp"
#include "AvailableGamesList.hpp"
class JoinGameScreen : public Screen
{
public:
JoinGameScreen();
~JoinGameScreen();
void buttonClicked(Button* pButton) override;
bool handleBackEvent(bool b) override;
void init() override;
bool isInGameScreen() override;
void render(int mouseX, int mouseY, float f) override;
void tick() override;
virtual bool isIndexValid(int idx);
public:
Button m_btnJoin;
Button m_btnBack;
AvailableGamesList* m_pAvailableGamesList = nullptr;
};

View File

@@ -0,0 +1,200 @@
#include "OptionsScreen.hpp"
#include "StartMenuScreen.hpp"
#include "PauseScreen.hpp"
enum eOptionsButton
{
OB_BACK = 1,
OB_AO,
OB_SRV_VIS,
OB_FANCY_GFX,
OB_INVERT_Y,
OB_ANAGLYPHS,
OB_VIEW_BOB,
OB_VIEW_DIST,
OB_FLY_HAX,
};
OptionsScreen::OptionsScreen()
#ifndef ORIGINAL_CODE
:m_BackButton (1, 0, 0, 200, 20, "Done"),
m_AOButton (2, 0, 0, 150, 20, ""),
m_srvVisButton (3, 0, 0, 150, 20, ""),
m_fancyGfxButton (4, 0, 0, 150, 20, ""),
m_invertYButton (5, 0, 0, 150, 20, ""),
m_anaglyphsButton(6, 0, 0, 150, 20, ""),
m_viewBobButton (7, 0, 0, 150, 20, ""),
m_viewDistButton (8, 0, 0, 150, 20, ""),
m_flightHaxButton(9, 0, 0, 150, 20, "")
#endif
{
}
#ifndef ORIGINAL_CODE
static std::string BoolOptionStr(bool b)
{
return b ? "ON" : "OFF";
}
static std::string ViewDistanceStr(int dist)
{
switch (dist)
{
case 0: return "EXTREME";
case 1: return "FAR";
case 2: return "NORMAL";
case 3: return "SHORT";
case 4: return "TINY";
default:
{
std::stringstream ss;
ss << dist;
return ss.str();
}
}
}
void OptionsScreen::UpdateTexts()
{
Options& o = m_pMinecraft->m_options;
m_AOButton.field_18 = "Smooth lighting: " + BoolOptionStr(o.field_18);
m_invertYButton.field_18 = "Invert Y-axis: " + BoolOptionStr(o.m_bInvertMouse);
m_viewBobButton.field_18 = "View bobbing: " + BoolOptionStr(o.field_14);
m_anaglyphsButton.field_18 = "3d Anaglyphs: " + BoolOptionStr(o.m_bAnaglyphs);
m_fancyGfxButton.field_18 = "Fancy graphics: " + BoolOptionStr(o.m_bFancyGraphics);
m_flightHaxButton.field_18 = "Flight hax: " + BoolOptionStr(o.m_bFlyCheat);
m_viewDistButton.field_18 = "View distance: " + ViewDistanceStr(o.field_10);
m_srvVisButton.field_18 = "Server " + std::string(o.m_bServerVisibleDefault ? "visible" : "invisible") + " by default";
}
#endif
void OptionsScreen::init()
{
m_pMinecraft->platform()->showDialog(AppPlatform::DLG_OPTIONS);
m_pMinecraft->platform()->createUserInput();
#ifndef ORIGINAL_CODE
m_BackButton.m_xPos = m_width / 2 - m_BackButton.m_width / 2;
m_BackButton.m_yPos = m_height - 33;
m_BackButton.m_height = 20;
m_buttons.push_back(&m_BackButton);
m_AOButton.m_xPos =
m_srvVisButton.m_xPos =
m_fancyGfxButton.m_xPos =
m_viewDistButton.m_xPos = m_width / 2 - m_AOButton.m_width - 5;
m_invertYButton.m_xPos =
m_anaglyphsButton.m_xPos =
m_viewBobButton.m_xPos =
m_flightHaxButton.m_xPos = m_width / 2 + 5;
int yPos = 40;
m_AOButton.m_yPos = m_invertYButton.m_yPos = yPos; yPos += 25;
m_srvVisButton.m_yPos = m_anaglyphsButton.m_yPos = yPos; yPos += 25;
m_fancyGfxButton.m_yPos = m_viewBobButton.m_yPos = yPos; yPos += 25;
m_viewDistButton.m_yPos = m_flightHaxButton.m_yPos = yPos; yPos += 25;
m_buttons.push_back(&m_AOButton);
m_buttons.push_back(&m_srvVisButton);
m_buttons.push_back(&m_fancyGfxButton);
m_buttons.push_back(&m_invertYButton);
m_buttons.push_back(&m_anaglyphsButton);
m_buttons.push_back(&m_viewBobButton);
m_buttons.push_back(&m_viewDistButton);
m_buttons.push_back(&m_flightHaxButton);
m_buttonTabList.push_back(&m_AOButton);
m_buttonTabList.push_back(&m_srvVisButton);
m_buttonTabList.push_back(&m_fancyGfxButton);
m_buttonTabList.push_back(&m_viewDistButton);
m_buttonTabList.push_back(&m_invertYButton);
m_buttonTabList.push_back(&m_anaglyphsButton);
m_buttonTabList.push_back(&m_viewBobButton);
m_buttonTabList.push_back(&m_flightHaxButton);
m_buttonTabList.push_back(&m_BackButton);
UpdateTexts();
#endif
}
void OptionsScreen::render(int a, int b, float c)
{
renderBackground();
if (m_pMinecraft->m_pPlatform->getUserInputStatus() >= 0)
{
m_pMinecraft->setScreen(new StartMenuScreen);
}
#ifndef ORIGINAL_CODE
drawCenteredString(m_pFont, "Options", m_width / 2, 20, 0xFFFFFF);
Screen::render(a, b, c);
#endif
}
void OptionsScreen::removed()
{
m_pMinecraft->reloadOptions();
}
#ifndef ORIGINAL_CODE
void OptionsScreen::buttonClicked(Button* pButton)
{
Options& o = m_pMinecraft->m_options;
bool* pOption = nullptr;
switch (pButton->field_30)
{
case OB_BACK:
if (m_pMinecraft->isLevelGenerated())
m_pMinecraft->setScreen(new PauseScreen);
else
m_pMinecraft->setScreen(new StartMenuScreen);
return;
case OB_AO:
o.field_18 ^= 1;
Minecraft::useAmbientOcclusion = o.field_18;
m_pMinecraft->m_pLevelRenderer->allChanged();
UpdateTexts();
return;
case OB_FANCY_GFX:
o.m_bFancyGraphics ^= 1;
m_pMinecraft->m_pLevelRenderer->allChanged();
UpdateTexts();
return;
case OB_VIEW_DIST:
// @TODO: fix the 'extreme' render distance
o.field_10 = (o.field_10 + 1) % 4;
UpdateTexts();
return;
case OB_ANAGLYPHS:
pOption = &o.m_bAnaglyphs;
break;
case OB_INVERT_Y:
pOption = &o.m_bInvertMouse;
break;
case OB_SRV_VIS:
pOption = &o.m_bServerVisibleDefault;
break;
case OB_VIEW_BOB:
pOption = &o.field_14;
break;
case OB_FLY_HAX:
pOption = &o.m_bFlyCheat;
break;
}
if (!pOption)
return;
*pOption ^= 1;
UpdateTexts();
}
#endif

View File

@@ -0,0 +1,30 @@
#pragma once
#include "Screen.hpp"
class OptionsScreen : public Screen
{
public:
OptionsScreen();
void init() override;
void render(int, int, float) override;
void removed() override;
#ifndef ORIGINAL_CODE
void buttonClicked(Button* pButton) override;
void UpdateTexts();
private:
Button m_BackButton;
Button m_AOButton;
Button m_srvVisButton;
Button m_fancyGfxButton;
Button m_invertYButton;
Button m_anaglyphsButton;
Button m_viewBobButton;
Button m_viewDistButton;
Button m_flightHaxButton;
#endif
};

View File

@@ -0,0 +1,112 @@
#include "PauseScreen.hpp"
#include "OptionsScreen.hpp"
#include "ServerSideNetworkHandler.hpp"
PauseScreen::PauseScreen() :
m_btnBack(1, "Back to game"),
m_btnQuit(2, "Quit to title"),
m_btnQuitAndCopy(3, "Quit and copy map"),
m_btnVisible(4, "")
#ifdef ENH_ADD_OPTIONS_PAUSE
, m_btnOptions(999, "Options")
#endif
{
}
void PauseScreen::init()
{
m_btnQuit.m_width = 160;
m_btnBack.m_width = 160;
m_btnVisible.m_width = 160;
m_btnQuitAndCopy.m_width = 160;
m_btnBack.m_yPos = 48;
m_btnQuit.m_yPos = 80;
m_btnBack.m_xPos = (m_width - 160) / 2;
m_btnQuit.m_xPos = (m_width - 160) / 2;
m_btnVisible.m_xPos = (m_width - 160) / 2;
m_btnQuitAndCopy.m_xPos = (m_width - 160) / 2;
m_btnVisible.m_yPos = 112;
m_btnQuitAndCopy.m_yPos = 112;
#ifdef ENH_ADD_OPTIONS_PAUSE
// TODO: when visible or quit&copy are on, lower this
m_btnOptions.m_width = 160;
m_btnOptions.m_yPos = 144;
m_btnOptions.m_xPos = m_btnBack.m_xPos;
#endif
// add the buttons to the screen:
m_buttons.push_back(&m_btnBack);
m_buttons.push_back(&m_btnQuit);
#ifdef ENH_ADD_OPTIONS_PAUSE
m_buttons.push_back(&m_btnOptions);
#endif
//m_buttons.push_back(&m_btnQuitAndCopy);
if (m_pMinecraft->m_pRakNetInstance)
{
updateServerVisibilityText();
m_buttons.push_back(&m_btnVisible);
}
for (auto thing : m_buttons)
m_buttonTabList.push_back(thing);
}
void PauseScreen::updateServerVisibilityText()
{
if (!m_pMinecraft->m_pRakNetInstance) return;
if (!m_pMinecraft->m_pRakNetInstance->m_bIsHost) return;
ServerSideNetworkHandler* pSSNH = (ServerSideNetworkHandler*)m_pMinecraft->m_pNetEventCallback;
if (pSSNH->m_bAllowIncoming)
m_btnVisible.field_18 = "Server is visible";
else
m_btnVisible.field_18 = "Server is invisible";
}
void PauseScreen::tick()
{
field_40++;
}
void PauseScreen::render(int a, int b, float c)
{
renderBackground();
drawCenteredString(m_pFont, "Game menu", m_width / 2, 24, 0xFFFFFF);
Screen::render(a, b, c);
}
void PauseScreen::buttonClicked(Button* pButton)
{
if (pButton->field_30 == m_btnBack.field_30)
m_pMinecraft->setScreen(nullptr);
if (pButton->field_30 == m_btnQuit.field_30)
m_pMinecraft->leaveGame(false);
if (pButton->field_30 == m_btnQuitAndCopy.field_30)
m_pMinecraft->leaveGame(true);
if (pButton->field_30 == m_btnVisible.field_30)
{
if (m_pMinecraft->m_pRakNetInstance && m_pMinecraft->m_pRakNetInstance->m_bIsHost)
{
ServerSideNetworkHandler* pSSNH = (ServerSideNetworkHandler*)m_pMinecraft->m_pNetEventCallback;
pSSNH->allowIncomingConnections(!pSSNH->m_bAllowIncoming);
updateServerVisibilityText();
}
}
#ifdef ENH_ADD_OPTIONS_PAUSE
if (pButton->field_30 == m_btnOptions.field_30)
m_pMinecraft->setScreen(new OptionsScreen);
#endif
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "Screen.hpp"
class PauseScreen : public Screen
{
public:
PauseScreen();
virtual void init() override;
virtual void tick() override;
virtual void render(int a, int b, float c) override;
virtual void buttonClicked(Button*) override;
void updateServerVisibilityText();
private:
int field_3C = 0;
int field_40 = 0;
Button m_btnBack;
Button m_btnQuit;
Button m_btnQuitAndCopy;
Button m_btnVisible;
#ifdef ENH_ADD_OPTIONS_PAUSE
Button m_btnOptions;
#endif
};

View File

@@ -0,0 +1,78 @@
#include "ProgressScreen.hpp"
bool ProgressScreen::isInGameScreen()
{
return false;
}
void ProgressScreen::render(int a, int b, float c)
{
if (m_pMinecraft->isLevelGenerated())
{
m_pMinecraft->setScreen(nullptr);
return;
}
renderBackground();
// render the dirt background
// for some reason, this was manually written:
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
//! why not use the screen stuff
int x_width = int(Minecraft::width * Gui::InvGuiScale);
int x_height = int(Minecraft::height * Gui::InvGuiScale);
Tesselator& t = Tesselator::instance;
t.begin();
t.color(0x404040);
t.vertexUV(0.0f, float(x_height), 0, 0, float(x_height) / 32.0f);
t.vertexUV(float(x_width), float(x_height), 0, float(x_width) / 32.0f, float(x_height) / 32.0f);
t.vertexUV(float(x_width), 0, 0, float(x_width) / 32.0f, 0);
t.vertexUV(0.0f, 0, 0, 0, 0);
t.draw();
int yPos = x_height / 2;
if (m_pMinecraft->m_progressPercent >= 0)
{
float lX = float(x_width) / 2 - 50, rX = float(x_width) / 2 + 50;
float prog = float(m_pMinecraft->m_progressPercent);
// disable the texturing
glDisable(GL_TEXTURE_2D);
t.begin();
t.color(0x808080); // gray background
t.vertex(lX, float(yPos + 16), 0);
t.vertex(lX, float(yPos + 18), 0);
t.vertex(rX, float(yPos + 18), 0);
t.vertex(rX, float(yPos + 16), 0);
t.color(0x80FF80); // the green stuff
t.vertex(lX, float(yPos + 16), 0);
t.vertex(lX, float(yPos + 18), 0);
t.vertex(lX + prog, float(yPos + 18), 0);
t.vertex(lX + prog, float(yPos + 16), 0);
t.draw();
// restore old state
glEnable(GL_TEXTURE_2D);
}
//! Using m_pMinecraft->m_pFont instead of m_pFont.
Font* pFont = m_pMinecraft->m_pFont;
int width = pFont->width("Generating world");
pFont->drawShadow("Generating world", (x_width - width) / 2, yPos - 20, 0xFFFFFF);
width = pFont->width(m_pMinecraft->getProgressMessage());
pFont->drawShadow(m_pMinecraft->getProgressMessage(), (x_width - width) / 2, yPos + 4, 0xFFFFFF);
#ifdef ORIGINAL_CODE
sleepMs(50);
#endif
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Screen.hpp"
class ProgressScreen : public Screen
{
public:
void render(int, int, float) override;
bool isInGameScreen() override;
};

View File

@@ -0,0 +1,30 @@
#include "RenameMPLevelScreen.hpp"
#include "StartMenuScreen.hpp"
RenameMPLevelScreen::RenameMPLevelScreen(const std::string& levelName) : m_levelName(levelName)
{
}
void RenameMPLevelScreen::init()
{
m_pMinecraft->platform()->showDialog(AppPlatform::DLG_RENAME_MP_WORLD);
m_pMinecraft->platform()->createUserInput();
}
void RenameMPLevelScreen::render(int mouseX, int mouseY, float f)
{
int userInputStatus = m_pMinecraft->platform()->getUserInputStatus();
if (userInputStatus < 0)
return;
if (userInputStatus == 1)
{
std::vector<std::string> input = m_pMinecraft->platform()->getUserInput();
if (input.size() > 0 && !input[0].empty())
{
m_pMinecraft->getLevelSource()->renameLevel(m_levelName, input[0]);
}
}
m_pMinecraft->setScreen(new StartMenuScreen);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Screen.hpp"
class RenameMPLevelScreen : public Screen
{
public:
RenameMPLevelScreen(const std::string& levelName);
void init() override;
void render(int mouseX, int mouseY, float f) override;
private:
std::string m_levelName;
};

View File

@@ -0,0 +1,252 @@
#include "Screen.hpp"
Screen::Screen()
{
}
Screen::~Screen()
{
m_pClickedButton = nullptr;
m_buttons.clear();
}
void Screen::init(Minecraft* pMinecraft, int a3, int a4)
{
m_width = a3;
m_height = a4;
m_pMinecraft = pMinecraft;
m_pFont = pMinecraft->m_pFont;
init();
updateTabButtonSelection();
}
void Screen::init()
{
}
void Screen::buttonClicked(Button* pButton)
{
}
void Screen::confirmResult(bool b, int i)
{
}
bool Screen::handleBackEvent(bool b)
{
return false;
}
bool Screen::isPauseScreen()
{
return true;
}
bool Screen::isErrorScreen()
{
return false;
}
bool Screen::isInGameScreen()
{
return true;
}
void Screen::keyPressed(int key)
{
if (key == '\x1B')//escape
{
m_pMinecraft->setScreen(nullptr);
}
if (m_buttonTabList.size())
{
#ifndef ENH_HIGHLIGHT_BY_HOVER
if (m_pMinecraft->m_options.m_keyBinds[Options::MENU_NEXT].value == key)
{
m_tabButtonIndex++;
if (m_tabButtonIndex == int(m_buttonTabList.size()))
m_tabButtonIndex = 0;
}
if (m_pMinecraft->m_options.m_keyBinds[Options::MENU_PREVIOUS].value == key)
{
m_tabButtonIndex--;
if (m_tabButtonIndex == -1)
m_tabButtonIndex = int(m_buttonTabList.size() - 1);
}
if (m_pMinecraft->m_options.m_keyBinds[Options::MENU_OK].value == key)
{
if (m_buttonTabList[m_tabButtonIndex]->m_bEnabled)
{
m_pMinecraft->m_pSoundEngine->play("random.click");
buttonClicked(m_buttonTabList[m_tabButtonIndex]);
}
}
updateTabButtonSelection();
#endif
}
#ifndef ORIGINAL_CODE
for (auto textInput : m_textInputs)
{
textInput->keyPressed(m_pMinecraft, key);
}
#endif
}
void Screen::mouseClicked(int xPos, int yPos, int d) // d = clicked?
{
if (!d) return;
for (auto button : m_buttons)
{
if (button->clicked(m_pMinecraft, xPos, yPos))
{
m_pClickedButton = button;
m_pMinecraft->m_pSoundEngine->play("random.click");
buttonClicked(button);
}
}
#ifndef ORIGINAL_CODE
for (auto textInput : m_textInputs)
{
textInput->onClick(xPos, yPos);
}
#endif
}
void Screen::mouseReleased(int xPos, int yPos, int d)
{
if (!d) return;
if (m_pClickedButton)
{
m_pClickedButton->released(xPos, yPos);
m_pClickedButton = nullptr;
}
}
void Screen::render(int xPos, int yPos, float unused)
{
for (auto button : m_buttons)
{
button->render(m_pMinecraft, xPos, yPos);
}
#ifndef ORIGINAL_CODE
for (auto textInput : m_textInputs)
{
textInput->tick();
textInput->render();
}
#endif
}
void Screen::tick()
{
}
void Screen::removed()
{
}
void Screen::setSize(int width, int height)
{
m_width = width;
m_height = height;
}
void Screen::updateEvents()
{
if (field_10) return;
for (int i = Mouse::_index + 1; i<int(Mouse::_inputs.size()); i++)
{
Mouse::_index = i;
mouseEvent();
}
for (int i = Keyboard::_index + 1; i<int(Keyboard::_inputs.size()); i++)
{
Keyboard::_index = i;
keyboardEvent();
}
}
void Screen::keyboardEvent()
{
// @UB: This probably behaves in an unexpected way if _inputs is empty
#ifndef ORIGINAL_CODE
if (Keyboard::_inputs.empty() || Keyboard::_index < 0)
return;
#endif
if (Keyboard::_inputs[Keyboard::_index].field_0)
keyPressed(Keyboard::_inputs[Keyboard::_index].field_4);
}
void Screen::mouseEvent()
{
MouseInput& inp = Mouse::_inputs[Mouse::_index];
if (1 <= inp.field_0 && inp.field_0 <= 2)
{
if (inp.field_4 == 1)
mouseClicked(m_width * Mouse::_x / Minecraft::width, m_height * Mouse::_y / Minecraft::height - 1, inp.field_0);
else
mouseReleased(m_width * Mouse::_x / Minecraft::width, m_height * Mouse::_y / Minecraft::height - 1, inp.field_0);
}
}
void Screen::renderBackground(int unk)
{
if (m_pMinecraft->isLevelGenerated())
{
fillGradient(0, 0, m_width, m_height, 0xC0101010, 0xD0101010);
}
else
{
renderDirtBackground(unk);
}
}
void Screen::renderBackground()
{
renderBackground(0);
}
void Screen::renderDirtBackground(int unk)
{
glDisable(GL_FOG);
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
glColor4f(1, 1, 1, 1);
Tesselator& t = Tesselator::instance;
t.begin();
t.color(0x404040);
t.vertexUV(0.0f, float(m_height), 0, 0, float(unk) + float(m_height) / 32.0f);
t.vertexUV(float(m_width), float(m_height), 0, float(unk) + float(m_width) / 32.0f, float(unk) + float(m_height) / 32.0f);
t.vertexUV(float(m_width), 0, 0, float(unk) + float(m_width) / 32.0f, 0);
t.vertexUV(0.0f, 0, 0, 0, 0);
t.draw();
}
void Screen::updateTabButtonSelection()
{
#ifndef ENH_HIGHLIGHT_BY_HOVER
for (int i = 0; i < int(m_buttonTabList.size()); i++)
{
m_buttonTabList[i]->field_36 = m_tabButtonIndex == i;
}
#endif
}

View File

@@ -0,0 +1,55 @@
#pragma once
#include "Mouse.hpp"
#include "Keyboard.hpp"
#include "Button.hpp"
#include "TextInputBox.hpp"
class Button;
class Screen : public GuiComponent
{
public:
Screen();
virtual ~Screen();
void init(Minecraft*, int, int);
void updateTabButtonSelection();
void setSize(int width, int height);
virtual void render(int, int, float);
virtual void init();
virtual void updateEvents();
virtual void mouseEvent();
virtual void keyboardEvent();
virtual bool handleBackEvent(bool);
virtual void tick();
virtual void removed();
virtual void renderBackground(int);
virtual void renderBackground();
virtual void renderDirtBackground(int);
virtual bool isPauseScreen();
virtual bool isErrorScreen();
virtual bool isInGameScreen();
virtual void confirmResult(bool, int);
virtual void buttonClicked(Button*);
virtual void mouseClicked(int, int, int);
virtual void mouseReleased(int, int, int);
virtual void keyPressed(int);
public:
int m_width = 1;
int m_height = 1;
bool field_10 = false;
Minecraft* m_pMinecraft;
std::vector<Button*> m_buttons;
std::vector<Button*> m_buttonTabList;
int m_tabButtonIndex = 0;
Font* m_pFont;
Button* m_pClickedButton = 0;
#ifndef ORIGINAL_CODE
std::vector<TextInputBox*> m_textInputs;
#endif
};

View File

@@ -0,0 +1,246 @@
#include "SelectWorldScreen.hpp"
#include "DeleteWorldScreen.hpp"
#include "ProgressScreen.hpp"
#include "StartMenuScreen.hpp"
#include "Util.hpp"
SelectWorldScreen::SelectWorldScreen() :
m_btnDelete (1, "Delete"),
m_btnCreateNew(2, "Create new"),
m_btnBack (3, "Back"),
m_btnUnknown (4, "")
{
m_btnDelete.m_bEnabled = false;
}
void SelectWorldScreen::init()
{
m_pWorldSelectionList = new WorldSelectionList(m_pMinecraft, m_width, m_height);
loadLevelSource();
m_pWorldSelectionList->commit();
m_btnDelete.m_yPos = m_btnBack.m_yPos = m_btnCreateNew.m_yPos = m_height - 28;
m_btnDelete.m_width = m_btnBack.m_width = m_btnCreateNew.m_width = 84;
m_btnDelete.m_height = m_btnBack.m_height = m_btnCreateNew.m_height = 24;
m_btnDelete.m_xPos = m_width / 2 - 130;
m_btnCreateNew.m_xPos = m_width / 2 - 42;
m_btnBack.m_xPos = m_width / 2 + 46;
m_buttons.push_back(&m_btnCreateNew);
m_buttons.push_back(&m_btnBack);
m_buttons.push_back(&m_btnDelete);
field_12C = Mouse::_buttonStates[1] == 0;
m_buttonTabList.push_back(&m_btnUnknown);
m_buttonTabList.push_back(&m_btnDelete);
m_buttonTabList.push_back(&m_btnCreateNew);
m_buttonTabList.push_back(&m_btnBack);
}
bool SelectWorldScreen::isInGameScreen()
{
return true;
}
void SelectWorldScreen::keyPressed(int code)
{
#ifndef ORIGINAL_CODE
if (m_pMinecraft->m_options.m_keyBinds[Options::MENU_OK].value == code)
m_pWorldSelectionList->selectItem(m_pWorldSelectionList->getItemAtPosition(m_width / 2, m_height / 2), false);
m_btnUnknown.field_36 = true;
#endif
if (m_btnUnknown.field_36)
{
if (m_pMinecraft->m_options.m_keyBinds[Options::LEFT].value == code)
m_pWorldSelectionList->stepLeft();
if (m_pMinecraft->m_options.m_keyBinds[Options::RIGHT].value == code)
m_pWorldSelectionList->stepRight();
}
Screen::keyPressed(code);
}
static char g_SelectWorldFilterArray[] = { '/','\n','\r','\x09','\0','\xC','`','?','*','\\','<','>','|','"',':'};
void SelectWorldScreen::tick()
{
#ifndef ORIGINAL_CODE
m_btnUnknown.field_36 = true;
#endif
if (field_130 == 1)
{
// poll the user status to get details about the world name and seed
int userInputStatus = m_pMinecraft->platform()->getUserInputStatus();
if (userInputStatus < 0)
return;
if (userInputStatus != 1)
{
field_130 = 0;
return;
}
std::vector<std::string> userInput = m_pMinecraft->platform()->getUserInput();
std::string levelNickname = Util::stringTrim(userInput[0]);
std::string levelUniqueName = levelNickname;
for (int i = 0; i < sizeof(g_SelectWorldFilterArray); i++)
{
std::string str;
str.push_back(g_SelectWorldFilterArray[i]);
Util::stringReplace(levelUniqueName, str, "");
}
levelUniqueName = getUniqueLevelName(levelUniqueName);
int seed = int(getEpochTimeS());
if (userInput.size() > 1)
{
std::string seedThing = Util::stringTrim(userInput[1]);
if (!seedThing.empty())
{
int num;
if (sscanf(seedThing.c_str(), "%d", &num) > 0)
seed = num;
else
seed = Util::hashCode(seedThing);
}
}
m_pMinecraft->selectLevel(levelUniqueName, levelNickname, seed);
m_pMinecraft->hostMultiplayer();
m_pMinecraft->setScreen(new ProgressScreen);
field_130 = 0;
return;
}
m_pWorldSelectionList->tick();
if (m_pWorldSelectionList->field_90)
{
LevelSummary& ls = m_pWorldSelectionList->m_levelSummary;
m_pMinecraft->selectLevel(ls.field_0, ls.field_18, 0);
m_pMinecraft->hostMultiplayer();
m_pMinecraft->setScreen(new ProgressScreen);
return;
}
// the level summary stuff is unused.
LevelSummary ls;
if (isIndexValid(m_pWorldSelectionList->m_selectedIndex))
ls = m_pWorldSelectionList->m_items[m_pWorldSelectionList->m_selectedIndex];
m_btnDelete.m_bEnabled = isIndexValid(m_pWorldSelectionList->m_selectedIndex);
}
void SelectWorldScreen::render(int mouseX, int mouseY, float f)
{
renderBackground();
#ifndef ORIGINAL_CODE
m_btnUnknown.field_36 = true;
#endif
m_pWorldSelectionList->setComponentSelected(m_btnUnknown.field_36);
if (field_12C)
{
m_pWorldSelectionList->render(mouseX, mouseY, f);
}
else
{
m_pWorldSelectionList->render(0, 0, f);
field_12C = Mouse::_buttonStates[1] == 0;
}
Screen::render(mouseX, mouseY, f);
drawCenteredString(m_pMinecraft->m_pFont, "Select world", m_width / 2, 8, 0xFFFFFFFF);
}
bool SelectWorldScreen::handleBackEvent(bool b)
{
if (b)
return true;
// @TODO: m_pMinecraft->cancelLocateMultiplayer();
m_pMinecraft->setScreen(new StartMenuScreen);
return true;
}
void SelectWorldScreen::buttonClicked(Button* pButton)
{
if (pButton->field_30 == m_btnCreateNew.field_30)
{
m_pMinecraft->platform()->showDialog(AppPlatform::DLG_CREATE_WORLD);
m_pMinecraft->platform()->createUserInput();
field_130 = true;
}
if (pButton->field_30 == m_btnDelete.field_30)
{
LevelSummary ls(m_pWorldSelectionList->m_items[m_pWorldSelectionList->m_selectedIndex]);
m_pMinecraft->setScreen(new DeleteWorldScreen(ls));
}
if (pButton->field_30 == m_btnBack.field_30)
{
// @TODO: m_pMinecraft->cancelLocateMultiplayer();
m_pMinecraft->setScreen(new StartMenuScreen);
}
if (pButton->field_30 == m_btnUnknown.field_30)
{
m_pWorldSelectionList->selectItem(m_pWorldSelectionList->getItemAtPosition(m_width / 2, m_height / 2), false);
}
}
bool SelectWorldScreen::isIndexValid(int idx)
{
if (!m_pWorldSelectionList)
return false;
if (idx < 0)
return false;
if (idx >= m_pWorldSelectionList->getNumberOfItems())
return false;
return true;
}
std::string SelectWorldScreen::getUniqueLevelName(const std::string& in)
{
std::set<std::string> maps;
for (const auto& ls : m_levels)
{
maps.insert(ls.field_0);
}
std::string out = in;
while (maps.find(out) != maps.end())
out += "-";
return out;
}
void SelectWorldScreen::loadLevelSource()
{
m_pMinecraft->getLevelSource()->getLevelList(m_levels);
std::sort(m_levels.begin(), m_levels.end());
for (const auto& level : m_levels)
{
if (level.field_0 == "_LastJoinedServer")
continue;
m_pWorldSelectionList->m_items.push_back(level);
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "Screen.hpp"
#include "WorldSelectionList.hpp"
class SelectWorldScreen : public Screen
{
public:
SelectWorldScreen();
void init() override;
bool isInGameScreen() override;
void keyPressed(int code) override;
void tick() override;
void render(int mouseX, int mouseY, float f) override;
bool handleBackEvent(bool b) override;
void buttonClicked(Button* pButton) override;
bool isIndexValid(int);
std::string getUniqueLevelName(const std::string& in);
void loadLevelSource();
public:
Button m_btnDelete;
Button m_btnCreateNew;
Button m_btnBack;
Button m_btnUnknown;
WorldSelectionList* m_pWorldSelectionList = nullptr;
std::vector<LevelSummary> m_levels;
bool field_12C;
int field_130 = 0;
};

View File

@@ -0,0 +1,171 @@
#include "StartMenuScreen.hpp"
#include "InvalidLicenseScreen.hpp"
#include "OptionsScreen.hpp"
#include "ProgressScreen.hpp"
#include "SelectWorldScreen.hpp"
#include "JoinGameScreen.hpp"
StartMenuScreen::StartMenuScreen() :
m_startButton (2, 0, 0, 160, 24, "Start Game"),
m_joinButton (3, 0, 0, 160, 24, "Join Game"),
m_optionsButton(4, 0, 0, 78, 22, "Options"),
m_testButton (999, 0, 0, 78, 22, "Test"),
m_buyButton (5, 0, 0, 78, 22, "Buy")
//, m_testBox(1, 10, 10, 200, 16, "Insert some text...")
{
}
void StartMenuScreen::_updateLicense()
{
int licenseID = m_pMinecraft->getLicenseId();
if (licenseID < 0)
{
m_optionsButton.m_bEnabled = false;
m_startButton.m_bEnabled = false;
m_joinButton.m_bEnabled = false;
}
else if (licenseID <= 1)
{
m_optionsButton.m_bEnabled = true;
m_startButton.m_bEnabled = true;
m_joinButton.m_bEnabled = true;
}
else
{
m_pMinecraft->setScreen(new InvalidLicenseScreen(licenseID, m_pMinecraft->platform()->hasBuyButtonWhenInvalidLicense()));
}
}
void StartMenuScreen::buttonClicked(Button* pButton)
{
if (pButton->field_30 == m_startButton.field_30)
{
#if defined(DEMO) || !defined(ORIGINAL_CODE)
# ifdef DEMO
# define DEMO_SEED int(getEpochTimeS())
# else
// 1942892620 = long(12345678901324)
# define DEMO_SEED 123456
# endif
m_pMinecraft->selectLevel("_DemoLevel", "_DemoLevel", DEMO_SEED);
m_pMinecraft->hostMultiplayer();
m_pMinecraft->setScreen(new ProgressScreen);
#else
m_pMinecraft->setScreen(new SelectWorldScreen);
#endif
}
else if (pButton->field_30 == m_joinButton.field_30)
{
m_pMinecraft->locateMultiplayer();
m_pMinecraft->setScreen(new JoinGameScreen);
}
else if (pButton->field_30 == m_buyButton.field_30)
{
m_pMinecraft->platform()->buyGame();
}
else if (pButton->field_30 == m_optionsButton.field_30)
{
m_pMinecraft->setScreen(new OptionsScreen);
}
}
void StartMenuScreen::init()
{
int yPos = m_height / 2;
m_joinButton.m_yPos = yPos + 25;
m_startButton.m_yPos = yPos - 3;
yPos += 55;
m_optionsButton.m_yPos = yPos;
m_testButton.m_yPos = yPos;
m_buyButton.m_yPos = yPos;
m_startButton.m_xPos = (m_width - m_startButton.m_width) / 2;
int x1 = m_width - m_joinButton.m_width;
m_joinButton.m_xPos = x1 / 2;
m_optionsButton.m_xPos = x1 / 2;
m_buyButton.m_xPos = x1 / 2 + m_optionsButton.m_width + 4;
m_testButton.m_xPos = x1 / 2 + m_optionsButton.m_width + 4;
// add the buttons to the screen:
m_buttons.push_back(&m_startButton);
m_buttonTabList.push_back(&m_startButton);
m_buttons.push_back(&m_joinButton);
m_buttonTabList.push_back(&m_joinButton);
m_buttons.push_back(&m_optionsButton);
m_buttonTabList.push_back(&m_optionsButton);
#ifdef DEMO
m_buttons.push_back(&m_buyButton);
m_buttonTabList.push_back(&m_buyButton);
#endif
field_154 = "\xFFMojang AB";
field_16C = m_width - 1 - m_pFont->width(field_154);
field_170 = "v0.1.0 alpha"
#ifdef DEMO
" (Demo)"
#endif
;
field_188 = (m_width - m_pFont->width(field_170)) / 2;
//m_testBox.init(m_pFont);
//m_textInputs.push_back(&m_testBox);
_updateLicense();
}
bool StartMenuScreen::isInGameScreen()
{
return false;
}
void StartMenuScreen::render(int a, int b, float c)
{
renderBackground();
Textures* tx = m_pMinecraft->m_pTextures;
int id = tx->loadTexture("gui/title.png", true);
Texture *pTex = tx->getTemporaryTextureData(id);
if (pTex)
{
if (id != tx->m_currBoundTex)
{
glBindTexture(GL_TEXTURE_2D, id);
tx->m_currBoundTex = id;
}
int left = (m_width - pTex->m_width) / 2;
int width = pTex->m_width;
int height = pTex->m_height;
Tesselator& t = Tesselator::instance;
glColor4f(1, 1, 1, 1);
t.begin();
t.vertexUV(float(left), float(height + 4), field_4, 0.0f, 1.0f);
t.vertexUV(float(left + width), float(height + 4), field_4, 1.0f, 1.0f);
t.vertexUV(float(left + width), 4, field_4, 1.0f, 0.0f);
t.vertexUV(float(left), 4, field_4, 0.0f, 0.0f);
t.draw();
}
drawString(m_pFont, field_170, field_188, 62, 0xFFCCCCCC);
drawString(m_pFont, field_154, field_16C, m_height - 10, 0x00FFFFFF);
Screen::render(a, b, c);
}
void StartMenuScreen::tick()
{
_updateLicense();
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include "Screen.hpp"
class StartMenuScreen : public Screen
{
public:
StartMenuScreen();
void _updateLicense();
void init() override;
void buttonClicked(Button*) override;
bool isInGameScreen() override;
void render(int, int, float) override;
void tick() override;
private:
Button m_startButton;
Button m_joinButton;
Button m_optionsButton;
Button m_testButton;
Button m_buyButton;
std::string field_154;
int field_16C;
std::string field_170;
int field_188;
//TextInputBox m_testBox;
};