diff --git a/.gitignore b/.gitignore index f840877..2664d8a 100644 --- a/.gitignore +++ b/.gitignore @@ -379,3 +379,5 @@ FodyWeavers.xsd /windows_vs/games/com.mojang /windows_vs/assets /windows_vs/assetsO + +/wasm diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..874433e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "thirdparty/coi-serviceworker"] + path = thirdparty/coi-serviceworker + url = https://github.com/gzuidhof/coi-serviceworker +[submodule "thirdparty/gles-compatibility-layer"] + path = thirdparty/gles-compatibility-layer + url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/gles-compatibility-layer.git diff --git a/build-wasm.sh b/build-wasm.sh new file mode 100755 index 0000000..0cb8ffd --- /dev/null +++ b/build-wasm.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e + +# Working Directory +mkdir -p wasm +cd wasm + +# Clone Emscripten SDK +if [ ! -d emsdk ]; then + git clone https://github.com/emscripten-core/emsdk.git +fi +cd emsdk + +# Update Emscripten SDK +git pull +./emsdk install 3.1.42 # https://github.com/emscripten-core/emscripten/issues/19921 +./emsdk activate 3.1.42 > /dev/null + +# Use Emscripten SDK +export EMSDK_QUIET=1 +source ./emsdk_env.sh + +# Create Output Directory +cd ../ +rm -rf dist +mkdir dist + +# Create Build Directory +mkdir -p build +cd build + +# Configure Build +emcmake cmake -GNinja "$@" ../../platforms/sdl + +# Build +cmake --build . + +# Bundle +cp reminecraftpe.* ../dist +cp ../../platforms/sdl/wasm_shell.html ../dist/reminecraftpe.html +cp ../../thirdparty/coi-serviceworker/coi-serviceworker.min.js ../dist diff --git a/compat/AKeyCodes.hpp b/compat/AKeyCodes.hpp index 7dcfad0..c4c61ff 100644 --- a/compat/AKeyCodes.hpp +++ b/compat/AKeyCodes.hpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -55,6 +55,7 @@ enum AKEYCODE_APOSTROPHE = VK_OEM_7, // ''"' AKEYCODE_SPACE = VK_SPACE, + AKEYCODE_1 = '1', AKEYCODE_0 = '0', //... AKEYCODE_9 = '9', @@ -73,6 +74,109 @@ enum #define AKEYCODE_ARROW_LEFT VK_LEFT #define AKEYCODE_ARROW_RIGHT VK_RIGHT +#elif defined(USE_SDL) + +#include + +enum +{ + AKEYCODE_UNKNOWN = 0, + AKEYCODE_MENU, + AKEYCODE_SEARCH, + AKEYCODE_BACK, + AKEYCODE_BUTTON_X, + AKEYCODE_BUTTON_Y, + AKEYCODE_DPAD_UP, + AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_CENTER, + AKEYCODE_BUTTON_L1, + AKEYCODE_BUTTON_R1, + AKEYCODE_SHIFT_LEFT, + AKEYCODE_SHIFT_RIGHT, + AKEYCODE_DEL, + AKEYCODE_FORWARD_DEL, + AKEYCODE_COMMA, + AKEYCODE_PERIOD, + AKEYCODE_PLUS, + AKEYCODE_MINUS, + AKEYCODE_SEMICOLON, + AKEYCODE_SLASH, + AKEYCODE_GRAVE, + AKEYCODE_LEFT_BRACKET, + AKEYCODE_BACKSLASH, + AKEYCODE_RIGHT_BRACKET, + AKEYCODE_APOSTROPHE, + AKEYCODE_SPACE, + AKEYCODE_0, + AKEYCODE_1, + AKEYCODE_2, + AKEYCODE_3, + AKEYCODE_4, + AKEYCODE_5, + AKEYCODE_6, + AKEYCODE_7, + AKEYCODE_8, + AKEYCODE_9, + AKEYCODE_A, + AKEYCODE_Q, + AKEYCODE_T, + AKEYCODE_Z, + AKEYCODE_F4, + AKEYCODE_ARROW_LEFT, + AKEYCODE_ARROW_RIGHT +}; + +static inline int translate_sdl_key_to_mcpe(int key) { + switch (key) { + case SDLK_ESCAPE: return AKEYCODE_MENU; + case SDLK_F5: return AKEYCODE_SEARCH; + case SDLK_y: return AKEYCODE_BACK; + case SDLK_u: return AKEYCODE_BUTTON_X; + case SDLK_e: return AKEYCODE_BUTTON_Y; + case SDLK_w: return AKEYCODE_DPAD_UP; + case SDLK_s: return AKEYCODE_DPAD_DOWN; + case SDLK_a: return AKEYCODE_DPAD_LEFT; + case SDLK_d: return AKEYCODE_DPAD_RIGHT; + case SDLK_SPACE: return AKEYCODE_DPAD_CENTER; + case SDLK_x: return AKEYCODE_BUTTON_L1; + case SDLK_c: return AKEYCODE_BUTTON_R1; + case SDLK_LSHIFT: return AKEYCODE_SHIFT_LEFT; + case SDLK_RSHIFT: return AKEYCODE_SHIFT_RIGHT; + case SDLK_BACKSPACE: return AKEYCODE_DEL; + case SDLK_DELETE: return AKEYCODE_FORWARD_DEL; + case SDLK_COMMA: return AKEYCODE_COMMA; + case SDLK_PERIOD: return AKEYCODE_PERIOD; + case SDLK_PLUS: return AKEYCODE_PLUS; + case SDLK_MINUS: return AKEYCODE_MINUS; + case SDLK_SEMICOLON: return AKEYCODE_SEMICOLON; + case SDLK_SLASH: return AKEYCODE_SLASH; + case SDLK_BACKQUOTE: return AKEYCODE_GRAVE; + case SDLK_LEFTBRACKET: return AKEYCODE_LEFT_BRACKET; + case SDLK_BACKSLASH: return AKEYCODE_BACKSLASH; + case SDLK_RIGHTBRACKET: return AKEYCODE_RIGHT_BRACKET; + case SDLK_QUOTE: return AKEYCODE_APOSTROPHE; + case SDLK_1: return AKEYCODE_1; + case SDLK_2: return AKEYCODE_2; + case SDLK_3: return AKEYCODE_3; + case SDLK_4: return AKEYCODE_4; + case SDLK_5: return AKEYCODE_5; + case SDLK_6: return AKEYCODE_6; + case SDLK_7: return AKEYCODE_7; + case SDLK_8: return AKEYCODE_8; + case SDLK_0: return AKEYCODE_0; + case SDLK_9: return AKEYCODE_9; + case SDLK_q: return AKEYCODE_Q; + case SDLK_t: return AKEYCODE_T; + case SDLK_z: return AKEYCODE_Z; + case SDLK_F4: return AKEYCODE_F4; + case SDLK_LEFT: return AKEYCODE_ARROW_LEFT; + case SDLK_RIGHT: return AKEYCODE_ARROW_RIGHT; + default: return AKEYCODE_UNKNOWN; + } +} + #else #error "Add AKEYCODEs for your platform!" #endif diff --git a/compat/GL.hpp b/compat/GL.hpp index 9404591..d22f2a7 100644 --- a/compat/GL.hpp +++ b/compat/GL.hpp @@ -8,6 +8,65 @@ #pragma once +#ifdef USE_SDL + +#ifdef USE_GLES1_COMPATIBILITY_LAYER +#include +#define GL_QUADS 0x7 + +#include + +// https://cgit.freedesktop.org/mesa/glu/tree/src/libutil/project.c +static inline void __gluMakeIdentityf(GLfloat m[16]) { + m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; + m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; + m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; + m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; +} +static inline void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) { + GLfloat m[4][4]; + float sine, cotangent, deltaZ; + float radians = fovy / 2 * M_PI / 180; + + deltaZ = zFar - zNear; + sine = sin(radians); + if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { + return; + } + cotangent = cosf(radians) / sine; + + __gluMakeIdentityf(&m[0][0]); + m[0][0] = cotangent / aspect; + m[1][1] = cotangent; + m[2][2] = -(zFar + zNear) / deltaZ; + m[2][3] = -1; + m[3][2] = -2 * zNear * zFar / deltaZ; + m[3][3] = 0; + glMultMatrixf(&m[0][0]); +} +#else +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#endif + +#define xglBindBuffer glBindBuffer +#define xglBufferData glBufferData +#define xglGenBuffers glGenBuffers +#define xglDeleteBuffers glDeleteBuffers +#ifdef USE_GLES1_COMPATIBILITY_LAYER +#define xglOrthof glOrthof +#else +#define xglOrthof(left, right, bottom, top, nearpl, farpl) glOrtho((GLdouble) (left), (GLdouble) (right), (GLdouble) (bottom), (GLdouble) (top), (GLdouble) (nearpl), (GLdouble) (farpl)) +#endif + +// @TODO: not the right place, but er, it's ok +void drawArrayVT(GLuint buffer, int count, int stride); +void drawArrayVTC(GLuint buffer, int count, int stride); + +#else + #ifdef USE_OPENGL_2 #define xglBindBuffer glBindBuffer @@ -36,3 +95,5 @@ void drawArrayVT(GLuint buffer, int count, int stride); void drawArrayVTC(GLuint buffer, int count, int stride); #endif + +#endif diff --git a/platforms/.gitignore b/platforms/.gitignore new file mode 100644 index 0000000..0ec9e7f --- /dev/null +++ b/platforms/.gitignore @@ -0,0 +1 @@ +/build* diff --git a/platforms/PlatformDefinitions.hpp b/platforms/PlatformDefinitions.hpp index 6eb3f0c..6cce195 100644 --- a/platforms/PlatformDefinitions.hpp +++ b/platforms/PlatformDefinitions.hpp @@ -15,6 +15,12 @@ // Add sound system overrides here +#elif defined(USE_SDL) + +// -- OpenAL based sound system for SDL +#include "sdl/SoundSystemAL.hpp" +#define SOUND_SYSTEM_TYPE SoundSystemAL + #elif defined(_WIN32) // -- DirectSound based sound system for Windows diff --git a/platforms/sdl/.gitignore b/platforms/sdl/.gitignore new file mode 100644 index 0000000..d01858b --- /dev/null +++ b/platforms/sdl/.gitignore @@ -0,0 +1,2 @@ +/build +/assets diff --git a/platforms/sdl/AppPlatform_sdl.cpp b/platforms/sdl/AppPlatform_sdl.cpp new file mode 100644 index 0000000..dd349c6 --- /dev/null +++ b/platforms/sdl/AppPlatform_sdl.cpp @@ -0,0 +1,308 @@ +#include "AppPlatform_sdl.hpp" + +#include +#include +#include + +#ifndef __EMSCRIPTEN__ +#include + +#include "compat/GL.hpp" +#else +#include +#endif + +#include "client/common/Utils.hpp" + +AppPlatform_sdl::AppPlatform_sdl(std::string storageDir, SDL_Window *window) { + _storageDir = storageDir; + _window = window; +} + +int AppPlatform_sdl::checkLicense() { + // we own the game!! + return 1; +} + +// Ensure Screenshots Folder Exists +void ensure_screenshots_folder(const char *screenshots) { + // Check Screenshots Folder + struct stat obj; + if (stat(screenshots, &obj) != 0 || !S_ISDIR(obj.st_mode)) { + // Create Screenshots Folder +#ifdef _WIN32 + int ret = mkdir(screenshots); +#else + int ret = mkdir(screenshots, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + if (ret != 0) { + // Unable To Create Folder + LogMsg("Error Creating Directory: %s: %s", screenshots, strerror(errno)); + exit(EXIT_FAILURE); + } + } +} + +#ifndef __EMSCRIPTEN__ +// 4 (Year) + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Null Terminator) +#define TIME_SIZE 20 +// Take Screenshot +static int save_png(const char *filename, unsigned char *pixels, int line_size, int width, int height) { + // Return value + int ret = 0; + + // Variables + png_structp png = NULL; + png_infop info = NULL; + FILE *file = NULL; + png_colorp palette = NULL; + png_bytep rows[height]; + for (int i = 0; i < height; ++i) { + rows[height - i - 1] = (png_bytep)(&pixels[i * line_size]); + } + + // Init + png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png) { + ret = 1; + goto ret; + } + info = png_create_info_struct(png); + if (!info) { + ret = 1; + goto ret; + } + + // Open File + file = fopen(filename, "wb"); + if (!file) { + ret = 1; + goto ret; + } + + // Prepare To Write + png_init_io(png, file); + png_set_IHDR(png, info, width, height, 8 /* Depth */, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + palette = (png_colorp) png_malloc(png, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); + if (!palette) { + ret = 1; + goto ret; + } + png_set_PLTE(png, info, palette, PNG_MAX_PALETTE_LENGTH); + png_write_info(png, info); + png_set_packing(png); + + // Write + png_write_image(png, rows); + png_write_end(png, info); + +ret: + // Free + if (palette != NULL) { + png_free(png, palette); + } + if (file != NULL) { + fclose(file); + } + if (png != NULL) { + png_destroy_write_struct(&png, &info); + } + + // Return + return ret; +} +void AppPlatform_sdl::saveScreenshot(const std::string &filename, int glWidth, int glHeight) { + // Get Directory + std::string screenshots = _storageDir + "/screenshots"; + + // Get Timestamp + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + char time[TIME_SIZE]; + strftime(time, TIME_SIZE, "%Y-%m-%d_%H.%M.%S", timeinfo); + + // Ensure Screenshots Folder Exists + ensure_screenshots_folder(screenshots.c_str()); + + // Prevent Overwriting Screenshots + int num = 1; + std::string file = screenshots + '/' + time + ".png"; + while (access(file.c_str(), F_OK) != -1) { + file = screenshots + '/' + time + '-' + std::to_string(num) + ".png"; + num++; + } + + // Get Image Size + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + int x = viewport[0]; + int y = viewport[1]; + int width = viewport[2]; + int height = viewport[3]; + + // Get Line Size + int line_size = width * 4; + { + // Handle Alignment + int alignment; + glGetIntegerv(GL_PACK_ALIGNMENT, &alignment); + // Round + int diff = line_size % alignment; + if (diff > 0) { + line_size = line_size + (alignment - diff); + } + } + int size = height * line_size; + + // Read Pixels + bool fail = false; + unsigned char *pixels = (unsigned char *) malloc(size); + if (pixels == NULL) { + fail = true; + } else { + glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + } + + // Save Image + if (fail || save_png(file.c_str(), pixels, line_size, width, height)) { + LogMsg("Screenshot Failed: %s", file.c_str()); + } else { + LogMsg("Screenshot Saved: %s", file.c_str()); + } + + // Free + if (pixels != NULL) { + free(pixels); + } +} +#endif + +int AppPlatform_sdl::getScreenWidth() const { + int width; + SDL_GL_GetDrawableSize(_window, &width, nullptr); + return width; +} + +int AppPlatform_sdl::getScreenHeight() const { + int height; + SDL_GL_GetDrawableSize(_window, nullptr, &height); + return height; +} + +#ifndef __EMSCRIPTEN__ +static void png_read_sdl(png_structp png_ptr, png_bytep data, png_size_t length) { + SDL_RWread((SDL_RWops *) png_get_io_ptr(png_ptr), (char *) data, length, 1); +} +static void nop_png_warning(png_structp png_ptr, png_const_charp warning_message) { + // Do Nothing +} +#endif +Texture AppPlatform_sdl::loadTexture(const std::string& str, bool b) { + Texture out; + out.field_C = 0; + out.field_D = 0; + + std::string realPath = str; + if (realPath.size() && realPath[0] == '/') { + // trim it off + realPath = realPath.substr(1); + } + realPath = "assets/" + realPath; + +#ifndef __EMSCRIPTEN__ + SDL_RWops *io = SDL_RWFromFile(realPath.c_str(), "rb"); + + if (io != NULL) { + png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, nop_png_warning); + if (!pngPtr) { + return out; + } + + png_infop infoPtr = png_create_info_struct(pngPtr); + if (!infoPtr) { + png_destroy_read_struct(&pngPtr, NULL, NULL); + return out; + } + + png_set_read_fn(pngPtr, (png_voidp) io, png_read_sdl); + + png_read_info(pngPtr, infoPtr); + + png_set_expand(pngPtr); + png_set_strip_16(pngPtr); + png_set_gray_to_rgb(pngPtr); + png_read_update_info(pngPtr, infoPtr); + + out.m_width = png_get_image_width(pngPtr, infoPtr); + out.m_height = png_get_image_height(pngPtr, infoPtr); + + bool opaque = png_get_color_type(pngPtr, infoPtr) != PNG_COLOR_TYPE_RGBA; + if (!opaque) { + out.field_C = 1; + } + int pixelSize = opaque ? 3 : 4; + + png_bytep *rowPtrs = new png_bytep[out.m_height]; + unsigned char *pixels = new unsigned char[pixelSize * out.m_width * out.m_height]; + + int rowStrideBytes = pixelSize * out.m_width; + for (int i = 0; i < out.m_height; i++) { + rowPtrs[i] = (png_bytep) &pixels[i * rowStrideBytes]; + } + png_read_image(pngPtr, rowPtrs); + + out.m_pixels = (uint32_t *) pixels; + + png_destroy_read_struct(&pngPtr, &infoPtr, (png_infopp) 0); + delete[](png_bytep) rowPtrs; + SDL_RWclose(io); + } +#else + char *data = emscripten_get_preloaded_image_data(("/" + realPath).c_str(), &out.m_width, &out.m_height); + if (data != NULL) { + size_t data_size = out.m_width * out.m_height * 4; + out.m_pixels = (uint32_t *) new unsigned char[data_size]; + out.field_C = 1; + memcpy(out.m_pixels, data, data_size); + free(data); + return out; + } +#endif + + LogMsg("Couldn't find file: %s", str.c_str()); + return out; +} + +void AppPlatform_sdl::setMouseGrabbed(bool b) { + SDL_SetWindowGrab(_window, b ? SDL_TRUE : SDL_FALSE); + SDL_SetRelativeMouseMode(b ? SDL_TRUE : SDL_FALSE); +} + +void AppPlatform_sdl::setMouseDiff(int x, int y) { + xrel = x; + yrel = y; +} + +void AppPlatform_sdl::getMouseDiff(int& x, int& y) { + x = xrel; + y = yrel; +} + +void AppPlatform_sdl::clearDiff() { + xrel = 0; + yrel = 0; +} + +bool AppPlatform_sdl::shiftPressed() { + return m_bShiftPressed[0] || m_bShiftPressed[1]; +} + +void AppPlatform_sdl::setShiftPressed(bool b, bool isLeft) { + m_bShiftPressed[isLeft ? 0 : 1] = b; +} + +int AppPlatform_sdl::getUserInputStatus() { + return -1; +} diff --git a/platforms/sdl/AppPlatform_sdl.hpp b/platforms/sdl/AppPlatform_sdl.hpp new file mode 100644 index 0000000..11b525f --- /dev/null +++ b/platforms/sdl/AppPlatform_sdl.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include + +#include "AppPlatform.hpp" + +#ifdef ORIGINAL_CODE +#error "This isn't original code. You probably shouldn't try to compile this" +#endif + +void ensure_screenshots_folder(const char *screenshots); + +class AppPlatform_sdl : public AppPlatform { + public: + AppPlatform_sdl(std::string storageDir, SDL_Window *window); + +#ifndef __EMSCRIPTEN__ + void saveScreenshot(const std::string& fileName, int width, int height) override; +#endif + int checkLicense() override; + int getScreenWidth() const override; + int getScreenHeight() const override; + Texture loadTexture(const std::string& str, bool b) override; + int getUserInputStatus() override; + + // Also add these to allow proper turning within the game. + void setMouseGrabbed(bool b) override; + void setMouseDiff(int x, int y); + void getMouseDiff(int& x, int& y) override; + void clearDiff() override; + + // Also add these to allow proper text input within the game. + bool shiftPressed() override; + void setShiftPressed(bool b, bool isLeft); + private: + std::string _storageDir; + SDL_Window *_window; + + bool m_bShiftPressed[2] = {false, false}; + + int xrel; + int yrel; +}; diff --git a/platforms/sdl/CMakeLists.txt b/platforms/sdl/CMakeLists.txt new file mode 100644 index 0000000..aa19a3b --- /dev/null +++ b/platforms/sdl/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.16.0) +project(reminecraftpe) + +# SDL Build +add_compile_definitions(USE_SDL HANDLE_CHARS_SEPARATELY) + +# WASM +if(EMSCRIPTEN) + function(add_compile_and_link_options) + add_compile_options(${ARGV}) + add_link_options(${ARGV}) + endfunction() + set(CMAKE_EXECUTABLE_SUFFIX ".js") +endif() + +# Clang +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_compile_options(-Wno-inconsistent-missing-override -Wno-enum-compare-switch -Wno-register) +endif() + +# Threads +if(EMSCRIPTEN) + add_compile_and_link_options(-pthread) +else() + find_package(Threads) + link_libraries(Threads::Threads) +endif() + +# Build +add_executable(reminecraftpe + main.cpp + AppPlatform_sdl.cpp + SoundSystemAL.cpp +) + +# Core +add_subdirectory(../../source source) +target_link_libraries(reminecraftpe reminecraftpe-core) + +# LibPNG +if(NOT EMSCRIPTEN) + find_package(PNG REQUIRED) + target_link_libraries(reminecraftpe PNG::PNG) +endif() + +# SDL +if(TARGET SDL2::SDL2main) + target_link_libraries(reminecraftpe SDL2::SDL2main) +endif() + +# WASM +if(EMSCRIPTEN) + target_link_options(reminecraftpe PRIVATE -Wno-pthreads-mem-growth) + target_link_options(reminecraftpe PRIVATE -sALLOW_MEMORY_GROWTH=1) + # Export Resize Function + target_link_options(reminecraftpe PRIVATE -sEXPORTED_FUNCTIONS=_main,_resize_from_js -sEXPORTED_RUNTIME_METHODS=ccall) +endif() + +# Assets +if(EMSCRIPTEN) + target_link_options(reminecraftpe PRIVATE --use-preload-plugins --preload-file "${CMAKE_CURRENT_SOURCE_DIR}/assets@/assets") +elseif(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/assets") + file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/assets" "${CMAKE_CURRENT_BINARY_DIR}/assets" SYMBOLIC) +endif() diff --git a/platforms/sdl/SoundSystemAL.cpp b/platforms/sdl/SoundSystemAL.cpp new file mode 100644 index 0000000..6783590 --- /dev/null +++ b/platforms/sdl/SoundSystemAL.cpp @@ -0,0 +1,245 @@ +#include "SoundSystemAL.hpp" + +#include "client/common/Utils.hpp" + +SoundSystemAL::SoundSystemAL() { + device = alcOpenDevice(NULL); + if (!device) { + LogMsg("Unable To Load Audio Engine"); + return; + } + + // Create Context + context = alcCreateContext(device, NULL); + ALCenum err = alcGetError(device); + if (err != ALC_NO_ERROR) { + LogMsg("Unable To Open Audio Context: %s", alcGetString(device, err)); + return; + } + + // Select Context + alcMakeContextCurrent(context); + err = alcGetError(device); + if (err != ALC_NO_ERROR) { + LogMsg("Unable To Select Audio Context: %s", alcGetString(device, err)); + return; + } + + // Set Distance Model + alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); + + // Mark As Loaded + loaded = true; +} + +SoundSystemAL::~SoundSystemAL() { + if (loaded) { + // Delete Audio Sources + delete_sources(); + + // Delete Audio Buffers + delete_buffers(); + + // Deselect Context + alcMakeContextCurrent(NULL); + ALCenum err = alcGetError(device); + if (err != ALC_NO_ERROR) { + LogMsg("Unable To Deselect Audio Context: %s", alcGetString(device, err)); + } + + // Destroy Context + alcDestroyContext(context); + err = alcGetError(device); + if (err != ALC_NO_ERROR) { + LogMsg("Unable To Destroy Audio Context: %s", alcGetString(device, err)); + } + + // Close Device + alcCloseDevice(device); + err = alcGetError(device); + if (err != ALC_NO_ERROR) { + LogMsg("Unable To Close Audio Device: %s", alcGetString(device, err)); + } + } +} + +// Error Checking +#define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError()) +#define AL_ERROR_CHECK_MANUAL(val) \ + { \ + ALenum __err = val; \ + if (__err != AL_NO_ERROR) { \ + LogMsg("(%s:%i) OpenAL Error: %s", __FILE__, __LINE__, alGetString(__err)); \ + exit(EXIT_FAILURE); \ + } \ + } + +// Delete Sources +void SoundSystemAL::delete_sources() { + if (loaded) { + for (ALuint source : idle_sources) { + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } + for (ALuint source : sources) { + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } + } + idle_sources.clear(); + sources.clear(); +} + +// Delete Buffers +void SoundSystemAL::delete_buffers() { + if (loaded) { + for (auto &it : buffers) { + if (it.second && alIsBuffer(it.second)) { + alDeleteBuffers(1, &it.second); + AL_ERROR_CHECK(); + } + } + } + buffers.clear(); +} + +// Get Buffer +ALuint SoundSystemAL::get_buffer(const SoundDesc &sound) { + if (buffers.count(sound.m_pData) > 0) { + return buffers[sound.m_pData]; + } else { + // Sound Format + ALenum format = AL_NONE; + if (sound.m_header.m_channels == 1) { + format = sound.m_header.m_bytes_per_sample == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8; + } else if (sound.m_header.m_channels == 2) { + format = sound.m_header.m_bytes_per_sample == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8; + } + + // Sound Data Size + int size = sound.m_header.m_length * sound.m_header.m_bytes_per_sample; + + // Create Buffer + ALuint buffer; + alGenBuffers(1, &buffer); + AL_ERROR_CHECK(); + alBufferData(buffer, format, sound.m_pData, size, sound.m_header.m_sample_rate); + AL_ERROR_CHECK(); + + // Store + buffers[sound.m_pData] = buffer; + return buffer; + } +} + +void SoundSystemAL::update(float x, float y, float z, float yaw) { + // Check + if (loaded) { + // Update Listener Volume + float volume = 1; + alListenerf(AL_GAIN, volume); + AL_ERROR_CHECK(); + + // Update Listener Position + alListener3f(AL_POSITION, x, y, z); + AL_ERROR_CHECK(); + + // Update Listener Orientation + float radian_yaw = yaw * (M_PI / 180); + ALfloat orientation[] = {-sinf(radian_yaw), 0.0f, cosf(radian_yaw), 0.0f, 1.0f, 0.0f}; + alListenerfv(AL_ORIENTATION, orientation); + AL_ERROR_CHECK(); + + // Clear Finished Sources + std::vector::iterator it = sources.begin(); + while (it != sources.end()) { + ALuint source = *it; + bool remove = false; + // Check + if (source && alIsSource(source)) { + // Is Valid Source + ALint source_state; + alGetSourcei(source, AL_SOURCE_STATE, &source_state); + AL_ERROR_CHECK(); + if (source_state != AL_PLAYING) { + // Finished Playing + remove = true; + if (idle_sources.size() < MAX_IDLE_SOURCES) { + idle_sources.push_back(source); + } else { + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } + } + } else { + // Not A Source + remove = true; + } + // Remove If Needed + if (remove) { + it = sources.erase(it); + } else { + ++it; + } + } + } +} + +void SoundSystemAL::play(const SoundDesc &sound, float x, float y, float z, float volume, float pitch, bool is_ui) { + if (loaded) { + // Load Sound + ALuint buffer = get_buffer(sound); + if (volume > 0.0f && buffer) { + // Get Source + ALuint al_source; + if (idle_sources.size() > 0) { + // Use Idle Source + al_source = idle_sources.back(); + idle_sources.pop_back(); + } else { + // Create Source + alGenSources(1, &al_source); + // Special Out-Of-Memory Handling + { + ALenum err = alGetError(); + if (err == AL_OUT_OF_MEMORY) { + return; + } else { + AL_ERROR_CHECK_MANUAL(err); + } + } + } + + // Set Properties + alSourcef(al_source, AL_PITCH, pitch); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_GAIN, volume); + AL_ERROR_CHECK(); + alSource3f(al_source, AL_POSITION, x, y, z); + AL_ERROR_CHECK(); + alSource3f(al_source, AL_VELOCITY, 0, 0, 0); + AL_ERROR_CHECK(); + alSourcei(al_source, AL_LOOPING, AL_FALSE); + AL_ERROR_CHECK(); + alSourcei(al_source, AL_SOURCE_RELATIVE, is_ui ? AL_TRUE : AL_FALSE); + AL_ERROR_CHECK(); + + // Set Attenuation + alSourcef(al_source, AL_MAX_DISTANCE, 16.0f); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_ROLLOFF_FACTOR, 6.0f); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_REFERENCE_DISTANCE, 5.0f); + AL_ERROR_CHECK(); + + // Set Buffer + alSourcei(al_source, AL_BUFFER, buffer); + AL_ERROR_CHECK(); + + // Play + alSourcePlay(al_source); + AL_ERROR_CHECK(); + sources.push_back(al_source); + } + } +} diff --git a/platforms/sdl/SoundSystemAL.hpp b/platforms/sdl/SoundSystemAL.hpp new file mode 100644 index 0000000..1ea75cf --- /dev/null +++ b/platforms/sdl/SoundSystemAL.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include "client/sound/SoundData.hpp" + +#define MAX_IDLE_SOURCES 50 + +class SoundSystemAL { + public: + SoundSystemAL(); + ~SoundSystemAL(); + void update(float x, float y, float z, float yaw); + void play(const SoundDesc &sound, float x, float y, float z, float volume, float pitch, bool is_ui); + private: + void delete_sources(); + void delete_buffers(); + ALuint get_buffer(const SoundDesc &sound); + + ALCdevice *device = NULL; + ALCcontext *context = NULL; + bool loaded = false; + std::vector sources; + std::vector idle_sources; + std::unordered_map buffers; +}; diff --git a/platforms/sdl/main.cpp b/platforms/sdl/main.cpp new file mode 100644 index 0000000..25459a5 --- /dev/null +++ b/platforms/sdl/main.cpp @@ -0,0 +1,258 @@ +#include + +#include + +#include "compat/GL.hpp" +#include "compat/AKeyCodes.hpp" +#include "App.hpp" +#include "AppPlatform_sdl.hpp" +#include "NinecraftApp.hpp" + +#ifdef __EMSCRIPTEN__ +#include +#include +#endif + +void LogMsg(const char* fmt, ...) { + va_list lst; + va_start(lst, fmt); + + vprintf(fmt, lst); + printf("\n"); + + va_end(lst); +} +// I hate duplicating code, but yeah +void LogMsgNoCR(const char* fmt, ...) { + va_list lst; + va_start(lst, fmt); + + vprintf(fmt, lst); + + va_end(lst); +} + +AppPlatform_sdl *g_AppPlatform; +NinecraftApp *g_pApp; + +SDL_Window *window = NULL; +SDL_GLContext context = NULL; +static void teardown() { + if (window != NULL) { + SDL_GL_DeleteContext(context); + SDL_DestroyWindow(window); + SDL_Quit(); + window = NULL; + } +} + +// Resize From JS +#ifdef __EMSCRIPTEN__ +extern "C" void resize_from_js(int new_width, int new_height) { + SDL_SetWindowSize(window, new_width, new_height); +} +#endif + +// Handle Events +static bool window_resized = false; +static void handle_events() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: { + Keyboard::feed(event.key.state == SDL_PRESSED ? 1 : 0, translate_sdl_key_to_mcpe(event.key.keysym.sym)); + if (event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT) { + g_AppPlatform->setShiftPressed(event.key.state == SDL_PRESSED, event.key.keysym.sym == SDLK_LSHIFT); + } + break; + } + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: { + Mouse::feed(event.button.button == SDL_BUTTON_LEFT ? 1 : 2, event.button.state == SDL_PRESSED ? 1 : 0, event.button.x, event.button.y); + break; + } + case SDL_MOUSEMOTION: { + Mouse::_x = event.motion.x; + Mouse::_y = event.motion.y; + Mouse::feed(0, 0, event.motion.x, event.motion.y); + g_AppPlatform->setMouseDiff(event.motion.xrel, event.motion.yrel); + break; + } + case SDL_MOUSEWHEEL: { + Mouse::feed(3, event.wheel.y, Mouse::_x, Mouse::_y); + break; + } + case SDL_TEXTINPUT: { + if (g_pApp != nullptr) { + char x = event.text.text[0]; + if (x >= ' ' && x <= '~') { + g_pApp->handleCharInput(x); + } + } + break; + } + case SDL_WINDOWEVENT: { + if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + window_resized = true; + } + break; + } + case SDL_QUIT: { + g_pApp->quit(); + break; + } + } + } +} + +// GUI Scale +static void calulate_gui_scale() { + int width = Minecraft::width; + + // Modified Version Of https://github.com/MCPI-Revival/Ninecraft/blob/3f71638a10b581f6a50669edb24bc1ef1a92fbea/ninecraft/src/main.c#L243-L255 + if (width < 1000) { + if (width < 400) { + Gui::InvGuiScale = 1.0; + } else { + Gui::InvGuiScale = 0.5; + } + } else { + Gui::InvGuiScale = 0.25; + } +} + +// Resizing +static void resize() { + SDL_GL_GetDrawableSize(window, &Minecraft::width, &Minecraft::height); + + calulate_gui_scale(); + + if (g_pApp != nullptr && g_pApp->m_pScreen != nullptr) { + g_pApp->m_pScreen->setSize(Minecraft::width * Gui::InvGuiScale, Minecraft::height * Gui::InvGuiScale); + } +} + +// Main Loop +#ifndef __EMSCRIPTEN__ +#define EM_BOOL bool +#define EM_TRUE true +#define EM_FALSE false +#endif +static bool is_first_window_resize = true; +static EM_BOOL main_loop(double time, void *user_data) { + // Handle Events + handle_events(); + + // Screen Size + if (window_resized) { + window_resized = false; + resize(); + } + + // Update MCPE + g_pApp->update(); + + // Swap Buffers + SDL_GL_SwapWindow(window); + + if (g_pApp->wantToQuit()) { + delete g_pApp; + delete g_AppPlatform; + teardown(); + // Stop Looping + return EM_FALSE; + } else { + // Keep Looping + return EM_TRUE; + } +} + +// Main +int main(int argc, char *argv[]) { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + LOGE("Unable To Initialize SDL: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } + + // Configure OpenGL ES Context + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); +#ifdef USE_GLES1_COMPATIBILITY_LAYER + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); +#endif + // Double-Buffering + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + // Window Size +#ifdef __EMSCRIPTEN__ + Minecraft::width = std::stoi(argv[1]); + Minecraft::height = std::stoi(argv[2]); +#endif + + // Create Window + window = SDL_CreateWindow("ReMinecraftPE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Minecraft::width, Minecraft::height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + if (!window) { + LOGE("Unable To Create SDL Window\n"); + exit(EXIT_FAILURE); + } + + // Enable Text Input + SDL_StartTextInput(); + + // Create OpenGL ES Context + context = SDL_GL_CreateContext(window); + if (!context) { + LOGE("Unable To Create OpenGL Context\n"); + exit(EXIT_FAILURE); + } + + // Setup Compatibility Layer If Needed +#ifdef USE_GLES1_COMPATIBILITY_LAYER + init_gles_compatibility_layer(); +#endif + + // Setup Teardown +#ifndef __EMSCRIPTEN__ + atexit(teardown); +#endif + + // Set Size + resize(); + + // Storage Directory +#ifdef _WIN32 + std::string storagePath = getenv("APPDATA"); +#elif defined(__EMSCRIPTEN__) + std::string storagePath = ""; +#else + std::string storagePath = getenv("HOME"); +#endif + storagePath += "/.reminecraftpe"; + ensure_screenshots_folder(storagePath.c_str()); + + // Start MCPE + g_pApp = new NinecraftApp; + g_pApp->m_externalStorageDir = storagePath; + g_AppPlatform = new AppPlatform_sdl(g_pApp->m_externalStorageDir, window); + g_pApp->m_pPlatform = g_AppPlatform; + g_pApp->init(); + + // Loop +#ifndef __EMSCRIPTEN__ + while (true) { + EM_BOOL result = main_loop(0, nullptr); + if (result == EM_FALSE) { + break; + } + } +#else + emscripten_request_animation_frame_loop(main_loop, nullptr); +#endif + + return 0; +} diff --git a/platforms/sdl/wasm_shell.html b/platforms/sdl/wasm_shell.html new file mode 100644 index 0000000..cad60cd --- /dev/null +++ b/platforms/sdl/wasm_shell.html @@ -0,0 +1,54 @@ + + + + + + ReMinecraftPE + + + + + + + + + diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 0000000..d12fe12 --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,254 @@ +cmake_minimum_required(VERSION 3.16.0) +project(reminecraftpe-core) + +# Build +add_library(reminecraftpe-core STATIC + NinecraftApp.cpp + client/renderer/LevelRenderer.cpp + client/renderer/Culler.cpp + client/renderer/entity/HumanoidMobRenderer.cpp + client/renderer/entity/TntRenderer.cpp + client/renderer/entity/MobRenderer.cpp + client/renderer/entity/FallingTileRenderer.cpp + client/renderer/entity/EntityRenderer.cpp + client/renderer/entity/ItemRenderer.cpp + client/renderer/entity/TripodCameraRenderer.cpp + client/renderer/entity/ItemSpriteRenderer.cpp + client/renderer/entity/EntityRenderDispatcher.cpp + client/renderer/RenderList.cpp + client/renderer/Chunk.cpp + client/renderer/RenderChunk.cpp + client/renderer/Frustum.cpp + client/renderer/ItemInHandRenderer.cpp + client/renderer/DynamicTexture.cpp + client/renderer/GameRenderer.cpp + client/renderer/Textures.cpp + client/renderer/FrustumCuller.cpp + client/renderer/LightUpdate.cpp + client/renderer/Font.cpp + client/renderer/WaterSideTexture.cpp + client/renderer/Tesselator.cpp + client/renderer/TileRenderer.cpp + client/renderer/LightLayer.cpp + client/renderer/WaterTexture.cpp + client/network/Packets/UpdateBlockPacket.cpp + client/network/Packets/RequestChunkPacket.cpp + client/network/Packets/PlayerEquipmentPacket.cpp + client/network/Packets/ChunkDataPacket.cpp + client/network/Packets/PlaceBlockPacket.cpp + client/network/Packets/LoginPacket.cpp + client/network/Packets/StartGamePacket.cpp + client/network/Packets/RemoveEntityPacket.cpp + client/network/Packets/AddPlayerPacket.cpp + client/network/Packets/RemoveBlockPacket.cpp + client/network/Packets/MovePlayerPacket.cpp + client/network/Packets/MessagePacket.cpp + client/network/ServerSideNetworkHandler.cpp + client/network/RakNetInstance.cpp + client/network/ClientSideNetworkHandler.cpp + client/network/MinecraftPackets.cpp + client/network/NetEventCallback.cpp + client/sound/SoundData.cpp + client/sound/SoundSystem.cpp + client/sound/SoundRepository.cpp + client/sound/SoundEngine.cpp + client/gui/Screen.cpp + client/gui/screens/OptionsScreen.cpp + client/gui/screens/StartMenuScreen.cpp + client/gui/screens/CreateWorldScreen.cpp + client/gui/screens/SelectWorldScreen.cpp + client/gui/screens/SavingWorldScreen.cpp + client/gui/screens/InvalidLicenseScreen.cpp + client/gui/screens/ConfirmScreen.cpp + client/gui/screens/DeleteWorldScreen.cpp + client/gui/screens/ChatScreen.cpp + client/gui/screens/RenameMPLevelScreen.cpp + client/gui/screens/ProgressScreen.cpp + client/gui/screens/JoinGameScreen.cpp + client/gui/screens/IngameBlockSelectionScreen.cpp + client/gui/screens/PauseScreen.cpp + client/gui/components/ScrolledSelectionList.cpp + client/gui/components/AvailableGamesList.cpp + client/gui/components/RolledSelectionList.cpp + client/gui/components/Button.cpp + client/gui/components/TextInputBox.cpp + client/gui/components/SmallButton.cpp + client/gui/components/WorldSelectionList.cpp + client/gui/Gui.cpp + client/gui/GuiComponent.cpp + client/model/PolygonQuad.cpp + client/model/Model.cpp + client/model/HumanoidModel.cpp + client/model/Cube.cpp + client/common/Random.cpp + client/common/HitResult.cpp + client/common/Utils.cpp + client/common/PerlinNoise.cpp + client/common/ImprovedNoise.cpp + client/common/Matrix.cpp + client/common/Mth.cpp + client/common/Options.cpp + client/common/Timer.cpp + client/common/Synth.cpp + client/common/CThread.cpp + client/common/Util.cpp + client/common/Vec3.cpp + client/common/AABB.cpp + client/player/input/ControllerTurnInput.cpp + client/player/input/Controller.cpp + client/player/input/Mouse.cpp + client/player/input/Keyboard.cpp + client/player/input/MouseTurnInput.cpp + client/player/input/KeyboardInput.cpp + client/player/input/ITurnInput.cpp + Minecraft.cpp + world/gamemode/SurvivalMode.cpp + world/gamemode/GameMode.cpp + world/gamemode/CreativeMode.cpp + world/entity/Mob.cpp + world/entity/LocalPlayer.cpp + world/entity/Player.cpp + world/entity/PrimedTnt.cpp + world/entity/Entity.cpp + world/entity/FallingTile.cpp + world/entity/TripodCamera.cpp + world/entity/ItemEntity.cpp + world/level/Dimension.cpp + world/level/Material.cpp + world/level/LevelListener.cpp + world/level/TickNextTickData.cpp + world/level/Explosion.cpp + world/level/storage/LevelStorageSource.cpp + world/level/storage/MemoryLevelStorageSource.cpp + world/level/storage/LevelData.cpp + world/level/storage/ExternalFileLevelStorage.cpp + world/level/storage/RegionFile.cpp + world/level/storage/LevelStorage.cpp + world/level/storage/MemoryLevelStorage.cpp + world/level/storage/ChunkStorage.cpp + world/level/storage/LevelSource.cpp + world/level/storage/MemoryChunkStorage.cpp + world/level/storage/ExternalFileLevelStorageSource.cpp + world/level/levelgen/feature/BirchFeature.cpp + world/level/levelgen/feature/LargeFeature.cpp + world/level/levelgen/feature/Feature.cpp + world/level/levelgen/feature/LargeCaveFeature.cpp + world/level/levelgen/feature/SpringFeature.cpp + world/level/levelgen/feature/TreeFeature.cpp + world/level/levelgen/feature/PineFeature.cpp + world/level/levelgen/feature/ReedsFeature.cpp + world/level/levelgen/feature/OreFeature.cpp + world/level/levelgen/feature/ClayFeature.cpp + world/level/levelgen/feature/FlowerFeature.cpp + world/level/levelgen/feature/SpruceFeature.cpp + world/level/levelgen/biome/Biome.cpp + world/level/levelgen/biome/BiomeSource.cpp + world/level/levelgen/chunk/RandomLevelSource.cpp + world/level/levelgen/chunk/LevelChunk.cpp + world/level/levelgen/chunk/ChunkCache.cpp + world/level/levelgen/chunk/ChunkSource.cpp + world/level/levelgen/chunk/PerformanceTestChunkSource.cpp + world/level/levelgen/chunk/TestChunkSource.cpp + world/level/Level.cpp + world/level/Region.cpp + world/item/TilePlanterItem.cpp + world/item/CameraItem.cpp + world/item/TileItem.cpp + world/item/Inventory.cpp + world/item/DoorItem.cpp + world/item/ItemInstance.cpp + world/item/Item.cpp + world/particle/RedDustParticle.cpp + world/particle/TerrainParticle.cpp + world/particle/BubbleParticle.cpp + world/particle/ExplodeParticle.cpp + world/particle/ParticleEngine.cpp + world/particle/FlameParticle.cpp + world/particle/SmokeParticle.cpp + world/particle/Particle.cpp + world/particle/LavaParticle.cpp + world/tile/InvisibleTile.cpp + world/tile/Sapling.cpp + world/tile/TreeTile.cpp + world/tile/GrassTile.cpp + world/tile/HalfTransparentTile.cpp + world/tile/ClothTile.cpp + world/tile/TorchTile.cpp + world/tile/MetalTile.cpp + world/tile/SpongeTile.cpp + world/tile/GlassTile.cpp + world/tile/SandTile.cpp + world/tile/Tile.cpp + world/tile/ClayTile.cpp + world/tile/StoneTile.cpp + world/tile/LadderTile.cpp + world/tile/IceTile.cpp + world/tile/TopSnowTile.cpp + world/tile/ReedTile.cpp + world/tile/Bush.cpp + world/tile/RedStoneOreTile.cpp + world/tile/DirtTile.cpp + world/tile/LiquidTileStatic.cpp + world/tile/BookshelfTile.cpp + world/tile/TntTile.cpp + world/tile/OreTile.cpp + world/tile/StairTile.cpp + world/tile/SandStoneTile.cpp + world/tile/FireTile.cpp + world/tile/StoneSlabTile.cpp + world/tile/LiquidTile.cpp + world/tile/GravelTile.cpp + world/tile/LiquidTileDynamic.cpp + world/tile/TransparentTile.cpp + world/tile/LeafTile.cpp + world/tile/ObsidianTile.cpp + world/tile/FarmTile.cpp + world/tile/DoorTile.cpp + App.cpp + AppPlatform.cpp +) +target_include_directories(reminecraftpe-core PUBLIC . ..) + +# RakNet +add_subdirectory(../thirdparty/raknet raknet) +target_link_libraries(reminecraftpe-core PUBLIC raknet) + +# SDL +add_library(SDL INTERFACE) +if(EMSCRIPTEN) + set(SDL_FLAG -sUSE_SDL=2) + target_compile_options(SDL INTERFACE "${SDL_FLAG}") + target_link_options(SDL INTERFACE "${SDL_FLAG}") +else() + find_package(SDL2 REQUIRED) + target_link_libraries(SDL INTERFACE SDL2::SDL2) +endif() +target_link_libraries(reminecraftpe-core PUBLIC SDL) + +# OpenGL +if(NOT EMSCRIPTEN) + option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" TRUE) +else() + set(USE_GLES1_COMPATIBILITY_LAYER TRUE) +endif() +if(USE_GLES1_COMPATIBILITY_LAYER) + set(GLES_COMPATIBILITY_LAYER_USE_SDL TRUE CACHE BOOL "" FORCE) + set(GLES_COMPATIBILITY_LAYER_DEPENDENCY SDL CACHE STRING "" FORCE) + add_subdirectory(../thirdparty/gles-compatibility-layer gles-compatibility-layer) + target_link_libraries(reminecraftpe-core PUBLIC gles-compatibility-layer) + target_compile_definitions(reminecraftpe-core PUBLIC USE_GLES1_COMPATIBILITY_LAYER) + if(EMSCRIPTEN) + target_link_options(reminecraftpe-core PUBLIC -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2) + endif() +else() + find_package(OpenGL REQUIRED) + target_link_libraries(reminecraftpe-core PUBLIC OpenGL::OpenGL OpenGL::GLU) +endif() + +# OpenAL +if(EMSCRIPTEN) + target_link_libraries(reminecraftpe-core PUBLIC openal) +else() + find_library(OPENAL_LIBRARY NAMES openal REQUIRED) + target_link_libraries(reminecraftpe-core PUBLIC "${OPENAL_LIBRARY}") +endif() diff --git a/source/Minecraft.cpp b/source/Minecraft.cpp index f9a8065..8cc9816 100644 --- a/source/Minecraft.cpp +++ b/source/Minecraft.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -48,7 +48,7 @@ Minecraft::Minecraft() : m_gui(this) #else m_pTurnInput = new ControllerTurnInput; #endif - + m_pRakNetInstance = new RakNetInstance; m_pSoundEngine = new SoundEngine; @@ -59,7 +59,7 @@ int Minecraft::getLicenseId() { if (m_licenseID < 0) m_licenseID = m_pPlatform->checkLicense(); - + return m_licenseID; } @@ -80,7 +80,7 @@ void Minecraft::grabMouse() { if (m_bGrabbedMouse) return; - + m_bGrabbedMouse = true; field_D20 = 0.0f; field_D24 = 0.0f; @@ -91,6 +91,12 @@ void Minecraft::grabMouse() void Minecraft::setScreen(Screen* pScreen) { +#ifndef ORIGINAL_CODE + if (pScreen == nullptr && !isLevelGenerated()) { + return; + } +#endif + if (m_bUsingScreen) { m_bHasQueuedScreen = true; @@ -396,7 +402,7 @@ void Minecraft::tickInput() { m_gui.handleKeyPressed(keyCode); - int index = keyCode - '1'; + int index = keyCode - AKEYCODE_1; if (index <= 8 && index >= 0) { m_pLocalPlayer->m_pInventory->selectSlot(index); @@ -441,7 +447,7 @@ void Minecraft::tickInput() } } - // @TODO: fix gotos + // @TODO: fix gotos bool v12 = false; if (m_options.field_19) @@ -484,7 +490,7 @@ void Minecraft::tickMouse() { if (!m_bGrabbedMouse) return; - + platform()->recenterMouse(); } @@ -506,7 +512,7 @@ void Minecraft::tick() field_DA4--; tickInput(); - + m_gui.tick(); // if the level has been prepared, delete the prep thread @@ -547,8 +553,12 @@ void Minecraft::tick() #ifndef ORIGINAL_CODE if (m_pMobPersp) { +#ifdef USE_SDL + m_pSoundEngine->m_soundSystem.update(m_pMobPersp->m_pos.x, m_pMobPersp->m_pos.y, m_pMobPersp->m_pos.z, m_pMobPersp->m_yaw); +#else m_pSoundEngine->m_soundSystem.setListenerPos(m_pMobPersp->m_pos.x, m_pMobPersp->m_pos.y, m_pMobPersp->m_pos.z); m_pSoundEngine->m_soundSystem.setListenerAngle(m_pMobPersp->m_yaw, m_pMobPersp->m_pitch); +#endif } #endif @@ -653,7 +663,7 @@ void Minecraft::prepareLevel(const std::string& unused) float startTime = getTimeS(); Level* pLevel = m_pLevel; - + if (!pLevel->field_B0C) { pLevel->setUpdateLights(0); @@ -769,7 +779,7 @@ void Minecraft::generateLevel(const std::string& unused, Level* pLevel) if (m_pLevelRenderer) m_pLevelRenderer->setLevel(pLevel); - + if (m_pParticleEngine) m_pParticleEngine->setLevel(pLevel); @@ -925,30 +935,38 @@ void Minecraft::leaveGame(bool bCopyMap) void Minecraft::hostMultiplayer() { +#ifndef __EMSCRIPTEN__ m_pRakNetInstance->host(m_pUser->field_0, C_DEFAULT_PORT, C_MAX_CONNECTIONS); m_pNetEventCallback = new ServerSideNetworkHandler(this, m_pRakNetInstance); +#endif } void Minecraft::joinMultiplayer(const PingedCompatibleServer& serverInfo) { +#ifndef __EMSCRIPTEN__ if (field_18 && m_pNetEventCallback) { field_18 = false; m_pRakNetInstance->connect(serverInfo.m_address.ToString(), serverInfo.m_address.GetPort()); } +#endif } void Minecraft::cancelLocateMultiplayer() { +#ifndef __EMSCRIPTEN__ field_18 = false; m_pRakNetInstance->stopPingForHosts(); delete m_pNetEventCallback; m_pNetEventCallback = nullptr; +#endif } void Minecraft::locateMultiplayer() { +#ifndef __EMSCRIPTEN__ field_18 = true; m_pRakNetInstance->pingForHosts(C_DEFAULT_PORT); m_pNetEventCallback = new ClientSideNetworkHandler(this, m_pRakNetInstance); +#endif } diff --git a/source/NinecraftApp.cpp b/source/NinecraftApp.cpp index a31a343..d4c73aa 100644 --- a/source/NinecraftApp.cpp +++ b/source/NinecraftApp.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ diff --git a/source/client/common/Utils.cpp b/source/client/common/Utils.cpp index c7022c9..66987a3 100644 --- a/source/client/common/Utils.cpp +++ b/source/client/common/Utils.cpp @@ -33,6 +33,8 @@ int g_TimeSecondsOnInit = 0; +#ifndef USE_SDL + DIR* opendir(const char* name) { size_t len = strlen(name); @@ -97,6 +99,13 @@ void closedir(DIR* dir) free(dir); } +#else + +#include +#include + +#endif + bool createFolderIfNotExists(const char* pDir) { if (!XPL_ACCESS(pDir, 0)) diff --git a/source/client/gui/GuiComponent.hpp b/source/client/gui/GuiComponent.hpp index c2883bd..62ca0c3 100644 --- a/source/client/gui/GuiComponent.hpp +++ b/source/client/gui/GuiComponent.hpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -21,6 +21,6 @@ public: void fillGradient(int left, int top, int right, int bottom, int colorUp, int colorDown); public: - float field_4; + float field_4 = 0; }; diff --git a/source/client/gui/Screen.cpp b/source/client/gui/Screen.cpp index 3c893e9..b90a255 100644 --- a/source/client/gui/Screen.cpp +++ b/source/client/gui/Screen.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -30,7 +30,7 @@ void Screen::init(Minecraft* pMinecraft, int a3, int a4) void Screen::init() { - + } void Screen::buttonClicked(Button* pButton) @@ -65,7 +65,7 @@ bool Screen::isInGameScreen() void Screen::keyPressed(int key) { - if (key == '\x1B')//escape + if (key == AKEYCODE_MENU)//escape { m_pMinecraft->setScreen(nullptr); } diff --git a/source/client/gui/components/TextInputBox.cpp b/source/client/gui/components/TextInputBox.cpp index 6fc77f7..dcf6506 100644 --- a/source/client/gui/components/TextInputBox.cpp +++ b/source/client/gui/components/TextInputBox.cpp @@ -128,6 +128,11 @@ void TextInputBox::keyPressed(Minecraft* minecraft, int key) case AKEYCODE_ARROW_RIGHT: chr = '\003'; break; +#ifdef USE_SDL + case AKEYCODE_DEL: + chr = '\b'; + break; +#endif } #endif diff --git a/source/client/gui/screens/StartMenuScreen.cpp b/source/client/gui/screens/StartMenuScreen.cpp index a6ce9d8..b431b50 100644 --- a/source/client/gui/screens/StartMenuScreen.cpp +++ b/source/client/gui/screens/StartMenuScreen.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -93,7 +93,7 @@ void StartMenuScreen::init() 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; diff --git a/source/client/player/input/Controller.cpp b/source/client/player/input/Controller.cpp index 7c193e6..4cf9bac 100644 --- a/source/client/player/input/Controller.cpp +++ b/source/client/player/input/Controller.cpp @@ -8,6 +8,8 @@ #include "Controller.hpp" +#include + bool Controller::isTouchedValues[2]; float Controller::stickValuesX[2]; float Controller::stickValuesY[2]; diff --git a/source/client/player/input/ControllerTurnInput.cpp b/source/client/player/input/ControllerTurnInput.cpp index 063a0fd..f0bd580 100644 --- a/source/client/player/input/ControllerTurnInput.cpp +++ b/source/client/player/input/ControllerTurnInput.cpp @@ -9,6 +9,8 @@ #include "ControllerTurnInput.hpp" #include "Controller.hpp" +#include + ITurnInput::Delta ControllerTurnInput::getTurnDelta() { bool isTouched = Controller::isTouched(m_stickNo); diff --git a/source/client/player/input/Keyboard.cpp b/source/client/player/input/Keyboard.cpp index 90461bf..a907924 100644 --- a/source/client/player/input/Keyboard.cpp +++ b/source/client/player/input/Keyboard.cpp @@ -1,19 +1,28 @@ /******************************************************************** 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 "Keyboard.hpp" +#include "GameMods.hpp" + std::vector Keyboard::_inputs; int Keyboard::_index = -1; -int Keyboard::_states[256]; +int Keyboard::_states[KEYBOARD_STATES_SIZE]; void Keyboard::feed(int down, int key) { +#ifndef ORIGINAL_CODE + // Prevent Crashes + if (key >= KEYBOARD_STATES_SIZE || key < 0) { + return; + } +#endif + Input i; i.field_0 = down; i.field_4 = uint8_t(key); diff --git a/source/client/player/input/Keyboard.hpp b/source/client/player/input/Keyboard.hpp index 74f8ae1..2ba7cd7 100644 --- a/source/client/player/input/Keyboard.hpp +++ b/source/client/player/input/Keyboard.hpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -9,6 +9,9 @@ #pragma once #include +#include + +#define KEYBOARD_STATES_SIZE 256 class Keyboard { @@ -21,7 +24,7 @@ public: }; static std::vector _inputs; - static int _states[256]; + static int _states[KEYBOARD_STATES_SIZE]; static int _index; // likely inlined diff --git a/source/client/renderer/GameRenderer.cpp b/source/client/renderer/GameRenderer.cpp index c4e102e..ee54eca 100644 --- a/source/client/renderer/GameRenderer.cpp +++ b/source/client/renderer/GameRenderer.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -328,7 +328,7 @@ void GameRenderer::setupFog(int i) float GameRenderer::getFov(float f) { Mob* pMob = m_pMinecraft->m_pMobPersp; - + float x1 = 70.0f; if (pMob->isUnderLiquid(Material::water)) diff --git a/source/client/renderer/LevelRenderer.cpp b/source/client/renderer/LevelRenderer.cpp index d24a945..bd13fa8 100644 --- a/source/client/renderer/LevelRenderer.cpp +++ b/source/client/renderer/LevelRenderer.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -459,14 +459,14 @@ void LevelRenderer::render(Mob* pMob, int a, float b) if (!a) field_54 = field_58 = field_5C = field_60 = field_64 = 0; - + float mobX1 = pMob->m_pos.x; float mobX2 = pMob->field_98.x + (pMob->m_pos.x - pMob->field_98.x) * b; float mobY1 = pMob->m_pos.y; float mobY2 = pMob->field_98.y + (pMob->m_pos.y - pMob->field_98.y) * b; float mobZ1 = pMob->m_pos.z; float mobZ2 = pMob->field_98.z + (pMob->m_pos.z - pMob->field_98.z) * b; - + float dX = pMob->m_pos.x - field_4, dY = pMob->m_pos.y - field_8, dZ = pMob->m_pos.z - field_C; if (dX * dX + dY * dY + dZ * dZ > 16.0f) @@ -567,7 +567,8 @@ void LevelRenderer::render(Mob* pMob, int a, float b) y3++; y2++; - pChunk->field_4E++; + //pChunk->field_4E++; + pChunk->field_4E = true; if (y3 == x3) goto label_37; } @@ -576,7 +577,7 @@ void LevelRenderer::render(Mob* pMob, int a, float b) label_26: y3++; y2++; - + if (y3 == x3) goto label_37; @@ -663,7 +664,7 @@ void LevelRenderer::tick() void LevelRenderer::updateDirtyChunks(Mob* pMob, bool b) { // @TODO This updates 16 chunks per frame. Not good. - + int updated = 0; for (int i = 0; i < 16 && i < int(field_88.size()); i++) { @@ -1021,7 +1022,7 @@ void LevelRenderer::takePicture(TripodCamera* pCamera, Entity* pOwner) #ifdef ENH_CAMERA_NO_PARTICLES g_bDisableParticles = false; #endif - + t_keepPic = -1; static char str[256]; @@ -1100,7 +1101,7 @@ void LevelRenderer::renderSky(float f) { if (m_pMinecraft->m_pLevel->m_pDimension->field_C) return; - + glDisable(GL_TEXTURE_2D); Vec3 skyColor = m_pLevel->getSkyColor(m_pMinecraft->m_pMobPersp, f); diff --git a/source/client/renderer/RenderList.cpp b/source/client/renderer/RenderList.cpp index a826945..5f1e596 100644 --- a/source/client/renderer/RenderList.cpp +++ b/source/client/renderer/RenderList.cpp @@ -9,6 +9,8 @@ #include "RenderList.hpp" #include "Tesselator.hpp" +#include + constexpr int C_MAX_RENDERS = 3072; RenderList::RenderList() diff --git a/source/client/renderer/Tesselator.cpp b/source/client/renderer/Tesselator.cpp index 024c372..7bee9a8 100644 --- a/source/client/renderer/Tesselator.cpp +++ b/source/client/renderer/Tesselator.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -9,6 +9,8 @@ #include "compat/GL.hpp" #include "Tesselator.hpp" +#include + int dword_2514A4 = 0; Tesselator Tesselator::instance; diff --git a/source/client/renderer/Textures.cpp b/source/client/renderer/Textures.cpp index 0142804..abdd8bd 100644 --- a/source/client/renderer/Textures.cpp +++ b/source/client/renderer/Textures.cpp @@ -1,7 +1,7 @@ /******************************************************************** 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 ********************************************************************/ @@ -69,7 +69,7 @@ int Textures::assignTexture(const std::string& name, Texture& texture) if (texture.field_C) internalFormat = GL_RGBA; - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, texture.m_width, texture.m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.m_pixels); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, texture.m_width, texture.m_height, 0, internalFormat, GL_UNSIGNED_BYTE, texture.m_pixels); m_textures[name] = textureID; diff --git a/source/client/sound/SoundEngine.cpp b/source/client/sound/SoundEngine.cpp index d754610..b7f51eb 100644 --- a/source/client/sound/SoundEngine.cpp +++ b/source/client/sound/SoundEngine.cpp @@ -63,8 +63,13 @@ void SoundEngine::play(const std::string& name) SoundDesc sd; - if (m_repository.get(name, sd)) + if (m_repository.get(name, sd)) { +#ifdef USE_SDL + m_soundSystem.play(sd, 0, 0, 0, 1, 1, true); +#else m_soundSystem.playAt(sd, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f); +#endif + } } void SoundEngine::play(const std::string& name, float a, float b, float c, float d, float e) @@ -74,6 +79,11 @@ void SoundEngine::play(const std::string& name, float a, float b, float c, float SoundDesc sd; - if (m_repository.get(name, sd)) + if (m_repository.get(name, sd)) { +#ifdef USE_SDL + m_soundSystem.play(sd, a, b, c, d, e, false); +#else m_soundSystem.playAt(sd, a, b, c, d, e); +#endif + } } diff --git a/thirdparty/coi-serviceworker b/thirdparty/coi-serviceworker new file mode 160000 index 0000000..34e0bc7 --- /dev/null +++ b/thirdparty/coi-serviceworker @@ -0,0 +1 @@ +Subproject commit 34e0bc7458c25dc7733bf5d1ed01b828b35b2318 diff --git a/thirdparty/gles-compatibility-layer b/thirdparty/gles-compatibility-layer new file mode 160000 index 0000000..c6f1947 --- /dev/null +++ b/thirdparty/gles-compatibility-layer @@ -0,0 +1 @@ +Subproject commit c6f1947c1b0df71128bfb702ff1a949be5846ac0 diff --git a/thirdparty/raknet/CMakeLists.txt b/thirdparty/raknet/CMakeLists.txt index 4f8c377..9946598 100644 --- a/thirdparty/raknet/CMakeLists.txt +++ b/thirdparty/raknet/CMakeLists.txt @@ -1 +1,117 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.16.0) +project(raknet) + +# Build +add_library(raknet STATIC + VariadicSQLParser.cpp + SuperFastHash.cpp + VariableListDeltaTracker.cpp + StatisticsHistory.cpp + SendToThread.cpp + SignaledEvent.cpp + ReplicaManager3.cpp + IncrementalReadInterface.cpp + Getche.cpp + RakNetSocket2_Berkley_NativeClient.cpp + WSAStartupSingleton.cpp + DataCompressor.cpp + RakMemoryOverride.cpp + CommandParserInterface.cpp + GetTime.cpp + RakNetSocket2_Berkley.cpp + PacketOutputWindowLogger.cpp + DynDNS.cpp + LocklessTypes.cpp + UDPForwarder.cpp + RakString.cpp + SimpleMutex.cpp + Itoa.cpp + VitaIncludes.cpp + TableSerializer.cpp + EpochTimeToString.cpp + ConnectionGraph2.cpp + EmailSender.cpp + UDPProxyCoordinator.cpp + UDPProxyClient.cpp + CloudClient.cpp + ReadyEvent.cpp + MessageFilter.cpp + TCPInterface.cpp + PS4Includes.cpp + NatPunchthroughClient.cpp + RakNetStatistics.cpp + PacketConsoleLogger.cpp + RakNetSocket2_NativeClient.cpp + PacketLogger.cpp + Gets.cpp + NatPunchthroughServer.cpp + FileOperations.cpp + CheckSum.cpp + HTTPConnection.cpp + NatTypeDetectionServer.cpp + RakNetSocket.cpp + DS_Table.cpp + RakNetSocket2.cpp + PacketizedTCP.cpp + RelayPlugin.cpp + ThreadsafePacketLogger.cpp + Rand.cpp + GridSectorizer.cpp + DS_BytePool.cpp + FullyConnectedMesh2.cpp + SocketLayer.cpp + RakWString.cpp + UDPProxyServer.cpp + StringTable.cpp + DR_SHA1.cpp + LinuxStrings.cpp + VariableDeltaSerializer.cpp + CloudServer.cpp + RPC4Plugin.cpp + PacketFileLogger.cpp + CloudCommon.cpp + SecureHandshake.cpp + FormatString.cpp + RakNetSocket2_PS4.cpp + DS_ByteQueue.cpp + NetworkIDObject.cpp + PluginInterface2.cpp + RakNetSocket2_WindowsStore8.cpp + RandSync.cpp + RakPeer.cpp + RakNetTransport2.cpp + RakNetSocket2_Windows_Linux_360.cpp + NatTypeDetectionClient.cpp + ConsoleServer.cpp + TelnetTransport.cpp + Base64Encoder.cpp + TeamManager.cpp + RakThread.cpp + DirectoryDeltaTransfer.cpp + CCRakNetSlidingWindow.cpp + Router2.cpp + StringCompressor.cpp + ReliabilityLayer.cpp + RakNetSocket2_Vita.cpp + NatTypeDetectionCommon.cpp + Rackspace.cpp + RakNetCommandParser.cpp + LogCommandParser.cpp + BitStream.cpp + HTTPConnection2.cpp + RakNetSocket2_Windows_Linux.cpp + RakNetTypes.cpp + RakNetSocket2_PS3_PS4.cpp + FileListTransfer.cpp + FileList.cpp + TwoWayAuthentication.cpp + _FindFirst.cpp + DS_HuffmanEncodingTree.cpp + gettimeofday.cpp + NetworkIDManager.cpp + TeamBalancer.cpp + CCRakNetUDT.cpp + RakNetSocket2_360_720.cpp + RakSleep.cpp +) +target_include_directories(raknet PUBLIC .) diff --git a/thirdparty/raknet/FileList.cpp b/thirdparty/raknet/FileList.cpp index 1a0f79c..ea657b7 100644 --- a/thirdparty/raknet/FileList.cpp +++ b/thirdparty/raknet/FileList.cpp @@ -20,7 +20,7 @@ #include -#elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __S3E__ ) +#elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __S3E__ ) && !defined( __EMSCRIPTEN__ ) #include #endif