Merge remote-tracking branch 'upstream/master' into Visuals-Vol-2
17
.github/workflows/android.yml
vendored
|
@ -20,6 +20,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'android/**'
|
||||
|
@ -27,15 +29,24 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends gettext openjdk-11-jdk-headless
|
||||
- name: Build with Gradle
|
||||
sudo apt-get install -y --no-install-recommends gettext openjdk-17-jdk-headless
|
||||
- name: Build AAB with Gradle
|
||||
# We build an AAB as well for uploading to the the Play Store.
|
||||
run: cd android; ./gradlew bundlerelease
|
||||
- name: Build APKs with Gradle
|
||||
# "assemblerelease" is very fast after "bundlerelease".
|
||||
run: cd android; ./gradlew assemblerelease
|
||||
- name: Save AAB artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Minetest-release.aab
|
||||
path: android/app/build/outputs/bundle/release/app-release.aab
|
||||
- name: Save armeabi artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
|
2
.github/workflows/cpp_lint.yml
vendored
|
@ -20,6 +20,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/ci/**'
|
||||
|
|
11
.github/workflows/docker_image.yml
vendored
|
@ -9,7 +9,7 @@ on:
|
|||
push:
|
||||
branches: [ "master" ]
|
||||
# Publish semver tags as releases.
|
||||
tags: [ "*.*.*" ]
|
||||
tags: [ "*" ]
|
||||
pull_request:
|
||||
# Build docker image on pull requests. (but do not publish)
|
||||
paths:
|
||||
|
@ -17,6 +17,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/ci/**'
|
||||
|
@ -25,6 +27,12 @@ on:
|
|||
- '.dockerignore'
|
||||
- '.github/workflows/docker_image.yml'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
use_cache:
|
||||
description: "Use build cache"
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
|
@ -82,6 +90,7 @@ jobs:
|
|||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
no-cache: ${{ (github.event_name == 'workflow_dispatch' && !inputs.use_cache) || startsWith(github.ref, 'refs/tags/') }}
|
||||
|
||||
- name: Test Docker Image
|
||||
run: |
|
||||
|
|
39
.github/workflows/linux.yml
vendored
|
@ -22,6 +22,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/ci/**'
|
||||
|
@ -55,21 +57,21 @@ jobs:
|
|||
./bin/minetest --run-unittests
|
||||
|
||||
# Current gcc version
|
||||
gcc_12:
|
||||
runs-on: ubuntu-22.04
|
||||
gcc_14:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install deps
|
||||
run: |
|
||||
source ./util/ci/common.sh
|
||||
install_linux_deps g++-12 libluajit-5.1-dev
|
||||
install_linux_deps g++-14 libluajit-5.1-dev
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
./util/ci/build.sh
|
||||
env:
|
||||
CC: gcc-12
|
||||
CXX: g++-12
|
||||
CC: gcc-14
|
||||
CXX: g++-14
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
@ -101,21 +103,21 @@ jobs:
|
|||
./bin/minetest --run-unittests
|
||||
|
||||
# Current clang version
|
||||
clang_14:
|
||||
runs-on: ubuntu-22.04
|
||||
clang_18:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install deps
|
||||
run: |
|
||||
source ./util/ci/common.sh
|
||||
install_linux_deps clang-14 lldb
|
||||
install_linux_deps clang-18 lldb
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
./util/ci/build.sh
|
||||
env:
|
||||
CC: clang-14
|
||||
CXX: clang++-14
|
||||
CC: clang-18
|
||||
CXX: clang++-18
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
@ -126,27 +128,26 @@ jobs:
|
|||
./util/test_multiplayer.sh
|
||||
|
||||
# Build with prometheus-cpp (server-only)
|
||||
clang_9_prometheus:
|
||||
name: "clang_9 (PROMETHEUS=1)"
|
||||
runs-on: ubuntu-20.04
|
||||
clang_11_prometheus:
|
||||
name: "clang_11 (PROMETHEUS=1)"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install deps
|
||||
run: |
|
||||
source ./util/ci/common.sh
|
||||
install_linux_deps clang-9
|
||||
install_linux_deps clang-11
|
||||
|
||||
- name: Build prometheus-cpp
|
||||
run: |
|
||||
./util/ci/build_prometheus_cpp.sh
|
||||
run: ./util/ci/build_prometheus_cpp.sh
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
./util/ci/build.sh
|
||||
env:
|
||||
CC: clang-9
|
||||
CXX: clang++-9
|
||||
CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0"
|
||||
CC: clang-11
|
||||
CXX: clang++-11
|
||||
CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0 -DENABLE_CURSES=0"
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
|
|
10
.github/workflows/lua.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
# Note that the integration tests are also run in build.yml, but only when C++ code is changed.
|
||||
integration_tests:
|
||||
name: "Compile and run multiplayer tests"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install deps
|
||||
|
@ -39,7 +39,7 @@ jobs:
|
|||
|
||||
luacheck:
|
||||
name: "Builtin Luacheck and Unit Tests"
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
|
@ -50,11 +50,7 @@ jobs:
|
|||
- uses: leafo/gh-actions-luarocks@v4.3.0
|
||||
|
||||
- name: Install LuaJIT
|
||||
run: |
|
||||
cd $HOME
|
||||
git clone https://github.com/LuaJIT/LuaJIT/
|
||||
cd LuaJIT
|
||||
make -j$(nproc)
|
||||
run: ./util/ci/build_luajit.sh
|
||||
|
||||
- name: Install luarocks tools
|
||||
run: |
|
||||
|
|
4
.github/workflows/macos.yml
vendored
|
@ -19,6 +19,9 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- 'irr/**.mm' # Objective-C(++)
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- '.github/workflows/macos.yml'
|
||||
|
@ -55,6 +58,7 @@ jobs:
|
|||
- name: CPack
|
||||
run: |
|
||||
cd build
|
||||
cmake .. -DINSTALL_DEVTEST=FALSE
|
||||
cpack -G ZIP -B macos
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
|
|
12
.github/workflows/windows.yml
vendored
|
@ -21,6 +21,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/buildbot/**'
|
||||
|
@ -67,8 +69,8 @@ jobs:
|
|||
name: VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }}
|
||||
runs-on: windows-2019
|
||||
env:
|
||||
VCPKG_VERSION: 8eb57355a4ffb410a2e94c07b4dca2dffbee8e50
|
||||
# 2023.10.19
|
||||
VCPKG_VERSION: 01f602195983451bc83e72f4214af2cbc495aa94
|
||||
# 2024.05.24
|
||||
vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp sdl2
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
@ -92,12 +94,6 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Workaround for regression, see https://github.com/minetest/minetest/pull/14536
|
||||
- name: Pin CMake to 3.28
|
||||
uses: lukka/get-cmake@latest
|
||||
with:
|
||||
cmakeVersion: "~3.28.0"
|
||||
|
||||
- name: Restore from cache and run vcpkg
|
||||
uses: lukka/run-vcpkg@v7
|
||||
with:
|
||||
|
|
9
.gitignore
vendored
|
@ -1,5 +1,8 @@
|
|||
## Editors and development environments
|
||||
*~
|
||||
.cmake
|
||||
CMakeUserPresets.json
|
||||
Testing/*
|
||||
*.swp
|
||||
*.bak*
|
||||
*.orig
|
||||
|
@ -26,7 +29,8 @@ gtags.files
|
|||
# Codelite
|
||||
*.project
|
||||
# Visual Studio Code & plugins
|
||||
.vscode/
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
build/.cmake/
|
||||
# Fleet
|
||||
.fleet
|
||||
|
@ -107,7 +111,10 @@ src/cmake_config_githash.h
|
|||
*.iml
|
||||
test_config.h
|
||||
cmake-build-debug/
|
||||
cmake-build-minsizerel/
|
||||
cmake-build-release/
|
||||
cmake-build-relwithdebinfo/
|
||||
cmake-build-default/
|
||||
cmake_config.h
|
||||
cmake_config_githash.h
|
||||
CMakeDoxy*
|
||||
|
|
5
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
|
@ -277,8 +277,9 @@ find_package(Lua REQUIRED)
|
|||
if(NOT USE_LUAJIT)
|
||||
add_subdirectory(lib/bitop)
|
||||
endif()
|
||||
add_subdirectory(lib/sha256)
|
||||
|
||||
if(BUILD_BENCHMARKS)
|
||||
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
|
||||
add_subdirectory(lib/catch2)
|
||||
endif()
|
||||
|
||||
|
|
41
CMakePresets.json
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 12
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"displayName": "Debug",
|
||||
"description": "Debug preset with debug symbols and no optimizations",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"displayName": "Release",
|
||||
"description": "Release preset with optimizations and no debug symbols",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "RelWithDebInfo",
|
||||
"displayName": "RelWithDebInfo",
|
||||
"description": "Release with debug symbols",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MinSizeRel",
|
||||
"displayName": "MinSizeRel",
|
||||
"description": "Release with minimal code size",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "MinSizeRel"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
ARG DOCKER_IMAGE=alpine:3.19
|
||||
FROM $DOCKER_IMAGE AS dev
|
||||
|
||||
ENV SPATIALINDEX_VERSION master
|
||||
ENV LUAJIT_VERSION v2.1
|
||||
|
||||
RUN apk add --no-cache git build-base cmake curl-dev zlib-dev zstd-dev \
|
||||
|
@ -19,7 +18,7 @@ RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp && \
|
|||
cmake --build build && \
|
||||
cmake --install build && \
|
||||
cd /usr/src/ && \
|
||||
git clone --recursive https://github.com/libspatialindex/libspatialindex -b ${SPATIALINDEX_VERSION} && \
|
||||
git clone --recursive https://github.com/libspatialindex/libspatialindex && \
|
||||
cd libspatialindex && \
|
||||
cmake -B build \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr/local && \
|
||||
|
|
|
@ -23,6 +23,7 @@ package net.minetest.minetest;
|
|||
import org.libsdl.app.SDLActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
|
@ -33,6 +34,7 @@ import android.view.WindowManager;
|
|||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
@ -201,7 +203,11 @@ public class GameActivity extends SDLActivity {
|
|||
|
||||
public void openURI(String uri) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||
startActivity(browserIntent);
|
||||
try {
|
||||
startActivity(browserIntent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
runOnUiThread(() -> Toast.makeText(this, R.string.no_web_browser, Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}
|
||||
|
||||
public String getUserDataPath() {
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
<string name="unzip_notification_title">Loading Minetest</string>
|
||||
<string name="unzip_notification_description">Less than 1 minute…</string>
|
||||
<string name="ime_dialog_done">Done</string>
|
||||
<string name="no_web_browser">No web browser found</string>
|
||||
</resources>
|
||||
|
|
|
@ -36,7 +36,7 @@ android {
|
|||
buildTypes {
|
||||
release {
|
||||
ndk {
|
||||
debugSymbolLevel 'SYMBOL_TABLE'
|
||||
debugSymbolLevel 'FULL'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,15 +78,12 @@ function dialog_create(name,get_formspec,buttonhandler,eventhandler)
|
|||
return self
|
||||
end
|
||||
|
||||
-- "message" must already be formspec-escaped, e.g. via fgettext or
|
||||
-- core.formspec_escape.
|
||||
function messagebox(name, message)
|
||||
return dialog_create(name,
|
||||
function()
|
||||
return ([[
|
||||
formspec_version[3]
|
||||
size[8,3]
|
||||
textarea[0.375,0.375;7.25,1.2;;;%s]
|
||||
button[3,1.825;2,0.8;ok;%s]
|
||||
]]):format(message, fgettext("OK"))
|
||||
return ui.get_message_formspec("", message, "ok")
|
||||
end,
|
||||
function(this, fields)
|
||||
if fields.ok then
|
||||
|
|
|
@ -50,6 +50,20 @@ function ui.find_by_name(name)
|
|||
return ui.childlist[name]
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- "title" and "message" must already be formspec-escaped, e.g. via fgettext or
|
||||
-- core.formspec_escape.
|
||||
function ui.get_message_formspec(title, message, btn_id)
|
||||
return table.concat({
|
||||
"size[14,8]",
|
||||
"real_coordinates[true]",
|
||||
"set_focus[", btn_id, ";true]",
|
||||
"box[0.5,1.2;13,5;#000]",
|
||||
("textarea[0.5,1.2;13,5;;%s;%s]"):format(title, message),
|
||||
"button[5,6.6;4,1;", btn_id, ";" .. fgettext("OK") .. "]",
|
||||
})
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
-- Internal functions not to be called from user
|
||||
|
@ -76,6 +90,9 @@ function ui.update()
|
|||
}
|
||||
ui.overridden = true
|
||||
elseif gamedata ~= nil and gamedata.errormessage ~= nil then
|
||||
-- Note to API users:
|
||||
-- "gamedata.errormessage" must not be formspec-escaped yet.
|
||||
-- For translations, fgettext_ne should be used.
|
||||
local error_message = core.formspec_escape(gamedata.errormessage)
|
||||
|
||||
local error_title
|
||||
|
@ -84,15 +101,7 @@ function ui.update()
|
|||
else
|
||||
error_title = fgettext("An error occurred:")
|
||||
end
|
||||
formspec = {
|
||||
"size[14,8]",
|
||||
"real_coordinates[true]",
|
||||
"set_focus[btn_error_confirm;true]",
|
||||
"box[0.5,1.2;13,5;#000]",
|
||||
("textarea[0.5,1.2;13,5;;%s;%s]"):format(
|
||||
error_title, error_message),
|
||||
"button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]"
|
||||
}
|
||||
formspec = {ui.get_message_formspec(error_title, error_message, "btn_error_confirm")}
|
||||
ui.overridden = true
|
||||
else
|
||||
local active_toplevel_ui_elements = 0
|
||||
|
|
|
@ -41,6 +41,7 @@ core.features = {
|
|||
item_meta_range = true,
|
||||
node_interaction_actor = true,
|
||||
moveresult_new_pos = true,
|
||||
override_item_remove_fields = true,
|
||||
}
|
||||
|
||||
function core.has_feature(arg)
|
||||
|
|
|
@ -110,7 +110,7 @@ if core.set_push_moveresult1 then
|
|||
standing_on_object = b2,
|
||||
collisions = {{
|
||||
type = "node",
|
||||
axis = AXES[axis],
|
||||
axis = AXES[axis + 1],
|
||||
node_pos = vector.new(npx, npy, npz),
|
||||
new_pos = vector.new(v0x, v0y, v0z),
|
||||
old_velocity = vector.new(v1x, v1y, v1z),
|
||||
|
|
|
@ -404,7 +404,7 @@ core.register_item(":", {
|
|||
})
|
||||
|
||||
|
||||
function core.override_item(name, redefinition)
|
||||
function core.override_item(name, redefinition, del_fields)
|
||||
if redefinition.name ~= nil then
|
||||
error("Attempt to redefine name of "..name.." to "..dump(redefinition.name), 2)
|
||||
end
|
||||
|
@ -418,6 +418,9 @@ function core.override_item(name, redefinition)
|
|||
for k, v in pairs(redefinition) do
|
||||
rawset(item, k, v)
|
||||
end
|
||||
for _, field in ipairs(del_fields or {}) do
|
||||
rawset(item, field, nil)
|
||||
end
|
||||
register_item_raw(item)
|
||||
end
|
||||
|
||||
|
|
|
@ -71,7 +71,9 @@ local function download_and_extract(param)
|
|||
os.remove(filename)
|
||||
if tempfolder == "" then
|
||||
return {
|
||||
msg = fgettext_ne("Failed to extract \"$1\" (unsupported file type or broken archive)", package.title),
|
||||
msg = fgettext_ne("Failed to extract \"$1\" " ..
|
||||
"(insufficient disk space, unsupported file type or broken archive)",
|
||||
package.title),
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ local function resolve_auto_install_spec()
|
|||
end
|
||||
|
||||
if not resolved then
|
||||
gamedata.errormessage = fgettext("The package $1 was not found.", auto_install_spec)
|
||||
gamedata.errormessage = fgettext_ne("The package $1 was not found.", auto_install_spec)
|
||||
ui.update()
|
||||
|
||||
auto_install_spec = nil
|
||||
|
|
|
@ -66,35 +66,45 @@ local function get_formspec(data)
|
|||
message_bg = mt_color_orange
|
||||
end
|
||||
|
||||
local ENABLE_TOUCH = core.settings:get_bool("enable_touch")
|
||||
|
||||
local w = ENABLE_TOUCH and 14 or 7
|
||||
local padded_w = w - 2*0.375
|
||||
local dropdown_w = ENABLE_TOUCH and 10.2 or 4.25
|
||||
local button_w = (padded_w - 0.25) / 3
|
||||
local button_pad = button_w / 2
|
||||
|
||||
local formspec = {
|
||||
"formspec_version[3]",
|
||||
"size[7,7.85]",
|
||||
"size[", w, ",9.05]",
|
||||
ENABLE_TOUCH and "padding[0.01,0.01]" or "position[0.5,0.55]",
|
||||
"style[title;border=false]",
|
||||
"box[0,0;7,0.5;#3333]",
|
||||
"button[0,0;7,0.5;title;", fgettext("Install $1", package.title) , "]",
|
||||
"box[0,0;", w, ",0.8;#3333]",
|
||||
"button[0,0;", w, ",0.8;title;", fgettext("Install $1", package.title) , "]",
|
||||
|
||||
"container[0.375,0.70]",
|
||||
"container[0.375,1]",
|
||||
|
||||
"label[0,0.25;", fgettext("Base Game:"), "]",
|
||||
"dropdown[2,0;4.25,0.5;selected_game;", table.concat(game_list, ","), ";", selected_game_idx, "]",
|
||||
"label[0,0.4;", fgettext("Base Game:"), "]",
|
||||
"dropdown[", padded_w - dropdown_w, ",0;", dropdown_w, ",0.8;selected_game;",
|
||||
table.concat(game_list, ","), ";", selected_game_idx, "]",
|
||||
|
||||
"label[0,0.8;", fgettext("Dependencies:"), "]",
|
||||
"label[0,1.1;", fgettext("Dependencies:"), "]",
|
||||
|
||||
"tablecolumns[color;text;color;text]",
|
||||
"table[0,1.1;6.25,3;packages;", table.concat(formatted_deps, ","), "]",
|
||||
"table[0,1.4;", padded_w, ",3;packages;", table.concat(formatted_deps, ","), "]",
|
||||
|
||||
"container_end[]",
|
||||
|
||||
"checkbox[0.375,5.1;will_install_deps;",
|
||||
"checkbox[0.375,5.7;will_install_deps;",
|
||||
fgettext("Install missing dependencies"), ";",
|
||||
will_install_deps and "true" or "false", "]",
|
||||
|
||||
"box[0,5.4;7,1.2;", message_bg, "]",
|
||||
"textarea[0.375,5.5;6.25,1;;;", message, "]",
|
||||
"box[0,6;", w, ",1.8;", message_bg, "]",
|
||||
"textarea[0.375,6.1;", padded_w, ",1.6;;;", message, "]",
|
||||
|
||||
"container[1.375,6.85]",
|
||||
"button[0,0;2,0.8;install_all;", fgettext("Install"), "]",
|
||||
"button[2.25,0;2,0.8;cancel;", fgettext("Cancel"), "]",
|
||||
"container[", 0.375 + button_pad, ",8.05]",
|
||||
"button[0,0;", button_w, ",0.8;install_all;", fgettext("Install"), "]",
|
||||
"button[", 0.25 + button_w, ",0;", button_w, ",0.8;cancel;", fgettext("Cancel"), "]",
|
||||
"container_end[]",
|
||||
}
|
||||
|
||||
|
|
|
@ -723,6 +723,11 @@ local function eventhandler(event)
|
|||
mm_game_theme.set_engine(true)
|
||||
return true
|
||||
end
|
||||
if event == "FullscreenChange" then
|
||||
-- Refresh the formspec to keep the fullscreen checkbox up to date.
|
||||
ui.update()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
|
|
@ -156,10 +156,18 @@ local function get_formspec(tabview, name, tabdata)
|
|||
|
||||
-- Point the player to ContentDB when no games are found
|
||||
if #pkgmgr.games == 0 then
|
||||
local W = tabview.width
|
||||
local H = tabview.height
|
||||
|
||||
local hypertext = "<global valign=middle halign=center size=18>" ..
|
||||
fgettext_ne("Minetest is a game-creation platform that allows you to play many different games.") .. "\n" ..
|
||||
fgettext_ne("Minetest doesn't come with a game by default.") .. " " ..
|
||||
fgettext_ne("You need to install a game before you can create a world.")
|
||||
|
||||
local button_y = H * 2/3 - 0.6
|
||||
return table.concat({
|
||||
"style[label_button;border=false]",
|
||||
"button[2.75,1.5;10,1;label_button;", fgettext("You have no games installed."), "]",
|
||||
"button[5.25,3.5;5,1.2;game_open_cdb;", fgettext("Install a game"), "]"})
|
||||
"hypertext[0.375,0;", W - 2*0.375, ",", button_y, ";ht;", core.formspec_escape(hypertext), "]",
|
||||
"button[5.25,", button_y, ";5,1.2;game_open_cdb;", fgettext("Install a game"), "]"})
|
||||
end
|
||||
|
||||
local retval = ""
|
||||
|
|
|
@ -265,8 +265,8 @@ undersampling (Undersampling) int 1 1 8
|
|||
|
||||
[**Graphics Effects]
|
||||
|
||||
# Makes all liquids opaque
|
||||
opaque_water (Opaque liquids) bool false
|
||||
# Allows liquids to be translucent.
|
||||
translucent_liquids (Translucent liquids) bool true
|
||||
|
||||
# Leaves style:
|
||||
# - Fancy: all faces visible
|
||||
|
@ -381,8 +381,7 @@ crosshair_alpha (Crosshair alpha) int 255 0 255
|
|||
|
||||
[**Fog]
|
||||
|
||||
# Whether to fog out the end of the visible area. This option only works
|
||||
# with the 'debug' privilege.
|
||||
# Whether to fog out the end of the visible area.
|
||||
enable_fog (Fog) bool true
|
||||
|
||||
# Make fog and sky colors depend on daytime (dawn/sunset) and view direction.
|
||||
|
@ -1785,6 +1784,9 @@ deprecated_lua_api_handling (Deprecated Lua API handling) enum log none,log,erro
|
|||
# Enable random user input (only used for testing).
|
||||
random_input (Random input) bool false
|
||||
|
||||
# Enable random mod loading (mainly used for testing).
|
||||
random_mod_load_order (Random mod load order) bool false
|
||||
|
||||
# Enable mod channels support.
|
||||
enable_mod_channels (Mod channels) bool false
|
||||
|
||||
|
@ -2421,6 +2423,9 @@ keymap_minimap (Minimap key) key KEY_KEY_V
|
|||
# Key for taking screenshots.
|
||||
keymap_screenshot (Screenshot) key KEY_F12
|
||||
|
||||
# Key for toggling fullscreen mode.
|
||||
keymap_fullscreen (Fullscreen key) key KEY_F11
|
||||
|
||||
# Key for dropping the currently selected item.
|
||||
keymap_drop (Drop item key) key KEY_KEY_Q
|
||||
|
||||
|
@ -2532,7 +2537,7 @@ keymap_toggle_chat (Chat toggle key) key KEY_F2
|
|||
# Key for toggling the display of the large chat console.
|
||||
keymap_console (Large chat console key) key KEY_F10
|
||||
|
||||
# Key for toggling the display of fog. Only usable with 'debug' privilege.
|
||||
# Key for toggling the display of fog.
|
||||
keymap_toggle_fog (Fog toggle key) key KEY_F3
|
||||
|
||||
# Key for toggling the camera update. Only usable with 'debug' privilege.
|
||||
|
@ -2544,6 +2549,9 @@ keymap_toggle_debug (Debug info toggle key) key KEY_F5
|
|||
# Key for toggling the display of the profiler. Used for development.
|
||||
keymap_toggle_profiler (Profiler toggle key) key KEY_F6
|
||||
|
||||
# Key for toggling the display of mapblock boundaries.
|
||||
keymap_toggle_block_bounds (Block bounds toggle key) key
|
||||
|
||||
# Key for switching between first- and third-person camera.
|
||||
keymap_camera_mode (Toggle camera mode key) key KEY_KEY_C
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@ vec4 applyBloom(vec4 color, vec2 uv)
|
|||
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
||||
*/
|
||||
|
||||
vec3 uncharted2Tonemap(vec3 x)
|
||||
// see https://github.com/minetest/minetest/pull/14688
|
||||
highp vec3 uncharted2Tonemap(highp vec3 x)
|
||||
{
|
||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ General options and their default values:
|
|||
SemiDebug - Partially optimized debug build
|
||||
RelWithDebInfo - Release build with debug information
|
||||
MinSizeRel - Release build with -Os passed to compiler to make executable as small as possible
|
||||
PRECOMPILE_HEADERS=FALSE - Precompile some headers (experimental; requires CMake 3.16 or later)
|
||||
PRECOMPILED_HEADERS_PATH= - Path to a file listing all headers to precompile (default points to src/precompiled_headers.txt)
|
||||
ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http
|
||||
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
|
||||
ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations
|
||||
|
|
BIN
doc/ides/images/jetbrains_cmake_profiles.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
doc/ides/images/jetbrains_ide.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
doc/ides/images/jetbrains_notification_profiles.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
doc/ides/images/jetbrains_open_project_wizard_profiles.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
doc/ides/images/jetbrains_open_project_wizard_windows_cmake.png
Normal file
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 46 KiB |
BIN
doc/ides/images/jetbrains_vcpkg.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/ides/images/vscode_cmake_preset_selection.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
doc/ides/images/vscode_toolbar.png
Normal file
After Width: | Height: | Size: 24 KiB |
81
doc/ides/jetbrains.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
# [Jetbrains IntellIJ CLion](https://www.jetbrains.com/clion)
|
||||
|
||||
## Linux
|
||||
|
||||
When opening the folder for the first time, select `Open as CMake project` if the IDE ask you between Make and CMake.
|
||||
|
||||
The IDE will open the folder and display the open project wizard:
|
||||
|
||||

|
||||
|
||||
CLion try to determine a base configuration, but Minetest define it's own presets for easier setup. So you need to
|
||||
delete the `Debug` profile with the `-` sign and close the dialog.
|
||||
|
||||
You should notice a notification telling you 4 presets have been loaded in the bottom right corner.
|
||||
|
||||

|
||||
|
||||
Clicking on the `View` link or going to `Settings > Build, Execution, Deployment > CMake` you should get a window
|
||||
similar to the Open Project Wizard, but with the readonly presets listed.
|
||||
|
||||

|
||||
|
||||
By default, none of the presets are enabled. You can select them and enable the ones you want. Keep in mind that
|
||||
triggering the CMake project reload (VCS updates, config changes, etc) will reload all the enabled profiles, so unless
|
||||
you need the other ones you can enable just `Debug` and `Release`.
|
||||
|
||||
If none of the availlable profiles fit your needs, you can create a `CMakeUserPresets.json` file, edit it by hand and
|
||||
CLion will load the presets in this window. But the easiest solution is to create an editable copy of one of the availlable
|
||||
presets with the `Copy` button icon.
|
||||
|
||||
After these steps you should get an IDE like this.
|
||||
|
||||
On the main toolbar at the top right, you have a dropdown for selecting the CMake profile to use for the build. You have another dropdown next to it to select the build target; by default the `minetest` executable will be selected, but you may also have to use `IrrlichtMt` for building just the library .
|
||||
|
||||

|
||||
|
||||
You can rightclick the topbar to change the project icon and color, for fancier looking IDE.
|
||||
|
||||
## Windows
|
||||
|
||||
Under Windows, the recommended compiler is the [Visual Studio](https://visualstudio.microsoft.com) compiler.
|
||||
|
||||
From the Visual Studio installer, you need to install the `Desktop development with C++` Workload. CMake is already
|
||||
bundled in CLion.
|
||||
|
||||
By default, CLion have a MinGW compiler bundled, so if you want to use Visual Studio, you need to configure it as the default compiler.
|
||||
|
||||
CLion may ask you in the open project wisard for your compilers, with MinGW and Visual Studio if you have installed it predefined. You can use the arrows to make `Visual Studio` the default.
|
||||
|
||||
If not you can go to `Settings > Build, Execution, Deployment > Toolchains` to change it.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
Then, the process is roughly similar to Linux, you just need to pick `Visual Studio` as toolchain.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
[Vcpkg](https://vcpkg.io) is the recommended way of installing Minetest dependencies.
|
||||
|
||||
You need to let CLion know about a `vcpkg` installation to let the bundled CMake use the dependencies seamlessly and get
|
||||
IDE integration. (Require CLion 2023 or later)
|
||||
|
||||
Go to `View > Tool Windows > Vcpkg` and click the add button. I will open a popup allowing you to add a Vcpkg
|
||||
installation. By default it will download a new one that you can use to install your dependencies, but if you already
|
||||
have one installed or you do not plan on using CLion only then install Vcpkg by hand and select your installation
|
||||
directory. Don't forget to check `Add vcpkg installation to existing CMake profiles`. If you haven't already installed
|
||||
Minetest dependencies in your vcpkg installation, you can do it right from CLion's Vcpkg tool window.
|
||||
|
||||

|
||||
|
||||
Reloading the CMake project (should happen automatically, or display a notification for outdated CMake project) will now
|
||||
load the dependencies.
|
||||
|
||||
[More infos on Vcpkg integration in CLion](https://blog.jetbrains.com/clion/2023/01/support-for-vcpkg-in-clion)
|
||||
|
7
doc/ides/visual_studio.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# [Visual Studio](https://visualstudio.microsoft.com)
|
||||
|
||||
From the Visual Studio installer, you need to install the `Desktop development with C++` Workload. You need to make sure the `C++ CMake tools for Windows` component is included in the installation details panel.
|
||||
|
||||
You need to install [Vcpkg](https://vcpkg.io) and install Minetest dependencies as stated in the compilation documentation.
|
||||
|
||||
For the packages to be discoverable and used by Visual Studio, you need to run `vcpkg integrate install`.
|
51
doc/ides/vscode.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# [Visual Studio Code](https://code.visualstudio.com)
|
||||
|
||||
VSCode suppport for C/C++ and CMake is provided by
|
||||
the [Microsoft C/C++ extension pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools-extension-pack).
|
||||
You can install it from the VSCode extensions tab.
|
||||
|
||||
If you use a unofficial VSCode distribution like [VSCodium](https://vscodium.com), you will need to install the
|
||||
extension pack manually by downloading the VSIX files and going to `Extensions > ... > Install from VSIX`.
|
||||
|
||||
CMake support for VSCode uses CMake presets provided by the project by default.
|
||||
|
||||
When you open the Minetest folder with VSCode, you should get a quick pick asking you for the default preset.
|
||||
|
||||

|
||||
|
||||
You can use the bottom bar to change the CMake profile, change the build target, build, run and debug (running/debugging doesn't build first).
|
||||
|
||||

|
||||
|
||||
Like most of the VSCode experience, it may be faster to use commands directly (most of the VSCode UI just trigger commands).
|
||||
|
||||
| Command Name | Usecase |
|
||||
|----------------------------------|----------------------------------|
|
||||
| `CMake: Select Configure Preset` | Change the current CMake profile |
|
||||
| `CMake: Set Build Target` | Change the current build target |
|
||||
| `CMake: Build` | Build current target |
|
||||
| `CMake: Clean` | Clean build files |
|
||||
| `CMake: Run Without Debugging` | Run selected run target |
|
||||
| `CMake: Debug` | Debug selected run target |
|
||||
|
||||
## Windows
|
||||
|
||||
Under Windows, the recommended compiler is the [Visual Studio](https://visualstudio.microsoft.com) compiler.
|
||||
|
||||
From the Visual Studio installer, you need to install the `Desktop development with C++` Workload.
|
||||
|
||||
[Vcpkg](https://vcpkg.io) is the recommended way of installing Minetest dependencies.
|
||||
|
||||
Follow the official documentation to install it and install Minetest dependencies as explained in [Windows compilation process](../compiling/windows.md).
|
||||
|
||||
You need to let CMake know about the `vcpkg` installation in VSCode.
|
||||
|
||||
Modify your `.vscode/settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"cmake.configureSettings": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -63,6 +63,8 @@ The game directory can contain the following files:
|
|||
* `name`: (Deprecated) same as title.
|
||||
* `description`: Short description to be shown in the content tab.
|
||||
See [Translating content meta](#translating-content-meta).
|
||||
* `first_mod`: Use this to specify the mod that must be loaded before any other mod.
|
||||
* `last_mod`: Use this to specify the mod that must be loaded after all other mods
|
||||
* `allowed_mapgens = <comma-separated mapgens>`
|
||||
e.g. `allowed_mapgens = v5,v6,flat`
|
||||
Mapgens not in this list are removed from the list of mapgens for the
|
||||
|
@ -5444,6 +5446,8 @@ Utilities
|
|||
node_interaction_actor = true,
|
||||
-- "new_pos" field in entity moveresult (5.9.0)
|
||||
moveresult_new_pos = true,
|
||||
-- Allow removing definition fields in `minetest.override_item`
|
||||
override_item_remove_fields = true,
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -5613,11 +5617,17 @@ Call these functions only at load time!
|
|||
* `minetest.register_node(name, node definition)`
|
||||
* `minetest.register_craftitem(name, item definition)`
|
||||
* `minetest.register_tool(name, item definition)`
|
||||
* `minetest.override_item(name, redefinition)`
|
||||
* `minetest.override_item(name, redefinition, del_fields)`
|
||||
* `redefinition` is a table of fields `[name] = new_value`,
|
||||
overwriting fields of or adding fields to the existing definition.
|
||||
* `del_fields` is a list of field names to be set
|
||||
to `nil` ("deleted from") the original definition.
|
||||
* Overrides fields of an item registered with register_node/tool/craftitem.
|
||||
* Note: Item must already be defined, (opt)depend on the mod defining it.
|
||||
* Example: `minetest.override_item("default:mese",
|
||||
{light_source=minetest.LIGHT_MAX})`
|
||||
{light_source=minetest.LIGHT_MAX}, {"sounds"})`:
|
||||
Overwrites the `light_source` field,
|
||||
removes the sounds from the definition of the mese block.
|
||||
* `minetest.unregister_item(name)`
|
||||
* Unregisters the item from the engine, and deletes the entry with key
|
||||
`name` from `minetest.registered_items` and from the associated item table
|
||||
|
@ -5786,6 +5796,7 @@ Call these functions only at load time!
|
|||
* `last_login`: The timestamp of the previous login, or nil if player is new
|
||||
* `minetest.register_on_leaveplayer(function(ObjectRef, timed_out))`
|
||||
* Called when a player leaves the game
|
||||
* Does not get executed for connected players on shutdown.
|
||||
* `timed_out`: True for timeout, false for other reasons.
|
||||
* `minetest.register_on_authplayer(function(name, ip, is_success))`
|
||||
* Called when a client attempts to log into an account.
|
||||
|
@ -8222,7 +8233,11 @@ child will follow movement and rotation of that bone.
|
|||
* `"plain"`: Uses 0 textures, `base_color` used as both fog and sky.
|
||||
(default: `"regular"`)
|
||||
* `textures`: A table containing up to six textures in the following
|
||||
order: Y+ (top), Y- (bottom), X- (west), X+ (east), Z+ (north), Z- (south).
|
||||
order: Y+ (top), Y- (bottom), X+ (east), X- (west), Z- (south), Z+ (north).
|
||||
The top and bottom textures are oriented in-line with the east (X+) face (the top edge of the
|
||||
bottom texture and the bottom edge of the top texture touch the east face).
|
||||
Some top and bottom textures expect to be aligned with the north face and will need to be rotated
|
||||
by -90 and 90 degrees, respectively, to fit the eastward orientation.
|
||||
* `clouds`: Boolean for whether clouds appear. (default: `true`)
|
||||
* `sky_color`: A table used in `"regular"` type only, containing the
|
||||
following values (alpha is ignored):
|
||||
|
@ -8257,14 +8272,13 @@ child will follow movement and rotation of that bone.
|
|||
`"default"` uses the classic Minetest sun and moon tinting.
|
||||
Will use tonemaps, if set to `"default"`. (default: `"default"`)
|
||||
* `fog`: A table with following optional fields:
|
||||
* `fog_distance`: integer, set an upper bound the client's viewing_range (inluding range_all).
|
||||
By default, fog_distance is controlled by the client's viewing_range, and this field is not set.
|
||||
Any value >= 0 sets the desired upper bound for the client's viewing_range and disables range_all.
|
||||
Any value < 0, resets the behavior to being client-controlled.
|
||||
* `fog_distance`: integer, set an upper bound for the client's viewing_range.
|
||||
Any value >= 0 sets the desired upper bound for viewing_range,
|
||||
disables range_all and prevents disabling fog (F3 key by default).
|
||||
Any value < 0 resets the behavior to being client-controlled.
|
||||
(default: -1)
|
||||
* `fog_start`: float, override the client's fog_start.
|
||||
Fraction of the visible distance at which fog starts to be rendered.
|
||||
By default, fog_start is controlled by the client's `fog_start` setting, and this field is not set.
|
||||
Any value between [0.0, 0.99] set the fog_start as a fraction of the viewing_range.
|
||||
Any value < 0, resets the behavior to being client-controlled.
|
||||
(default: -1)
|
||||
|
|
|
@ -14,7 +14,8 @@ Callbacks
|
|||
* `core.button_handler(fields)`: called when a button is pressed.
|
||||
* `fields` = `{name1 = value1, name2 = value2, ...}`
|
||||
* `core.event_handler(event)`
|
||||
* `event`: `"MenuQuit"`, `"KeyEnter"`, `"ExitButton"` or `"EditBoxEnter"`
|
||||
* `event`: `"MenuQuit"`, `"KeyEnter"`, `"ExitButton"`, `"EditBoxEnter"` or
|
||||
`"FullscreenChange"`
|
||||
|
||||
|
||||
Gamedata
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
title = Development Test
|
||||
description = Testing environment to help with testing the engine features of Minetest. It can also be helpful in mod development.
|
||||
first_mod = first_mod
|
||||
last_mod = last_mod
|
||||
|
|
1
games/devtest/mods/first_mod/init.lua
Normal file
|
@ -0,0 +1 @@
|
|||
-- Nothing to do here, loading order is tested in C++ unittests.
|
2
games/devtest/mods/first_mod/mod.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
name = first_mod
|
||||
description = Mod which should be loaded before every other mod.
|
1
games/devtest/mods/last_mod/init.lua
Normal file
|
@ -0,0 +1 @@
|
|||
-- Nothing to do here, loading order is tested in C++ unittests.
|
5
games/devtest/mods/last_mod/mod.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
name = last_mod
|
||||
description = Mod which should be loaded as last mod.
|
||||
# Test dependencies
|
||||
optional_depends = unittests
|
||||
depends = first_mod
|
|
@ -181,14 +181,6 @@ fractal = nil
|
|||
frac_emb = nil
|
||||
checker = nil
|
||||
|
||||
do
|
||||
-- we used to write the textures to our mod folder. in order to avoid
|
||||
-- duplication errors delete them if they still exist.
|
||||
local path = core.get_modpath(core.get_current_modname()) .. "/textures/"
|
||||
os.remove(path .. "testnodes_generated_mb.png")
|
||||
os.remove(path .. "testnodes_generated_ck.png")
|
||||
end
|
||||
|
||||
local textures_path = core.get_worldpath() .. "/"
|
||||
core.safe_file_write(
|
||||
textures_path .. "testnodes1.png",
|
||||
|
|
|
@ -160,7 +160,7 @@ function unittests.run_all()
|
|||
-- Print stats
|
||||
assert(#unittests.list == counters.total)
|
||||
print(string.rep("+", 80))
|
||||
print(string.format("Unit Test Results: %s",
|
||||
print(string.format("Devtest Unit Test Results: %s",
|
||||
counters.total == counters.passed and "PASSED" or "FAILED"))
|
||||
print(string.format(" %d / %d failed tests.",
|
||||
counters.total - counters.passed, counters.total))
|
||||
|
@ -185,22 +185,46 @@ dofile(modpath .. "/content_ids.lua")
|
|||
dofile(modpath .. "/metadata.lua")
|
||||
dofile(modpath .. "/raycast.lua")
|
||||
dofile(modpath .. "/inventory.lua")
|
||||
dofile(modpath .. "/load_time.lua")
|
||||
|
||||
--------------
|
||||
|
||||
local function send_results(name, ok)
|
||||
core.chat_send_player(name,
|
||||
minetest.colorize(ok and "green" or "red",
|
||||
(ok and "All devtest unit tests passed." or
|
||||
"There were devtest unit test failures.") ..
|
||||
" Check the console for detailed output."))
|
||||
end
|
||||
|
||||
if core.settings:get_bool("devtest_unittests_autostart", false) then
|
||||
local test_results = nil
|
||||
core.after(0, function()
|
||||
-- CI adds a mod which sets `unittests.on_finished`
|
||||
-- to write status information to the filesystem
|
||||
local old_on_finished = unittests.on_finished
|
||||
unittests.on_finished = function(ok)
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
send_results(player:get_player_name(), ok)
|
||||
end
|
||||
test_results = ok
|
||||
old_on_finished(ok)
|
||||
end
|
||||
coroutine.wrap(unittests.run_all)()
|
||||
end)
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
if test_results == nil then
|
||||
return -- tests haven't completed yet
|
||||
end
|
||||
send_results(player:get_player_name(), test_results)
|
||||
end)
|
||||
else
|
||||
core.register_chatcommand("unittests", {
|
||||
privs = {basic_privs=true},
|
||||
description = "Runs devtest unittests (may modify player or map state)",
|
||||
func = function(name, param)
|
||||
unittests.on_finished = function(ok)
|
||||
core.chat_send_player(name,
|
||||
(ok and "All tests passed." or "There were test failures.") ..
|
||||
" Check the console for detailed output.")
|
||||
send_results(name, ok)
|
||||
end
|
||||
coroutine.wrap(unittests.run_all)()
|
||||
return true, ""
|
||||
|
|
13
games/devtest/mods/unittests/load_time.lua
Normal file
|
@ -0,0 +1,13 @@
|
|||
-- Test item (un)registration and overriding
|
||||
do
|
||||
local itemname = "unittests:test_override_item"
|
||||
minetest.register_craftitem(":" .. itemname, {description = "foo"})
|
||||
assert(assert(minetest.registered_items[itemname]).description == "foo")
|
||||
minetest.override_item(itemname, {description = "bar"})
|
||||
assert(assert(minetest.registered_items[itemname]).description == "bar")
|
||||
minetest.override_item(itemname, {}, {"description"})
|
||||
-- description has the empty string as a default
|
||||
assert(assert(minetest.registered_items[itemname]).description == "")
|
||||
minetest.unregister_item("unittests:test_override_item")
|
||||
assert(minetest.registered_items["unittests:test_override_item"] == nil)
|
||||
end
|
|
@ -1,3 +1,4 @@
|
|||
name = unittests
|
||||
description = Adds automated unit tests for the engine
|
||||
depends = basenodes
|
||||
# Also test that it is possible to depend on first_mod
|
||||
depends = first_mod, basenodes
|
||||
|
|
|
@ -331,7 +331,6 @@ struct SEvent
|
|||
|
||||
//! A bitmap of button states. You can use isButtonPressed() to determine
|
||||
//! if a button is pressed or not.
|
||||
//! Currently only valid if the event was EMIE_MOUSE_MOVED
|
||||
u32 ButtonStates;
|
||||
|
||||
//! Is the left button pressed down?
|
||||
|
|
|
@ -176,6 +176,32 @@ public:
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Calculate size of vertices and indices in memory
|
||||
virtual size_t getSize() const
|
||||
{
|
||||
size_t ret = 0;
|
||||
switch (getVertexType()) {
|
||||
case video::EVT_STANDARD:
|
||||
ret += sizeof(video::S3DVertex) * getVertexCount();
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
ret += sizeof(video::S3DVertex2TCoords) * getVertexCount();
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
ret += sizeof(video::S3DVertexTangents) * getVertexCount();
|
||||
break;
|
||||
}
|
||||
switch (getIndexType()) {
|
||||
case video::EIT_16BIT:
|
||||
ret += sizeof(u16) * getIndexCount();
|
||||
break;
|
||||
case video::EIT_32BIT:
|
||||
ret += sizeof(u32) * getIndexCount();
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -179,6 +179,11 @@ public:
|
|||
/** \return True if window is fullscreen. */
|
||||
virtual bool isFullscreen() const = 0;
|
||||
|
||||
//! Enables or disables fullscreen mode.
|
||||
/** Only works on SDL.
|
||||
\return True on success. */
|
||||
virtual bool setFullscreen(bool fullscreen) { return false; }
|
||||
|
||||
//! Checks if the window could possibly be visible.
|
||||
/** If this returns false, you should not do any rendering. */
|
||||
virtual bool isWindowVisible() const { return true; };
|
||||
|
|
|
@ -852,6 +852,7 @@ bool CIrrDeviceMacOSX::run()
|
|||
ievent.MouseInput.Wheel *= 10.0f;
|
||||
else
|
||||
ievent.MouseInput.Wheel *= 5.0f;
|
||||
ievent.MouseInput.ButtonStates = MouseButtonStates;
|
||||
postMouseEvent(event, ievent);
|
||||
break;
|
||||
|
||||
|
@ -1048,6 +1049,7 @@ void CIrrDeviceMacOSX::storeMouseLocation()
|
|||
ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
|
||||
ievent.MouseInput.X = x;
|
||||
ievent.MouseInput.Y = y;
|
||||
ievent.MouseInput.ButtonStates = MouseButtonStates;
|
||||
postEventFromUser(ievent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,6 +272,19 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters ¶m) :
|
|||
SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0");
|
||||
#endif
|
||||
|
||||
// Minetest has its own signal handler
|
||||
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
|
||||
|
||||
// Disabling the compositor is not a good idea in windowed mode.
|
||||
// See https://github.com/minetest/minetest/issues/14596
|
||||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
|
||||
|
||||
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
|
||||
// These are not interesting for our use
|
||||
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
|
||||
SDL_SetHint(SDL_HINT_TV_REMOTE_AS_JOYSTICK, "0");
|
||||
#endif
|
||||
|
||||
// Minetest has its own code to synthesize mouse events from touch events,
|
||||
// so we prevent SDL from doing it.
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||
|
@ -463,13 +476,7 @@ bool CIrrDeviceSDL::createWindowWithContext()
|
|||
{
|
||||
u32 SDL_Flags = 0;
|
||||
|
||||
if (CreationParams.Fullscreen) {
|
||||
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
|
||||
SDL_Flags |= SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
SDL_Flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
#endif
|
||||
}
|
||||
SDL_Flags |= getFullscreenFlag(CreationParams.Fullscreen);
|
||||
if (Resizable)
|
||||
SDL_Flags |= SDL_WINDOW_RESIZABLE;
|
||||
if (CreationParams.WindowMaximized)
|
||||
|
@ -673,6 +680,7 @@ bool CIrrDeviceSDL::run()
|
|||
#else
|
||||
irrevent.MouseInput.Wheel = SDL_event.wheel.y;
|
||||
#endif
|
||||
irrevent.MouseInput.ButtonStates = MouseButtonStates;
|
||||
irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0;
|
||||
irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0;
|
||||
irrevent.MouseInput.X = MouseX;
|
||||
|
@ -889,6 +897,14 @@ bool CIrrDeviceSDL::run()
|
|||
IsInBackground = false;
|
||||
break;
|
||||
|
||||
case SDL_RENDER_TARGETS_RESET:
|
||||
os::Printer::log("Received SDL_RENDER_TARGETS_RESET. Rendering is probably broken.", ELL_ERROR);
|
||||
break;
|
||||
|
||||
case SDL_RENDER_DEVICE_RESET:
|
||||
os::Printer::log("Received SDL_RENDER_DEVICE_RESET. Rendering is probably broken.", ELL_ERROR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // end switch
|
||||
|
@ -1157,14 +1173,37 @@ bool CIrrDeviceSDL::isWindowMaximized() const
|
|||
|
||||
bool CIrrDeviceSDL::isFullscreen() const
|
||||
{
|
||||
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
|
||||
return SDL_GetWindowFlags(0) == SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
if (!Window)
|
||||
return false;
|
||||
u32 flags = SDL_GetWindowFlags(Window);
|
||||
return (flags & SDL_WINDOW_FULLSCREEN) != 0 ||
|
||||
(flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
|
||||
}
|
||||
|
||||
return CIrrDeviceStub::isFullscreen();
|
||||
u32 CIrrDeviceSDL::getFullscreenFlag(bool fullscreen)
|
||||
{
|
||||
if (!fullscreen)
|
||||
return 0;
|
||||
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
|
||||
return SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
return SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CIrrDeviceSDL::setFullscreen(bool fullscreen)
|
||||
{
|
||||
if (!Window)
|
||||
return false;
|
||||
// The SDL wiki says that this may trigger SDL_RENDER_TARGETS_RESET, but
|
||||
// looking at the SDL source, this only happens with D3D, so it's not
|
||||
// relevant to us.
|
||||
bool success = SDL_SetWindowFullscreen(Window, getFullscreenFlag(fullscreen)) == 0;
|
||||
if (!success)
|
||||
os::Printer::log("SDL_SetWindowFullscreen failed", SDL_GetError(), ELL_ERROR);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CIrrDeviceSDL::isWindowVisible() const
|
||||
{
|
||||
return !IsInBackground;
|
||||
|
|
|
@ -86,6 +86,10 @@ public:
|
|||
/** \return True if window is fullscreen. */
|
||||
bool isFullscreen() const override;
|
||||
|
||||
//! Enables or disables fullscreen mode.
|
||||
/** \return True on success. */
|
||||
bool setFullscreen(bool fullscreen) override;
|
||||
|
||||
//! Checks if the window could possibly be visible.
|
||||
bool isWindowVisible() const override;
|
||||
|
||||
|
@ -299,6 +303,8 @@ private:
|
|||
|
||||
bool Resizable;
|
||||
|
||||
static u32 getFullscreenFlag(bool fullscreen);
|
||||
|
||||
core::rect<s32> lastElemPos;
|
||||
|
||||
struct SKeyMap
|
||||
|
|
|
@ -31,7 +31,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
|
|||
elseif(MSVC)
|
||||
string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " msvcrt.lib") # ???? fuck off
|
||||
|
||||
add_compile_options(/GR- /Zl)
|
||||
add_compile_options(/Zl)
|
||||
|
||||
# Enable SSE for floating point math on 32-bit x86 by default
|
||||
# reasoning see minetest issue #11810 and https://gcc.gnu.org/wiki/FloatingPointMath
|
||||
|
|
|
@ -29,18 +29,6 @@
|
|||
|
||||
#include "fast_atof.h"
|
||||
|
||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
||||
static const bool sdl_supports_primary_selection = [] {
|
||||
#if SDL_VERSION_ATLEAST(2, 25, 0)
|
||||
SDL_version linked_version;
|
||||
SDL_GetVersion(&linked_version);
|
||||
return (linked_version.major == 2 && linked_version.minor >= 25) || linked_version.major > 2;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}();
|
||||
#endif
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
|
@ -131,8 +119,7 @@ void COSOperator::copyToPrimarySelection(const c8 *text) const
|
|||
|
||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
||||
#if SDL_VERSION_ATLEAST(2, 25, 0)
|
||||
if (sdl_supports_primary_selection)
|
||||
SDL_SetPrimarySelectionText(text);
|
||||
SDL_SetPrimarySelectionText(text);
|
||||
#endif
|
||||
|
||||
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||
|
@ -195,11 +182,9 @@ const c8 *COSOperator::getTextFromPrimarySelection() const
|
|||
{
|
||||
#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
|
||||
#if SDL_VERSION_ATLEAST(2, 25, 0)
|
||||
if (sdl_supports_primary_selection) {
|
||||
SDL_free(PrimarySelectionText);
|
||||
PrimarySelectionText = SDL_GetPrimarySelectionText();
|
||||
return PrimarySelectionText;
|
||||
}
|
||||
SDL_free(PrimarySelectionText);
|
||||
PrimarySelectionText = SDL_GetPrimarySelectionText();
|
||||
return PrimarySelectionText;
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -704,12 +704,6 @@ IRenderTarget *COpenGL3DriverBase::addRenderTarget()
|
|||
return renderTarget;
|
||||
}
|
||||
|
||||
// small helper function to create vertex buffer object adress offsets
|
||||
static inline u8 *buffer_offset(const long offset)
|
||||
{
|
||||
return ((u8 *)0 + offset);
|
||||
}
|
||||
|
||||
//! draws a vertex primitive list
|
||||
void COpenGL3DriverBase::drawVertexPrimitiveList(const void *vertices, u32 vertexCount,
|
||||
const void *indexList, u32 primitiveCount,
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
// internally used
|
||||
virtual void draw2DImage(const video::ITexture *texture, u32 layer, bool flip);
|
||||
|
||||
using CNullDriver::draw2DImage;
|
||||
|
||||
void draw2DImageBatch(const video::ITexture *texture,
|
||||
const core::array<core::position2d<s32>> &positions,
|
||||
const core::array<core::rect<s32>> &sourceRects,
|
||||
|
|
|
@ -12,47 +12,14 @@
|
|||
#include "os.h"
|
||||
#include <mt_opengl.h>
|
||||
|
||||
// FIXME: this basically duplicates what mt_opengl.h already does
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace video
|
||||
{
|
||||
void COpenGL3ExtensionHandler::initExtensionsOld()
|
||||
{
|
||||
auto extensions_string = reinterpret_cast<const char *>(GL.GetString(GL_EXTENSIONS));
|
||||
const char *pos = extensions_string;
|
||||
while (const char *next = strchr(pos, ' ')) {
|
||||
addExtension(std::string{pos, next});
|
||||
pos = next + 1;
|
||||
}
|
||||
addExtension(pos);
|
||||
extensionsLoaded();
|
||||
}
|
||||
|
||||
void COpenGL3ExtensionHandler::initExtensionsNew()
|
||||
void COpenGL3ExtensionHandler::initExtensions()
|
||||
{
|
||||
int ext_count = GetInteger(GL_NUM_EXTENSIONS);
|
||||
for (int k = 0; k < ext_count; k++)
|
||||
addExtension(reinterpret_cast<const char *>(GL.GetStringi(GL_EXTENSIONS, k)));
|
||||
extensionsLoaded();
|
||||
}
|
||||
|
||||
void COpenGL3ExtensionHandler::addExtension(std::string &&name)
|
||||
{
|
||||
Extensions.emplace(std::move(name));
|
||||
}
|
||||
|
||||
bool COpenGL3ExtensionHandler::queryExtension(const std::string &name) const noexcept
|
||||
{
|
||||
return Extensions.find(name) != Extensions.end();
|
||||
}
|
||||
|
||||
void COpenGL3ExtensionHandler::extensionsLoaded()
|
||||
{
|
||||
os::Printer::log((std::string("Loaded ") + std::to_string(Extensions.size()) + " extensions:").c_str(), ELL_DEBUG);
|
||||
for (const auto &it : Extensions)
|
||||
os::Printer::log((std::string(" ") + it).c_str(), ELL_DEBUG);
|
||||
// reading extensions happens in mt_opengl.cpp
|
||||
for (size_t j = 0; j < IRR_OGLES_Feature_Count; ++j)
|
||||
FeatureAvailable[j] = queryExtension(getFeatureString(j));
|
||||
}
|
||||
|
|
|
@ -28,11 +28,13 @@ public:
|
|||
COpenGL3ExtensionHandler() :
|
||||
COGLESCoreExtensionHandler() {}
|
||||
|
||||
void initExtensionsOld();
|
||||
void initExtensionsNew();
|
||||
void initExtensions();
|
||||
|
||||
/// Checks whether a named extension is present
|
||||
bool queryExtension(const std::string &name) const noexcept;
|
||||
inline bool queryExtension(const std::string &name) const noexcept
|
||||
{
|
||||
return GL.IsExtensionPresent(name);
|
||||
}
|
||||
|
||||
bool queryFeature(video::E_VIDEO_DRIVER_FEATURE feature) const
|
||||
{
|
||||
|
@ -138,7 +140,8 @@ public:
|
|||
|
||||
inline void irrGlDrawBuffer(GLenum mode)
|
||||
{
|
||||
GL.DrawBuffer(mode);
|
||||
// GLES only has DrawBuffers, so use that
|
||||
GL.DrawBuffers(1, &mode);
|
||||
}
|
||||
|
||||
inline void irrGlDrawBuffers(GLsizei n, const GLenum *bufs)
|
||||
|
@ -158,12 +161,6 @@ public:
|
|||
|
||||
bool AnisotropicFilterSupported = false;
|
||||
bool BlendMinMaxSupported = false;
|
||||
|
||||
private:
|
||||
void addExtension(std::string &&name);
|
||||
void extensionsLoaded();
|
||||
|
||||
std::unordered_set<std::string> Extensions;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -37,15 +37,15 @@ public:
|
|||
GLuint getProgram() const;
|
||||
|
||||
virtual void OnSetMaterial(const SMaterial &material, const SMaterial &lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices *services);
|
||||
bool resetAllRenderstates, IMaterialRendererServices *services) override;
|
||||
|
||||
virtual bool OnRender(IMaterialRendererServices *service, E_VERTEX_TYPE vtxtype);
|
||||
virtual bool OnRender(IMaterialRendererServices *service, E_VERTEX_TYPE vtxtype) override;
|
||||
|
||||
virtual void OnUnsetMaterial();
|
||||
virtual void OnUnsetMaterial() override;
|
||||
|
||||
virtual bool isTransparent() const;
|
||||
virtual bool isTransparent() const override;
|
||||
|
||||
virtual s32 getRenderCapability() const;
|
||||
virtual s32 getRenderCapability() const override;
|
||||
|
||||
void setBasicRenderStates(const SMaterial &material, const SMaterial &lastMaterial, bool resetAllRenderstates) override;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ void COpenGL3Driver::initFeatures()
|
|||
{
|
||||
assert(Version.Spec == OpenGLSpec::Compat);
|
||||
assert(isVersionAtLeast(3, 2));
|
||||
initExtensionsNew();
|
||||
initExtensions();
|
||||
|
||||
TextureFormats[ECF_A1R5G5B5] = {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}; // WARNING: may not be renderable
|
||||
TextureFormats[ECF_R5G6B5] = {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}; // GL_RGB565 is an extension until 4.1
|
||||
|
|
|
@ -31,10 +31,7 @@ void COpenGLES2Driver::initFeatures()
|
|||
{
|
||||
assert(Version.Spec == OpenGLSpec::ES);
|
||||
assert(Version.Major >= 2);
|
||||
if (Version.Major >= 3)
|
||||
initExtensionsNew();
|
||||
else
|
||||
initExtensionsOld();
|
||||
initExtensions();
|
||||
|
||||
static const GLenum BGRA8_EXT = 0x93A1;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# catch2 is distributed as a standalone header.
|
||||
# catch2 is distributed as a standalone header / source amalgamation.
|
||||
#
|
||||
# Downloaded from:
|
||||
#
|
||||
# https://github.com/catchorg/Catch2/releases/download/v2.13.9/catch.hpp
|
||||
# https://github.com/catchorg/Catch2/releases/tag/v3.6.0
|
||||
#
|
||||
# The following changes were made to always print in microseconds, fixed format:
|
||||
#
|
||||
|
@ -12,5 +12,7 @@
|
|||
# - return os << duration.value() << ' ' << duration.unitsAsString();
|
||||
# + return os << std::fixed << duration.value() << ' ' << duration.unitsAsString();
|
||||
|
||||
add_library(catch2 INTERFACE)
|
||||
target_include_directories(catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_library(catch2 STATIC catch_amalgamated.cpp)
|
||||
target_compile_definitions(catch2 PRIVATE CATCH_CONFIG_NOSTDOUT CATCH_AMALGAMATED_CUSTOM_MAIN)
|
||||
add_library(Catch2::Catch2 ALIAS catch2)
|
||||
target_include_directories(catch2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
|
17976
lib/catch2/catch.hpp
11638
lib/catch2/catch_amalgamated.cpp
Normal file
14057
lib/catch2/catch_amalgamated.hpp
Normal file
14
lib/sha256/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
project(sha256 C)
|
||||
|
||||
add_library(sha256 STATIC sha256.c)
|
||||
|
||||
target_include_directories(sha256 INTERFACE .)
|
||||
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
check_include_files(endian.h HAVE_ENDIAN_H)
|
||||
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/cmake_config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/cmake_config.h"
|
||||
)
|
||||
target_include_directories(sha256 PRIVATE "${PROJECT_BINARY_DIR}")
|
5
lib/sha256/cmake_config.h.in
Normal file
|
@ -0,0 +1,5 @@
|
|||
// Filled in by the build system
|
||||
|
||||
#pragma once
|
||||
|
||||
#cmakedefine HAVE_ENDIAN_H
|
|
@ -56,17 +56,13 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/sha256.h"
|
||||
#include "my_sha256.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && !defined(__attribute__)
|
||||
#define __attribute__(a)
|
||||
#endif
|
||||
|
||||
/* pull HAVE_ENDIAN_H from Minetest */
|
||||
#include "config.h"
|
||||
#if !HAVE_ENDIAN_H
|
||||
#undef HAVE_ENDIAN_H
|
||||
#endif
|
||||
#include "cmake_config.h" /* HAVE_ENDIAN_H */
|
||||
|
||||
/** endian.h **/
|
||||
/*
|
|
@ -48,6 +48,25 @@ if(NOT (BUILD_CLIENT OR BUILD_SERVER))
|
|||
endif()
|
||||
|
||||
|
||||
option(PRECOMPILE_HEADERS "Precompile some headers (experimental; requires CMake 3.16 or later)" FALSE)
|
||||
set(PRECOMPILED_HEADERS_PATH "" CACHE FILEPATH "Path to a file listing all headers to precompile")
|
||||
|
||||
if(PRECOMPILE_HEADERS)
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.16)
|
||||
message(FATAL_ERROR "PRECOMPILE_HEADERS is on, but precompiled headers require at least CMake 3.16.")
|
||||
endif()
|
||||
if(PRECOMPILED_HEADERS_PATH)
|
||||
set(PRECOMPILED_HEADERS ${PRECOMPILED_HEADERS_PATH})
|
||||
else()
|
||||
set(PRECOMPILED_HEADERS "${CMAKE_SOURCE_DIR}/src/precompiled_headers.txt")
|
||||
endif()
|
||||
message(STATUS "Reading headers to precompile from: ${PRECOMPILED_HEADERS}")
|
||||
# ignore lines that begin with # and empty lines
|
||||
file(STRINGS ${PRECOMPILED_HEADERS} PRECOMPILED_HEADERS_LIST REGEX "^[^#].*$")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PRECOMPILED_HEADERS})
|
||||
endif()
|
||||
|
||||
|
||||
option(ENABLE_CURL "Enable cURL support for fetching media" TRUE)
|
||||
set(USE_CURL FALSE)
|
||||
|
||||
|
@ -332,6 +351,12 @@ endif()
|
|||
include(CheckSymbolExists)
|
||||
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
|
||||
|
||||
if(UNIX)
|
||||
check_symbol_exists(malloc_trim "malloc.h" HAVE_MALLOC_TRIM)
|
||||
else()
|
||||
set(HAVE_MALLOC_TRIM FALSE)
|
||||
endif()
|
||||
|
||||
check_include_files(endian.h HAVE_ENDIAN_H)
|
||||
|
||||
configure_file(
|
||||
|
@ -449,6 +474,10 @@ if(BUILD_BENCHMARKS)
|
|||
set(common_SRCS ${common_SRCS} ${BENCHMARK_SRCS})
|
||||
endif()
|
||||
|
||||
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
|
||||
set(common_SRCS ${common_SRCS} catch.cpp)
|
||||
endif()
|
||||
|
||||
# This gives us the icon and file version information
|
||||
if(WIN32)
|
||||
set(WINRESOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../misc/winresource.rc")
|
||||
|
@ -565,6 +594,7 @@ if(BUILD_CLIENT)
|
|||
${GMP_LIBRARY}
|
||||
${JSON_LIBRARY}
|
||||
${LUA_BIT_LIBRARY}
|
||||
sha256
|
||||
${FREETYPE_LIBRARY}
|
||||
${PLATFORM_LIBS}
|
||||
# on Android, Minetest depends on SDL2 directly
|
||||
|
@ -615,8 +645,12 @@ if(BUILD_CLIENT)
|
|||
if (USE_SPATIAL)
|
||||
target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY})
|
||||
endif()
|
||||
if(BUILD_BENCHMARKS)
|
||||
target_link_libraries(${PROJECT_NAME} catch2)
|
||||
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
|
||||
target_link_libraries(${PROJECT_NAME} Catch2::Catch2)
|
||||
endif()
|
||||
|
||||
if(PRECOMPILE_HEADERS)
|
||||
target_precompile_headers(${PROJECT_NAME} PRIVATE ${PRECOMPILED_HEADERS_LIST})
|
||||
endif()
|
||||
endif(BUILD_CLIENT)
|
||||
|
||||
|
@ -637,6 +671,7 @@ if(BUILD_SERVER)
|
|||
${JSON_LIBRARY}
|
||||
${LUA_LIBRARY}
|
||||
${LUA_BIT_LIBRARY}
|
||||
sha256
|
||||
${GMP_LIBRARY}
|
||||
${PLATFORM_LIBS}
|
||||
)
|
||||
|
@ -677,8 +712,12 @@ if(BUILD_SERVER)
|
|||
${CURL_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
if(BUILD_BENCHMARKS)
|
||||
target_link_libraries(${PROJECT_NAME}server catch2)
|
||||
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
|
||||
target_link_libraries(${PROJECT_NAME}server Catch2::Catch2)
|
||||
endif()
|
||||
|
||||
if(PRECOMPILE_HEADERS)
|
||||
target_precompile_headers(${PROJECT_NAME}server PRIVATE ${PRECOMPILED_HEADERS_LIST})
|
||||
endif()
|
||||
endif(BUILD_SERVER)
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ class TestServerActiveObjectMgr;
|
|||
template <typename T>
|
||||
class ActiveObjectMgr
|
||||
{
|
||||
friend class ::TestClientActiveObjectMgr;
|
||||
friend class ::TestServerActiveObjectMgr;
|
||||
|
||||
public:
|
||||
|
|
|
@ -19,9 +19,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
// This must be set in just this file
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "benchmark_setup.h"
|
||||
#define CATCH_CONFIG_ENABLE_BENCHMARKING
|
||||
#include "catch.h"
|
||||
|
||||
bool run_benchmarks(const char *arg)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Minetest
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "benchmark_setup.h"
|
||||
#include "catch.h"
|
||||
#include "server/activeobjectmgr.h"
|
||||
#include "util/numeric.h"
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "benchmark_setup.h"
|
||||
#include "catch.h"
|
||||
#include "voxelalgorithms.h"
|
||||
#include "dummygamedef.h"
|
||||
#include "dummymap.h"
|
||||
|
|
|
@ -17,7 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "benchmark_setup.h"
|
||||
#include "catch.h"
|
||||
#include "mapblock.h"
|
||||
#include <vector>
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "benchmark_setup.h"
|
||||
#include "catch.h"
|
||||
#include "util/container.h"
|
||||
|
||||
// Testing the standard library is not useful except to compare
|
||||
|
|
|
@ -17,7 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "benchmark_setup.h"
|
||||
#include "catch.h"
|
||||
#include "util/serialize.h"
|
||||
#include <sstream>
|
||||
#include <ios>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2022 Minetest Authors
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#define CATCH_CONFIG_ENABLE_BENCHMARKING
|
||||
#define CATCH_CONFIG_CONSOLE_WIDTH 160
|
||||
#include <catch.hpp>
|
18
src/catch.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Minetest
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "catch.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
namespace Catch {
|
||||
std::ostream& cout() {
|
||||
return rawstream;
|
||||
}
|
||||
std::ostream& clog() {
|
||||
return rawstream;
|
||||
}
|
||||
std::ostream& cerr() {
|
||||
return rawstream;
|
||||
}
|
||||
}
|
14
src/catch.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Minetest
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
// We want to have catch write to rawstream (stderr) instead of stdout.
|
||||
// This should be included instead of <catch_amalgamated.hpp>
|
||||
// to patch the output streams accordingly.
|
||||
#define CATCH_CONFIG_NOSTDOUT
|
||||
#include <catch_amalgamated.hpp>
|
||||
|
||||
namespace Catch {
|
||||
std::ostream& cout();
|
||||
std::ostream& clog();
|
||||
std::ostream& cerr();
|
||||
}
|
|
@ -376,6 +376,13 @@ u32 ChatBuffer::formatChatLine(const ChatLine &line, u32 cols,
|
|||
tempchar = linestring[in_pos+frag_length];
|
||||
}
|
||||
|
||||
// Remove tailing punctuation characters
|
||||
static const std::wstring tailing_chars = L",.";
|
||||
tempchar = linestring[in_pos+frag_length - 1];
|
||||
if (tailing_chars.find(tempchar) != std::wstring::npos) {
|
||||
frag_length--;
|
||||
}
|
||||
|
||||
space_pos = frag_length - 1;
|
||||
// This frag may need to be force-split. That's ok, urls aren't "words"
|
||||
if (frag_length >= remaining_in_output) {
|
||||
|
|
|
@ -278,9 +278,7 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo
|
|||
<< "\" as \"" << vfs_path << "\"." << std::endl;
|
||||
|
||||
std::string contents;
|
||||
if (!fs::ReadFile(real_path, contents)) {
|
||||
errorstream << "Client::scanModSubfolder(): Can't read file \""
|
||||
<< real_path << "\"." << std::endl;
|
||||
if (!fs::ReadFile(real_path, contents, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1945,8 +1943,7 @@ void Client::makeScreenshot()
|
|||
|
||||
while (serial < SCREENSHOT_MAX_SERIAL_TRIES) {
|
||||
filename = filename_base + (serial > 0 ? ("_" + itos(serial)) : "") + filename_ext;
|
||||
std::ifstream tmp(filename.c_str());
|
||||
if (!tmp.good())
|
||||
if (!fs::PathExists(filename))
|
||||
break; // File did not apparently exist, we'll go with it
|
||||
serial++;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "network/networkexceptions.h"
|
||||
#include <IGUISpriteBank.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#if USE_SOUND
|
||||
#include "sound/sound_openal.h"
|
||||
|
@ -68,6 +69,7 @@ static void dump_start_data(const GameStartData &data)
|
|||
ClientLauncher::~ClientLauncher()
|
||||
{
|
||||
delete input;
|
||||
g_settings->deregisterChangedCallback("gui_scaling", setting_changed_callback, this);
|
||||
|
||||
delete g_fontengine;
|
||||
g_fontengine = nullptr;
|
||||
|
@ -126,7 +128,8 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
|||
setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
|
||||
|
||||
guienv = m_rendering_engine->get_gui_env();
|
||||
init_guienv(guienv);
|
||||
config_guienv();
|
||||
g_settings->registerChangedCallback("gui_scaling", setting_changed_callback, this);
|
||||
|
||||
g_fontengine = new FontEngine(guienv);
|
||||
|
||||
|
@ -326,7 +329,12 @@ void ClientLauncher::init_input()
|
|||
}
|
||||
}
|
||||
|
||||
void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv)
|
||||
void ClientLauncher::setting_changed_callback(const std::string &name, void *data)
|
||||
{
|
||||
static_cast<ClientLauncher*>(data)->config_guienv();
|
||||
}
|
||||
|
||||
void ClientLauncher::config_guienv()
|
||||
{
|
||||
gui::IGUISkin *skin = guienv->getSkin();
|
||||
|
||||
|
@ -343,25 +351,37 @@ void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv)
|
|||
float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5f, 20) *
|
||||
RenderingEngine::getDisplayDensity();
|
||||
skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
|
||||
skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density));
|
||||
skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(21.0f * density));
|
||||
skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
|
||||
|
||||
static u32 orig_sprite_id = skin->getIcon(gui::EGDI_CHECK_BOX_CHECKED);
|
||||
static std::unordered_map<std::string, u32> sprite_ids;
|
||||
|
||||
if (density > 1.5f) {
|
||||
std::string sprite_path = porting::path_share + "/textures/base/pack/";
|
||||
if (density > 3.5f)
|
||||
sprite_path.append("checkbox_64.png");
|
||||
else if (density > 2.0f)
|
||||
sprite_path.append("checkbox_32.png");
|
||||
else
|
||||
sprite_path.append("checkbox_16.png");
|
||||
// Texture dimensions should be a power of 2
|
||||
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
|
||||
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
|
||||
video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str());
|
||||
if (sprite_texture) {
|
||||
s32 sprite_id = sprites->addTextureAsSprite(sprite_texture);
|
||||
if (sprite_id != -1)
|
||||
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id);
|
||||
std::string path = porting::path_share + "/textures/base/pack/";
|
||||
if (density > 3.5f)
|
||||
path.append("checkbox_64.png");
|
||||
else if (density > 2.0f)
|
||||
path.append("checkbox_32.png");
|
||||
else
|
||||
path.append("checkbox_16.png");
|
||||
|
||||
auto cached_id = sprite_ids.find(path);
|
||||
if (cached_id != sprite_ids.end()) {
|
||||
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, cached_id->second);
|
||||
} else {
|
||||
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
|
||||
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
|
||||
video::ITexture *texture = driver->getTexture(path.c_str());
|
||||
s32 id = sprites->addTextureAsSprite(texture);
|
||||
if (id != -1) {
|
||||
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, id);
|
||||
sprite_ids.emplace(path, id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, orig_sprite_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@ private:
|
|||
void init_args(GameStartData &start_data, const Settings &cmd_args);
|
||||
bool init_engine();
|
||||
void init_input();
|
||||
void init_guienv(gui::IGUIEnvironment *guienv);
|
||||
|
||||
static void setting_changed_callback(const std::string &name, void *data);
|
||||
void config_guienv();
|
||||
|
||||
bool launch_game(std::string &error_message, bool reconnect_requested,
|
||||
GameStartData &start_data, const Settings &cmd_args);
|
||||
|
|
|
@ -38,13 +38,9 @@ void FileCache::createDir()
|
|||
|
||||
bool FileCache::loadByPath(const std::string &path, std::ostream &os)
|
||||
{
|
||||
std::ifstream fis(path.c_str(), std::ios_base::binary);
|
||||
|
||||
if(!fis.good()){
|
||||
verbosestream<<"FileCache: File not found in cache: "
|
||||
<<path<<std::endl;
|
||||
auto fis = open_ifstream(path.c_str(), false);
|
||||
if (!fis.good())
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bad = false;
|
||||
for(;;){
|
||||
|
@ -70,15 +66,10 @@ bool FileCache::loadByPath(const std::string &path, std::ostream &os)
|
|||
bool FileCache::updateByPath(const std::string &path, std::string_view data)
|
||||
{
|
||||
createDir();
|
||||
std::ofstream file(path.c_str(), std::ios_base::binary |
|
||||
std::ios_base::trunc);
|
||||
|
||||
if(!file.good())
|
||||
{
|
||||
errorstream<<"FileCache: Can't write to file at "
|
||||
<<path<<std::endl;
|
||||
auto file = open_ofstream(path.c_str(), true);
|
||||
if (!file.good())
|
||||
return false;
|
||||
}
|
||||
|
||||
file << data;
|
||||
file.close();
|
||||
|
@ -101,8 +92,7 @@ bool FileCache::load(const std::string &name, std::ostream &os)
|
|||
bool FileCache::exists(const std::string &name)
|
||||
{
|
||||
std::string path = m_dir + DIR_DELIM + name;
|
||||
std::ifstream fis(path.c_str(), std::ios_base::binary);
|
||||
return fis.good();
|
||||
return fs::PathExists(path);
|
||||
}
|
||||
|
||||
bool FileCache::updateCopyFile(const std::string &name, const std::string &src_path)
|
||||
|
|
|
@ -801,7 +801,15 @@ protected:
|
|||
|
||||
// Misc
|
||||
void showOverlayMessage(const char *msg, float dtime, int percent,
|
||||
bool draw_clouds = true);
|
||||
float *indef_pos = nullptr);
|
||||
|
||||
inline bool fogEnabled()
|
||||
{
|
||||
// Client setting only takes effect if fog distance unlimited or debug priv
|
||||
if (sky->getFogDistance() < 0 || client->checkPrivilege("debug"))
|
||||
return m_cache_enable_fog;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void settingChangedCallback(const std::string &setting_name, void *data);
|
||||
void readSettings();
|
||||
|
@ -969,6 +977,8 @@ private:
|
|||
#ifdef __ANDROID__
|
||||
bool m_android_chat_open;
|
||||
#endif
|
||||
|
||||
float m_shutdown_progress = 0.0f;
|
||||
};
|
||||
|
||||
Game::Game() :
|
||||
|
@ -1165,7 +1175,8 @@ void Game::run()
|
|||
g_settings->getU16("screen_w"),
|
||||
g_settings->getU16("screen_h")
|
||||
);
|
||||
const bool initial_window_maximized = g_settings->getBool("window_maximized");
|
||||
const bool initial_window_maximized = !g_settings->getBool("fullscreen") &&
|
||||
g_settings->getBool("window_maximized");
|
||||
|
||||
while (m_rendering_engine->run()
|
||||
&& !(*kill || g_gamecallback->shutdown_requested
|
||||
|
@ -1248,7 +1259,9 @@ void Game::shutdown()
|
|||
if (g_touchscreengui)
|
||||
g_touchscreengui->hide();
|
||||
|
||||
showOverlayMessage(N_("Shutting down..."), 0, 0, false);
|
||||
// only if the shutdown progress bar isn't shown yet
|
||||
if (m_shutdown_progress == 0.0f)
|
||||
showOverlayMessage(N_("Shutting down..."), 0, 0);
|
||||
|
||||
if (clouds)
|
||||
clouds->drop();
|
||||
|
@ -1300,7 +1313,7 @@ void Game::shutdown()
|
|||
m_rendering_engine->run();
|
||||
f32 dtime;
|
||||
fps_control.limit(device, &dtime);
|
||||
showOverlayMessage(N_("Shutting down..."), dtime, 0, false);
|
||||
showOverlayMessage(N_("Shutting down..."), dtime, 0, &m_shutdown_progress);
|
||||
}
|
||||
|
||||
stop_thread->rethrow();
|
||||
|
@ -1432,7 +1445,7 @@ bool Game::createSingleplayerServer(const std::string &map_dir,
|
|||
if (success)
|
||||
showOverlayMessage(N_("Creating server..."), dtime, 5);
|
||||
else
|
||||
showOverlayMessage(N_("Shutting down..."), dtime, 0, false);
|
||||
showOverlayMessage(N_("Shutting down..."), dtime, 0, &m_shutdown_progress);
|
||||
}
|
||||
|
||||
start_thread->rethrow();
|
||||
|
@ -2426,9 +2439,6 @@ void Game::toggleBlockBounds()
|
|||
case Hud::BLOCK_BOUNDS_NEAR:
|
||||
m_game_ui->showTranslatedStatusText("Block bounds shown for nearby blocks");
|
||||
break;
|
||||
case Hud::BLOCK_BOUNDS_MAX:
|
||||
m_game_ui->showTranslatedStatusText("Block bounds shown for all blocks");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2479,15 +2489,12 @@ void Game::toggleMinimap(bool shift_pressed)
|
|||
|
||||
void Game::toggleFog()
|
||||
{
|
||||
bool flag;
|
||||
// do not modify setting if no privilege
|
||||
if (!client->checkPrivilege("debug")) {
|
||||
flag = true;
|
||||
} else {
|
||||
flag = !g_settings->getBool("enable_fog");
|
||||
g_settings->setBool("enable_fog", flag);
|
||||
}
|
||||
if (flag)
|
||||
bool flag = !g_settings->getBool("enable_fog");
|
||||
g_settings->setBool("enable_fog", flag);
|
||||
bool allowed = sky->getFogDistance() < 0 || client->checkPrivilege("debug");
|
||||
if (!allowed)
|
||||
m_game_ui->showTranslatedStatusText("Fog enabled by game or mod");
|
||||
else if (flag)
|
||||
m_game_ui->showTranslatedStatusText("Fog enabled");
|
||||
else
|
||||
m_game_ui->showTranslatedStatusText("Fog disabled");
|
||||
|
@ -4242,8 +4249,7 @@ void Game::updateClouds(float dtime)
|
|||
camera_node_position.Y = camera_node_position.Y + camera_offset.Y * BS;
|
||||
camera_node_position.Z = camera_node_position.Z + camera_offset.Z * BS;
|
||||
this->clouds->update(camera_node_position, this->sky->getCloudColor());
|
||||
bool enable_fog = this->m_cache_enable_fog || !client->checkPrivilege("debug");
|
||||
if (this->clouds->isCameraInsideCloud() && enable_fog) {
|
||||
if (this->clouds->isCameraInsideCloud() && this->fogEnabled()) {
|
||||
// If camera is inside cloud and fog is enabled, use cloud's colors as sky colors.
|
||||
video::SColor clouds_dark = this->clouds->getColor().getInterpolated(
|
||||
video::SColor(255, 0, 0, 0), 0.9);
|
||||
|
@ -4303,7 +4309,7 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
|
|||
/*
|
||||
Fog
|
||||
*/
|
||||
if (this->m_cache_enable_fog || !client->checkPrivilege("debug")) {
|
||||
if (this->fogEnabled()) {
|
||||
this->driver->setFog(
|
||||
fog_color,
|
||||
video::EFT_FOG_LINEAR,
|
||||
|
@ -4374,10 +4380,10 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
|
|||
Misc
|
||||
****************************************************************************/
|
||||
|
||||
void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_sky)
|
||||
void Game::showOverlayMessage(const char *msg, float dtime, int percent, float *indef_pos)
|
||||
{
|
||||
m_rendering_engine->draw_load_screen(wstrgettext(msg), guienv, texture_src,
|
||||
dtime, percent, draw_sky);
|
||||
dtime, percent, indef_pos);
|
||||
}
|
||||
|
||||
void Game::settingChangedCallback(const std::string &setting_name, void *data)
|
||||
|
|
|
@ -913,7 +913,7 @@ enum Hud::BlockBoundsMode Hud::toggleBlockBounds()
|
|||
{
|
||||
m_block_bounds_mode = static_cast<BlockBoundsMode>(m_block_bounds_mode + 1);
|
||||
|
||||
if (m_block_bounds_mode >= BLOCK_BOUNDS_MAX) {
|
||||
if (m_block_bounds_mode > BLOCK_BOUNDS_NEAR) {
|
||||
m_block_bounds_mode = BLOCK_BOUNDS_OFF;
|
||||
}
|
||||
return m_block_bounds_mode;
|
||||
|
|
|
@ -40,7 +40,6 @@ public:
|
|||
BLOCK_BOUNDS_OFF,
|
||||
BLOCK_BOUNDS_CURRENT,
|
||||
BLOCK_BOUNDS_NEAR,
|
||||
BLOCK_BOUNDS_MAX
|
||||
} m_block_bounds_mode = BLOCK_BOUNDS_OFF;
|
||||
|
||||
video::SColor crosshair_argb;
|
||||
|
|
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "util/numeric.h"
|
||||
#include "inputhandler.h"
|
||||
#include "gui/mainmenumanager.h"
|
||||
|
@ -113,6 +114,19 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
|
|||
return true;
|
||||
}
|
||||
|
||||
// This is separate from other keyboard handling so that it also works in menus.
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT) {
|
||||
const KeyPress keyCode(event.KeyInput);
|
||||
if (keyCode == getKeySetting("keymap_fullscreen")) {
|
||||
if (event.KeyInput.PressedDown && !fullscreen_is_down) {
|
||||
bool fullscreen = RenderingEngine::get_raw_device()->isFullscreen();
|
||||
g_settings->setBool("fullscreen", !fullscreen);
|
||||
}
|
||||
fullscreen_is_down = event.KeyInput.PressedDown;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Let the menu handle events, if one is active.
|
||||
if (isMenuActive()) {
|
||||
if (g_touchscreengui)
|
||||
|
|
|
@ -220,6 +220,9 @@ private:
|
|||
// often changing keys, and keysListenedFor is expected
|
||||
// to change seldomly but contain lots of keys.
|
||||
KeyList keysListenedFor;
|
||||
|
||||
// Intentionally not reset by clearInput/releaseAllKeys.
|
||||
bool fullscreen_is_down = false;
|
||||
};
|
||||
|
||||
class InputHandler
|
||||
|
|
|
@ -437,15 +437,18 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
|||
m_speed.Z = 0.0f;
|
||||
}
|
||||
|
||||
if (y_diff > 0 && m_speed.Y <= 0.0f &&
|
||||
(physics_override.sneak_glitch || y_diff < BS * 0.6f)) {
|
||||
if (y_diff > 0 && m_speed.Y <= 0.0f) {
|
||||
// Move player to the maximal height when falling or when
|
||||
// the ledge is climbed on the next step.
|
||||
|
||||
// Smoothen the movement (based on 'position.Y = bmax.Y')
|
||||
position.Y += y_diff * dtime * 22.0f + BS * 0.01f;
|
||||
position.Y = std::min(position.Y, bmax.Y);
|
||||
m_speed.Y = 0.0f;
|
||||
v3f check_pos = position;
|
||||
check_pos.Y += y_diff * dtime * 22.0f + BS * 0.01f;
|
||||
if (y_diff < BS * 0.6f || (physics_override.sneak_glitch
|
||||
&& !collision_check_intersection(env, m_client, m_collisionbox, check_pos))) {
|
||||
// Smoothen the movement (based on 'position.Y = bmax.Y')
|
||||
position.Y = std::min(check_pos.Y, bmax.Y);
|
||||
m_speed.Y = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow jumping on node edges while sneaking
|
||||
|
|
|
@ -329,32 +329,6 @@ void final_color_blend(video::SColor *result,
|
|||
Mesh generation helpers
|
||||
*/
|
||||
|
||||
// This table is moved outside getNodeVertexDirs to avoid the compiler using
|
||||
// a mutex to initialize this table at runtime right in the hot path.
|
||||
// For details search the internet for "cxa_guard_acquire".
|
||||
static const v3s16 vertex_dirs_table[] = {
|
||||
// ( 1, 0, 0)
|
||||
v3s16( 1,-1, 1), v3s16( 1,-1,-1),
|
||||
v3s16( 1, 1,-1), v3s16( 1, 1, 1),
|
||||
// ( 0, 1, 0)
|
||||
v3s16( 1, 1,-1), v3s16(-1, 1,-1),
|
||||
v3s16(-1, 1, 1), v3s16( 1, 1, 1),
|
||||
// ( 0, 0, 1)
|
||||
v3s16(-1,-1, 1), v3s16( 1,-1, 1),
|
||||
v3s16( 1, 1, 1), v3s16(-1, 1, 1),
|
||||
// invalid
|
||||
v3s16(), v3s16(), v3s16(), v3s16(),
|
||||
// ( 0, 0,-1)
|
||||
v3s16( 1,-1,-1), v3s16(-1,-1,-1),
|
||||
v3s16(-1, 1,-1), v3s16( 1, 1,-1),
|
||||
// ( 0,-1, 0)
|
||||
v3s16( 1,-1, 1), v3s16(-1,-1, 1),
|
||||
v3s16(-1,-1,-1), v3s16( 1,-1,-1),
|
||||
// (-1, 0, 0)
|
||||
v3s16(-1,-1,-1), v3s16(-1,-1, 1),
|
||||
v3s16(-1, 1, 1), v3s16(-1, 1,-1)
|
||||
};
|
||||
|
||||
/*
|
||||
Gets nth node tile (0 <= n <= 5).
|
||||
*/
|
||||
|
@ -826,11 +800,16 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
|||
|
||||
MapBlockMesh::~MapBlockMesh()
|
||||
{
|
||||
size_t sz = 0;
|
||||
for (scene::IMesh *m : m_mesh) {
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); i++)
|
||||
sz += m->getMeshBuffer(i)->getSize();
|
||||
m->drop();
|
||||
}
|
||||
for (MinimapMapblock *block : m_minimap_mapblocks)
|
||||
delete block;
|
||||
|
||||
porting::TrackFreedMemory(sz);
|
||||
}
|
||||
|
||||
bool MapBlockMesh::animate(bool faraway, float time, int crack,
|
||||
|
@ -1006,7 +985,6 @@ video::SColor encode_light(u16 light, u8 emissive_light)
|
|||
u8 get_solid_sides(MeshMakeData *data)
|
||||
{
|
||||
std::unordered_map<v3s16, u8> results;
|
||||
v3s16 ofs;
|
||||
v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
|
||||
const NodeDefManager *ndef = data->nodedef;
|
||||
|
||||
|
|
|
@ -1008,7 +1008,6 @@ video::SMaterial ParticleManager::getMaterialForParticle(const ClientParticleTex
|
|||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
material.BlendOperation = blendop;
|
||||
assert(texture.ref);
|
||||
material.setTexture(0, texture.ref);
|
||||
|
||||
return material;
|
||||
|
|
|
@ -207,7 +207,12 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
|
|||
#else
|
||||
u16 screen_w = std::max<u16>(g_settings->getU16("screen_w"), 1);
|
||||
u16 screen_h = std::max<u16>(g_settings->getU16("screen_h"), 1);
|
||||
bool window_maximized = g_settings->getBool("window_maximized");
|
||||
// If I…
|
||||
// 1. … set fullscreen = true and window_maximized = true on startup
|
||||
// 2. … set fullscreen = false later
|
||||
// on Linux with SDL, everything breaks.
|
||||
// => Don't do it.
|
||||
bool window_maximized = !fullscreen && g_settings->getBool("window_maximized");
|
||||
#endif
|
||||
|
||||
// bpp, fsaa, vsync
|
||||
|
@ -249,18 +254,40 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
|
|||
gui::EGST_WINDOWS_METALLIC, driver);
|
||||
m_device->getGUIEnvironment()->setSkin(skin);
|
||||
skin->drop();
|
||||
|
||||
g_settings->registerChangedCallback("fullscreen", settingChangedCallback, this);
|
||||
g_settings->registerChangedCallback("window_maximized", settingChangedCallback, this);
|
||||
}
|
||||
|
||||
RenderingEngine::~RenderingEngine()
|
||||
{
|
||||
sanity_check(s_singleton == this);
|
||||
|
||||
g_settings->deregisterChangedCallback("fullscreen", settingChangedCallback, this);
|
||||
g_settings->deregisterChangedCallback("window_maximized", settingChangedCallback, this);
|
||||
|
||||
core.reset();
|
||||
m_device->closeDevice();
|
||||
m_device->drop();
|
||||
s_singleton = nullptr;
|
||||
}
|
||||
|
||||
void RenderingEngine::settingChangedCallback(const std::string &name, void *data)
|
||||
{
|
||||
IrrlichtDevice *device = static_cast<RenderingEngine*>(data)->m_device;
|
||||
if (name == "fullscreen") {
|
||||
device->setFullscreen(g_settings->getBool("fullscreen"));
|
||||
|
||||
} else if (name == "window_maximized") {
|
||||
if (!device->isFullscreen()) {
|
||||
if (g_settings->getBool("window_maximized"))
|
||||
device->maximizeWindow();
|
||||
else
|
||||
device->restoreWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v2u32 RenderingEngine::_getWindowSize() const
|
||||
{
|
||||
if (core)
|
||||
|
@ -308,7 +335,7 @@ bool RenderingEngine::setWindowIcon()
|
|||
*/
|
||||
void RenderingEngine::draw_load_screen(const std::wstring &text,
|
||||
gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime,
|
||||
int percent, bool sky)
|
||||
int percent, float *indef_pos)
|
||||
{
|
||||
v2u32 screensize = getWindowSize();
|
||||
|
||||
|
@ -322,18 +349,22 @@ void RenderingEngine::draw_load_screen(const std::wstring &text,
|
|||
|
||||
auto *driver = get_video_driver();
|
||||
|
||||
if (sky) {
|
||||
driver->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
|
||||
if (g_settings->getBool("menu_clouds")) {
|
||||
g_menuclouds->step(dtime * 3);
|
||||
g_menucloudsmgr->drawAll();
|
||||
}
|
||||
} else {
|
||||
driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
|
||||
driver->setFog(RenderingEngine::MENU_SKY_COLOR);
|
||||
driver->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
|
||||
if (g_settings->getBool("menu_clouds")) {
|
||||
g_menuclouds->step(dtime * 3);
|
||||
g_menucloudsmgr->drawAll();
|
||||
}
|
||||
|
||||
int percent_min = 0;
|
||||
int percent_max = percent;
|
||||
if (indef_pos) {
|
||||
*indef_pos = fmodf(*indef_pos + (dtime * 50.0f), 140.0f);
|
||||
percent_max = std::min((int) *indef_pos, 100);
|
||||
percent_min = std::max((int) *indef_pos - 40, 0);
|
||||
}
|
||||
// draw progress bar
|
||||
if ((percent >= 0) && (percent <= 100)) {
|
||||
if ((percent_min >= 0) && (percent_max <= 100)) {
|
||||
video::ITexture *progress_img = tsrc->getTexture("progress_bar.png");
|
||||
video::ITexture *progress_img_bg =
|
||||
tsrc->getTexture("progress_bar_bg.png");
|
||||
|
@ -364,11 +395,11 @@ void RenderingEngine::draw_load_screen(const std::wstring &text,
|
|||
0, 0, true);
|
||||
|
||||
draw2DImageFilterScaled(get_video_driver(), progress_img,
|
||||
core::rect<s32>(img_pos.X, img_pos.Y,
|
||||
img_pos.X + (percent * imgW) / 100,
|
||||
core::rect<s32>(img_pos.X + (percent_min * imgW) / 100, img_pos.Y,
|
||||
img_pos.X + (percent_max * imgW) / 100,
|
||||
img_pos.Y + imgH),
|
||||
core::rect<s32>(0, 0,
|
||||
(percent * img_size.Width) / 100,
|
||||
core::rect<s32>(percent_min * img_size.Width / 100, 0,
|
||||
percent_max * img_size.Width / 100,
|
||||
img_size.Height),
|
||||
0, 0, true);
|
||||
}
|
||||
|
|
|
@ -137,9 +137,11 @@ public:
|
|||
return m_device->getGUIEnvironment();
|
||||
}
|
||||
|
||||
// If "indef_pos" is given, the value of "percent" is ignored and an indefinite
|
||||
// progress bar is drawn.
|
||||
void draw_load_screen(const std::wstring &text,
|
||||
gui::IGUIEnvironment *guienv, ITextureSource *tsrc,
|
||||
float dtime = 0, int percent = 0, bool sky = true);
|
||||
float dtime = 0, int percent = 0, float *indef_pos = nullptr);
|
||||
|
||||
void draw_scene(video::SColor skycolor, bool show_hud,
|
||||
bool draw_wield_tool, bool draw_crosshair);
|
||||
|
@ -166,6 +168,7 @@ public:
|
|||
const bool initial_window_maximized);
|
||||
|
||||
private:
|
||||
static void settingChangedCallback(const std::string &name, void *data);
|
||||
v2u32 _getWindowSize() const;
|
||||
|
||||
std::unique_ptr<RenderingCore> core;
|
||||
|
|