mirror of https://github.com/minetest/minetest.git
Merge branch 'master' into doc-refactor-2
This commit is contained in:
commit
3337cc2091
|
@ -1,2 +1,5 @@
|
||||||
|
# Forces all files which git considers text files to use LF line endings
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
*.cpp diff=cpp
|
*.cpp diff=cpp
|
||||||
*.h diff=cpp
|
*.h diff=cpp
|
||||||
|
|
|
@ -8,6 +8,8 @@ on:
|
||||||
- 'lib/**.cpp'
|
- 'lib/**.cpp'
|
||||||
- 'src/**.[ch]'
|
- 'src/**.[ch]'
|
||||||
- 'src/**.cpp'
|
- 'src/**.cpp'
|
||||||
|
- 'irr/**.[ch]'
|
||||||
|
- 'irr/**.cpp'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- 'android/**'
|
- 'android/**'
|
||||||
|
|
|
@ -8,6 +8,8 @@ on:
|
||||||
- 'lib/**.cpp'
|
- 'lib/**.cpp'
|
||||||
- 'src/**.[ch]'
|
- 'src/**.[ch]'
|
||||||
- 'src/**.cpp'
|
- 'src/**.cpp'
|
||||||
|
- 'irr/**.[ch]'
|
||||||
|
- 'irr/**.cpp'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- 'util/ci/**'
|
- 'util/ci/**'
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
---
|
||||||
|
name: docker_image
|
||||||
|
|
||||||
|
# https://docs.github.com/en/actions/publishing-packages/publishing-docker-images
|
||||||
|
# https://docs.docker.com/build/ci/github-actions/multi-platform
|
||||||
|
# https://github.com/opencontainers/image-spec/blob/main/annotations.md
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
# Publish semver tags as releases.
|
||||||
|
tags: [ "*.*.*" ]
|
||||||
|
pull_request:
|
||||||
|
# Build docker image on pull requests. (but do not publish)
|
||||||
|
paths:
|
||||||
|
- 'lib/**.[ch]'
|
||||||
|
- 'lib/**.cpp'
|
||||||
|
- 'src/**.[ch]'
|
||||||
|
- 'src/**.cpp'
|
||||||
|
- '**/CMakeLists.txt'
|
||||||
|
- 'cmake/Modules/**'
|
||||||
|
- 'util/ci/**'
|
||||||
|
- 'misc/irrlichtmt_tag.txt'
|
||||||
|
- 'Dockerfile'
|
||||||
|
- '.dockerignore'
|
||||||
|
- '.github/workflows/docker_image.yml'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
# github.repository as <account>/<repo>
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Docker buildx
|
||||||
|
uses: docker/setup-buildx-action@v3.0.0
|
||||||
|
|
||||||
|
# Login against the Docker registry except on PR
|
||||||
|
# https://github.com/docker/login-action
|
||||||
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3.0.0
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# Extract metadata (tags, labels) for Docker
|
||||||
|
# https://github.com/docker/metadata-action
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5.5.0
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.title=Minetest
|
||||||
|
org.opencontainers.image.vendor=Minetest
|
||||||
|
org.opencontainers.image.licenses=LGPL-2.1-only
|
||||||
|
|
||||||
|
# Build and push Docker image
|
||||||
|
# https://github.com/docker/build-push-action
|
||||||
|
# No arm support for now. Require cross-compilation support in Dockerfile to not use QEMU.
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v5.1.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
load: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Test Docker Image
|
||||||
|
run: |
|
||||||
|
docker run --rm $(cut -d, -f1 <<<"$DOCKER_METADATA_OUTPUT_TAGS") minetestserver --version
|
||||||
|
shell: bash
|
|
@ -8,10 +8,11 @@ on:
|
||||||
- 'lib/**.cpp'
|
- 'lib/**.cpp'
|
||||||
- 'src/**.[ch]'
|
- 'src/**.[ch]'
|
||||||
- 'src/**.cpp'
|
- 'src/**.cpp'
|
||||||
|
- 'irr/**.[ch]'
|
||||||
|
- 'irr/**.cpp'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- 'util/ci/**'
|
- 'util/ci/**'
|
||||||
- 'misc/irrlichtmt_tag.txt'
|
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
- '.dockerignore'
|
- '.dockerignore'
|
||||||
- '.github/workflows/linux.yml'
|
- '.github/workflows/linux.yml'
|
||||||
|
@ -24,7 +25,6 @@ on:
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- 'util/ci/**'
|
- 'util/ci/**'
|
||||||
- 'misc/irrlichtmt_tag.txt'
|
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
- '.dockerignore'
|
- '.dockerignore'
|
||||||
- '.github/workflows/linux.yml'
|
- '.github/workflows/linux.yml'
|
||||||
|
@ -108,7 +108,7 @@ jobs:
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps clang-14 gdb
|
install_linux_deps clang-14 lldb
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
@ -151,13 +151,3 @@ jobs:
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
./bin/minetestserver --run-unittests
|
./bin/minetestserver --run-unittests
|
||||||
|
|
||||||
docker:
|
|
||||||
name: "Docker image"
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Build docker image
|
|
||||||
run: |
|
|
||||||
docker build . -t minetest:latest
|
|
||||||
docker run --rm minetest:latest /usr/local/bin/minetestserver --version
|
|
||||||
|
|
|
@ -14,24 +14,24 @@ on:
|
||||||
- '.github/workflows/**.yml'
|
- '.github/workflows/**.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Note that the integration tests are also run build.yml, but only when C++ code is changed.
|
# Note that the integration tests are also run in build.yml, but only when C++ code is changed.
|
||||||
integration_tests:
|
integration_tests:
|
||||||
name: "Compile and run multiplayer tests"
|
name: "Compile and run multiplayer tests"
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps clang-10 gdb libluajit-5.1-dev
|
install_linux_deps clang gdb libluajit-5.1-dev
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./util/ci/build.sh
|
./util/ci/build.sh
|
||||||
env:
|
env:
|
||||||
CC: clang-10
|
CC: clang
|
||||||
CXX: clang++-10
|
CXX: clang++
|
||||||
CMAKE_FLAGS: "-DENABLE_GETTEXT=0 -DBUILD_SERVER=0"
|
CMAKE_FLAGS: "-DENABLE_GETTEXT=0 -DBUILD_SERVER=0 -DBUILD_UNITTESTS=0"
|
||||||
|
|
||||||
- name: Integration test + devtest
|
- name: Integration test + devtest
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -16,8 +16,8 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
if: github.repository == 'minetest/minetest'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ on:
|
||||||
- 'lib/**.cpp'
|
- 'lib/**.cpp'
|
||||||
- 'src/**.[ch]'
|
- 'src/**.[ch]'
|
||||||
- 'src/**.cpp'
|
- 'src/**.cpp'
|
||||||
|
- 'irr/**.[ch]'
|
||||||
|
- 'irr/**.cpp'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- '.github/workflows/macos.yml'
|
- '.github/workflows/macos.yml'
|
||||||
|
@ -33,7 +35,6 @@ jobs:
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
git clone https://github.com/minetest/irrlicht lib/irrlichtmt --depth 1 -b $(cat misc/irrlichtmt_tag.txt)
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. \
|
cmake .. \
|
||||||
|
|
|
@ -8,10 +8,11 @@ on:
|
||||||
- 'lib/**.cpp'
|
- 'lib/**.cpp'
|
||||||
- 'src/**.[ch]'
|
- 'src/**.[ch]'
|
||||||
- 'src/**.cpp'
|
- 'src/**.cpp'
|
||||||
|
- 'irr/**.[ch]'
|
||||||
|
- 'irr/**.cpp'
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- 'util/buildbot/**'
|
- 'util/buildbot/**'
|
||||||
- 'misc/irrlichtmt_tag.txt'
|
|
||||||
- 'misc/*.manifest'
|
- 'misc/*.manifest'
|
||||||
- '.github/workflows/windows.yml'
|
- '.github/workflows/windows.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -23,7 +24,6 @@ on:
|
||||||
- '**/CMakeLists.txt'
|
- '**/CMakeLists.txt'
|
||||||
- 'cmake/Modules/**'
|
- 'cmake/Modules/**'
|
||||||
- 'util/buildbot/**'
|
- 'util/buildbot/**'
|
||||||
- 'misc/irrlichtmt_tag.txt'
|
|
||||||
- 'misc/*.manifest'
|
- 'misc/*.manifest'
|
||||||
- '.github/workflows/windows.yml'
|
- '.github/workflows/windows.yml'
|
||||||
|
|
||||||
|
@ -97,11 +97,6 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Checkout IrrlichtMt
|
|
||||||
run: |
|
|
||||||
$ref = @(Get-Content misc\irrlichtmt_tag.txt)
|
|
||||||
git clone https://github.com/minetest/irrlicht lib\irrlichtmt --depth 1 -b $ref[0]
|
|
||||||
|
|
||||||
- name: Restore from cache and run vcpkg
|
- name: Restore from cache and run vcpkg
|
||||||
uses: lukka/run-vcpkg@v7
|
uses: lukka/run-vcpkg@v7
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -64,6 +64,7 @@ AppDir
|
||||||
/clientmods/*
|
/clientmods/*
|
||||||
!/clientmods/preview/
|
!/clientmods/preview/
|
||||||
/client/mod_storage/
|
/client/mod_storage/
|
||||||
|
/mod_data
|
||||||
|
|
||||||
## Configuration/log files
|
## Configuration/log files
|
||||||
minetest.conf
|
minetest.conf
|
||||||
|
@ -118,7 +119,7 @@ compile_commands.json
|
||||||
*.sln
|
*.sln
|
||||||
.vs/
|
.vs/
|
||||||
|
|
||||||
# Optional user provided library folder
|
# Old irrlichtmt. Still ignored to make bisecting easier.
|
||||||
lib/irrlichtmt
|
lib/irrlichtmt
|
||||||
|
|
||||||
# Generated mod storage database
|
# Generated mod storage database
|
||||||
|
|
|
@ -91,27 +91,12 @@ if(ANDROID)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
set(IRRLICHTMT_BUILD_DIR "" CACHE PATH "Path to IrrlichtMt build directory.")
|
if(TRUE)
|
||||||
if(ANDROID)
|
message(STATUS "Using imported IrrlichtMt at subdirectory 'irr'")
|
||||||
# currently manually provided
|
|
||||||
elseif(NOT "${IRRLICHTMT_BUILD_DIR}" STREQUAL "")
|
|
||||||
find_package(IrrlichtMt QUIET
|
|
||||||
PATHS "${IRRLICHTMT_BUILD_DIR}"
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT TARGET IrrlichtMt::IrrlichtMt)
|
|
||||||
# find_package() searches certain subdirectories. ${PATH}/cmake is not
|
|
||||||
# the only one, but it is the one where IrrlichtMt is supposed to export
|
|
||||||
# IrrlichtMtConfig.cmake
|
|
||||||
message(FATAL_ERROR "Could not find IrrlichtMtConfig.cmake in ${IRRLICHTMT_BUILD_DIR}/cmake.")
|
|
||||||
endif()
|
|
||||||
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt")
|
|
||||||
message(STATUS "Using user-provided IrrlichtMt at subdirectory 'lib/irrlichtmt'")
|
|
||||||
if(BUILD_CLIENT)
|
if(BUILD_CLIENT)
|
||||||
# tell IrrlichtMt to create a static library
|
# tell IrrlichtMt to create a static library
|
||||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library" FORCE)
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library" FORCE)
|
||||||
add_subdirectory(lib/irrlichtmt EXCLUDE_FROM_ALL)
|
add_subdirectory(irr EXCLUDE_FROM_ALL)
|
||||||
unset(BUILD_SHARED_LIBS CACHE)
|
unset(BUILD_SHARED_LIBS CACHE)
|
||||||
|
|
||||||
if(NOT TARGET IrrlichtMt)
|
if(NOT TARGET IrrlichtMt)
|
||||||
|
@ -120,44 +105,7 @@ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt")
|
||||||
else()
|
else()
|
||||||
add_library(IrrlichtMt::IrrlichtMt INTERFACE IMPORTED)
|
add_library(IrrlichtMt::IrrlichtMt INTERFACE IMPORTED)
|
||||||
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt/include")
|
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/irr/include")
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
find_package(IrrlichtMt QUIET)
|
|
||||||
if(NOT TARGET IrrlichtMt::IrrlichtMt)
|
|
||||||
string(CONCAT explanation_msg
|
|
||||||
"You must install IrrlichMt as described in docs/compiling/\n")
|
|
||||||
if(BUILD_CLIENT)
|
|
||||||
message(FATAL_ERROR "IrrlichtMt is required to build the client, but it was not found.\n${explanation_msg}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(MinetestFindIrrlichtHeaders)
|
|
||||||
if(NOT IRRLICHT_INCLUDE_DIR)
|
|
||||||
message(FATAL_ERROR "IrrlichtMt headers are required to build the server, but none found.\n${explanation_msg}")
|
|
||||||
endif()
|
|
||||||
message(STATUS "Found IrrlichtMt headers: ${IRRLICHT_INCLUDE_DIR}")
|
|
||||||
add_library(IrrlichtMt::IrrlichtMt INTERFACE IMPORTED)
|
|
||||||
# Note that we can't use target_include_directories() since that doesn't work for IMPORTED targets before CMake 3.11
|
|
||||||
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${IRRLICHT_INCLUDE_DIR}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ANDROID)
|
|
||||||
# skipped for now
|
|
||||||
elseif(BUILD_CLIENT AND TARGET IrrlichtMt::IrrlichtMt)
|
|
||||||
# retrieve version somehow
|
|
||||||
if(NOT IrrlichtMt_VERSION)
|
|
||||||
get_target_property(IrrlichtMt_VERSION IrrlichtMt VERSION)
|
|
||||||
endif()
|
|
||||||
message(STATUS "Found IrrlichtMt ${IrrlichtMt_VERSION}")
|
|
||||||
|
|
||||||
set(TARGET_VER_S 1.9.0mt15)
|
|
||||||
string(REPLACE "mt" "." TARGET_VER ${TARGET_VER_S})
|
|
||||||
if(IrrlichtMt_VERSION VERSION_LESS ${TARGET_VER})
|
|
||||||
message(FATAL_ERROR "At least IrrlichtMt ${TARGET_VER_S} is required to build")
|
|
||||||
elseif(NOT DEVELOPMENT_BUILD AND IrrlichtMt_VERSION VERSION_GREATER ${TARGET_VER})
|
|
||||||
message(FATAL_ERROR "IrrlichtMt ${TARGET_VER_S} is required to build")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
ARG DOCKER_IMAGE=alpine:3.19
|
ARG DOCKER_IMAGE=alpine:3.19
|
||||||
FROM $DOCKER_IMAGE AS dev
|
FROM $DOCKER_IMAGE AS dev
|
||||||
|
|
||||||
ENV IRRLICHT_VERSION master
|
|
||||||
ENV SPATIALINDEX_VERSION master
|
ENV SPATIALINDEX_VERSION master
|
||||||
ENV LUAJIT_VERSION v2.1
|
ENV LUAJIT_VERSION v2.1
|
||||||
|
|
||||||
|
@ -30,9 +29,7 @@ RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp && \
|
||||||
git clone --recursive https://luajit.org/git/luajit.git -b ${LUAJIT_VERSION} && \
|
git clone --recursive https://luajit.org/git/luajit.git -b ${LUAJIT_VERSION} && \
|
||||||
cd luajit && \
|
cd luajit && \
|
||||||
make amalg && make install && \
|
make amalg && make install && \
|
||||||
cd /usr/src/ && \
|
cd /usr/src/
|
||||||
git clone --depth=1 https://github.com/minetest/irrlicht -b ${IRRLICHT_VERSION} && \
|
|
||||||
cp -r irrlicht/include /usr/include/irrlichtmt
|
|
||||||
|
|
||||||
FROM dev as builder
|
FROM dev as builder
|
||||||
|
|
||||||
|
@ -48,6 +45,7 @@ COPY lib /usr/src/minetest/lib
|
||||||
COPY misc /usr/src/minetest/misc
|
COPY misc /usr/src/minetest/misc
|
||||||
COPY po /usr/src/minetest/po
|
COPY po /usr/src/minetest/po
|
||||||
COPY src /usr/src/minetest/src
|
COPY src /usr/src/minetest/src
|
||||||
|
COPY irr /usr/src/minetest/irr
|
||||||
COPY textures /usr/src/minetest/textures
|
COPY textures /usr/src/minetest/textures
|
||||||
|
|
||||||
WORKDIR /usr/src/minetest
|
WORKDIR /usr/src/minetest
|
||||||
|
|
|
@ -108,9 +108,9 @@ Use `--help`
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
* [Developing minetestserver with Docker](doc/developing/docker.md)
|
- [Developing minetestserver with Docker](doc/developing/docker.md)
|
||||||
|
|
||||||
We provide a Dockerfile that can be used to build the server.
|
- [Running a server with Docker](doc/docker_server.md)
|
||||||
|
|
||||||
## Version Scheme
|
## Version Scheme
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ task prepareAssets() {
|
||||||
from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders"
|
from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders"
|
||||||
}
|
}
|
||||||
copy {
|
copy {
|
||||||
from "../native/deps/armeabi-v7a/Irrlicht/Shaders" into "${assetsFolder}/client/shaders/Irrlicht"
|
from "${projRoot}/irr/media/Shaders" into "${assetsFolder}/client/shaders/Irrlicht"
|
||||||
}
|
}
|
||||||
copy {
|
copy {
|
||||||
from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
|
from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
|
||||||
|
@ -108,6 +108,10 @@ task prepareAssets() {
|
||||||
preBuild.dependsOn zipAssets
|
preBuild.dependsOn zipAssets
|
||||||
prepareAssets.dependsOn ':native:getDeps'
|
prepareAssets.dependsOn ':native:getDeps'
|
||||||
|
|
||||||
|
clean {
|
||||||
|
delete new File("src/main/assets", "Minetest.zip")
|
||||||
|
}
|
||||||
|
|
||||||
// Map for the version code that gives each ABI a value.
|
// Map for the version code that gives each ABI a value.
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ project.ext.set("versionCode", 46) // Android Version Code
|
||||||
// each APK must have a larger `versionCode` than the previous
|
// each APK must have a larger `versionCode` than the previous
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.ndk_version = '25.2.9519653'
|
ext.ndk_version = '26.2.11394342'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,7 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -17,78 +17,111 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
# This is normally unused
|
||||||
APP_BASE_NAME=`basename "$0"`
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
@ -97,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
command -v java >/dev/null || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
# shellcheck disable=SC2039,SC3045
|
||||||
fi
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
ulimit -n $MAX_FD
|
warn "Could not query maximum file descriptor limit"
|
||||||
if [ $? -ne 0 ] ; then
|
esac
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
case $MAX_FD in #(
|
||||||
fi
|
'' | soft) :;; #(
|
||||||
else
|
*)
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
fi
|
# shellcheck disable=SC2039,SC3045
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=$((i+1))
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
(0) set -- ;;
|
|
||||||
(1) set -- "$args0" ;;
|
|
||||||
(2) set -- "$args0" "$args1" ;;
|
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=$(save "$@")
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
@rem
|
|
||||||
@rem Copyright 2015 the original author or authors.
|
|
||||||
@rem
|
|
||||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
@rem you may not use this file except in compliance with the License.
|
|
||||||
@rem You may obtain a copy of the License at
|
|
||||||
@rem
|
|
||||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
@rem
|
|
||||||
@rem Unless required by applicable law or agreed to in writing, software
|
|
||||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
@rem See the License for the specific language governing permissions and
|
|
||||||
@rem limitations under the License.
|
|
||||||
@rem
|
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
|
||||||
@rem ##########################################################################
|
|
||||||
@rem
|
|
||||||
@rem Gradle startup script for Windows
|
|
||||||
@rem
|
|
||||||
@rem ##########################################################################
|
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
|
||||||
set APP_BASE_NAME=%~n0
|
|
||||||
set APP_HOME=%DIRNAME%
|
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
|
||||||
|
|
||||||
@rem Find java.exe
|
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
|
||||||
|
|
||||||
:win9xME_args
|
|
||||||
@rem Slurp the command line arguments.
|
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
|
||||||
|
|
||||||
:win9xME_args_slurp
|
|
||||||
if "x%~1" == "x" goto execute
|
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
:execute
|
|
||||||
@rem Setup the command line
|
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
|
||||||
|
|
||||||
:end
|
|
||||||
@rem End local scope for the variables with windows NT shell
|
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
|
@ -43,19 +43,25 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get precompiled deps
|
// get precompiled deps
|
||||||
task downloadDeps(type: Download) {
|
def depsDir = new File(buildDir.parent, 'deps')
|
||||||
def depsDir = new File(buildDir.parent, 'deps')
|
if (new File(depsDir, 'armeabi-v7a').exists()) {
|
||||||
def depsZip = new File(buildDir, 'deps.zip')
|
task getDeps {
|
||||||
|
doLast { logger.lifecycle('Using existing deps from {}', depsDir) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
task downloadDeps(type: Download) {
|
||||||
|
def depsZip = new File(buildDir, 'deps.zip')
|
||||||
|
|
||||||
src 'https://github.com/minetest/minetest_android_deps/releases/download/latest/deps.zip'
|
src 'https://github.com/minetest/minetest_android_deps/releases/download/latest/deps-lite.zip'
|
||||||
dest depsZip
|
dest depsZip
|
||||||
overwrite false
|
overwrite false
|
||||||
|
|
||||||
task getDeps(dependsOn: downloadDeps, type: Copy) {
|
task getDeps(dependsOn: downloadDeps, type: Copy) {
|
||||||
depsDir.mkdir()
|
depsDir.mkdir()
|
||||||
from zipTree(depsZip)
|
from zipTree(depsZip)
|
||||||
into depsDir
|
into depsDir
|
||||||
doFirst { logger.lifecycle('Extracting to {}', depsDir) }
|
doFirst { logger.lifecycle('Extracting to {}', depsDir) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
-- Registered metatables, used by the C++ packer
|
||||||
|
local known_metatables = {}
|
||||||
|
function core.register_async_metatable(name, mt)
|
||||||
|
assert(type(name) == "string", ("attempt to use %s value as metatable name"):format(type(name)))
|
||||||
|
assert(type(mt) == "table", ("attempt to register a %s value as metatable"):format(type(mt)))
|
||||||
|
assert(known_metatables[name] == nil or known_metatables[name] == mt,
|
||||||
|
("attempt to override metatable %s"):format(name))
|
||||||
|
known_metatables[name] = mt
|
||||||
|
known_metatables[mt] = name
|
||||||
|
end
|
||||||
|
core.known_metatables = known_metatables
|
||||||
|
|
||||||
|
core.register_async_metatable("__builtin:vector", vector.metatable)
|
|
@ -31,11 +31,6 @@ function core.get_node(pos)
|
||||||
return core.vmanip:get_node_at(pos)
|
return core.vmanip:get_node_at(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
function core.get_node_or_nil(pos)
|
|
||||||
local node = core.vmanip:get_node_at(pos)
|
|
||||||
return node.name ~= "ignore" and node
|
|
||||||
end
|
|
||||||
|
|
||||||
function core.get_perlin(seed, octaves, persist, spread)
|
function core.get_perlin(seed, octaves, persist, spread)
|
||||||
local params
|
local params
|
||||||
if type(seed) == "table" then
|
if type(seed) == "table" then
|
||||||
|
|
|
@ -37,6 +37,8 @@ core.features = {
|
||||||
blocking_pointability_type = true,
|
blocking_pointability_type = true,
|
||||||
dynamic_add_media_startup = true,
|
dynamic_add_media_startup = true,
|
||||||
dynamic_add_media_filepath = true,
|
dynamic_add_media_filepath = true,
|
||||||
|
lsystem_decoration_type = true,
|
||||||
|
item_meta_range = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
|
|
@ -18,6 +18,7 @@ if core.settings:get_bool("profiler.load") then
|
||||||
end
|
end
|
||||||
|
|
||||||
dofile(commonpath .. "after.lua")
|
dofile(commonpath .. "after.lua")
|
||||||
|
dofile(commonpath .. "metatable.lua")
|
||||||
dofile(commonpath .. "mod_storage.lua")
|
dofile(commonpath .. "mod_storage.lua")
|
||||||
dofile(gamepath .. "item_entity.lua")
|
dofile(gamepath .. "item_entity.lua")
|
||||||
dofile(gamepath .. "deprecated.lua")
|
dofile(gamepath .. "deprecated.lua")
|
||||||
|
|
|
@ -736,3 +736,22 @@ core.noneitemdef_default = { -- This is used for the hand and unknown items
|
||||||
on_drop = nil,
|
on_drop = nil,
|
||||||
on_use = nil,
|
on_use = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
-- get_node implementation
|
||||||
|
--
|
||||||
|
|
||||||
|
local get_node_raw = core.get_node_raw
|
||||||
|
core.get_node_raw = nil
|
||||||
|
|
||||||
|
function core.get_node(pos)
|
||||||
|
local content, param1, param2 = get_node_raw(pos.x, pos.y, pos.z)
|
||||||
|
return {name = core.get_name_from_content_id(content), param1 = param1, param2 = param2}
|
||||||
|
end
|
||||||
|
|
||||||
|
function core.get_node_or_nil(pos)
|
||||||
|
local content, param1, param2, pos_ok = get_node_raw(pos.x, pos.y, pos.z)
|
||||||
|
return pos_ok and
|
||||||
|
{name = core.get_name_from_content_id(content), param1 = param1, param2 = param2}
|
||||||
|
or nil
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
-- Table to keep track of callback executions
|
||||||
|
-- [i + 0] = count of expected patterns of index (i + 1)
|
||||||
|
-- [i + 1] = pattern to check
|
||||||
|
local PATTERN_NORMAL = { 4, "allow_%w", 2, "on_take", 1, "on_put", 1 }
|
||||||
|
local PATTERN_SWAP = { 8, "allow_%w", 4, "on_take", 2, "on_put", 2 }
|
||||||
|
local exec_listing = {} -- List of logged callbacks (e.g. "on_take", "allow_put")
|
||||||
|
|
||||||
|
-- Checks whether the logged callbacks equal the expected pattern
|
||||||
|
core.__helper_check_callbacks = function(expect_swap)
|
||||||
|
local exec_pattern = expect_swap and PATTERN_SWAP or PATTERN_NORMAL
|
||||||
|
local ok = #exec_listing == exec_pattern[1]
|
||||||
|
if ok then
|
||||||
|
local list_index = 1
|
||||||
|
for i = 2, #exec_pattern, 2 do
|
||||||
|
for n = 1, exec_pattern[i + 1] do
|
||||||
|
-- Match the list for "n" occurrences of the wanted callback name pattern
|
||||||
|
ok = exec_listing[list_index]:find(exec_pattern[i])
|
||||||
|
list_index = list_index + 1
|
||||||
|
if not ok then break end
|
||||||
|
end
|
||||||
|
if not ok then break end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
print("Execution order mismatch!")
|
||||||
|
print("Expected patterns: ", dump(exec_pattern))
|
||||||
|
print("Got list: ", dump(exec_listing))
|
||||||
|
end
|
||||||
|
exec_listing = {}
|
||||||
|
return ok
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Uncomment the other line for easier callback debugging
|
||||||
|
local log = function(...) end
|
||||||
|
--local log = print
|
||||||
|
|
||||||
|
minetest.register_allow_player_inventory_action(function(_, action, inv, info)
|
||||||
|
log("\tallow " .. action, info.count or info.stack:to_string())
|
||||||
|
|
||||||
|
if action == "move" then
|
||||||
|
-- testMoveFillStack
|
||||||
|
return info.count
|
||||||
|
end
|
||||||
|
|
||||||
|
if action == "take" or action == "put" then
|
||||||
|
assert(not info.stack:is_empty(), "Stack empty in: " .. action)
|
||||||
|
|
||||||
|
-- testMoveUnallowed
|
||||||
|
-- testSwapFromUnallowed
|
||||||
|
-- testSwapToUnallowed
|
||||||
|
if info.stack:get_name() == "default:takeput_deny" then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- testMovePartial
|
||||||
|
if info.stack:get_name() == "default:takeput_max_5" then
|
||||||
|
return 5
|
||||||
|
end
|
||||||
|
|
||||||
|
-- testCallbacks
|
||||||
|
if info.stack:get_name():find("default:takeput_cb_%d") then
|
||||||
|
-- Log callback as executed
|
||||||
|
table.insert(exec_listing, "allow_" .. action)
|
||||||
|
return -- Unlimited
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return -- Unlimited
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_player_inventory_action(function(_, action, inv, info)
|
||||||
|
log("\ton " .. action, info.count or info.stack:to_string())
|
||||||
|
|
||||||
|
if action == "take" or action == "put" then
|
||||||
|
assert(not info.stack:is_empty(), action)
|
||||||
|
|
||||||
|
if info.stack:get_name():find("default:takeput_cb_%d") then
|
||||||
|
-- Log callback as executed
|
||||||
|
table.insert(exec_listing, "on_" .. action)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
|
@ -63,6 +63,7 @@ elseif INIT == "mainmenu" then
|
||||||
elseif INIT == "async" then
|
elseif INIT == "async" then
|
||||||
dofile(asyncpath .. "mainmenu.lua")
|
dofile(asyncpath .. "mainmenu.lua")
|
||||||
elseif INIT == "async_game" then
|
elseif INIT == "async_game" then
|
||||||
|
dofile(commonpath .. "metatable.lua")
|
||||||
dofile(asyncpath .. "game.lua")
|
dofile(asyncpath .. "game.lua")
|
||||||
elseif INIT == "client" then
|
elseif INIT == "client" then
|
||||||
dofile(scriptdir .. "client" .. DIR_DELIM .. "init.lua")
|
dofile(scriptdir .. "client" .. DIR_DELIM .. "init.lua")
|
||||||
|
|
|
@ -18,6 +18,26 @@
|
||||||
-- Global menu data
|
-- Global menu data
|
||||||
menudata = {}
|
menudata = {}
|
||||||
|
|
||||||
|
-- located in user cache path, for remembering this like e.g. last update check
|
||||||
|
cache_settings = Settings(core.get_cache_path() .. DIR_DELIM .. "common.conf")
|
||||||
|
|
||||||
|
--- Checks if the given key contains a timestamp less than a certain age.
|
||||||
|
--- Pair this with a call to `cache_settings:set(key, tostring(os.time()))`
|
||||||
|
--- after successfully refreshing the cache.
|
||||||
|
--- @param key Name of entry in cache_settings
|
||||||
|
--- @param max_age Age to check against, in seconds
|
||||||
|
--- @return true if the max age is not reached
|
||||||
|
function check_cache_age(key, max_age)
|
||||||
|
local time_now = os.time()
|
||||||
|
local time_checked = tonumber(cache_settings:get(key)) or 0
|
||||||
|
return time_now - time_checked < max_age
|
||||||
|
end
|
||||||
|
|
||||||
|
function core.on_before_close()
|
||||||
|
-- called before the menu is closed, either exit or to join a game
|
||||||
|
cache_settings:write()
|
||||||
|
end
|
||||||
|
|
||||||
-- Local cached values
|
-- Local cached values
|
||||||
local min_supp_proto, max_supp_proto
|
local min_supp_proto, max_supp_proto
|
||||||
|
|
||||||
|
@ -27,6 +47,16 @@ function common_update_cached_supp_proto()
|
||||||
end
|
end
|
||||||
common_update_cached_supp_proto()
|
common_update_cached_supp_proto()
|
||||||
|
|
||||||
|
-- Other global functions
|
||||||
|
|
||||||
|
function core.sound_stop(handle, ...)
|
||||||
|
return handle:stop(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function os.tmpname()
|
||||||
|
error('do not use') -- instead: core.get_temp_path()
|
||||||
|
end
|
||||||
|
|
||||||
-- Menu helper functions
|
-- Menu helper functions
|
||||||
|
|
||||||
local function render_client_count(n)
|
local function render_client_count(n)
|
||||||
|
@ -140,11 +170,6 @@ function render_serverlist_row(spec)
|
||||||
|
|
||||||
return table.concat(details, ",")
|
return table.concat(details, ",")
|
||||||
end
|
end
|
||||||
---------------------------------------------------------------------------------
|
|
||||||
os.tmpname = function()
|
|
||||||
error('do not use') -- instead use core.get_temp_path()
|
|
||||||
end
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function menu_render_worldlist()
|
function menu_render_worldlist()
|
||||||
local retval = {}
|
local retval = {}
|
||||||
|
|
|
@ -26,13 +26,23 @@ if not core.get_http_api then
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
assert(core.create_dir(core.get_cache_path() .. DIR_DELIM .. "cdb"))
|
||||||
|
local cache_file_path = core.get_cache_path() .. DIR_DELIM .. "cdb" .. DIR_DELIM .. "updates.json"
|
||||||
local has_fetched = false
|
local has_fetched = false
|
||||||
local latest_releases
|
local latest_releases
|
||||||
do
|
do
|
||||||
local tmp = core.get_once("cdb_latest_releases")
|
if check_cache_age("cdb_updates_last_checked", 3 * 3600) then
|
||||||
if tmp then
|
local f = io.open(cache_file_path, "r")
|
||||||
latest_releases = core.deserialize(tmp, true)
|
local data = ""
|
||||||
has_fetched = latest_releases ~= nil
|
if f then
|
||||||
|
data = f:read("*a")
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
data = data ~= "" and core.parse_json(data) or nil
|
||||||
|
if type(data) == "table" then
|
||||||
|
latest_releases = data
|
||||||
|
has_fetched = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -97,7 +107,8 @@ local function fetch()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
latest_releases = lowercase_keys(releases)
|
latest_releases = lowercase_keys(releases)
|
||||||
core.set_once("cdb_latest_releases", core.serialize(latest_releases))
|
core.safe_file_write(cache_file_path, core.write_json(latest_releases))
|
||||||
|
cache_settings:set("cdb_updates_last_checked", tostring(os.time()))
|
||||||
|
|
||||||
if update_detector.get_count() > 0 then
|
if update_detector.get_count() > 0 then
|
||||||
local maintab = ui.find_by_name("maintab")
|
local maintab = ui.find_by_name("maintab")
|
||||||
|
|
|
@ -15,15 +15,30 @@
|
||||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
---- IMPORTANT ----
|
||||||
|
-- This whole file can be removed after a while.
|
||||||
|
-- It was only directly useful for upgrades from 5.7.0 to 5.8.0, but
|
||||||
|
-- maybe some odd fellow directly upgrades from 5.6.1 to 5.9.0 in the future...
|
||||||
|
-- see <https://github.com/minetest/minetest/pull/13850> in case it's not obvious
|
||||||
|
---- ----
|
||||||
|
|
||||||
|
local SETTING_NAME = "no_mtg_notification"
|
||||||
|
|
||||||
function check_reinstall_mtg()
|
function check_reinstall_mtg()
|
||||||
if core.settings:get_bool("no_mtg_notification") then
|
-- used to be in minetest.conf
|
||||||
|
if core.settings:get_bool(SETTING_NAME) then
|
||||||
|
cache_settings:set_bool(SETTING_NAME, true)
|
||||||
|
core.settings:remove(SETTING_NAME)
|
||||||
|
end
|
||||||
|
|
||||||
|
if cache_settings:get_bool(SETTING_NAME) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local games = core.get_games()
|
local games = core.get_games()
|
||||||
for _, game in ipairs(games) do
|
for _, game in ipairs(games) do
|
||||||
if game.id == "minetest" then
|
if game.id == "minetest" then
|
||||||
core.settings:set_bool("no_mtg_notification", true)
|
cache_settings:set_bool(SETTING_NAME, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -37,7 +52,7 @@ function check_reinstall_mtg()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not mtg_world_found then
|
if not mtg_world_found then
|
||||||
core.settings:set_bool("no_mtg_notification", true)
|
cache_settings:set_bool(SETTING_NAME, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -87,7 +102,7 @@ local function buttonhandler(this, fields)
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.dismiss then
|
if fields.dismiss then
|
||||||
core.settings:set_bool("no_mtg_notification", true)
|
cache_settings:set_bool("no_mtg_notification", true)
|
||||||
this:delete()
|
this:delete()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,12 +51,13 @@ end
|
||||||
local function version_info_buttonhandler(this, fields)
|
local function version_info_buttonhandler(this, fields)
|
||||||
if fields.version_check_remind then
|
if fields.version_check_remind then
|
||||||
-- Erase last known, user will be reminded again at next check
|
-- Erase last known, user will be reminded again at next check
|
||||||
core.settings:set("update_last_known", "")
|
cache_settings:set("update_last_known", "")
|
||||||
this:delete()
|
this:delete()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
if fields.version_check_never then
|
if fields.version_check_never then
|
||||||
core.settings:set("update_last_checked", "disabled")
|
-- clear checked URL
|
||||||
|
core.settings:set("update_information_url", "")
|
||||||
this:delete()
|
this:delete()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -116,7 +117,7 @@ local function on_version_info_received(json)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local known_update = tonumber(core.settings:get("update_last_known")) or 0
|
local known_update = tonumber(cache_settings:get("update_last_known")) or 0
|
||||||
|
|
||||||
-- Format: MMNNPPP (Major, Minor, Patch)
|
-- Format: MMNNPPP (Major, Minor, Patch)
|
||||||
local new_number = type(json.latest) == "table" and json.latest.version_code
|
local new_number = type(json.latest) == "table" and json.latest.version_code
|
||||||
|
@ -135,7 +136,7 @@ local function on_version_info_received(json)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
core.settings:set("update_last_known", tostring(new_number))
|
cache_settings:set("update_last_known", tostring(new_number))
|
||||||
|
|
||||||
-- Show version info dialog (once)
|
-- Show version info dialog (once)
|
||||||
maintab:hide()
|
maintab:hide()
|
||||||
|
@ -149,20 +150,20 @@ end
|
||||||
|
|
||||||
function check_new_version()
|
function check_new_version()
|
||||||
local url = core.settings:get("update_information_url")
|
local url = core.settings:get("update_information_url")
|
||||||
if core.settings:get("update_last_checked") == "disabled" or
|
if url == "" then
|
||||||
url == "" then
|
|
||||||
-- Never show any updates
|
-- Never show any updates
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local time_now = os.time()
|
-- every 2 days
|
||||||
local time_checked = tonumber(core.settings:get("update_last_checked")) or 0
|
if check_cache_age("update_last_checked", 2 * 24 * 3600) then
|
||||||
if time_now - time_checked < 2 * 24 * 3600 then
|
|
||||||
-- Check interval of 2 entire days
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
cache_settings:set("update_last_checked", tostring(os.time()))
|
||||||
|
|
||||||
core.settings:set("update_last_checked", tostring(time_now))
|
-- Clean old leftovers (this can be removed after 5.9.0 or so)
|
||||||
|
core.settings:remove("update_last_checked")
|
||||||
|
core.settings:remove("update_last_known")
|
||||||
|
|
||||||
core.handle_async(function(params)
|
core.handle_async(function(params)
|
||||||
local http = core.get_http_api()
|
local http = core.get_http_api()
|
||||||
|
|
|
@ -28,8 +28,6 @@ local basepath = core.get_builtin_path()
|
||||||
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
|
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
|
||||||
DIR_DELIM .. "pack" .. DIR_DELIM
|
DIR_DELIM .. "pack" .. DIR_DELIM
|
||||||
|
|
||||||
dofile(menupath .. DIR_DELIM .. "misc.lua")
|
|
||||||
|
|
||||||
dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua")
|
dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua")
|
||||||
dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua")
|
dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.lua")
|
||||||
dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua")
|
dofile(basepath .. "fstk" .. DIR_DELIM .. "dialog.lua")
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
-- old non-method sound function
|
|
||||||
|
|
||||||
function core.sound_stop(handle, ...)
|
|
||||||
return handle:stop(...)
|
|
||||||
end
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
serverlistmgr = {
|
serverlistmgr = {
|
||||||
-- continent code we detected for ourselves
|
-- continent code we detected for ourselves
|
||||||
my_continent = core.get_once("continent"),
|
my_continent = nil,
|
||||||
|
|
||||||
-- list of locally favorites servers
|
-- list of locally favorites servers
|
||||||
favorites = nil,
|
favorites = nil,
|
||||||
|
@ -26,6 +26,15 @@ serverlistmgr = {
|
||||||
servers = nil,
|
servers = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
if check_cache_age("geoip_last_checked", 3600) then
|
||||||
|
local tmp = cache_settings:get("geoip") or ""
|
||||||
|
if tmp:match("^[A-Z][A-Z]$") then
|
||||||
|
serverlistmgr.my_continent = tmp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Efficient data structure for normalizing arbitrary scores attached to objects
|
-- Efficient data structure for normalizing arbitrary scores attached to objects
|
||||||
-- e.g. {{"a", 3.14}, {"b", 3.14}, {"c", 20}, {"d", 0}}
|
-- e.g. {{"a", 3.14}, {"b", 3.14}, {"c", 20}, {"d", 0}}
|
||||||
|
@ -112,6 +121,22 @@ local public_downloading = false
|
||||||
local geoip_downloading = false
|
local geoip_downloading = false
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
local function fetch_geoip()
|
||||||
|
local http = core.get_http_api()
|
||||||
|
local url = core.settings:get("serverlist_url") .. "/geoip"
|
||||||
|
|
||||||
|
local response = http.fetch_sync({ url = url })
|
||||||
|
if not response.succeeded then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local retval = core.parse_json(response.data)
|
||||||
|
if type(retval) ~= "table" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return type(retval.continent) == "string" and retval.continent
|
||||||
|
end
|
||||||
|
|
||||||
function serverlistmgr.sync()
|
function serverlistmgr.sync()
|
||||||
if not serverlistmgr.servers then
|
if not serverlistmgr.servers then
|
||||||
serverlistmgr.servers = {{
|
serverlistmgr.servers = {{
|
||||||
|
@ -129,37 +154,23 @@ function serverlistmgr.sync()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- only fetched once per MT instance
|
|
||||||
if not serverlistmgr.my_continent and not geoip_downloading then
|
if not serverlistmgr.my_continent and not geoip_downloading then
|
||||||
geoip_downloading = true
|
geoip_downloading = true
|
||||||
core.handle_async(
|
core.handle_async(fetch_geoip, nil, function(result)
|
||||||
function(param)
|
geoip_downloading = false
|
||||||
local http = core.get_http_api()
|
if not result then
|
||||||
local url = core.settings:get("serverlist_url") .. "/geoip"
|
return
|
||||||
|
|
||||||
local response = http.fetch_sync({ url = url })
|
|
||||||
if not response.succeeded then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local retval = core.parse_json(response.data)
|
|
||||||
return retval and type(retval.continent) == "string" and retval.continent
|
|
||||||
end,
|
|
||||||
nil,
|
|
||||||
function(result)
|
|
||||||
geoip_downloading = false
|
|
||||||
if not result then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
serverlistmgr.my_continent = result
|
|
||||||
core.set_once("continent", result)
|
|
||||||
-- reorder list if we already have it
|
|
||||||
if serverlistmgr.servers then
|
|
||||||
serverlistmgr.servers = order_server_list(serverlistmgr.servers)
|
|
||||||
core.event_handler("Refresh")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
)
|
serverlistmgr.my_continent = result
|
||||||
|
cache_settings:set("geoip", result)
|
||||||
|
cache_settings:set("geoip_last_checked", tostring(os.time()))
|
||||||
|
|
||||||
|
-- re-sort list if applicable
|
||||||
|
if serverlistmgr.servers then
|
||||||
|
serverlistmgr.servers = order_server_list(serverlistmgr.servers)
|
||||||
|
core.event_handler("Refresh")
|
||||||
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
if public_downloading then
|
if public_downloading then
|
||||||
|
@ -167,6 +178,7 @@ function serverlistmgr.sync()
|
||||||
end
|
end
|
||||||
public_downloading = true
|
public_downloading = true
|
||||||
|
|
||||||
|
-- note: this isn't cached because it's way too dynamic
|
||||||
core.handle_async(
|
core.handle_async(
|
||||||
function(param)
|
function(param)
|
||||||
local http = core.get_http_api()
|
local http = core.get_http_api()
|
||||||
|
|
|
@ -158,7 +158,7 @@ return {
|
||||||
"style[label_button;border=false]" ..
|
"style[label_button;border=false]" ..
|
||||||
"button[0.1,3.4;5.3,0.5;label_button;" ..
|
"button[0.1,3.4;5.3,0.5;label_button;" ..
|
||||||
core.formspec_escape(version.project .. " " .. version.string) .. "]" ..
|
core.formspec_escape(version.project .. " " .. version.string) .. "]" ..
|
||||||
"button[1.5,4.1;2.5,0.8;homepage;minetest.net]" ..
|
"button_url[1.5,4.1;2.5,0.8;homepage;minetest.net;https://www.minetest.net/]" ..
|
||||||
"hypertext[5.5,0.25;9.75,6.6;credits;" .. minetest.formspec_escape(hypertext) .. "]"
|
"hypertext[5.5,0.25;9.75,6.6;credits;" .. minetest.formspec_escape(hypertext) .. "]"
|
||||||
|
|
||||||
-- Render information
|
-- Render information
|
||||||
|
@ -188,10 +188,6 @@ return {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
cbf_button_handler = function(this, fields, name, tabdata)
|
cbf_button_handler = function(this, fields, name, tabdata)
|
||||||
if fields.homepage then
|
|
||||||
core.open_url("https://www.minetest.net")
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.share_debug then
|
if fields.share_debug then
|
||||||
local path = core.get_user_path() .. DIR_DELIM .. "debug.txt"
|
local path = core.get_user_path() .. DIR_DELIM .. "debug.txt"
|
||||||
core.share_file(path)
|
core.share_file(path)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
_G.core = {get_once = function(_) end}
|
_G.core = {}
|
||||||
_G.unpack = table.unpack
|
_G.unpack = table.unpack
|
||||||
|
_G.check_cache_age = function() return false end
|
||||||
_G.serverlistmgr = {}
|
_G.serverlistmgr = {}
|
||||||
|
|
||||||
dofile("builtin/common/vector.lua")
|
dofile("builtin/common/vector.lua")
|
||||||
|
|
|
@ -114,7 +114,11 @@ always_fly_fast (Always fly fast) bool true
|
||||||
# the place button.
|
# the place button.
|
||||||
#
|
#
|
||||||
# Requires: keyboard_mouse
|
# Requires: keyboard_mouse
|
||||||
repeat_place_time (Place repetition interval) float 0.25 0.16 2
|
repeat_place_time (Place repetition interval) float 0.25 0.15 2.0
|
||||||
|
|
||||||
|
# The minimum time in seconds it takes between digging nodes when holding
|
||||||
|
# the dig button.
|
||||||
|
repeat_dig_time (Dig repetition interval) float 0.15 0.15 2.0
|
||||||
|
|
||||||
# Automatically jump up single-node obstacles.
|
# Automatically jump up single-node obstacles.
|
||||||
autojump (Automatic jumping) bool false
|
autojump (Automatic jumping) bool false
|
||||||
|
@ -153,16 +157,21 @@ invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
|
||||||
# Requires: !android
|
# Requires: !android
|
||||||
enable_touch (Enable touchscreen) bool true
|
enable_touch (Enable touchscreen) bool true
|
||||||
|
|
||||||
# The length in pixels it takes for touchscreen interaction to start.
|
|
||||||
#
|
|
||||||
# Requires: touchscreen_gui
|
|
||||||
touchscreen_threshold (Touchscreen threshold) int 20 0 100
|
|
||||||
|
|
||||||
# Touchscreen sensitivity multiplier.
|
# Touchscreen sensitivity multiplier.
|
||||||
#
|
#
|
||||||
# Requires: touchscreen_gui
|
# Requires: touchscreen_gui
|
||||||
touchscreen_sensitivity (Touchscreen sensitivity) float 0.2 0.001 10.0
|
touchscreen_sensitivity (Touchscreen sensitivity) float 0.2 0.001 10.0
|
||||||
|
|
||||||
|
# The length in pixels after which a touch interaction is considered movement.
|
||||||
|
#
|
||||||
|
# Requires: touchscreen_gui
|
||||||
|
touchscreen_threshold (Movement threshold) int 20 0 100
|
||||||
|
|
||||||
|
# The delay in milliseconds after which a touch interaction is considered a long tap.
|
||||||
|
#
|
||||||
|
# Requires: touchscreen_gui
|
||||||
|
touch_long_tap_delay (Threshold for long taps) int 400 100 1000
|
||||||
|
|
||||||
# Use crosshair to select object instead of whole screen.
|
# Use crosshair to select object instead of whole screen.
|
||||||
# If enabled, a crosshair will be shown and will be used for selecting object.
|
# If enabled, a crosshair will be shown and will be used for selecting object.
|
||||||
#
|
#
|
||||||
|
@ -181,6 +190,19 @@ fixed_virtual_joystick (Fixed virtual joystick) bool false
|
||||||
# Requires: touchscreen_gui
|
# Requires: touchscreen_gui
|
||||||
virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false
|
virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false
|
||||||
|
|
||||||
|
# The gesture for for punching players/entities.
|
||||||
|
# This can be overridden by games and mods.
|
||||||
|
#
|
||||||
|
# * short_tap
|
||||||
|
# Easy to use and well-known from other games that shall not be named.
|
||||||
|
#
|
||||||
|
# * long_tap
|
||||||
|
# Known from the classic Minetest mobile controls.
|
||||||
|
# Combat is more or less impossible.
|
||||||
|
#
|
||||||
|
# Requires: touchscreen_gui
|
||||||
|
touch_punch_gesture (Punch gesture) enum short_tap short_tap,long_tap
|
||||||
|
|
||||||
|
|
||||||
[Graphics and Audio]
|
[Graphics and Audio]
|
||||||
|
|
||||||
|
@ -772,6 +794,7 @@ serverlist_url (Serverlist URL) string servers.minetest.net
|
||||||
enable_split_login_register (Enable split login/register) bool true
|
enable_split_login_register (Enable split login/register) bool true
|
||||||
|
|
||||||
# URL to JSON file which provides information about the newest Minetest release
|
# URL to JSON file which provides information about the newest Minetest release
|
||||||
|
# If this is empty the engine will never check for updates.
|
||||||
update_information_url (Update information URL) string https://www.minetest.net/release_info.json
|
update_information_url (Update information URL) string https://www.minetest.net/release_info.json
|
||||||
|
|
||||||
[*Server]
|
[*Server]
|
||||||
|
@ -1816,10 +1839,6 @@ video_driver (Video driver) enum ,opengl,opengl3,ogles1,ogles2
|
||||||
# Use this to limit the performance impact of transparency depth sorting
|
# Use this to limit the performance impact of transparency depth sorting
|
||||||
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
|
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
|
||||||
|
|
||||||
# Enable vertex buffer objects.
|
|
||||||
# This should greatly improve graphics performance.
|
|
||||||
enable_vbo (VBO) bool true
|
|
||||||
|
|
||||||
# Radius of cloud area stated in number of 64 node cloud squares.
|
# Radius of cloud area stated in number of 64 node cloud squares.
|
||||||
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
|
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
|
||||||
cloud_radius (Cloud radius) int 12 1 62
|
cloud_radius (Cloud radius) int 12 1 62
|
||||||
|
@ -2291,20 +2310,6 @@ show_advanced (Show advanced settings) bool false
|
||||||
# Changing this setting requires a restart.
|
# Changing this setting requires a restart.
|
||||||
enable_sound (Sound) bool true
|
enable_sound (Sound) bool true
|
||||||
|
|
||||||
# Unix timestamp (integer) of when the client last checked for an update
|
|
||||||
# Set this value to "disabled" to never check for updates.
|
|
||||||
update_last_checked (Last update check) string
|
|
||||||
|
|
||||||
# Version number which was last seen during an update check.
|
|
||||||
#
|
|
||||||
# Representation: MMMIIIPPP, where M=Major, I=Minor, P=Patch
|
|
||||||
# Ex: 5.5.0 is 005005000
|
|
||||||
update_last_known (Last known version update) int 0
|
|
||||||
|
|
||||||
# If this is set to true, the user will never (again) be shown the
|
|
||||||
# "reinstall Minetest Game" notification.
|
|
||||||
no_mtg_notification (Don't show "reinstall Minetest Game" notification) bool false
|
|
||||||
|
|
||||||
# Key for moving the player forward.
|
# Key for moving the player forward.
|
||||||
keymap_forward (Forward key) key KEY_KEY_W
|
keymap_forward (Forward key) key KEY_KEY_W
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../irr/media/Shaders
|
|
@ -0,0 +1,17 @@
|
||||||
|
uniform vec4 fogColor;
|
||||||
|
uniform float fogDistance;
|
||||||
|
uniform float fogShadingParameter;
|
||||||
|
varying vec3 eyeVec;
|
||||||
|
|
||||||
|
varying lowp vec4 varColor;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 col = varColor;
|
||||||
|
|
||||||
|
float clarity = clamp(fogShadingParameter
|
||||||
|
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||||
|
col.rgb = mix(fogColor.rgb, col.rgb, clarity);
|
||||||
|
|
||||||
|
gl_FragColor = col;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
uniform vec4 emissiveColor;
|
||||||
|
|
||||||
|
varying lowp vec4 varColor;
|
||||||
|
|
||||||
|
varying vec3 eyeVec;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = mWorldViewProj * inVertexPosition;
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
vec4 color = inVertexColor.bgra;
|
||||||
|
#else
|
||||||
|
vec4 color = inVertexColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color *= emissiveColor;
|
||||||
|
varColor = color;
|
||||||
|
|
||||||
|
eyeVec = -(mWorldView * inVertexPosition).xyz;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
uniform vec4 starColor;
|
uniform vec4 emissiveColor;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
gl_FragColor = starColor;
|
gl_FragColor = emissiveColor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,27 @@
|
||||||
set(DEPS "${CMAKE_SOURCE_DIR}/android/native/deps/${ANDROID_ABI}")
|
set(DEPS "${CMAKE_SOURCE_DIR}/android/native/deps/${ANDROID_ABI}")
|
||||||
|
|
||||||
add_library(IrrlichtMt::IrrlichtMt STATIC IMPORTED)
|
|
||||||
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES ${DEPS}/Irrlicht/include)
|
|
||||||
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
|
||||||
IMPORTED_LOCATION ${DEPS}/Irrlicht/libIrrlichtMt.a)
|
|
||||||
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
|
||||||
INTERFACE_LINK_LIBRARIES "EGL;GLESv1_CM;GLESv2;${DEPS}/Irrlicht/libpng.a;${DEPS}/Irrlicht/libjpeg.a")
|
|
||||||
|
|
||||||
set(CURL_INCLUDE_DIR ${DEPS}/Curl/include)
|
set(CURL_INCLUDE_DIR ${DEPS}/Curl/include)
|
||||||
set(CURL_LIBRARY ${DEPS}/Curl/libcurl.a;${DEPS}/Curl/libmbedcrypto.a;${DEPS}/Curl/libmbedtls.a;${DEPS}/Curl/libmbedx509.a)
|
set(CURL_LIBRARY ${DEPS}/Curl/libcurl.a;${DEPS}/Curl/libmbedcrypto.a;${DEPS}/Curl/libmbedtls.a;${DEPS}/Curl/libmbedx509.a)
|
||||||
set(FREETYPE_INCLUDE_DIR_ft2build ${DEPS}/Freetype/include/freetype2)
|
|
||||||
set(FREETYPE_INCLUDE_DIR_freetype2 ${FREETYPE_INCLUDE_DIR_ft2build}/freetype)
|
set(FREETYPE_INCLUDE_DIR_freetype2 ${FREETYPE_INCLUDE_DIR_ft2build}/freetype)
|
||||||
|
set(FREETYPE_INCLUDE_DIR_ft2build ${DEPS}/Freetype/include/freetype2)
|
||||||
set(FREETYPE_LIBRARY ${DEPS}/Freetype/libfreetype.a)
|
set(FREETYPE_LIBRARY ${DEPS}/Freetype/libfreetype.a)
|
||||||
set(GETTEXT_INCLUDE_DIR ${DEPS}/Gettext/include;${DEPS}/Iconv/include)
|
set(GETTEXT_INCLUDE_DIR ${DEPS}/Gettext/include;${DEPS}/Iconv/include)
|
||||||
set(GETTEXT_LIBRARY ${DEPS}/Gettext/libintl.a)
|
set(GETTEXT_LIBRARY ${DEPS}/Gettext/libintl.a)
|
||||||
set(ICONV_LIBRARY ${DEPS}/Iconv/libiconv.a;${DEPS}/Iconv/libcharset.a)
|
set(ICONV_LIBRARY ${DEPS}/Iconv/libiconv.a;${DEPS}/Iconv/libcharset.a)
|
||||||
|
set(JPEG_INCLUDE_DIR ${DEPS}/JPEG/include)
|
||||||
|
set(JPEG_LIBRARY ${DEPS}/JPEG/libjpeg.a)
|
||||||
set(LUA_INCLUDE_DIR ${DEPS}/LuaJIT/include)
|
set(LUA_INCLUDE_DIR ${DEPS}/LuaJIT/include)
|
||||||
set(LUA_LIBRARY ${DEPS}/LuaJIT/libluajit.a)
|
set(LUA_LIBRARY ${DEPS}/LuaJIT/libluajit.a)
|
||||||
set(OGG_INCLUDE_DIR ${DEPS}/Vorbis/include)
|
set(OGG_INCLUDE_DIR ${DEPS}/Vorbis/include)
|
||||||
set(OGG_LIBRARY ${DEPS}/Vorbis/libogg.a)
|
set(OGG_LIBRARY ${DEPS}/Vorbis/libogg.a)
|
||||||
set(OPENAL_INCLUDE_DIR ${DEPS}/OpenAL-Soft/include)
|
set(OPENAL_INCLUDE_DIR ${DEPS}/OpenAL-Soft/include)
|
||||||
set(OPENAL_LIBRARY ${DEPS}/OpenAL-Soft/libopenal.a;OpenSLES)
|
set(OPENAL_LIBRARY ${DEPS}/OpenAL-Soft/libopenal.a;OpenSLES)
|
||||||
|
set(PNG_LIBRARY ${DEPS}/PNG/libpng.a)
|
||||||
|
set(PNG_PNG_INCLUDE_DIR ${DEPS}/PNG/include)
|
||||||
set(SQLITE3_INCLUDE_DIR ${DEPS}/SQLite/include)
|
set(SQLITE3_INCLUDE_DIR ${DEPS}/SQLite/include)
|
||||||
set(SQLITE3_LIBRARY ${DEPS}/SQLite/libsqlite3.a)
|
set(SQLITE3_LIBRARY ${DEPS}/SQLite/libsqlite3.a)
|
||||||
set(VORBIS_INCLUDE_DIR ${DEPS}/Vorbis/include)
|
set(VORBIS_INCLUDE_DIR ${DEPS}/Vorbis/include)
|
||||||
set(VORBISFILE_LIBRARY ${DEPS}/Vorbis/libvorbisfile.a)
|
|
||||||
set(VORBIS_LIBRARY ${DEPS}/Vorbis/libvorbis.a)
|
set(VORBIS_LIBRARY ${DEPS}/Vorbis/libvorbis.a)
|
||||||
|
set(VORBISFILE_LIBRARY ${DEPS}/Vorbis/libvorbisfile.a)
|
||||||
set(ZSTD_INCLUDE_DIR ${DEPS}/Zstd/include)
|
set(ZSTD_INCLUDE_DIR ${DEPS}/Zstd/include)
|
||||||
set(ZSTD_LIBRARY ${DEPS}/Zstd/libzstd.a)
|
set(ZSTD_LIBRARY ${DEPS}/Zstd/libzstd.a)
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Locate IrrlichtMt headers on system.
|
|
||||||
|
|
||||||
find_path(IRRLICHT_INCLUDE_DIR NAMES irrlicht.h
|
|
||||||
DOC "Path to the directory with IrrlichtMt includes"
|
|
||||||
PATHS
|
|
||||||
/usr/local/include/irrlichtmt
|
|
||||||
/usr/include/irrlichtmt
|
|
||||||
/system/develop/headers/irrlichtmt #Haiku
|
|
||||||
PATH_SUFFIXES "include/irrlichtmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Handholding for users
|
|
||||||
if(IRRLICHT_INCLUDE_DIR AND (NOT IS_DIRECTORY "${IRRLICHT_INCLUDE_DIR}" OR
|
|
||||||
NOT EXISTS "${IRRLICHT_INCLUDE_DIR}/irrlicht.h"))
|
|
||||||
message(WARNING "IRRLICHT_INCLUDE_DIR was set to ${IRRLICHT_INCLUDE_DIR} "
|
|
||||||
"but irrlicht.h does not exist inside. The path will not be used.")
|
|
||||||
unset(IRRLICHT_INCLUDE_DIR CACHE)
|
|
||||||
endif()
|
|
|
@ -54,8 +54,6 @@ Library specific options:
|
||||||
GETTEXT_LIBRARY - Optional/platform-dependent with gettext; path to libintl.so/libintl.dll.a
|
GETTEXT_LIBRARY - Optional/platform-dependent with gettext; path to libintl.so/libintl.dll.a
|
||||||
GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
|
GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
|
||||||
ICONV_LIBRARY - Optional/platform-dependent; path to libiconv.so/libiconv.dylib
|
ICONV_LIBRARY - Optional/platform-dependent; path to libiconv.so/libiconv.dylib
|
||||||
IRRLICHT_DLL - Only on Windows; path to IrrlichtMt.dll
|
|
||||||
IRRLICHT_INCLUDE_DIR - Directory that contains IrrCompileConfig.h (usable for server build only)
|
|
||||||
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
|
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
|
||||||
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
|
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
|
||||||
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
|
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
|
||||||
|
|
|
@ -2,47 +2,47 @@
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
| Dependency | Version | Commentary |
|
| Dependency | Version | Commentary |
|
||||||
| ---------- | ------- | -------------------------------------------------------------------- |
|
| ---------- | ------- | ---------- |
|
||||||
| GCC | 7.5+ | or Clang 7.0.1+ |
|
| GCC | 7.5+ | or Clang 7.0.1+ |
|
||||||
| CMake | 3.5+ | |
|
| CMake | 3.5+ | |
|
||||||
| IrrlichtMt | - | Custom version of Irrlicht, see https://github.com/minetest/irrlicht |
|
| IrrlichtMt | - | Custom version of Irrlicht, see https://github.com/minetest/irrlicht |
|
||||||
| libjpeg | - | (via IrrlichtMt) |
|
| libjpeg | - | |
|
||||||
| libpng | - | (via IrrlichtMt) |
|
| libpng | - | |
|
||||||
| SDL | 2.x | (via IrrlichtMt) |
|
| SDL | 2.x | |
|
||||||
| Freetype | 2.0+ | |
|
| Freetype | 2.0+ | |
|
||||||
| SQLite3 | 3+ | |
|
| SQLite3 | 3+ | |
|
||||||
| Zlib | - | |
|
| Zlib | - | |
|
||||||
| Zstd | 1.0+ | |
|
| Zstd | 1.0+ | |
|
||||||
| LuaJIT | 2.0+ | Bundled Lua 5.1 is used if not present |
|
| LuaJIT | 2.0+ | Bundled Lua 5.1 is used if not present |
|
||||||
| GMP | 5.0.0+ | Bundled mini-GMP is used if not present |
|
| GMP | 5.0.0+ | Bundled mini-GMP is used if not present |
|
||||||
| JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present |
|
| JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present |
|
||||||
| Curl | 7.56.0+ | Optional |
|
| Curl | 7.56.0+ | Optional |
|
||||||
| gettext | - | Optional |
|
| gettext | - | Optional |
|
||||||
|
|
||||||
For Debian/Ubuntu users:
|
For Debian/Ubuntu users:
|
||||||
|
|
||||||
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxi-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext libsdl2-dev
|
sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev gettext libsdl2-dev
|
||||||
|
|
||||||
For Fedora users:
|
For Fedora users:
|
||||||
|
|
||||||
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libXi-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext SDL2-devel
|
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libpng-devel libjpeg-devel libvorbis-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel gettext SDL2-devel
|
||||||
|
|
||||||
For openSUSE users:
|
For openSUSE users:
|
||||||
|
|
||||||
sudo zypper install gcc cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libXi-devel libvorbis-devel freetype2-devel SDL2-devel
|
sudo zypper install gcc cmake libjpeg8-devel libpng16-devel openal-soft-devel libcurl-devel sqlite3-devel luajit-devel libzstd-devel Mesa-libGL-devel libvorbis-devel freetype2-devel SDL2-devel
|
||||||
|
|
||||||
For Arch users:
|
For Arch users:
|
||||||
|
|
||||||
sudo pacman -S --needed base-devel libcurl-gnutls cmake libxi libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext sdl2
|
sudo pacman -S --needed base-devel libcurl-gnutls cmake libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd gettext sdl2
|
||||||
|
|
||||||
For Alpine users:
|
For Alpine users:
|
||||||
|
|
||||||
sudo apk add build-base cmake libpng-dev jpeg-dev libxi-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext sdl2-dev
|
sudo apk add build-base cmake libpng-dev jpeg-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev zstd-dev gettext sdl2-dev
|
||||||
|
|
||||||
For Void users:
|
For Void users:
|
||||||
|
|
||||||
sudo xbps-install cmake libpng-devel jpeg-devel libXi-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel libzstd-devel gettext SDL2-devel
|
sudo xbps-install cmake libpng-devel jpeg-devel mesa sqlite-devel libogg-devel libvorbis-devel libopenal-devel libcurl-devel freetype-devel zlib-devel gmp-devel jsoncpp-devel LuaJIT-devel libzstd-devel gettext SDL2-devel
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
|
@ -73,24 +73,12 @@ Download source (this is the URL to the latest of source repository, which might
|
||||||
git clone --depth 1 https://github.com/minetest/minetest.git
|
git clone --depth 1 https://github.com/minetest/minetest.git
|
||||||
cd minetest
|
cd minetest
|
||||||
|
|
||||||
Download IrrlichtMt to `lib/irrlichtmt`, it will be used to satisfy the IrrlichtMt dependency that way:
|
|
||||||
|
|
||||||
git clone --depth 1 --branch "$(cat misc/irrlichtmt_tag.txt)" https://github.com/minetest/irrlicht.git lib/irrlichtmt
|
|
||||||
|
|
||||||
Download source, without using Git:
|
Download source, without using Git:
|
||||||
|
|
||||||
wget https://github.com/minetest/minetest/archive/master.tar.gz
|
wget https://github.com/minetest/minetest/archive/master.tar.gz
|
||||||
tar xf master.tar.gz
|
tar xf master.tar.gz
|
||||||
cd minetest-master
|
cd minetest-master
|
||||||
|
|
||||||
Download IrrlichtMt, without using Git:
|
|
||||||
|
|
||||||
cd lib/
|
|
||||||
wget https://github.com/minetest/irrlicht/archive/master.tar.gz
|
|
||||||
tar xf master.tar.gz
|
|
||||||
mv irrlicht-master irrlichtmt
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Build a version that runs directly from the source directory:
|
Build a version that runs directly from the source directory:
|
||||||
|
@ -109,13 +97,3 @@ Run it:
|
||||||
* You can disable the client build by specifying `-DBUILD_CLIENT=FALSE`.
|
* You can disable the client build by specifying `-DBUILD_CLIENT=FALSE`.
|
||||||
* You can select between Release and Debug build by `-DCMAKE_BUILD_TYPE=<Debug or Release>`.
|
* You can select between Release and Debug build by `-DCMAKE_BUILD_TYPE=<Debug or Release>`.
|
||||||
* Debug build is slower, but gives much more useful output in a debugger.
|
* Debug build is slower, but gives much more useful output in a debugger.
|
||||||
* If you build a bare server you don't need to compile IrrlichtMt, just the headers suffice.
|
|
||||||
* In that case use `-DIRRLICHT_INCLUDE_DIR=/some/where/irrlichtmt/include`.
|
|
||||||
|
|
||||||
* Minetest will use the IrrlichtMt package that is found first, given by the following order:
|
|
||||||
1. Specified `IRRLICHTMT_BUILD_DIR` CMake variable
|
|
||||||
2. `${PROJECT_SOURCE_DIR}/lib/irrlichtmt` (if existent)
|
|
||||||
3. Installation of IrrlichtMt in the system-specific library paths
|
|
||||||
4. For server builds with disabled `BUILD_CLIENT` variable, the headers from `IRRLICHT_INCLUDE_DIR` will be used.
|
|
||||||
> [!NOTE]
|
|
||||||
> Changing the IrrlichtMt build directory (includes system installs) requires regenerating the CMake cache (`rm CMakeCache.txt`)
|
|
|
@ -19,12 +19,6 @@ git clone --depth 1 https://github.com/minetest/minetest.git
|
||||||
cd minetest
|
cd minetest
|
||||||
```
|
```
|
||||||
|
|
||||||
Download Minetest's fork of Irrlicht:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone --depth 1 --branch "$(cat misc/irrlichtmt_tag.txt)" https://github.com/minetest/irrlicht.git lib/irrlichtmt
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -17,12 +17,6 @@ After you successfully built vcpkg you can easily install the required libraries
|
||||||
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext sdl2 --triplet x64-windows
|
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext sdl2 --triplet x64-windows
|
||||||
```
|
```
|
||||||
|
|
||||||
* **Don't forget about IrrlichtMt.** The easiest way is to clone it to `lib/irrlichtmt`:
|
|
||||||
|
|
||||||
```bat
|
|
||||||
for /F %i in (misc\irrlichtmt_tag.txt) do git clone --depth 1 --branch %i https://github.com/minetest/irrlicht.git lib\irrlichtmt
|
|
||||||
```
|
|
||||||
|
|
||||||
* `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
|
* `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
|
||||||
* `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound.
|
* `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound.
|
||||||
* `luajit` is optional, it replaces the integrated Lua interpreter with a faster just-in-time interpreter.
|
* `luajit` is optional, it replaces the integrated Lua interpreter with a faster just-in-time interpreter.
|
||||||
|
|
|
@ -15,6 +15,7 @@ Notable pages:
|
||||||
## In This Folder
|
## In This Folder
|
||||||
|
|
||||||
* [Developing minetestserver with Docker](docker.md)
|
* [Developing minetestserver with Docker](docker.md)
|
||||||
|
* [Android Tips & Tricks](android.md)
|
||||||
* [Miscellaneous](misc.md)
|
* [Miscellaneous](misc.md)
|
||||||
|
|
||||||
## IRC
|
## IRC
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Android tips & tricks
|
||||||
|
|
||||||
|
## Sign the Android APK from CI
|
||||||
|
|
||||||
|
The [Github Actions Workflow](https://github.com/minetest/minetest/actions?query=workflow%3Aandroid+event%3Apush)
|
||||||
|
automatically produces an APK for each architecture.
|
||||||
|
Before installing them onto a device they however need to be signed.
|
||||||
|
|
||||||
|
This requires an installation of the Android SDK and `adb`.
|
||||||
|
```bash
|
||||||
|
.../android-sdk/build-tools/30.0.3/apksigner sign --ks ~/.android/debug.keystore \
|
||||||
|
app-arm64-v8a-release-unsigned.apk
|
||||||
|
# Enter 'android' (without quotes) when asked for a password
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `debug.keystore` will not exist if you have never compiled an
|
||||||
|
Android app on your system (probably).
|
||||||
|
|
||||||
|
After that installing it will work:
|
||||||
|
```bash
|
||||||
|
adb install -r -d ./app-arm64-v8a-release-unsigned.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to get debug output from Minetest on Android
|
||||||
|
|
||||||
|
In case debug.txt isn't enough (e.g. when debugging a crash), you can get debug
|
||||||
|
output using logcat:
|
||||||
|
|
||||||
|
`adb logcat -s 'Minetest:*' '*:F'`
|
||||||
|
|
||||||
|
Note that you can do this even *after* the app has crashed,
|
||||||
|
since Android keeps an internal buffer.
|
||||||
|
|
||||||
|
A segmentation fault for example looks like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
01-10 17:20:22.215 19308 20560 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 20560 (MinetestNativeT), pid 19308 (netest.minetest)
|
||||||
|
01-10 17:20:22.287 20576 20576 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
|
||||||
|
01-10 17:20:22.287 20576 20576 F DEBUG : Build fingerprint: '...'
|
||||||
|
01-10 17:20:22.287 20576 20576 F DEBUG : Revision: '4'
|
||||||
|
01-10 17:20:22.287 20576 20576 F DEBUG : ABI: 'arm64'
|
||||||
|
01-10 17:20:22.288 20576 20576 F DEBUG : Timestamp: 2024-01-10 17:20:22+0100
|
||||||
|
01-10 17:20:22.288 20576 20576 F DEBUG : pid: 19308, tid: 20560, name: MinetestNativeT >>> net.minetest.minetest <<<
|
||||||
|
01-10 17:20:22.288 20576 20576 F DEBUG : uid: 10385
|
||||||
|
01-10 17:20:22.288 20576 20576 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
|
||||||
|
[ ... more information follows ... ]
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want get rid of previous output you can do that with `adb logcat -c`.
|
||||||
|
|
||||||
|
## I edited builtin, shaders, ... but nothing changed. Help!
|
||||||
|
|
||||||
|
You're probably hitting two problems:
|
||||||
|
* the build system only generates assets once
|
||||||
|
* the app only re-extracts assets when the version changes
|
||||||
|
|
||||||
|
Force regenerating the assets: `./gradlew app:clean`
|
||||||
|
|
||||||
|
Erase the app's memory of which version was installed: `adb shell run-as net.minetest.minetest rm shared_prefs/MinetestSettings.xml`
|
||||||
|
|
||||||
|
If this doesn't work you can also uninstall it using `adb shell pm uninstall net.minetest.minetest`. You will obviously lose your data.
|
||||||
|
|
||||||
|
Then build and install as normal and your changes should be applied.
|
|
@ -1,51 +1,5 @@
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
|
|
||||||
## Sign the Android APK from CI
|
|
||||||
|
|
||||||
The [Github Actions Workflow](https://github.com/minetest/minetest/actions?query=workflow%3Aandroid+event%3Apush)
|
|
||||||
automatically produces an APK for each architecture.
|
|
||||||
Before installing them onto a device they however need to be signed.
|
|
||||||
|
|
||||||
This requires an installation of the Android SDK and `adb`.
|
|
||||||
```bash
|
|
||||||
.../android-sdk/build-tools/30.0.3/apksigner sign --ks ~/.android/debug.keystore \
|
|
||||||
app-arm64-v8a-release-unsigned.apk
|
|
||||||
# Enter 'android' (without quotes) when asked for a password
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the `debug.keystore` will not exist if you have never compiled an
|
|
||||||
Android app on your system (probably).
|
|
||||||
|
|
||||||
After that installing it will work:
|
|
||||||
```bash
|
|
||||||
adb install -r -d ./app-arm64-v8a-release-unsigned.apk
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to get debug output from Minetest on Android
|
|
||||||
|
|
||||||
In case debug.txt isn't enough (e.g. when debugging a crash), you can get debug
|
|
||||||
output using logcat:
|
|
||||||
|
|
||||||
`adb logcat -s 'Minetest:*' '*:F'`
|
|
||||||
|
|
||||||
Note that you can do this even *after* the app has crashed,
|
|
||||||
since Android keeps an internal buffer.
|
|
||||||
|
|
||||||
A segmentation fault for example looks like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
01-10 17:20:22.215 19308 20560 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 20560 (MinetestNativeT), pid 19308 (netest.minetest)
|
|
||||||
01-10 17:20:22.287 20576 20576 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
|
|
||||||
01-10 17:20:22.287 20576 20576 F DEBUG : Build fingerprint: '...'
|
|
||||||
01-10 17:20:22.287 20576 20576 F DEBUG : Revision: '4'
|
|
||||||
01-10 17:20:22.287 20576 20576 F DEBUG : ABI: 'arm64'
|
|
||||||
01-10 17:20:22.288 20576 20576 F DEBUG : Timestamp: 2024-01-10 17:20:22+0100
|
|
||||||
01-10 17:20:22.288 20576 20576 F DEBUG : pid: 19308, tid: 20560, name: MinetestNativeT >>> net.minetest.minetest <<<
|
|
||||||
01-10 17:20:22.288 20576 20576 F DEBUG : uid: 10385
|
|
||||||
01-10 17:20:22.288 20576 20576 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
|
|
||||||
[ ... more information follows ... ]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Profiling Minetest on Linux
|
## Profiling Minetest on Linux
|
||||||
|
|
||||||
We will be using a tool called "perf", which you can get by installing `perf` or `linux-perf` or `linux-tools-common`.
|
We will be using a tool called "perf", which you can get by installing `perf` or `linux-perf` or `linux-tools-common`.
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Docker Server
|
||||||
|
|
||||||
|
We provide Minetest server Docker images using the GitHub container registry.
|
||||||
|
|
||||||
|
Images are built on each commit and available using the following tag scheme:
|
||||||
|
|
||||||
|
* `ghcr.io/minetest/minetest:master` (latest build)
|
||||||
|
* `ghcr.io/minetest/minetest:<tag>` (specific Git tag)
|
||||||
|
* `ghcr.io/minetest/minetest:latest` (latest Git tag, which is the stable release)
|
||||||
|
|
||||||
|
See [here](https://github.com/minetest/minetest/pkgs/container/minetest) for all available tags.
|
||||||
|
|
||||||
|
For a quick test you can easily run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run ghcr.io/minetest/minetest:master
|
||||||
|
```
|
||||||
|
|
||||||
|
To use it in a production environment, you should use volumes bound to the Docker host to persist data and modify the configuration:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker create -v /home/minetest/data/:/var/lib/minetest/ -v /home/minetest/conf/:/etc/minetest/ ghcr.io/minetest/minetest:master
|
||||||
|
```
|
||||||
|
|
||||||
|
You may also want to use [Docker Compose](https://docs.docker.com/compose):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
version: "2"
|
||||||
|
services:
|
||||||
|
minetest_server:
|
||||||
|
image: ghcr.io/minetest/minetest:master
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
volumes:
|
||||||
|
- /home/minetest/data/:/var/lib/minetest/
|
||||||
|
- /home/minetest/conf/:/etc/minetest/
|
||||||
|
ports:
|
||||||
|
- "30000:30000/udp"
|
||||||
|
- "127.0.0.1:30000:30000/tcp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Data will be written to `/home/minetest/data` on the host, and configuration will be read from `/home/minetest/conf/minetest.conf`.
|
||||||
|
|
||||||
|
**Note:** If you don't understand the previous commands please read the [official Docker documentation](https://docs.docker.com) before use.
|
228
doc/lua_api.md
228
doc/lua_api.md
|
@ -652,8 +652,9 @@ The mask is applied using binary AND.
|
||||||
|
|
||||||
#### `[sheet:<w>x<h>:<x>,<y>`
|
#### `[sheet:<w>x<h>:<x>,<y>`
|
||||||
|
|
||||||
Retrieves a tile at position x,y from the base image
|
Retrieves a tile at position x, y (in tiles, 0-indexed)
|
||||||
which it assumes to be a tilesheet with dimensions w,h.
|
from the base image, which it assumes to be a tilesheet
|
||||||
|
with dimensions w, h (in tiles).
|
||||||
|
|
||||||
#### `[colorize:<color>:<ratio>`
|
#### `[colorize:<color>:<ratio>`
|
||||||
|
|
||||||
|
@ -1085,6 +1086,7 @@ Table used to specify how a sound is played:
|
||||||
-- its end in `-start_time` seconds.
|
-- its end in `-start_time` seconds.
|
||||||
-- It is unspecified what happens if `loop` is false and `start_time` is
|
-- It is unspecified what happens if `loop` is false and `start_time` is
|
||||||
-- smaller than minus the sound's length.
|
-- smaller than minus the sound's length.
|
||||||
|
|
||||||
-- Available since feature `sound_params_start_time`.
|
-- Available since feature `sound_params_start_time`.
|
||||||
|
|
||||||
loop = false,
|
loop = false,
|
||||||
|
@ -1098,6 +1100,21 @@ Table used to specify how a sound is played:
|
||||||
-- Attach the sound to an object.
|
-- Attach the sound to an object.
|
||||||
-- Can't be used together with `pos`.
|
-- Can't be used together with `pos`.
|
||||||
|
|
||||||
|
-- For backward compatibility, sounds continue playing at the last location
|
||||||
|
-- of the object if an object is removed (for example if an entity dies).
|
||||||
|
-- It is not recommended to rely on this.
|
||||||
|
-- For death sounds, prefer playing a positional sound instead.
|
||||||
|
|
||||||
|
-- If you want to stop a sound when an entity dies or is deactivated,
|
||||||
|
-- store the handle and call `minetest.sound_stop` in `on_die` / `on_deactivate`.
|
||||||
|
|
||||||
|
-- Ephemeral sounds are entirely unaffected by the object being removed
|
||||||
|
-- or leaving the active object range.
|
||||||
|
|
||||||
|
-- Non-ephemeral sounds stop playing on clients if objects leave
|
||||||
|
-- the active object range; they should start playing again if objects
|
||||||
|
--- come back into range (but due to a known bug, they don't yet).
|
||||||
|
|
||||||
to_player = name,
|
to_player = name,
|
||||||
-- Only play for this player.
|
-- Only play for this player.
|
||||||
-- Can't be used together with `exclude_player`.
|
-- Can't be used together with `exclude_player`.
|
||||||
|
@ -1382,8 +1399,7 @@ Look for examples in `games/devtest` or `games/minetest_game`.
|
||||||
* `liquid`
|
* `liquid`
|
||||||
* The cubic source node for a liquid.
|
* The cubic source node for a liquid.
|
||||||
* Faces bordering to the same node are never rendered.
|
* Faces bordering to the same node are never rendered.
|
||||||
* Connects to node specified in `liquid_alternative_flowing`.
|
* Connects to node specified in `liquid_alternative_flowing` if specified.
|
||||||
* You *must* set `liquid_alternative_source` to the node's own name.
|
|
||||||
* Use `backface_culling = false` for the tiles you want to make
|
* Use `backface_culling = false` for the tiles you want to make
|
||||||
visible when inside the node.
|
visible when inside the node.
|
||||||
* `flowingliquid`
|
* `flowingliquid`
|
||||||
|
@ -2499,6 +2515,8 @@ Some of the values in the key-value store are handled specially:
|
||||||
0 = default, 1 = left / up, 2 = middle, 3 = right / down
|
0 = default, 1 = left / up, 2 = middle, 3 = right / down
|
||||||
The default currently is the same as right/down.
|
The default currently is the same as right/down.
|
||||||
Example: 6 = 2 + 1*4 = middle,up
|
Example: 6 = 2 + 1*4 = middle,up
|
||||||
|
* `range`: Overrides the pointing range
|
||||||
|
Example: `meta:set_float("range", 4.2)`
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -2965,6 +2983,16 @@ background elements are drawn before all other elements.
|
||||||
centered on `H`. With the new coordinate system, `H` will modify the height.
|
centered on `H`. With the new coordinate system, `H` will modify the height.
|
||||||
* `label` is the text on the button
|
* `label` is the text on the button
|
||||||
|
|
||||||
|
### `button_url[<X>,<Y>;<W>,<H>;<name>;<label>;<url>]`
|
||||||
|
|
||||||
|
* Clickable button. When clicked, fields will be sent and the user will be given the
|
||||||
|
option to open the URL in a browser.
|
||||||
|
* With the old coordinate system, buttons are a set height, but will be vertically
|
||||||
|
centered on `H`. With the new coordinate system, `H` will modify the height.
|
||||||
|
* To make this into an `image_button`, you can use formspec styling.
|
||||||
|
* `label` is the text on the button.
|
||||||
|
* `url` must be a valid web URL, starting with `http://` or `https://`.
|
||||||
|
|
||||||
### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
|
### `image_button[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
|
||||||
|
|
||||||
* `texture name` is the filename of an image
|
* `texture name` is the filename of an image
|
||||||
|
@ -2991,6 +3019,11 @@ background elements are drawn before all other elements.
|
||||||
* When clicked, fields will be sent and the form will quit.
|
* When clicked, fields will be sent and the form will quit.
|
||||||
* Same as `button` in all other respects.
|
* Same as `button` in all other respects.
|
||||||
|
|
||||||
|
### `button_url_exit[<X>,<Y>;<W>,<H>;<name>;<label>;<url>]`
|
||||||
|
|
||||||
|
* When clicked, fields will be sent and the form will quit.
|
||||||
|
* Same as `button_url` in all other respects.
|
||||||
|
|
||||||
### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
|
### `image_button_exit[<X>,<Y>;<W>,<H>;<texture name>;<name>;<label>]`
|
||||||
|
|
||||||
* When clicked, fields will be sent and the form will quit.
|
* When clicked, fields will be sent and the form will quit.
|
||||||
|
@ -3482,11 +3515,13 @@ Changes the style of the text.
|
||||||
Sets global style.
|
Sets global style.
|
||||||
|
|
||||||
Global only styles:
|
Global only styles:
|
||||||
|
|
||||||
* `background`: Text background, a `colorspec` or `none`.
|
* `background`: Text background, a `colorspec` or `none`.
|
||||||
* `margin`: Page margins in pixel.
|
* `margin`: Page margins in pixel.
|
||||||
* `valign`: Text vertical alignment (`top`, `middle`, `bottom`).
|
* `valign`: Text vertical alignment (`top`, `middle`, `bottom`).
|
||||||
|
|
||||||
Inheriting styles (affects child elements):
|
Inheriting styles (affects child elements):
|
||||||
|
|
||||||
* `color`: Default text color. Given color is a `colorspec`.
|
* `color`: Default text color. Given color is a `colorspec`.
|
||||||
* `hovercolor`: Color of <action> tags when mouse is over.
|
* `hovercolor`: Color of <action> tags when mouse is over.
|
||||||
* `size`: Default text size.
|
* `size`: Default text size.
|
||||||
|
@ -3500,6 +3535,7 @@ tags appear.
|
||||||
`<tag name=... color=... hovercolor=... font=... size=...>`
|
`<tag name=... color=... hovercolor=... font=... size=...>`
|
||||||
|
|
||||||
Defines or redefines tag style. This can be used to define new tags.
|
Defines or redefines tag style. This can be used to define new tags.
|
||||||
|
|
||||||
* `name`: Name of the tag to define or change.
|
* `name`: Name of the tag to define or change.
|
||||||
* `color`: Text color. Given color is a `colorspec`.
|
* `color`: Text color. Given color is a `colorspec`.
|
||||||
* `hovercolor`: Text color when element hovered (only for `action` tags). Given color is a `colorspec`.
|
* `hovercolor`: Text color when element hovered (only for `action` tags). Given color is a `colorspec`.
|
||||||
|
@ -3532,6 +3568,7 @@ Other tags can be added using `<tag ...>` tag.
|
||||||
Make that text a clickable text triggering an action.
|
Make that text a clickable text triggering an action.
|
||||||
|
|
||||||
* `name`: Name of the action (mandatory).
|
* `name`: Name of the action (mandatory).
|
||||||
|
* `url`: URL to open when the action is triggered (optional).
|
||||||
|
|
||||||
When clicked, the formspec is send to the server. The value of the text field
|
When clicked, the formspec is send to the server. The value of the text field
|
||||||
sent to `on_player_receive_fields` will be "action:" concatenated to the action
|
sent to `on_player_receive_fields` will be "action:" concatenated to the action
|
||||||
|
@ -3585,6 +3622,18 @@ X, Y and Z being angles around each three axes. Works only if
|
||||||
* Is not created automatically, use `InvRef:set_size`
|
* Is not created automatically, use `InvRef:set_size`
|
||||||
* Is only used to enhance the empty hand's tool capabilities
|
* Is only used to enhance the empty hand's tool capabilities
|
||||||
|
|
||||||
|
## ItemStack transaction order
|
||||||
|
|
||||||
|
This list describes the situation for non-empty ItemStacks in both slots
|
||||||
|
that cannot be stacked at all, hence triggering an ItemStack swap operation.
|
||||||
|
Put/take callbacks on empty ItemStack are not executed.
|
||||||
|
|
||||||
|
1. The "allow take" and "allow put" callbacks are each run once for the source
|
||||||
|
and destination inventory.
|
||||||
|
2. The allowed ItemStacks are exchanged.
|
||||||
|
3. The "on take" callbacks are run for the source and destination inventories
|
||||||
|
4. The "on put" callbacks are run for the source and destination inventories
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
|
@ -4005,25 +4054,31 @@ Two functions are provided to translate strings: `minetest.translate` and
|
||||||
avoid clashes with other mods.
|
avoid clashes with other mods.
|
||||||
This function must be given a number of arguments equal to the number of
|
This function must be given a number of arguments equal to the number of
|
||||||
arguments the translated string expects.
|
arguments the translated string expects.
|
||||||
Arguments are literal strings -- they will not be translated, so if you want
|
Arguments are literal strings -- they will not be translated.
|
||||||
them to be, they need to come as outputs of `minetest.translate` as well.
|
|
||||||
|
|
||||||
For instance, suppose we want to translate "@1 Wool" with "@1" being replaced
|
For instance, suppose we want to greet players when they join. We can do the
|
||||||
by the translation of "Red". We can do the following:
|
following:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local S = minetest.get_translator()
|
local S = minetest.get_translator("hello")
|
||||||
S("@1 Wool", S("Red"))
|
minetest.register_on_joinplayer(function(player)
|
||||||
```
|
local name = player:get_player_name()
|
||||||
|
minetest.chat_send_player(name, S("Hello @1, how are you today?", name))
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
|
||||||
This will be displayed as "Red Wool" on old clients and on clients that do
|
When someone called "CoolGuy" joins the game with an old client or a client
|
||||||
not have localization enabled. However, if we have for instance a translation
|
that does not have localization enabled, they will see `Hello CoolGuy, how are
|
||||||
file named `wool.fr.tr` containing the following:
|
you today?`
|
||||||
|
|
||||||
@1 Wool=Laine @1
|
However, if we have for instance a translation file named `hello.de.tr`
|
||||||
Red=Rouge
|
containing the following:
|
||||||
|
|
||||||
this will be displayed as "Laine Rouge" on clients with a French locale.
|
# textdomain: hello
|
||||||
|
Hello @1, how are you today?=Hallo @1, wie geht es dir heute?
|
||||||
|
|
||||||
|
and CoolGuy has set a German locale, they will see `Hallo CoolGuy, wie geht es
|
||||||
|
dir heute?`
|
||||||
|
|
||||||
## Operations on Translated Strings
|
## Operations on Translated Strings
|
||||||
|
|
||||||
|
@ -4450,6 +4505,11 @@ Can specify a probability of a node randomly appearing when placed.
|
||||||
This decoration type is intended to be used for multi-node sized discrete
|
This decoration type is intended to be used for multi-node sized discrete
|
||||||
structures, such as trees, cave spikes, rocks, and so on.
|
structures, such as trees, cave spikes, rocks, and so on.
|
||||||
|
|
||||||
|
## `lsystem`
|
||||||
|
|
||||||
|
Generates a L-system tree at the position where the decoration is placed.
|
||||||
|
Uses the same L-system as `minetest.spawn_tree`, but is faster than using it manually.
|
||||||
|
The `treedef` field in the decoration definition is used for the tree definition.
|
||||||
|
|
||||||
|
|
||||||
# Schematics
|
# Schematics
|
||||||
|
@ -5187,6 +5247,12 @@ Minetest includes the following settings to control behavior of privileges:
|
||||||
|
|
||||||
* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"`
|
* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"`
|
||||||
* Useful for storing custom data
|
* Useful for storing custom data
|
||||||
|
* `minetest.get_mod_data_path()`: returns e.g. `"/home/user/.minetest/mod_data/mymod"`
|
||||||
|
* Useful for storing custom data *independently of worlds*.
|
||||||
|
* Must be called during mod load time.
|
||||||
|
* Can read or write to this directory at any time.
|
||||||
|
* It's possible that multiple Minetest instances are running at the same
|
||||||
|
time, which may lead to corruption if you are not careful.
|
||||||
* `minetest.is_singleplayer()`
|
* `minetest.is_singleplayer()`
|
||||||
* `minetest.features`: Table containing API feature flags
|
* `minetest.features`: Table containing API feature flags
|
||||||
|
|
||||||
|
@ -5278,6 +5344,10 @@ Minetest includes the following settings to control behavior of privileges:
|
||||||
dynamic_add_media_startup = true,
|
dynamic_add_media_startup = true,
|
||||||
-- dynamic_add_media supports `filename` and `filedata` parameters (5.9.0)
|
-- dynamic_add_media supports `filename` and `filedata` parameters (5.9.0)
|
||||||
dynamic_add_media_filepath = true,
|
dynamic_add_media_filepath = true,
|
||||||
|
-- L-system decoration type (5.9.0)
|
||||||
|
lsystem_decoration_type = true,
|
||||||
|
-- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0)
|
||||||
|
item_meta_range = true,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -5883,6 +5953,7 @@ handler.
|
||||||
returns `{name="ignore", param1=0, param2=0}` for unloaded areas.
|
returns `{name="ignore", param1=0, param2=0}` for unloaded areas.
|
||||||
* `minetest.get_node_or_nil(pos)`
|
* `minetest.get_node_or_nil(pos)`
|
||||||
* Same as `get_node` but returns `nil` for unloaded areas.
|
* Same as `get_node` but returns `nil` for unloaded areas.
|
||||||
|
* Note that areas may still contain "ignore" despite being loaded.
|
||||||
* `minetest.get_node_light(pos[, timeofday])`
|
* `minetest.get_node_light(pos[, timeofday])`
|
||||||
* Gets the light value at the given position. Note that the light value
|
* Gets the light value at the given position. Note that the light value
|
||||||
"inside" the node at the given position is returned, so you usually want
|
"inside" the node at the given position is returned, so you usually want
|
||||||
|
@ -5928,7 +5999,7 @@ handler.
|
||||||
* `minetest.add_entity(pos, name, [staticdata])`: Spawn Lua-defined entity at
|
* `minetest.add_entity(pos, name, [staticdata])`: Spawn Lua-defined entity at
|
||||||
position.
|
position.
|
||||||
* Returns `ObjectRef`, or `nil` if failed
|
* Returns `ObjectRef`, or `nil` if failed
|
||||||
* Entities with `static_save = true` can be added also
|
* Entities with `static_save = true` can be added also
|
||||||
to unloaded and non-generated blocks.
|
to unloaded and non-generated blocks.
|
||||||
* `minetest.add_item(pos, item)`: Spawn item
|
* `minetest.add_item(pos, item)`: Spawn item
|
||||||
* Returns `ObjectRef`, or `nil` if failed
|
* Returns `ObjectRef`, or `nil` if failed
|
||||||
|
@ -6120,13 +6191,16 @@ handler.
|
||||||
* Returns the position of the blocking node when `false`
|
* Returns the position of the blocking node when `false`
|
||||||
* `pos1`: First position
|
* `pos1`: First position
|
||||||
* `pos2`: Second position
|
* `pos2`: Second position
|
||||||
* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast`
|
* `minetest.raycast(pos1, pos2, objects, liquids, pointabilities)`: returns `Raycast`
|
||||||
* Creates a `Raycast` object.
|
* Creates a `Raycast` object.
|
||||||
* `pos1`: start of the ray
|
* `pos1`: start of the ray
|
||||||
* `pos2`: end of the ray
|
* `pos2`: end of the ray
|
||||||
* `objects`: if false, only nodes will be returned. Default is `true`.
|
* `objects`: if false, only nodes will be returned. Default is `true`.
|
||||||
* `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be
|
* `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be
|
||||||
returned. Default is `false`.
|
returned. Default is `false`.
|
||||||
|
* `pointabilities`: Allows overriding the `pointable` property of
|
||||||
|
nodes and objects. Uses the same format as the `pointabilities` property
|
||||||
|
of item definitions. Default is `nil`.
|
||||||
* `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)`
|
* `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)`
|
||||||
* returns table containing path that can be walked on
|
* returns table containing path that can be walked on
|
||||||
* returns a table of 3D points representing a path from `pos1` to `pos2` or
|
* returns a table of 3D points representing a path from `pos1` to `pos2` or
|
||||||
|
@ -6503,6 +6577,18 @@ This allows you easy interoperability for delegating work to jobs.
|
||||||
* Register a path to a Lua file to be imported when an async environment
|
* Register a path to a Lua file to be imported when an async environment
|
||||||
is initialized. You can use this to preload code which you can then call
|
is initialized. You can use this to preload code which you can then call
|
||||||
later using `minetest.handle_async()`.
|
later using `minetest.handle_async()`.
|
||||||
|
* `minetest.register_async_metatable(name, mt)`:
|
||||||
|
* Register a metatable that should be preserved when data is transferred
|
||||||
|
between the main thread and the async environment.
|
||||||
|
* `name` is a string that identifies the metatable. It is recommended to
|
||||||
|
follow the `modname:name` convention for this identifier.
|
||||||
|
* `mt` is the metatable to register.
|
||||||
|
* Note that it is allowed to register the same metatable under multiple
|
||||||
|
names, but it is not allowed to register multiple metatables under the
|
||||||
|
same name.
|
||||||
|
* You must register the metatable in both the main environment
|
||||||
|
and the async environment for this mechanism to work.
|
||||||
|
|
||||||
|
|
||||||
### List of APIs Available in an Async Environment
|
### List of APIs Available in an Async Environment
|
||||||
|
|
||||||
|
@ -6528,6 +6614,7 @@ Class instances that can be transferred between environments:
|
||||||
Functions:
|
Functions:
|
||||||
* Standalone helpers such as logging, filesystem, encoding,
|
* Standalone helpers such as logging, filesystem, encoding,
|
||||||
hashing or compression APIs
|
hashing or compression APIs
|
||||||
|
* `minetest.register_async_metatable` (see above)
|
||||||
|
|
||||||
Variables:
|
Variables:
|
||||||
* `minetest.settings`
|
* `minetest.settings`
|
||||||
|
@ -7143,9 +7230,45 @@ You can use the gennotify mechanism to transfer this information.
|
||||||
All callbacks registered with [Global callback registration functions] are added
|
All callbacks registered with [Global callback registration functions] are added
|
||||||
to corresponding `minetest.registered_*` tables.
|
to corresponding `minetest.registered_*` tables.
|
||||||
|
|
||||||
|
For historical reasons, the use of an -s suffix in these names is inconsistent.
|
||||||
|
|
||||||
|
* `minetest.registered_on_chat_messages`
|
||||||
|
* `minetest.registered_on_chatcommands`
|
||||||
|
* `minetest.registered_globalsteps`
|
||||||
|
* `minetest.registered_on_punchnodes`
|
||||||
|
* `minetest.registered_on_placenodes`
|
||||||
|
* `minetest.registered_on_dignodes`
|
||||||
|
* `minetest.registered_on_generateds`
|
||||||
|
* `minetest.registered_on_newplayers`
|
||||||
|
* `minetest.registered_on_dieplayers`
|
||||||
|
* `minetest.registered_on_respawnplayers`
|
||||||
|
* `minetest.registered_on_prejoinplayers`
|
||||||
|
* `minetest.registered_on_joinplayers`
|
||||||
|
* `minetest.registered_on_leaveplayers`
|
||||||
|
* `minetest.registered_on_player_receive_fields`
|
||||||
|
* `minetest.registered_on_cheats`
|
||||||
|
* `minetest.registered_on_crafts`
|
||||||
|
* `minetest.registered_craft_predicts`
|
||||||
|
* `minetest.registered_on_item_eats`
|
||||||
|
* `minetest.registered_on_item_pickups`
|
||||||
|
* `minetest.registered_on_punchplayers`
|
||||||
|
* `minetest.registered_on_authplayers`
|
||||||
|
* `minetest.registered_on_player_inventory_actions`
|
||||||
|
* `minetest.registered_allow_player_inventory_actions`
|
||||||
|
* `minetest.registered_on_rightclickplayers`
|
||||||
|
* `minetest.registered_on_mods_loaded`
|
||||||
|
* `minetest.registered_on_shutdown`
|
||||||
|
* `minetest.registered_on_protection_violation`
|
||||||
|
* `minetest.registered_on_priv_grant`
|
||||||
|
* `minetest.registered_on_priv_revoke`
|
||||||
|
* `minetest.registered_can_bypass_userlimit`
|
||||||
|
* `minetest.registered_on_modchannel_message`
|
||||||
|
* `minetest.registered_on_liquid_transformed`
|
||||||
|
* `minetest.registered_on_mapblocks_changed`
|
||||||
|
|
||||||
|
|
||||||
# Class Reference
|
|
||||||
|
# Class reference
|
||||||
|
|
||||||
Sorted alphabetically.
|
Sorted alphabetically.
|
||||||
|
|
||||||
|
@ -7765,10 +7888,14 @@ child will follow movement and rotation of that bone.
|
||||||
* Second column: subject looking to the left
|
* Second column: subject looking to the left
|
||||||
* Third column: subject backing the camera
|
* Third column: subject backing the camera
|
||||||
* Fourth column: subject looking to the right
|
* Fourth column: subject looking to the right
|
||||||
* Fifth column: subject viewed from above
|
* Fifth column: subject viewed from above
|
||||||
* Sixth column: subject viewed from below
|
* Sixth column: subject viewed from below
|
||||||
* `get_entity_name()`: (**Deprecated**: Will be removed in a future version, use the field `self.name` instead)
|
* `get_luaentity()`:
|
||||||
* `get_luaentity()`
|
* Returns the object's associated luaentity table, if there is one
|
||||||
|
* Otherwise returns `nil` (e.g. for players)
|
||||||
|
* `get_entity_name()`:
|
||||||
|
* **Deprecated**: Will be removed in a future version,
|
||||||
|
use `:get_luaentity().name` instead.
|
||||||
|
|
||||||
#### Player Only (No-Op for Other Objects)
|
#### Player Only (No-Op for Other Objects)
|
||||||
|
|
||||||
|
@ -8473,7 +8600,8 @@ Player properties need to be saved manually.
|
||||||
-- "mesh" uses the defined mesh model.
|
-- "mesh" uses the defined mesh model.
|
||||||
-- "wielditem" is used for dropped items.
|
-- "wielditem" is used for dropped items.
|
||||||
-- (see builtin/game/item_entity.lua).
|
-- (see builtin/game/item_entity.lua).
|
||||||
-- For this use 'wield_item = itemname' (Deprecated: 'textures = {itemname}').
|
-- For this use 'wield_item = itemname'.
|
||||||
|
-- Setting 'textures = {itemname}' has the same effect, but is deprecated.
|
||||||
-- If the item has a 'wield_image' the object will be an extrusion of
|
-- If the item has a 'wield_image' the object will be an extrusion of
|
||||||
-- that, otherwise:
|
-- that, otherwise:
|
||||||
-- If 'itemname' is a cubic node or nodebox the object will appear
|
-- If 'itemname' is a cubic node or nodebox the object will appear
|
||||||
|
@ -8500,8 +8628,8 @@ Player properties need to be saved manually.
|
||||||
-- "cube" uses 6 textures just like a node, but all 6 must be defined.
|
-- "cube" uses 6 textures just like a node, but all 6 must be defined.
|
||||||
-- "sprite" uses 1 texture.
|
-- "sprite" uses 1 texture.
|
||||||
-- "upright_sprite" uses 2 textures: {front, back}.
|
-- "upright_sprite" uses 2 textures: {front, back}.
|
||||||
-- "wielditem" expects 'textures = {itemname}' (see 'visual' above).
|
|
||||||
-- "mesh" requires one texture for each mesh buffer/material (in order)
|
-- "mesh" requires one texture for each mesh buffer/material (in order)
|
||||||
|
-- Deprecated usage of "wielditem" expects 'textures = {itemname}' (see 'visual' above).
|
||||||
|
|
||||||
colors = {},
|
colors = {},
|
||||||
-- Number of required colors depends on visual
|
-- Number of required colors depends on visual
|
||||||
|
@ -8817,6 +8945,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
|
||||||
|
|
||||||
range = 4.0,
|
range = 4.0,
|
||||||
-- Range of node and object pointing that is possible with this item held
|
-- Range of node and object pointing that is possible with this item held
|
||||||
|
-- Can be overridden with itemstack meta.
|
||||||
|
|
||||||
liquids_pointable = false,
|
liquids_pointable = false,
|
||||||
-- If true, item can point to all liquid nodes (`liquidtype ~= "none"`),
|
-- If true, item can point to all liquid nodes (`liquidtype ~= "none"`),
|
||||||
|
@ -8830,9 +8959,9 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
|
||||||
objects = {
|
objects = {
|
||||||
["modname:entityname"] = true,
|
["modname:entityname"] = true,
|
||||||
["group:ghosty"] = true, -- (an armor group)
|
["group:ghosty"] = true, -- (an armor group)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
-- Contains lists to override the `pointable` property of pointed nodes and objects.
|
-- Contains lists to override the `pointable` property of nodes and objects.
|
||||||
-- The index can be a node/entity name or a group with the prefix `"group:"`.
|
-- The index can be a node/entity name or a group with the prefix `"group:"`.
|
||||||
-- (For objects `armor_groups` are used and for players the entity name is irrelevant.)
|
-- (For objects `armor_groups` are used and for players the entity name is irrelevant.)
|
||||||
-- If multiple fields fit, the following priority order is applied:
|
-- If multiple fields fit, the following priority order is applied:
|
||||||
|
@ -8897,19 +9026,20 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
|
||||||
-- Otherwise should be name of node which the client immediately places
|
-- Otherwise should be name of node which the client immediately places
|
||||||
-- upon digging. Server will always update with actual result shortly.
|
-- upon digging. Server will always update with actual result shortly.
|
||||||
|
|
||||||
touch_interaction = {
|
touch_interaction = <TouchInteractionMode> OR {
|
||||||
-- Only affects touchscreen clients.
|
pointed_nothing = <TouchInteractionMode>,
|
||||||
-- Defines the meaning of short and long taps with the item in hand.
|
pointed_node = <TouchInteractionMode>,
|
||||||
-- The fields in this table have two valid values:
|
pointed_object = <TouchInteractionMode>,
|
||||||
-- * "long_dig_short_place" (long tap = dig, short tap = place)
|
|
||||||
-- * "short_dig_long_place" (short tap = dig, long tap = place)
|
|
||||||
-- The field to be used is selected according to the current
|
|
||||||
-- `pointed_thing`.
|
|
||||||
|
|
||||||
pointed_nothing = "long_dig_short_place",
|
|
||||||
pointed_node = "long_dig_short_place",
|
|
||||||
pointed_object = "short_dig_long_place",
|
|
||||||
},
|
},
|
||||||
|
-- Only affects touchscreen clients.
|
||||||
|
-- Defines the meaning of short and long taps with the item in hand.
|
||||||
|
-- If specified as a table, the field to be used is selected according to
|
||||||
|
-- the current `pointed_thing`.
|
||||||
|
-- There are three possible TouchInteractionMode values:
|
||||||
|
-- * "user" (meaning depends on client-side settings)
|
||||||
|
-- * "long_dig_short_place" (long tap = dig, short tap = place)
|
||||||
|
-- * "short_dig_long_place" (short tap = dig, long tap = place)
|
||||||
|
-- The default value is "user".
|
||||||
|
|
||||||
sound = {
|
sound = {
|
||||||
-- Definition of item sounds to be played at various events.
|
-- Definition of item sounds to be played at various events.
|
||||||
|
@ -9121,10 +9251,8 @@ Used by `minetest.register_node`.
|
||||||
-- flowing version (`liquid_alternative_flowing`) and
|
-- flowing version (`liquid_alternative_flowing`) and
|
||||||
-- source version (`liquid_alternative_source`) of a liquid.
|
-- source version (`liquid_alternative_source`) of a liquid.
|
||||||
--
|
--
|
||||||
-- Specifically, these fields are required if any of these is true:
|
-- Specifically, these fields are required if `liquidtype ~= "none"` or
|
||||||
-- * `liquidtype ~= "none" or
|
-- `drawtype == "flowingliquid"`.
|
||||||
-- * `drawtype == "liquid" or
|
|
||||||
-- * `drawtype == "flowingliquid"
|
|
||||||
--
|
--
|
||||||
-- Liquids consist of up to two nodes: source and flowing.
|
-- Liquids consist of up to two nodes: source and flowing.
|
||||||
--
|
--
|
||||||
|
@ -9988,7 +10116,7 @@ See [Decoration types]. Used by `minetest.register_decoration`.
|
||||||
```lua
|
```lua
|
||||||
{
|
{
|
||||||
deco_type = "simple",
|
deco_type = "simple",
|
||||||
-- Type. "simple" or "schematic" supported
|
-- Type. "simple", "schematic" or "lsystem" supported
|
||||||
|
|
||||||
place_on = "default:dirt_with_grass",
|
place_on = "default:dirt_with_grass",
|
||||||
-- Node (or list of nodes) that the decoration can be placed on
|
-- Node (or list of nodes) that the decoration can be placed on
|
||||||
|
@ -10141,6 +10269,12 @@ See [Decoration types]. Used by `minetest.register_decoration`.
|
||||||
-- Effect is inverted for "all_ceilings" decorations.
|
-- Effect is inverted for "all_ceilings" decorations.
|
||||||
-- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer
|
-- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer
|
||||||
-- to the 'place_on' node.
|
-- to the 'place_on' node.
|
||||||
|
|
||||||
|
----- L-system-type parameters
|
||||||
|
|
||||||
|
treedef = {},
|
||||||
|
-- Same as for `minetest.spawn_tree`.
|
||||||
|
-- See section [L-system trees] for more details.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,6 @@ The "gamedata" table is read when calling `core.start()`. It should contain:
|
||||||
* Android only. Shares file using the share popup
|
* Android only. Shares file using the share popup
|
||||||
* `core.get_version()` (possible in async calls)
|
* `core.get_version()` (possible in async calls)
|
||||||
* returns current core version
|
* returns current core version
|
||||||
* `core.set_once(key, value)`:
|
|
||||||
* save a string value that persists even if menu is closed
|
|
||||||
* `core.get_once(key)`:
|
|
||||||
* get a string value saved by above function, or `nil`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,22 @@ minetest.register_chatcommand("bench_content2name", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function get_positions_cube(ppos)
|
||||||
|
local pos_list = {}
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
for x=2,100 do
|
||||||
|
for y=2,100 do
|
||||||
|
for z=2,100 do
|
||||||
|
pos_list[i] = ppos:offset(x, y, z)
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return pos_list
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_chatcommand("bench_bulk_set_node", {
|
minetest.register_chatcommand("bench_bulk_set_node", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Benchmark: Bulk-set 99×99×99 stone nodes",
|
description = "Benchmark: Bulk-set 99×99×99 stone nodes",
|
||||||
|
@ -79,25 +95,15 @@ minetest.register_chatcommand("bench_bulk_set_node", {
|
||||||
if not player then
|
if not player then
|
||||||
return false, "No player."
|
return false, "No player."
|
||||||
end
|
end
|
||||||
local pos_list = {}
|
local pos_list = get_positions_cube(player:get_pos())
|
||||||
local ppos = player:get_pos()
|
|
||||||
local i = 1
|
|
||||||
for x=2,100 do
|
|
||||||
for y=2,100 do
|
|
||||||
for z=2,100 do
|
|
||||||
pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.chat_send_player(name, "Benchmarking minetest.bulk_set_node. Warming up ...");
|
minetest.chat_send_player(name, "Benchmarking minetest.bulk_set_node. Warming up ...")
|
||||||
|
|
||||||
-- warm up with stone to prevent having different callbacks
|
-- warm up with stone to prevent having different callbacks
|
||||||
-- due to different node topology
|
-- due to different node topology
|
||||||
minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
|
minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
|
||||||
|
|
||||||
minetest.chat_send_player(name, "Warming up finished, now benchmarking ...");
|
minetest.chat_send_player(name, "Warming up finished, now benchmarking ...")
|
||||||
|
|
||||||
local start_time = minetest.get_us_time()
|
local start_time = minetest.get_us_time()
|
||||||
for i=1,#pos_list do
|
for i=1,#pos_list do
|
||||||
|
@ -114,4 +120,37 @@ minetest.register_chatcommand("bench_bulk_set_node", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("bench_bulk_get_node", {
|
||||||
|
params = "",
|
||||||
|
description = "Benchmark: Bulk-get 99×99×99 nodes",
|
||||||
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
if not player then
|
||||||
|
return false, "No player."
|
||||||
|
end
|
||||||
|
local pos_list = get_positions_cube(player:get_pos())
|
||||||
|
local function bench()
|
||||||
|
local start_time = minetest.get_us_time()
|
||||||
|
for i=1,#pos_list do
|
||||||
|
local n = minetest.get_node(pos_list[i])
|
||||||
|
-- Make sure the name lookup is never optimized away.
|
||||||
|
-- Table allocation might still be omitted. But only accessing
|
||||||
|
-- the name of a node is a common pattern anyways.
|
||||||
|
if n.name == "benchmarks:nonexistent_node" then
|
||||||
|
error("should never happen")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return minetest.get_us_time() - start_time
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.chat_send_player(name, "Benchmarking minetest.get_node. Warming up ...")
|
||||||
|
bench()
|
||||||
|
|
||||||
|
minetest.chat_send_player(name, "Warming up finished, now benchmarking ...")
|
||||||
|
local result_us = bench()
|
||||||
|
|
||||||
|
local msg = string.format("Benchmark results: minetest.get_node loop 1: %.2f ms",
|
||||||
|
result_us / 1000)
|
||||||
|
return true, msg
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
|
@ -29,12 +29,16 @@ minetest.register_node("chest:chest", {
|
||||||
return inv:is_empty("main")
|
return inv:is_empty("main")
|
||||||
end,
|
end,
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow put' event for " .. stack:to_string())
|
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow put' (10) event for " .. stack:to_string())
|
||||||
return stack:get_count()
|
return 10
|
||||||
end,
|
end,
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow take' event for " .. stack:to_string())
|
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow take' (20) event for " .. stack:to_string())
|
||||||
return stack:get_count()
|
return 20
|
||||||
|
end,
|
||||||
|
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
|
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow move' (30) event")
|
||||||
|
return 30
|
||||||
end,
|
end,
|
||||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
print_to_everything("Chest: ".. player:get_player_name() .. " put " .. stack:to_string())
|
print_to_everything("Chest: ".. player:get_player_name() .. " put " .. stack:to_string())
|
||||||
|
@ -42,4 +46,7 @@ minetest.register_node("chest:chest", {
|
||||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
print_to_everything("Chest: ".. player:get_player_name() .. " took " .. stack:to_string())
|
print_to_everything("Chest: ".. player:get_player_name() .. " took " .. stack:to_string())
|
||||||
end,
|
end,
|
||||||
|
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
|
print_to_everything("Chest: ".. player:get_player_name() .. " moved " .. count)
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
local color = minetest.colorize
|
local color = minetest.colorize
|
||||||
|
|
||||||
|
-- \208\176 is a cyrillic small a
|
||||||
|
local unsafe_url = minetest.formspec_escape("https://u:p@wikipedi\208\176.org:1233/heIIoll?a=b#c")
|
||||||
|
|
||||||
local clip_fs = [[
|
local clip_fs = [[
|
||||||
style_type[label,button,image_button,item_image_button,
|
style_type[label,button,image_button,item_image_button,
|
||||||
tabheader,scrollbar,table,animated_image
|
tabheader,scrollbar,table,animated_image
|
||||||
,field,textarea,checkbox,dropdown;noclip=%c]
|
,field,textarea,checkbox,dropdown;noclip=%c]
|
||||||
|
|
||||||
label[0,0;A clipping test]
|
label[0,0;A clipping test]
|
||||||
button[0,1;3,0.8;clip_button;A clipping test]
|
button_url[0,1;3,0.8;clip_button;A clipping test;]] .. unsafe_url .. [[]
|
||||||
image_button[0,2;3,0.8;testformspec_button_image.png;clip_image_button;A clipping test]
|
image_button[0,2;3,0.8;testformspec_button_image.png;clip_image_button;A clipping test]
|
||||||
item_image_button[0,3;3,0.8;testformspec:item;clip_item_image_button;A clipping test]
|
item_image_button[0,3;3,0.8;testformspec:item;clip_item_image_button;A clipping test]
|
||||||
tabheader[0,4.7;3,0.63;clip_tabheader;Clip,Test,Text,Tabs;1;false;false]
|
tabheader[0,4.7;3,0.63;clip_tabheader;Clip,Test,Text,Tabs;1;false;false]
|
||||||
|
@ -92,6 +95,7 @@ This is a normal text.
|
||||||
<t_green>color=green</t_green>
|
<t_green>color=green</t_green>
|
||||||
Action: <action name=color><t_green>color=green</t_green></action>
|
Action: <action name=color><t_green>color=green</t_green></action>
|
||||||
Action: <action name=hovercolor><t_hover>hovercolor=yellow</t_hover></action>
|
Action: <action name=hovercolor><t_hover>hovercolor=yellow</t_hover></action>
|
||||||
|
Action URL: <action name=open url=https://example.com/?a=b#c>open URL</action>
|
||||||
<t_size>size=24</t_size>
|
<t_size>size=24</t_size>
|
||||||
<t_mono>font=mono</t_mono>
|
<t_mono>font=mono</t_mono>
|
||||||
<t_multi>color=green font=mono size=24</t_multi>
|
<t_multi>color=green font=mono size=24</t_multi>
|
||||||
|
@ -145,7 +149,7 @@ local hypertext_fs = "hypertext[0,0;11,9;hypertext;"..minetest.formspec_escape(h
|
||||||
local style_fs = [[
|
local style_fs = [[
|
||||||
style[one_btn1;bgcolor=red;textcolor=yellow;bgcolor_hovered=orange;
|
style[one_btn1;bgcolor=red;textcolor=yellow;bgcolor_hovered=orange;
|
||||||
bgcolor_pressed=purple]
|
bgcolor_pressed=purple]
|
||||||
button[0,0;2.5,0.8;one_btn1;Button]
|
button_url_exit[0,0;2.5,0.8;one_btn1;Button;]] .. unsafe_url .. [[]
|
||||||
|
|
||||||
style[one_btn2;border=false;textcolor=cyan] ]]..
|
style[one_btn2;border=false;textcolor=cyan] ]]..
|
||||||
"button[0,1.05;2.5,0.8;one_btn2;Text " .. color("#FF0", "Yellow") .. [[]
|
"button[0,1.05;2.5,0.8;one_btn2;Text " .. color("#FF0", "Yellow") .. [[]
|
||||||
|
|
|
@ -90,3 +90,18 @@ minetest.register_craftitem("testitems:image_meta", {
|
||||||
return itemstack
|
return itemstack
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("testitems:telescope_stick", {
|
||||||
|
description = S("Telescope Stick (Increases range on use.)"),
|
||||||
|
inventory_image = "testitems_telescope_stick.png",
|
||||||
|
on_use = function(itemstack, player)
|
||||||
|
local meta = itemstack:get_meta()
|
||||||
|
local range = meta:get_float("range") + 1.2
|
||||||
|
if range > 10 then
|
||||||
|
range = 0
|
||||||
|
end
|
||||||
|
meta:set_float("range", range)
|
||||||
|
minetest.chat_send_player(player:get_player_name(), "Telescope Stick range set to "..range)
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 170 B |
|
@ -33,6 +33,25 @@ minetest.register_node("testnodes:anim", {
|
||||||
groups = { dig_immediate = 2 },
|
groups = { dig_immediate = 2 },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_node("testnodes:fill_positioning", {
|
||||||
|
description = S("Fill Modifier Test Node") .. "\n" ..
|
||||||
|
S("The node should have the same look as " ..
|
||||||
|
"testnodes:fill_positioning_reference."),
|
||||||
|
drawtype = "glasslike",
|
||||||
|
paramtype = "light",
|
||||||
|
tiles = {"[fill:16x16:#ffffff^[fill:6x6:1,1:#00ffdc" ..
|
||||||
|
"^[fill:6x6:1,9:#00ffdc^[fill:6x6:9,1:#00ffdc^[fill:6x6:9,9:#00ffdc"},
|
||||||
|
groups = {dig_immediate = 3},
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_node("testnodes:fill_positioning_reference", {
|
||||||
|
description = S("Fill Modifier Test Node Reference"),
|
||||||
|
drawtype = "glasslike",
|
||||||
|
paramtype = "light",
|
||||||
|
tiles = {"testnodes_fill_positioning_reference.png"},
|
||||||
|
groups = {dig_immediate = 3},
|
||||||
|
})
|
||||||
|
|
||||||
-- Node texture transparency test
|
-- Node texture transparency test
|
||||||
|
|
||||||
local alphas = { 64, 128, 191 }
|
local alphas = { 64, 128, 191 }
|
||||||
|
@ -69,6 +88,19 @@ for a=1,#alphas do
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
minetest.register_node("testnodes:alpha_compositing", {
|
||||||
|
description = S("Alpha Compositing Test Node") .. "\n" ..
|
||||||
|
S("A regular grid should be visible where each cell contains two " ..
|
||||||
|
"texels with the same colour.") .. "\n" ..
|
||||||
|
S("Alpha compositing is gamma-incorrect for backwards compatibility."),
|
||||||
|
drawtype = "glasslike",
|
||||||
|
paramtype = "light",
|
||||||
|
tiles = {"testnodes_alpha_compositing_bottom.png^" ..
|
||||||
|
"testnodes_alpha_compositing_top.png"},
|
||||||
|
use_texture_alpha = "blend",
|
||||||
|
groups = {dig_immediate = 3},
|
||||||
|
})
|
||||||
|
|
||||||
-- Generate PNG textures
|
-- Generate PNG textures
|
||||||
|
|
||||||
local function mandelbrot(w, h, iterations)
|
local function mandelbrot(w, h, iterations)
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 251 B |
Binary file not shown.
After Width: | Height: | Size: 160 B |
Binary file not shown.
After Width: | Height: | Size: 92 B |
|
@ -53,7 +53,7 @@ local test_object = {
|
||||||
end,
|
end,
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
light_source = 0,
|
pos = vector.new(-1, -2, -3),
|
||||||
}
|
}
|
||||||
|
|
||||||
local function test_object_passing()
|
local function test_object_passing()
|
||||||
|
@ -166,3 +166,44 @@ local function test_userdata_passing2(cb, _, pos)
|
||||||
end, vm, pos)
|
end, vm, pos)
|
||||||
end
|
end
|
||||||
unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})
|
unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})
|
||||||
|
|
||||||
|
local function test_async_metatable_override()
|
||||||
|
assert(pcall(core.register_async_metatable, "__builtin:vector", vector.metatable),
|
||||||
|
"Metatable name aliasing throws an error when it should be allowed")
|
||||||
|
|
||||||
|
assert(not pcall(core.register_async_metatable, "__builtin:vector", {}),
|
||||||
|
"Illegal metatable overriding allowed")
|
||||||
|
end
|
||||||
|
unittests.register("test_async_metatable_override", test_async_metatable_override)
|
||||||
|
|
||||||
|
local function test_async_metatable_registration(cb)
|
||||||
|
local custom_metatable = {}
|
||||||
|
core.register_async_metatable("unittests:custom_metatable", custom_metatable)
|
||||||
|
|
||||||
|
core.handle_async(function(x)
|
||||||
|
-- unittests.custom_metatable is registered in inside_async_env.lua
|
||||||
|
return getmetatable(x) == unittests.custom_metatable, x
|
||||||
|
end, function(metatable_preserved_async, table_after_roundtrip)
|
||||||
|
if not metatable_preserved_async then
|
||||||
|
return cb("Custom metatable not preserved (main -> async)")
|
||||||
|
end
|
||||||
|
if getmetatable(table_after_roundtrip) ~= custom_metatable then
|
||||||
|
return cb("Custom metable not preserved (after roundtrip)")
|
||||||
|
end
|
||||||
|
cb()
|
||||||
|
end, setmetatable({}, custom_metatable))
|
||||||
|
end
|
||||||
|
unittests.register("test_async_metatable_registration", test_async_metatable_registration, {async=true})
|
||||||
|
|
||||||
|
local function test_vector_preserve(cb)
|
||||||
|
local vec = vector.new(1, 2, 3)
|
||||||
|
core.handle_async(function(x)
|
||||||
|
return x[1]
|
||||||
|
end, function(ret)
|
||||||
|
if ret ~= vec then -- fails if metatable was not preserved
|
||||||
|
return cb("Vector value mismatch")
|
||||||
|
end
|
||||||
|
cb()
|
||||||
|
end, {vec})
|
||||||
|
end
|
||||||
|
unittests.register("test_async_vector", test_vector_preserve, {async=true})
|
||||||
|
|
|
@ -108,9 +108,9 @@ local function wait_for_player(callback)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function wait_for_map(player, callback)
|
local function wait_for_map(pos, callback)
|
||||||
local function check()
|
local function check()
|
||||||
if core.get_node_or_nil(player:get_pos()) ~= nil then
|
if core.get_node(pos).name ~= "ignore" then
|
||||||
callback()
|
callback()
|
||||||
else
|
else
|
||||||
core.after(0, check)
|
core.after(0, check)
|
||||||
|
@ -119,8 +119,8 @@ local function wait_for_map(player, callback)
|
||||||
check()
|
check()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- This runs in a coroutine so it uses await()
|
||||||
function unittests.run_all()
|
function unittests.run_all()
|
||||||
-- This runs in a coroutine so it uses await().
|
|
||||||
local counters = { time = 0, total = 0, passed = 0 }
|
local counters = { time = 0, total = 0, passed = 0 }
|
||||||
|
|
||||||
-- Run standalone tests first
|
-- Run standalone tests first
|
||||||
|
@ -143,10 +143,11 @@ function unittests.run_all()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Wait for the world to generate/load, run tests that require map access
|
-- Wait for the world to generate/load, run tests that require map access
|
||||||
|
local pos = player:get_pos():round():offset(0, 5, 0)
|
||||||
|
core.forceload_block(pos, true, -1)
|
||||||
await(function(cb)
|
await(function(cb)
|
||||||
wait_for_map(player, cb)
|
wait_for_map(pos, cb)
|
||||||
end)
|
end)
|
||||||
local pos = vector.round(player:get_pos())
|
|
||||||
for idx = 1, #unittests.list do
|
for idx = 1, #unittests.list do
|
||||||
local def = unittests.list[idx]
|
local def = unittests.list[idx]
|
||||||
if not def.done then
|
if not def.done then
|
||||||
|
@ -182,6 +183,7 @@ dofile(modpath .. "/get_version.lua")
|
||||||
dofile(modpath .. "/itemstack_equals.lua")
|
dofile(modpath .. "/itemstack_equals.lua")
|
||||||
dofile(modpath .. "/content_ids.lua")
|
dofile(modpath .. "/content_ids.lua")
|
||||||
dofile(modpath .. "/metadata.lua")
|
dofile(modpath .. "/metadata.lua")
|
||||||
|
dofile(modpath .. "/raycast.lua")
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@ unittests = {}
|
||||||
|
|
||||||
core.log("info", "Hello World")
|
core.log("info", "Hello World")
|
||||||
|
|
||||||
|
unittests.custom_metatable = {}
|
||||||
|
core.register_async_metatable("unittests:custom_metatable", unittests.custom_metatable)
|
||||||
|
|
||||||
local function do_tests()
|
local function do_tests()
|
||||||
assert(core == minetest)
|
assert(core == minetest)
|
||||||
-- stuff that should not be here
|
-- stuff that should not be here
|
||||||
|
|
|
@ -99,17 +99,24 @@ local function test_clear_meta(_, pos)
|
||||||
end
|
end
|
||||||
unittests.register("test_clear_meta", test_clear_meta, {map=true})
|
unittests.register("test_clear_meta", test_clear_meta, {map=true})
|
||||||
|
|
||||||
local on_punch_called
|
local on_punch_called, on_place_called
|
||||||
minetest.register_on_punchnode(function()
|
core.register_on_placenode(function()
|
||||||
|
on_place_called = true
|
||||||
|
end)
|
||||||
|
core.register_on_punchnode(function()
|
||||||
on_punch_called = true
|
on_punch_called = true
|
||||||
end)
|
end)
|
||||||
unittests.register("test_punch_node", function(_, pos)
|
local function test_node_callbacks(_, pos)
|
||||||
minetest.place_node(pos, {name="basenodes:dirt"})
|
on_place_called = false
|
||||||
on_punch_called = false
|
on_punch_called = false
|
||||||
minetest.punch_node(pos)
|
|
||||||
minetest.remove_node(pos)
|
core.place_node(pos, {name="basenodes:dirt"})
|
||||||
-- currently failing: assert(on_punch_called)
|
assert(on_place_called, "on_place not called")
|
||||||
end, {map=true})
|
core.punch_node(pos)
|
||||||
|
assert(on_punch_called, "on_punch not called")
|
||||||
|
core.remove_node(pos)
|
||||||
|
end
|
||||||
|
unittests.register("test_node_callbacks", test_node_callbacks, {map=true})
|
||||||
|
|
||||||
local function test_hashing()
|
local function test_hashing()
|
||||||
local input = "hello\000world"
|
local input = "hello\000world"
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
local function raycast_with_pointabilities(start_pos, end_pos, pointabilities)
|
||||||
|
local ray = core.raycast(start_pos, end_pos, nil, nil, pointabilities)
|
||||||
|
for hit in ray do
|
||||||
|
if hit.type == "node" then
|
||||||
|
return hit.under
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function test_raycast_pointabilities(player, pos1)
|
||||||
|
local pos2 = pos1:offset(0, 0, 1)
|
||||||
|
local pos3 = pos1:offset(0, 0, 2)
|
||||||
|
|
||||||
|
local oldnode1 = core.get_node(pos1)
|
||||||
|
local oldnode2 = core.get_node(pos2)
|
||||||
|
local oldnode3 = core.get_node(pos3)
|
||||||
|
core.swap_node(pos1, {name = "air"})
|
||||||
|
core.swap_node(pos2, {name = "testnodes:not_pointable"})
|
||||||
|
core.swap_node(pos3, {name = "testnodes:pointable"})
|
||||||
|
|
||||||
|
local p = nil
|
||||||
|
assert(raycast_with_pointabilities(pos1, pos3, p) == pos3)
|
||||||
|
|
||||||
|
p = core.registered_items["testtools:blocked_pointing_staff"].pointabilities
|
||||||
|
assert(raycast_with_pointabilities(pos1, pos3, p) == nil)
|
||||||
|
|
||||||
|
p = core.registered_items["testtools:ultimate_pointing_staff"].pointabilities
|
||||||
|
assert(raycast_with_pointabilities(pos1, pos3, p) == pos2)
|
||||||
|
|
||||||
|
core.swap_node(pos1, oldnode1)
|
||||||
|
core.swap_node(pos2, oldnode2)
|
||||||
|
core.swap_node(pos3, oldnode3)
|
||||||
|
end
|
||||||
|
|
||||||
|
unittests.register("test_raycast_pointabilities", test_raycast_pointabilities, {map=true})
|
|
@ -0,0 +1,10 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.{cpp,h,txt,cmake,fsh,vsh}]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
|
@ -0,0 +1,310 @@
|
||||||
|
name: build
|
||||||
|
|
||||||
|
# build on c/cpp changes or workflow changes
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
linux-gl:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install g++ cmake libxi-dev libgl1-mesa-dev libpng-dev libjpeg-dev zlib1g-dev -qyy
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DUSE_SDL2=OFF
|
||||||
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
ctest --output-on-failure
|
||||||
|
|
||||||
|
- name: Package
|
||||||
|
run: |
|
||||||
|
make DESTDIR=$PWD/_install install
|
||||||
|
tar -c -I "gzip -9" -f irrlicht-linux.tar.gz -C ./_install/usr/local .
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: irrlicht-linux
|
||||||
|
path: ./irrlicht-linux.tar.gz
|
||||||
|
|
||||||
|
linux-gles:
|
||||||
|
# Xvfb test is broken on 20.04 for unknown reasons (not our bug)
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install g++ cmake libxi-dev libgles2-mesa-dev libpng-dev libjpeg-dev zlib1g-dev xvfb -qyy
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=OFF -DENABLE_OPENGL=OFF -DENABLE_GLES2=ON
|
||||||
|
make -j2
|
||||||
|
|
||||||
|
- name: Test (headless)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
./AutomatedTest null
|
||||||
|
|
||||||
|
- name: Test (Xvfb)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
LIBGL_ALWAYS_SOFTWARE=true xvfb-run ./AutomatedTest ogles2
|
||||||
|
|
||||||
|
linux-sdl:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install g++ cmake libsdl2-dev libpng-dev libjpeg-dev zlib1g-dev -qyy
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
make -j2
|
||||||
|
|
||||||
|
- name: Test (headless)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
./AutomatedTest null
|
||||||
|
|
||||||
|
linux-sdl-gl3:
|
||||||
|
# Xvfb test is broken on 20.04 for unknown reasons (not our bug)
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install g++ cmake libsdl2-dev libpng-dev libjpeg-dev zlib1g-dev xvfb -qyy
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=ON -DENABLE_OPENGL=OFF -DENABLE_OPENGL3=ON
|
||||||
|
make -j2
|
||||||
|
|
||||||
|
- name: Test (headless)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
./AutomatedTest null
|
||||||
|
|
||||||
|
- name: Test (Xvfb)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
LIBGL_ALWAYS_SOFTWARE=true xvfb-run ./AutomatedTest opengl3
|
||||||
|
|
||||||
|
linux-sdl-gles2:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install g++ cmake libsdl2-dev libpng-dev libjpeg-dev zlib1g-dev xvfb -qyy
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=ON -DENABLE_OPENGL=OFF -DENABLE_GLES2=ON
|
||||||
|
make -j2
|
||||||
|
|
||||||
|
- name: Test (headless)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
./AutomatedTest null
|
||||||
|
|
||||||
|
- name: Test (Xvfb)
|
||||||
|
run: |
|
||||||
|
cd bin/Linux
|
||||||
|
LIBGL_ALWAYS_SOFTWARE=true xvfb-run ./AutomatedTest ogles2
|
||||||
|
|
||||||
|
mingw:
|
||||||
|
name: "MinGW ${{matrix.config.variant}}${{matrix.config.extras}}"
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {variant: win32, arch: i686}
|
||||||
|
- {variant: win64, arch: x86_64}
|
||||||
|
- {variant: win32, arch: i686, extras: "-sdl"}
|
||||||
|
- {variant: win64, arch: x86_64, extras: "-sdl"}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install compiler
|
||||||
|
run: |
|
||||||
|
sudo apt-get update && sudo apt-get install cmake -qyy
|
||||||
|
./scripts/ci-get-mingw.sh
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
./scripts/ci-build-mingw.sh package
|
||||||
|
env:
|
||||||
|
CC: ${{matrix.config.arch}}-w64-mingw32-clang
|
||||||
|
CXX: ${{matrix.config.arch}}-w64-mingw32-clang++
|
||||||
|
extras: ${{matrix.config.extras}}
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: irrlicht-${{matrix.config.variant}}${{matrix.config.extras}}
|
||||||
|
path: ./irrlicht-${{matrix.config.variant}}${{matrix.config.extras}}.zip
|
||||||
|
|
||||||
|
macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
brew update --auto-update
|
||||||
|
brew install cmake libpng jpeg
|
||||||
|
env:
|
||||||
|
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
|
||||||
|
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DCMAKE_FIND_FRAMEWORK=LAST -DBUILD_EXAMPLES=1
|
||||||
|
make -j3
|
||||||
|
|
||||||
|
- name: Test (headless)
|
||||||
|
run: |
|
||||||
|
./bin/OSX/AutomatedTest null
|
||||||
|
|
||||||
|
macos-sdl:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
brew update --auto-update
|
||||||
|
brew install cmake libpng jpeg sdl2
|
||||||
|
env:
|
||||||
|
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
|
||||||
|
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cmake . -DCMAKE_FIND_FRAMEWORK=LAST -DBUILD_EXAMPLES=1 -DUSE_SDL2=1
|
||||||
|
make -j3
|
||||||
|
|
||||||
|
msvc:
|
||||||
|
name: VS 2019 ${{ matrix.config.arch }} ${{ matrix.sdl.label }}
|
||||||
|
runs-on: windows-2019
|
||||||
|
env:
|
||||||
|
VCPKG_VERSION: 8eb57355a4ffb410a2e94c07b4dca2dffbee8e50
|
||||||
|
# 2023.10.19
|
||||||
|
vcpkg_packages: zlib libpng libjpeg-turbo
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
-
|
||||||
|
arch: x86
|
||||||
|
generator: "-G'Visual Studio 16 2019' -A Win32"
|
||||||
|
vcpkg_triplet: x86-windows
|
||||||
|
-
|
||||||
|
arch: x64
|
||||||
|
generator: "-G'Visual Studio 16 2019' -A x64"
|
||||||
|
vcpkg_triplet: x64-windows
|
||||||
|
sdl:
|
||||||
|
-
|
||||||
|
use: FALSE
|
||||||
|
label: '(no SDL)'
|
||||||
|
vcpkg_packages: opengl-registry
|
||||||
|
-
|
||||||
|
use: TRUE
|
||||||
|
label: '(with SDL)'
|
||||||
|
vcpkg_packages: sdl2
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Restore from cache and run vcpkg
|
||||||
|
uses: lukka/run-vcpkg@v7
|
||||||
|
with:
|
||||||
|
vcpkgArguments: ${{env.vcpkg_packages}} ${{matrix.sdl.vcpkg_packages}}
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}\vcpkg'
|
||||||
|
appendedCacheKey: ${{ matrix.config.vcpkg_triplet }}
|
||||||
|
vcpkgGitCommitId: ${{ env.VCPKG_VERSION }}
|
||||||
|
vcpkgTriplet: ${{ matrix.config.vcpkg_triplet }}
|
||||||
|
|
||||||
|
- name: CMake
|
||||||
|
run: |
|
||||||
|
cmake ${{matrix.config.generator}} `
|
||||||
|
-DUSE_SDL2=${{matrix.sdl.use}} `
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}\vcpkg\scripts\buildsystems\vcpkg.cmake" `
|
||||||
|
-DCMAKE_BUILD_TYPE=Release .
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build . --config Release
|
||||||
|
|
||||||
|
- name: Create artifact folder
|
||||||
|
run: |
|
||||||
|
mkdir artifact/
|
||||||
|
mkdir artifact/lib/
|
||||||
|
|
||||||
|
- name: Move dlls into artifact folder
|
||||||
|
run: move bin\Win32-VisualStudio\Release\* artifact\lib\
|
||||||
|
|
||||||
|
- name: Move includes into artifact folder
|
||||||
|
run: move include artifact/
|
||||||
|
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: msvc-${{ matrix.config.arch }}-${{matrix.sdl.use}}
|
||||||
|
path: artifact/
|
||||||
|
|
||||||
|
android:
|
||||||
|
name: Android ${{ matrix.arch }}
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
env:
|
||||||
|
ndk_version: "r25c"
|
||||||
|
ANDROID_NDK: ${{ github.workspace }}/android-ndk
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: [armeabi-v7a, arm64-v8a, x86, x86_64]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo rm /var/lib/man-db/auto-update
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -qyy wget unzip zip gcc-multilib make cmake
|
||||||
|
|
||||||
|
- name: Cache NDK
|
||||||
|
id: cache-ndk
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
key: android-ndk-${{ env.ndk_version }}-linux
|
||||||
|
path: ${{ env.ANDROID_NDK }}
|
||||||
|
|
||||||
|
- name: Install NDK
|
||||||
|
run: |
|
||||||
|
wget --progress=bar:force "http://dl.google.com/android/repository/android-ndk-${ndk_version}-linux.zip"
|
||||||
|
unzip -q "android-ndk-${ndk_version}-linux.zip"
|
||||||
|
rm "android-ndk-${ndk_version}-linux.zip"
|
||||||
|
mv "android-ndk-${ndk_version}" "${ANDROID_NDK}"
|
||||||
|
if: ${{ steps.cache-ndk.outputs.cache-hit != 'true' }}
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: ./scripts/ci-build-android.sh ${{ matrix.arch }}
|
||||||
|
|
||||||
|
#- name: Upload Artifact
|
||||||
|
# uses: actions/upload-artifact@v4
|
||||||
|
# with:
|
||||||
|
# name: irrlicht-android-${{ matrix.arch }}
|
||||||
|
# path: ${{ runner.temp }}/pkg/${{ matrix.arch }}
|
|
@ -0,0 +1,25 @@
|
||||||
|
CMakeFiles
|
||||||
|
CMakeCache.txt
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
IrrlichtMtConfig.cmake
|
||||||
|
IrrlichtMtConfigVersion.cmake
|
||||||
|
IrrlichtMtTargets.cmake
|
||||||
|
CTestTestfile.cmake
|
||||||
|
Makefile
|
||||||
|
libs/*
|
||||||
|
*.so*
|
||||||
|
*.a
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
bin/Linux
|
||||||
|
scripts/gl2ext.h
|
||||||
|
scripts/glcorearb.h
|
||||||
|
scripts/glext.h
|
||||||
|
*.vcxproj*
|
||||||
|
*.dir/
|
||||||
|
*.sln
|
||||||
|
*visualstudio/
|
||||||
|
|
||||||
|
# vscode cmake plugin
|
||||||
|
build/*
|
|
@ -0,0 +1,82 @@
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
|
set(IRRLICHTMT_REVISION 15)
|
||||||
|
|
||||||
|
project(Irrlicht
|
||||||
|
VERSION 1.9.0.${IRRLICHTMT_REVISION}
|
||||||
|
LANGUAGES CXX
|
||||||
|
)
|
||||||
|
|
||||||
|
message(STATUS "*** Building IrrlichtMt ${PROJECT_VERSION} ***")
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
set(sysname Android)
|
||||||
|
elseif(APPLE)
|
||||||
|
set(sysname OSX)
|
||||||
|
elseif(MSVC)
|
||||||
|
set(sysname Win32-VisualStudio)
|
||||||
|
elseif(WIN32)
|
||||||
|
set(sysname Win32-gcc)
|
||||||
|
else()
|
||||||
|
set(sysname Linux)
|
||||||
|
endif()
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/${sysname})
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/${sysname})
|
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
enable_testing()
|
||||||
|
add_subdirectory(src)
|
||||||
|
add_subdirectory(test)
|
||||||
|
|
||||||
|
option(BUILD_EXAMPLES "Build example applications" FALSE)
|
||||||
|
if(BUILD_EXAMPLES)
|
||||||
|
add_subdirectory(examples)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Export a file that describes the targets that IrrlichtMt creates.
|
||||||
|
# The file is placed in the location FILE points to, where CMake can easily
|
||||||
|
# locate it by pointing CMAKE_PREFIX_PATH to this project root.
|
||||||
|
export(EXPORT IrrlichtMt-export
|
||||||
|
FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/IrrlichtMtTargets.cmake"
|
||||||
|
NAMESPACE IrrlichtMt::
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation of headers.
|
||||||
|
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/irrlichtmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Installation of CMake target and configuration files.
|
||||||
|
install(EXPORT IrrlichtMt-export
|
||||||
|
FILE IrrlichtMtTargets.cmake
|
||||||
|
NAMESPACE IrrlichtMt::
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/IrrlichtMt"
|
||||||
|
)
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
configure_package_config_file("${PROJECT_SOURCE_DIR}/Config.cmake.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake/IrrlichtMtConfig.cmake"
|
||||||
|
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/IrrlichtMt"
|
||||||
|
NO_SET_AND_CHECK_MACRO
|
||||||
|
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||||
|
)
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake/IrrlichtMtConfigVersion.cmake"
|
||||||
|
COMPATIBILITY AnyNewerVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake/IrrlichtMtConfig.cmake"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake/IrrlichtMtConfigVersion.cmake"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/IrrlichtMt"
|
||||||
|
)
|
|
@ -0,0 +1,11 @@
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
|
||||||
|
if(NOT TARGET IrrlichtMt::IrrlichtMt)
|
||||||
|
# private dependency only explicitly needed with static libs
|
||||||
|
if(@USE_SDL2@ AND NOT @BUILD_SHARED_LIBS@)
|
||||||
|
find_dependency(SDL2)
|
||||||
|
endif()
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/IrrlichtMtTargets.cmake")
|
||||||
|
endif()
|
|
@ -0,0 +1,26 @@
|
||||||
|
Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
Please note that the Irrlicht Engine is based in part on the work of the
|
||||||
|
Independent JPEG Group, the zlib, libPng and aesGladman. This means that if you use
|
||||||
|
the Irrlicht Engine in your product, you must acknowledge somewhere in your
|
||||||
|
documentation that you've used the IJPG code. It would also be nice to mention
|
||||||
|
that you use the Irrlicht Engine, the zlib, libPng and aesGladman. See the
|
||||||
|
corresponding license files for further informations. It is also possible to disable
|
||||||
|
usage of those additional libraries by defines in the IrrCompileConfig.h header and
|
||||||
|
recompiling the engine.
|
|
@ -0,0 +1,88 @@
|
||||||
|
IrrlichtMt version 1.9
|
||||||
|
======================
|
||||||
|
|
||||||
|
IrrlichtMt is the 3D engine of [Minetest](https://github.com/minetest).
|
||||||
|
It is based on the [Irrlicht Engine](https://irrlicht.sourceforge.io/) but is now developed independently.
|
||||||
|
It is intentionally not compatible to upstream and is planned to be eventually absorbed into Minetest.
|
||||||
|
|
||||||
|
Build
|
||||||
|
-----
|
||||||
|
|
||||||
|
The build system is CMake.
|
||||||
|
|
||||||
|
The following libraries are required to be installed:
|
||||||
|
* zlib, libPNG, libJPEG
|
||||||
|
* OpenGL
|
||||||
|
* or on mobile: OpenGL ES (can be optionally enabled on desktop too)
|
||||||
|
* on Unix: X11
|
||||||
|
* SDL2 (see below)
|
||||||
|
|
||||||
|
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
|
||||||
|
* `BUILD_SHARED_LIBS` (default: `ON`) - Build IrrlichtMt as a shared library
|
||||||
|
* `BUILD_EXAMPLES` (default: `OFF`) - Build example applications
|
||||||
|
* `ENABLE_OPENGL` - Enable OpenGL driver
|
||||||
|
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
|
||||||
|
* `ENABLE_GLES1` - Enable OpenGL ES driver, legacy
|
||||||
|
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
|
||||||
|
* `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
|
||||||
|
|
||||||
|
e.g. on a Linux system you might want to build for local use like this:
|
||||||
|
|
||||||
|
git clone https://github.com/minetest/irrlicht
|
||||||
|
cd irrlicht
|
||||||
|
cmake . -DBUILD_SHARED_LIBS=OFF
|
||||||
|
make -j$(nproc)
|
||||||
|
|
||||||
|
This will put an IrrlichtMtTargets.cmake file into the cmake directory in the current build directory, and it can then be imported from another project by pointing `find_package()` to the build directory, or by setting the `CMAKE_PREFIX_PATH` variable to that same path.
|
||||||
|
|
||||||
|
on Windows system:
|
||||||
|
|
||||||
|
It is highly recommended to use vcpkg as package manager.
|
||||||
|
|
||||||
|
After you successfully built vcpkg you can easily install the required libraries:
|
||||||
|
|
||||||
|
vcpkg install zlib libjpeg-turbo libpng sdl2 --triplet x64-windows
|
||||||
|
|
||||||
|
Run the following script in PowerShell:
|
||||||
|
|
||||||
|
git clone https://github.com/minetest/irrlicht
|
||||||
|
cd irrlicht
|
||||||
|
cmake -B build -G "Visual Studio 17 2022" -A "Win64" -DCMAKE_TOOLCHAIN_FILE=[vcpkg-root]/scripts/buildsystems/vcpkg.cmake -DBUILD_SHARED_LIBS=OFF
|
||||||
|
cmake --build build --config Release
|
||||||
|
|
||||||
|
Platforms
|
||||||
|
---------
|
||||||
|
|
||||||
|
We aim to support these platforms:
|
||||||
|
* Windows via MinGW
|
||||||
|
* Linux (GL or GLES)
|
||||||
|
* macOS
|
||||||
|
* Android
|
||||||
|
|
||||||
|
This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
The license of the Irrlicht Engine is based on the zlib/libpng license and applies to this fork, too.
|
||||||
|
|
||||||
|
The Irrlicht Engine License
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgement in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be clearly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
|
@ -0,0 +1,38 @@
|
||||||
|
#-------------------------------------------------------------------
|
||||||
|
# The contents of this file are placed in the public domain. Feel
|
||||||
|
# free to make use of it in any way you like.
|
||||||
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Try to find OpenGL ES 2 and EGL
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
find_path(OPENGLES2_INCLUDE_DIR GLES2/gl2.h)
|
||||||
|
find_library(OPENGLES2_LIBRARY libGLESv2)
|
||||||
|
elseif(APPLE)
|
||||||
|
find_library(OPENGLES2_LIBRARY OpenGLES REQUIRED) # framework
|
||||||
|
else()
|
||||||
|
# Unix
|
||||||
|
find_path(OPENGLES2_INCLUDE_DIR GLES2/gl2.h
|
||||||
|
PATHS /usr/X11R6/include /usr/include
|
||||||
|
)
|
||||||
|
find_library(OPENGLES2_LIBRARY
|
||||||
|
NAMES GLESv2
|
||||||
|
PATHS /usr/X11R6/lib /usr/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR)
|
||||||
|
|
||||||
|
find_path(EGL_INCLUDE_DIR EGL/egl.h
|
||||||
|
PATHS /usr/X11R6/include /usr/include
|
||||||
|
)
|
||||||
|
find_library(EGL_LIBRARY
|
||||||
|
NAMES EGL
|
||||||
|
PATHS /usr/X11R6/lib /usr/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(EGL REQUIRED_VARS EGL_LIBRARY EGL_INCLUDE_DIR NAME_MISMATCHED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(OPENGLES2_LIBRARIES ${OPENGLES2_LIBRARY} ${EGL_LIBRARY})
|
|
@ -0,0 +1,154 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <irrlicht.h>
|
||||||
|
#include "exampleHelper.h"
|
||||||
|
|
||||||
|
using namespace irr;
|
||||||
|
|
||||||
|
static IrrlichtDevice *device = nullptr;
|
||||||
|
static int test_fail = 0;
|
||||||
|
|
||||||
|
void test_irr_array();
|
||||||
|
void test_irr_string();
|
||||||
|
|
||||||
|
static video::E_DRIVER_TYPE chooseDriver(core::stringc arg_)
|
||||||
|
{
|
||||||
|
if (arg_ == "null")
|
||||||
|
return video::EDT_NULL;
|
||||||
|
if (arg_ == "ogles1")
|
||||||
|
return video::EDT_OGLES1;
|
||||||
|
if (arg_ == "ogles2")
|
||||||
|
return video::EDT_OGLES2;
|
||||||
|
if (arg_ == "opengl")
|
||||||
|
return video::EDT_OPENGL;
|
||||||
|
if (arg_ == "opengl3")
|
||||||
|
return video::EDT_OPENGL3;
|
||||||
|
std::cerr << "Unknown driver type: " << arg_.c_str() << ". Trying OpenGL." << std::endl;
|
||||||
|
return video::EDT_OPENGL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void check(bool ok, const char *msg)
|
||||||
|
{
|
||||||
|
if (!ok) {
|
||||||
|
test_fail++;
|
||||||
|
device->getLogger()->log((core::stringc("FAILED TEST: ") + msg).c_str(), ELL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_unit_tests()
|
||||||
|
{
|
||||||
|
std::cout << "Running unit tests:" << std::endl;
|
||||||
|
try {
|
||||||
|
test_irr_array();
|
||||||
|
test_irr_string();
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
test_fail++;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
run_unit_tests();
|
||||||
|
|
||||||
|
SIrrlichtCreationParameters p;
|
||||||
|
p.DriverType = chooseDriver(argc > 1 ? argv[1] : "");
|
||||||
|
p.WindowSize = core::dimension2du(640, 480);
|
||||||
|
p.Vsync = true;
|
||||||
|
p.LoggingLevel = ELL_DEBUG;
|
||||||
|
|
||||||
|
device = createDeviceEx(p);
|
||||||
|
if (!device)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
u32 total = 0;
|
||||||
|
device->getOSOperator()->getSystemMemory(&total, nullptr);
|
||||||
|
core::stringc message = core::stringc("Total RAM in MiB: ") + core::stringc(total >> 10);
|
||||||
|
device->getLogger()->log(message.c_str(), ELL_INFORMATION);
|
||||||
|
check(total > 130 * 1024, "RAM amount");
|
||||||
|
}
|
||||||
|
|
||||||
|
device->setWindowCaption(L"Hello World!");
|
||||||
|
device->setResizable(true);
|
||||||
|
|
||||||
|
video::IVideoDriver *driver = device->getVideoDriver();
|
||||||
|
scene::ISceneManager *smgr = device->getSceneManager();
|
||||||
|
gui::IGUIEnvironment *guienv = device->getGUIEnvironment();
|
||||||
|
|
||||||
|
guienv->addStaticText(L"sample text", core::rect<s32>(10, 10, 110, 22), false);
|
||||||
|
|
||||||
|
gui::IGUIButton *button = guienv->addButton(
|
||||||
|
core::rect<s32>(10, 30, 110, 30 + 32), 0, -1, L"sample button",
|
||||||
|
L"sample tooltip");
|
||||||
|
|
||||||
|
gui::IGUIEditBox *editbox = guienv->addEditBox(L"",
|
||||||
|
core::rect<s32>(10, 70, 60, 70 + 16));
|
||||||
|
|
||||||
|
const io::path mediaPath = getExampleMediaPath();
|
||||||
|
|
||||||
|
auto mesh_file = device->getFileSystem()->createAndOpenFile(mediaPath + "coolguy_opt.x");
|
||||||
|
check(mesh_file, "mesh file loading");
|
||||||
|
scene::IAnimatedMesh *mesh = smgr->getMesh(mesh_file);
|
||||||
|
check(mesh, "mesh loading");
|
||||||
|
if (mesh_file)
|
||||||
|
mesh_file->drop();
|
||||||
|
if (mesh) {
|
||||||
|
video::ITexture *tex = driver->getTexture(mediaPath + "cooltexture.png");
|
||||||
|
check(tex, "texture loading");
|
||||||
|
scene::IAnimatedMeshSceneNode *node = smgr->addAnimatedMeshSceneNode(mesh);
|
||||||
|
if (node) {
|
||||||
|
node->forEachMaterial([tex](video::SMaterial &mat) {
|
||||||
|
mat.Lighting = false;
|
||||||
|
mat.setTexture(0, tex);
|
||||||
|
});
|
||||||
|
node->setFrameLoop(0, 29);
|
||||||
|
node->setAnimationSpeed(30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
smgr->addCameraSceneNode(0, core::vector3df(0, 4, 5), core::vector3df(0, 2, 0));
|
||||||
|
|
||||||
|
s32 n = 0;
|
||||||
|
SEvent event;
|
||||||
|
device->getTimer()->start();
|
||||||
|
|
||||||
|
while (device->run()) {
|
||||||
|
if (device->getTimer()->getTime() >= 1000) {
|
||||||
|
device->getTimer()->setTime(0);
|
||||||
|
++n;
|
||||||
|
if (n == 1) { // Tooltip display
|
||||||
|
bzero(&event, sizeof(SEvent));
|
||||||
|
event.EventType = irr::EET_MOUSE_INPUT_EVENT;
|
||||||
|
event.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
|
||||||
|
event.MouseInput.X = button->getAbsolutePosition().getCenter().X;
|
||||||
|
event.MouseInput.Y = button->getAbsolutePosition().getCenter().Y;
|
||||||
|
device->postEventFromUser(event);
|
||||||
|
} else if (n == 2) // Text input focus
|
||||||
|
guienv->setFocus(editbox);
|
||||||
|
else if (n == 3) { // Keypress for Text input
|
||||||
|
bzero(&event, sizeof(SEvent));
|
||||||
|
event.EventType = irr::EET_KEY_INPUT_EVENT;
|
||||||
|
event.KeyInput.Char = L'a';
|
||||||
|
event.KeyInput.Key = KEY_KEY_A;
|
||||||
|
event.KeyInput.PressedDown = true;
|
||||||
|
device->postEventFromUser(event);
|
||||||
|
event.KeyInput.PressedDown = false;
|
||||||
|
device->postEventFromUser(event);
|
||||||
|
} else
|
||||||
|
device->closeDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH,
|
||||||
|
video::SColor(255, 100, 100, 150));
|
||||||
|
smgr->drawAll();
|
||||||
|
guienv->drawAll();
|
||||||
|
driver->endScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
check(core::stringw(L"a") == editbox->getText(), "EditBox text");
|
||||||
|
|
||||||
|
device->getLogger()->log("Done.", ELL_INFORMATION);
|
||||||
|
device->drop();
|
||||||
|
return test_fail > 0 ? 1 : 0;
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include <irrArray.h>
|
||||||
|
#include "test_helper.h"
|
||||||
|
|
||||||
|
using namespace irr;
|
||||||
|
using core::array;
|
||||||
|
|
||||||
|
static void test_basics()
|
||||||
|
{
|
||||||
|
array<int> v;
|
||||||
|
v.push_back(1); // 1
|
||||||
|
v.push_front(2); // 2, 1
|
||||||
|
v.insert(4, 0); // 4, 2, 1
|
||||||
|
v.insert(3, 1); // 4, 3, 2, 1
|
||||||
|
v.insert(0, 4); // 4, 3, 2, 1, 0
|
||||||
|
UASSERTEQ(v.size(), 5);
|
||||||
|
UASSERTEQ(v[0], 4);
|
||||||
|
UASSERTEQ(v[1], 3);
|
||||||
|
UASSERTEQ(v[2], 2);
|
||||||
|
UASSERTEQ(v[3], 1);
|
||||||
|
UASSERTEQ(v[4], 0);
|
||||||
|
array<int> w = v;
|
||||||
|
UASSERTEQ(w.size(), 5);
|
||||||
|
UASSERT(w == v);
|
||||||
|
w.clear();
|
||||||
|
UASSERTEQ(w.size(), 0);
|
||||||
|
UASSERTEQ(w.allocated_size(), 0);
|
||||||
|
UASSERT(w.empty());
|
||||||
|
w = v;
|
||||||
|
UASSERTEQ(w.size(), 5);
|
||||||
|
w.set_used(3);
|
||||||
|
UASSERTEQ(w.size(), 3);
|
||||||
|
UASSERTEQ(w[0], 4);
|
||||||
|
UASSERTEQ(w[1], 3);
|
||||||
|
UASSERTEQ(w[2], 2);
|
||||||
|
UASSERTEQ(w.getLast(), 2);
|
||||||
|
w.set_used(20);
|
||||||
|
UASSERTEQ(w.size(), 20);
|
||||||
|
w = v;
|
||||||
|
w.sort();
|
||||||
|
UASSERTEQ(w.size(), 5);
|
||||||
|
UASSERTEQ(w[0], 0);
|
||||||
|
UASSERTEQ(w[1], 1);
|
||||||
|
UASSERTEQ(w[2], 2);
|
||||||
|
UASSERTEQ(w[3], 3);
|
||||||
|
UASSERTEQ(w[4], 4);
|
||||||
|
w.erase(0);
|
||||||
|
UASSERTEQ(w.size(), 4);
|
||||||
|
UASSERTEQ(w[0], 1);
|
||||||
|
UASSERTEQ(w[1], 2);
|
||||||
|
UASSERTEQ(w[2], 3);
|
||||||
|
UASSERTEQ(w[3], 4);
|
||||||
|
w.erase(1, 2);
|
||||||
|
UASSERTEQ(w.size(), 2);
|
||||||
|
UASSERTEQ(w[0], 1);
|
||||||
|
UASSERTEQ(w[1], 4);
|
||||||
|
w.swap(v);
|
||||||
|
UASSERTEQ(w.size(), 5);
|
||||||
|
UASSERTEQ(v.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_linear_searches()
|
||||||
|
{
|
||||||
|
// Populate the array with 0, 1, 2, ..., 100, 100, 99, 98, 97, ..., 0
|
||||||
|
array<int> arr;
|
||||||
|
for (int i = 0; i <= 100; i++)
|
||||||
|
arr.push_back(i);
|
||||||
|
for (int i = 100; i >= 0; i--)
|
||||||
|
arr.push_back(i);
|
||||||
|
s32 end = arr.size() - 1;
|
||||||
|
for (int i = 0; i <= 100; i++) {
|
||||||
|
s32 index = arr.linear_reverse_search(i);
|
||||||
|
UASSERTEQ(index, end - i);
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= 100; i++) {
|
||||||
|
s32 index = arr.linear_search(i);
|
||||||
|
UASSERTEQ(index, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_binary_searches()
|
||||||
|
{
|
||||||
|
const auto &values = {3, 5, 1, 2, 5, 10, 19, 9, 7, 1, 2, 5, 8, 15};
|
||||||
|
array<int> arr;
|
||||||
|
for (int value : values) {
|
||||||
|
arr.push_back(value);
|
||||||
|
}
|
||||||
|
// Test the const form first, it uses a linear search without sorting
|
||||||
|
const array<int> &carr = arr;
|
||||||
|
UASSERTEQ(carr.binary_search(20), -1);
|
||||||
|
UASSERTEQ(carr.binary_search(0), -1);
|
||||||
|
UASSERTEQ(carr.binary_search(1), 2);
|
||||||
|
|
||||||
|
// Sorted: 1, 1, 2, 2, 3, 5, 5, 5, 7, 8, 9, 10, 15, 19
|
||||||
|
UASSERTEQ(arr.binary_search(20), -1);
|
||||||
|
UASSERTEQ(arr.binary_search(0), -1);
|
||||||
|
|
||||||
|
for (int value : values) {
|
||||||
|
s32 i = arr.binary_search(value);
|
||||||
|
UASSERTNE(i, -1);
|
||||||
|
UASSERTEQ(arr[i], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 first, last;
|
||||||
|
first = arr.binary_search_multi(1, last);
|
||||||
|
UASSERTEQ(first, 0);
|
||||||
|
UASSERTEQ(last, 1);
|
||||||
|
|
||||||
|
first = arr.binary_search_multi(2, last);
|
||||||
|
UASSERTEQ(first, 2);
|
||||||
|
UASSERTEQ(last, 3);
|
||||||
|
|
||||||
|
first = arr.binary_search_multi(3, last);
|
||||||
|
UASSERTEQ(first, 4);
|
||||||
|
UASSERTEQ(last, 4);
|
||||||
|
|
||||||
|
first = arr.binary_search_multi(4, last);
|
||||||
|
UASSERTEQ(first, -1);
|
||||||
|
|
||||||
|
first = arr.binary_search_multi(5, last);
|
||||||
|
UASSERTEQ(first, 5);
|
||||||
|
UASSERTEQ(last, 7);
|
||||||
|
|
||||||
|
first = arr.binary_search_multi(7, last);
|
||||||
|
UASSERTEQ(first, 8);
|
||||||
|
UASSERTEQ(last, 8);
|
||||||
|
|
||||||
|
first = arr.binary_search_multi(19, last);
|
||||||
|
UASSERTEQ(first, 13);
|
||||||
|
UASSERTEQ(last, 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_irr_array()
|
||||||
|
{
|
||||||
|
test_basics();
|
||||||
|
test_linear_searches();
|
||||||
|
test_binary_searches();
|
||||||
|
std::cout << " test_irr_array PASSED" << std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class TestFailedException : public std::exception
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Asserts the comparison specified by CMP is true, or fails the current unit test
|
||||||
|
#define UASSERTCMP(CMP, actual, expected) \
|
||||||
|
do { \
|
||||||
|
const auto &a = (actual); \
|
||||||
|
const auto &e = (expected); \
|
||||||
|
if (!CMP(a, e)) { \
|
||||||
|
std::cout \
|
||||||
|
<< "Test assertion failed: " << #actual << " " << #CMP << " " \
|
||||||
|
<< #expected << std::endl \
|
||||||
|
<< " at " << __FILE__ << ":" << __LINE__ << std::endl \
|
||||||
|
<< " actual: " << a << std::endl \
|
||||||
|
<< " expected: " \
|
||||||
|
<< e << std::endl; \
|
||||||
|
throw TestFailedException(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CMPEQ(a, e) (a == e)
|
||||||
|
#define CMPTRUE(a, e) (a)
|
||||||
|
#define CMPNE(a, e) (a != e)
|
||||||
|
|
||||||
|
#define UASSERTEQ(actual, expected) UASSERTCMP(CMPEQ, actual, expected)
|
||||||
|
#define UASSERTNE(actual, nexpected) UASSERTCMP(CMPNE, actual, nexpected)
|
||||||
|
#define UASSERT(actual) UASSERTCMP(CMPTRUE, actual, true)
|
|
@ -0,0 +1,205 @@
|
||||||
|
#include <irrString.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <clocale>
|
||||||
|
#include <vector>
|
||||||
|
#include "test_helper.h"
|
||||||
|
|
||||||
|
using namespace irr;
|
||||||
|
using namespace irr::core;
|
||||||
|
|
||||||
|
#define CMPSTR(a, b) (!strcmp(a, b))
|
||||||
|
#define UASSERTSTR(actual, expected) UASSERTCMP(CMPSTR, actual.c_str(), expected)
|
||||||
|
|
||||||
|
static void test_basics()
|
||||||
|
{
|
||||||
|
// ctor
|
||||||
|
stringc s;
|
||||||
|
UASSERTEQ(s.c_str()[0], '\0');
|
||||||
|
s = stringc(0.1234567);
|
||||||
|
UASSERTSTR(s, "0.123457");
|
||||||
|
s = stringc(0x1p+53);
|
||||||
|
UASSERTSTR(s, "9007199254740992.000000");
|
||||||
|
s = stringc(static_cast<int>(-102400));
|
||||||
|
UASSERTSTR(s, "-102400");
|
||||||
|
s = stringc(static_cast<unsigned int>(102400));
|
||||||
|
UASSERTSTR(s, "102400");
|
||||||
|
s = stringc(static_cast<long>(-1024000));
|
||||||
|
UASSERTSTR(s, "-1024000");
|
||||||
|
s = stringc(static_cast<unsigned long>(1024000));
|
||||||
|
UASSERTSTR(s, "1024000");
|
||||||
|
s = stringc("YESno", 3);
|
||||||
|
UASSERTSTR(s, "YES");
|
||||||
|
s = stringc(L"test", 4);
|
||||||
|
UASSERTSTR(s, "test");
|
||||||
|
s = stringc("Hello World!");
|
||||||
|
UASSERTSTR(s, "Hello World!");
|
||||||
|
// operator=
|
||||||
|
s = stringw(L"abcdef");
|
||||||
|
UASSERTSTR(s, "abcdef");
|
||||||
|
s = L"abcdef";
|
||||||
|
UASSERTSTR(s, "abcdef");
|
||||||
|
s = static_cast<const char *>(nullptr);
|
||||||
|
UASSERTSTR(s, "");
|
||||||
|
// operator+
|
||||||
|
s = s + stringc("foo");
|
||||||
|
UASSERTSTR(s, "foo");
|
||||||
|
s = s + L"bar";
|
||||||
|
UASSERTSTR(s, "foobar");
|
||||||
|
// the rest
|
||||||
|
s = "f";
|
||||||
|
UASSERTEQ(s[0], 'f');
|
||||||
|
const auto &sref = s;
|
||||||
|
UASSERTEQ(sref[0], 'f');
|
||||||
|
UASSERT(sref == "f");
|
||||||
|
UASSERT(sref == stringc("f"));
|
||||||
|
s = "a";
|
||||||
|
UASSERT(sref < stringc("aa"));
|
||||||
|
UASSERT(sref < stringc("b"));
|
||||||
|
UASSERT(stringc("Z") < sref);
|
||||||
|
UASSERT(!(sref < stringc("a")));
|
||||||
|
UASSERT(sref.lower_ignore_case("AA"));
|
||||||
|
UASSERT(sref.lower_ignore_case("B"));
|
||||||
|
UASSERT(!sref.lower_ignore_case("A"));
|
||||||
|
s = "dog";
|
||||||
|
UASSERT(sref != "cat");
|
||||||
|
UASSERT(sref != stringc("cat"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_methods()
|
||||||
|
{
|
||||||
|
stringc s;
|
||||||
|
const auto &sref = s;
|
||||||
|
s = "irrlicht";
|
||||||
|
UASSERTEQ(sref.size(), 8);
|
||||||
|
UASSERT(!sref.empty());
|
||||||
|
s.clear();
|
||||||
|
UASSERTEQ(sref.size(), 0);
|
||||||
|
UASSERT(sref.empty());
|
||||||
|
UASSERT(sref[0] == 0);
|
||||||
|
s = "\tAz#`";
|
||||||
|
s.make_lower();
|
||||||
|
UASSERTSTR(s, "\taz#`");
|
||||||
|
s.make_upper();
|
||||||
|
UASSERTSTR(s, "\tAZ#`");
|
||||||
|
UASSERT(sref.equals_ignore_case("\taz#`"));
|
||||||
|
UASSERT(sref.equals_substring_ignore_case("Z#`", 2));
|
||||||
|
s = "irrlicht";
|
||||||
|
UASSERT(sref.equalsn(stringc("irr"), 3));
|
||||||
|
UASSERT(sref.equalsn("irr", 3));
|
||||||
|
s = "fo";
|
||||||
|
s.append('o');
|
||||||
|
UASSERTSTR(s, "foo");
|
||||||
|
s.append("bar", 1);
|
||||||
|
UASSERTSTR(s, "foob");
|
||||||
|
s.append("ar", 999999);
|
||||||
|
UASSERTSTR(s, "foobar");
|
||||||
|
s = "nyan";
|
||||||
|
s.append(stringc("cat"));
|
||||||
|
UASSERTSTR(s, "nyancat");
|
||||||
|
s.append(stringc("sam"), 1);
|
||||||
|
UASSERTSTR(s, "nyancats");
|
||||||
|
s = "fbar";
|
||||||
|
s.insert(1, "ooXX", 2);
|
||||||
|
UASSERTSTR(s, "foobar");
|
||||||
|
UASSERTEQ(sref.findFirst('o'), 1);
|
||||||
|
UASSERTEQ(sref.findFirst('X'), -1);
|
||||||
|
UASSERTEQ(sref.findFirstChar("abff", 2), 3);
|
||||||
|
UASSERTEQ(sref.findFirstCharNotInList("fobb", 2), 3);
|
||||||
|
UASSERTEQ(sref.findLast('o'), 2);
|
||||||
|
UASSERTEQ(sref.findLast('X'), -1);
|
||||||
|
UASSERTEQ(sref.findLastChar("abrr", 2), 4);
|
||||||
|
UASSERTEQ(sref.findLastCharNotInList("rabb", 2), 3);
|
||||||
|
UASSERTEQ(sref.findNext('o', 2), 2);
|
||||||
|
UASSERTEQ(sref.findLast('o', 1), 1);
|
||||||
|
s = "ob-oob";
|
||||||
|
UASSERTEQ(sref.find("ob", 1), 4);
|
||||||
|
UASSERTEQ(sref.find("ob"), 0);
|
||||||
|
UASSERTEQ(sref.find("?"), -1);
|
||||||
|
s = "HOMEOWNER";
|
||||||
|
stringc s2 = sref.subString(2, 4);
|
||||||
|
UASSERTSTR(s2, "MEOW");
|
||||||
|
s2 = sref.subString(2, 4, true);
|
||||||
|
UASSERTSTR(s2, "meow");
|
||||||
|
s = "land";
|
||||||
|
s.replace('l', 's');
|
||||||
|
UASSERTSTR(s, "sand");
|
||||||
|
s = ">dog<";
|
||||||
|
s.replace("dog", "cat");
|
||||||
|
UASSERTSTR(s, ">cat<");
|
||||||
|
s.replace("cat", "horse");
|
||||||
|
UASSERTSTR(s, ">horse<");
|
||||||
|
s.replace("horse", "gnu");
|
||||||
|
UASSERTSTR(s, ">gnu<");
|
||||||
|
s = " h e l p ";
|
||||||
|
s.remove(' ');
|
||||||
|
UASSERTSTR(s, "help");
|
||||||
|
s.remove("el");
|
||||||
|
UASSERTSTR(s, "hp");
|
||||||
|
s = "irrlicht";
|
||||||
|
s.removeChars("it");
|
||||||
|
UASSERTSTR(s, "rrlch");
|
||||||
|
s = "\r\nfoo bar ";
|
||||||
|
s.trim();
|
||||||
|
UASSERTSTR(s, "foo bar");
|
||||||
|
s = "foxo";
|
||||||
|
s.erase(2);
|
||||||
|
UASSERTSTR(s, "foo");
|
||||||
|
s = "a";
|
||||||
|
s.append('\0');
|
||||||
|
s.append('b');
|
||||||
|
UASSERTEQ(s.size(), 3);
|
||||||
|
s.validate();
|
||||||
|
UASSERTEQ(s.size(), 1);
|
||||||
|
UASSERTEQ(s.lastChar(), 'a');
|
||||||
|
std::vector<stringc> res;
|
||||||
|
s = "a,,b,c";
|
||||||
|
s.split(res, ",aa", 1, true, false);
|
||||||
|
UASSERTEQ(res.size(), 3);
|
||||||
|
UASSERTSTR(res[0], "a");
|
||||||
|
UASSERTSTR(res[2], "c");
|
||||||
|
res.clear();
|
||||||
|
s.split(res, ",", 1, false, true);
|
||||||
|
UASSERTEQ(res.size(), 7);
|
||||||
|
UASSERTSTR(res[0], "a");
|
||||||
|
UASSERTSTR(res[2], "");
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
UASSERTSTR(res[2 * i + 1], ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_conv()
|
||||||
|
{
|
||||||
|
// locale-independent
|
||||||
|
|
||||||
|
stringw out;
|
||||||
|
utf8ToWString(out, "†††");
|
||||||
|
UASSERTEQ(out.size(), 3);
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
UASSERTEQ(static_cast<u16>(out[i]), 0x2020);
|
||||||
|
|
||||||
|
stringc out2;
|
||||||
|
wStringToUTF8(out2, L"†††");
|
||||||
|
UASSERTEQ(out2.size(), 9);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
UASSERTEQ(static_cast<u8>(out2[3 * i]), 0xe2);
|
||||||
|
UASSERTEQ(static_cast<u8>(out2[3 * i + 1]), 0x80);
|
||||||
|
UASSERTEQ(static_cast<u8>(out2[3 * i + 2]), 0xa0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// locale-dependent
|
||||||
|
if (!setlocale(LC_CTYPE, "C.UTF-8"))
|
||||||
|
setlocale(LC_CTYPE, "UTF-8"); // macOS
|
||||||
|
|
||||||
|
stringw out3;
|
||||||
|
multibyteToWString(out3, "†††");
|
||||||
|
UASSERTEQ(out3.size(), 3);
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
UASSERTEQ(static_cast<u16>(out3[i]), 0x2020);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_irr_string()
|
||||||
|
{
|
||||||
|
test_basics();
|
||||||
|
test_methods();
|
||||||
|
test_conv();
|
||||||
|
std::cout << " test_irr_string PASSED" << std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
set(IRREXAMPLES
|
||||||
|
# removed
|
||||||
|
)
|
||||||
|
if(UNIX)
|
||||||
|
list(APPEND IRREXAMPLES AutomatedTest)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(exname IN ITEMS ${IRREXAMPLES})
|
||||||
|
file(GLOB sources "${CMAKE_CURRENT_SOURCE_DIR}/${exname}/*.cpp")
|
||||||
|
add_executable(${exname} ${sources})
|
||||||
|
|
||||||
|
target_include_directories(${exname} PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/include
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${exname}
|
||||||
|
)
|
||||||
|
target_link_libraries(${exname} IrrlichtMt)
|
||||||
|
endforeach()
|
|
@ -0,0 +1,274 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrArray.h"
|
||||||
|
#include "IMeshBuffer.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
//! Template implementation of the IMeshBuffer interface
|
||||||
|
template <class T>
|
||||||
|
class CMeshBuffer : public IMeshBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Default constructor for empty meshbuffer
|
||||||
|
CMeshBuffer() :
|
||||||
|
ChangedID_Vertex(1), ChangedID_Index(1), MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER), HWBuffer(NULL), PrimitiveType(EPT_TRIANGLES)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
setDebugName("CMeshBuffer");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get material of this meshbuffer
|
||||||
|
/** \return Material of this buffer */
|
||||||
|
const video::SMaterial &getMaterial() const override
|
||||||
|
{
|
||||||
|
return Material;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get material of this meshbuffer
|
||||||
|
/** \return Material of this buffer */
|
||||||
|
video::SMaterial &getMaterial() override
|
||||||
|
{
|
||||||
|
return Material;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get pointer to vertices
|
||||||
|
/** \return Pointer to vertices. */
|
||||||
|
const void *getVertices() const override
|
||||||
|
{
|
||||||
|
return Vertices.const_pointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get pointer to vertices
|
||||||
|
/** \return Pointer to vertices. */
|
||||||
|
void *getVertices() override
|
||||||
|
{
|
||||||
|
return Vertices.pointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get number of vertices
|
||||||
|
/** \return Number of vertices. */
|
||||||
|
u32 getVertexCount() const override
|
||||||
|
{
|
||||||
|
return Vertices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get type of index data which is stored in this meshbuffer.
|
||||||
|
/** \return Index type of this buffer. */
|
||||||
|
video::E_INDEX_TYPE getIndexType() const override
|
||||||
|
{
|
||||||
|
return video::EIT_16BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get pointer to indices
|
||||||
|
/** \return Pointer to indices. */
|
||||||
|
const u16 *getIndices() const override
|
||||||
|
{
|
||||||
|
return Indices.const_pointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get pointer to indices
|
||||||
|
/** \return Pointer to indices. */
|
||||||
|
u16 *getIndices() override
|
||||||
|
{
|
||||||
|
return Indices.pointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get number of indices
|
||||||
|
/** \return Number of indices. */
|
||||||
|
u32 getIndexCount() const override
|
||||||
|
{
|
||||||
|
return Indices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the axis aligned bounding box
|
||||||
|
/** \return Axis aligned bounding box of this buffer. */
|
||||||
|
const core::aabbox3d<f32> &getBoundingBox() const override
|
||||||
|
{
|
||||||
|
return BoundingBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Set the axis aligned bounding box
|
||||||
|
/** \param box New axis aligned bounding box for this buffer. */
|
||||||
|
//! set user axis aligned bounding box
|
||||||
|
void setBoundingBox(const core::aabbox3df &box) override
|
||||||
|
{
|
||||||
|
BoundingBox = box;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Recalculate the bounding box.
|
||||||
|
/** should be called if the mesh changed. */
|
||||||
|
void recalculateBoundingBox() override
|
||||||
|
{
|
||||||
|
if (!Vertices.empty()) {
|
||||||
|
BoundingBox.reset(Vertices[0].Pos);
|
||||||
|
const irr::u32 vsize = Vertices.size();
|
||||||
|
for (u32 i = 1; i < vsize; ++i)
|
||||||
|
BoundingBox.addInternalPoint(Vertices[i].Pos);
|
||||||
|
} else
|
||||||
|
BoundingBox.reset(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get type of vertex data stored in this buffer.
|
||||||
|
/** \return Type of vertex data. */
|
||||||
|
video::E_VERTEX_TYPE getVertexType() const override
|
||||||
|
{
|
||||||
|
return T::getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! returns position of vertex i
|
||||||
|
const core::vector3df &getPosition(u32 i) const override
|
||||||
|
{
|
||||||
|
return Vertices[i].Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! returns position of vertex i
|
||||||
|
core::vector3df &getPosition(u32 i) override
|
||||||
|
{
|
||||||
|
return Vertices[i].Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! returns normal of vertex i
|
||||||
|
const core::vector3df &getNormal(u32 i) const override
|
||||||
|
{
|
||||||
|
return Vertices[i].Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! returns normal of vertex i
|
||||||
|
core::vector3df &getNormal(u32 i) override
|
||||||
|
{
|
||||||
|
return Vertices[i].Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! returns texture coord of vertex i
|
||||||
|
const core::vector2df &getTCoords(u32 i) const override
|
||||||
|
{
|
||||||
|
return Vertices[i].TCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! returns texture coord of vertex i
|
||||||
|
core::vector2df &getTCoords(u32 i) override
|
||||||
|
{
|
||||||
|
return Vertices[i].TCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Append the vertices and indices to the current buffer
|
||||||
|
/** Only works for compatible types, i.e. either the same type
|
||||||
|
or the main buffer is of standard type. Otherwise, behavior is
|
||||||
|
undefined.
|
||||||
|
*/
|
||||||
|
void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override
|
||||||
|
{
|
||||||
|
if (vertices == getVertices())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const u32 vertexCount = getVertexCount();
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
Vertices.reallocate(vertexCount + numVertices);
|
||||||
|
for (i = 0; i < numVertices; ++i) {
|
||||||
|
Vertices.push_back(static_cast<const T *>(vertices)[i]);
|
||||||
|
BoundingBox.addInternalPoint(static_cast<const T *>(vertices)[i].Pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
Indices.reallocate(getIndexCount() + numIndices);
|
||||||
|
for (i = 0; i < numIndices; ++i) {
|
||||||
|
Indices.push_back(indices[i] + vertexCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! get the current hardware mapping hint
|
||||||
|
E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const override
|
||||||
|
{
|
||||||
|
return MappingHint_Vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! get the current hardware mapping hint
|
||||||
|
E_HARDWARE_MAPPING getHardwareMappingHint_Index() const override
|
||||||
|
{
|
||||||
|
return MappingHint_Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! set the hardware mapping hint, for driver
|
||||||
|
void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override
|
||||||
|
{
|
||||||
|
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_VERTEX)
|
||||||
|
MappingHint_Vertex = NewMappingHint;
|
||||||
|
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_INDEX)
|
||||||
|
MappingHint_Index = NewMappingHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Describe what kind of primitive geometry is used by the meshbuffer
|
||||||
|
void setPrimitiveType(E_PRIMITIVE_TYPE type) override
|
||||||
|
{
|
||||||
|
PrimitiveType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the kind of primitive geometry which is used by the meshbuffer
|
||||||
|
E_PRIMITIVE_TYPE getPrimitiveType() const override
|
||||||
|
{
|
||||||
|
return PrimitiveType;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! flags the mesh as changed, reloads hardware buffers
|
||||||
|
void setDirty(E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override
|
||||||
|
{
|
||||||
|
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_VERTEX)
|
||||||
|
++ChangedID_Vertex;
|
||||||
|
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_INDEX)
|
||||||
|
++ChangedID_Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the currently used ID for identification of changes.
|
||||||
|
/** This shouldn't be used for anything outside the VideoDriver. */
|
||||||
|
u32 getChangedID_Vertex() const override { return ChangedID_Vertex; }
|
||||||
|
|
||||||
|
//! Get the currently used ID for identification of changes.
|
||||||
|
/** This shouldn't be used for anything outside the VideoDriver. */
|
||||||
|
u32 getChangedID_Index() const override { return ChangedID_Index; }
|
||||||
|
|
||||||
|
void setHWBuffer(void *ptr) const override
|
||||||
|
{
|
||||||
|
HWBuffer = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *getHWBuffer() const override
|
||||||
|
{
|
||||||
|
return HWBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ChangedID_Vertex;
|
||||||
|
u32 ChangedID_Index;
|
||||||
|
|
||||||
|
//! hardware mapping hint
|
||||||
|
E_HARDWARE_MAPPING MappingHint_Vertex;
|
||||||
|
E_HARDWARE_MAPPING MappingHint_Index;
|
||||||
|
mutable void *HWBuffer;
|
||||||
|
|
||||||
|
//! Material for this meshbuffer.
|
||||||
|
video::SMaterial Material;
|
||||||
|
//! Vertices of this buffer
|
||||||
|
core::array<T> Vertices;
|
||||||
|
//! Indices into the vertices of this buffer.
|
||||||
|
core::array<u16> Indices;
|
||||||
|
//! Bounding box of this meshbuffer.
|
||||||
|
core::aabbox3d<f32> BoundingBox;
|
||||||
|
//! Primitive type used for rendering (triangles, lines, ...)
|
||||||
|
E_PRIMITIVE_TYPE PrimitiveType;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Standard meshbuffer
|
||||||
|
typedef CMeshBuffer<video::S3DVertex> SMeshBuffer;
|
||||||
|
//! Meshbuffer with two texture coords per vertex, e.g. for lightmaps
|
||||||
|
typedef CMeshBuffer<video::S3DVertex2TCoords> SMeshBufferLightMap;
|
||||||
|
//! Meshbuffer with vertices having tangents stored, e.g. for normal mapping
|
||||||
|
typedef CMeshBuffer<video::S3DVertexTangents> SMeshBufferTangents;
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace io
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Types of attributes available for IAttributes
|
||||||
|
enum E_ATTRIBUTE_TYPE
|
||||||
|
{
|
||||||
|
// integer attribute
|
||||||
|
EAT_INT = 0,
|
||||||
|
|
||||||
|
// float attribute
|
||||||
|
EAT_FLOAT,
|
||||||
|
|
||||||
|
// boolean attribute
|
||||||
|
EAT_BOOL,
|
||||||
|
|
||||||
|
// known attribute type count
|
||||||
|
EAT_COUNT,
|
||||||
|
|
||||||
|
// unknown attribute
|
||||||
|
EAT_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace io
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
|
||||||
|
//! An enumeration for all types of automatic culling for built-in scene nodes
|
||||||
|
enum E_CULLING_TYPE
|
||||||
|
{
|
||||||
|
EAC_OFF = 0,
|
||||||
|
EAC_BOX = 1,
|
||||||
|
EAC_FRUSTUM_BOX = 2,
|
||||||
|
EAC_FRUSTUM_SPHERE = 4,
|
||||||
|
EAC_OCC_QUERY = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Names for culling type
|
||||||
|
const c8 *const AutomaticCullingNames[] = {
|
||||||
|
"false",
|
||||||
|
"box", // camera box against node box
|
||||||
|
"frustum_box", // camera frustum against node box
|
||||||
|
"frustum_sphere", // camera frustum against node sphere
|
||||||
|
"occ_query", // occlusion query
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
|
||||||
|
//! An enumeration for all types of debug data for built-in scene nodes (flags)
|
||||||
|
enum E_DEBUG_SCENE_TYPE
|
||||||
|
{
|
||||||
|
//! No Debug Data ( Default )
|
||||||
|
EDS_OFF = 0,
|
||||||
|
|
||||||
|
//! Show Bounding Boxes of SceneNode
|
||||||
|
EDS_BBOX = 1,
|
||||||
|
|
||||||
|
//! Show Vertex Normals
|
||||||
|
EDS_NORMALS = 2,
|
||||||
|
|
||||||
|
//! Shows Skeleton/Tags
|
||||||
|
EDS_SKELETON = 4,
|
||||||
|
|
||||||
|
//! Overlays Mesh Wireframe
|
||||||
|
EDS_MESH_WIRE_OVERLAY = 8,
|
||||||
|
|
||||||
|
//! Show Bounding Boxes of all MeshBuffers
|
||||||
|
EDS_BBOX_BUFFERS = 32,
|
||||||
|
|
||||||
|
//! EDS_BBOX | EDS_BBOX_BUFFERS
|
||||||
|
EDS_BBOX_ALL = EDS_BBOX | EDS_BBOX_BUFFERS,
|
||||||
|
|
||||||
|
//! Show all debug infos
|
||||||
|
EDS_FULL = 0xffffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
|
||||||
|
//! An enum for the different device types supported by the Irrlicht Engine.
|
||||||
|
enum E_DEVICE_TYPE
|
||||||
|
{
|
||||||
|
|
||||||
|
//! A device native to Microsoft Windows
|
||||||
|
/** This device uses the Win32 API and works in all versions of Windows. */
|
||||||
|
EIDT_WIN32,
|
||||||
|
|
||||||
|
//! A device native to Unix style operating systems.
|
||||||
|
/** This device uses the X11 windowing system and works in Linux, Solaris, FreeBSD, OSX and
|
||||||
|
other operating systems which support X11. */
|
||||||
|
EIDT_X11,
|
||||||
|
|
||||||
|
//! A device native to Mac OSX
|
||||||
|
/** This device uses Apple's Cocoa API and works in Mac OSX 10.2 and above. */
|
||||||
|
EIDT_OSX,
|
||||||
|
|
||||||
|
//! A device which uses Simple DirectMedia Layer
|
||||||
|
/** The SDL device works under all platforms supported by SDL but first must be compiled
|
||||||
|
in by setting the USE_SDL2 CMake option to ON */
|
||||||
|
EIDT_SDL,
|
||||||
|
|
||||||
|
//! This selection allows Irrlicht to choose the best device from the ones available.
|
||||||
|
/** If this selection is chosen then Irrlicht will try to use the IrrlichtDevice native
|
||||||
|
to your operating system. If this is unavailable then the X11, SDL and then console device
|
||||||
|
will be tried. This ensures that Irrlicht will run even if your platform is unsupported,
|
||||||
|
although it may not be able to render anything. */
|
||||||
|
EIDT_BEST,
|
||||||
|
|
||||||
|
//! A device for Android platforms
|
||||||
|
/** Best used with embedded devices and mobile systems.
|
||||||
|
Does not need X11 or other graphical subsystems.
|
||||||
|
May support hw-acceleration via OpenGL-ES */
|
||||||
|
EIDT_ANDROID,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,137 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace video
|
||||||
|
{
|
||||||
|
|
||||||
|
//! enumeration for querying features of the video driver.
|
||||||
|
enum E_VIDEO_DRIVER_FEATURE
|
||||||
|
{
|
||||||
|
//! Is driver able to render to a surface?
|
||||||
|
EVDF_RENDER_TO_TARGET = 0,
|
||||||
|
|
||||||
|
//! Is hardware transform and lighting supported?
|
||||||
|
EVDF_HARDWARE_TL,
|
||||||
|
|
||||||
|
//! Are multiple textures per material possible?
|
||||||
|
EVDF_MULTITEXTURE,
|
||||||
|
|
||||||
|
//! Is driver able to render with a bilinear filter applied?
|
||||||
|
EVDF_BILINEAR_FILTER,
|
||||||
|
|
||||||
|
//! Can the driver handle mip maps?
|
||||||
|
EVDF_MIP_MAP,
|
||||||
|
|
||||||
|
//! Can the driver update mip maps automatically?
|
||||||
|
EVDF_MIP_MAP_AUTO_UPDATE,
|
||||||
|
|
||||||
|
//! Are stencilbuffers switched on and does the device support stencil buffers?
|
||||||
|
EVDF_STENCIL_BUFFER,
|
||||||
|
|
||||||
|
//! Is Vertex Shader 1.1 supported?
|
||||||
|
EVDF_VERTEX_SHADER_1_1,
|
||||||
|
|
||||||
|
//! Is Vertex Shader 2.0 supported?
|
||||||
|
EVDF_VERTEX_SHADER_2_0,
|
||||||
|
|
||||||
|
//! Is Vertex Shader 3.0 supported?
|
||||||
|
EVDF_VERTEX_SHADER_3_0,
|
||||||
|
|
||||||
|
//! Is Pixel Shader 1.1 supported?
|
||||||
|
EVDF_PIXEL_SHADER_1_1,
|
||||||
|
|
||||||
|
//! Is Pixel Shader 1.2 supported?
|
||||||
|
EVDF_PIXEL_SHADER_1_2,
|
||||||
|
|
||||||
|
//! Is Pixel Shader 1.3 supported?
|
||||||
|
EVDF_PIXEL_SHADER_1_3,
|
||||||
|
|
||||||
|
//! Is Pixel Shader 1.4 supported?
|
||||||
|
EVDF_PIXEL_SHADER_1_4,
|
||||||
|
|
||||||
|
//! Is Pixel Shader 2.0 supported?
|
||||||
|
EVDF_PIXEL_SHADER_2_0,
|
||||||
|
|
||||||
|
//! Is Pixel Shader 3.0 supported?
|
||||||
|
EVDF_PIXEL_SHADER_3_0,
|
||||||
|
|
||||||
|
//! Are ARB vertex programs v1.0 supported?
|
||||||
|
EVDF_ARB_VERTEX_PROGRAM_1,
|
||||||
|
|
||||||
|
//! Are ARB fragment programs v1.0 supported?
|
||||||
|
EVDF_ARB_FRAGMENT_PROGRAM_1,
|
||||||
|
|
||||||
|
//! Is GLSL supported?
|
||||||
|
EVDF_ARB_GLSL,
|
||||||
|
|
||||||
|
//! Is HLSL supported?
|
||||||
|
EVDF_HLSL,
|
||||||
|
|
||||||
|
//! Are non-square textures supported?
|
||||||
|
EVDF_TEXTURE_NSQUARE,
|
||||||
|
|
||||||
|
//! Are non-power-of-two textures supported?
|
||||||
|
EVDF_TEXTURE_NPOT,
|
||||||
|
|
||||||
|
//! Are framebuffer objects supported?
|
||||||
|
EVDF_FRAMEBUFFER_OBJECT,
|
||||||
|
|
||||||
|
//! Are vertex buffer objects supported?
|
||||||
|
EVDF_VERTEX_BUFFER_OBJECT,
|
||||||
|
|
||||||
|
//! Supports Alpha To Coverage
|
||||||
|
EVDF_ALPHA_TO_COVERAGE,
|
||||||
|
|
||||||
|
//! Supports Color masks (disabling color planes in output)
|
||||||
|
EVDF_COLOR_MASK,
|
||||||
|
|
||||||
|
//! Supports multiple render targets at once
|
||||||
|
EVDF_MULTIPLE_RENDER_TARGETS,
|
||||||
|
|
||||||
|
//! Supports separate blend settings for multiple render targets
|
||||||
|
EVDF_MRT_BLEND,
|
||||||
|
|
||||||
|
//! Supports separate color masks for multiple render targets
|
||||||
|
EVDF_MRT_COLOR_MASK,
|
||||||
|
|
||||||
|
//! Supports separate blend functions for multiple render targets
|
||||||
|
EVDF_MRT_BLEND_FUNC,
|
||||||
|
|
||||||
|
//! Supports geometry shaders
|
||||||
|
EVDF_GEOMETRY_SHADER,
|
||||||
|
|
||||||
|
//! Supports occlusion queries
|
||||||
|
EVDF_OCCLUSION_QUERY,
|
||||||
|
|
||||||
|
//! Supports polygon offset/depth bias for avoiding z-fighting
|
||||||
|
EVDF_POLYGON_OFFSET,
|
||||||
|
|
||||||
|
//! Support for different blend functions. Without, only ADD is available
|
||||||
|
EVDF_BLEND_OPERATIONS,
|
||||||
|
|
||||||
|
//! Support for separate blending for RGB and Alpha.
|
||||||
|
EVDF_BLEND_SEPARATE,
|
||||||
|
|
||||||
|
//! Support for texture coord transformation via texture matrix
|
||||||
|
EVDF_TEXTURE_MATRIX,
|
||||||
|
|
||||||
|
//! Support for cube map textures.
|
||||||
|
EVDF_TEXTURE_CUBEMAP,
|
||||||
|
|
||||||
|
//! Support for filtering across different faces of the cubemap
|
||||||
|
EVDF_TEXTURE_CUBEMAP_SEAMLESS,
|
||||||
|
|
||||||
|
//! Support for clamping vertices beyond far-plane to depth instead of capping them.
|
||||||
|
EVDF_DEPTH_CLAMP,
|
||||||
|
|
||||||
|
//! Only used for counting the elements of this enum
|
||||||
|
EVDF_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace video
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace video
|
||||||
|
{
|
||||||
|
|
||||||
|
//! An enum for all types of drivers the Irrlicht Engine supports.
|
||||||
|
enum E_DRIVER_TYPE
|
||||||
|
{
|
||||||
|
//! Null driver, useful for applications to run the engine without visualization.
|
||||||
|
/** The null device is able to load textures, but does not
|
||||||
|
render and display any graphics. */
|
||||||
|
EDT_NULL,
|
||||||
|
|
||||||
|
//! OpenGL device, available on most platforms.
|
||||||
|
/** Performs hardware accelerated rendering of 3D and 2D
|
||||||
|
primitives. */
|
||||||
|
EDT_OPENGL,
|
||||||
|
|
||||||
|
//! OpenGL-ES 1.x driver, for embedded and mobile systems
|
||||||
|
EDT_OGLES1,
|
||||||
|
|
||||||
|
//! OpenGL-ES 2.x driver, for embedded and mobile systems
|
||||||
|
/** Supports shaders etc. */
|
||||||
|
EDT_OGLES2,
|
||||||
|
|
||||||
|
//! WebGL1 friendly subset of OpenGL-ES 2.x driver for Emscripten
|
||||||
|
EDT_WEBGL1,
|
||||||
|
|
||||||
|
EDT_OPENGL3,
|
||||||
|
|
||||||
|
//! No driver, just for counting the elements
|
||||||
|
EDT_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace video
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,34 @@
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Bitflags for defining the the focus behavior of the gui
|
||||||
|
// (all names start with SET as we might add REMOVE flags later to control that behavior as well)
|
||||||
|
enum EFOCUS_FLAG
|
||||||
|
{
|
||||||
|
//! When set the focus changes when the left mouse-button got clicked while over an element
|
||||||
|
EFF_SET_ON_LMOUSE_DOWN = 0x1,
|
||||||
|
|
||||||
|
//! When set the focus changes when the right mouse-button got clicked while over an element
|
||||||
|
//! Note that elements usually don't care about right-click and that won't change with this flag
|
||||||
|
//! This is mostly to allow taking away focus from elements with right-mouse additionally.
|
||||||
|
EFF_SET_ON_RMOUSE_DOWN = 0x2,
|
||||||
|
|
||||||
|
//! When set the focus changes when the mouse-cursor is over an element
|
||||||
|
EFF_SET_ON_MOUSE_OVER = 0x4,
|
||||||
|
|
||||||
|
//! When set the focus can be changed with TAB-key combinations.
|
||||||
|
EFF_SET_ON_TAB = 0x8,
|
||||||
|
|
||||||
|
//! When set it's possible to set the focus to disabled elements.
|
||||||
|
EFF_CAN_FOCUS_DISABLED = 0x16
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace irr
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
enum EGUI_ALIGNMENT
|
||||||
|
{
|
||||||
|
//! Aligned to parent's top or left side (default)
|
||||||
|
EGUIA_UPPERLEFT = 0,
|
||||||
|
//! Aligned to parent's bottom or right side
|
||||||
|
EGUIA_LOWERRIGHT,
|
||||||
|
//! Aligned to the center of parent
|
||||||
|
EGUIA_CENTER,
|
||||||
|
//! Stretched to fit parent
|
||||||
|
EGUIA_SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Names for alignments
|
||||||
|
const c8 *const GUIAlignmentNames[] = {
|
||||||
|
"upperLeft",
|
||||||
|
"lowerRight",
|
||||||
|
"center",
|
||||||
|
"scale",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gui
|
||||||
|
} // namespace irr
|
|
@ -0,0 +1,133 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
|
||||||
|
//! List of all basic Irrlicht GUI elements.
|
||||||
|
/** An IGUIElement returns this when calling IGUIElement::getType(); */
|
||||||
|
enum EGUI_ELEMENT_TYPE
|
||||||
|
{
|
||||||
|
//! A button (IGUIButton)
|
||||||
|
EGUIET_BUTTON = 0,
|
||||||
|
|
||||||
|
//! A check box (IGUICheckBox)
|
||||||
|
EGUIET_CHECK_BOX,
|
||||||
|
|
||||||
|
//! A combo box (IGUIComboBox)
|
||||||
|
EGUIET_COMBO_BOX,
|
||||||
|
|
||||||
|
//! A context menu (IGUIContextMenu)
|
||||||
|
EGUIET_CONTEXT_MENU,
|
||||||
|
|
||||||
|
//! A menu (IGUIMenu)
|
||||||
|
EGUIET_MENU,
|
||||||
|
|
||||||
|
//! An edit box (IGUIEditBox)
|
||||||
|
EGUIET_EDIT_BOX,
|
||||||
|
|
||||||
|
//! A file open dialog (IGUIFileOpenDialog)
|
||||||
|
EGUIET_FILE_OPEN_DIALOG,
|
||||||
|
|
||||||
|
//! A color select open dialog (IGUIColorSelectDialog)
|
||||||
|
EGUIET_COLOR_SELECT_DIALOG,
|
||||||
|
|
||||||
|
//! A in/out fader (IGUIInOutFader)
|
||||||
|
EGUIET_IN_OUT_FADER,
|
||||||
|
|
||||||
|
//! An image (IGUIImage)
|
||||||
|
EGUIET_IMAGE,
|
||||||
|
|
||||||
|
//! A list box (IGUIListBox)
|
||||||
|
EGUIET_LIST_BOX,
|
||||||
|
|
||||||
|
//! A mesh viewer (IGUIMeshViewer)
|
||||||
|
EGUIET_MESH_VIEWER,
|
||||||
|
|
||||||
|
//! A message box (IGUIWindow)
|
||||||
|
EGUIET_MESSAGE_BOX,
|
||||||
|
|
||||||
|
//! A modal screen
|
||||||
|
EGUIET_MODAL_SCREEN,
|
||||||
|
|
||||||
|
//! A scroll bar (IGUIScrollBar)
|
||||||
|
EGUIET_SCROLL_BAR,
|
||||||
|
|
||||||
|
//! A spin box (IGUISpinBox)
|
||||||
|
EGUIET_SPIN_BOX,
|
||||||
|
|
||||||
|
//! A static text (IGUIStaticText)
|
||||||
|
EGUIET_STATIC_TEXT,
|
||||||
|
|
||||||
|
//! A tab (IGUITab)
|
||||||
|
EGUIET_TAB,
|
||||||
|
|
||||||
|
//! A tab control
|
||||||
|
EGUIET_TAB_CONTROL,
|
||||||
|
|
||||||
|
//! A Table
|
||||||
|
EGUIET_TABLE,
|
||||||
|
|
||||||
|
//! A tool bar (IGUIToolBar)
|
||||||
|
EGUIET_TOOL_BAR,
|
||||||
|
|
||||||
|
//! A Tree View
|
||||||
|
EGUIET_TREE_VIEW,
|
||||||
|
|
||||||
|
//! A window
|
||||||
|
EGUIET_WINDOW,
|
||||||
|
|
||||||
|
//! Unknown type.
|
||||||
|
EGUIET_ELEMENT,
|
||||||
|
|
||||||
|
//! The root of the GUI
|
||||||
|
EGUIET_ROOT,
|
||||||
|
|
||||||
|
//! Not an element, amount of elements in there
|
||||||
|
EGUIET_COUNT,
|
||||||
|
|
||||||
|
//! This enum is never used, it only forces the compiler to compile this enumeration to 32 bit.
|
||||||
|
EGUIET_FORCE_32_BIT = 0x7fffffff
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Names for built-in element types
|
||||||
|
const c8 *const GUIElementTypeNames[] = {
|
||||||
|
"button",
|
||||||
|
"checkBox",
|
||||||
|
"comboBox",
|
||||||
|
"contextMenu",
|
||||||
|
"menu",
|
||||||
|
"editBox",
|
||||||
|
"fileOpenDialog",
|
||||||
|
"colorSelectDialog",
|
||||||
|
"inOutFader",
|
||||||
|
"image",
|
||||||
|
"listBox",
|
||||||
|
"meshViewer",
|
||||||
|
"messageBox",
|
||||||
|
"modalScreen",
|
||||||
|
"scrollBar",
|
||||||
|
"spinBox",
|
||||||
|
"staticText",
|
||||||
|
"tab",
|
||||||
|
"tabControl",
|
||||||
|
"table",
|
||||||
|
"toolBar",
|
||||||
|
"treeview",
|
||||||
|
"window",
|
||||||
|
"element",
|
||||||
|
"root",
|
||||||
|
"profiler",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace gui
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
|
||||||
|
enum E_HARDWARE_MAPPING
|
||||||
|
{
|
||||||
|
//! Don't store on the hardware
|
||||||
|
EHM_NEVER = 0,
|
||||||
|
|
||||||
|
//! Rarely changed, usually stored completely on the hardware
|
||||||
|
EHM_STATIC,
|
||||||
|
|
||||||
|
//! Sometimes changed, driver optimized placement
|
||||||
|
EHM_DYNAMIC,
|
||||||
|
|
||||||
|
//! Always changed, cache optimizing on the GPU
|
||||||
|
EHM_STREAM
|
||||||
|
};
|
||||||
|
|
||||||
|
enum E_BUFFER_TYPE
|
||||||
|
{
|
||||||
|
//! Does not change anything
|
||||||
|
EBT_NONE = 0,
|
||||||
|
//! Change the vertex mapping
|
||||||
|
EBT_VERTEX,
|
||||||
|
//! Change the index mapping
|
||||||
|
EBT_INDEX,
|
||||||
|
//! Change both vertex and index mapping to the same value
|
||||||
|
EBT_VERTEX_AND_INDEX
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace video
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Material properties
|
||||||
|
enum E_MATERIAL_PROP
|
||||||
|
{
|
||||||
|
//! Corresponds to SMaterial::Wireframe.
|
||||||
|
EMP_WIREFRAME = 0x1,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::PointCloud.
|
||||||
|
EMP_POINTCLOUD = 0x2,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::GouraudShading.
|
||||||
|
EMP_GOURAUD_SHADING = 0x4,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::Lighting.
|
||||||
|
EMP_LIGHTING = 0x8,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::ZBuffer.
|
||||||
|
EMP_ZBUFFER = 0x10,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::ZWriteEnable.
|
||||||
|
EMP_ZWRITE_ENABLE = 0x20,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::BackfaceCulling.
|
||||||
|
EMP_BACK_FACE_CULLING = 0x40,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::FrontfaceCulling.
|
||||||
|
EMP_FRONT_FACE_CULLING = 0x80,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterialLayer::MinFilter.
|
||||||
|
EMP_MIN_FILTER = 0x100,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterialLayer::MagFilter.
|
||||||
|
EMP_MAG_FILTER = 0x200,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterialLayer::AnisotropicFilter.
|
||||||
|
EMP_ANISOTROPIC_FILTER = 0x400,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::FogEnable.
|
||||||
|
EMP_FOG_ENABLE = 0x800,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::NormalizeNormals.
|
||||||
|
EMP_NORMALIZE_NORMALS = 0x1000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterialLayer::TextureWrapU, TextureWrapV and
|
||||||
|
//! TextureWrapW.
|
||||||
|
EMP_TEXTURE_WRAP = 0x2000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::AntiAliasing.
|
||||||
|
EMP_ANTI_ALIASING = 0x4000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::ColorMask.
|
||||||
|
EMP_COLOR_MASK = 0x8000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::ColorMaterial.
|
||||||
|
EMP_COLOR_MATERIAL = 0x10000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::UseMipMaps.
|
||||||
|
EMP_USE_MIP_MAPS = 0x20000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::BlendOperation.
|
||||||
|
EMP_BLEND_OPERATION = 0x40000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::PolygonOffsetFactor, PolygonOffsetDirection,
|
||||||
|
//! PolygonOffsetDepthBias and PolygonOffsetSlopeScale.
|
||||||
|
EMP_POLYGON_OFFSET = 0x80000,
|
||||||
|
|
||||||
|
//! Corresponds to SMaterial::BlendFactor.
|
||||||
|
EMP_BLEND_FACTOR = 0x100000,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace video
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace video
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Abstracted and easy to use fixed function/programmable pipeline material modes.
|
||||||
|
enum E_MATERIAL_TYPE
|
||||||
|
{
|
||||||
|
//! Standard solid material.
|
||||||
|
/** Only first texture is used, which is supposed to be the
|
||||||
|
diffuse material. */
|
||||||
|
EMT_SOLID = 0,
|
||||||
|
|
||||||
|
//! Makes the material transparent based on the texture alpha channel.
|
||||||
|
/** The final color is blended together from the destination
|
||||||
|
color and the texture color, using the alpha channel value as
|
||||||
|
blend factor. Only first texture is used. If you are using
|
||||||
|
this material with small textures, it is a good idea to load
|
||||||
|
the texture in 32 bit mode
|
||||||
|
(video::IVideoDriver::setTextureCreationFlag()). Also, an alpha
|
||||||
|
ref is used, which can be manipulated using
|
||||||
|
SMaterial::MaterialTypeParam. This value controls how sharp the
|
||||||
|
edges become when going from a transparent to a solid spot on
|
||||||
|
the texture. */
|
||||||
|
EMT_TRANSPARENT_ALPHA_CHANNEL,
|
||||||
|
|
||||||
|
//! Makes the material transparent based on the texture alpha channel.
|
||||||
|
/** If the alpha channel value is greater than 127, a
|
||||||
|
pixel is written to the target, otherwise not. This
|
||||||
|
material does not use alpha blending and is a lot faster
|
||||||
|
than EMT_TRANSPARENT_ALPHA_CHANNEL. It is ideal for drawing
|
||||||
|
stuff like leaves of plants, because the borders are not
|
||||||
|
blurry but sharp. Only first texture is used. If you are
|
||||||
|
using this material with small textures and 3d object, it
|
||||||
|
is a good idea to load the texture in 32 bit mode
|
||||||
|
(video::IVideoDriver::setTextureCreationFlag()). */
|
||||||
|
EMT_TRANSPARENT_ALPHA_CHANNEL_REF,
|
||||||
|
|
||||||
|
//! Makes the material transparent based on the vertex alpha value.
|
||||||
|
EMT_TRANSPARENT_VERTEX_ALPHA,
|
||||||
|
|
||||||
|
//! BlendFunc = source * sourceFactor + dest * destFactor ( E_BLEND_FUNC )
|
||||||
|
/** Using only first texture. Generic blending method.
|
||||||
|
The blend function is set to SMaterial::MaterialTypeParam with
|
||||||
|
pack_textureBlendFunc (for 2D) or pack_textureBlendFuncSeparate (for 3D). */
|
||||||
|
EMT_ONETEXTURE_BLEND,
|
||||||
|
|
||||||
|
//! This value is not used. It only forces this enumeration to compile to 32 bit.
|
||||||
|
EMT_FORCE_32BIT = 0x7fffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Array holding the built in material type names
|
||||||
|
const char *const sBuiltInMaterialTypeNames[] = {
|
||||||
|
"solid",
|
||||||
|
"trans_alphach",
|
||||||
|
"trans_alphach_ref",
|
||||||
|
"trans_vertex_alpha",
|
||||||
|
"onetexture_blend",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr u32 numBuiltInMaterials =
|
||||||
|
sizeof(sBuiltInMaterialTypeNames) / sizeof(char *) - 1;
|
||||||
|
|
||||||
|
} // end namespace video
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Enumeration for all primitive types there are.
|
||||||
|
enum E_PRIMITIVE_TYPE
|
||||||
|
{
|
||||||
|
//! All vertices are non-connected points.
|
||||||
|
EPT_POINTS = 0,
|
||||||
|
|
||||||
|
//! All vertices form a single connected line.
|
||||||
|
EPT_LINE_STRIP,
|
||||||
|
|
||||||
|
//! Just as LINE_STRIP, but the last and the first vertex is also connected.
|
||||||
|
EPT_LINE_LOOP,
|
||||||
|
|
||||||
|
//! Every two vertices are connected creating n/2 lines.
|
||||||
|
EPT_LINES,
|
||||||
|
|
||||||
|
//! After the first two vertices each vertex defines a new triangle.
|
||||||
|
//! Always the two last and the new one form a new triangle.
|
||||||
|
EPT_TRIANGLE_STRIP,
|
||||||
|
|
||||||
|
//! After the first two vertices each vertex defines a new triangle.
|
||||||
|
//! All around the common first vertex.
|
||||||
|
EPT_TRIANGLE_FAN,
|
||||||
|
|
||||||
|
//! Explicitly set all vertices for each triangle.
|
||||||
|
EPT_TRIANGLES,
|
||||||
|
|
||||||
|
//! The single vertices are expanded to quad billboards on the GPU.
|
||||||
|
EPT_POINT_SPRITES
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (C) Michael Zeilfelder
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace io
|
||||||
|
{
|
||||||
|
|
||||||
|
//! An enumeration for different class types implementing IReadFile
|
||||||
|
enum EREAD_FILE_TYPE
|
||||||
|
{
|
||||||
|
//! CReadFile
|
||||||
|
ERFT_READ_FILE = MAKE_IRR_ID('r', 'e', 'a', 'd'),
|
||||||
|
|
||||||
|
//! CMemoryReadFile
|
||||||
|
ERFT_MEMORY_READ_FILE = MAKE_IRR_ID('r', 'm', 'e', 'm'),
|
||||||
|
|
||||||
|
//! CLimitReadFile
|
||||||
|
ERFT_LIMIT_READ_FILE = MAKE_IRR_ID('r', 'l', 'i', 'm'),
|
||||||
|
|
||||||
|
//! Unknown type
|
||||||
|
EFIT_UNKNOWN = MAKE_IRR_ID('u', 'n', 'k', 'n')
|
||||||
|
};
|
||||||
|
} // end namespace io
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
|
||||||
|
//! An enumeration for all types of built-in scene nodes
|
||||||
|
/** A scene node type is represented by a four character code
|
||||||
|
such as 'cube' or 'mesh' instead of simple numbers, to avoid
|
||||||
|
name clashes with external scene nodes.*/
|
||||||
|
enum ESCENE_NODE_TYPE
|
||||||
|
{
|
||||||
|
//! of type CSceneManager (note that ISceneManager is not(!) an ISceneNode)
|
||||||
|
ESNT_SCENE_MANAGER = MAKE_IRR_ID('s', 'm', 'n', 'g'),
|
||||||
|
|
||||||
|
//! Mesh Scene Node
|
||||||
|
ESNT_MESH = MAKE_IRR_ID('m', 'e', 's', 'h'),
|
||||||
|
|
||||||
|
//! Empty Scene Node
|
||||||
|
ESNT_EMPTY = MAKE_IRR_ID('e', 'm', 't', 'y'),
|
||||||
|
|
||||||
|
//! Dummy Transformation Scene Node
|
||||||
|
ESNT_DUMMY_TRANSFORMATION = MAKE_IRR_ID('d', 'm', 'm', 'y'),
|
||||||
|
|
||||||
|
//! Camera Scene Node
|
||||||
|
ESNT_CAMERA = MAKE_IRR_ID('c', 'a', 'm', '_'),
|
||||||
|
|
||||||
|
//! Billboard Scene Node
|
||||||
|
ESNT_BILLBOARD = MAKE_IRR_ID('b', 'i', 'l', 'l'),
|
||||||
|
|
||||||
|
//! Animated Mesh Scene Node
|
||||||
|
ESNT_ANIMATED_MESH = MAKE_IRR_ID('a', 'm', 's', 'h'),
|
||||||
|
|
||||||
|
//! Unknown scene node
|
||||||
|
ESNT_UNKNOWN = MAKE_IRR_ID('u', 'n', 'k', 'n'),
|
||||||
|
|
||||||
|
//! Will match with any scene node when checking types
|
||||||
|
ESNT_ANY = MAKE_IRR_ID('a', 'n', 'y', '_')
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,85 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "irrTypes.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace video
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Compile target enumeration for the addHighLevelShaderMaterial() method.
|
||||||
|
enum E_VERTEX_SHADER_TYPE
|
||||||
|
{
|
||||||
|
EVST_VS_1_1 = 0,
|
||||||
|
EVST_VS_2_0,
|
||||||
|
EVST_VS_2_a,
|
||||||
|
EVST_VS_3_0,
|
||||||
|
EVST_VS_4_0,
|
||||||
|
EVST_VS_4_1,
|
||||||
|
EVST_VS_5_0,
|
||||||
|
|
||||||
|
//! This is not a type, but a value indicating how much types there are.
|
||||||
|
EVST_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Names for all vertex shader types, each entry corresponds to a E_VERTEX_SHADER_TYPE entry.
|
||||||
|
const c8 *const VERTEX_SHADER_TYPE_NAMES[] = {
|
||||||
|
"vs_1_1",
|
||||||
|
"vs_2_0",
|
||||||
|
"vs_2_a",
|
||||||
|
"vs_3_0",
|
||||||
|
"vs_4_0",
|
||||||
|
"vs_4_1",
|
||||||
|
"vs_5_0",
|
||||||
|
0};
|
||||||
|
|
||||||
|
//! Compile target enumeration for the addHighLevelShaderMaterial() method.
|
||||||
|
enum E_PIXEL_SHADER_TYPE
|
||||||
|
{
|
||||||
|
EPST_PS_1_1 = 0,
|
||||||
|
EPST_PS_1_2,
|
||||||
|
EPST_PS_1_3,
|
||||||
|
EPST_PS_1_4,
|
||||||
|
EPST_PS_2_0,
|
||||||
|
EPST_PS_2_a,
|
||||||
|
EPST_PS_2_b,
|
||||||
|
EPST_PS_3_0,
|
||||||
|
EPST_PS_4_0,
|
||||||
|
EPST_PS_4_1,
|
||||||
|
EPST_PS_5_0,
|
||||||
|
|
||||||
|
//! This is not a type, but a value indicating how much types there are.
|
||||||
|
EPST_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Names for all pixel shader types, each entry corresponds to a E_PIXEL_SHADER_TYPE entry.
|
||||||
|
const c8 *const PIXEL_SHADER_TYPE_NAMES[] = {
|
||||||
|
"ps_1_1",
|
||||||
|
"ps_1_2",
|
||||||
|
"ps_1_3",
|
||||||
|
"ps_1_4",
|
||||||
|
"ps_2_0",
|
||||||
|
"ps_2_a",
|
||||||
|
"ps_2_b",
|
||||||
|
"ps_3_0",
|
||||||
|
"ps_4_0",
|
||||||
|
"ps_4_1",
|
||||||
|
"ps_5_0",
|
||||||
|
0};
|
||||||
|
|
||||||
|
//! Enum for supported geometry shader types
|
||||||
|
enum E_GEOMETRY_SHADER_TYPE
|
||||||
|
{
|
||||||
|
EGST_GS_4_0 = 0,
|
||||||
|
|
||||||
|
//! This is not a type, but a value indicating how much types there are.
|
||||||
|
EGST_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
//! String names for supported geometry shader types
|
||||||
|
const c8 *const GEOMETRY_SHADER_TYPE_NAMES[] = {
|
||||||
|
"gs_4_0",
|
||||||
|
0};
|
||||||
|
|
||||||
|
} // end namespace video
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace video
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Enumeration for all vertex attributes there are.
|
||||||
|
enum E_VERTEX_ATTRIBUTES
|
||||||
|
{
|
||||||
|
EVA_POSITION = 0,
|
||||||
|
EVA_NORMAL,
|
||||||
|
EVA_COLOR,
|
||||||
|
EVA_TCOORD0,
|
||||||
|
EVA_TCOORD1,
|
||||||
|
EVA_TANGENT,
|
||||||
|
EVA_BINORMAL,
|
||||||
|
EVA_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Array holding the built in vertex attribute names
|
||||||
|
const char *const sBuiltInVertexAttributeNames[] = {
|
||||||
|
"inVertexPosition",
|
||||||
|
"inVertexNormal",
|
||||||
|
"inVertexColor",
|
||||||
|
"inTexCoord0",
|
||||||
|
"inTexCoord1",
|
||||||
|
"inVertexTangent",
|
||||||
|
"inVertexBinormal",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace video
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "aabbox3d.h"
|
||||||
|
#include "IMesh.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
//! Interface for an animated mesh.
|
||||||
|
/** There are already simple implementations of this interface available so
|
||||||
|
you don't have to implement this interface on your own if you need to:
|
||||||
|
You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh,
|
||||||
|
irr::scene::SMeshBuffer etc. */
|
||||||
|
class IAnimatedMesh : public IMesh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Gets the frame count of the animated mesh.
|
||||||
|
/** Note that the play-time is usually getFrameCount()-1 as it stops as soon as the last frame-key is reached.
|
||||||
|
\return The amount of frames. If the amount is 1,
|
||||||
|
it is a static, non animated mesh. */
|
||||||
|
virtual u32 getFrameCount() const = 0;
|
||||||
|
|
||||||
|
//! Gets the animation speed of the animated mesh.
|
||||||
|
/** \return The number of frames per second to play the
|
||||||
|
animation with by default. If the amount is 0,
|
||||||
|
it is a static, non animated mesh. */
|
||||||
|
virtual f32 getAnimationSpeed() const = 0;
|
||||||
|
|
||||||
|
//! Sets the animation speed of the animated mesh.
|
||||||
|
/** \param fps Number of frames per second to play the
|
||||||
|
animation with by default. If the amount is 0,
|
||||||
|
it is not animated. The actual speed is set in the
|
||||||
|
scene node the mesh is instantiated in.*/
|
||||||
|
virtual void setAnimationSpeed(f32 fps) = 0;
|
||||||
|
|
||||||
|
//! Returns the IMesh interface for a frame.
|
||||||
|
/** \param frame: Frame number as zero based index. The maximum
|
||||||
|
frame number is getFrameCount() - 1;
|
||||||
|
\param detailLevel: Level of detail. 0 is the lowest, 255 the
|
||||||
|
highest level of detail. Most meshes will ignore the detail level.
|
||||||
|
\param startFrameLoop: Because some animated meshes (.MD2) are
|
||||||
|
blended between 2 static frames, and maybe animated in a loop,
|
||||||
|
the startFrameLoop and the endFrameLoop have to be defined, to
|
||||||
|
prevent the animation to be blended between frames which are
|
||||||
|
outside of this loop.
|
||||||
|
If startFrameLoop and endFrameLoop are both -1, they are ignored.
|
||||||
|
\param endFrameLoop: see startFrameLoop.
|
||||||
|
\return Returns the animated mesh based on a detail level. */
|
||||||
|
virtual IMesh *getMesh(s32 frame, s32 detailLevel = 255, s32 startFrameLoop = -1, s32 endFrameLoop = -1) = 0;
|
||||||
|
|
||||||
|
//! Returns the type of the animated mesh.
|
||||||
|
/** In most cases it is not necessary to use this method.
|
||||||
|
This is useful for making a safe downcast. For example,
|
||||||
|
if getMeshType() returns EAMT_MD2 it's safe to cast the
|
||||||
|
IAnimatedMesh to IAnimatedMeshMD2.
|
||||||
|
\returns Type of the mesh. */
|
||||||
|
E_ANIMATED_MESH_TYPE getMeshType() const override
|
||||||
|
{
|
||||||
|
return EAMT_UNKNOWN;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
|
@ -0,0 +1,169 @@
|
||||||
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine".
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISceneNode.h"
|
||||||
|
#include "IBoneSceneNode.h"
|
||||||
|
#include "IAnimatedMesh.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
enum E_JOINT_UPDATE_ON_RENDER
|
||||||
|
{
|
||||||
|
//! do nothing
|
||||||
|
EJUOR_NONE = 0,
|
||||||
|
|
||||||
|
//! get joints positions from the mesh (for attached nodes, etc)
|
||||||
|
EJUOR_READ,
|
||||||
|
|
||||||
|
//! control joint positions in the mesh (eg. ragdolls, or set the animation from animateJoints() )
|
||||||
|
EJUOR_CONTROL
|
||||||
|
};
|
||||||
|
|
||||||
|
class IAnimatedMeshSceneNode;
|
||||||
|
|
||||||
|
//! Callback interface for catching events of ended animations.
|
||||||
|
/** Implement this interface and use
|
||||||
|
IAnimatedMeshSceneNode::setAnimationEndCallback to be able to
|
||||||
|
be notified if an animation playback has ended.
|
||||||
|
**/
|
||||||
|
class IAnimationEndCallBack : public virtual IReferenceCounted
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Will be called when the animation playback has ended.
|
||||||
|
/** See IAnimatedMeshSceneNode::setAnimationEndCallback for
|
||||||
|
more information.
|
||||||
|
\param node: Node of which the animation has ended. */
|
||||||
|
virtual void OnAnimationEnd(IAnimatedMeshSceneNode *node) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Scene node capable of displaying an animated mesh.
|
||||||
|
class IAnimatedMeshSceneNode : public ISceneNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
IAnimatedMeshSceneNode(ISceneNode *parent, ISceneManager *mgr, s32 id,
|
||||||
|
const core::vector3df &position = core::vector3df(0, 0, 0),
|
||||||
|
const core::vector3df &rotation = core::vector3df(0, 0, 0),
|
||||||
|
const core::vector3df &scale = core::vector3df(1.0f, 1.0f, 1.0f)) :
|
||||||
|
ISceneNode(parent, mgr, id, position, rotation, scale) {}
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
virtual ~IAnimatedMeshSceneNode() {}
|
||||||
|
|
||||||
|
//! Sets the current frame number.
|
||||||
|
/** From now on the animation is played from this frame.
|
||||||
|
\param frame: Number of the frame to let the animation be started from.
|
||||||
|
The frame number must be a valid frame number of the IMesh used by this
|
||||||
|
scene node. Set IAnimatedMesh::getMesh() for details. */
|
||||||
|
virtual void setCurrentFrame(f32 frame) = 0;
|
||||||
|
|
||||||
|
//! Sets the frame numbers between the animation is looped.
|
||||||
|
/** The default is 0 to getFrameCount()-1 of the mesh.
|
||||||
|
Number of played frames is end-start.
|
||||||
|
It interpolates toward the last frame but stops when it is reached.
|
||||||
|
It does not interpolate back to start even when looping.
|
||||||
|
Looping animations should ensure last and first frame-key are identical.
|
||||||
|
\param begin: Start frame number of the loop.
|
||||||
|
\param end: End frame number of the loop.
|
||||||
|
\return True if successful, false if not. */
|
||||||
|
virtual bool setFrameLoop(s32 begin, s32 end) = 0;
|
||||||
|
|
||||||
|
//! Sets the speed with which the animation is played.
|
||||||
|
/** \param framesPerSecond: Frames per second played. */
|
||||||
|
virtual void setAnimationSpeed(f32 framesPerSecond) = 0;
|
||||||
|
|
||||||
|
//! Gets the speed with which the animation is played.
|
||||||
|
/** \return Frames per second played. */
|
||||||
|
virtual f32 getAnimationSpeed() const = 0;
|
||||||
|
|
||||||
|
//! Get a pointer to a joint in the mesh (if the mesh is a bone based mesh).
|
||||||
|
/** With this method it is possible to attach scene nodes to
|
||||||
|
joints for example possible to attach a weapon to the left hand
|
||||||
|
of an animated model. This example shows how:
|
||||||
|
\code
|
||||||
|
ISceneNode* hand =
|
||||||
|
yourAnimatedMeshSceneNode->getJointNode("LeftHand");
|
||||||
|
hand->addChild(weaponSceneNode);
|
||||||
|
\endcode
|
||||||
|
Please note that the joint returned by this method may not exist
|
||||||
|
before this call and the joints in the node were created by it.
|
||||||
|
\param jointName: Name of the joint.
|
||||||
|
\return Pointer to the scene node which represents the joint
|
||||||
|
with the specified name. Returns 0 if the contained mesh is not
|
||||||
|
an skinned mesh or the name of the joint could not be found. */
|
||||||
|
virtual IBoneSceneNode *getJointNode(const c8 *jointName) = 0;
|
||||||
|
|
||||||
|
//! same as getJointNode(const c8* jointName), but based on id
|
||||||
|
virtual IBoneSceneNode *getJointNode(u32 jointID) = 0;
|
||||||
|
|
||||||
|
//! Gets joint count.
|
||||||
|
/** \return Amount of joints in the mesh. */
|
||||||
|
virtual u32 getJointCount() const = 0;
|
||||||
|
|
||||||
|
//! Returns the currently displayed frame number.
|
||||||
|
virtual f32 getFrameNr() const = 0;
|
||||||
|
//! Returns the current start frame number.
|
||||||
|
virtual s32 getStartFrame() const = 0;
|
||||||
|
//! Returns the current end frame number.
|
||||||
|
virtual s32 getEndFrame() const = 0;
|
||||||
|
|
||||||
|
//! Sets looping mode which is on by default.
|
||||||
|
/** If set to false, animations will not be played looped. */
|
||||||
|
virtual void setLoopMode(bool playAnimationLooped) = 0;
|
||||||
|
|
||||||
|
//! returns the current loop mode
|
||||||
|
/** When true the animations are played looped */
|
||||||
|
virtual bool getLoopMode() const = 0;
|
||||||
|
|
||||||
|
//! Sets a callback interface which will be called if an animation playback has ended.
|
||||||
|
/** Set this to 0 to disable the callback again.
|
||||||
|
Please note that this will only be called when in non looped
|
||||||
|
mode, see IAnimatedMeshSceneNode::setLoopMode(). */
|
||||||
|
virtual void setAnimationEndCallback(IAnimationEndCallBack *callback = 0) = 0;
|
||||||
|
|
||||||
|
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
||||||
|
/** In this way it is possible to change the materials a mesh
|
||||||
|
causing all mesh scene nodes referencing this mesh to change
|
||||||
|
too. */
|
||||||
|
virtual void setReadOnlyMaterials(bool readonly) = 0;
|
||||||
|
|
||||||
|
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
||||||
|
virtual bool isReadOnlyMaterials() const = 0;
|
||||||
|
|
||||||
|
//! Sets a new mesh
|
||||||
|
virtual void setMesh(IAnimatedMesh *mesh) = 0;
|
||||||
|
|
||||||
|
//! Returns the current mesh
|
||||||
|
virtual IAnimatedMesh *getMesh(void) = 0;
|
||||||
|
|
||||||
|
//! Set how the joints should be updated on render
|
||||||
|
virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) = 0;
|
||||||
|
|
||||||
|
//! Sets the transition time in seconds
|
||||||
|
/** Note: This needs to enable joints, and setJointmode set to
|
||||||
|
EJUOR_CONTROL. You must call animateJoints(), or the mesh will
|
||||||
|
not animate. */
|
||||||
|
virtual void setTransitionTime(f32 Time) = 0;
|
||||||
|
|
||||||
|
//! animates the joints in the mesh based on the current frame.
|
||||||
|
/** Also takes in to account transitions. */
|
||||||
|
virtual void animateJoints(bool CalculateAbsolutePositions = true) = 0;
|
||||||
|
|
||||||
|
//! render mesh ignoring its transformation.
|
||||||
|
/** Culling is unaffected. */
|
||||||
|
virtual void setRenderFromIdentity(bool On) = 0;
|
||||||
|
|
||||||
|
//! Creates a clone of this scene node and its children.
|
||||||
|
/** \param newParent An optional new parent.
|
||||||
|
\param newManager An optional new scene manager.
|
||||||
|
\return The newly created clone of this node. */
|
||||||
|
virtual ISceneNode *clone(ISceneNode *newParent = 0, ISceneManager *newManager = 0) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace scene
|
||||||
|
} // end namespace irr
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue