mcpe/source/common/Utils.cpp

406 lines
7.4 KiB
C++
Raw Normal View History

2023-07-30 22:22:02 +03:00
/********************************************************************
Minecraft: Pocket Edition - Decompilation Project
Copyright (C) 2023 iProgramInCpp
2023-07-30 22:41:09 +03:00
The following code is licensed under the BSD 1 clause license.
SPDX-License-Identifier: BSD-1-Clause
2023-07-30 22:22:02 +03:00
********************************************************************/
// note: not an official file name
#include "common/Utils.hpp"
2023-07-30 22:22:02 +03:00
#if defined(_WIN32) && !defined(_XBOX)
#define WIN32_LEAN_AND_MEAN
2023-07-30 22:22:02 +03:00
#include <Windows.h>
#include <io.h>
#include <direct.h>
2023-07-30 22:22:02 +03:00
// Why are we not using GetTickCount64()? It's simple -- getTimeMs has the exact same problem as using regular old GetTickCount.
#pragma warning(disable : 28159)
#elif defined(_XBOX)
2023-07-30 22:22:02 +03:00
#else
2023-07-30 22:22:02 +03:00
#include <sys/time.h>
#include <unistd.h>
#include <sys/stat.h>
2023-07-30 22:22:02 +03:00
#endif
// include zlib stuff
WIP Android Port (#79) * WIP Android Port Android port. Still needs touch controls and mouse turning (if that's even possible on android) and file saving and SoundSystemSL You control the camera and movement with your controller for now. You can navigate the gui using touch. Options.cpp,LocalPlayer.cpp,Minecraft.cpp is configured to use controller. Blocked out some code in ControllerTurnInput.cpp,Controller.cpp that didn't make sense. * Fix glClear glClear is supossed to use GL_DEPTH_BUFFER_BIT (thx TheBrokenRail) * * Fix build. * * Ignore assets. * * More stuff * * Fix more build errors. * * It finally built What I needed to do is rebuild the debug keystore because apparently android studio created it with sha1 digest alg which isn't supported by ant * * Clean up filters. * * Add cramped mode to the pause screen. * * Fix a bug with the hotbar * * In NinecraftApp::handleBack, pause the game if there is no screen. * * AppPlatform_android: Add placeholder SoundSystem instance till we get SoundSystemSL working * * Add properly working touch code. * * Oh, remove some testing things * * Fix state resetting when going in background and back in foreground * Fix bug where the sky isn't being regenerated on graphics reset * Fix bug where the m_currBoundTex isn't reset in Textures::clear potentially leaving a texture with that ID unassigned and corrupted * Fix bug in CThread where the thread is detached and then also joined. * Don't log anything if the program isn't in debug mode. * * Add virtual keyboard support. The screen instance slides so that the focused text box is kept visible. * Rename from com.minecraftcpp to com.reminecraftpe --------- Co-authored-by: iProgramInCpp <iprogramincpp@gmail.com>
2023-11-03 11:54:39 +01:00
// cant get zlib to build on android, they include prebuilt one anyways. using that one
#include "zlib.h"
2023-07-30 22:22:02 +03:00
int g_TimeSecondsOnInit = 0;
WIP Android Port (#79) * WIP Android Port Android port. Still needs touch controls and mouse turning (if that's even possible on android) and file saving and SoundSystemSL You control the camera and movement with your controller for now. You can navigate the gui using touch. Options.cpp,LocalPlayer.cpp,Minecraft.cpp is configured to use controller. Blocked out some code in ControllerTurnInput.cpp,Controller.cpp that didn't make sense. * Fix glClear glClear is supossed to use GL_DEPTH_BUFFER_BIT (thx TheBrokenRail) * * Fix build. * * Ignore assets. * * More stuff * * Fix more build errors. * * It finally built What I needed to do is rebuild the debug keystore because apparently android studio created it with sha1 digest alg which isn't supported by ant * * Clean up filters. * * Add cramped mode to the pause screen. * * Fix a bug with the hotbar * * In NinecraftApp::handleBack, pause the game if there is no screen. * * AppPlatform_android: Add placeholder SoundSystem instance till we get SoundSystemSL working * * Add properly working touch code. * * Oh, remove some testing things * * Fix state resetting when going in background and back in foreground * Fix bug where the sky isn't being regenerated on graphics reset * Fix bug where the m_currBoundTex isn't reset in Textures::clear potentially leaving a texture with that ID unassigned and corrupted * Fix bug in CThread where the thread is detached and then also joined. * Don't log anything if the program isn't in debug mode. * * Add virtual keyboard support. The screen instance slides so that the focused text box is kept visible. * Rename from com.minecraftcpp to com.reminecraftpe --------- Co-authored-by: iProgramInCpp <iprogramincpp@gmail.com>
2023-11-03 11:54:39 +01:00
#if (!defined(USE_SDL) || defined(_WIN32)) && !defined(__ANDROID__)
2023-08-05 01:58:24 -04:00
2023-08-02 13:15:25 +03:00
DIR* opendir(const char* name)
{
size_t len = strlen(name);
if (len == 0)
return NULL;
char buf[1024];
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>
2023-10-22 02:08:59 -05:00
if (len >= sizeof(buf) - 5)
2023-08-02 13:15:25 +03:00
return NULL;
strcpy(buf, name);
if (name[len - 1] != '/')
strcpy(&buf[len], "/*");
else
strcpy(&buf[len], "*");
DIR* pDir = (DIR*)malloc(sizeof(DIR));
if (!pDir)
return pDir;
memset(pDir, 0, sizeof * pDir);
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>
2023-10-22 02:08:59 -05:00
// Stupid Unicode bullshit
//LPTSTR msBuff;
//mbstowcs(&msBuff, buf, sizeof(buf));
2023-08-02 13:15:25 +03:00
pDir->current = FindFirstFile(buf, &pDir->findData);
if (pDir->current == INVALID_HANDLE_VALUE)
{
free(pDir);
return NULL;
}
return pDir;
}
dirent* readdir(DIR* dir)
{
if (dir->current == INVALID_HANDLE_VALUE)
return NULL;
static dirent de;
if (!dir->returnedFirstFileData)
{
dir->returnedFirstFileData = true;
}
else
{
if (!FindNextFile(dir->current, &dir->findData))
return NULL;
}
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>
2023-10-22 02:08:59 -05:00
LPTSTR fileName = dir->findData.cFileName;
// Stupid Unicode bullshit
//char* fileName;
//wcstombs(fileName, fileNameMs, 255);
strcpy(de.d_name, fileName);
2023-08-02 13:15:25 +03:00
de.d_type = (dir->findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;
return &de;
}
void closedir(DIR* dir)
{
if (dir->current != INVALID_HANDLE_VALUE)
FindClose(dir->current);
free(dir);
}
2023-08-05 01:58:24 -04:00
#else
#include <sys/types.h>
#include <dirent.h>
#endif
bool createFolderIfNotExists(const char* pDir)
{
if (!XPL_ACCESS(pDir, 0))
return true;
return XPL_MKDIR(pDir, 0755) == 0;
}
2023-08-23 12:40:05 +03:00
bool DeleteDirectory(const std::string& name2, bool unused)
2023-08-02 13:15:25 +03:00
{
2023-08-23 12:40:05 +03:00
std::string name = name2;
if (name.empty())
return false;
if (name[name.size() - 1] == '/')
name.resize(name.size() - 1);
2023-08-02 13:15:25 +03:00
DIR* dir = opendir(name.c_str());
if (!dir)
return false;
while (true)
{
dirent* de = readdir(dir);
if (!de)
break;
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
2023-08-23 12:40:05 +03:00
const std::string dirPath = name + "/" + de->d_name;
remove(dirPath.c_str());
2023-08-02 13:15:25 +03:00
}
closedir(dir);
2023-08-23 12:40:05 +03:00
#ifdef _WIN32
return RemoveDirectoryA(name.c_str());
#else
2023-08-02 13:15:25 +03:00
return remove(name.c_str()) == 0;
2023-08-23 12:40:05 +03:00
#endif
2023-08-02 13:15:25 +03:00
}
2023-07-30 22:22:02 +03:00
const char* GetTerrainName()
{
return "terrain.png";
}
const char* GetItemsName()
{
return "gui/items.png";
}
const char* GetGUIBlocksName()
{
return "gui/gui_blocks.png";
}
// In regular mode, getTimeMs depends on getTimeS.
// In Win32 mode, it's vice versa. Cool
int getTimeMs();
float getTimeS()
{
#ifdef _WIN32
return float(getTimeMs()) / 1000.0f;
#else
// variant implemented by Mojang. This does not work on MSVC
timeval tv;
gettimeofday(&tv, NULL);
if (g_TimeSecondsOnInit == 0)
g_TimeSecondsOnInit = tv.tv_sec;
return float(tv.tv_sec - g_TimeSecondsOnInit) + float(tv.tv_usec) / 1000000.0f;
#endif
}
int getTimeMs()
{
#ifdef _WIN32
// just return GetTickCount
int time = GetTickCount();
if (g_TimeSecondsOnInit == 0)
g_TimeSecondsOnInit = time;
return time - g_TimeSecondsOnInit;
#else
return int(getTimeS() * 1000.0f);
#endif
}
time_t getRawTimeS()
{
#ifdef _WIN32
return time_t(GetTickCount() / 1000);
#else
timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec;
#endif
}
time_t getEpochTimeS()
{
return time(0);
}
#ifdef _WIN32
HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL;
void SetInstance(HINSTANCE hinst)
{
g_hInstance = hinst;
}
HINSTANCE GetInstance()
{
return g_hInstance;
}
void SetHWND(HWND hwnd)
{
g_hWnd = hwnd;
}
HWND GetHWND()
{
return g_hWnd;
}
void CenterWindow(HWND hWnd)
{
RECT r, desk;
GetWindowRect(hWnd, &r);
GetWindowRect(GetDesktopWindow(), &desk);
int wa, ha, wb, hb;
wa = (r.right - r.left) / 2;
ha = (r.bottom - r.top) / 2;
wb = (desk.right - desk.left) / 2;
hb = (desk.bottom - desk.top) / 2;
SetWindowPos(hWnd, NULL, wb - wa, hb - ha, r.right - r.left, r.bottom - r.top, 0);
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC(hwnd);
/* set the pixel format for the DC */
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
2023-07-30 22:22:02 +03:00
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 8;
2023-07-30 22:22:02 +03:00
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
void DisableOpenGL(HWND hwnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
}
void sleepMs(int ms)
{
#ifdef _WIN32
Sleep(ms);
#else
usleep(1000 * ms);
#endif
}
#endif
float Max(float a, float b)
{
if (a < b)
a = b;
return a;
}
// zlib stuff
uint8_t* ZlibInflateToMemory(uint8_t* pInput, size_t compressedSize, size_t decompressedSize)
{
int ret;
z_stream strm;
memset(&strm, 0, sizeof strm);
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
// initialize the inflation state machine
ret = inflateInit(&strm);
if (ret != Z_OK)
return nullptr;
uint8_t* pDestBuff = new uint8_t[decompressedSize + 1]; //room for extra null at the end;
pDestBuff[decompressedSize] = 0; //add the extra null, if we decompressed a text file this can be useful
strm.avail_in = compressedSize;
strm.next_in = pInput;
strm.avail_out = decompressedSize;
strm.next_out = pDestBuff;
ret = inflate(&strm, Z_NO_FLUSH);
if (!(ret == Z_OK || ret == Z_STREAM_END))
{
SAFE_DELETE_ARRAY(pDestBuff);
return nullptr;
}
(void)inflateEnd(&strm);
return pDestBuff;
}
uint8_t* ZlibDeflateToMemory(uint8_t* pInput, size_t sizeBytes, size_t* compressedSizeOut)
{
return ZlibDeflateToMemoryLvl(pInput, sizeBytes, compressedSizeOut, Z_DEFAULT_COMPRESSION);
}
uint8_t* ZlibDeflateToMemoryLvl(uint8_t* pInput, size_t sizeBytes, size_t* compressedSizeOut, int level)
{
z_stream strm;
memset(&strm, 0, sizeof strm);
int ret;
// initialize deflate state
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
// initialize deflation state machine
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return nullptr;
// padding bytes in case our compressed output is larger than the raw input for some reason
const int ZLIB_PADDING_BYTES = (1024 * 5);
uint8_t* pOut = new uint8_t[sizeBytes + ZLIB_PADDING_BYTES];
strm.avail_in = sizeBytes;
strm.next_in = pInput;
strm.avail_out = sizeBytes + ZLIB_PADDING_BYTES;
strm.next_out = pOut;
ret = deflate(&strm, Z_FINISH);
assert(ret != Z_STREAM_ERROR);
deflateEnd(&strm);
*compressedSizeOut = strm.total_out;
return pOut;
}