mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-19 22:43:32 +00:00
ADD: WebASM port (no sound/no network)
This commit is contained in:
174
CMakeLists.txt
174
CMakeLists.txt
@@ -11,48 +11,69 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
find_package(OpenSSL)
|
find_package(OpenSSL)
|
||||||
if (OpenSSL_FOUND)
|
|
||||||
message(STATUS "found openssl ${OPENSSL_VERSION}")
|
if(EMSCRIPTEN)
|
||||||
|
set(AL_LIBTYPE "STATIC")
|
||||||
|
else()
|
||||||
|
set(AL_LIBTYPE "SHARED")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CPMAddPackage("gh:madler/zlib@1.3.2")
|
# I totally shocked
|
||||||
CPMAddPackage(
|
if(EMSCRIPTEN)
|
||||||
NAME "libpng"
|
add_library(zlib INTERFACE IMPORTED)
|
||||||
GIT_REPOSITORY "https://github.com/pnggroup/libpng.git"
|
set_target_properties(zlib PROPERTIES
|
||||||
GIT_TAG "v1.6.55"
|
INTERFACE_LINK_OPTIONS "-sUSE_ZLIB=1"
|
||||||
EXCLUDE_FROM_ALL TRUE
|
)
|
||||||
OPTIONS
|
|
||||||
"ZLIB_ROOT ${zlib_SOURCE_DIR}"
|
add_library(png INTERFACE IMPORTED)
|
||||||
"ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}"
|
set_target_properties(png PROPERTIES
|
||||||
"PNG_TOOLS OFF"
|
INTERFACE_LINK_OPTIONS "-sUSE_LIBPNG=1"
|
||||||
"PNG_TESTS OFF"
|
)
|
||||||
"BUILD_SHARED_LIBS ON"
|
|
||||||
)
|
add_library(glfw INTERFACE IMPORTED)
|
||||||
|
set_target_properties(glfw PROPERTIES
|
||||||
|
INTERFACE_LINK_OPTIONS "-sUSE_GLFW=3"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME "zlib"
|
||||||
|
GIT_REPOSITORY "https://github.com/madler/zlib"
|
||||||
|
GIT_TAG "v1.3.2"
|
||||||
|
)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME "libpng"
|
||||||
|
GIT_REPOSITORY "https://github.com/pnggroup/libpng.git"
|
||||||
|
GIT_TAG "v1.6.55"
|
||||||
|
OPTIONS
|
||||||
|
"ZLIB_ROOT ${zlib_SOURCE_DIR}"
|
||||||
|
"ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}"
|
||||||
|
"PNG_TOOLS OFF"
|
||||||
|
"PNG_TESTS OFF"
|
||||||
|
)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME "glfw"
|
||||||
|
GIT_REPOSITORY "https://github.com/glfw/glfw.git"
|
||||||
|
GIT_TAG "3.4"
|
||||||
|
EXCLUDE_FROM_ALL TRUE
|
||||||
|
OPTIONS
|
||||||
|
"GLFW_BUILD_EXAMPLES OFF"
|
||||||
|
"GLFW_BUILD_TESTS OFF"
|
||||||
|
"GLFW_BUILD_DOCS OFF"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
NAME "openal"
|
NAME "openal"
|
||||||
GIT_REPOSITORY "https://github.com/kcat/openal-soft.git"
|
GIT_REPOSITORY "https://github.com/kcat/openal-soft.git"
|
||||||
GIT_TAG "1.25.1"
|
GIT_TAG "1.25.1"
|
||||||
EXCLUDE_FROM_ALL TRUE
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
"ALSOFT_EXAMPLES OFF"
|
"ALSOFT_EXAMPLES OFF"
|
||||||
"ALSOFT_TESTS OFF"
|
"ALSOFT_TESTS OFF"
|
||||||
"ALSOFT_UTILS OFF"
|
"ALSOFT_UTILS OFF"
|
||||||
"BUILD_SHARED_LIBS ON"
|
"LIBTYPE ${AL_LIBTYPE}"
|
||||||
)
|
|
||||||
|
|
||||||
CPMAddPackage(
|
|
||||||
NAME "glfw"
|
|
||||||
GIT_REPOSITORY "https://github.com/glfw/glfw.git"
|
|
||||||
GIT_TAG "3.4"
|
|
||||||
EXCLUDE_FROM_ALL TRUE
|
|
||||||
OPTIONS
|
|
||||||
"GLFW_BUILD_EXAMPLES OFF"
|
|
||||||
"GLFW_BUILD_TESTS OFF"
|
|
||||||
"GLFW_BUILD_DOCS OFF"
|
|
||||||
"BUILD_SHARED_LIBS ON"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Clear this paths with *
|
# TODO: Clear this paths with *
|
||||||
@@ -242,11 +263,15 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
if(PLATFORM STREQUAL "PLATFORM_WIN32")
|
if(PLATFORM STREQUAL "PLATFORM_WIN32")
|
||||||
list(APPEND CLIENT_SOURCES "src/AppPlatform_win32.cpp")
|
list(APPEND CLIENT_SOURCES "src/AppPlatform_win32.cpp" "glad/src/glad.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(PLATFORM STREQUAL "PLATFORM_GLFW")
|
if(PLATFORM STREQUAL "PLATFORM_GLFW")
|
||||||
list(APPEND CLIENT_SOURCES "src/AppPlatform_glfw.cpp")
|
list(APPEND CLIENT_SOURCES "src/AppPlatform_glfw.cpp" "glad/src/glad.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
list(APPEND CLIENT_SOURCES "glad/src/glad.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
@@ -260,13 +285,10 @@ target_include_directories("${PROJECT_NAME}-server" PUBLIC
|
|||||||
"project/lib_projects/raknet/jni/RaknetSources"
|
"project/lib_projects/raknet/jni/RaknetSources"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT} png_shared)
|
target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME} ${CLIENT_SOURCES})
|
||||||
${CLIENT_SOURCES}
|
|
||||||
"glad/src/glad.c"
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(EXTRA_LIBS "ws2_32")
|
set(EXTRA_LIBS "ws2_32")
|
||||||
@@ -277,8 +299,6 @@ if(PLATFORM STREQUAL "PLATFORM_WIN32" OR PLATFORM STREQUAL "PLATFORM_GLFW")
|
|||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC "PLATFORM_DESKTOP")
|
target_compile_definitions(${PROJECT_NAME} PUBLIC "PLATFORM_DESKTOP")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
"${CMAKE_SOURCE_DIR}/glad/include/"
|
"${CMAKE_SOURCE_DIR}/glad/include/"
|
||||||
"${CMAKE_SOURCE_DIR}/src"
|
"${CMAKE_SOURCE_DIR}/src"
|
||||||
@@ -287,9 +307,53 @@ target_include_directories(${PROJECT_NAME} PUBLIC
|
|||||||
"lib/include"
|
"lib/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
# uuuh i hate it
|
||||||
|
set(EM_FLAGS "-pthread -sUSE_PTHREADS=1 -sSHARED_MEMORY=1")
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EM_FLAGS}")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EM_FLAGS}")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EM_FLAGS} --preload-file ${CMAKE_SOURCE_DIR}/data@/data -sPROXY_TO_PTHREAD")
|
||||||
|
|
||||||
|
target_compile_options(${PROJECT_NAME} PUBLIC
|
||||||
|
"-Os"
|
||||||
|
"-Wno-invalid-source-encoding"
|
||||||
|
"-Wno-narrowing"
|
||||||
|
"-Wno-deprecated-register"
|
||||||
|
"-Wno-reserved-user-defined-literal"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_options(${PROJECT_NAME} PUBLIC
|
||||||
|
"-Os"
|
||||||
|
"-sALLOW_MEMORY_GROWTH=1"
|
||||||
|
"-sFORCE_FILESYSTEM=1"
|
||||||
|
"-sLEGACY_GL_EMULATION=1"
|
||||||
|
"-sGL_UNSAFE_OPTS=0"
|
||||||
|
"-sEMULATE_FUNCTION_POINTER_CASTS=1"
|
||||||
|
"-sALLOW_TABLE_GROWTH=1"
|
||||||
|
"-sEXPORTED_RUNTIME_METHODS=['FS','stringToUTF8','UTF8ToString','cwrap','ccall','HEAP8','HEAPU8','HEAP32','HEAPU32']"
|
||||||
|
"-sEXPORTED_FUNCTIONS=['_main']"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message("DEBUG MODE")
|
||||||
|
|
||||||
|
target_link_options(${PROJECT_NAME} PUBLIC
|
||||||
|
"-sASSERTIONS=2"
|
||||||
|
"-sSTACK_OVERFLOW_CHECK=2"
|
||||||
|
"-sSTACK_SIZE=5242880"
|
||||||
|
"-sGL_DEBUG=1"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC "__EMSCRIPTEN__" "NO_SOUND" "NO_NETWORK")
|
||||||
|
set(EXTRA_LIBS "idbfs.js")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Client
|
# Client
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
|
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
|
||||||
target_link_libraries(${PROJECT_NAME} zlib png_shared alsoft.common OpenAL::OpenAL glfw ${EXTRA_LIBS})
|
target_link_libraries(${PROJECT_NAME} zlib png alsoft.common OpenAL::OpenAL glfw ${EXTRA_LIBS})
|
||||||
|
|
||||||
if (OpenSSL_FOUND)
|
if (OpenSSL_FOUND)
|
||||||
target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto)
|
||||||
@@ -297,19 +361,27 @@ if (OpenSSL_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT UNIX)
|
if (NOT UNIX)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT_NAME}
|
TARGET ${PROJECT_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${PROJECT_NAME}> $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${PROJECT_NAME}> $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
||||||
COMMAND_EXPAND_LISTS
|
COMMAND_EXPAND_LISTS
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_command(
|
if(NOT EMSCRIPTEN)
|
||||||
TARGET ${PROJECT_NAME}
|
add_custom_command(
|
||||||
POST_BUILD
|
TARGET ${PROJECT_NAME}
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/data" $<TARGET_FILE_DIR:${PROJECT_NAME}>/data
|
POST_BUILD
|
||||||
)
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/data" $<TARGET_FILE_DIR:${PROJECT_NAME}>/data
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${PROJECT_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/index.html" $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Installing and packing
|
# Installing and packing
|
||||||
|
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -167,3 +167,34 @@ cmake --build .
|
|||||||
|
|
||||||
8. Re run `build.sh`
|
8. Re run `build.sh`
|
||||||
|
|
||||||
|
## Web
|
||||||
|
1. Download and install **emsdk**: https://emscripten.org/docs/getting_started/downloads.html
|
||||||
|
> [!NOTE]
|
||||||
|
> On arch linux you can use AUR:
|
||||||
|
> `yay -Sy emsdk`
|
||||||
|
|
||||||
|
2. Configure and build project:
|
||||||
|
```
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -B . -G Ninja "-DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
|
||||||
|
cmake --build . --target MinecraftPE
|
||||||
|
```
|
||||||
|
> [!NOTE]
|
||||||
|
> If you are using VSCode with CMake plugin, you can add Emscripten kit
|
||||||
|
> 1. Press Ctrl + Shift + P
|
||||||
|
> 2. Type `CMake: Edit User-Local CMake Kits` and hit Enter
|
||||||
|
> 3. Add this:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Emscripten",
|
||||||
|
"compilers": {
|
||||||
|
"C": "/usr/lib/emsdk/upstream/bin/clang",
|
||||||
|
"CXX": "/usr/lib/emsdk/upstream/bin/clang++"
|
||||||
|
},
|
||||||
|
"toolchainFile": "/usr/lib/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Run game:
|
||||||
|
```
|
||||||
|
emrun --port 8080 .
|
||||||
|
```
|
||||||
143
misc/web/index.html
Normal file
143
misc/web/index.html
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>Emscripten-Generated Code</title>
|
||||||
|
<style>
|
||||||
|
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
textarea.emscripten { font-family: monospace; width: 80%; }
|
||||||
|
div.emscripten { text-align: center; }
|
||||||
|
div.emscripten_border { border: 1px solid black; }
|
||||||
|
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||||
|
canvas.emscripten { border: 0px none; background-color: black; }
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
margin: 0px auto;
|
||||||
|
-webkit-animation: rotation .8s linear infinite;
|
||||||
|
-moz-animation: rotation .8s linear infinite;
|
||||||
|
-o-animation: rotation .8s linear infinite;
|
||||||
|
animation: rotation 0.8s linear infinite;
|
||||||
|
border-left: 10px solid rgb(0,150,240);
|
||||||
|
border-right: 10px solid rgb(0,150,240);
|
||||||
|
border-bottom: 10px solid rgb(0,150,240);
|
||||||
|
border-top: 10px solid rgb(100,0,200);
|
||||||
|
border-radius: 100%;
|
||||||
|
background-color: rgb(200,100,250);
|
||||||
|
}
|
||||||
|
@-webkit-keyframes rotation {
|
||||||
|
from {-webkit-transform: rotate(0deg);}
|
||||||
|
to {-webkit-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@-moz-keyframes rotation {
|
||||||
|
from {-moz-transform: rotate(0deg);}
|
||||||
|
to {-moz-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@-o-keyframes rotation {
|
||||||
|
from {-o-transform: rotate(0deg);}
|
||||||
|
to {-o-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@keyframes rotation {
|
||||||
|
from {transform: rotate(0deg);}
|
||||||
|
to {transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<hr/>
|
||||||
|
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
|
||||||
|
<div class="emscripten" id="status">Downloading...</div>
|
||||||
|
<div class="emscripten">
|
||||||
|
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||||
|
</div>
|
||||||
|
<div class="emscripten_border">
|
||||||
|
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<div class="emscripten">
|
||||||
|
<input type="checkbox" id="resize">Resize canvas
|
||||||
|
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||||
|
|
||||||
|
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
|
||||||
|
document.getElementById('resize').checked)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
<textarea class="emscripten" id="output" rows="8"></textarea>
|
||||||
|
<hr>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var statusElement = document.getElementById('status');
|
||||||
|
var progressElement = document.getElementById('progress');
|
||||||
|
var spinnerElement = document.getElementById('spinner');
|
||||||
|
var canvasElement = document.getElementById('canvas');
|
||||||
|
var outputElement = document.getElementById('output');
|
||||||
|
if (outputElement) outputElement.value = ''; // clear browser cache
|
||||||
|
|
||||||
|
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||||
|
// application robust, you may want to override this behavior before shipping!
|
||||||
|
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||||
|
canvasElement.addEventListener("webglcontextlost", (e) => {
|
||||||
|
alert('WebGL context lost. You will need to reload the page.');
|
||||||
|
e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function setStatus(text) {
|
||||||
|
if (!setStatus.last) setStatus.last = { time: Date.now(), text: '' };
|
||||||
|
if (text === setStatus.last.text) return;
|
||||||
|
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||||
|
var now = Date.now();
|
||||||
|
if (m && now - setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
|
||||||
|
setStatus.last.time = now;
|
||||||
|
setStatus.last.text = text;
|
||||||
|
if (m) {
|
||||||
|
text = m[1];
|
||||||
|
progressElement.value = parseInt(m[2])*100;
|
||||||
|
progressElement.max = parseInt(m[4])*100;
|
||||||
|
progressElement.hidden = false;
|
||||||
|
spinnerElement.hidden = false;
|
||||||
|
} else {
|
||||||
|
progressElement.value = null;
|
||||||
|
progressElement.max = null;
|
||||||
|
progressElement.hidden = true;
|
||||||
|
if (!text) spinnerElement.hidden = true;
|
||||||
|
}
|
||||||
|
statusElement.innerHTML = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Module = {
|
||||||
|
print(...args) {
|
||||||
|
// These replacements are necessary if you render to raw HTML
|
||||||
|
//text = text.replace(/&/g, "&");
|
||||||
|
//text = text.replace(/</g, "<");
|
||||||
|
//text = text.replace(/>/g, ">");
|
||||||
|
//text = text.replace('\n', '<br>', 'g');
|
||||||
|
console.log(...args);
|
||||||
|
if (outputElement) {
|
||||||
|
var text = args.join(' ');
|
||||||
|
outputElement.value += text + "\n";
|
||||||
|
outputElement.scrollTop = outputElement.scrollHeight; // focus on bottom
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canvas: canvasElement,
|
||||||
|
setStatus: setStatus,
|
||||||
|
totalDependencies: 0,
|
||||||
|
monitorRunDependencies(left) {
|
||||||
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||||
|
setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setStatus('Downloading...');
|
||||||
|
window.onerror = () => {
|
||||||
|
setStatus('Exception thrown, see JavaScript console');
|
||||||
|
spinnerElement.style.display = 'none';
|
||||||
|
setStatus = (text) => {
|
||||||
|
if (text) console.error('[post-exception status] ' + text);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="MinecraftPE.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryBlob readAssetFile(const std::string& filename) {
|
BinaryBlob readAssetFile(const std::string& filename) override {
|
||||||
FILE* fp = fopen(("data/" + filename).c_str(), "r");
|
FILE* fp = fopen(("data/" + filename).c_str(), "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return BinaryBlob();
|
return BinaryBlob();
|
||||||
@@ -48,7 +48,7 @@ public:
|
|||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveScreenshot(const std::string& filename, int glWidth, int glHeight) {
|
void saveScreenshot(const std::string& filename, int glWidth, int glHeight) override {
|
||||||
//@todo
|
//@todo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
return (p & 0xff00ff00) | ((p >> 16) & 0xff) | ((p << 16) & 0xff0000);
|
return (p & 0xff00ff00) | ((p >> 16) & 0xff) | ((p << 16) & 0xff0000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureData loadTexture(const std::string& filename_, bool textureFolder)
|
TextureData loadTexture(const std::string& filename_, bool textureFolder) override
|
||||||
{
|
{
|
||||||
// Support fetching PNG textures via HTTP/HTTPS (for skins, etc)
|
// Support fetching PNG textures via HTTP/HTTPS (for skins, etc)
|
||||||
if (Util::startsWith(filename_, "http://") || Util::startsWith(filename_, "https://")) {
|
if (Util::startsWith(filename_, "http://") || Util::startsWith(filename_, "https://")) {
|
||||||
@@ -132,10 +132,10 @@ public:
|
|||||||
return std::string(mbstr);
|
return std::string(mbstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int getScreenWidth() { return 854; };
|
virtual int getScreenWidth() override { return 854; };
|
||||||
virtual int getScreenHeight() { return 480; };
|
virtual int getScreenHeight() override { return 480; };
|
||||||
|
|
||||||
virtual float getPixelsPerMillimeter();
|
virtual float getPixelsPerMillimeter() override;
|
||||||
|
|
||||||
virtual bool supportsTouchscreen() override { return true; }
|
virtual bool supportsTouchscreen() override { return true; }
|
||||||
|
|
||||||
@@ -148,6 +148,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWwindow* window;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
#endif /*APPPLATFORM_GLFW_H__*/
|
#endif /*APPPLATFORM_GLFW_H__*/
|
||||||
|
|||||||
@@ -245,8 +245,9 @@ void NinecraftApp::initGLStates()
|
|||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
glEnable2(GL_TEXTURE_2D);
|
glEnable2(GL_TEXTURE_2D);
|
||||||
|
#ifndef _EMSCRIPTEN_
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
|
#endif
|
||||||
// Both updates isPowerVR flag in java and returns if the graphics chip is PowerVR SGX or not
|
// Both updates isPowerVR flag in java and returns if the graphics chip is PowerVR SGX or not
|
||||||
_powerVr = platform()->isPowerVR();
|
_powerVr = platform()->isPowerVR();
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ void CreditsScreen::init() {
|
|||||||
_lines.push_back("mschiller890");
|
_lines.push_back("mschiller890");
|
||||||
_lines.push_back("InviseDivine");
|
_lines.push_back("InviseDivine");
|
||||||
_lines.push_back("Kolyah35");
|
_lines.push_back("Kolyah35");
|
||||||
|
_lines.push_back("karson");
|
||||||
|
_lines.push_back("deepfriedwaffles");
|
||||||
_lines.push_back("");
|
_lines.push_back("");
|
||||||
// avoid color tags around the URL so it isn't mangled by the parser please
|
// avoid color tags around the URL so it isn't mangled by the parser please
|
||||||
_lines.push_back("Join our Discord server: https://discord.gg/c58YesBxve");
|
_lines.push_back("Join our Discord server: https://discord.gg/c58YesBxve");
|
||||||
|
|||||||
@@ -86,21 +86,21 @@ public:
|
|||||||
SelectWorldScreen();
|
SelectWorldScreen();
|
||||||
virtual ~SelectWorldScreen();
|
virtual ~SelectWorldScreen();
|
||||||
|
|
||||||
virtual void init();
|
virtual void init() override;
|
||||||
virtual void setupPositions();
|
virtual void setupPositions() override;
|
||||||
|
|
||||||
virtual void tick();
|
virtual void tick() override;
|
||||||
virtual void render(int xm, int ym, float a);
|
virtual void render(int xm, int ym, float a) override;
|
||||||
|
|
||||||
virtual bool isIndexValid(int index);
|
virtual bool isIndexValid(int index);
|
||||||
virtual bool handleBackEvent(bool isDown);
|
virtual bool handleBackEvent(bool isDown) override;
|
||||||
virtual void buttonClicked(Button* button);
|
virtual void buttonClicked(Button* button) override;
|
||||||
virtual void keyPressed(int eventKey);
|
virtual void keyPressed(int eventKey) override;
|
||||||
|
|
||||||
// support for mouse wheel when desktop code uses touch variant
|
// support for mouse wheel when desktop code uses touch variant
|
||||||
virtual void mouseWheel(int dx, int dy, int xm, int ym) override;
|
virtual void mouseWheel(int dx, int dy, int xm, int ym) override;
|
||||||
|
|
||||||
bool isInGameScreen();
|
bool isInGameScreen() override;
|
||||||
private:
|
private:
|
||||||
void loadLevelSource();
|
void loadLevelSource();
|
||||||
std::string getUniqueLevelName(const std::string& level);
|
std::string getUniqueLevelName(const std::string& level);
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ RenderChunk Tesselator::end( bool useMine, int bufferId )
|
|||||||
const int o_vertices = vertices;
|
const int o_vertices = vertices;
|
||||||
|
|
||||||
if (vertices > 0) {
|
if (vertices > 0) {
|
||||||
|
if (p <= 0 || p > maxVertices) { clear(); return RenderChunk(); }
|
||||||
|
int bytes = p * sizeof(VERTEX);
|
||||||
|
if (bytes <= 0) return RenderChunk();
|
||||||
if (++vboId >= vboCounts)
|
if (++vboId >= vboCounts)
|
||||||
vboId = 0;
|
vboId = 0;
|
||||||
|
|
||||||
@@ -92,11 +95,11 @@ RenderChunk Tesselator::end( bool useMine, int bufferId )
|
|||||||
bufferId = vboIds[vboId];
|
bufferId = vboIds[vboId];
|
||||||
#endif
|
#endif
|
||||||
int access = GL_STATIC_DRAW;//(accessMode==ACCESS_DYNAMIC) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
int access = GL_STATIC_DRAW;//(accessMode==ACCESS_DYNAMIC) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
||||||
int bytes = p * sizeof(VERTEX);
|
|
||||||
glBindBuffer2(GL_ARRAY_BUFFER, bufferId);
|
glBindBuffer2(GL_ARRAY_BUFFER, bufferId);
|
||||||
glBufferData2(GL_ARRAY_BUFFER, bytes, _varray, access); // GL_STREAM_DRAW
|
glBufferData2(GL_ARRAY_BUFFER, bytes, _varray, access); // GL_STREAM_DRAW
|
||||||
|
|
||||||
totalSize += bytes;
|
totalSize += bytes;
|
||||||
|
|
||||||
#ifndef USE_VBO
|
#ifndef USE_VBO
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
// x y z u v c
|
// x y z u v c
|
||||||
@@ -264,6 +267,7 @@ void Tesselator::vertex( float x, float y, float z )
|
|||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
|
||||||
const int offs = 3 - i;
|
const int offs = 3 - i;
|
||||||
|
if (p - offs < 0 || p >= maxVertices) { clear(); return; }
|
||||||
VERTEX& src = _varray[p - offs];
|
VERTEX& src = _varray[p - offs];
|
||||||
VERTEX& dst = _varray[p];
|
VERTEX& dst = _varray[p];
|
||||||
|
|
||||||
@@ -287,6 +291,7 @@ void Tesselator::vertex( float x, float y, float z )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p < 0 || p >= maxVertices) { clear(); return; }
|
||||||
VERTEX& vertex = _varray[p];
|
VERTEX& vertex = _varray[p];
|
||||||
|
|
||||||
if (hasTexture) {
|
if (hasTexture) {
|
||||||
@@ -377,13 +382,15 @@ void Tesselator::draw()
|
|||||||
tesselating = false;
|
tesselating = false;
|
||||||
|
|
||||||
if (vertices > 0) {
|
if (vertices > 0) {
|
||||||
|
if (p <= 0 || p > maxVertices) { clear(); return; }
|
||||||
|
int bytes = p * sizeof(VERTEX);
|
||||||
|
if (bytes <= 0) { clear(); return; }
|
||||||
if (++vboId >= vboCounts)
|
if (++vboId >= vboCounts)
|
||||||
vboId = 0;
|
vboId = 0;
|
||||||
|
|
||||||
int bufferId = vboIds[vboId];
|
int bufferId = vboIds[vboId];
|
||||||
|
|
||||||
int access = GL_DYNAMIC_DRAW;//(accessMode==ACCESS_DYNAMIC) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
int access = GL_DYNAMIC_DRAW;//(accessMode==ACCESS_DYNAMIC) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
||||||
int bytes = p * sizeof(VERTEX);
|
|
||||||
glBindBuffer2(GL_ARRAY_BUFFER, bufferId);
|
glBindBuffer2(GL_ARRAY_BUFFER, bufferId);
|
||||||
glBufferData2(GL_ARRAY_BUFFER, bytes, _varray, access); // GL_STREAM_DRAW
|
glBufferData2(GL_ARRAY_BUFFER, bytes, _varray, access); // GL_STREAM_DRAW
|
||||||
|
|
||||||
|
|||||||
@@ -47,9 +47,13 @@ void glInit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void anGenBuffers(GLsizei n, GLuint* buffers) {
|
void anGenBuffers(GLsizei n, GLuint* buffers) {
|
||||||
static GLuint k = 1;
|
#ifdef __EMSCRIPTEN__
|
||||||
for (int i = 0; i < n; ++i)
|
glGenBuffers(n, buffers);
|
||||||
buffers[i] = ++k;
|
#else
|
||||||
|
static GLuint k = 1;
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
buffers[i] = ++k;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_VBO
|
#ifdef USE_VBO
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Other systems might run it, if they #define OPENGL_ES
|
// Other systems might run it, if they #define OPENGL_ES
|
||||||
#if defined(OPENGL_ES) // || defined(ANDROID)
|
// #if defined(OPENGL_ES) // || defined(ANDROID)
|
||||||
#define USE_VBO
|
#define USE_VBO
|
||||||
#define GL_QUADS 0x0007
|
#define GL_QUADS 0x0007
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#import <OpenGLES/ES1/gl.height>
|
#import <OpenGLES/ES1/gl.height>
|
||||||
#import <OpenGLES/ES1/glext.height>
|
#import <OpenGLES/ES1/glext.height>
|
||||||
#elif defined(ANDROID)
|
#elif defined(ANDROID) || defined(__EMSCRIPTEN__)
|
||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
#include <GLES/glext.h>
|
#include <GLES/glext.h>
|
||||||
#else
|
#else
|
||||||
@@ -28,18 +28,18 @@
|
|||||||
#define glClearDepthf(x) glClearDepth(x)
|
#define glClearDepthf(x) glClearDepth(x)
|
||||||
#define glDepthRangef(a,b) glDepthRange(a,b)
|
#define glDepthRangef(a,b) glDepthRange(a,b)
|
||||||
#endif
|
#endif
|
||||||
#else
|
// #else
|
||||||
// Uglyness to fix redeclaration issues
|
// // Uglyness to fix redeclaration issues
|
||||||
#ifdef WIN32
|
// #ifdef WIN32
|
||||||
#include <WinSock2.h>
|
// #include <WinSock2.h>
|
||||||
#include <Windows.h>
|
// #include <Windows.h>
|
||||||
#endif
|
// #endif
|
||||||
#include <gl/glew.h>
|
// #include <gl/glew.h>
|
||||||
#include <gl/GL.h>
|
// #include <gl/GL.h>
|
||||||
|
|
||||||
#define glFogx(a,b) glFogi(a,b)
|
// #define glFogx(a,b) glFogi(a,b)
|
||||||
#define glOrthof(a,b,c,d,e,f) glOrtho(a,b,c,d,e,f)
|
// #define glOrthof(a,b,c,d,e,f) glOrtho(a,b,c,d,e,f)
|
||||||
#endif
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
#define GLERRDEBUG 1
|
#define GLERRDEBUG 1
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
#define MAIN_GLFW_H__
|
#define MAIN_GLFW_H__
|
||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "GLFW/glfw3.h"
|
#include "client/renderer/entity/PlayerRenderer.h"
|
||||||
#include "client/renderer/gles.h"
|
#include "client/renderer/gles.h"
|
||||||
#include "SharedConstants.h"
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@@ -12,9 +12,10 @@
|
|||||||
#include "platform/input/Keyboard.h"
|
#include "platform/input/Keyboard.h"
|
||||||
#include "platform/input/Mouse.h"
|
#include "platform/input/Mouse.h"
|
||||||
#include "platform/input/Multitouch.h"
|
#include "platform/input/Multitouch.h"
|
||||||
#include "util/Mth.h"
|
|
||||||
#include "AppPlatform_glfw.h"
|
#include "AppPlatform_glfw.h"
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#include <emscripten/emscripten.h>
|
||||||
|
#endif
|
||||||
static App* g_app = 0;
|
static App* g_app = 0;
|
||||||
|
|
||||||
int transformKey(int glfwkey) {
|
int transformKey(int glfwkey) {
|
||||||
@@ -112,12 +113,39 @@ void error_callback(int error, const char* desc) {
|
|||||||
printf("Error: %s\n", desc);
|
printf("Error: %s\n", desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
using clock = std::chrono::steady_clock;
|
||||||
|
auto frameStart = clock::now();
|
||||||
|
|
||||||
|
g_app->update();
|
||||||
|
|
||||||
|
glfwSwapBuffers(((AppPlatform_glfw*)g_app->platform())->window);
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
glfwSwapInterval(((MAIN_CLASS*)g_app)->options.getBooleanValue(OPTIONS_VSYNC) ? 1 : 0);
|
||||||
|
if(((MAIN_CLASS*)g_app)->options.getBooleanValue(OPTIONS_LIMIT_FRAMERATE)) {
|
||||||
|
auto frameEnd = clock::now();
|
||||||
|
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(frameEnd - frameStart);
|
||||||
|
auto target = std::chrono::microseconds(33333); // ~30 fps
|
||||||
|
if(elapsed < target)
|
||||||
|
std::this_thread::sleep_for(target - elapsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
AppContext appContext;
|
AppContext appContext;
|
||||||
|
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
// Platform init.
|
// Platform init.
|
||||||
appContext.platform = new AppPlatform_glfw();
|
appContext.platform = new AppPlatform_glfw();
|
||||||
|
#if defined(DEBUG) && defined(__EMSCRIPTEN__)
|
||||||
|
EM_ASM({
|
||||||
|
console.log(FS.readdir("/"));
|
||||||
|
console.log(FS.readdir("/data"));
|
||||||
|
console.log(FS.readdir("/data/images"));
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
@@ -126,26 +154,36 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
|
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||||
|
#else
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
GLFWwindow* window = glfwCreateWindow(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight(), "main", NULL, NULL);
|
AppPlatform_glfw* platform = (AppPlatform_glfw*)appContext.platform;
|
||||||
|
|
||||||
|
platform->window = glfwCreateWindow(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight(), "main", NULL, NULL);
|
||||||
|
|
||||||
if (window == NULL) {
|
if (platform->window == NULL) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSetKeyCallback(window, key_callback);
|
glfwSetKeyCallback(platform->window, key_callback);
|
||||||
glfwSetCharCallback(window, character_callback);
|
glfwSetCharCallback(platform->window, character_callback);
|
||||||
glfwSetCursorPosCallback(window, cursor_position_callback);
|
glfwSetCursorPosCallback(platform->window, cursor_position_callback);
|
||||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
glfwSetMouseButtonCallback(platform->window, mouse_button_callback);
|
||||||
glfwSetScrollCallback(window, scroll_callback);
|
glfwSetScrollCallback(platform->window, scroll_callback);
|
||||||
glfwSetWindowSizeCallback(window, window_size_callback);
|
glfwSetWindowSizeCallback(platform->window, window_size_callback);
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(platform->window);
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
App* app = new MAIN_CLASS();
|
App* app = new MAIN_CLASS();
|
||||||
@@ -156,25 +194,14 @@ int main(void) {
|
|||||||
g_app->init(appContext);
|
g_app->init(appContext);
|
||||||
g_app->setSize(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight());
|
g_app->setSize(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight());
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
emscripten_set_main_loop(loop, 0, 1);
|
||||||
|
#else
|
||||||
// Main event loop
|
// Main event loop
|
||||||
using clock = std::chrono::steady_clock;
|
while(!glfwWindowShouldClose(platform->window) && !app->wantToQuit()) {
|
||||||
while(!glfwWindowShouldClose(window) && !app->wantToQuit()) {
|
loop();
|
||||||
auto frameStart = clock::now();
|
|
||||||
|
|
||||||
app->update();
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
glfwSwapInterval(((MAIN_CLASS*)app)->options.getBooleanValue(OPTIONS_VSYNC) ? 1 : 0);
|
|
||||||
if(((MAIN_CLASS*)app)->options.getBooleanValue(OPTIONS_LIMIT_FRAMERATE)) {
|
|
||||||
auto frameEnd = clock::now();
|
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(frameEnd - frameStart);
|
|
||||||
auto target = std::chrono::microseconds(33333); // ~30 fps
|
|
||||||
if(elapsed < target)
|
|
||||||
std::this_thread::sleep_for(target - elapsed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
delete app;
|
delete app;
|
||||||
|
|
||||||
@@ -184,7 +211,7 @@ int main(void) {
|
|||||||
|
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
// Exit.
|
// Exit.
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(platform->window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
&m_threadID // pointer to receive thread ID
|
&m_threadID // pointer to receive thread ID
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__)
|
||||||
mp_threadFunc = (pthread_fn)threadFunc;
|
mp_threadFunc = (pthread_fn)threadFunc;
|
||||||
|
|
||||||
pthread_attr_init(&m_attributes);
|
pthread_attr_init(&m_attributes);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
typedef void *( * pthread_fn )( void * );
|
typedef void *( * pthread_fn )( void * );
|
||||||
|
|
||||||
#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ typedef void *( * pthread_fn )( void * );
|
|||||||
DWORD m_threadID;
|
DWORD m_threadID;
|
||||||
HANDLE m_threadHandle;
|
HANDLE m_threadHandle;
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__)
|
||||||
pthread_fn mp_threadFunc;
|
pthread_fn mp_threadFunc;
|
||||||
pthread_t m_thread;
|
pthread_t m_thread;
|
||||||
pthread_attr_t m_attributes;
|
pthread_attr_t m_attributes;
|
||||||
|
|||||||
Reference in New Issue
Block a user