mirror of
https://github.com/celisej567/mcpe.git
synced 2026-01-04 14:09:47 +03:00
Visual Studio Project Overhaul + Cleanup (#80)
* Visual Studio Project Overhaul + Cleanup * SDL2 project for Windows * Re-added game client icon to SDL2 code * Renamed "AppPlatform_windows" to "AppPlatform_win32" (this is the name of the Windows API and is not representative of the architecture type) * Renamed "LoggerWindows" to "LoggerWin32" * Renamed "SoundSystemWindows to "SoundSystemDS" (DirectSound). This may be used for the 360, so it wouldn't really be Windows-specific then. * Moved "ClientSideNetworkHandler" from "network" to "client/network". We don't need it being compiled for the server if the client's the only thing that needs it. * I wonder if this still works on macOS... * Bugfixes & Fixed for macOS * Options::savePropertiesToFile Logging Bugfix * Silence Winsock Deprecation Warnings in RakNet * VS Project Improvements - Replaced 50 billion relative paths with $(MC_ROOT) - Added $(RAKNET_PATH) variable to override RakNet location - Re-added gitignore for .vcxproj.user files - Added debugging config to Directory.Builds.props - Slimmed down project configurations for SDL2 * VS Project Config Bugfixes - Fixed RakNet header path for additional includes * RakNet Target for XCode * XCode Project Config Fixes * Packet logging * Network VS Project Filter Fix * Fix RakNet Packet ID Length We previously didn't have consistency between old and new C++ regarding PacketType enum length. Now we do. This is required or else it completely breaks networking between the versions. * Additional RakNet Error Handling * Disable packet logging * * Fix CMakeLists.txt This reflects the relocation of ClientSideNetworkHandler.cpp. * * Also add renderer/GL/GL.cpp to the CMakeLists.txt * * Replace libpng with stb_image * * Fix buggy water behavior. * * Put the CMakeLists of the SDL project in debug mode * Visual Studio 2010 Support * * Change the SdlIoCallbacks from an array to a single member. This fixes compilation of the sdl2 target on VS. * * Fix missing _error label. * Revert "* Fix missing _error label." This reverts commit 99a057fc84049a16c864bd840fb439a008af5c74. * Revert "* Replace libpng with stb_image" * info_updateGame Tiles --------- Co-authored-by: Brent Da Mage <BrentDaMage@users.noreply.github.com> Co-authored-by: iProgramInCpp <iprogramincpp@gmail.com>
This commit is contained in:
63
source/client/app/App.cpp
Normal file
63
source/client/app/App.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/********************************************************************
|
||||
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 "App.hpp"
|
||||
|
||||
void App::destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void App::draw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool App::handleBack(bool b)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void App::init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void App::loadState(void* a2, int a3)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AppPlatform* App::platform()
|
||||
{
|
||||
return m_pPlatform;
|
||||
}
|
||||
|
||||
void App::quit()
|
||||
{
|
||||
m_bWantToQuit = true;
|
||||
}
|
||||
|
||||
bool App::wantToQuit()
|
||||
{
|
||||
return m_bWantToQuit;
|
||||
}
|
||||
|
||||
void App::saveState(void**, int)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void App::update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void App::sizeUpdate(int newWidth, int newHeight)
|
||||
{
|
||||
}
|
||||
46
source/client/app/App.hpp
Normal file
46
source/client/app/App.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/********************************************************************
|
||||
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 "AppPlatform.hpp"
|
||||
|
||||
class App
|
||||
{
|
||||
protected:
|
||||
App()
|
||||
{
|
||||
m_bWantToQuit = false;
|
||||
m_pPlatform = nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool handleBack(bool);
|
||||
virtual void init();
|
||||
virtual void update();
|
||||
virtual void sizeUpdate(int newWidth, int newHeight);
|
||||
|
||||
void destroy();
|
||||
void draw();
|
||||
void loadState(void*, int);
|
||||
AppPlatform* platform();
|
||||
void quit();
|
||||
void saveState(void**, int);
|
||||
bool wantToQuit();
|
||||
|
||||
public:
|
||||
bool m_bWantToQuit;
|
||||
|
||||
// don't know what these are ...
|
||||
int field_8;
|
||||
int field_C;
|
||||
int field_10;
|
||||
|
||||
AppPlatform* m_pPlatform;
|
||||
};
|
||||
|
||||
168
source/client/app/AppPlatform.cpp
Normal file
168
source/client/app/AppPlatform.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/********************************************************************
|
||||
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 "AppPlatform.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
|
||||
AppPlatform* AppPlatform::m_singleton = nullptr;
|
||||
|
||||
AppPlatform* const AppPlatform::singleton()
|
||||
{
|
||||
return m_singleton;
|
||||
}
|
||||
|
||||
AppPlatform::AppPlatform()
|
||||
{
|
||||
m_singleton = this;
|
||||
}
|
||||
|
||||
AppPlatform::~AppPlatform()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::_tick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::buyGame()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int AppPlatform::checkLicense()
|
||||
{
|
||||
return 0; // assume no license
|
||||
}
|
||||
|
||||
void AppPlatform::createUserInput()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::finish()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string AppPlatform::getDateString(int time)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// ??? AppPlatform::getOptionStrings()
|
||||
|
||||
int AppPlatform::getScreenWidth() const
|
||||
{
|
||||
return C_DEFAULT_SCREEN_WIDTH; // default rez of the XPERIA PLAY?
|
||||
}
|
||||
|
||||
int AppPlatform::getScreenHeight() const
|
||||
{
|
||||
return C_DEFAULT_SCREEN_HEIGHT;
|
||||
}
|
||||
|
||||
std::vector<std::string> AppPlatform::getUserInput()
|
||||
{
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
int AppPlatform::getUserInputStatus()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AppPlatform::hasBuyButtonWhenInvalidLicense()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// void AppPlatform::loadTexture(const std::string&, bool);
|
||||
|
||||
void AppPlatform::saveScreenshot(const std::string&, int, int)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::showDialog(eDialogType type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::uploadPlatformDependentData(int, void*)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Texture AppPlatform::loadTexture(const std::string&, bool)
|
||||
{
|
||||
return Texture(0, 0, nullptr, 1, 0);
|
||||
}
|
||||
|
||||
void AppPlatform::recenterMouse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::setMouseGrabbed(bool b)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::getMouseDiff(int& x, int& y)
|
||||
{
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
void AppPlatform::clearDiff()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppPlatform::updateFocused(bool focused)
|
||||
{
|
||||
}
|
||||
|
||||
bool AppPlatform::shiftPressed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AppPlatform::hasFileSystemAccess()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AppPlatform::getPatchData()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void AppPlatform::initSoundSystem()
|
||||
{
|
||||
}
|
||||
|
||||
SoundSystem* const AppPlatform::getSoundSystem() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string AppPlatform::getAssetPath(const std::string &path) const
|
||||
{
|
||||
std::string realPath = path;
|
||||
if (realPath.size() && realPath[0] == '/')
|
||||
{
|
||||
// trim it off
|
||||
realPath = realPath.substr(1);
|
||||
}
|
||||
realPath = "assets/" + realPath;
|
||||
|
||||
return realPath;
|
||||
}
|
||||
73
source/client/app/AppPlatform.hpp
Normal file
73
source/client/app/AppPlatform.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/********************************************************************
|
||||
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 <string>
|
||||
#include <vector>
|
||||
|
||||
#include "client/renderer/Texture.hpp"
|
||||
#include "client/sound/SoundSystem.hpp"
|
||||
|
||||
class AppPlatform
|
||||
{
|
||||
public:
|
||||
enum eDialogType
|
||||
{
|
||||
DLG_CREATE_WORLD = 1,
|
||||
DLG_CHAT,
|
||||
DLG_OPTIONS,
|
||||
DLG_RENAME_MP_WORLD,
|
||||
};
|
||||
|
||||
private:
|
||||
static AppPlatform* m_singleton;
|
||||
public:
|
||||
static AppPlatform* const singleton();
|
||||
|
||||
AppPlatform();
|
||||
~AppPlatform();
|
||||
|
||||
virtual void buyGame();
|
||||
virtual int checkLicense();
|
||||
virtual void createUserInput();
|
||||
virtual void finish();
|
||||
virtual std::string getDateString(int);
|
||||
virtual int getScreenWidth() const;
|
||||
virtual int getScreenHeight() const;
|
||||
virtual std::vector<std::string> getUserInput();
|
||||
virtual int getUserInputStatus();
|
||||
virtual bool hasBuyButtonWhenInvalidLicense();
|
||||
virtual void saveScreenshot(const std::string&, int, int);
|
||||
virtual void showDialog(eDialogType);
|
||||
virtual void uploadPlatformDependentData(int, void*);
|
||||
virtual Texture loadTexture(const std::string&, bool);
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
// Also add these to allow proper turning within the game.
|
||||
virtual void recenterMouse();
|
||||
virtual void setMouseGrabbed(bool b);
|
||||
virtual void getMouseDiff(int& x, int& y);
|
||||
virtual void clearDiff();
|
||||
virtual void updateFocused(bool focused);
|
||||
// Also add this to allow proper text input within the game.
|
||||
virtual bool shiftPressed();
|
||||
virtual bool hasFileSystemAccess();
|
||||
// Also add this to allow dynamic patching.
|
||||
virtual std::string getPatchData();
|
||||
virtual void initSoundSystem();
|
||||
virtual SoundSystem* const getSoundSystem() const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual std::string getAssetPath(const std::string& path) const;
|
||||
|
||||
private:
|
||||
virtual void _tick();
|
||||
};
|
||||
|
||||
1161
source/client/app/Minecraft.cpp
Normal file
1161
source/client/app/Minecraft.cpp
Normal file
File diff suppressed because it is too large
Load Diff
143
source/client/app/Minecraft.hpp
Normal file
143
source/client/app/Minecraft.hpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/********************************************************************
|
||||
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 "App.hpp"
|
||||
#include "common/CThread.hpp"
|
||||
#include "common/Mth.hpp"
|
||||
#include "common/Timer.hpp"
|
||||
#include "client/gui/Gui.hpp"
|
||||
#include "client/gui/Screen.hpp"
|
||||
#include "network/RakNetInstance.hpp"
|
||||
#include "network/NetEventCallback.hpp"
|
||||
#include "client/player/input/ITurnInput.hpp"
|
||||
#include "client/renderer/GameRenderer.hpp"
|
||||
#include "client/renderer/LevelRenderer.hpp"
|
||||
#include "client/renderer/entity/EntityRenderDispatcher.hpp"
|
||||
#include "client/sound/SoundEngine.hpp"
|
||||
#include "world/level/Level.hpp"
|
||||
#include "world/entity/LocalPlayer.hpp"
|
||||
#include "world/gamemode/GameMode.hpp"
|
||||
#include "world/particle/ParticleEngine.hpp"
|
||||
|
||||
class Screen; // in case we're included from Screen.hpp
|
||||
|
||||
class Minecraft : public App
|
||||
{
|
||||
public:
|
||||
Minecraft();
|
||||
virtual ~Minecraft();
|
||||
|
||||
int getLicenseId();
|
||||
void setScreen(Screen * pScreen);
|
||||
void releaseMouse();
|
||||
void grabMouse();
|
||||
void tick();
|
||||
void tickInput();
|
||||
void saveOptions();
|
||||
void handleMouseClick(int type);
|
||||
void handleMouseDown(int type, bool b);
|
||||
bool isLevelGenerated();
|
||||
void selectLevel(const std::string&, const std::string&, int);
|
||||
void setLevel(Level*, const std::string&, LocalPlayer*);
|
||||
void pauseGame();
|
||||
void leaveGame(bool bCopyMap);
|
||||
void hostMultiplayer();
|
||||
void joinMultiplayer(const PingedCompatibleServer& serverInfo);
|
||||
void cancelLocateMultiplayer();
|
||||
void locateMultiplayer();
|
||||
void tickMouse();
|
||||
void handleCharInput(char chr);
|
||||
void sendMessage(const std::string& message);
|
||||
void resetPlayer(Player* player);
|
||||
void respawnPlayer(Player* player);
|
||||
std::string getVersionString();
|
||||
|
||||
virtual void update() override;
|
||||
virtual void init() override;
|
||||
virtual void onGraphicsReset();
|
||||
virtual void sizeUpdate(int newWidth, int newHeight) override;
|
||||
virtual int getFpsIntlCounter();
|
||||
|
||||
float getBestScaleForThisScreenSize(int width, int height);
|
||||
void generateLevel(const std::string& unused, Level* pLevel);
|
||||
void prepareLevel(const std::string& unused);
|
||||
void _levelGenerated();
|
||||
bool isOnline();
|
||||
bool isOnlineClient();
|
||||
static void* prepareLevel_tspawn(void* pMinecraft);
|
||||
|
||||
const char* getProgressMessage();
|
||||
LevelStorageSource* getLevelSource();
|
||||
ItemInstance* getSelectedItem();
|
||||
Options* getOptions() const { return m_options; }
|
||||
|
||||
static void setGuiScaleMultiplier(float f);
|
||||
|
||||
public:
|
||||
static float guiScaleMultiplier;
|
||||
static int width, height;
|
||||
static bool useAmbientOcclusion;
|
||||
static const char* progressMessages[];
|
||||
static const bool DEADMAU5_CAMERA_CHEATS;
|
||||
static int customDebugId;
|
||||
|
||||
private:
|
||||
Logger *m_Logger;
|
||||
Options *m_options;
|
||||
|
||||
public:
|
||||
bool field_18;
|
||||
bool field_288;
|
||||
LevelRenderer* m_pLevelRenderer;
|
||||
GameRenderer* m_pGameRenderer;
|
||||
ParticleEngine* m_pParticleEngine;
|
||||
SoundEngine* m_pSoundEngine;
|
||||
GameMode* m_pGameMode;
|
||||
Textures* m_pTextures;
|
||||
Font* m_pFont;
|
||||
RakNetInstance* m_pRakNetInstance;
|
||||
NetEventCallback* m_pNetEventCallback;
|
||||
int field_2B0;
|
||||
int field_2B4;
|
||||
int field_2B8;
|
||||
User* m_pUser;
|
||||
Level* m_pLevel;
|
||||
LocalPlayer* m_pLocalPlayer;
|
||||
Mob* m_pMobPersp; // why is there a duplicate?
|
||||
Gui m_gui;
|
||||
int field_D0C;
|
||||
CThread* m_pPrepThread;
|
||||
Screen* m_pScreen;
|
||||
int field_D18;
|
||||
ITurnInput* m_pTurnInput;
|
||||
float field_D20;
|
||||
float field_D24;
|
||||
bool m_bGrabbedMouse;
|
||||
HitResult m_hitResult;
|
||||
int m_progressPercent;
|
||||
std::string m_externalStorageDir;
|
||||
Timer m_timer;
|
||||
bool m_bPreparingLevel;
|
||||
LevelStorageSource* m_pLevelStorageSource; // TODO
|
||||
int field_D9C;
|
||||
int field_DA0;
|
||||
int field_DA4;
|
||||
int field_DA8;
|
||||
int field_DAC;
|
||||
bool m_bUsingScreen;
|
||||
bool m_bHasQueuedScreen;
|
||||
Screen* m_pQueuedScreen;
|
||||
int m_licenseID;
|
||||
ItemInstance m_CurrItemInstance;
|
||||
|
||||
// in 0.8. Offset 3368
|
||||
double m_fDeltaTime, m_fLastUpdated;
|
||||
};
|
||||
|
||||
154
source/client/app/NinecraftApp.cpp
Normal file
154
source/client/app/NinecraftApp.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/********************************************************************
|
||||
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 "NinecraftApp.hpp"
|
||||
#include "world/item/Item.hpp"
|
||||
#include "client/gui/screens/StartMenuScreen.hpp"
|
||||
|
||||
#ifdef DEMO
|
||||
#include "world/level/storage/MemoryLevelStorageSource.hpp"
|
||||
#else
|
||||
#include "world/level/storage/ExternalFileLevelStorageSource.hpp"
|
||||
#endif
|
||||
|
||||
bool NinecraftApp::_hasInitedStatics;
|
||||
|
||||
bool NinecraftApp::handleBack(bool b)
|
||||
{
|
||||
if (m_bPreparingLevel)
|
||||
return true;
|
||||
|
||||
if (!m_pLevel)
|
||||
{
|
||||
if (!m_pScreen)
|
||||
return false;
|
||||
return m_pScreen->handleBackEvent(b);
|
||||
}
|
||||
|
||||
if (b)
|
||||
return 1;
|
||||
|
||||
if (!m_pScreen) return false;
|
||||
|
||||
if (m_pScreen->handleBackEvent(b))
|
||||
return true;
|
||||
|
||||
setScreen(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NinecraftApp::initGLStates()
|
||||
{
|
||||
GL_TEXTURE_2D;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.1f);
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
int NinecraftApp::getFpsIntlCounter()
|
||||
{
|
||||
int ofps = m_fps;
|
||||
m_fps = 0;
|
||||
return ofps;
|
||||
}
|
||||
|
||||
void NinecraftApp::init()
|
||||
{
|
||||
Mth::initMth();
|
||||
|
||||
if (!_hasInitedStatics)
|
||||
{
|
||||
_hasInitedStatics = true;
|
||||
Material::initMaterials();
|
||||
Tile::initTiles();
|
||||
Item::initItems();
|
||||
Biome::initBiomes();
|
||||
}
|
||||
|
||||
initGLStates();
|
||||
Tesselator::instance.init();
|
||||
platform()->initSoundSystem();
|
||||
Minecraft::init();
|
||||
|
||||
#ifdef DEMO
|
||||
m_pLevelStorageSource = new MemoryLevelStorageSource;
|
||||
#else
|
||||
m_pLevelStorageSource = new ExternalFileLevelStorageSource(m_externalStorageDir);
|
||||
#endif
|
||||
|
||||
field_D9C = 0;
|
||||
|
||||
setScreen(new StartMenuScreen);
|
||||
}
|
||||
|
||||
void NinecraftApp::onGraphicsReset()
|
||||
{
|
||||
initGLStates();
|
||||
Tesselator::instance.init();
|
||||
Minecraft::onGraphicsReset();
|
||||
}
|
||||
|
||||
void NinecraftApp::teardown()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NinecraftApp::update()
|
||||
{
|
||||
++m_fps;
|
||||
Minecraft::update();
|
||||
|
||||
#ifdef ORIGINAL_CODE
|
||||
eglSwapBuffers(field_8, m_rotY);
|
||||
#endif
|
||||
|
||||
Mouse::reset2();
|
||||
updateStats();
|
||||
}
|
||||
|
||||
void NinecraftApp::updateStats()
|
||||
{
|
||||
/*
|
||||
int timeMs = getTimeMs();
|
||||
if (timeMs > field_2B0 + 999)
|
||||
{
|
||||
if (m_pLocalPlayer)
|
||||
{
|
||||
Vec3 &pos = m_pLocalPlayer->m_pos;
|
||||
LOG_I("%d fps\t%3d chunk updates. (%.2f, %.2f, %.2f)", m_fps, Chunk::updates, pos.x, pos.y, pos.z);
|
||||
LOG_I("%s", m_pLevelRenderer->gatherStats1().c_str());
|
||||
Chunk::updates = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_I("%d fps", m_fps);
|
||||
}
|
||||
|
||||
field_2B0 = timeMs;
|
||||
m_fps = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
NinecraftApp::NinecraftApp()
|
||||
{
|
||||
field_DBC = 0;
|
||||
field_DC0 = 1;
|
||||
m_fps = 0;
|
||||
}
|
||||
|
||||
NinecraftApp::~NinecraftApp()
|
||||
{
|
||||
teardown();
|
||||
}
|
||||
41
source/client/app/NinecraftApp.hpp
Normal file
41
source/client/app/NinecraftApp.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/********************************************************************
|
||||
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 "client/app/Minecraft.hpp"
|
||||
#include "world/level/Level.hpp"
|
||||
#include "world/tile/Tile.hpp"
|
||||
|
||||
//@TYPO: This is probably meant to say "MinecraftApp". Still not fixed in V0.3.0 though so not sure
|
||||
// This is renamed to MinecraftClient in 0.13.1
|
||||
class NinecraftApp : public Minecraft
|
||||
{
|
||||
public:
|
||||
NinecraftApp();
|
||||
virtual ~NinecraftApp();
|
||||
|
||||
bool handleBack(bool) override;
|
||||
void init() override;
|
||||
void update() override;
|
||||
void onGraphicsReset() override;
|
||||
void teardown();
|
||||
|
||||
void updateStats();
|
||||
void initGLStates();
|
||||
|
||||
int getFpsIntlCounter() override;
|
||||
|
||||
private:
|
||||
int field_DBC;
|
||||
bool field_DC0;
|
||||
int m_fps;
|
||||
|
||||
static bool _hasInitedStatics;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "client/gui/screens/IngameBlockSelectionScreen.hpp"
|
||||
#include "client/gui/screens/ChatScreen.hpp"
|
||||
#include "client/renderer/entity/ItemRenderer.hpp"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "common/Random.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
class Screen;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
class RolledSelectionList : public GuiComponent
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
class ScrolledSelectionList : public GuiComponent
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "TextInputBox.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#ifndef ORIGINAL_CODE
|
||||
|
||||
TextInputBox::TextInputBox(int id, int x, int y, int width, int height, const std::string& placeholder, const std::string& text)
|
||||
@@ -111,16 +111,16 @@ void TextInputBox::keyPressed(Minecraft* minecraft, int key)
|
||||
char chr = '\0';
|
||||
|
||||
// here we'll just use the raw key codes...
|
||||
#ifdef _WIN32
|
||||
#define AKEYCODE_FORWARD_DEL VK_DELETE
|
||||
#define AKEYCODE_ARROW_LEFT VK_LEFT
|
||||
#define AKEYCODE_ARROW_RIGHT VK_RIGHT
|
||||
#define AKEYCODE_DEL VK_BACK
|
||||
#elif defined(USE_SDL)
|
||||
#ifdef USE_SDL
|
||||
#define AKEYCODE_FORWARD_DEL SDLVK_DELETE
|
||||
#define AKEYCODE_ARROW_LEFT SDLVK_LEFT
|
||||
#define AKEYCODE_ARROW_RIGHT SDLVK_RIGHT
|
||||
#define AKEYCODE_DEL SDLVK_BACKSPACE
|
||||
#elif defined(_WIN32)
|
||||
#define AKEYCODE_FORWARD_DEL VK_DELETE
|
||||
#define AKEYCODE_ARROW_LEFT VK_LEFT
|
||||
#define AKEYCODE_ARROW_RIGHT VK_RIGHT
|
||||
#define AKEYCODE_DEL VK_BACK
|
||||
#endif
|
||||
|
||||
switch (key)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "Cube.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
#include "renderer/GL/GL.hpp"
|
||||
|
||||
const float Cube::c = 180.0f / float(M_PI);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "HumanoidModel.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
HumanoidModel::HumanoidModel(float a, float b):
|
||||
m_head(0, 0),
|
||||
|
||||
509
source/client/network/ClientSideNetworkHandler.cpp
Normal file
509
source/client/network/ClientSideNetworkHandler.cpp
Normal file
@@ -0,0 +1,509 @@
|
||||
/********************************************************************
|
||||
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 <RakPeer.h>
|
||||
#include "ClientSideNetworkHandler.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
#include "client/gui/screens/StartMenuScreen.hpp"
|
||||
|
||||
// This lets you make the client shut up and not log events in the debug console.
|
||||
#define VERBOSE_CLIENT
|
||||
|
||||
#if defined(ORIGINAL_CODE) || defined(VERBOSE_CLIENT)
|
||||
#define puts_ignorable(str) LOG_I(str)
|
||||
#define printf_ignorable(str, ...) LOG_I(str, __VA_ARGS__)
|
||||
#else
|
||||
#define puts_ignorable(str)
|
||||
#define printf_ignorable(str, ...)
|
||||
#endif
|
||||
|
||||
ClientSideNetworkHandler::ClientSideNetworkHandler(Minecraft* pMinecraft, RakNetInstance* pRakNetInstance)
|
||||
{
|
||||
m_pMinecraft = pMinecraft;
|
||||
m_pRakNetInstance = pRakNetInstance;
|
||||
m_pServerPeer = m_pRakNetInstance->getPeer();
|
||||
m_chunksRequested = 0;
|
||||
m_serverProtocolVersion = 0;
|
||||
m_pLevel = nullptr;
|
||||
m_field_14 = 0;
|
||||
m_field_24 = 0;
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::levelGenerated(Level* level)
|
||||
{
|
||||
m_pLevel = level;
|
||||
requestNextChunk();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& rakGuid) // server guid
|
||||
{
|
||||
RakNet::RakNetGUID localGuid = ((RakNet::RakPeer*)m_pServerPeer)->GetMyGUID();
|
||||
printf_ignorable("onConnect, server guid: %s, local guid: %s", rakGuid.ToString(), localGuid.ToString());
|
||||
|
||||
m_serverGUID = rakGuid;
|
||||
|
||||
LoginPacket* pLoginPkt = new LoginPacket;
|
||||
pLoginPkt->m_str = RakNet::RakString(m_pMinecraft->m_pUser->field_0.c_str());
|
||||
|
||||
m_pRakNetInstance->send(pLoginPkt);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onUnableToConnect()
|
||||
{
|
||||
puts_ignorable("onUnableToConnect");
|
||||
|
||||
// get rid of the prepare-thread to stop preparation immediately
|
||||
if (m_pMinecraft->m_pPrepThread)
|
||||
{
|
||||
delete m_pMinecraft->m_pPrepThread;
|
||||
m_pMinecraft->m_pPrepThread = nullptr;
|
||||
}
|
||||
|
||||
// throw to the start menu for now
|
||||
m_pMinecraft->setScreen(new StartMenuScreen);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& rakGuid)
|
||||
{
|
||||
puts_ignorable("onDisconnect");
|
||||
|
||||
if (m_pLevel)
|
||||
m_pLevel->m_bIsMultiplayer = false;
|
||||
|
||||
m_pMinecraft->m_gui.addMessage("Disconnected from server");
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, MessagePacket* pMsgPkt)
|
||||
{
|
||||
puts_ignorable("MessagePacket");
|
||||
|
||||
m_pMinecraft->m_gui.addMessage(pMsgPkt->m_str.C_String());
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, StartGamePacket* pStartGamePkt)
|
||||
{
|
||||
puts_ignorable("StartGamePacket");
|
||||
|
||||
m_pMinecraft->getLevelSource()->deleteLevel("_LastJoinedServer");
|
||||
|
||||
m_pLevel = new Level(
|
||||
m_pMinecraft->getLevelSource()->selectLevel("_LastJoinedServer", true),
|
||||
"temp",
|
||||
pStartGamePkt->field_4,
|
||||
pStartGamePkt->field_8);
|
||||
|
||||
m_pLevel->m_bIsMultiplayer = true;
|
||||
|
||||
LocalPlayer *pLocalPlayer = new LocalPlayer(m_pMinecraft, m_pLevel, m_pMinecraft->m_pUser, m_pLevel->m_pDimension->field_50);
|
||||
pLocalPlayer->m_guid = ((RakNet::RakPeer*)m_pServerPeer)->GetMyGUID();
|
||||
pLocalPlayer->m_EntityID = pStartGamePkt->field_C;
|
||||
|
||||
pLocalPlayer->moveTo(
|
||||
pStartGamePkt->field_10,
|
||||
pStartGamePkt->field_14,
|
||||
pStartGamePkt->field_18,
|
||||
pLocalPlayer->m_yaw,
|
||||
pLocalPlayer->m_pitch);
|
||||
|
||||
pLocalPlayer->m_pInventory->prepareCreativeInventory();
|
||||
|
||||
m_pLevel->setTime(pStartGamePkt->m_time);
|
||||
|
||||
m_serverProtocolVersion = pStartGamePkt->m_version;
|
||||
|
||||
m_pMinecraft->setLevel(m_pLevel, "ClientSideNetworkHandler -> setLevel", pLocalPlayer);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, AddPlayerPacket* pAddPlayerPkt)
|
||||
{
|
||||
puts_ignorable("AddPlayerPacket");
|
||||
|
||||
if (!m_pLevel) return;
|
||||
|
||||
Player* pPlayer = new Player(m_pLevel);
|
||||
pPlayer->m_EntityID = pAddPlayerPkt->m_id;
|
||||
m_pLevel->addEntity(pPlayer);
|
||||
|
||||
pPlayer->moveTo(
|
||||
pAddPlayerPkt->m_x,
|
||||
pAddPlayerPkt->m_y,
|
||||
pAddPlayerPkt->m_z,
|
||||
pPlayer->m_yaw,
|
||||
pPlayer->m_pitch);
|
||||
|
||||
pPlayer->m_name = pAddPlayerPkt->m_name;
|
||||
pPlayer->m_guid = pAddPlayerPkt->m_guid;
|
||||
|
||||
pPlayer->m_pInventory->prepareCreativeInventory();
|
||||
|
||||
m_pMinecraft->m_gui.addMessage(pPlayer->m_name + " joined the game");
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, RemoveEntityPacket* pRemoveEntityPkt)
|
||||
{
|
||||
if (!m_pLevel) return;
|
||||
|
||||
Entity* pEnt = m_pLevel->getEntity(pRemoveEntityPkt->m_id);
|
||||
|
||||
#if defined(ORIGINAL_CODE) || UINTPTR_MAX == UINT32_MAX
|
||||
// @NOTE: On x64 systems, this won't print the right things.
|
||||
printf_ignorable("RemoveEntityPacket %d %d", pEnt, m_pMinecraft->m_pLocalPlayer);
|
||||
#else
|
||||
printf_ignorable("RemoveEntityPacket %p %p", pEnt, m_pMinecraft->m_pLocalPlayer);
|
||||
#endif
|
||||
|
||||
if (pEnt)
|
||||
m_pLevel->removeEntity(pEnt);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, MovePlayerPacket* packet)
|
||||
{
|
||||
if (!m_pLevel) return;
|
||||
|
||||
Entity* pEntity = m_pLevel->getEntity(packet->m_id);
|
||||
if (!pEntity)
|
||||
{
|
||||
LOG_E("No player with id %d", packet->m_id);
|
||||
return;
|
||||
}
|
||||
|
||||
pEntity->lerpTo(packet->m_x, packet->m_y, packet->m_z, packet->m_yaw, packet->m_pitch, 3);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, PlaceBlockPacket* pPlaceBlockPkt)
|
||||
{
|
||||
puts_ignorable("PlaceBlockPacket");
|
||||
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(pPlaceBlockPkt->m_playerID);
|
||||
if (!pPlayer)
|
||||
{
|
||||
LOG_E("No player with id %d", pPlaceBlockPkt->m_playerID);
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->swing();
|
||||
|
||||
// @BUG: Not buffering the update.
|
||||
if (!areAllChunksLoaded())
|
||||
return;
|
||||
|
||||
int x = pPlaceBlockPkt->m_x;
|
||||
int y = pPlaceBlockPkt->m_y;
|
||||
int z = pPlaceBlockPkt->m_z;
|
||||
int tile = pPlaceBlockPkt->m_tile;
|
||||
int face = pPlaceBlockPkt->m_face;
|
||||
|
||||
if (!m_pLevel->mayPlace(tile, x, y, z, true))
|
||||
return;
|
||||
|
||||
Tile* pTile = Tile::tiles[tile];
|
||||
if (!m_pLevel->setTile(x, y, z, tile))
|
||||
return;
|
||||
|
||||
Tile::tiles[tile]->setPlacedOnFace(m_pLevel, x, y, z, face);
|
||||
Tile::tiles[tile]->setPlacedBy(m_pLevel, x, y, z, pPlayer);
|
||||
|
||||
const Tile::SoundType* pSound = pTile->m_pSound;
|
||||
m_pLevel->playSound(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f, "step." + pSound->m_name, 0.5f * (1.0f + pSound->field_18), 0.8f * pSound->field_1C);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, RemoveBlockPacket* pRemoveBlockPkt)
|
||||
{
|
||||
puts_ignorable("RemoveBlockPacket");
|
||||
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(pRemoveBlockPkt->m_playerID);
|
||||
if (!pPlayer)
|
||||
{
|
||||
LOG_E("No player with id %d", pRemoveBlockPkt->m_playerID);
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->swing();
|
||||
|
||||
// @BUG: Not buffering the update.
|
||||
if (!areAllChunksLoaded())
|
||||
return;
|
||||
|
||||
int x = pRemoveBlockPkt->m_x;
|
||||
int y = pRemoveBlockPkt->m_y;
|
||||
int z = pRemoveBlockPkt->m_z;
|
||||
|
||||
Tile* pTile = Tile::tiles[m_pLevel->getTile(x, y, z)];
|
||||
int data = m_pLevel->getData(x, y, z);
|
||||
bool setTileResult = m_pLevel->setTile(x, y, z, TILE_AIR);
|
||||
|
||||
if (pTile && setTileResult)
|
||||
{
|
||||
const Tile::SoundType* pSound = pTile->m_pSound;
|
||||
m_pLevel->playSound(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f, "step." + pSound->m_name, 0.5f * (1.0f + pSound->field_18), 0.8f * pSound->field_1C);
|
||||
|
||||
pTile->destroy(m_pLevel, x, y, z, data);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, UpdateBlockPacket* pkt)
|
||||
{
|
||||
if (!areAllChunksLoaded())
|
||||
{
|
||||
m_bufferedBlockUpdates.push_back(SBufferedBlockUpdate(pkt->m_x, pkt->m_y, pkt->m_z, pkt->m_tile, pkt->m_data));
|
||||
return;
|
||||
}
|
||||
|
||||
m_pLevel->setTileAndData(pkt->m_x, pkt->m_y, pkt->m_z, pkt->m_tile, pkt->m_data);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, ChunkDataPacket* pChunkDataPkt)
|
||||
{
|
||||
if (!m_pLevel)
|
||||
{
|
||||
LOG_E("Level @ handle ChunkDataPacket is 0");
|
||||
return;
|
||||
}
|
||||
|
||||
LevelChunk* pChunk = m_pLevel->getChunkSource()->create(pChunkDataPkt->m_x, pChunkDataPkt->m_z);
|
||||
if (!pChunk || pChunk->isEmpty())
|
||||
{
|
||||
LOG_E("Failed to find write-able chunk");
|
||||
// @BUG: Not trying again.
|
||||
return;
|
||||
}
|
||||
|
||||
int x16 = 16 * pChunkDataPkt->m_x;
|
||||
int z16 = 16 * pChunkDataPkt->m_z;
|
||||
|
||||
bool updated = false;
|
||||
|
||||
int minY = 128, maxY = 0;
|
||||
int minX = 16, minZ = 16;
|
||||
int maxX = 0, maxZ = 0;
|
||||
|
||||
for (int k = 0; k < 256; k++)
|
||||
{
|
||||
uint8_t updMap;
|
||||
pChunkDataPkt->m_data.Read(updMap);
|
||||
|
||||
if (!updMap)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if ((updMap >> j) & 1)
|
||||
{
|
||||
int yPos = j * 16;
|
||||
TileID tiles[16];
|
||||
uint8_t datas[16 / 2];
|
||||
|
||||
pChunkDataPkt->m_data.Read((char*)tiles, 16 * sizeof(TileID));
|
||||
pChunkDataPkt->m_data.Read((char*)datas, 16 / 2);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
m_pLevel->setTileNoUpdate(x16 + (k & 0xF), yPos + i, z16 + (k >> 4), tiles[i]);
|
||||
}
|
||||
|
||||
int idx = ((k & 0xF) << 11) | ((k >> 4) << 7) + yPos;
|
||||
memcpy(&pChunk->m_tileData[idx >> 1], datas, sizeof datas);
|
||||
}
|
||||
|
||||
int ymin = 16 * (1 << j);
|
||||
if (minY >= ymin)
|
||||
minY = ymin;
|
||||
if (maxY < ymin + 15)
|
||||
maxY = ymin + 15;
|
||||
}
|
||||
|
||||
if (minX >= (k & 0xF))
|
||||
minX = k & 0xF;
|
||||
if (minZ >= (k >> 4))
|
||||
minZ = k >> 4;
|
||||
if (maxX <= (k & 0xF))
|
||||
maxX = k & 0xF;
|
||||
if (maxZ <= (k >> 4))
|
||||
maxZ = k >> 4;
|
||||
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
m_pLevel->setTilesDirty(minX + x16, minY, minZ, maxX + x16, maxY, maxZ + z16);
|
||||
|
||||
pChunk->m_bUnsaved = true;
|
||||
|
||||
if (m_serverProtocolVersion < 2)
|
||||
{
|
||||
if (areAllChunksLoaded())
|
||||
flushAllBufferedUpdates();
|
||||
else
|
||||
requestNextChunk();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, PlayerEquipmentPacket* pPlayerEquipmentPkt)
|
||||
{
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(pPlayerEquipmentPkt->m_playerID);
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
if (!Item::items[pPlayerEquipmentPkt->m_itemID])
|
||||
{
|
||||
LOG_W("That item %d doesn't actually exist!", pPlayerEquipmentPkt->m_itemID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pPlayer->m_guid == m_pServerPeer->GetMyGUID())
|
||||
{
|
||||
LOG_W("Attempted to modify local player's inventory");
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->m_pInventory->selectItemById(pPlayerEquipmentPkt->m_itemID);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, LevelDataPacket* packet)
|
||||
{
|
||||
const int uncompMagic = 12847812, compMagic = 58712758, chunkSepMagic = 284787658;
|
||||
RakNet::BitStream* bs = &packet->m_data, bs2;
|
||||
|
||||
int magicNum = 0;
|
||||
bs->Read(magicNum);
|
||||
if (magicNum != compMagic && magicNum != uncompMagic)
|
||||
{
|
||||
LOG_E("Invalid level data packet with magic %d", magicNum);
|
||||
return;
|
||||
}
|
||||
|
||||
// If our data is compressed
|
||||
if (magicNum == compMagic)
|
||||
{
|
||||
// Decompress it before we handle it.
|
||||
int uncompSize = 0, compSize = 0;
|
||||
bs->Read(uncompSize);
|
||||
bs->Read(compSize);
|
||||
|
||||
LOG_I("Decompressing level data. Compressed: %d bytes, uncompressed: %d bytes", compSize, uncompSize);
|
||||
|
||||
// Read the compressed data.
|
||||
uint8_t* pCompData = new uint8_t[compSize];
|
||||
bs->Read((char*)pCompData, compSize);
|
||||
|
||||
// Inflate it.
|
||||
uint8_t* pUncompData = ZlibInflateToMemory(pCompData, compSize, uncompSize);
|
||||
SAFE_DELETE_ARRAY(pCompData);
|
||||
|
||||
// If we couldn't, bail
|
||||
if (!pUncompData)
|
||||
{
|
||||
LOG_E("Failed to decompress level data!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Do some small scale hacks to get bs2 contain the uncompressed data.
|
||||
bs2.Reset();
|
||||
bs2.Write((const char*)pUncompData, uncompSize);
|
||||
bs2.ResetReadPointer();
|
||||
bs = &bs2;
|
||||
|
||||
// Delete the uncompressed data, since we've written it to our bitstream.
|
||||
SAFE_DELETE_ARRAY(pUncompData);
|
||||
|
||||
bs->Read(magicNum);
|
||||
}
|
||||
|
||||
int chunksX = 0, chunksZ = 0;
|
||||
bs->Read(chunksX);
|
||||
bs->Read(chunksZ);
|
||||
|
||||
if (chunksX != C_MAX_CHUNKS_X || chunksZ != C_MAX_CHUNKS_Z)
|
||||
{
|
||||
LOG_E("We don't yet support a level of size %d x %d chunks. Some chunks may disappear or be regenerated.", chunksX, chunksZ);
|
||||
}
|
||||
|
||||
for (int x = 0; x < chunksX; x++)
|
||||
{
|
||||
for (int z = 0; z < chunksZ; z++)
|
||||
{
|
||||
bs->Read(magicNum);
|
||||
|
||||
if (magicNum != chunkSepMagic)
|
||||
{
|
||||
_FAIL_BECAUSE_INVALID:
|
||||
LOG_E("Aborting because level data is invalid, reading chunk %d, %d. Magic: %d", x, z, magicNum);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t ptype = 0;
|
||||
|
||||
// read the data size. This'll let us know how much to read.
|
||||
int dataSize = 0;
|
||||
bs->Read(dataSize);
|
||||
|
||||
LevelChunk* pChunk = m_pLevel->getChunk(x, z);
|
||||
if (!pChunk || pChunk->isEmpty())
|
||||
LOG_E("No chunk at %d, %d", x, z);
|
||||
|
||||
// continue reading anyway to skip over the offending chunk
|
||||
|
||||
// Seems like reading a bitstream from another bitstream reads all the way
|
||||
// to the end, so we need to duplicate in this fashion.
|
||||
RakNet::BitStream bs2;
|
||||
bs2.Write(*bs, 8 * dataSize);
|
||||
|
||||
// Ensure the packet type is correct.
|
||||
bs2.Read(ptype);
|
||||
if (ptype != PACKET_CHUNK_DATA)
|
||||
goto _FAIL_BECAUSE_INVALID;
|
||||
|
||||
// Read the chunk data packet itself, and handle it.
|
||||
ChunkDataPacket cdp(x, z, pChunk);
|
||||
cdp.read(&bs2);
|
||||
|
||||
if (pChunk)
|
||||
handle(guid, &cdp);
|
||||
|
||||
// Handle lighting immediately, to ensure it doesn't get out of control.
|
||||
while (m_pLevel->updateLights());
|
||||
}
|
||||
}
|
||||
|
||||
// All chunks are loaded. Also flush all the updates we've buffered.
|
||||
m_chunksRequested = 256;
|
||||
flushAllBufferedUpdates();
|
||||
}
|
||||
|
||||
bool ClientSideNetworkHandler::areAllChunksLoaded()
|
||||
{
|
||||
return m_chunksRequested > 255;
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::requestNextChunk()
|
||||
{
|
||||
if (areAllChunksLoaded())
|
||||
return;
|
||||
|
||||
// @BUG: The return value of areAllChunksLoaded() is actually true even before the
|
||||
// 256th chunk is loaded.
|
||||
|
||||
if (m_serverProtocolVersion < 2)
|
||||
{
|
||||
m_pRakNetInstance->send(new RequestChunkPacket(m_chunksRequested % 16, m_chunksRequested / 16));
|
||||
m_chunksRequested++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pRakNetInstance->send(new RequestChunkPacket(-9999, -9999));
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::flushAllBufferedUpdates()
|
||||
{
|
||||
for (int i = 0; i < int(m_bufferedBlockUpdates.size()); i++)
|
||||
{
|
||||
SBufferedBlockUpdate& u = m_bufferedBlockUpdates[i];
|
||||
m_pLevel->setTileAndData(u.x, u.y, u.z, u.tile, u.data);
|
||||
}
|
||||
}
|
||||
64
source/client/network/ClientSideNetworkHandler.hpp
Normal file
64
source/client/network/ClientSideNetworkHandler.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/********************************************************************
|
||||
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 "network/NetEventCallback.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "network/RakNetInstance.hpp"
|
||||
|
||||
struct SBufferedBlockUpdate
|
||||
{
|
||||
int x, z;
|
||||
uint8_t y;
|
||||
uint8_t tile, data;
|
||||
|
||||
SBufferedBlockUpdate(int x, int y, int z, TileID tile, int data) :
|
||||
x(x), y(uint8_t(y)), z(z), tile(uint8_t(tile)), data(uint8_t(data))
|
||||
{}
|
||||
};
|
||||
|
||||
// @TODO: Rename to ClientNetworkHandler?
|
||||
class ClientSideNetworkHandler : public NetEventCallback
|
||||
{
|
||||
public:
|
||||
ClientSideNetworkHandler(Minecraft*, RakNetInstance*);
|
||||
|
||||
void levelGenerated(Level*) override;
|
||||
void onConnect(const RakNet::RakNetGUID&) override;
|
||||
void onDisconnect(const RakNet::RakNetGUID&) override;
|
||||
void onUnableToConnect() override;
|
||||
void handle(const RakNet::RakNetGUID&, MessagePacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, StartGamePacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, AddPlayerPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, RemoveEntityPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, MovePlayerPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, PlaceBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, RemoveBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, UpdateBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, ChunkDataPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, PlayerEquipmentPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, LevelDataPacket*) override;
|
||||
|
||||
bool areAllChunksLoaded();
|
||||
void requestNextChunk();
|
||||
void flushAllBufferedUpdates(); // inlined
|
||||
|
||||
private:
|
||||
Minecraft* m_pMinecraft;
|
||||
Level* m_pLevel;
|
||||
RakNetInstance* m_pRakNetInstance;
|
||||
RakNet::RakPeerInterface* m_pServerPeer;
|
||||
int m_field_14;
|
||||
RakNet::RakNetGUID m_serverGUID;
|
||||
int m_field_24;
|
||||
std::vector<SBufferedBlockUpdate> m_bufferedBlockUpdates;
|
||||
int m_chunksRequested;
|
||||
int m_serverProtocolVersion;
|
||||
};
|
||||
|
||||
359
source/client/options/Options.cpp
Normal file
359
source/client/options/Options.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
/********************************************************************
|
||||
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 <fstream>
|
||||
|
||||
#include "Options.hpp"
|
||||
#include "common/Util.hpp"
|
||||
#include "compat/KeyCodes.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
Options::Option
|
||||
Options::Option::MUSIC (0, "options.music", true, false),
|
||||
Options::Option::SOUND (1, "options.sound", true, false),
|
||||
Options::Option::INVERT_MOUSE (2, "options.invertMouse", false, true),
|
||||
Options::Option::SENSITIVITY (3, "options.sensitivity", true, false),
|
||||
Options::Option::RENDER_DISTANCE (4, "options.renderDistance", false, false),
|
||||
Options::Option::VIEW_BOBBING (5, "options.viewBobbing", false, true),
|
||||
Options::Option::ANAGLYPH (6, "options.anaglyph", false, true),
|
||||
Options::Option::LIMIT_FRAMERATE (7, "options.limitFramerate", false, true),
|
||||
Options::Option::DIFFICULTY (8, "options.difficulty", false, false),
|
||||
Options::Option::GRAPHICS (9, "options.graphics", false, false),
|
||||
Options::Option::AMBIENT_OCCLUSION(10, "options.ao", false, true),
|
||||
Options::Option::GUI_SCALE (11, "options.guiScale", false, false);
|
||||
|
||||
void Options::_initDefaultValues()
|
||||
{
|
||||
field_238 = 2;
|
||||
field_244 = 1.0f;
|
||||
m_bDontRenderGui = false;
|
||||
field_248 = 1.0f;
|
||||
m_bThirdPerson = false;
|
||||
field_0 = 1.0f;
|
||||
field_23E = 0;
|
||||
m_fMasterVolume = 1.0f;
|
||||
m_bFlyCheat = false;
|
||||
field_241 = 0;
|
||||
field_8 = 0.5f;
|
||||
field_24C = 0;
|
||||
m_bInvertMouse = false;
|
||||
m_bAnaglyphs = false;
|
||||
field_16 = 0;
|
||||
m_bAmbientOcclusion = Minecraft::useAmbientOcclusion;
|
||||
field_240 = 1;
|
||||
m_iViewDistance = 2;
|
||||
m_bViewBobbing = 1;
|
||||
m_bAutoJump = true;
|
||||
m_bFancyGraphics = true;
|
||||
field_19 = 1;
|
||||
field_1C = "Default";
|
||||
m_playerName = "Steve";
|
||||
m_bServerVisibleDefault = true;
|
||||
m_bDebugText = false;
|
||||
|
||||
// Win32 key codes are being used by default
|
||||
#define KM(idx, name, code) m_keyMappings[idx] = KeyMapping(name, code)
|
||||
KM(KM_FORWARD, "key.forward", 'W');
|
||||
KM(KM_LEFT, "key.left", 'A');
|
||||
KM(KM_BACKWARD, "key.back", 'S');
|
||||
KM(KM_RIGHT, "key.right", 'D');
|
||||
KM(KM_JUMP, "key.jump", ' ');
|
||||
KM(KM_INVENTORY, "key.inventory", 'E');
|
||||
KM(KM_DROP, "key.drop", 'Q');
|
||||
KM(KM_CHAT, "key.chat", 'T');
|
||||
KM(KM_FOG, "key.fog", 'F');
|
||||
KM(KM_SNEAK, "key.sneak", 0x10); // VK_SHIFT. In original, it's 10 (misspelling?)
|
||||
KM(KM_DESTROY, "key.destroy", 'K'); // was 'X'
|
||||
KM(KM_PLACE, "key.place", 'L'); // was 'C'
|
||||
KM(KM_MENU_NEXT, "key.menu.next", 0x28); // VK_DOWN
|
||||
KM(KM_MENU_PREVIOUS,"key.menu.previous", 0x26); // VK_UP
|
||||
KM(KM_MENU_OK, "key.menu.ok", 0x0D); // VK_RETURN
|
||||
KM(KM_MENU_CANCEL, "key.menu.cancel", 0x1B); // VK_ESCAPE, was 0x08 = VK_BACK
|
||||
KM(KM_SLOT_1, "key.slot.1", '1');
|
||||
KM(KM_SLOT_2, "key.slot.2", '2');
|
||||
KM(KM_SLOT_3, "key.slot.3", '3');
|
||||
KM(KM_SLOT_4, "key.slot.4", '4');
|
||||
KM(KM_SLOT_5, "key.slot.5", '5');
|
||||
KM(KM_SLOT_6, "key.slot.6", '6');
|
||||
KM(KM_SLOT_7, "key.slot.7", '7');
|
||||
KM(KM_SLOT_8, "key.slot.8", '8');
|
||||
KM(KM_SLOT_9, "key.slot.9", '9');
|
||||
KM(KM_SLOT_L, "key.slot.left", 'Y');
|
||||
KM(KM_SLOT_R, "key.slot.right", 'U');
|
||||
KM(KM_TOGGLEGUI, "key.fn.gui", 0x70); // VK_F1
|
||||
KM(KM_SCREENSHOT, "key.fn.screenshot", 0x71); // VK_F2
|
||||
KM(KM_TOGGLEDEBUG, "key.fn.debug", 0x72); // VK_F3
|
||||
KM(KM_TOGGLEAO, "key.fn.ao", 0x73); // VK_F4
|
||||
KM(KM_TOGGLE3RD, "key.fn.3rd", 0x74); // VK_F5
|
||||
KM(KM_FLY_UP, "key.fly.up", 'X');
|
||||
KM(KM_FLY_DOWN, "key.fly.down", 'C');
|
||||
KM(KM_CHAT_CMD, "key.chat.cmd", 0xBF); // VK_OEM_2
|
||||
#undef KM
|
||||
|
||||
#ifdef ORIGINAL_CODE
|
||||
m_iViewDistance = 2;
|
||||
m_bThirdPerson = 0;
|
||||
field_19 = 0;
|
||||
#endif
|
||||
|
||||
m_bFancyGraphics = 1;
|
||||
|
||||
#define KM(idx,code) m_keyMappings[idx].value = code
|
||||
#ifdef USE_SDL
|
||||
KM(KM_FORWARD, SDLVK_w);
|
||||
KM(KM_LEFT, SDLVK_a);
|
||||
KM(KM_BACKWARD, SDLVK_s);
|
||||
KM(KM_RIGHT, SDLVK_d);
|
||||
KM(KM_JUMP, SDLVK_SPACE);
|
||||
KM(KM_DESTROY, SDLVK_x);
|
||||
KM(KM_PLACE, SDLVK_c);
|
||||
KM(KM_MENU_NEXT, SDLVK_DOWN);
|
||||
KM(KM_MENU_PREVIOUS, SDLVK_UP);
|
||||
KM(KM_MENU_OK, SDLVK_RETURN);
|
||||
KM(KM_MENU_CANCEL, SDLVK_ESCAPE);
|
||||
KM(KM_DROP, SDLVK_q);
|
||||
KM(KM_CHAT, SDLVK_t);
|
||||
KM(KM_FOG, SDLVK_f);
|
||||
KM(KM_INVENTORY, SDLVK_e);
|
||||
KM(KM_SNEAK, SDLVK_LSHIFT);
|
||||
KM(KM_SLOT_1, SDLVK_1);
|
||||
KM(KM_SLOT_2, SDLVK_2);
|
||||
KM(KM_SLOT_3, SDLVK_3);
|
||||
KM(KM_SLOT_4, SDLVK_4);
|
||||
KM(KM_SLOT_5, SDLVK_5);
|
||||
KM(KM_SLOT_6, SDLVK_6);
|
||||
KM(KM_SLOT_7, SDLVK_7);
|
||||
KM(KM_SLOT_8, SDLVK_8);
|
||||
KM(KM_SLOT_9, SDLVK_9);
|
||||
KM(KM_TOGGLEGUI, SDLVK_F1);
|
||||
KM(KM_SCREENSHOT, SDLVK_F2);
|
||||
KM(KM_TOGGLEDEBUG, SDLVK_F3);
|
||||
KM(KM_TOGGLEAO, SDLVK_F4);
|
||||
KM(KM_TOGGLE3RD, SDLVK_F5);
|
||||
KM(KM_SLOT_L, SDLVK_y);
|
||||
KM(KM_SLOT_R, SDLVK_u);
|
||||
KM(KM_FLY_UP, SDLVK_c);
|
||||
KM(KM_FLY_DOWN, SDLVK_x);
|
||||
KM(KM_CHAT_CMD, SDLVK_SLASH);
|
||||
#endif
|
||||
#ifdef PLATFORM_ANDROID
|
||||
// -- Original xperia play controls
|
||||
//KM(KM_FORWARD, AKEYCODE_DPAD_UP);
|
||||
//KM(KM_LEFT, AKEYCODE_DPAD_LEFT);
|
||||
//KM(KM_BACKWARD, AKEYCODE_DPAD_DOWN);
|
||||
//KM(KM_RIGHT, AKEYCODE_DPAD_RIGHT);
|
||||
//KM(KM_JUMP, AKEYCODE_DPAD_CENTER);
|
||||
//KM(KM_DESTROY, AKEYCODE_BUTTON_L1);
|
||||
//KM(KM_PLACE, AKEYCODE_BUTTON_R1);
|
||||
//KM(KM_MENU_NEXT, AKEYCODE_DPAD_DOWN);
|
||||
//KM(KM_MENU_PREVIOUS, AKEYCODE_DPAD_UP);
|
||||
//KM(KM_MENU_OK, AKEYCODE_DPAD_CENTER);
|
||||
//KM(KM_MENU_CANCEL, AKEYCODE_BACK);
|
||||
//custom
|
||||
//KM(KM_INVENTORY, AKEYCODE_BUTTON_Y);
|
||||
//KM(KM_SLOT_R, AKEYCODE_BACK);
|
||||
//KM(KM_SLOT_L, AKEYCODE_BUTTON_X);
|
||||
//KM(KM_FLY_UP, AKEYCODE_BUTTON_R1);
|
||||
//KM(KM_FLY_DOWN, AKEYCODE_BUTTON_L1);
|
||||
|
||||
KM(KM_FORWARD, AKEYCODE_W);
|
||||
KM(KM_LEFT, AKEYCODE_A);
|
||||
KM(KM_BACKWARD, AKEYCODE_S);
|
||||
KM(KM_RIGHT, AKEYCODE_D);
|
||||
KM(KM_JUMP, AKEYCODE_SPACE);
|
||||
KM(KM_DESTROY, AKEYCODE_X);
|
||||
KM(KM_PLACE, AKEYCODE_C);
|
||||
KM(KM_MENU_NEXT, AKEYCODE_DPAD_DOWN);
|
||||
KM(KM_MENU_PREVIOUS, AKEYCODE_DPAD_UP);
|
||||
KM(KM_MENU_OK, AKEYCODE_ENTER);
|
||||
KM(KM_MENU_CANCEL, AKEYCODE_ESCAPE);
|
||||
// custom
|
||||
KM(KM_SLOT_L, AKEYCODE_Y);
|
||||
KM(KM_SLOT_R, AKEYCODE_U);
|
||||
KM(KM_DROP, AKEYCODE_Q);
|
||||
KM(KM_CHAT, AKEYCODE_T);
|
||||
KM(KM_FOG, AKEYCODE_F);
|
||||
KM(KM_INVENTORY, AKEYCODE_F);
|
||||
KM(KM_SNEAK, AKEYCODE_SHIFT_LEFT);
|
||||
KM(KM_SLOT_1, AKEYCODE_1);
|
||||
KM(KM_SLOT_2, AKEYCODE_2);
|
||||
KM(KM_SLOT_3, AKEYCODE_3);
|
||||
KM(KM_SLOT_4, AKEYCODE_4);
|
||||
KM(KM_SLOT_5, AKEYCODE_5);
|
||||
KM(KM_SLOT_6, AKEYCODE_6);
|
||||
KM(KM_SLOT_7, AKEYCODE_7);
|
||||
KM(KM_SLOT_8, AKEYCODE_8);
|
||||
KM(KM_SLOT_9, AKEYCODE_9);
|
||||
KM(KM_TOGGLEGUI, AKEYCODE_F1);
|
||||
KM(KM_SCREENSHOT, AKEYCODE_F2);
|
||||
KM(KM_TOGGLEDEBUG, AKEYCODE_F3);
|
||||
KM(KM_TOGGLEAO, AKEYCODE_F4);
|
||||
KM(KM_TOGGLE3RD, AKEYCODE_F5);
|
||||
KM(KM_FLY_UP, AKEYCODE_C);
|
||||
KM(KM_FLY_DOWN, AKEYCODE_X);
|
||||
KM(KM_CHAT_CMD, AKEYCODE_SLASH);
|
||||
#endif
|
||||
#undef KM
|
||||
}
|
||||
|
||||
Options::Options()
|
||||
{
|
||||
_initDefaultValues();
|
||||
}
|
||||
|
||||
Options::Options(const std::string& folderPath)
|
||||
{
|
||||
m_filePath = folderPath + "/options.txt";
|
||||
_initDefaultValues();
|
||||
_load();
|
||||
}
|
||||
|
||||
std::string getMessage(const Options::Option& option)
|
||||
{
|
||||
return "Options::getMessage - Not implemented";
|
||||
}
|
||||
|
||||
void Options::_load()
|
||||
{
|
||||
std::vector<std::string> strings = readPropertiesFromFile(m_filePath);
|
||||
|
||||
for (int i = 0; i < strings.size(); i += 2)
|
||||
{
|
||||
std::string key = strings[i], value = strings[i + 1];
|
||||
|
||||
if (key == "mp_username")
|
||||
m_playerName = value;
|
||||
else if (key == "ctrl_invertmouse")
|
||||
m_bInvertMouse = readBool(value);
|
||||
else if (key == "ctrl_autojump")
|
||||
m_bAutoJump = readBool(value);
|
||||
else if (key == "gfx_fancygraphics")
|
||||
m_bFancyGraphics = readBool(value);
|
||||
else if (key == "mp_server_visible_default")
|
||||
m_bServerVisibleDefault = readBool(value);
|
||||
else if (key == "gfx_smoothlighting")
|
||||
Minecraft::useAmbientOcclusion = m_bAmbientOcclusion = readBool(value);
|
||||
else if (key == "gfx_viewdistance")
|
||||
m_iViewDistance = readInt(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Options::save()
|
||||
{
|
||||
savePropertiesToFile(m_filePath, getOptionStrings());
|
||||
}
|
||||
|
||||
std::string Options::getMessage(const Options::Option& option)
|
||||
{
|
||||
return "Options::getMessage - Not implemented";
|
||||
}
|
||||
|
||||
bool Options::readBool(const std::string& str)
|
||||
{
|
||||
std::string trimmed = Util::stringTrim(str);
|
||||
if (trimmed == "true" || trimmed == "1")
|
||||
return true;
|
||||
if (trimmed == "false" || trimmed == "0")
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Options::readInt(const std::string& str)
|
||||
{
|
||||
int f;
|
||||
|
||||
if (!sscanf(str.c_str(), "%d", &f))
|
||||
f = 0;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
std::string Options::saveBool(bool b)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string Options::saveInt(int i)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << i;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> Options::readPropertiesFromFile(const std::string& filePath)
|
||||
{
|
||||
std::vector<std::string> o;
|
||||
|
||||
const char* const path = filePath.c_str();
|
||||
LOG_I("Loading options from %s", path);
|
||||
|
||||
std::ifstream ifs(path);
|
||||
if (!ifs.is_open())
|
||||
{
|
||||
LOG_W("%s doesn't exist, resetting to defaults", path);
|
||||
return o;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
while (true)
|
||||
{
|
||||
if (!std::getline(ifs, str, '\n'))
|
||||
break;
|
||||
|
||||
if (str.empty() || str[0] == '#')
|
||||
continue;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << str;
|
||||
|
||||
std::string key, value;
|
||||
if (std::getline(ss, key, ':') && std::getline(ss, value))
|
||||
{
|
||||
o.push_back(key);
|
||||
o.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
void Options::savePropertiesToFile(const std::string& filePath, std::vector<std::string> properties)
|
||||
{
|
||||
assert(properties.size() % 2 == 0);
|
||||
|
||||
std::ofstream os;
|
||||
os.open(filePath.c_str());
|
||||
if (!os.is_open())
|
||||
{
|
||||
LOG_E("Failed to read %s", filePath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
os << "#Config file for Minecraft PE. The # at the start denotes a comment, removing it makes it a command.\n\n";
|
||||
|
||||
for (int i = 0; i < properties.size(); i += 2)
|
||||
os << properties[i] << ':' << properties[i + 1] << '\n';
|
||||
}
|
||||
|
||||
std::vector<std::string> Options::getOptionStrings()
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
|
||||
#define SO(optname, value) do { vec.push_back(optname); vec.push_back(value); } while (0)
|
||||
|
||||
SO("mp_username", m_playerName);
|
||||
SO("ctrl_invertmouse", saveBool(m_bInvertMouse));
|
||||
SO("ctrl_autojump", saveBool(m_bAutoJump));
|
||||
SO("gfx_fancygraphics", saveBool(m_bFancyGraphics));
|
||||
SO("mp_server_visible_default", saveBool(m_bServerVisibleDefault));
|
||||
SO("gfx_smoothlighting", saveBool(m_bAmbientOcclusion));
|
||||
SO("gfx_viewdistance", saveInt (m_iViewDistance));
|
||||
|
||||
return vec;
|
||||
}
|
||||
153
source/client/options/Options.hpp
Normal file
153
source/client/options/Options.hpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/********************************************************************
|
||||
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 <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum eKeyMappingIndex
|
||||
{
|
||||
KM_FORWARD,
|
||||
KM_LEFT,
|
||||
KM_BACKWARD,
|
||||
KM_RIGHT,
|
||||
KM_JUMP,
|
||||
KM_INVENTORY,
|
||||
KM_DROP,
|
||||
KM_CHAT,
|
||||
KM_FOG,
|
||||
KM_SNEAK,
|
||||
KM_DESTROY,
|
||||
KM_PLACE,
|
||||
KM_MENU_NEXT,
|
||||
KM_MENU_PREVIOUS,
|
||||
KM_MENU_OK,
|
||||
KM_MENU_CANCEL, KM_BACK = KM_MENU_CANCEL,
|
||||
KM_SLOT_1,
|
||||
KM_SLOT_2,
|
||||
KM_SLOT_3,
|
||||
KM_SLOT_4,
|
||||
KM_SLOT_5,
|
||||
KM_SLOT_6,
|
||||
KM_SLOT_7,
|
||||
KM_SLOT_8,
|
||||
KM_SLOT_9,
|
||||
KM_SLOT_L,
|
||||
KM_SLOT_R,
|
||||
KM_TOGGLEGUI,
|
||||
KM_SCREENSHOT,
|
||||
KM_TOGGLEDEBUG,
|
||||
KM_TOGGLEAO,
|
||||
KM_TOGGLE3RD,
|
||||
KM_FLY_UP,
|
||||
KM_FLY_DOWN,
|
||||
KM_CHAT_CMD, // called "Open Chat" in Release 1.8
|
||||
KM_COUNT,
|
||||
};
|
||||
|
||||
struct KeyMapping
|
||||
{
|
||||
std::string key;
|
||||
int value;
|
||||
|
||||
KeyMapping() {}
|
||||
KeyMapping(const char* keyName, int keyCode) : key(keyName), value(keyCode) {}
|
||||
};
|
||||
|
||||
class Options
|
||||
{
|
||||
public:
|
||||
struct Option;
|
||||
struct KeyBind;
|
||||
private:
|
||||
static bool readBool(const std::string& str);
|
||||
static int readInt(const std::string& str);
|
||||
static std::string saveBool(bool b);
|
||||
static std::string saveInt(int i);
|
||||
static std::vector<std::string> readPropertiesFromFile(const std::string& filePath);
|
||||
static void savePropertiesToFile(const std::string& filePath, std::vector<std::string> properties);
|
||||
|
||||
private:
|
||||
void _initDefaultValues();
|
||||
void _load();
|
||||
public:
|
||||
Options();
|
||||
Options(const std::string& folderPath);
|
||||
void save();
|
||||
std::string getMessage(const Options::Option&);
|
||||
std::vector<std::string> getOptionStrings();
|
||||
|
||||
int getKey(eKeyMappingIndex idx)
|
||||
{
|
||||
return m_keyMappings[idx].value;
|
||||
}
|
||||
bool isKey(eKeyMappingIndex idx, int keyCode)
|
||||
{
|
||||
return getKey(idx) == keyCode;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_filePath;
|
||||
|
||||
public:
|
||||
float field_0;
|
||||
float m_fMasterVolume;
|
||||
float field_8;
|
||||
bool m_bInvertMouse;
|
||||
int m_iViewDistance;
|
||||
bool m_bViewBobbing;
|
||||
bool m_bAnaglyphs;
|
||||
uint8_t field_16;
|
||||
bool m_bFancyGraphics;
|
||||
bool m_bAmbientOcclusion;
|
||||
uint8_t field_19;
|
||||
std::string field_1C;
|
||||
KeyMapping m_keyMappings[KM_COUNT];
|
||||
int field_238;
|
||||
bool m_bDontRenderGui;
|
||||
bool m_bThirdPerson;
|
||||
uint8_t field_23E;
|
||||
bool m_bFlyCheat;
|
||||
uint8_t field_240;
|
||||
uint8_t field_241;
|
||||
float field_244;
|
||||
float field_248;
|
||||
int field_24C;
|
||||
std::string m_playerName;
|
||||
bool m_bServerVisibleDefault;
|
||||
bool m_bAutoJump;
|
||||
bool m_bDebugText;
|
||||
|
||||
public:
|
||||
struct Option
|
||||
{
|
||||
bool field_0;
|
||||
bool field_1;
|
||||
std::string str;
|
||||
int field_1C;
|
||||
|
||||
Option(int i, const std::string& str, bool b1, bool b2) : field_0(b1), field_1(b2), str(str), field_1C(i) {}
|
||||
|
||||
static Option MUSIC;
|
||||
static Option SOUND;
|
||||
static Option INVERT_MOUSE;
|
||||
static Option SENSITIVITY;
|
||||
static Option RENDER_DISTANCE;
|
||||
static Option VIEW_BOBBING;
|
||||
static Option ANAGLYPH;
|
||||
static Option LIMIT_FRAMERATE;
|
||||
static Option DIFFICULTY;
|
||||
static Option GRAPHICS;
|
||||
static Option AMBIENT_OCCLUSION;
|
||||
static Option GUI_SCALE;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Options.hpp"
|
||||
#include "client/options/Options.hpp"
|
||||
|
||||
class KeyboardInput
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITurnInput.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
class Minecraft;
|
||||
|
||||
class MouseTurnInput : public ITurnInput
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Textures.hpp"
|
||||
#include "common/Options.hpp"
|
||||
#include "client/options/Options.hpp"
|
||||
|
||||
class Font
|
||||
{
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "compat/GL.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
#include "GameRenderer.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "Frustum.hpp"
|
||||
|
||||
int t_keepPic;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "ItemInHandRenderer.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
ItemInHandRenderer::ItemInHandRenderer(Minecraft* pMC) :
|
||||
m_ItemInstance(0, 1, 0),
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "LevelRenderer.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "renderer/GL/GL.hpp"
|
||||
#include "world/tile/LeafTile.hpp"
|
||||
|
||||
LevelRenderer::LevelRenderer(Minecraft* pMC, Textures* pTexs)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include "compat/GL.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
#include "world/level/LevelListener.hpp"
|
||||
#include "Textures.hpp"
|
||||
#include "RenderList.hpp"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "PatchManager.hpp"
|
||||
#include "AppPlatform.hpp"
|
||||
#include "client/app/AppPlatform.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
#include "world/tile/Tile.hpp"
|
||||
#include "world/item/Item.hpp"
|
||||
#include "compat/GL.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
|
||||
#define PM_SEPARATOR ('|')
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "compat/GL.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
|
||||
class RenderChunk
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "Tesselator.hpp"
|
||||
#include "compat/GL.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include "compat/GL.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
#include "RenderChunk.hpp"
|
||||
|
||||
#define GET_RED(c) (uint8_t(((c) >> 0) & 0xFF))
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
|
||||
#include "compat/GL.hpp"
|
||||
#include "common/Options.hpp"
|
||||
#include "AppPlatform.hpp"
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
#include "client/options/Options.hpp"
|
||||
#include "client/app/AppPlatform.hpp"
|
||||
#include "DynamicTexture.hpp"
|
||||
|
||||
class DynamicTexture; // in case we are being included from DynamicTexture. We don't store complete references to that
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "TileRenderer.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "client/renderer/PatchManager.hpp"
|
||||
#include "world/tile/FireTile.hpp"
|
||||
#include "world/tile/LiquidTile.hpp"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "EntityRenderDispatcher.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "../ItemInHandRenderer.hpp"
|
||||
|
||||
EntityRenderDispatcher* EntityRenderDispatcher::instance;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "HumanoidMobRenderer.hpp"
|
||||
#include "EntityRenderDispatcher.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "client/renderer/ItemInHandRenderer.hpp"
|
||||
#include "client/renderer/TileRenderer.hpp"
|
||||
#include "world/entity/Player.hpp"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "MobRenderer.hpp"
|
||||
#include "EntityRenderDispatcher.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
MobRenderer::MobRenderer(Model* pModel, float f)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "TripodCameraRenderer.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
|
||||
TripodCameraRenderer::TripodCameraRenderer() :
|
||||
m_tile(),
|
||||
|
||||
@@ -9,14 +9,13 @@
|
||||
#include "SoundEngine.hpp"
|
||||
#include "SoundDefs.hpp"
|
||||
|
||||
SoundEngine::SoundEngine()
|
||||
SoundEngine::SoundEngine(SoundSystem* soundSystem)
|
||||
{
|
||||
field_40 = 0;
|
||||
field_A1C = 0;
|
||||
#ifndef ORIGINAL_CODE
|
||||
m_pOptions = nullptr;
|
||||
field_A20 = 0;
|
||||
#endif
|
||||
m_pSoundSystem = soundSystem;
|
||||
}
|
||||
|
||||
void SoundEngine::init(Options* options)
|
||||
@@ -67,7 +66,7 @@ void SoundEngine::play(const std::string& name)
|
||||
SoundDesc sd;
|
||||
|
||||
if (m_repository.get(name, sd)) {
|
||||
m_soundSystem.playAt(sd, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
m_pSoundSystem->playAt(sd, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +78,6 @@ void SoundEngine::play(const std::string& name, float x, float y, float z, float
|
||||
SoundDesc sd;
|
||||
|
||||
if (m_repository.get(name, sd)) {
|
||||
m_soundSystem.playAt(sd, x, y, z, volume, pitch);
|
||||
m_pSoundSystem->playAt(sd, x, y, z, volume, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,23 +8,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Options.hpp"
|
||||
#include "client/options/Options.hpp"
|
||||
#include "common/Random.hpp"
|
||||
#include "SoundSystem.hpp"
|
||||
#include "SoundRepository.hpp"
|
||||
|
||||
#include "platforms/PlatformDefinitions.hpp"
|
||||
|
||||
class SoundEngine
|
||||
{
|
||||
public:
|
||||
SoundEngine();
|
||||
SoundEngine(SoundSystem* soundSystem);
|
||||
void init(Options*);
|
||||
void play(const std::string& name);
|
||||
void play(const std::string& name, float x, float y, float z, float volume, float pitch);
|
||||
|
||||
public:
|
||||
SOUND_SYSTEM_TYPE m_soundSystem;
|
||||
SoundSystem* m_pSoundSystem;
|
||||
Options* m_pOptions;
|
||||
int field_40;
|
||||
Random m_random;
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
#include "SoundSystem.hpp"
|
||||
|
||||
SoundSystem::~SoundSystem()
|
||||
{
|
||||
}
|
||||
|
||||
bool SoundSystem::isAvailable()
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
class SoundSystem
|
||||
{
|
||||
public:
|
||||
virtual ~SoundSystem();
|
||||
|
||||
virtual bool isAvailable();
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float yaw, float pitch);
|
||||
|
||||
Reference in New Issue
Block a user