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
|
||||
*.h diff=cpp
|
||||
|
|
|
@ -8,6 +8,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'android/**'
|
||||
|
|
|
@ -8,6 +8,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- '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'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/ci/**'
|
||||
- 'misc/irrlichtmt_tag.txt'
|
||||
- 'Dockerfile'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows/linux.yml'
|
||||
|
@ -24,7 +25,6 @@ on:
|
|||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/ci/**'
|
||||
- 'misc/irrlichtmt_tag.txt'
|
||||
- 'Dockerfile'
|
||||
- '.dockerignore'
|
||||
- '.github/workflows/linux.yml'
|
||||
|
@ -108,7 +108,7 @@ jobs:
|
|||
- name: Install deps
|
||||
run: |
|
||||
source ./util/ci/common.sh
|
||||
install_linux_deps clang-14 gdb
|
||||
install_linux_deps clang-14 lldb
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
@ -151,13 +151,3 @@ jobs:
|
|||
- name: Test
|
||||
run: |
|
||||
./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'
|
||||
|
||||
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:
|
||||
name: "Compile and run multiplayer tests"
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install deps
|
||||
run: |
|
||||
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
|
||||
run: |
|
||||
./util/ci/build.sh
|
||||
env:
|
||||
CC: clang-10
|
||||
CXX: clang++-10
|
||||
CMAKE_FLAGS: "-DENABLE_GETTEXT=0 -DBUILD_SERVER=0"
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CMAKE_FLAGS: "-DENABLE_GETTEXT=0 -DBUILD_SERVER=0 -DBUILD_UNITTESTS=0"
|
||||
|
||||
- name: Integration test + devtest
|
||||
run: |
|
||||
|
|
|
@ -16,8 +16,8 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
if: github.repository == 'minetest/minetest'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- '.github/workflows/macos.yml'
|
||||
|
@ -33,7 +35,6 @@ jobs:
|
|||
|
||||
- name: Build
|
||||
run: |
|
||||
git clone https://github.com/minetest/irrlicht lib/irrlichtmt --depth 1 -b $(cat misc/irrlichtmt_tag.txt)
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. \
|
||||
|
|
|
@ -8,10 +8,11 @@ on:
|
|||
- 'lib/**.cpp'
|
||||
- 'src/**.[ch]'
|
||||
- 'src/**.cpp'
|
||||
- 'irr/**.[ch]'
|
||||
- 'irr/**.cpp'
|
||||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/buildbot/**'
|
||||
- 'misc/irrlichtmt_tag.txt'
|
||||
- 'misc/*.manifest'
|
||||
- '.github/workflows/windows.yml'
|
||||
pull_request:
|
||||
|
@ -23,7 +24,6 @@ on:
|
|||
- '**/CMakeLists.txt'
|
||||
- 'cmake/Modules/**'
|
||||
- 'util/buildbot/**'
|
||||
- 'misc/irrlichtmt_tag.txt'
|
||||
- 'misc/*.manifest'
|
||||
- '.github/workflows/windows.yml'
|
||||
|
||||
|
@ -97,11 +97,6 @@ jobs:
|
|||
steps:
|
||||
- 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
|
||||
uses: lukka/run-vcpkg@v7
|
||||
with:
|
||||
|
|
|
@ -64,6 +64,7 @@ AppDir
|
|||
/clientmods/*
|
||||
!/clientmods/preview/
|
||||
/client/mod_storage/
|
||||
/mod_data
|
||||
|
||||
## Configuration/log files
|
||||
minetest.conf
|
||||
|
@ -118,7 +119,7 @@ compile_commands.json
|
|||
*.sln
|
||||
.vs/
|
||||
|
||||
# Optional user provided library folder
|
||||
# Old irrlichtmt. Still ignored to make bisecting easier.
|
||||
lib/irrlichtmt
|
||||
|
||||
# Generated mod storage database
|
||||
|
|
|
@ -91,27 +91,12 @@ if(ANDROID)
|
|||
endif()
|
||||
|
||||
|
||||
set(IRRLICHTMT_BUILD_DIR "" CACHE PATH "Path to IrrlichtMt build directory.")
|
||||
if(ANDROID)
|
||||
# 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(TRUE)
|
||||
message(STATUS "Using imported IrrlichtMt at subdirectory 'irr'")
|
||||
if(BUILD_CLIENT)
|
||||
# tell IrrlichtMt to create a static library
|
||||
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)
|
||||
|
||||
if(NOT TARGET IrrlichtMt)
|
||||
|
@ -120,44 +105,7 @@ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt")
|
|||
else()
|
||||
add_library(IrrlichtMt::IrrlichtMt INTERFACE IMPORTED)
|
||||
set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt/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")
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/irr/include")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
ARG DOCKER_IMAGE=alpine:3.19
|
||||
FROM $DOCKER_IMAGE AS dev
|
||||
|
||||
ENV IRRLICHT_VERSION master
|
||||
ENV SPATIALINDEX_VERSION master
|
||||
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} && \
|
||||
cd luajit && \
|
||||
make amalg && make install && \
|
||||
cd /usr/src/ && \
|
||||
git clone --depth=1 https://github.com/minetest/irrlicht -b ${IRRLICHT_VERSION} && \
|
||||
cp -r irrlicht/include /usr/include/irrlichtmt
|
||||
cd /usr/src/
|
||||
|
||||
FROM dev as builder
|
||||
|
||||
|
@ -48,6 +45,7 @@ COPY lib /usr/src/minetest/lib
|
|||
COPY misc /usr/src/minetest/misc
|
||||
COPY po /usr/src/minetest/po
|
||||
COPY src /usr/src/minetest/src
|
||||
COPY irr /usr/src/minetest/irr
|
||||
COPY textures /usr/src/minetest/textures
|
||||
|
||||
WORKDIR /usr/src/minetest
|
||||
|
|
|
@ -108,9 +108,9 @@ Use `--help`
|
|||
|
||||
## 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
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ task prepareAssets() {
|
|||
from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders"
|
||||
}
|
||||
copy {
|
||||
from "../native/deps/armeabi-v7a/Irrlicht/Shaders" into "${assetsFolder}/client/shaders/Irrlicht"
|
||||
from "${projRoot}/irr/media/Shaders" into "${assetsFolder}/client/shaders/Irrlicht"
|
||||
}
|
||||
copy {
|
||||
from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
|
||||
|
@ -108,6 +108,10 @@ task prepareAssets() {
|
|||
preBuild.dependsOn zipAssets
|
||||
prepareAssets.dependsOn ':native:getDeps'
|
||||
|
||||
clean {
|
||||
delete new File("src/main/assets", "Minetest.zip")
|
||||
}
|
||||
|
||||
// Map for the version code that gives each ABI a value.
|
||||
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
|
||||
|
||||
buildscript {
|
||||
ext.ndk_version = '25.2.9519653'
|
||||
ext.ndk_version = '26.2.11394342'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
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");
|
||||
# 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
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# 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"'
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
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."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
command -v java >/dev/null || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD=java
|
||||
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
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --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
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
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
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# 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" "$@"
|
||||
|
|
|
@ -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
|
||||
task downloadDeps(type: Download) {
|
||||
def depsDir = new File(buildDir.parent, 'deps')
|
||||
def depsZip = new File(buildDir, 'deps.zip')
|
||||
def depsDir = new File(buildDir.parent, 'deps')
|
||||
if (new File(depsDir, 'armeabi-v7a').exists()) {
|
||||
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'
|
||||
dest depsZip
|
||||
overwrite false
|
||||
src 'https://github.com/minetest/minetest_android_deps/releases/download/latest/deps-lite.zip'
|
||||
dest depsZip
|
||||
overwrite false
|
||||
|
||||
task getDeps(dependsOn: downloadDeps, type: Copy) {
|
||||
depsDir.mkdir()
|
||||
from zipTree(depsZip)
|
||||
into depsDir
|
||||
doFirst { logger.lifecycle('Extracting to {}', depsDir) }
|
||||
task getDeps(dependsOn: downloadDeps, type: Copy) {
|
||||
depsDir.mkdir()
|
||||
from zipTree(depsZip)
|
||||
into 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)
|
||||
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)
|
||||
local params
|
||||
if type(seed) == "table" then
|
||||
|
|
|
@ -37,6 +37,8 @@ core.features = {
|
|||
blocking_pointability_type = true,
|
||||
dynamic_add_media_startup = true,
|
||||
dynamic_add_media_filepath = true,
|
||||
lsystem_decoration_type = true,
|
||||
item_meta_range = true,
|
||||
}
|
||||
|
||||
function core.has_feature(arg)
|
||||
|
|
|
@ -18,6 +18,7 @@ if core.settings:get_bool("profiler.load") then
|
|||
end
|
||||
|
||||
dofile(commonpath .. "after.lua")
|
||||
dofile(commonpath .. "metatable.lua")
|
||||
dofile(commonpath .. "mod_storage.lua")
|
||||
dofile(gamepath .. "item_entity.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_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
|
||||
dofile(asyncpath .. "mainmenu.lua")
|
||||
elseif INIT == "async_game" then
|
||||
dofile(commonpath .. "metatable.lua")
|
||||
dofile(asyncpath .. "game.lua")
|
||||
elseif INIT == "client" then
|
||||
dofile(scriptdir .. "client" .. DIR_DELIM .. "init.lua")
|
||||
|
|
|
@ -18,6 +18,26 @@
|
|||
-- Global menu data
|
||||
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 min_supp_proto, max_supp_proto
|
||||
|
||||
|
@ -27,6 +47,16 @@ function common_update_cached_supp_proto()
|
|||
end
|
||||
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
|
||||
|
||||
local function render_client_count(n)
|
||||
|
@ -140,11 +170,6 @@ function render_serverlist_row(spec)
|
|||
|
||||
return table.concat(details, ",")
|
||||
end
|
||||
---------------------------------------------------------------------------------
|
||||
os.tmpname = function()
|
||||
error('do not use') -- instead use core.get_temp_path()
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function menu_render_worldlist()
|
||||
local retval = {}
|
||||
|
|
|
@ -26,13 +26,23 @@ if not core.get_http_api then
|
|||
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 latest_releases
|
||||
do
|
||||
local tmp = core.get_once("cdb_latest_releases")
|
||||
if tmp then
|
||||
latest_releases = core.deserialize(tmp, true)
|
||||
has_fetched = latest_releases ~= nil
|
||||
if check_cache_age("cdb_updates_last_checked", 3 * 3600) then
|
||||
local f = io.open(cache_file_path, "r")
|
||||
local data = ""
|
||||
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
|
||||
|
||||
|
@ -97,7 +107,8 @@ local function fetch()
|
|||
return
|
||||
end
|
||||
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
|
||||
local maintab = ui.find_by_name("maintab")
|
||||
|
|
|
@ -15,15 +15,30 @@
|
|||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--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()
|
||||
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
|
||||
end
|
||||
|
||||
local games = core.get_games()
|
||||
for _, game in ipairs(games) do
|
||||
if game.id == "minetest" then
|
||||
core.settings:set_bool("no_mtg_notification", true)
|
||||
cache_settings:set_bool(SETTING_NAME, true)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -37,7 +52,7 @@ function check_reinstall_mtg()
|
|||
end
|
||||
end
|
||||
if not mtg_world_found then
|
||||
core.settings:set_bool("no_mtg_notification", true)
|
||||
cache_settings:set_bool(SETTING_NAME, true)
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -87,7 +102,7 @@ local function buttonhandler(this, fields)
|
|||
end
|
||||
|
||||
if fields.dismiss then
|
||||
core.settings:set_bool("no_mtg_notification", true)
|
||||
cache_settings:set_bool("no_mtg_notification", true)
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -51,12 +51,13 @@ end
|
|||
local function version_info_buttonhandler(this, fields)
|
||||
if fields.version_check_remind then
|
||||
-- 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()
|
||||
return true
|
||||
end
|
||||
if fields.version_check_never then
|
||||
core.settings:set("update_last_checked", "disabled")
|
||||
-- clear checked URL
|
||||
core.settings:set("update_information_url", "")
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
@ -116,7 +117,7 @@ local function on_version_info_received(json)
|
|||
return
|
||||
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)
|
||||
local new_number = type(json.latest) == "table" and json.latest.version_code
|
||||
|
@ -135,7 +136,7 @@ local function on_version_info_received(json)
|
|||
return
|
||||
end
|
||||
|
||||
core.settings:set("update_last_known", tostring(new_number))
|
||||
cache_settings:set("update_last_known", tostring(new_number))
|
||||
|
||||
-- Show version info dialog (once)
|
||||
maintab:hide()
|
||||
|
@ -149,20 +150,20 @@ end
|
|||
|
||||
function check_new_version()
|
||||
local url = core.settings:get("update_information_url")
|
||||
if core.settings:get("update_last_checked") == "disabled" or
|
||||
url == "" then
|
||||
if url == "" then
|
||||
-- Never show any updates
|
||||
return
|
||||
end
|
||||
|
||||
local time_now = os.time()
|
||||
local time_checked = tonumber(core.settings:get("update_last_checked")) or 0
|
||||
if time_now - time_checked < 2 * 24 * 3600 then
|
||||
-- Check interval of 2 entire days
|
||||
-- every 2 days
|
||||
if check_cache_age("update_last_checked", 2 * 24 * 3600) then
|
||||
return
|
||||
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)
|
||||
local http = core.get_http_api()
|
||||
|
|
|
@ -28,8 +28,6 @@ local basepath = core.get_builtin_path()
|
|||
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
|
||||
DIR_DELIM .. "pack" .. DIR_DELIM
|
||||
|
||||
dofile(menupath .. DIR_DELIM .. "misc.lua")
|
||||
|
||||
dofile(basepath .. "common" .. DIR_DELIM .. "filterlist.lua")
|
||||
dofile(basepath .. "fstk" .. DIR_DELIM .. "buttonbar.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 = {
|
||||
-- continent code we detected for ourselves
|
||||
my_continent = core.get_once("continent"),
|
||||
my_continent = nil,
|
||||
|
||||
-- list of locally favorites servers
|
||||
favorites = nil,
|
||||
|
@ -26,6 +26,15 @@ serverlistmgr = {
|
|||
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
|
||||
-- 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 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()
|
||||
if not serverlistmgr.servers then
|
||||
serverlistmgr.servers = {{
|
||||
|
@ -129,37 +154,23 @@ function serverlistmgr.sync()
|
|||
return
|
||||
end
|
||||
|
||||
-- only fetched once per MT instance
|
||||
if not serverlistmgr.my_continent and not geoip_downloading then
|
||||
geoip_downloading = true
|
||||
core.handle_async(
|
||||
function(param)
|
||||
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)
|
||||
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
|
||||
core.handle_async(fetch_geoip, nil, function(result)
|
||||
geoip_downloading = false
|
||||
if not result then
|
||||
return
|
||||
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
|
||||
|
||||
if public_downloading then
|
||||
|
@ -167,6 +178,7 @@ function serverlistmgr.sync()
|
|||
end
|
||||
public_downloading = true
|
||||
|
||||
-- note: this isn't cached because it's way too dynamic
|
||||
core.handle_async(
|
||||
function(param)
|
||||
local http = core.get_http_api()
|
||||
|
|
|
@ -158,7 +158,7 @@ return {
|
|||
"style[label_button;border=false]" ..
|
||||
"button[0.1,3.4;5.3,0.5;label_button;" ..
|
||||
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) .. "]"
|
||||
|
||||
-- Render information
|
||||
|
@ -188,10 +188,6 @@ return {
|
|||
end,
|
||||
|
||||
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
|
||||
local path = core.get_user_path() .. DIR_DELIM .. "debug.txt"
|
||||
core.share_file(path)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
_G.core = {get_once = function(_) end}
|
||||
_G.core = {}
|
||||
_G.unpack = table.unpack
|
||||
_G.check_cache_age = function() return false end
|
||||
_G.serverlistmgr = {}
|
||||
|
||||
dofile("builtin/common/vector.lua")
|
||||
|
|
|
@ -114,7 +114,11 @@ always_fly_fast (Always fly fast) bool true
|
|||
# the place button.
|
||||
#
|
||||
# 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.
|
||||
autojump (Automatic jumping) bool false
|
||||
|
@ -153,16 +157,21 @@ invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
|
|||
# Requires: !android
|
||||
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.
|
||||
#
|
||||
# Requires: touchscreen_gui
|
||||
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.
|
||||
# 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
|
||||
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]
|
||||
|
||||
|
@ -772,6 +794,7 @@ serverlist_url (Serverlist URL) string servers.minetest.net
|
|||
enable_split_login_register (Enable split login/register) bool true
|
||||
|
||||
# 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
|
||||
|
||||
[*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
|
||||
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.
|
||||
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
|
||||
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.
|
||||
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.
|
||||
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)
|
||||
{
|
||||
gl_FragColor = starColor;
|
||||
gl_FragColor = emissiveColor;
|
||||
}
|
||||
|
|
|
@ -1,31 +1,27 @@
|
|||
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_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_ft2build ${DEPS}/Freetype/include/freetype2)
|
||||
set(FREETYPE_LIBRARY ${DEPS}/Freetype/libfreetype.a)
|
||||
set(GETTEXT_INCLUDE_DIR ${DEPS}/Gettext/include;${DEPS}/Iconv/include)
|
||||
set(GETTEXT_LIBRARY ${DEPS}/Gettext/libintl.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_LIBRARY ${DEPS}/LuaJIT/libluajit.a)
|
||||
set(OGG_INCLUDE_DIR ${DEPS}/Vorbis/include)
|
||||
set(OGG_LIBRARY ${DEPS}/Vorbis/libogg.a)
|
||||
set(OPENAL_INCLUDE_DIR ${DEPS}/OpenAL-Soft/include)
|
||||
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_LIBRARY ${DEPS}/SQLite/libsqlite3.a)
|
||||
set(VORBIS_INCLUDE_DIR ${DEPS}/Vorbis/include)
|
||||
set(VORBISFILE_LIBRARY ${DEPS}/Vorbis/libvorbisfile.a)
|
||||
set(VORBIS_LIBRARY ${DEPS}/Vorbis/libvorbis.a)
|
||||
set(VORBISFILE_LIBRARY ${DEPS}/Vorbis/libvorbisfile.a)
|
||||
set(ZSTD_INCLUDE_DIR ${DEPS}/Zstd/include)
|
||||
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_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
|
||||
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_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
|
||||
|
|
|
@ -2,47 +2,47 @@
|
|||
|
||||
## Dependencies
|
||||
|
||||
| Dependency | Version | Commentary |
|
||||
| ---------- | ------- | -------------------------------------------------------------------- |
|
||||
| GCC | 7.5+ | or Clang 7.0.1+ |
|
||||
| CMake | 3.5+ | |
|
||||
| Dependency | Version | Commentary |
|
||||
| ---------- | ------- | ---------- |
|
||||
| GCC | 7.5+ | or Clang 7.0.1+ |
|
||||
| CMake | 3.5+ | |
|
||||
| IrrlichtMt | - | Custom version of Irrlicht, see https://github.com/minetest/irrlicht |
|
||||
| libjpeg | - | (via IrrlichtMt) |
|
||||
| libpng | - | (via IrrlichtMt) |
|
||||
| SDL | 2.x | (via IrrlichtMt) |
|
||||
| Freetype | 2.0+ | |
|
||||
| SQLite3 | 3+ | |
|
||||
| Zlib | - | |
|
||||
| Zstd | 1.0+ | |
|
||||
| LuaJIT | 2.0+ | Bundled Lua 5.1 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 |
|
||||
| Curl | 7.56.0+ | Optional |
|
||||
| gettext | - | Optional |
|
||||
| libjpeg | - | |
|
||||
| libpng | - | |
|
||||
| SDL | 2.x | |
|
||||
| Freetype | 2.0+ | |
|
||||
| SQLite3 | 3+ | |
|
||||
| Zlib | - | |
|
||||
| Zstd | 1.0+ | |
|
||||
| LuaJIT | 2.0+ | Bundled Lua 5.1 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 |
|
||||
| Curl | 7.56.0+ | Optional |
|
||||
| gettext | - | Optional |
|
||||
|
||||
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:
|
||||
|
||||
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:
|
||||
|
||||
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:
|
||||
|
||||
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:
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
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:
|
||||
|
||||
wget https://github.com/minetest/minetest/archive/master.tar.gz
|
||||
tar xf master.tar.gz
|
||||
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 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 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.
|
||||
* 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
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
* **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.
|
||||
* `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.
|
||||
|
|
|
@ -15,6 +15,7 @@ Notable pages:
|
|||
## In This Folder
|
||||
|
||||
* [Developing minetestserver with Docker](docker.md)
|
||||
* [Android Tips & Tricks](android.md)
|
||||
* [Miscellaneous](misc.md)
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
|
||||
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>`
|
||||
|
||||
Retrieves a tile at position x,y from the base image
|
||||
which it assumes to be a tilesheet with dimensions w,h.
|
||||
Retrieves a tile at position x, y (in tiles, 0-indexed)
|
||||
from the base image, which it assumes to be a tilesheet
|
||||
with dimensions w, h (in tiles).
|
||||
|
||||
#### `[colorize:<color>:<ratio>`
|
||||
|
||||
|
@ -1085,6 +1086,7 @@ Table used to specify how a sound is played:
|
|||
-- its end in `-start_time` seconds.
|
||||
-- It is unspecified what happens if `loop` is false and `start_time` is
|
||||
-- smaller than minus the sound's length.
|
||||
|
||||
-- Available since feature `sound_params_start_time`.
|
||||
|
||||
loop = false,
|
||||
|
@ -1098,6 +1100,21 @@ Table used to specify how a sound is played:
|
|||
-- Attach the sound to an object.
|
||||
-- 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,
|
||||
-- Only play for this player.
|
||||
-- Can't be used together with `exclude_player`.
|
||||
|
@ -1382,8 +1399,7 @@ Look for examples in `games/devtest` or `games/minetest_game`.
|
|||
* `liquid`
|
||||
* The cubic source node for a liquid.
|
||||
* Faces bordering to the same node are never rendered.
|
||||
* Connects to node specified in `liquid_alternative_flowing`.
|
||||
* You *must* set `liquid_alternative_source` to the node's own name.
|
||||
* Connects to node specified in `liquid_alternative_flowing` if specified.
|
||||
* Use `backface_culling = false` for the tiles you want to make
|
||||
visible when inside the node.
|
||||
* `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
|
||||
The default currently is the same as right/down.
|
||||
Example: 6 = 2 + 1*4 = middle,up
|
||||
* `range`: Overrides the pointing range
|
||||
Example: `meta:set_float("range", 4.2)`
|
||||
|
||||
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.
|
||||
* `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>]`
|
||||
|
||||
* `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.
|
||||
* 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>]`
|
||||
|
||||
* When clicked, fields will be sent and the form will quit.
|
||||
|
@ -3482,11 +3515,13 @@ Changes the style of the text.
|
|||
Sets global style.
|
||||
|
||||
Global only styles:
|
||||
|
||||
* `background`: Text background, a `colorspec` or `none`.
|
||||
* `margin`: Page margins in pixel.
|
||||
* `valign`: Text vertical alignment (`top`, `middle`, `bottom`).
|
||||
|
||||
Inheriting styles (affects child elements):
|
||||
|
||||
* `color`: Default text color. Given color is a `colorspec`.
|
||||
* `hovercolor`: Color of <action> tags when mouse is over.
|
||||
* `size`: Default text size.
|
||||
|
@ -3500,6 +3535,7 @@ tags appear.
|
|||
`<tag name=... color=... hovercolor=... font=... size=...>`
|
||||
|
||||
Defines or redefines tag style. This can be used to define new tags.
|
||||
|
||||
* `name`: Name of the tag to define or change.
|
||||
* `color`: Text color. 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.
|
||||
|
||||
* `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
|
||||
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 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
|
||||
|
@ -4005,25 +4054,31 @@ Two functions are provided to translate strings: `minetest.translate` and
|
|||
avoid clashes with other mods.
|
||||
This function must be given a number of arguments equal to the number of
|
||||
arguments the translated string expects.
|
||||
Arguments are literal strings -- they will not be translated, so if you want
|
||||
them to be, they need to come as outputs of `minetest.translate` as well.
|
||||
Arguments are literal strings -- they will not be translated.
|
||||
|
||||
For instance, suppose we want to translate "@1 Wool" with "@1" being replaced
|
||||
by the translation of "Red". We can do the following:
|
||||
For instance, suppose we want to greet players when they join. We can do the
|
||||
following:
|
||||
|
||||
```lua
|
||||
local S = minetest.get_translator()
|
||||
S("@1 Wool", S("Red"))
|
||||
```
|
||||
```lua
|
||||
local S = minetest.get_translator("hello")
|
||||
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
|
||||
not have localization enabled. However, if we have for instance a translation
|
||||
file named `wool.fr.tr` containing the following:
|
||||
When someone called "CoolGuy" joins the game with an old client or a client
|
||||
that does not have localization enabled, they will see `Hello CoolGuy, how are
|
||||
you today?`
|
||||
|
||||
@1 Wool=Laine @1
|
||||
Red=Rouge
|
||||
However, if we have for instance a translation file named `hello.de.tr`
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
|
@ -5187,6 +5247,12 @@ Minetest includes the following settings to control behavior of privileges:
|
|||
|
||||
* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"`
|
||||
* 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.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 supports `filename` and `filedata` parameters (5.9.0)
|
||||
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.
|
||||
* `minetest.get_node_or_nil(pos)`
|
||||
* 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])`
|
||||
* 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
|
||||
|
@ -5928,7 +5999,7 @@ handler.
|
|||
* `minetest.add_entity(pos, name, [staticdata])`: Spawn Lua-defined entity at
|
||||
position.
|
||||
* 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.
|
||||
* `minetest.add_item(pos, item)`: Spawn item
|
||||
* Returns `ObjectRef`, or `nil` if failed
|
||||
|
@ -6120,13 +6191,16 @@ handler.
|
|||
* Returns the position of the blocking node when `false`
|
||||
* `pos1`: First 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.
|
||||
* `pos1`: start of the ray
|
||||
* `pos2`: end of the ray
|
||||
* `objects`: if false, only nodes will be returned. Default is `true`.
|
||||
* `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)`
|
||||
* returns table containing path that can be walked on
|
||||
* 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
|
||||
is initialized. You can use this to preload code which you can then call
|
||||
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
|
||||
|
||||
|
@ -6528,6 +6614,7 @@ Class instances that can be transferred between environments:
|
|||
Functions:
|
||||
* Standalone helpers such as logging, filesystem, encoding,
|
||||
hashing or compression APIs
|
||||
* `minetest.register_async_metatable` (see above)
|
||||
|
||||
Variables:
|
||||
* `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
|
||||
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.
|
||||
|
||||
|
@ -7765,10 +7888,14 @@ child will follow movement and rotation of that bone.
|
|||
* Second column: subject looking to the left
|
||||
* Third column: subject backing the camera
|
||||
* Fourth column: subject looking to the right
|
||||
* Fifth column: subject viewed from above
|
||||
* 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()`
|
||||
* Fifth column: subject viewed from above
|
||||
* Sixth column: subject viewed from below
|
||||
* `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)
|
||||
|
||||
|
@ -8473,7 +8600,8 @@ Player properties need to be saved manually.
|
|||
-- "mesh" uses the defined mesh model.
|
||||
-- "wielditem" is used for dropped items.
|
||||
-- (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
|
||||
-- that, otherwise:
|
||||
-- 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.
|
||||
-- "sprite" uses 1 texture.
|
||||
-- "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)
|
||||
-- Deprecated usage of "wielditem" expects 'textures = {itemname}' (see 'visual' above).
|
||||
|
||||
colors = {},
|
||||
-- Number of required colors depends on visual
|
||||
|
@ -8817,6 +8945,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
|
|||
|
||||
range = 4.0,
|
||||
-- Range of node and object pointing that is possible with this item held
|
||||
-- Can be overridden with itemstack meta.
|
||||
|
||||
liquids_pointable = false,
|
||||
-- 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 = {
|
||||
["modname:entityname"] = true,
|
||||
["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:"`.
|
||||
-- (For objects `armor_groups` are used and for players the entity name is irrelevant.)
|
||||
-- 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
|
||||
-- upon digging. Server will always update with actual result shortly.
|
||||
|
||||
touch_interaction = {
|
||||
-- Only affects touchscreen clients.
|
||||
-- Defines the meaning of short and long taps with the item in hand.
|
||||
-- The fields in this table have two valid values:
|
||||
-- * "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",
|
||||
touch_interaction = <TouchInteractionMode> OR {
|
||||
pointed_nothing = <TouchInteractionMode>,
|
||||
pointed_node = <TouchInteractionMode>,
|
||||
pointed_object = <TouchInteractionMode>,
|
||||
},
|
||||
-- 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 = {
|
||||
-- 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
|
||||
-- source version (`liquid_alternative_source`) of a liquid.
|
||||
--
|
||||
-- Specifically, these fields are required if any of these is true:
|
||||
-- * `liquidtype ~= "none" or
|
||||
-- * `drawtype == "liquid" or
|
||||
-- * `drawtype == "flowingliquid"
|
||||
-- Specifically, these fields are required if `liquidtype ~= "none"` or
|
||||
-- `drawtype == "flowingliquid"`.
|
||||
--
|
||||
-- Liquids consist of up to two nodes: source and flowing.
|
||||
--
|
||||
|
@ -9988,7 +10116,7 @@ See [Decoration types]. Used by `minetest.register_decoration`.
|
|||
```lua
|
||||
{
|
||||
deco_type = "simple",
|
||||
-- Type. "simple" or "schematic" supported
|
||||
-- Type. "simple", "schematic" or "lsystem" supported
|
||||
|
||||
place_on = "default:dirt_with_grass",
|
||||
-- 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.
|
||||
-- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer
|
||||
-- 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
|
||||
* `core.get_version()` (possible in async calls)
|
||||
* 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,
|
||||
})
|
||||
|
||||
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", {
|
||||
params = "",
|
||||
description = "Benchmark: Bulk-set 99×99×99 stone nodes",
|
||||
|
@ -79,25 +95,15 @@ minetest.register_chatcommand("bench_bulk_set_node", {
|
|||
if not player then
|
||||
return false, "No player."
|
||||
end
|
||||
local pos_list = {}
|
||||
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
|
||||
local pos_list = get_positions_cube(player:get_pos())
|
||||
|
||||
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
|
||||
-- due to different node topology
|
||||
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()
|
||||
for i=1,#pos_list do
|
||||
|
@ -114,4 +120,37 @@ minetest.register_chatcommand("bench_bulk_set_node", {
|
|||
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")
|
||||
end,
|
||||
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())
|
||||
return stack:get_count()
|
||||
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow put' (10) event for " .. stack:to_string())
|
||||
return 10
|
||||
end,
|
||||
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())
|
||||
return stack:get_count()
|
||||
print_to_everything("Chest: ".. player:get_player_name() .. " triggered 'allow take' (20) event for " .. stack:to_string())
|
||||
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,
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
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)
|
||||
print_to_everything("Chest: ".. player:get_player_name() .. " took " .. stack:to_string())
|
||||
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
|
||||
|
||||
-- \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 = [[
|
||||
style_type[label,button,image_button,item_image_button,
|
||||
tabheader,scrollbar,table,animated_image
|
||||
,field,textarea,checkbox,dropdown;noclip=%c]
|
||||
|
||||
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]
|
||||
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]
|
||||
|
@ -92,6 +95,7 @@ This is a normal text.
|
|||
<t_green>color=green</t_green>
|
||||
Action: <action name=color><t_green>color=green</t_green></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_mono>font=mono</t_mono>
|
||||
<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 = [[
|
||||
style[one_btn1;bgcolor=red;textcolor=yellow;bgcolor_hovered=orange;
|
||||
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] ]]..
|
||||
"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
|
||||
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 },
|
||||
})
|
||||
|
||||
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
|
||||
|
||||
local alphas = { 64, 128, 191 }
|
||||
|
@ -69,6 +88,19 @@ for a=1,#alphas do
|
|||
})
|
||||
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
|
||||
|
||||
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,
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
light_source = 0,
|
||||
pos = vector.new(-1, -2, -3),
|
||||
}
|
||||
|
||||
local function test_object_passing()
|
||||
|
@ -166,3 +166,44 @@ local function test_userdata_passing2(cb, _, pos)
|
|||
end, vm, pos)
|
||||
end
|
||||
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
|
||||
|
||||
local function wait_for_map(player, callback)
|
||||
local function wait_for_map(pos, callback)
|
||||
local function check()
|
||||
if core.get_node_or_nil(player:get_pos()) ~= nil then
|
||||
if core.get_node(pos).name ~= "ignore" then
|
||||
callback()
|
||||
else
|
||||
core.after(0, check)
|
||||
|
@ -119,8 +119,8 @@ local function wait_for_map(player, callback)
|
|||
check()
|
||||
end
|
||||
|
||||
-- This runs in a coroutine so it uses await()
|
||||
function unittests.run_all()
|
||||
-- This runs in a coroutine so it uses await().
|
||||
local counters = { time = 0, total = 0, passed = 0 }
|
||||
|
||||
-- Run standalone tests first
|
||||
|
@ -143,10 +143,11 @@ function unittests.run_all()
|
|||
end
|
||||
|
||||
-- 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)
|
||||
wait_for_map(player, cb)
|
||||
wait_for_map(pos, cb)
|
||||
end)
|
||||
local pos = vector.round(player:get_pos())
|
||||
for idx = 1, #unittests.list do
|
||||
local def = unittests.list[idx]
|
||||
if not def.done then
|
||||
|
@ -182,6 +183,7 @@ dofile(modpath .. "/get_version.lua")
|
|||
dofile(modpath .. "/itemstack_equals.lua")
|
||||
dofile(modpath .. "/content_ids.lua")
|
||||
dofile(modpath .. "/metadata.lua")
|
||||
dofile(modpath .. "/raycast.lua")
|
||||
|
||||
--------------
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@ unittests = {}
|
|||
|
||||
core.log("info", "Hello World")
|
||||
|
||||
unittests.custom_metatable = {}
|
||||
core.register_async_metatable("unittests:custom_metatable", unittests.custom_metatable)
|
||||
|
||||
local function do_tests()
|
||||
assert(core == minetest)
|
||||
-- stuff that should not be here
|
||||
|
|
|
@ -99,17 +99,24 @@ local function test_clear_meta(_, pos)
|
|||
end
|
||||
unittests.register("test_clear_meta", test_clear_meta, {map=true})
|
||||
|
||||
local on_punch_called
|
||||
minetest.register_on_punchnode(function()
|
||||
local on_punch_called, on_place_called
|
||||
core.register_on_placenode(function()
|
||||
on_place_called = true
|
||||
end)
|
||||
core.register_on_punchnode(function()
|
||||
on_punch_called = true
|
||||
end)
|
||||
unittests.register("test_punch_node", function(_, pos)
|
||||
minetest.place_node(pos, {name="basenodes:dirt"})
|
||||
local function test_node_callbacks(_, pos)
|
||||
on_place_called = false
|
||||
on_punch_called = false
|
||||
minetest.punch_node(pos)
|
||||
minetest.remove_node(pos)
|
||||
-- currently failing: assert(on_punch_called)
|
||||
end, {map=true})
|
||||
|
||||
core.place_node(pos, {name="basenodes:dirt"})
|
||||
assert(on_place_called, "on_place not called")
|
||||
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 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