Merge branch 'master' of https://github.com/minetest/minetest
This commit is contained in:
commit
cca4254f7c
25
.github/workflows/build.yml
vendored
25
.github/workflows/build.yml
vendored
@ -33,9 +33,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install g++-6 gcc-6 -qyy
|
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps
|
install_linux_deps g++-6
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
@ -55,9 +54,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install g++-8 gcc-8 -qyy
|
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps
|
install_linux_deps g++-8
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
@ -77,9 +75,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install clang-3.9 -qyy
|
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps
|
install_linux_deps clang-3.9
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
@ -99,11 +96,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install clang-9 valgrind -qyy
|
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps
|
install_linux_deps clang-9 valgrind libluajit-5.1-dev
|
||||||
env:
|
|
||||||
WITH_LUAJIT: 1
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
@ -111,6 +105,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CC: clang-9
|
CC: clang-9
|
||||||
CXX: clang++-9
|
CXX: clang++-9
|
||||||
|
CMAKE_FLAGS: "-DREQUIRE_LUAJIT=1"
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
@ -128,9 +123,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install clang-9 -qyy
|
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps
|
install_linux_deps clang-9
|
||||||
|
|
||||||
- name: Build prometheus-cpp
|
- name: Build prometheus-cpp
|
||||||
run: |
|
run: |
|
||||||
@ -156,9 +150,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install clang-9 -qyy
|
|
||||||
source ./util/ci/common.sh
|
source ./util/ci/common.sh
|
||||||
install_linux_deps
|
install_linux_deps clang-9
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
@ -188,7 +181,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install compiler
|
- name: Install compiler
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install gettext -qyy
|
sudo apt-get update -q && sudo apt-get install gettext -qyy
|
||||||
wget http://minetest.kitsunemimi.pw/mingw-w64-i686_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
wget http://minetest.kitsunemimi.pw/mingw-w64-i686_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
||||||
sudo tar -xaf mingw.tar.xz -C /usr
|
sudo tar -xaf mingw.tar.xz -C /usr
|
||||||
|
|
||||||
@ -206,7 +199,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install compiler
|
- name: Install compiler
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install gettext -qyy
|
sudo apt-get update -q && sudo apt-get install gettext -qyy
|
||||||
wget http://minetest.kitsunemimi.pw/mingw-w64-x86_64_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
wget http://minetest.kitsunemimi.pw/mingw-w64-x86_64_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
||||||
sudo tar -xaf mingw.tar.xz -C /usr
|
sudo tar -xaf mingw.tar.xz -C /usr
|
||||||
|
|
||||||
|
131
.gitlab-ci.yml
131
.gitlab-ci.yml
@ -18,12 +18,12 @@ variables:
|
|||||||
- mkdir cmakebuild
|
- mkdir cmakebuild
|
||||||
- mkdir -p artifact/minetest/usr/
|
- mkdir -p artifact/minetest/usr/
|
||||||
- cd cmakebuild
|
- cd cmakebuild
|
||||||
- cmake -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE ..
|
- cmake -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DENABLE_SYSTEM_JSONCPP=TRUE -DBUILD_SERVER=TRUE ..
|
||||||
- make -j2
|
- make -j2
|
||||||
- make install
|
- make install
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_success
|
when: on_success
|
||||||
expire_in: 2h
|
expire_in: 1h
|
||||||
paths:
|
paths:
|
||||||
- artifact/*
|
- artifact/*
|
||||||
|
|
||||||
@ -34,15 +34,14 @@ variables:
|
|||||||
- apt-get install -y git
|
- apt-get install -y git
|
||||||
- mkdir -p build/deb/minetest/DEBIAN/
|
- mkdir -p build/deb/minetest/DEBIAN/
|
||||||
- cp misc/debpkg-control build/deb/minetest/DEBIAN/control
|
- cp misc/debpkg-control build/deb/minetest/DEBIAN/control
|
||||||
- cp -Rp artifact/minetest/usr build/deb/minetest/
|
- cp -a artifact/minetest/usr build/deb/minetest/
|
||||||
script:
|
script:
|
||||||
- git clone $MINETEST_GAME_REPO build/deb/minetest/usr/share/minetest/games/minetest_game
|
- git clone $MINETEST_GAME_REPO build/deb/minetest/usr/share/minetest/games/minetest_game
|
||||||
- rm -Rf build/deb/minetest/usr/share/minetest/games/minetest/.git
|
- rm -rf build/deb/minetest/usr/share/minetest/games/minetest/.git
|
||||||
- sed -i 's/DATEPLACEHOLDER/'$(date +%y.%m.%d)'/g' build/deb/minetest/DEBIAN/control
|
- sed -i 's/DATEPLACEHOLDER/'$(date +%y.%m.%d)'/g' build/deb/minetest/DEBIAN/control
|
||||||
- sed -i 's/LEVELDB_PLACEHOLDER/'$LEVELDB_PKG'/g' build/deb/minetest/DEBIAN/control
|
- sed -i 's/LEVELDB_PLACEHOLDER/'$LEVELDB_PKG'/g' build/deb/minetest/DEBIAN/control
|
||||||
- cd build/deb/ && dpkg-deb -b minetest/ && mv minetest.deb ../../
|
- cd build/deb/ && dpkg-deb -b minetest/ && mv minetest.deb ../../
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_success
|
|
||||||
expire_in: 90 day
|
expire_in: 90 day
|
||||||
paths:
|
paths:
|
||||||
- ./*.deb
|
- ./*.deb
|
||||||
@ -51,44 +50,14 @@ variables:
|
|||||||
stage: deploy
|
stage: deploy
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
- apt-get install -y libc6 libcurl3-gnutls libfreetype6 libirrlicht1.8 $LEVELDB_PKG liblua5.1-0 libluajit-5.1-2 libopenal1 libstdc++6 libvorbisfile3 libx11-6 zlib1g
|
|
||||||
script:
|
script:
|
||||||
- dpkg -i ./*.deb
|
- apt-get install -y ./*.deb
|
||||||
|
- minetest --version
|
||||||
|
|
||||||
##
|
##
|
||||||
## Debian
|
## Debian
|
||||||
##
|
##
|
||||||
|
|
||||||
# Jessie
|
|
||||||
|
|
||||||
build:debian-8:
|
|
||||||
extends: .build_template
|
|
||||||
image: debian:8
|
|
||||||
before_script:
|
|
||||||
- echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main" > /etc/apt/sources.list.d/uptodate-toolchain.list
|
|
||||||
- apt-key adv --keyserver keyserver.ubuntu.com --recv BA9EF27F
|
|
||||||
- apt-get update -y
|
|
||||||
- apt-get -y install build-essential gcc-6 g++-6 libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
|
||||||
variables:
|
|
||||||
CC: gcc-6
|
|
||||||
CXX: g++-6
|
|
||||||
|
|
||||||
package:debian-8:
|
|
||||||
extends: .debpkg_template
|
|
||||||
image: debian:8
|
|
||||||
dependencies:
|
|
||||||
- build:debian-8
|
|
||||||
variables:
|
|
||||||
LEVELDB_PKG: libleveldb1
|
|
||||||
|
|
||||||
deploy:debian-8:
|
|
||||||
extends: .debpkg_install
|
|
||||||
image: debian:8
|
|
||||||
dependencies:
|
|
||||||
- package:debian-8
|
|
||||||
variables:
|
|
||||||
LEVELDB_PKG: libleveldb1
|
|
||||||
|
|
||||||
# Stretch
|
# Stretch
|
||||||
|
|
||||||
build:debian-9:
|
build:debian-9:
|
||||||
@ -101,7 +70,7 @@ build:debian-9:
|
|||||||
package:debian-9:
|
package:debian-9:
|
||||||
extends: .debpkg_template
|
extends: .debpkg_template
|
||||||
image: debian:9
|
image: debian:9
|
||||||
dependencies:
|
needs:
|
||||||
- build:debian-9
|
- build:debian-9
|
||||||
variables:
|
variables:
|
||||||
LEVELDB_PKG: libleveldb1v5
|
LEVELDB_PKG: libleveldb1v5
|
||||||
@ -109,12 +78,10 @@ package:debian-9:
|
|||||||
deploy:debian-9:
|
deploy:debian-9:
|
||||||
extends: .debpkg_install
|
extends: .debpkg_install
|
||||||
image: debian:9
|
image: debian:9
|
||||||
dependencies:
|
needs:
|
||||||
- package:debian-9
|
- package:debian-9
|
||||||
variables:
|
|
||||||
LEVELDB_PKG: libleveldb1v5
|
|
||||||
|
|
||||||
# Stretch
|
# Buster
|
||||||
|
|
||||||
build:debian-10:
|
build:debian-10:
|
||||||
extends: .build_template
|
extends: .build_template
|
||||||
@ -126,7 +93,7 @@ build:debian-10:
|
|||||||
package:debian-10:
|
package:debian-10:
|
||||||
extends: .debpkg_template
|
extends: .debpkg_template
|
||||||
image: debian:10
|
image: debian:10
|
||||||
dependencies:
|
needs:
|
||||||
- build:debian-10
|
- build:debian-10
|
||||||
variables:
|
variables:
|
||||||
LEVELDB_PKG: libleveldb1d
|
LEVELDB_PKG: libleveldb1d
|
||||||
@ -134,10 +101,9 @@ package:debian-10:
|
|||||||
deploy:debian-10:
|
deploy:debian-10:
|
||||||
extends: .debpkg_install
|
extends: .debpkg_install
|
||||||
image: debian:10
|
image: debian:10
|
||||||
dependencies:
|
needs:
|
||||||
- package:debian-10
|
- package:debian-10
|
||||||
variables:
|
|
||||||
LEVELDB_PKG: libleveldb1d
|
|
||||||
##
|
##
|
||||||
## Ubuntu
|
## Ubuntu
|
||||||
##
|
##
|
||||||
@ -154,7 +120,7 @@ build:ubuntu-16.04:
|
|||||||
package:ubuntu-16.04:
|
package:ubuntu-16.04:
|
||||||
extends: .debpkg_template
|
extends: .debpkg_template
|
||||||
image: ubuntu:xenial
|
image: ubuntu:xenial
|
||||||
dependencies:
|
needs:
|
||||||
- build:ubuntu-16.04
|
- build:ubuntu-16.04
|
||||||
variables:
|
variables:
|
||||||
LEVELDB_PKG: libleveldb1v5
|
LEVELDB_PKG: libleveldb1v5
|
||||||
@ -162,10 +128,8 @@ package:ubuntu-16.04:
|
|||||||
deploy:ubuntu-16.04:
|
deploy:ubuntu-16.04:
|
||||||
extends: .debpkg_install
|
extends: .debpkg_install
|
||||||
image: ubuntu:xenial
|
image: ubuntu:xenial
|
||||||
dependencies:
|
needs:
|
||||||
- package:ubuntu-16.04
|
- package:ubuntu-16.04
|
||||||
variables:
|
|
||||||
LEVELDB_PKG: libleveldb1v5
|
|
||||||
|
|
||||||
# Bionic
|
# Bionic
|
||||||
|
|
||||||
@ -179,7 +143,7 @@ build:ubuntu-18.04:
|
|||||||
package:ubuntu-18.04:
|
package:ubuntu-18.04:
|
||||||
extends: .debpkg_template
|
extends: .debpkg_template
|
||||||
image: ubuntu:bionic
|
image: ubuntu:bionic
|
||||||
dependencies:
|
needs:
|
||||||
- build:ubuntu-18.04
|
- build:ubuntu-18.04
|
||||||
variables:
|
variables:
|
||||||
LEVELDB_PKG: libleveldb1v5
|
LEVELDB_PKG: libleveldb1v5
|
||||||
@ -187,25 +151,22 @@ package:ubuntu-18.04:
|
|||||||
deploy:ubuntu-18.04:
|
deploy:ubuntu-18.04:
|
||||||
extends: .debpkg_install
|
extends: .debpkg_install
|
||||||
image: ubuntu:bionic
|
image: ubuntu:bionic
|
||||||
dependencies:
|
needs:
|
||||||
- package:ubuntu-18.04
|
- package:ubuntu-18.04
|
||||||
variables:
|
|
||||||
LEVELDB_PKG: libleveldb1v5
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Fedora
|
## Fedora
|
||||||
##
|
##
|
||||||
|
|
||||||
# Do we need to support this old version ?
|
# Fedora 28 <-> RHEL 8
|
||||||
build:fedora-24:
|
build:fedora-28:
|
||||||
extends: .build_template
|
extends: .build_template
|
||||||
image: fedora:24
|
image: fedora:28
|
||||||
before_script:
|
before_script:
|
||||||
- dnf -y install make automake gcc gcc-c++ kernel-devel cmake libcurl* openal* libvorbis* libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
|
- dnf -y install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Mingw for Windows
|
## MinGW for Windows
|
||||||
##
|
##
|
||||||
|
|
||||||
.generic_win_template:
|
.generic_win_template:
|
||||||
@ -213,68 +174,63 @@ build:fedora-24:
|
|||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
- apt-get install -y wget xz-utils unzip git cmake gettext
|
- apt-get install -y wget xz-utils unzip git cmake gettext
|
||||||
- wget -q http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
- wget -nv http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
|
||||||
- tar -xaf mingw.tar.xz -C /usr
|
- tar -xaf mingw.tar.xz -C /usr
|
||||||
|
|
||||||
.build_win_template:
|
.build_win_template:
|
||||||
extends: .generic_win_template
|
extends: .generic_win_template
|
||||||
stage: build
|
stage: build
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_success
|
expire_in: 1h
|
||||||
expire_in: 2h
|
|
||||||
paths:
|
paths:
|
||||||
- build/*
|
- build/minetest/_build/*
|
||||||
|
|
||||||
.package_win_template:
|
.package_win_template:
|
||||||
extends: .generic_win_template
|
extends: .generic_win_template
|
||||||
stage: package
|
stage: package
|
||||||
script:
|
script:
|
||||||
- cd build/minetest/_build
|
- unzip build/minetest/_build/minetest-*.zip
|
||||||
- make package
|
- cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libgcc*.dll minetest-*-win*/bin/
|
||||||
- cd ../../../
|
- cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libstdc++*.dll minetest-*-win*/bin/
|
||||||
- mkdir minetest-win-${WIN_ARCH}
|
- cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libwinpthread*.dll minetest-*-win*/bin/
|
||||||
- unzip build/minetest/_build/minetest-*-win*.zip -d minetest-win-${WIN_ARCH}
|
|
||||||
- cp /usr/${WIN_ARCH}-w64-mingw32/bin/libgcc*.dll minetest-win-${WIN_ARCH}/minetest-*-win*/bin
|
|
||||||
- cp /usr/${WIN_ARCH}-w64-mingw32/bin/libstdc++*.dll minetest-win-${WIN_ARCH}/minetest-*-win*/bin
|
|
||||||
- cp /usr/${WIN_ARCH}-w64-mingw32/bin/libwinpthread*.dll minetest-win-${WIN_ARCH}/minetest-*-win*/bin
|
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_success
|
|
||||||
expire_in: 90 day
|
expire_in: 90 day
|
||||||
paths:
|
paths:
|
||||||
- minetest-win-*/*
|
- minetest-*-win*/*
|
||||||
|
|
||||||
build:win32:
|
build:win32:
|
||||||
extends: .build_win_template
|
extends: .build_win_template
|
||||||
script:
|
script:
|
||||||
- ./util/buildbot/buildwin32.sh build
|
- ./util/buildbot/buildwin32.sh build
|
||||||
variables:
|
variables:
|
||||||
NO_PACKAGE: "1"
|
|
||||||
WIN_ARCH: "i686"
|
WIN_ARCH: "i686"
|
||||||
|
|
||||||
package:win32:
|
package:win32:
|
||||||
extends: .package_win_template
|
extends: .package_win_template
|
||||||
dependencies:
|
needs:
|
||||||
- build:win32
|
- build:win32
|
||||||
variables:
|
variables:
|
||||||
NO_PACKAGE: "1"
|
|
||||||
WIN_ARCH: "i686"
|
WIN_ARCH: "i686"
|
||||||
|
|
||||||
|
|
||||||
build:win64:
|
build:win64:
|
||||||
extends: .build_win_template
|
extends: .build_win_template
|
||||||
script:
|
script:
|
||||||
- ./util/buildbot/buildwin64.sh build
|
- ./util/buildbot/buildwin64.sh build
|
||||||
variables:
|
variables:
|
||||||
NO_PACKAGE: "1"
|
|
||||||
WIN_ARCH: "x86_64"
|
WIN_ARCH: "x86_64"
|
||||||
|
|
||||||
package:win64:
|
package:win64:
|
||||||
extends: .package_win_template
|
extends: .package_win_template
|
||||||
dependencies:
|
needs:
|
||||||
- build:win64
|
- build:win64
|
||||||
variables:
|
variables:
|
||||||
NO_PACKAGE: "1"
|
|
||||||
WIN_ARCH: "x86_64"
|
WIN_ARCH: "x86_64"
|
||||||
|
|
||||||
|
##
|
||||||
|
## Docker
|
||||||
|
##
|
||||||
|
|
||||||
package:docker:
|
package:docker:
|
||||||
stage: package
|
stage: package
|
||||||
image: docker:stable
|
image: docker:stable
|
||||||
@ -288,6 +244,10 @@ package:docker:
|
|||||||
- docker push ${CONTAINER_IMAGE}/server:$CI_COMMIT_REF_NAME
|
- docker push ${CONTAINER_IMAGE}/server:$CI_COMMIT_REF_NAME
|
||||||
- docker push ${CONTAINER_IMAGE}/server:latest
|
- docker push ${CONTAINER_IMAGE}/server:latest
|
||||||
|
|
||||||
|
##
|
||||||
|
## Gitlab Pages (Lua API documentation)
|
||||||
|
##
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
image: python:3.8
|
image: python:3.8
|
||||||
@ -303,10 +263,14 @@ pages:
|
|||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
|
##
|
||||||
|
## AppImage
|
||||||
|
##
|
||||||
|
|
||||||
package:appimage-client:
|
package:appimage-client:
|
||||||
stage: package
|
stage: package
|
||||||
image: appimagecrafters/appimage-builder
|
image: appimagecrafters/appimage-builder
|
||||||
dependencies:
|
needs:
|
||||||
- build:ubuntu-18.04
|
- build:ubuntu-18.04
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
@ -315,16 +279,15 @@ package:appimage-client:
|
|||||||
- mkdir AppDir
|
- mkdir AppDir
|
||||||
- cp -a artifact/minetest/usr/ AppDir/usr/
|
- cp -a artifact/minetest/usr/ AppDir/usr/
|
||||||
- rm AppDir/usr/bin/minetestserver
|
- rm AppDir/usr/bin/minetestserver
|
||||||
- cp -R clientmods AppDir/usr/share/minetest
|
- cp -a clientmods AppDir/usr/share/minetest
|
||||||
script:
|
script:
|
||||||
- git clone $MINETEST_GAME_REPO AppDir/usr/share/minetest/games/minetest_game
|
- git clone $MINETEST_GAME_REPO AppDir/usr/share/minetest/games/minetest_game
|
||||||
- rm -Rf AppDir/usr/share/minetest/games/minetest/.git
|
- rm -rf AppDir/usr/share/minetest/games/minetest/.git
|
||||||
- export VERSION=$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA
|
- export VERSION=$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA
|
||||||
# Remove PrefersNonDefaultGPU property due to validation errors
|
# Remove PrefersNonDefaultGPU property due to validation errors
|
||||||
- sed -i '/PrefersNonDefaultGPU/d' AppDir/usr/share/applications/net.minetest.minetest.desktop
|
- sed -i '/PrefersNonDefaultGPU/d' AppDir/usr/share/applications/net.minetest.minetest.desktop
|
||||||
- appimage-builder --skip-test
|
- appimage-builder --skip-test
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_success
|
|
||||||
expire_in: 90 day
|
expire_in: 90 day
|
||||||
paths:
|
paths:
|
||||||
- ./*.AppImage
|
- ./*.AppImage
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
if(${CMAKE_VERSION} STREQUAL "2.8.2")
|
|
||||||
# Bug http://vtk.org/Bug/view.php?id=11020
|
|
||||||
message(WARNING "CMake/CPack version 2.8.2 will not create working .deb packages!")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# This can be read from ${PROJECT_NAME} after project() is called
|
# This can be read from ${PROJECT_NAME} after project() is called
|
||||||
project(minetest)
|
project(minetest)
|
||||||
set(PROJECT_NAME_CAPITALIZED "Dragonfire")
|
set(PROJECT_NAME_CAPITALIZED "Dragonfire")
|
||||||
|
|
||||||
# Works only for cmake 3.1 and greater
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(GCC_MINIMUM_VERSION "4.8")
|
set(GCC_MINIMUM_VERSION "4.8")
|
||||||
set(CLANG_MINIMUM_VERSION "3.4")
|
set(CLANG_MINIMUM_VERSION "3.4")
|
||||||
@ -278,11 +272,12 @@ if(WIN32)
|
|||||||
set(CPACK_GENERATOR ZIP)
|
set(CPACK_GENERATOR ZIP)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
set(CPACK_GENERATOR WIX ZIP)
|
set(CPACK_GENERATOR WIX)
|
||||||
set(CPACK_PACKAGE_NAME "${PROJECT_NAME_CAPITALIZED}")
|
set(CPACK_PACKAGE_NAME "${PROJECT_NAME_CAPITALIZED}")
|
||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME_CAPITALIZED}")
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY ".")
|
||||||
set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME} "${PROJECT_NAME_CAPITALIZED}")
|
set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME} "${PROJECT_NAME_CAPITALIZED}")
|
||||||
set(CPACK_CREATE_DESKTOP_LINKS ${PROJECT_NAME})
|
set(CPACK_CREATE_DESKTOP_LINKS ${PROJECT_NAME})
|
||||||
|
set(CPACK_PACKAGING_INSTALL_PREFIX "/${PROJECT_NAME_CAPITALIZED}")
|
||||||
|
|
||||||
set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/misc/minetest-icon.ico")
|
set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/misc/minetest-icon.ico")
|
||||||
# Supported languages can be found at
|
# Supported languages can be found at
|
||||||
|
13
LICENSE.txt
13
LICENSE.txt
@ -11,6 +11,9 @@ http://creativecommons.org/licenses/by-sa/3.0/
|
|||||||
textures/base/pack/refresh.png is under the Apache 2 license
|
textures/base/pack/refresh.png is under the Apache 2 license
|
||||||
https://www.apache.org/licenses/LICENSE-2.0.html
|
https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
Textures by Zughy are under CC BY-SA 4.0
|
||||||
|
https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
|
||||||
Authors of media files
|
Authors of media files
|
||||||
-----------------------
|
-----------------------
|
||||||
Everything not listed in here:
|
Everything not listed in here:
|
||||||
@ -23,6 +26,8 @@ paramat:
|
|||||||
textures/base/pack/menu_header.png
|
textures/base/pack/menu_header.png
|
||||||
textures/base/pack/next_icon.png
|
textures/base/pack/next_icon.png
|
||||||
textures/base/pack/prev_icon.png
|
textures/base/pack/prev_icon.png
|
||||||
|
textures/base/pack/clear.png
|
||||||
|
textures/base/pack/search.png
|
||||||
|
|
||||||
rubenwardy, paramat:
|
rubenwardy, paramat:
|
||||||
textures/base/pack/start_icon.png
|
textures/base/pack/start_icon.png
|
||||||
@ -45,6 +50,14 @@ srifqi
|
|||||||
textures/base/pack/joystick_off.png
|
textures/base/pack/joystick_off.png
|
||||||
textures/base/pack/minimap_btn.png
|
textures/base/pack/minimap_btn.png
|
||||||
|
|
||||||
|
Zughy:
|
||||||
|
textures/base/pack/cdb_add.png
|
||||||
|
textures/base/pack/cdb_clear.png
|
||||||
|
textures/base/pack/cdb_downloading.png
|
||||||
|
textures/base/pack/cdb_queued.png
|
||||||
|
textures/base/pack/cdb_update.png
|
||||||
|
textures/base/pack/cdb_viewonline.png
|
||||||
|
|
||||||
License of Minetest source code
|
License of Minetest source code
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@ -142,8 +142,8 @@ public class GameActivity extends NativeActivity {
|
|||||||
return getResources().getDisplayMetrics().widthPixels;
|
return getResources().getDisplayMetrics().widthPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openURL(String url) {
|
public void openURI(String uri) {
|
||||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||||
startActivity(browserIntent);
|
startActivity(browserIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -781,3 +781,7 @@ function core.privs_to_string(privs, delim)
|
|||||||
end
|
end
|
||||||
return table.concat(list, delim)
|
return table.concat(list, delim)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function core.is_nan(number)
|
||||||
|
return number ~= number
|
||||||
|
end
|
||||||
|
@ -152,8 +152,8 @@ core.register_entity(":__builtin:falling_node", {
|
|||||||
else
|
else
|
||||||
self.object:set_yaw(-math.pi*0.25)
|
self.object:set_yaw(-math.pi*0.25)
|
||||||
end
|
end
|
||||||
elseif (node.param2 ~= 0 and (def.wield_image == ""
|
elseif ((node.param2 ~= 0 or def.drawtype == "nodebox" or def.drawtype == "mesh")
|
||||||
or def.wield_image == nil))
|
and (def.wield_image == "" or def.wield_image == nil))
|
||||||
or def.drawtype == "signlike"
|
or def.drawtype == "signlike"
|
||||||
or def.drawtype == "mesh"
|
or def.drawtype == "mesh"
|
||||||
or def.drawtype == "normal"
|
or def.drawtype == "normal"
|
||||||
@ -168,16 +168,30 @@ core.register_entity(":__builtin:falling_node", {
|
|||||||
elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted") then
|
elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted") then
|
||||||
local rot = node.param2 % 8
|
local rot = node.param2 % 8
|
||||||
local pitch, yaw, roll = 0, 0, 0
|
local pitch, yaw, roll = 0, 0, 0
|
||||||
if rot == 1 then
|
if def.drawtype == "nodebox" or def.drawtype == "mesh" then
|
||||||
pitch, yaw = math.pi, math.pi
|
if rot == 0 then
|
||||||
elseif rot == 2 then
|
pitch, yaw = math.pi/2, 0
|
||||||
pitch, yaw = math.pi/2, math.pi/2
|
elseif rot == 1 then
|
||||||
elseif rot == 3 then
|
pitch, yaw = -math.pi/2, math.pi
|
||||||
pitch, yaw = math.pi/2, -math.pi/2
|
elseif rot == 2 then
|
||||||
elseif rot == 4 then
|
pitch, yaw = 0, math.pi/2
|
||||||
pitch, yaw = math.pi/2, math.pi
|
elseif rot == 3 then
|
||||||
elseif rot == 5 then
|
pitch, yaw = 0, -math.pi/2
|
||||||
pitch, yaw = math.pi/2, 0
|
elseif rot == 4 then
|
||||||
|
pitch, yaw = 0, math.pi
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if rot == 1 then
|
||||||
|
pitch, yaw = math.pi, math.pi
|
||||||
|
elseif rot == 2 then
|
||||||
|
pitch, yaw = math.pi/2, math.pi/2
|
||||||
|
elseif rot == 3 then
|
||||||
|
pitch, yaw = math.pi/2, -math.pi/2
|
||||||
|
elseif rot == 4 then
|
||||||
|
pitch, yaw = math.pi/2, math.pi
|
||||||
|
elseif rot == 5 then
|
||||||
|
pitch, yaw = math.pi/2, 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if def.drawtype == "signlike" then
|
if def.drawtype == "signlike" then
|
||||||
pitch = pitch - math.pi/2
|
pitch = pitch - math.pi/2
|
||||||
@ -186,7 +200,7 @@ core.register_entity(":__builtin:falling_node", {
|
|||||||
elseif rot == 1 then
|
elseif rot == 1 then
|
||||||
yaw = yaw - math.pi/2
|
yaw = yaw - math.pi/2
|
||||||
end
|
end
|
||||||
elseif def.drawtype == "mesh" or def.drawtype == "normal" then
|
elseif def.drawtype == "mesh" or def.drawtype == "normal" or def.drawtype == "nodebox" then
|
||||||
if rot >= 0 and rot <= 1 then
|
if rot >= 0 and rot <= 1 then
|
||||||
roll = roll + math.pi
|
roll = roll + math.pi
|
||||||
else
|
else
|
||||||
|
@ -159,6 +159,331 @@ local function queue_download(package)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function get_raw_dependencies(package)
|
||||||
|
if package.raw_deps then
|
||||||
|
return package.raw_deps
|
||||||
|
end
|
||||||
|
|
||||||
|
local url_fmt = "/api/packages/%s/dependencies/?only_hard=1&protocol_version=%s&engine_version=%s"
|
||||||
|
local version = core.get_version()
|
||||||
|
local base_url = core.settings:get("contentdb_url")
|
||||||
|
local url = base_url .. url_fmt:format(package.id, core.get_max_supp_proto(), version.string)
|
||||||
|
|
||||||
|
local response = http.fetch_sync({ url = url })
|
||||||
|
if not response.succeeded then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = core.parse_json(response.data) or {}
|
||||||
|
|
||||||
|
local content_lookup = {}
|
||||||
|
for _, pkg in pairs(store.packages_full) do
|
||||||
|
content_lookup[pkg.id] = pkg
|
||||||
|
end
|
||||||
|
|
||||||
|
for id, raw_deps in pairs(data) do
|
||||||
|
local package2 = content_lookup[id:lower()]
|
||||||
|
if package2 and not package2.raw_deps then
|
||||||
|
package2.raw_deps = raw_deps
|
||||||
|
|
||||||
|
for _, dep in pairs(raw_deps) do
|
||||||
|
local packages = {}
|
||||||
|
for i=1, #dep.packages do
|
||||||
|
packages[#packages + 1] = content_lookup[dep.packages[i]:lower()]
|
||||||
|
end
|
||||||
|
dep.packages = packages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return package.raw_deps
|
||||||
|
end
|
||||||
|
|
||||||
|
local function has_hard_deps(raw_deps)
|
||||||
|
for i=1, #raw_deps do
|
||||||
|
if not raw_deps[i].is_optional then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Recursively resolve dependencies, given the installed mods
|
||||||
|
local function resolve_dependencies_2(raw_deps, installed_mods, out)
|
||||||
|
local function resolve_dep(dep)
|
||||||
|
-- Check whether it's already installed
|
||||||
|
if installed_mods[dep.name] then
|
||||||
|
return {
|
||||||
|
is_optional = dep.is_optional,
|
||||||
|
name = dep.name,
|
||||||
|
installed = true,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Find exact name matches
|
||||||
|
local fallback
|
||||||
|
for _, package in pairs(dep.packages) do
|
||||||
|
if package.type ~= "game" then
|
||||||
|
if package.name == dep.name then
|
||||||
|
return {
|
||||||
|
is_optional = dep.is_optional,
|
||||||
|
name = dep.name,
|
||||||
|
installed = false,
|
||||||
|
package = package,
|
||||||
|
}
|
||||||
|
elseif not fallback then
|
||||||
|
fallback = package
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Otherwise, find the first mod that fulfils it
|
||||||
|
if fallback then
|
||||||
|
return {
|
||||||
|
is_optional = dep.is_optional,
|
||||||
|
name = dep.name,
|
||||||
|
installed = false,
|
||||||
|
package = fallback,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
is_optional = dep.is_optional,
|
||||||
|
name = dep.name,
|
||||||
|
installed = false,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, dep in pairs(raw_deps) do
|
||||||
|
if not dep.is_optional and not out[dep.name] then
|
||||||
|
local result = resolve_dep(dep)
|
||||||
|
out[dep.name] = result
|
||||||
|
if result and result.package and not result.installed then
|
||||||
|
local raw_deps2 = get_raw_dependencies(result.package)
|
||||||
|
if raw_deps2 then
|
||||||
|
resolve_dependencies_2(raw_deps2, installed_mods, out)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Resolve dependencies for a package, calls the recursive version.
|
||||||
|
local function resolve_dependencies(raw_deps, game)
|
||||||
|
assert(game)
|
||||||
|
|
||||||
|
local installed_mods = {}
|
||||||
|
|
||||||
|
local mods = {}
|
||||||
|
pkgmgr.get_game_mods(game, mods)
|
||||||
|
for _, mod in pairs(mods) do
|
||||||
|
installed_mods[mod.name] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, mod in pairs(pkgmgr.global_mods:get_list()) do
|
||||||
|
installed_mods[mod.name] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local out = {}
|
||||||
|
if not resolve_dependencies_2(raw_deps, installed_mods, out) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local retval = {}
|
||||||
|
for _, dep in pairs(out) do
|
||||||
|
retval[#retval + 1] = dep
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(retval, function(a, b)
|
||||||
|
return a.name < b.name
|
||||||
|
end)
|
||||||
|
|
||||||
|
return retval
|
||||||
|
end
|
||||||
|
|
||||||
|
local install_dialog = {}
|
||||||
|
function install_dialog.get_formspec()
|
||||||
|
local package = install_dialog.package
|
||||||
|
local raw_deps = install_dialog.raw_deps
|
||||||
|
local will_install_deps = install_dialog.will_install_deps
|
||||||
|
|
||||||
|
local selected_game_idx = 1
|
||||||
|
local selected_gameid = core.settings:get("menu_last_game")
|
||||||
|
local games = table.copy(pkgmgr.games)
|
||||||
|
for i=1, #games do
|
||||||
|
if selected_gameid and games[i].id == selected_gameid then
|
||||||
|
selected_game_idx = i
|
||||||
|
end
|
||||||
|
|
||||||
|
games[i] = minetest.formspec_escape(games[i].name)
|
||||||
|
end
|
||||||
|
|
||||||
|
local selected_game = pkgmgr.games[selected_game_idx]
|
||||||
|
local deps_to_install = 0
|
||||||
|
local deps_not_found = 0
|
||||||
|
|
||||||
|
install_dialog.dependencies = resolve_dependencies(raw_deps, selected_game)
|
||||||
|
local formatted_deps = {}
|
||||||
|
for _, dep in pairs(install_dialog.dependencies) do
|
||||||
|
formatted_deps[#formatted_deps + 1] = "#fff"
|
||||||
|
formatted_deps[#formatted_deps + 1] = minetest.formspec_escape(dep.name)
|
||||||
|
if dep.installed then
|
||||||
|
formatted_deps[#formatted_deps + 1] = "#ccf"
|
||||||
|
formatted_deps[#formatted_deps + 1] = fgettext("Already installed")
|
||||||
|
elseif dep.package then
|
||||||
|
formatted_deps[#formatted_deps + 1] = "#cfc"
|
||||||
|
formatted_deps[#formatted_deps + 1] = fgettext("$1 by $2", dep.package.title, dep.package.author)
|
||||||
|
deps_to_install = deps_to_install + 1
|
||||||
|
else
|
||||||
|
formatted_deps[#formatted_deps + 1] = "#f00"
|
||||||
|
formatted_deps[#formatted_deps + 1] = fgettext("Not found")
|
||||||
|
deps_not_found = deps_not_found + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local message_bg = "#3333"
|
||||||
|
local message
|
||||||
|
if will_install_deps then
|
||||||
|
message = fgettext("$1 and $2 dependencies will be installed.", package.title, deps_to_install)
|
||||||
|
else
|
||||||
|
message = fgettext("$1 will be installed, and $2 dependencies will be skipped.", package.title, deps_to_install)
|
||||||
|
end
|
||||||
|
if deps_not_found > 0 then
|
||||||
|
message = fgettext("$1 required dependencies could not be found.", deps_not_found) ..
|
||||||
|
" " .. fgettext("Please check that the base game is correct.", deps_not_found) ..
|
||||||
|
"\n" .. message
|
||||||
|
message_bg = mt_color_orange
|
||||||
|
end
|
||||||
|
|
||||||
|
local formspec = {
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[7,7.85]",
|
||||||
|
"style[title;border=false]",
|
||||||
|
"box[0,0;7,0.5;#3333]",
|
||||||
|
"button[0,0;7,0.5;title;", fgettext("Install $1", package.title) , "]",
|
||||||
|
|
||||||
|
"container[0.375,0.70]",
|
||||||
|
|
||||||
|
"label[0,0.25;", fgettext("Base Game:"), "]",
|
||||||
|
"dropdown[2,0;4.25,0.5;gameid;", table.concat(games, ","), ";", selected_game_idx, "]",
|
||||||
|
|
||||||
|
"label[0,0.8;", fgettext("Dependencies:"), "]",
|
||||||
|
|
||||||
|
"tablecolumns[color;text;color;text]",
|
||||||
|
"table[0,1.1;6.25,3;packages;", table.concat(formatted_deps, ","), "]",
|
||||||
|
|
||||||
|
"container_end[]",
|
||||||
|
|
||||||
|
"checkbox[0.375,5.1;will_install_deps;",
|
||||||
|
fgettext("Install missing dependencies"), ";",
|
||||||
|
will_install_deps and "true" or "false", "]",
|
||||||
|
|
||||||
|
"box[0,5.4;7,1.2;", message_bg, "]",
|
||||||
|
"textarea[0.375,5.5;6.25,1;;;", message, "]",
|
||||||
|
|
||||||
|
"container[1.375,6.85]",
|
||||||
|
"button[0,0;2,0.8;install_all;", fgettext("Install"), "]",
|
||||||
|
"button[2.25,0;2,0.8;cancel;", fgettext("Cancel"), "]",
|
||||||
|
"container_end[]",
|
||||||
|
}
|
||||||
|
|
||||||
|
return table.concat(formspec, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
function install_dialog.handle_submit(this, fields)
|
||||||
|
if fields.cancel then
|
||||||
|
this:delete()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.will_install_deps ~= nil then
|
||||||
|
install_dialog.will_install_deps = minetest.is_yes(fields.will_install_deps)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.install_all then
|
||||||
|
queue_download(install_dialog.package)
|
||||||
|
|
||||||
|
if install_dialog.will_install_deps then
|
||||||
|
for _, dep in pairs(install_dialog.dependencies) do
|
||||||
|
if not dep.is_optional and not dep.installed and dep.package then
|
||||||
|
queue_download(dep.package)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
this:delete()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.gameid then
|
||||||
|
for _, game in pairs(pkgmgr.games) do
|
||||||
|
if game.name == fields.gameid then
|
||||||
|
core.settings:set("menu_last_game", game.id)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function install_dialog.create(package, raw_deps)
|
||||||
|
install_dialog.dependencies = nil
|
||||||
|
install_dialog.package = package
|
||||||
|
install_dialog.raw_deps = raw_deps
|
||||||
|
install_dialog.will_install_deps = true
|
||||||
|
return dialog_create("install_dialog",
|
||||||
|
install_dialog.get_formspec,
|
||||||
|
install_dialog.handle_submit,
|
||||||
|
nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local confirm_overwrite = {}
|
||||||
|
function confirm_overwrite.get_formspec()
|
||||||
|
local package = confirm_overwrite.package
|
||||||
|
|
||||||
|
return "size[11.5,4.5,true]" ..
|
||||||
|
"label[2,2;" ..
|
||||||
|
fgettext("\"$1\" already exists. Would you like to overwrite it?", package.name) .. "]"..
|
||||||
|
"style[install;bgcolor=red]" ..
|
||||||
|
"button[3.25,3.5;2.5,0.5;install;" .. fgettext("Overwrite") .. "]" ..
|
||||||
|
"button[5.75,3.5;2.5,0.5;cancel;" .. fgettext("Cancel") .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
function confirm_overwrite.handle_submit(this, fields)
|
||||||
|
if fields.cancel then
|
||||||
|
this:delete()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.install then
|
||||||
|
this:delete()
|
||||||
|
confirm_overwrite.callback()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function confirm_overwrite.create(package, callback)
|
||||||
|
assert(type(package) == "table")
|
||||||
|
assert(type(callback) == "function")
|
||||||
|
|
||||||
|
confirm_overwrite.package = package
|
||||||
|
confirm_overwrite.callback = callback
|
||||||
|
return dialog_create("confirm_overwrite",
|
||||||
|
confirm_overwrite.get_formspec,
|
||||||
|
confirm_overwrite.handle_submit,
|
||||||
|
nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function get_file_extension(path)
|
local function get_file_extension(path)
|
||||||
local parts = path:split(".")
|
local parts = path:split(".")
|
||||||
return parts[#parts]
|
return parts[#parts]
|
||||||
@ -340,7 +665,6 @@ function store.get_formspec(dlgdata)
|
|||||||
|
|
||||||
local W = 15.75
|
local W = 15.75
|
||||||
local H = 9.5
|
local H = 9.5
|
||||||
|
|
||||||
local formspec
|
local formspec
|
||||||
if #store.packages_full > 0 then
|
if #store.packages_full > 0 then
|
||||||
formspec = {
|
formspec = {
|
||||||
@ -348,12 +672,13 @@ function store.get_formspec(dlgdata)
|
|||||||
"size[15.75,9.5]",
|
"size[15.75,9.5]",
|
||||||
"position[0.5,0.55]",
|
"position[0.5,0.55]",
|
||||||
|
|
||||||
"style[status;border=false]",
|
"style[status,downloading,queued;border=false]",
|
||||||
|
|
||||||
"container[0.375,0.375]",
|
"container[0.375,0.375]",
|
||||||
"field[0,0;7.225,0.8;search_string;;", core.formspec_escape(search_string), "]",
|
"field[0,0;7.225,0.8;search_string;;", core.formspec_escape(search_string), "]",
|
||||||
"field_close_on_enter[search_string;false]",
|
"field_close_on_enter[search_string;false]",
|
||||||
"button[7.225,0;2,0.8;search;", fgettext("Search"), "]",
|
"image_button[7.3,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;]",
|
||||||
|
"image_button[8.125,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";clear;]",
|
||||||
"dropdown[9.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]",
|
"dropdown[9.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]",
|
||||||
"container_end[]",
|
"container_end[]",
|
||||||
|
|
||||||
@ -374,7 +699,7 @@ function store.get_formspec(dlgdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if number_downloading > 0 then
|
if number_downloading > 0 then
|
||||||
formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;status;"
|
formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;downloading;"
|
||||||
if #download_queue > 0 then
|
if #download_queue > 0 then
|
||||||
formspec[#formspec + 1] = fgettext("$1 downloading,\n$2 queued", number_downloading, #download_queue)
|
formspec[#formspec + 1] = fgettext("$1 downloading,\n$2 queued", number_downloading, #download_queue)
|
||||||
else
|
else
|
||||||
@ -418,11 +743,17 @@ function store.get_formspec(dlgdata)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- download/queued tooltips always have the same message
|
||||||
|
local tooltip_colors = ";#dff6f5;#302c2e]"
|
||||||
|
formspec[#formspec + 1] = "tooltip[downloading;" .. fgettext("Downloading...") .. tooltip_colors
|
||||||
|
formspec[#formspec + 1] = "tooltip[queued;" .. fgettext("Queued") .. tooltip_colors
|
||||||
|
|
||||||
local start_idx = (cur_page - 1) * num_per_page + 1
|
local start_idx = (cur_page - 1) * num_per_page + 1
|
||||||
for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do
|
for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do
|
||||||
local package = store.packages[i]
|
local package = store.packages[i]
|
||||||
|
local container_y = (i - start_idx) * 1.375 + (2*0.375 + 0.8)
|
||||||
formspec[#formspec + 1] = "container[0.375,"
|
formspec[#formspec + 1] = "container[0.375,"
|
||||||
formspec[#formspec + 1] = (i - start_idx) * 1.375 + (2*0.375 + 0.8)
|
formspec[#formspec + 1] = container_y
|
||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "]"
|
||||||
|
|
||||||
-- image
|
-- image
|
||||||
@ -438,52 +769,50 @@ function store.get_formspec(dlgdata)
|
|||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "]"
|
||||||
|
|
||||||
-- buttons
|
-- buttons
|
||||||
local description_width = W - 0.375*5 - 1 - 2*1.5
|
local left_base = "image_button[-1.55,0;0.7,0.7;" .. core.formspec_escape(defaulttexturedir)
|
||||||
formspec[#formspec + 1] = "container["
|
formspec[#formspec + 1] = "container["
|
||||||
formspec[#formspec + 1] = W - 0.375*2
|
formspec[#formspec + 1] = W - 0.375*2
|
||||||
formspec[#formspec + 1] = ",0.1]"
|
formspec[#formspec + 1] = ",0.1]"
|
||||||
|
|
||||||
if package.downloading then
|
if package.downloading then
|
||||||
formspec[#formspec + 1] = "button[-3.5,0;2,0.8;status;"
|
formspec[#formspec + 1] = "animated_image[-1.7,-0.15;1,1;downloading;"
|
||||||
formspec[#formspec + 1] = fgettext("Downloading...")
|
formspec[#formspec + 1] = core.formspec_escape(defaulttexturedir)
|
||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "cdb_downloading.png;3;400;]"
|
||||||
elseif package.queued then
|
elseif package.queued then
|
||||||
formspec[#formspec + 1] = "button[-3.5,0;2,0.8;status;"
|
formspec[#formspec + 1] = left_base
|
||||||
formspec[#formspec + 1] = fgettext("Queued")
|
formspec[#formspec + 1] = core.formspec_escape(defaulttexturedir)
|
||||||
formspec[#formspec + 1] = "]"
|
formspec[#formspec + 1] = "cdb_queued.png;queued]"
|
||||||
elseif not package.path then
|
elseif not package.path then
|
||||||
formspec[#formspec + 1] = "button[-3,0;1.5,0.8;install_"
|
local elem_name = "install_" .. i .. ";"
|
||||||
formspec[#formspec + 1] = tostring(i)
|
formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#71aa34]"
|
||||||
formspec[#formspec + 1] = ";"
|
formspec[#formspec + 1] = left_base .. "cdb_add.png;" .. elem_name .. "]"
|
||||||
formspec[#formspec + 1] = fgettext("Install")
|
formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Install") .. tooltip_colors
|
||||||
formspec[#formspec + 1] = "]"
|
|
||||||
else
|
else
|
||||||
if package.installed_release < package.release then
|
if package.installed_release < package.release then
|
||||||
description_width = description_width - 1.5
|
|
||||||
|
|
||||||
-- The install_ action also handles updating
|
-- The install_ action also handles updating
|
||||||
formspec[#formspec + 1] = "button[-4.5,0;1.5,0.8;install_"
|
local elem_name = "install_" .. i .. ";"
|
||||||
formspec[#formspec + 1] = tostring(i)
|
formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#28ccdf]"
|
||||||
formspec[#formspec + 1] = ";"
|
formspec[#formspec + 1] = left_base .. "cdb_update.png;" .. elem_name .. "]"
|
||||||
formspec[#formspec + 1] = fgettext("Update")
|
formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Update") .. tooltip_colors
|
||||||
formspec[#formspec + 1] = "]"
|
else
|
||||||
end
|
|
||||||
|
|
||||||
formspec[#formspec + 1] = "button[-3,0;1.5,0.8;uninstall_"
|
local elem_name = "uninstall_" .. i .. ";"
|
||||||
formspec[#formspec + 1] = tostring(i)
|
formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#a93b3b]"
|
||||||
formspec[#formspec + 1] = ";"
|
formspec[#formspec + 1] = left_base .. "cdb_clear.png;" .. elem_name .. "]"
|
||||||
formspec[#formspec + 1] = fgettext("Uninstall")
|
formspec[#formspec + 1] = "tooltip[" .. elem_name .. fgettext("Uninstall") .. tooltip_colors
|
||||||
formspec[#formspec + 1] = "]"
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
formspec[#formspec + 1] = "button[-1.5,0;1.5,0.8;view_"
|
local web_elem_name = "view_" .. i .. ";"
|
||||||
formspec[#formspec + 1] = tostring(i)
|
formspec[#formspec + 1] = "image_button[-0.7,0;0.7,0.7;" ..
|
||||||
formspec[#formspec + 1] = ";"
|
core.formspec_escape(defaulttexturedir) .. "cdb_viewonline.png;" .. web_elem_name .. "]"
|
||||||
formspec[#formspec + 1] = fgettext("View")
|
formspec[#formspec + 1] = "tooltip[" .. web_elem_name ..
|
||||||
formspec[#formspec + 1] = "]"
|
fgettext("View more information in a web browser") .. tooltip_colors
|
||||||
formspec[#formspec + 1] = "container_end[]"
|
formspec[#formspec + 1] = "container_end[]"
|
||||||
|
|
||||||
-- description
|
-- description
|
||||||
|
local description_width = W - 0.375*5 - 0.85 - 2*0.7
|
||||||
formspec[#formspec + 1] = "textarea[1.855,0.3;"
|
formspec[#formspec + 1] = "textarea[1.855,0.3;"
|
||||||
formspec[#formspec + 1] = tostring(description_width)
|
formspec[#formspec + 1] = tostring(description_width)
|
||||||
formspec[#formspec + 1] = ",0.8;;;"
|
formspec[#formspec + 1] = ",0.8;;;"
|
||||||
@ -504,6 +833,13 @@ function store.handle_submit(this, fields)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fields.clear then
|
||||||
|
search_string = ""
|
||||||
|
cur_page = 1
|
||||||
|
store.filter_packages("")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
if fields.back then
|
if fields.back then
|
||||||
this:delete()
|
this:delete()
|
||||||
return true
|
return true
|
||||||
@ -563,15 +899,47 @@ function store.handle_submit(this, fields)
|
|||||||
assert(package)
|
assert(package)
|
||||||
|
|
||||||
if fields["install_" .. i] then
|
if fields["install_" .. i] then
|
||||||
queue_download(package)
|
local install_parent
|
||||||
|
if package.type == "mod" then
|
||||||
|
install_parent = core.get_modpath()
|
||||||
|
elseif package.type == "game" then
|
||||||
|
install_parent = core.get_gamepath()
|
||||||
|
elseif package.type == "txp" then
|
||||||
|
install_parent = core.get_texturepath()
|
||||||
|
else
|
||||||
|
error("Unknown package type: " .. package.type)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function on_confirm()
|
||||||
|
local deps = get_raw_dependencies(package)
|
||||||
|
if deps and has_hard_deps(deps) then
|
||||||
|
local dlg = install_dialog.create(package, deps)
|
||||||
|
dlg:set_parent(this)
|
||||||
|
this:hide()
|
||||||
|
dlg:show()
|
||||||
|
else
|
||||||
|
queue_download(package)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then
|
||||||
|
local dlg = confirm_overwrite.create(package, on_confirm)
|
||||||
|
dlg:set_parent(this)
|
||||||
|
this:hide()
|
||||||
|
dlg:show()
|
||||||
|
else
|
||||||
|
on_confirm()
|
||||||
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields["uninstall_" .. i] then
|
if fields["uninstall_" .. i] then
|
||||||
local dlg_delmod = create_delete_content_dlg(package)
|
local dlg = create_delete_content_dlg(package)
|
||||||
dlg_delmod:set_parent(this)
|
dlg:set_parent(this)
|
||||||
this:hide()
|
this:hide()
|
||||||
dlg_delmod:show()
|
dlg:show()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ local function create_world_formspec(dialogdata)
|
|||||||
-- Error out when no games found
|
-- Error out when no games found
|
||||||
if #pkgmgr.games == 0 then
|
if #pkgmgr.games == 0 then
|
||||||
return "size[12.25,3,true]" ..
|
return "size[12.25,3,true]" ..
|
||||||
"box[0,0;12,2;#ff8800]" ..
|
"box[0,0;12,2;" .. mt_color_orange .. "]" ..
|
||||||
"textarea[0.3,0;11.7,2;;;"..
|
"textarea[0.3,0;11.7,2;;;"..
|
||||||
fgettext("You have no games installed.") .. "\n" ..
|
fgettext("You have no games installed.") .. "\n" ..
|
||||||
fgettext("Download one from minetest.net") .. "]" ..
|
fgettext("Download one from minetest.net") .. "]" ..
|
||||||
|
@ -19,6 +19,7 @@ mt_color_grey = "#AAAAAA"
|
|||||||
mt_color_blue = "#6389FF"
|
mt_color_blue = "#6389FF"
|
||||||
mt_color_green = "#72FF63"
|
mt_color_green = "#72FF63"
|
||||||
mt_color_dark_green = "#25C191"
|
mt_color_dark_green = "#25C191"
|
||||||
|
mt_color_orange = "#FF8800"
|
||||||
|
|
||||||
local menupath = core.get_mainmenu_path()
|
local menupath = core.get_mainmenu_path()
|
||||||
local basepath = core.get_builtin_path()
|
local basepath = core.get_builtin_path()
|
||||||
@ -105,6 +106,16 @@ local function init_globals()
|
|||||||
if last_tab and tv_main.current_tab ~= last_tab then
|
if last_tab and tv_main.current_tab ~= last_tab then
|
||||||
tv_main:set_tab(last_tab)
|
tv_main:set_tab(last_tab)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- In case the folder of the last selected game has been deleted,
|
||||||
|
-- display "Minetest" as a header
|
||||||
|
if tv_main.current_tab == "local" then
|
||||||
|
local game = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
|
||||||
|
if game == nil then
|
||||||
|
mm_texture.reset()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
ui.set_default("maintab")
|
ui.set_default("maintab")
|
||||||
tv_main:show()
|
tv_main:show()
|
||||||
|
|
||||||
|
@ -109,9 +109,10 @@ return {
|
|||||||
cbf_formspec = function(tabview, name, tabdata)
|
cbf_formspec = function(tabview, name, tabdata)
|
||||||
local logofile = defaulttexturedir .. "logo.png"
|
local logofile = defaulttexturedir .. "logo.png"
|
||||||
local version = core.get_version()
|
local version = core.get_version()
|
||||||
return "image[0.5,1;" .. core.formspec_escape(logofile) .. "]" ..
|
local fs = "image[0.75,0.5;2.2,2.2;" .. core.formspec_escape(logofile) .. "]" ..
|
||||||
"label[0.5,2.8;" .. version.project .. " " .. version.string .. "]" ..
|
"style[label_button;border=false]" ..
|
||||||
"button[0.5,3;2,2;homepage;minetest.net]" ..
|
"button[0.5,2;2.5,2;label_button;" .. version.project .. " " .. version.string .. "]" ..
|
||||||
|
"button[0.75,2.75;2,2;homepage;minetest.net]" ..
|
||||||
"tablecolumns[color;text]" ..
|
"tablecolumns[color;text]" ..
|
||||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||||
"table[3.5,-0.25;8.5,6.05;list_credits;" ..
|
"table[3.5,-0.25;8.5,6.05;list_credits;" ..
|
||||||
@ -126,10 +127,23 @@ return {
|
|||||||
"#FFFF00," .. fgettext("Previous Contributors") .. ",," ..
|
"#FFFF00," .. fgettext("Previous Contributors") .. ",," ..
|
||||||
buildCreditList(previous_contributors) .. "," ..
|
buildCreditList(previous_contributors) .. "," ..
|
||||||
";1]"
|
";1]"
|
||||||
|
|
||||||
|
if PLATFORM ~= "Android" then
|
||||||
|
fs = fs .. "tooltip[userdata;" ..
|
||||||
|
fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" ..
|
||||||
|
"and texture packs in a file manager / explorer.") .. "]"
|
||||||
|
fs = fs .. "button[0,4.75;3.5,1;userdata;" .. fgettext("Open User Data Directory") .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
return fs
|
||||||
end,
|
end,
|
||||||
cbf_button_handler = function(this, fields, name, tabdata)
|
cbf_button_handler = function(this, fields, name, tabdata)
|
||||||
if fields.homepage then
|
if fields.homepage then
|
||||||
core.open_url("https://www.minetest.net")
|
core.open_url("https://www.minetest.net")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fields.userdata then
|
||||||
|
core.open_dir(core.get_user_path())
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
local enable_gamebar = PLATFORM ~= "Android"
|
local enable_gamebar = PLATFORM ~= "Android"
|
||||||
local current_game, singleplayer_refresh_gamebar
|
local current_game, singleplayer_refresh_gamebar
|
||||||
|
|
||||||
if enable_gamebar then
|
if enable_gamebar then
|
||||||
function current_game()
|
function current_game()
|
||||||
local last_game_id = core.settings:get("menu_last_game")
|
local last_game_id = core.settings:get("menu_last_game")
|
||||||
|
@ -34,7 +34,8 @@ local function get_formspec(tabview, name, tabdata)
|
|||||||
local retval =
|
local retval =
|
||||||
-- Search
|
-- Search
|
||||||
"field[0.15,0.075;5.91,1;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" ..
|
"field[0.15,0.075;5.91,1;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" ..
|
||||||
"button[5.62,-0.25;1.5,1;btn_mp_search;" .. fgettext("Search") .. "]" ..
|
"image_button[5.63,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" ..
|
||||||
|
"image_button[6.3,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "clear.png") .. ";btn_mp_clear;]" ..
|
||||||
"image_button[6.97,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "refresh.png")
|
"image_button[6.97,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "refresh.png")
|
||||||
.. ";btn_mp_refresh;]" ..
|
.. ";btn_mp_refresh;]" ..
|
||||||
|
|
||||||
@ -243,6 +244,12 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fields.btn_mp_clear then
|
||||||
|
tabdata.search_for = ""
|
||||||
|
menudata.search_result = nil
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
|
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
|
||||||
tabdata.fav_selected = 1
|
tabdata.fav_selected = 1
|
||||||
local input = fields.te_search:lower()
|
local input = fields.te_search:lower()
|
||||||
|
@ -160,6 +160,7 @@ local function init()
|
|||||||
-- Simple iteration would ignore lookup via __index.
|
-- Simple iteration would ignore lookup via __index.
|
||||||
local entity_instrumentation = {
|
local entity_instrumentation = {
|
||||||
"on_activate",
|
"on_activate",
|
||||||
|
"on_deactivate",
|
||||||
"on_step",
|
"on_step",
|
||||||
"on_punch",
|
"on_punch",
|
||||||
"on_rightclick",
|
"on_rightclick",
|
||||||
|
@ -152,6 +152,9 @@ joystick_type (Joystick type) enum auto auto,generic,xbox
|
|||||||
# when holding down a joystick button combination.
|
# when holding down a joystick button combination.
|
||||||
repeat_joystick_button_time (Joystick button repetition interval) float 0.17 0.001
|
repeat_joystick_button_time (Joystick button repetition interval) float 0.17 0.001
|
||||||
|
|
||||||
|
# The deadzone of the joystick
|
||||||
|
joystick_deadzone (Joystick deadzone) int 2048
|
||||||
|
|
||||||
# The sensitivity of the joystick axes for moving the
|
# The sensitivity of the joystick axes for moving the
|
||||||
# ingame view frustum around.
|
# ingame view frustum around.
|
||||||
joystick_frustum_sensitivity (Joystick frustum sensitivity) float 170
|
joystick_frustum_sensitivity (Joystick frustum sensitivity) float 170
|
||||||
@ -1060,6 +1063,13 @@ full_block_send_enable_min_time_from_building (Delay in sending blocks after bui
|
|||||||
# client number.
|
# client number.
|
||||||
max_packets_per_iteration (Max. packets per iteration) int 1024
|
max_packets_per_iteration (Max. packets per iteration) int 1024
|
||||||
|
|
||||||
|
# ZLib compression level to use when sending mapblocks to the client.
|
||||||
|
# -1 - Zlib's default compression level
|
||||||
|
# 0 - no compresson, fastest
|
||||||
|
# 9 - best compression, slowest
|
||||||
|
# (levels 1-3 use Zlib's "fast" method, 4-9 use the normal method)
|
||||||
|
map_compression_level_net (Map Compression Level for Network Transfer) int -1 -1 9
|
||||||
|
|
||||||
[*Game]
|
[*Game]
|
||||||
|
|
||||||
# Default game when creating a new world.
|
# Default game when creating a new world.
|
||||||
@ -1252,6 +1262,13 @@ max_objects_per_block (Maximum objects per block) int 64
|
|||||||
# See https://www.sqlite.org/pragma.html#pragma_synchronous
|
# See https://www.sqlite.org/pragma.html#pragma_synchronous
|
||||||
sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2
|
sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2
|
||||||
|
|
||||||
|
# ZLib compression level to use when saving mapblocks to disk.
|
||||||
|
# -1 - Zlib's default compression level
|
||||||
|
# 0 - no compresson, fastest
|
||||||
|
# 9 - best compression, slowest
|
||||||
|
# (levels 1-3 use Zlib's "fast" method, 4-9 use the normal method)
|
||||||
|
map_compression_level_disk (Map Compression Level for Disk Storage) int 3 -1 9
|
||||||
|
|
||||||
# Length of a server tick and the interval at which objects are generally updated over
|
# Length of a server tick and the interval at which objects are generally updated over
|
||||||
# network.
|
# network.
|
||||||
dedicated_server_step (Dedicated server step) float 0.09
|
dedicated_server_step (Dedicated server step) float 0.09
|
||||||
@ -2200,6 +2217,7 @@ contentdb_url (ContentDB URL) string https://content.minetest.net
|
|||||||
contentdb_flag_blacklist (ContentDB Flag Blacklist) string nonfree, desktop_default
|
contentdb_flag_blacklist (ContentDB Flag Blacklist) string nonfree, desktop_default
|
||||||
|
|
||||||
# Maximum number of concurrent downloads. Downloads exceeding this limit will be queued.
|
# Maximum number of concurrent downloads. Downloads exceeding this limit will be queued.
|
||||||
|
# This should be lower than curl_parallel_limit.
|
||||||
contentdb_max_concurrent_downloads (ContentDB Max Concurrent Downloads) int 3
|
contentdb_max_concurrent_downloads (ContentDB Max Concurrent Downloads) int 3
|
||||||
|
|
||||||
[Cheat Menu]
|
[Cheat Menu]
|
||||||
|
@ -16,13 +16,17 @@ varying vec3 vPosition;
|
|||||||
// precision must be considered).
|
// precision must be considered).
|
||||||
varying vec3 worldPosition;
|
varying vec3 worldPosition;
|
||||||
varying lowp vec4 varColor;
|
varying lowp vec4 varColor;
|
||||||
centroid varying mediump vec2 varTexCoord;
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
|
|
||||||
const float fogStart = FOG_START;
|
const float fogStart = FOG_START;
|
||||||
const float fogShadingParameter = 1.0 / ( 1.0 - fogStart);
|
const float fogShadingParameter = 1.0 / ( 1.0 - fogStart);
|
||||||
|
|
||||||
#ifdef ENABLE_TONE_MAPPING
|
#if ENABLE_TONE_MAPPING
|
||||||
|
|
||||||
/* Hable's UC2 Tone mapping parameters
|
/* Hable's UC2 Tone mapping parameters
|
||||||
A = 0.22;
|
A = 0.22;
|
||||||
@ -73,7 +77,7 @@ void main(void)
|
|||||||
|
|
||||||
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
|
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
|
||||||
|
|
||||||
#ifdef ENABLE_TONE_MAPPING
|
#if ENABLE_TONE_MAPPING
|
||||||
col = applyToneMapping(col);
|
col = applyToneMapping(col);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -19,7 +19,11 @@ varying lowp vec4 varColor;
|
|||||||
// The centroid keyword ensures that after interpolation the texture coordinates
|
// The centroid keyword ensures that after interpolation the texture coordinates
|
||||||
// lie within the same bounds when MSAA is en- and disabled.
|
// lie within the same bounds when MSAA is en- and disabled.
|
||||||
// This fixes the stripes problem with nearest-neighbour textures and MSAA.
|
// This fixes the stripes problem with nearest-neighbour textures and MSAA.
|
||||||
centroid varying mediump vec2 varTexCoord;
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
|
|
||||||
// Color of the light emitted by the light sources.
|
// Color of the light emitted by the light sources.
|
||||||
|
@ -9,7 +9,11 @@ varying vec3 vNormal;
|
|||||||
varying vec3 vPosition;
|
varying vec3 vPosition;
|
||||||
varying vec3 worldPosition;
|
varying vec3 worldPosition;
|
||||||
varying lowp vec4 varColor;
|
varying lowp vec4 varColor;
|
||||||
centroid varying mediump vec2 varTexCoord;
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
varying float vIDiff;
|
varying float vIDiff;
|
||||||
@ -19,7 +23,7 @@ const float BS = 10.0;
|
|||||||
const float fogStart = FOG_START;
|
const float fogStart = FOG_START;
|
||||||
const float fogShadingParameter = 1.0 / (1.0 - fogStart);
|
const float fogShadingParameter = 1.0 / (1.0 - fogStart);
|
||||||
|
|
||||||
#ifdef ENABLE_TONE_MAPPING
|
#if ENABLE_TONE_MAPPING
|
||||||
|
|
||||||
/* Hable's UC2 Tone mapping parameters
|
/* Hable's UC2 Tone mapping parameters
|
||||||
A = 0.22;
|
A = 0.22;
|
||||||
@ -75,7 +79,7 @@ void main(void)
|
|||||||
|
|
||||||
col.rgb *= emissiveColor.rgb * vIDiff;
|
col.rgb *= emissiveColor.rgb * vIDiff;
|
||||||
|
|
||||||
#ifdef ENABLE_TONE_MAPPING
|
#if ENABLE_TONE_MAPPING
|
||||||
col = applyToneMapping(col);
|
col = applyToneMapping(col);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7,7 +7,11 @@ varying vec3 vNormal;
|
|||||||
varying vec3 vPosition;
|
varying vec3 vPosition;
|
||||||
varying vec3 worldPosition;
|
varying vec3 worldPosition;
|
||||||
varying lowp vec4 varColor;
|
varying lowp vec4 varColor;
|
||||||
centroid varying mediump vec2 varTexCoord;
|
#ifdef GL_ES
|
||||||
|
varying mediump vec2 varTexCoord;
|
||||||
|
#else
|
||||||
|
centroid varying vec2 varTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
varying float vIDiff;
|
varying float vIDiff;
|
||||||
|
@ -2114,6 +2114,22 @@ Examples
|
|||||||
list[current_player;craft;3,0;3,3;]
|
list[current_player;craft;3,0;3,3;]
|
||||||
list[current_player;craftpreview;7,1;1,1;]
|
list[current_player;craftpreview;7,1;1,1;]
|
||||||
|
|
||||||
|
Version History
|
||||||
|
---------------
|
||||||
|
|
||||||
|
* FORMSPEC VERSION 1:
|
||||||
|
* (too much)
|
||||||
|
* FORMSPEC VERSION 2:
|
||||||
|
* Forced real coordinates
|
||||||
|
* background9[]: 9-slice scaling parameters
|
||||||
|
* FORMSPEC VERSION 3:
|
||||||
|
* Formspec elements are drawn in the order of definition
|
||||||
|
* bgcolor[]: use 3 parameters (bgcolor, formspec (now an enum), fbgcolor)
|
||||||
|
* box[] and image[] elements enable clipping by default
|
||||||
|
* new element: scroll_container[]
|
||||||
|
* FORMSPEC VERSION 4:
|
||||||
|
* Allow dropdown indexing events
|
||||||
|
|
||||||
Elements
|
Elements
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -2125,6 +2141,7 @@ Elements
|
|||||||
* Clients older than this version can neither show newer elements nor display
|
* Clients older than this version can neither show newer elements nor display
|
||||||
elements with new arguments correctly.
|
elements with new arguments correctly.
|
||||||
* Available since feature `formspec_version_element`.
|
* Available since feature `formspec_version_element`.
|
||||||
|
* See also: [Version History]
|
||||||
|
|
||||||
### `size[<W>,<H>,<fixed_size>]`
|
### `size[<W>,<H>,<fixed_size>]`
|
||||||
|
|
||||||
@ -2277,7 +2294,7 @@ Elements
|
|||||||
* `frame duration`: Milliseconds between each frame. `0` means the frames don't advance.
|
* `frame duration`: Milliseconds between each frame. `0` means the frames don't advance.
|
||||||
* `frame start` (Optional): The index of the frame to start on. Default `1`.
|
* `frame start` (Optional): The index of the frame to start on. Default `1`.
|
||||||
|
|
||||||
### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>]`
|
### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>;<frame loop range>]`
|
||||||
|
|
||||||
* Show a mesh model.
|
* Show a mesh model.
|
||||||
* `name`: Element name that can be used for styling
|
* `name`: Element name that can be used for styling
|
||||||
@ -2288,6 +2305,9 @@ Elements
|
|||||||
The axes are euler angles in degrees.
|
The axes are euler angles in degrees.
|
||||||
* `continuous` (Optional): Whether the rotation is continuous. Default `false`.
|
* `continuous` (Optional): Whether the rotation is continuous. Default `false`.
|
||||||
* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`.
|
* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`.
|
||||||
|
* `frame loop range` (Optional): Range of the animation frames.
|
||||||
|
* Defaults to the full range of all available frames.
|
||||||
|
* Syntax: `<begin>,<end>`
|
||||||
|
|
||||||
### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
|
### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
|
||||||
|
|
||||||
@ -2789,6 +2809,7 @@ Some types may inherit styles from parent types.
|
|||||||
* image_button
|
* image_button
|
||||||
* item_image_button
|
* item_image_button
|
||||||
* label
|
* label
|
||||||
|
* model
|
||||||
* pwdfield, inherits from field
|
* pwdfield, inherits from field
|
||||||
* scrollbar
|
* scrollbar
|
||||||
* tabheader
|
* tabheader
|
||||||
@ -4188,6 +4209,8 @@ Callbacks:
|
|||||||
* Called when the object is instantiated.
|
* Called when the object is instantiated.
|
||||||
* `dtime_s` is the time passed since the object was unloaded, which can be
|
* `dtime_s` is the time passed since the object was unloaded, which can be
|
||||||
used for updating the entity state.
|
used for updating the entity state.
|
||||||
|
* `on_deactivate(self)
|
||||||
|
* Called when the object is about to get removed or unloaded.
|
||||||
* `on_step(self, dtime)`
|
* `on_step(self, dtime)`
|
||||||
* Called on every server tick, after movement and collision processing.
|
* Called on every server tick, after movement and collision processing.
|
||||||
`dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting
|
`dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting
|
||||||
@ -4308,11 +4331,14 @@ Utilities
|
|||||||
|
|
||||||
* `minetest.get_current_modname()`: returns the currently loading mod's name,
|
* `minetest.get_current_modname()`: returns the currently loading mod's name,
|
||||||
when loading a mod.
|
when loading a mod.
|
||||||
* `minetest.get_modpath(modname)`: returns e.g.
|
* `minetest.get_modpath(modname)`: returns the directory path for a mod,
|
||||||
`"/home/user/.minetest/usermods/modname"`.
|
e.g. `"/home/user/.minetest/usermods/modname"`.
|
||||||
* Useful for loading additional `.lua` modules or static data from mod
|
* Returns nil if the mod is not enabled or does not exist (not installed).
|
||||||
* `minetest.get_modnames()`: returns a list of installed mods
|
* Works regardless of whether the mod has been loaded yet.
|
||||||
* Return a list of installed mods, sorted alphabetically
|
* Useful for loading additional `.lua` modules or static data from a mod,
|
||||||
|
or checking if a mod is enabled.
|
||||||
|
* `minetest.get_modnames()`: returns a list of enabled mods, sorted alphabetically.
|
||||||
|
* Does not include disabled mods, even if they are installed.
|
||||||
* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"`
|
* `minetest.get_worldpath()`: returns e.g. `"/home/user/.minetest/world"`
|
||||||
* Useful for storing custom data
|
* Useful for storing custom data
|
||||||
* `minetest.is_singleplayer()`
|
* `minetest.is_singleplayer()`
|
||||||
@ -4872,6 +4898,9 @@ Environment access
|
|||||||
* `minetest.get_objects_inside_radius(pos, radius)`: returns a list of
|
* `minetest.get_objects_inside_radius(pos, radius)`: returns a list of
|
||||||
ObjectRefs.
|
ObjectRefs.
|
||||||
* `radius`: using an euclidean metric
|
* `radius`: using an euclidean metric
|
||||||
|
* `minetest.get_objects_in_area(pos1, pos2)`: returns a list of
|
||||||
|
ObjectRefs.
|
||||||
|
* `pos1` and `pos2` are the min and max positions of the area to search.
|
||||||
* `minetest.set_timeofday(val)`
|
* `minetest.set_timeofday(val)`
|
||||||
* `val` is between `0` and `1`; `0` for midnight, `0.5` for midday
|
* `val` is between `0` and `1`; `0` for midnight, `0.5` for midday
|
||||||
* `minetest.get_timeofday()`
|
* `minetest.get_timeofday()`
|
||||||
@ -7614,6 +7643,13 @@ Used by `minetest.register_node`.
|
|||||||
-- intensity: 1.0 = mid range of regular TNT.
|
-- intensity: 1.0 = mid range of regular TNT.
|
||||||
-- If defined, called when an explosion touches the node, instead of
|
-- If defined, called when an explosion touches the node, instead of
|
||||||
-- removing the node.
|
-- removing the node.
|
||||||
|
|
||||||
|
mod_origin = "modname",
|
||||||
|
-- stores which mod actually registered a node
|
||||||
|
-- if it can not find a source, returns "??"
|
||||||
|
-- useful for getting what mod truly registered something
|
||||||
|
-- example: if a node is registered as ":othermodname:nodename",
|
||||||
|
-- nodename will show "othermodname", but mod_orgin will say "modname"
|
||||||
}
|
}
|
||||||
|
|
||||||
Crafting recipes
|
Crafting recipes
|
||||||
|
@ -43,10 +43,14 @@ core.get_max_supp_proto()
|
|||||||
core.open_url(url)
|
core.open_url(url)
|
||||||
^ opens the URL in a web browser, returns false on failure.
|
^ opens the URL in a web browser, returns false on failure.
|
||||||
^ Must begin with http:// or https://
|
^ Must begin with http:// or https://
|
||||||
|
core.open_dir(path)
|
||||||
|
^ opens the path in the system file browser/explorer, returns false on failure.
|
||||||
|
^ Must be an existing directory.
|
||||||
core.get_version() (possible in async calls)
|
core.get_version() (possible in async calls)
|
||||||
^ returns current core version
|
^ returns current core version
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Filesystem
|
Filesystem
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -63,6 +67,8 @@ core.copy_dir(source,destination,keep_soure) (possible in async calls)
|
|||||||
^ destination folder
|
^ destination folder
|
||||||
^ keep_source DEFAULT true --> if set to false source is deleted after copying
|
^ keep_source DEFAULT true --> if set to false source is deleted after copying
|
||||||
^ returns true/false
|
^ returns true/false
|
||||||
|
core.is_dir(path) (possible in async calls)
|
||||||
|
^ returns true if path is a valid dir
|
||||||
core.extract_zip(zipfile,destination) [unzip within path required]
|
core.extract_zip(zipfile,destination) [unzip within path required]
|
||||||
^ zipfile to extract
|
^ zipfile to extract
|
||||||
^ destination folder to extract to
|
^ destination folder to extract to
|
||||||
@ -207,6 +213,9 @@ Content and Packages
|
|||||||
Content - an installed mod, modpack, game, or texture pack (txt)
|
Content - an installed mod, modpack, game, or texture pack (txt)
|
||||||
Package - content which is downloadable from the content db, may or may not be installed.
|
Package - content which is downloadable from the content db, may or may not be installed.
|
||||||
|
|
||||||
|
* core.get_user_path() (possible in async calls)
|
||||||
|
* returns path to global user data,
|
||||||
|
the directory that contains user-provided mods, worlds, games, and texture packs.
|
||||||
* core.get_modpath() (possible in async calls)
|
* core.get_modpath() (possible in async calls)
|
||||||
* returns path to global modpath
|
* returns path to global modpath
|
||||||
* core.get_clientmodpath() (possible in async calls)
|
* core.get_clientmodpath() (possible in async calls)
|
||||||
|
@ -31,6 +31,9 @@ minetest.register_entity("testentities:callback", {
|
|||||||
on_activate = function(self, staticdata, dtime_s)
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s)
|
message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s)
|
||||||
end,
|
end,
|
||||||
|
on_deactivate = function(self)
|
||||||
|
message("Callback entity: on_deactivate! pos="..spos(self))
|
||||||
|
end,
|
||||||
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
|
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
|
||||||
local name = get_object_name(puncher)
|
local name = get_object_name(puncher)
|
||||||
message(
|
message(
|
||||||
|
@ -94,3 +94,32 @@ minetest.register_entity("testentities:upright_animated", {
|
|||||||
self.object:set_sprite({x=0, y=0}, 4, 1.0, false)
|
self.object:set_sprite({x=0, y=0}, 4, 1.0, false)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_entity("testentities:nametag", {
|
||||||
|
initial_properties = {
|
||||||
|
visual = "sprite",
|
||||||
|
textures = { "testentities_sprite.png" },
|
||||||
|
},
|
||||||
|
|
||||||
|
on_activate = function(self, staticdata)
|
||||||
|
if staticdata ~= "" then
|
||||||
|
self.color = minetest.deserialize(staticdata).color
|
||||||
|
else
|
||||||
|
self.color = {
|
||||||
|
r = math.random(0, 255),
|
||||||
|
g = math.random(0, 255),
|
||||||
|
b = math.random(0, 255),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(self.color)
|
||||||
|
self.object:set_properties({
|
||||||
|
nametag = tostring(math.random(1000, 10000)),
|
||||||
|
nametag_color = self.color,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
|
||||||
|
get_staticdata = function(self)
|
||||||
|
return minetest.serialize({ color = self.color })
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
@ -22,3 +22,10 @@ minetest.register_craftitem("testfood:bad5", {
|
|||||||
on_use = minetest.item_eat(-5),
|
on_use = minetest.item_eat(-5),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("testfood:replace1", {
|
||||||
|
description = S("Replacing Food (+1)").."\n"..
|
||||||
|
S("Replaced with 'Good Food (+1)' when eaten"),
|
||||||
|
inventory_image = "testfood_replace.png",
|
||||||
|
on_use = minetest.item_eat(1, "testfood:good1"),
|
||||||
|
})
|
||||||
|
|
||||||
|
BIN
games/devtest/mods/testfood/textures/testfood_replace.png
Normal file
BIN
games/devtest/mods/testfood/textures/testfood_replace.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 135 B |
@ -1,5 +1,3 @@
|
|||||||
cmake_minimum_required(VERSION 2.4 FATAL_ERROR)
|
|
||||||
|
|
||||||
project(lua C)
|
project(lua C)
|
||||||
|
|
||||||
set(LUA_VERSION_MAJOR 5)
|
set(LUA_VERSION_MAJOR 5)
|
||||||
@ -15,9 +13,8 @@ set(LIBS)
|
|||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(DEFAULT_POSIX TRUE)
|
set(DEFAULT_POSIX TRUE)
|
||||||
set(DEFAULT_DLOPEN ON)
|
set(DEFAULT_DLOPEN OFF)
|
||||||
# use this on Mac OS X 10.3-
|
set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX")
|
||||||
option(LUA_USE_MACOSX "Mac OS X 10.3-" OFF)
|
|
||||||
elseif(UNIX OR CYGWIN)
|
elseif(UNIX OR CYGWIN)
|
||||||
set(DEFAULT_POSIX TRUE)
|
set(DEFAULT_POSIX TRUE)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
@ -32,12 +29,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||||||
set(DEFAULT_DLOPEN ON)
|
set(DEFAULT_DLOPEN ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# For "Mac OS X 10.3-"
|
|
||||||
if(LUA_USE_MACOSX)
|
|
||||||
set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX")
|
|
||||||
set(LUA_USE_DLOPEN FALSE)
|
|
||||||
endif(LUA_USE_MACOSX)
|
|
||||||
|
|
||||||
option(LUA_USE_DLOPEN "Enable dlopen support." ${DEFAULT_DLOPEN})
|
option(LUA_USE_DLOPEN "Enable dlopen support." ${DEFAULT_DLOPEN})
|
||||||
mark_as_advanced(LUA_USE_DLOPEN)
|
mark_as_advanced(LUA_USE_DLOPEN)
|
||||||
|
|
||||||
|
@ -129,6 +129,9 @@
|
|||||||
# type: float min: 0.001
|
# type: float min: 0.001
|
||||||
# repeat_joystick_button_time = 0.17
|
# repeat_joystick_button_time = 0.17
|
||||||
|
|
||||||
|
# The deadzone of the joystick
|
||||||
|
# joystick_deadzone = 2048
|
||||||
|
|
||||||
# The sensitivity of the joystick axes for moving the
|
# The sensitivity of the joystick axes for moving the
|
||||||
# ingame view frustum around.
|
# ingame view frustum around.
|
||||||
# type: float
|
# type: float
|
||||||
|
@ -3,9 +3,9 @@ Priority: extra
|
|||||||
Standards-Version: 3.6.2
|
Standards-Version: 3.6.2
|
||||||
Package: minetest-staging
|
Package: minetest-staging
|
||||||
Version: 0.4.15-DATEPLACEHOLDER
|
Version: 0.4.15-DATEPLACEHOLDER
|
||||||
Depends: libc6, libcurl3-gnutls, libfreetype6, libirrlicht1.8, LEVELDB_PLACEHOLDER, liblua5.1-0, libluajit-5.1-2, libopenal1, libstdc++6, libvorbisfile3, libx11-6, zlib1g
|
Depends: libc6, libcurl3-gnutls, libfreetype6, libirrlicht1.8, libjsoncpp1, LEVELDB_PLACEHOLDER, liblua5.1-0, libluajit-5.1-2, libopenal1, libsqlite3-0, libstdc++6, libvorbisfile3, libx11-6, zlib1g
|
||||||
Maintainer: Loic Blot <loic.blot@unix-experience.fr>
|
Maintainer: Loic Blot <loic.blot@unix-experience.fr>
|
||||||
Homepage: http://minetest.net/
|
Homepage: https://www.minetest.net/
|
||||||
Vcs-Git: https://github.com/minetest/minetest.git
|
Vcs-Git: https://github.com/minetest/minetest.git
|
||||||
Vcs-Browser: https://github.com/minetest/minetest.git
|
Vcs-Browser: https://github.com/minetest/minetest.git
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
cmake_minimum_required(VERSION 2.6)
|
|
||||||
|
|
||||||
project(minetest)
|
project(minetest)
|
||||||
|
|
||||||
INCLUDE(CheckIncludeFiles)
|
INCLUDE(CheckIncludeFiles)
|
||||||
@ -124,27 +122,6 @@ option(ENABLE_FREETYPE "Enable FreeType2 (TrueType fonts and basic unicode suppo
|
|||||||
set(USE_FREETYPE FALSE)
|
set(USE_FREETYPE FALSE)
|
||||||
|
|
||||||
if(ENABLE_FREETYPE)
|
if(ENABLE_FREETYPE)
|
||||||
##
|
|
||||||
## Note: FindFreetype.cmake seems to have been fixed in recent versions of
|
|
||||||
## CMake. If issues persist, re-enable this workaround specificially for the
|
|
||||||
## failing platforms.
|
|
||||||
##
|
|
||||||
# if(UNIX)
|
|
||||||
# include(FindPkgConfig)
|
|
||||||
# if(PKG_CONFIG_FOUND)
|
|
||||||
# pkg_check_modules(FREETYPE QUIET freetype2)
|
|
||||||
# if(FREETYPE_FOUND)
|
|
||||||
# SET(FREETYPE_PKGCONFIG_FOUND TRUE)
|
|
||||||
# SET(FREETYPE_LIBRARY ${FREETYPE_LIBRARIES})
|
|
||||||
# # Because CMake is idiotic
|
|
||||||
# string(REPLACE ";" " " FREETYPE_CFLAGS_STR ${FREETYPE_CFLAGS})
|
|
||||||
# string(REPLACE ";" " " FREETYPE_LDFLAGS_STR ${FREETYPE_LDFLAGS})
|
|
||||||
# endif(FREETYPE_FOUND)
|
|
||||||
# endif(PKG_CONFIG_FOUND)
|
|
||||||
# endif(UNIX)
|
|
||||||
# if(NOT FREETYPE_FOUND)
|
|
||||||
# find_package(Freetype)
|
|
||||||
# endif()
|
|
||||||
find_package(Freetype)
|
find_package(Freetype)
|
||||||
if(FREETYPE_FOUND)
|
if(FREETYPE_FOUND)
|
||||||
message(STATUS "Freetype enabled.")
|
message(STATUS "Freetype enabled.")
|
||||||
|
@ -691,10 +691,11 @@ void Camera::drawNametags()
|
|||||||
core::matrix4 trans = m_cameranode->getProjectionMatrix();
|
core::matrix4 trans = m_cameranode->getProjectionMatrix();
|
||||||
trans *= m_cameranode->getViewMatrix();
|
trans *= m_cameranode->getViewMatrix();
|
||||||
|
|
||||||
for (std::list<Nametag *>::const_iterator
|
gui::IGUIFont *font = g_fontengine->getFont();
|
||||||
i = m_nametags.begin();
|
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
|
||||||
i != m_nametags.end(); ++i) {
|
v2u32 screensize = driver->getScreenSize();
|
||||||
Nametag *nametag = *i;
|
|
||||||
|
for (const Nametag *nametag : m_nametags) {
|
||||||
if (nametag->nametag_color.getAlpha() == 0) {
|
if (nametag->nametag_color.getAlpha() == 0) {
|
||||||
// Enforce hiding nametag,
|
// Enforce hiding nametag,
|
||||||
// because if freetype is enabled, a grey
|
// because if freetype is enabled, a grey
|
||||||
@ -707,21 +708,29 @@ void Camera::drawNametags()
|
|||||||
if (transformed_pos[3] > 0) {
|
if (transformed_pos[3] > 0) {
|
||||||
std::wstring nametag_colorless =
|
std::wstring nametag_colorless =
|
||||||
unescape_translate(utf8_to_wide(nametag->nametag_text));
|
unescape_translate(utf8_to_wide(nametag->nametag_text));
|
||||||
core::dimension2d<u32> textsize =
|
core::dimension2d<u32> textsize = font->getDimension(
|
||||||
g_fontengine->getFont()->getDimension(
|
|
||||||
nametag_colorless.c_str());
|
nametag_colorless.c_str());
|
||||||
f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
|
f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
|
||||||
core::reciprocal(transformed_pos[3]);
|
core::reciprocal(transformed_pos[3]);
|
||||||
v2u32 screensize = RenderingEngine::get_video_driver()->getScreenSize();
|
|
||||||
v2s32 screen_pos;
|
v2s32 screen_pos;
|
||||||
screen_pos.X = screensize.X *
|
screen_pos.X = screensize.X *
|
||||||
(0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2;
|
(0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2;
|
||||||
screen_pos.Y = screensize.Y *
|
screen_pos.Y = screensize.Y *
|
||||||
(0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2;
|
(0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2;
|
||||||
core::rect<s32> size(0, 0, textsize.Width, textsize.Height);
|
core::rect<s32> size(0, 0, textsize.Width, textsize.Height);
|
||||||
g_fontengine->getFont()->draw(
|
core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height);
|
||||||
|
|
||||||
|
video::SColor textColor = nametag->nametag_color;
|
||||||
|
|
||||||
|
bool darkBackground = textColor.getLuminance() > 186;
|
||||||
|
video::SColor backgroundColor = darkBackground
|
||||||
|
? video::SColor(50, 50, 50, 50)
|
||||||
|
: video::SColor(50, 255, 255, 255);
|
||||||
|
driver->draw2DRectangle(backgroundColor, bg_size + screen_pos);
|
||||||
|
|
||||||
|
font->draw(
|
||||||
translate_string(utf8_to_wide(nametag->nametag_text)).c_str(),
|
translate_string(utf8_to_wide(nametag->nametag_text)).c_str(),
|
||||||
size + screen_pos, nametag->nametag_color);
|
size + screen_pos, textColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,8 @@ public:
|
|||||||
|
|
||||||
~CAOShaderConstantSetter() override = default;
|
~CAOShaderConstantSetter() override = default;
|
||||||
|
|
||||||
void onSetConstants(video::IMaterialRendererServices *services,
|
void onSetConstants(video::IMaterialRendererServices *services) override
|
||||||
bool is_highlevel) override
|
|
||||||
{
|
{
|
||||||
if (!is_highlevel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Ambient color
|
// Ambient color
|
||||||
video::SColorf emissive_color(m_emissive_color);
|
video::SColorf emissive_color(m_emissive_color);
|
||||||
|
|
||||||
|
@ -290,6 +290,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
u32 vertex_count = 0;
|
u32 vertex_count = 0;
|
||||||
|
u32 drawcall_count = 0;
|
||||||
|
|
||||||
// For limiting number of mesh animations per frame
|
// For limiting number of mesh animations per frame
|
||||||
u32 mesh_animate_count = 0;
|
u32 mesh_animate_count = 0;
|
||||||
@ -391,6 +392,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||||||
}
|
}
|
||||||
driver->setMaterial(list.m);
|
driver->setMaterial(list.m);
|
||||||
|
|
||||||
|
drawcall_count += list.bufs.size();
|
||||||
for (auto &pair : list.bufs) {
|
for (auto &pair : list.bufs) {
|
||||||
scene::IMeshBuffer *buf = pair.second;
|
scene::IMeshBuffer *buf = pair.second;
|
||||||
|
|
||||||
@ -411,6 +413,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_profiler->avg(prefix + "vertices drawn [#]", vertex_count);
|
g_profiler->avg(prefix + "vertices drawn [#]", vertex_count);
|
||||||
|
g_profiler->avg(prefix + "drawcalls [#]", drawcall_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
|
static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
|
||||||
|
@ -1173,7 +1173,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getParent() && std::fabs(m_prop.automatic_rotate) > 0.001) {
|
if (!getParent() && node && fabs(m_prop.automatic_rotate) > 0.001f) {
|
||||||
// This is the child node's rotation. It is only used for automatic_rotate.
|
// This is the child node's rotation. It is only used for automatic_rotate.
|
||||||
v3f local_rot = node->getRotation();
|
v3f local_rot = node->getRotation();
|
||||||
local_rot.Y = modulo360f(local_rot.Y - dtime * core::RADTODEG *
|
local_rot.Y = modulo360f(local_rot.Y - dtime * core::RADTODEG *
|
||||||
@ -1182,7 +1182,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!getParent() && m_prop.automatic_face_movement_dir &&
|
if (!getParent() && m_prop.automatic_face_movement_dir &&
|
||||||
(fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)) {
|
(fabs(m_velocity.Z) > 0.001f || fabs(m_velocity.X) > 0.001f)) {
|
||||||
float target_yaw = atan2(m_velocity.Z, m_velocity.X) * 180 / M_PI
|
float target_yaw = atan2(m_velocity.Z, m_velocity.X) * 180 / M_PI
|
||||||
+ m_prop.automatic_face_movement_dir_offset;
|
+ m_prop.automatic_face_movement_dir_offset;
|
||||||
float max_rotation_per_sec =
|
float max_rotation_per_sec =
|
||||||
|
@ -519,7 +519,7 @@ bool Game::createClient(const GameStartData &start_data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameGlobalShaderConstantSetterFactory *scsf = new GameGlobalShaderConstantSetterFactory(
|
auto *scsf = new GameGlobalShaderConstantSetterFactory(
|
||||||
&m_flags.force_fog_off, &runData.fog_range, client);
|
&m_flags.force_fog_off, &runData.fog_range, client);
|
||||||
shader_src->addShaderConstantSetterFactory(scsf);
|
shader_src->addShaderConstantSetterFactory(scsf);
|
||||||
|
|
||||||
@ -529,20 +529,14 @@ bool Game::createClient(const GameStartData &start_data)
|
|||||||
/* Camera
|
/* Camera
|
||||||
*/
|
*/
|
||||||
camera = new Camera(*draw_control, client);
|
camera = new Camera(*draw_control, client);
|
||||||
if (!camera || !camera->successfullyCreated(*error_message))
|
if (!camera->successfullyCreated(*error_message))
|
||||||
return false;
|
return false;
|
||||||
client->setCamera(camera);
|
client->setCamera(camera);
|
||||||
|
|
||||||
/* Clouds
|
/* Clouds
|
||||||
*/
|
*/
|
||||||
if (m_cache_enable_clouds) {
|
if (m_cache_enable_clouds)
|
||||||
clouds = new Clouds(smgr, -1, time(0));
|
clouds = new Clouds(smgr, -1, time(0));
|
||||||
if (!clouds) {
|
|
||||||
*error_message = "Memory allocation error (clouds)";
|
|
||||||
errorstream << *error_message << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skybox
|
/* Skybox
|
||||||
*/
|
*/
|
||||||
@ -550,12 +544,6 @@ bool Game::createClient(const GameStartData &start_data)
|
|||||||
scsf->setSky(sky);
|
scsf->setSky(sky);
|
||||||
skybox = NULL; // This is used/set later on in the main run loop
|
skybox = NULL; // This is used/set later on in the main run loop
|
||||||
|
|
||||||
if (!sky) {
|
|
||||||
*error_message = "Memory allocation error sky";
|
|
||||||
errorstream << *error_message << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pre-calculated values
|
/* Pre-calculated values
|
||||||
*/
|
*/
|
||||||
video::ITexture *t = texture_src->getTexture("crack_anylength.png");
|
video::ITexture *t = texture_src->getTexture("crack_anylength.png");
|
||||||
@ -585,12 +573,6 @@ bool Game::createClient(const GameStartData &start_data)
|
|||||||
|
|
||||||
hud = new Hud(guienv, client, player, &player->inventory);
|
hud = new Hud(guienv, client, player, &player->inventory);
|
||||||
|
|
||||||
if (!hud) {
|
|
||||||
*error_message = "Memory error: could not create HUD";
|
|
||||||
errorstream << *error_message << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper = client->getMinimap();
|
mapper = client->getMinimap();
|
||||||
|
|
||||||
if (mapper && client->modsLoaded())
|
if (mapper && client->modsLoaded())
|
||||||
@ -682,9 +664,6 @@ bool Game::connectToServer(const GameStartData &start_data,
|
|||||||
itemdef_manager, nodedef_manager, sound, eventmgr,
|
itemdef_manager, nodedef_manager, sound, eventmgr,
|
||||||
connect_address.isIPv6(), m_game_ui.get());
|
connect_address.isIPv6(), m_game_ui.get());
|
||||||
|
|
||||||
if (!client)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
client->m_simple_singleplayer_mode = simple_singleplayer_mode;
|
client->m_simple_singleplayer_mode = simple_singleplayer_mode;
|
||||||
|
|
||||||
infostream << "Connecting to server at ";
|
infostream << "Connecting to server at ";
|
||||||
@ -2415,8 +2394,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
|
|||||||
wasKeyDown(KeyType::DIG);
|
wasKeyDown(KeyType::DIG);
|
||||||
wasKeyDown(KeyType::PLACE);
|
wasKeyDown(KeyType::PLACE);
|
||||||
|
|
||||||
input->joystick.clearWasKeyDown(KeyType::DIG);
|
input->joystick.clearWasKeyPressed(KeyType::DIG);
|
||||||
input->joystick.clearWasKeyDown(KeyType::PLACE);
|
input->joystick.clearWasKeyPressed(KeyType::PLACE);
|
||||||
|
|
||||||
input->joystick.clearWasKeyReleased(KeyType::DIG);
|
input->joystick.clearWasKeyReleased(KeyType::DIG);
|
||||||
input->joystick.clearWasKeyReleased(KeyType::PLACE);
|
input->joystick.clearWasKeyReleased(KeyType::PLACE);
|
||||||
|
@ -203,7 +203,7 @@ struct LocalFormspecHandler : public TextDest
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_client && m_client->modsLoaded())
|
if (m_client->modsLoaded())
|
||||||
m_client->getScript()->on_formspec_input(m_formname, fields);
|
m_client->getScript()->on_formspec_input(m_formname, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,12 +492,8 @@ public:
|
|||||||
g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
|
g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
void onSetConstants(video::IMaterialRendererServices *services) override
|
||||||
bool is_highlevel)
|
|
||||||
{
|
{
|
||||||
if (!is_highlevel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Background color
|
// Background color
|
||||||
video::SColor bgcolor = m_sky->getBgColor();
|
video::SColor bgcolor = m_sky->getBgColor();
|
||||||
video::SColorf bgcolorf(bgcolor);
|
video::SColorf bgcolorf(bgcolor);
|
||||||
@ -604,7 +600,7 @@ public:
|
|||||||
|
|
||||||
virtual IShaderConstantSetter* create()
|
virtual IShaderConstantSetter* create()
|
||||||
{
|
{
|
||||||
GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter(
|
auto *scs = new GameGlobalShaderConstantSetter(
|
||||||
m_sky, m_force_fog_off, m_fog_range, m_client);
|
m_sky, m_force_fog_off, m_fog_range, m_client);
|
||||||
if (!m_sky)
|
if (!m_sky)
|
||||||
created_nosky.push_back(scs);
|
created_nosky.push_back(scs);
|
||||||
@ -643,7 +639,6 @@ struct GameRunData {
|
|||||||
bool btn_down_for_dig;
|
bool btn_down_for_dig;
|
||||||
bool dig_instantly;
|
bool dig_instantly;
|
||||||
bool digging_blocked;
|
bool digging_blocked;
|
||||||
bool left_punch;
|
|
||||||
bool reset_jump_timer;
|
bool reset_jump_timer;
|
||||||
float nodig_delay_timer;
|
float nodig_delay_timer;
|
||||||
float dig_time;
|
float dig_time;
|
||||||
|
@ -100,7 +100,7 @@ Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player,
|
|||||||
if (g_settings->getBool("enable_shaders")) {
|
if (g_settings->getBool("enable_shaders")) {
|
||||||
IShaderSource *shdrsrc = client->getShaderSource();
|
IShaderSource *shdrsrc = client->getShaderSource();
|
||||||
u16 shader_id = shdrsrc->getShader(
|
u16 shader_id = shdrsrc->getShader(
|
||||||
m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", 1, 1);
|
m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", TILE_MATERIAL_ALPHA);
|
||||||
m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
|
m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
|
||||||
} else {
|
} else {
|
||||||
m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
@ -1055,9 +1055,9 @@ void drawItemStack(
|
|||||||
|
|
||||||
if (def.type == ITEM_TOOL && item.wear != 0) {
|
if (def.type == ITEM_TOOL && item.wear != 0) {
|
||||||
// Draw a progressbar
|
// Draw a progressbar
|
||||||
float barheight = rect.getHeight() / 16;
|
float barheight = static_cast<float>(rect.getHeight()) / 16;
|
||||||
float barpad_x = rect.getWidth() / 16;
|
float barpad_x = static_cast<float>(rect.getWidth()) / 16;
|
||||||
float barpad_y = rect.getHeight() / 16;
|
float barpad_y = static_cast<float>(rect.getHeight()) / 16;
|
||||||
|
|
||||||
core::rect<s32> progressrect(
|
core::rect<s32> progressrect(
|
||||||
rect.UpperLeftCorner.X + barpad_x,
|
rect.UpperLeftCorner.X + barpad_x,
|
||||||
|
@ -290,7 +290,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual bool wasKeyPressed(GameKeyType k)
|
virtual bool wasKeyPressed(GameKeyType k)
|
||||||
{
|
{
|
||||||
return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyReleased(k);
|
return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyPressed(k);
|
||||||
}
|
}
|
||||||
virtual bool wasKeyReleased(GameKeyType k)
|
virtual bool wasKeyReleased(GameKeyType k)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@ bool JoystickAxisCmb::isTriggered(const irr::SEvent::SJoystickEvent &ev) const
|
|||||||
{
|
{
|
||||||
s16 ax_val = ev.Axis[axis_to_compare];
|
s16 ax_val = ev.Axis[axis_to_compare];
|
||||||
|
|
||||||
return (ax_val * direction < 0) && (thresh * direction > ax_val * direction);
|
return (ax_val * direction < -thresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// spares many characters
|
// spares many characters
|
||||||
@ -48,7 +48,7 @@ JoystickLayout create_default_layout()
|
|||||||
{
|
{
|
||||||
JoystickLayout jlo;
|
JoystickLayout jlo;
|
||||||
|
|
||||||
jlo.axes_dead_border = 1024;
|
jlo.axes_deadzone = g_settings->getU16("joystick_deadzone");
|
||||||
|
|
||||||
const JoystickAxisLayout axes[JA_COUNT] = {
|
const JoystickAxisLayout axes[JA_COUNT] = {
|
||||||
{0, 1}, // JA_SIDEWARD_MOVE
|
{0, 1}, // JA_SIDEWARD_MOVE
|
||||||
@ -93,14 +93,14 @@ JoystickLayout create_default_layout()
|
|||||||
// Now about the buttons simulated by the axes
|
// Now about the buttons simulated by the axes
|
||||||
|
|
||||||
// Movement buttons, important for vessels
|
// Movement buttons, important for vessels
|
||||||
JLO_A_PB(KeyType::FORWARD, 1, 1, 1024);
|
JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::BACKWARD, 1, -1, 1024);
|
JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::LEFT, 0, 1, 1024);
|
JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::RIGHT, 0, -1, 1024);
|
JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone);
|
||||||
|
|
||||||
// Scroll buttons
|
// Scroll buttons
|
||||||
JLO_A_PB(KeyType::HOTBAR_PREV, 2, -1, 1024);
|
JLO_A_PB(KeyType::HOTBAR_PREV, 2, -1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, 1024);
|
JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, jlo.axes_deadzone);
|
||||||
|
|
||||||
return jlo;
|
return jlo;
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ JoystickLayout create_xbox_layout()
|
|||||||
{
|
{
|
||||||
JoystickLayout jlo;
|
JoystickLayout jlo;
|
||||||
|
|
||||||
jlo.axes_dead_border = 7000;
|
jlo.axes_deadzone = 7000;
|
||||||
|
|
||||||
const JoystickAxisLayout axes[JA_COUNT] = {
|
const JoystickAxisLayout axes[JA_COUNT] = {
|
||||||
{0, 1}, // JA_SIDEWARD_MOVE
|
{0, 1}, // JA_SIDEWARD_MOVE
|
||||||
@ -146,10 +146,10 @@ JoystickLayout create_xbox_layout()
|
|||||||
JLO_B_PB(KeyType::FREEMOVE, 1 << 16, 1 << 16); // down
|
JLO_B_PB(KeyType::FREEMOVE, 1 << 16, 1 << 16); // down
|
||||||
|
|
||||||
// Movement buttons, important for vessels
|
// Movement buttons, important for vessels
|
||||||
JLO_A_PB(KeyType::FORWARD, 1, 1, 1024);
|
JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::BACKWARD, 1, -1, 1024);
|
JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::LEFT, 0, 1, 1024);
|
JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone);
|
||||||
JLO_A_PB(KeyType::RIGHT, 0, -1, 1024);
|
JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone);
|
||||||
|
|
||||||
return jlo;
|
return jlo;
|
||||||
}
|
}
|
||||||
@ -219,16 +219,19 @@ bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev)
|
|||||||
|
|
||||||
for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) {
|
for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) {
|
||||||
if (keys_pressed[i]) {
|
if (keys_pressed[i]) {
|
||||||
if (!m_past_pressed_keys[i] &&
|
if (!m_past_keys_pressed[i] &&
|
||||||
m_past_pressed_time[i] < m_internal_time - doubling_dtime) {
|
m_past_pressed_time[i] < m_internal_time - doubling_dtime) {
|
||||||
m_past_pressed_keys[i] = true;
|
m_past_keys_pressed[i] = true;
|
||||||
m_past_pressed_time[i] = m_internal_time;
|
m_past_pressed_time[i] = m_internal_time;
|
||||||
}
|
}
|
||||||
} else if (m_pressed_keys[i]) {
|
} else if (m_keys_down[i]) {
|
||||||
m_past_released_keys[i] = true;
|
m_keys_released[i] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pressed_keys[i] = keys_pressed[i];
|
if (keys_pressed[i] && !(m_keys_down[i]))
|
||||||
|
m_keys_pressed[i] = true;
|
||||||
|
|
||||||
|
m_keys_down[i] = keys_pressed[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < JA_COUNT; i++) {
|
for (size_t i = 0; i < JA_COUNT; i++) {
|
||||||
@ -236,23 +239,22 @@ bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev)
|
|||||||
m_axes_vals[i] = ax_la.invert * ev.Axis[ax_la.axis_id];
|
m_axes_vals[i] = ax_la.invert * ev.Axis[ax_la.axis_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickController::clear()
|
void JoystickController::clear()
|
||||||
{
|
{
|
||||||
m_pressed_keys.reset();
|
m_keys_pressed.reset();
|
||||||
m_past_pressed_keys.reset();
|
m_keys_down.reset();
|
||||||
m_past_released_keys.reset();
|
m_past_keys_pressed.reset();
|
||||||
|
m_keys_released.reset();
|
||||||
memset(m_axes_vals, 0, sizeof(m_axes_vals));
|
memset(m_axes_vals, 0, sizeof(m_axes_vals));
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 JoystickController::getAxisWithoutDead(JoystickAxis axis)
|
s16 JoystickController::getAxisWithoutDead(JoystickAxis axis)
|
||||||
{
|
{
|
||||||
s16 v = m_axes_vals[axis];
|
s16 v = m_axes_vals[axis];
|
||||||
if (((v > 0) && (v < m_layout.axes_dead_border)) ||
|
if (abs(v) < m_layout.axes_deadzone)
|
||||||
((v < 0) && (v > -m_layout.axes_dead_border)))
|
|
||||||
return 0;
|
return 0;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ struct JoystickLayout {
|
|||||||
std::vector<JoystickButtonCmb> button_keys;
|
std::vector<JoystickButtonCmb> button_keys;
|
||||||
std::vector<JoystickAxisCmb> axis_keys;
|
std::vector<JoystickAxisCmb> axis_keys;
|
||||||
JoystickAxisLayout axes[JA_COUNT];
|
JoystickAxisLayout axes[JA_COUNT];
|
||||||
s16 axes_dead_border;
|
s16 axes_deadzone;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JoystickController {
|
class JoystickController {
|
||||||
@ -111,37 +111,32 @@ public:
|
|||||||
|
|
||||||
bool wasKeyDown(GameKeyType b)
|
bool wasKeyDown(GameKeyType b)
|
||||||
{
|
{
|
||||||
bool r = m_past_pressed_keys[b];
|
bool r = m_past_keys_pressed[b];
|
||||||
m_past_pressed_keys[b] = false;
|
m_past_keys_pressed[b] = false;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
bool getWasKeyDown(GameKeyType b)
|
|
||||||
{
|
|
||||||
return m_past_pressed_keys[b];
|
|
||||||
}
|
|
||||||
void clearWasKeyDown(GameKeyType b)
|
|
||||||
{
|
|
||||||
m_past_pressed_keys[b] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wasKeyReleased(GameKeyType b)
|
bool wasKeyReleased(GameKeyType b)
|
||||||
{
|
{
|
||||||
bool r = m_past_released_keys[b];
|
return m_keys_released[b];
|
||||||
m_past_released_keys[b] = false;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
bool getWasKeyReleased(GameKeyType b)
|
|
||||||
{
|
|
||||||
return m_past_pressed_keys[b];
|
|
||||||
}
|
}
|
||||||
void clearWasKeyReleased(GameKeyType b)
|
void clearWasKeyReleased(GameKeyType b)
|
||||||
{
|
{
|
||||||
m_past_pressed_keys[b] = false;
|
m_keys_released[b] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wasKeyPressed(GameKeyType b)
|
||||||
|
{
|
||||||
|
return m_keys_pressed[b];
|
||||||
|
}
|
||||||
|
void clearWasKeyPressed(GameKeyType b)
|
||||||
|
{
|
||||||
|
m_keys_pressed[b] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isKeyDown(GameKeyType b)
|
bool isKeyDown(GameKeyType b)
|
||||||
{
|
{
|
||||||
return m_pressed_keys[b];
|
return m_keys_down[b];
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 getAxis(JoystickAxis axis)
|
s16 getAxis(JoystickAxis axis)
|
||||||
@ -162,12 +157,13 @@ private:
|
|||||||
|
|
||||||
u8 m_joystick_id = 0;
|
u8 m_joystick_id = 0;
|
||||||
|
|
||||||
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_pressed_keys;
|
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_keys_down;
|
||||||
|
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_keys_pressed;
|
||||||
|
|
||||||
f32 m_internal_time;
|
f32 m_internal_time;
|
||||||
|
|
||||||
f32 m_past_pressed_time[KeyType::INTERNAL_ENUM_COUNT];
|
f32 m_past_pressed_time[KeyType::INTERNAL_ENUM_COUNT];
|
||||||
|
|
||||||
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_past_pressed_keys;
|
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_past_keys_pressed;
|
||||||
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_past_released_keys;
|
std::bitset<KeyType::INTERNAL_ENUM_COUNT> m_keys_released;
|
||||||
};
|
};
|
||||||
|
@ -1269,13 +1269,13 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
|||||||
MapBlockMesh::~MapBlockMesh()
|
MapBlockMesh::~MapBlockMesh()
|
||||||
{
|
{
|
||||||
for (scene::IMesh *m : m_mesh) {
|
for (scene::IMesh *m : m_mesh) {
|
||||||
if (m_enable_vbo && m)
|
if (m_enable_vbo) {
|
||||||
for (u32 i = 0; i < m->getMeshBufferCount(); i++) {
|
for (u32 i = 0; i < m->getMeshBufferCount(); i++) {
|
||||||
scene::IMeshBuffer *buf = m->getMeshBuffer(i);
|
scene::IMeshBuffer *buf = m->getMeshBuffer(i);
|
||||||
RenderingEngine::get_video_driver()->removeHardwareBuffer(buf);
|
RenderingEngine::get_video_driver()->removeHardwareBuffer(buf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m->drop();
|
m->drop();
|
||||||
m = NULL;
|
|
||||||
}
|
}
|
||||||
delete m_minimap_mapblock;
|
delete m_minimap_mapblock;
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ void Minimap::drawMinimap(core::rect<s32> rect) {
|
|||||||
material.TextureLayer[1].Texture = data->heightmap_texture;
|
material.TextureLayer[1].Texture = data->heightmap_texture;
|
||||||
|
|
||||||
if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) {
|
if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) {
|
||||||
u16 sid = m_shdrsrc->getShader("minimap_shader", 1, 1);
|
u16 sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA);
|
||||||
material.MaterialType = m_shdrsrc->getShaderInfo(sid).material;
|
material.MaterialType = m_shdrsrc->getShaderInfo(sid).material;
|
||||||
} else {
|
} else {
|
||||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
|
@ -36,7 +36,7 @@ void RenderingCoreInterlaced::initMaterial()
|
|||||||
mat.UseMipMaps = false;
|
mat.UseMipMaps = false;
|
||||||
mat.ZBuffer = false;
|
mat.ZBuffer = false;
|
||||||
mat.ZWriteEnable = false;
|
mat.ZWriteEnable = false;
|
||||||
u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC, 0);
|
u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC);
|
||||||
mat.MaterialType = s->getShaderInfo(shader).material;
|
mat.MaterialType = s->getShaderInfo(shader).material;
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
mat.TextureLayer[k].AnisotropicFilter = false;
|
mat.TextureLayer[k].AnisotropicFilter = false;
|
||||||
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
|
#include "irr_ptr.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "util/container.h"
|
#include "util/container.h"
|
||||||
@ -189,19 +190,14 @@ private:
|
|||||||
|
|
||||||
class ShaderCallback : public video::IShaderConstantSetCallBack
|
class ShaderCallback : public video::IShaderConstantSetCallBack
|
||||||
{
|
{
|
||||||
std::vector<IShaderConstantSetter*> m_setters;
|
std::vector<std::unique_ptr<IShaderConstantSetter>> m_setters;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShaderCallback(const std::vector<IShaderConstantSetterFactory *> &factories)
|
template <typename Factories>
|
||||||
|
ShaderCallback(const Factories &factories)
|
||||||
{
|
{
|
||||||
for (IShaderConstantSetterFactory *factory : factories)
|
for (auto &&factory : factories)
|
||||||
m_setters.push_back(factory->create());
|
m_setters.push_back(std::unique_ptr<IShaderConstantSetter>(factory->create()));
|
||||||
}
|
|
||||||
|
|
||||||
~ShaderCallback()
|
|
||||||
{
|
|
||||||
for (IShaderConstantSetter *setter : m_setters)
|
|
||||||
delete setter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData) override
|
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData) override
|
||||||
@ -209,15 +205,13 @@ public:
|
|||||||
video::IVideoDriver *driver = services->getVideoDriver();
|
video::IVideoDriver *driver = services->getVideoDriver();
|
||||||
sanity_check(driver != NULL);
|
sanity_check(driver != NULL);
|
||||||
|
|
||||||
bool is_highlevel = userData;
|
for (auto &&setter : m_setters)
|
||||||
|
setter->onSetConstants(services);
|
||||||
for (IShaderConstantSetter *setter : m_setters)
|
|
||||||
setter->onSetConstants(services, is_highlevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnSetMaterial(const video::SMaterial& material) override
|
virtual void OnSetMaterial(const video::SMaterial& material) override
|
||||||
{
|
{
|
||||||
for (IShaderConstantSetter *setter : m_setters)
|
for (auto &&setter : m_setters)
|
||||||
setter->onSetMaterial(material);
|
setter->onSetMaterial(material);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -252,47 +246,39 @@ public:
|
|||||||
{}
|
{}
|
||||||
~MainShaderConstantSetter() = default;
|
~MainShaderConstantSetter() = default;
|
||||||
|
|
||||||
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
virtual void onSetConstants(video::IMaterialRendererServices *services) override
|
||||||
bool is_highlevel)
|
|
||||||
{
|
{
|
||||||
video::IVideoDriver *driver = services->getVideoDriver();
|
video::IVideoDriver *driver = services->getVideoDriver();
|
||||||
sanity_check(driver);
|
sanity_check(driver);
|
||||||
|
|
||||||
// Set world matrix
|
// Set world matrix
|
||||||
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
|
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
|
||||||
if (is_highlevel)
|
m_world.set(*reinterpret_cast<float(*)[16]>(world.pointer()), services);
|
||||||
m_world.set(*reinterpret_cast<float(*)[16]>(world.pointer()), services);
|
|
||||||
else
|
|
||||||
services->setVertexShaderConstant(world.pointer(), 4, 4);
|
|
||||||
|
|
||||||
// Set clip matrix
|
// Set clip matrix
|
||||||
core::matrix4 worldView;
|
core::matrix4 worldView;
|
||||||
worldView = driver->getTransform(video::ETS_VIEW);
|
worldView = driver->getTransform(video::ETS_VIEW);
|
||||||
worldView *= world;
|
worldView *= world;
|
||||||
|
|
||||||
core::matrix4 worldViewProj;
|
core::matrix4 worldViewProj;
|
||||||
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
|
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
|
||||||
worldViewProj *= worldView;
|
worldViewProj *= worldView;
|
||||||
if (is_highlevel)
|
m_world_view_proj.set(*reinterpret_cast<float(*)[16]>(worldViewProj.pointer()), services);
|
||||||
m_world_view_proj.set(*reinterpret_cast<float(*)[16]>(worldViewProj.pointer()), services);
|
|
||||||
else
|
|
||||||
services->setVertexShaderConstant(worldViewProj.pointer(), 0, 4);
|
|
||||||
|
|
||||||
#if ENABLE_GLES
|
#if ENABLE_GLES
|
||||||
if (is_highlevel) {
|
core::matrix4 texture = driver->getTransform(video::ETS_TEXTURE_0);
|
||||||
core::matrix4 texture = driver->getTransform(video::ETS_TEXTURE_0);
|
m_world_view.set(*reinterpret_cast<float(*)[16]>(worldView.pointer()), services);
|
||||||
m_world_view.set(*reinterpret_cast<float(*)[16]>(worldView.pointer()), services);
|
m_texture.set(*reinterpret_cast<float(*)[16]>(texture.pointer()), services);
|
||||||
m_texture.set(*reinterpret_cast<float(*)[16]>(texture.pointer()), services);
|
|
||||||
|
|
||||||
core::matrix4 normal;
|
core::matrix4 normal;
|
||||||
worldView.getTransposed(normal);
|
worldView.getTransposed(normal);
|
||||||
sanity_check(normal.makeInverse());
|
sanity_check(normal.makeInverse());
|
||||||
float m[9] = {
|
float m[9] = {
|
||||||
normal[0], normal[1], normal[2],
|
normal[0], normal[1], normal[2],
|
||||||
normal[4], normal[5], normal[6],
|
normal[4], normal[5], normal[6],
|
||||||
normal[8], normal[9], normal[10],
|
normal[8], normal[9], normal[10],
|
||||||
};
|
};
|
||||||
m_normal.set(m, services);
|
m_normal.set(m, services);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -314,7 +300,6 @@ class ShaderSource : public IWritableShaderSource
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShaderSource();
|
ShaderSource();
|
||||||
~ShaderSource();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
- If shader material specified by name is found from cache,
|
- If shader material specified by name is found from cache,
|
||||||
@ -324,7 +309,7 @@ public:
|
|||||||
The id 0 points to a null shader. Its material is EMT_SOLID.
|
The id 0 points to a null shader. Its material is EMT_SOLID.
|
||||||
*/
|
*/
|
||||||
u32 getShaderIdDirect(const std::string &name,
|
u32 getShaderIdDirect(const std::string &name,
|
||||||
const u8 material_type, const u8 drawtype);
|
MaterialType material_type, NodeDrawType drawtype) override;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If shader specified by the name pointed by the id doesn't
|
If shader specified by the name pointed by the id doesn't
|
||||||
@ -336,26 +321,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
u32 getShader(const std::string &name,
|
u32 getShader(const std::string &name,
|
||||||
const u8 material_type, const u8 drawtype);
|
MaterialType material_type, NodeDrawType drawtype) override;
|
||||||
|
|
||||||
ShaderInfo getShaderInfo(u32 id);
|
ShaderInfo getShaderInfo(u32 id) override;
|
||||||
|
|
||||||
// Processes queued shader requests from other threads.
|
// Processes queued shader requests from other threads.
|
||||||
// Shall be called from the main thread.
|
// Shall be called from the main thread.
|
||||||
void processQueue();
|
void processQueue() override;
|
||||||
|
|
||||||
// Insert a shader program into the cache without touching the
|
// Insert a shader program into the cache without touching the
|
||||||
// filesystem. Shall be called from the main thread.
|
// filesystem. Shall be called from the main thread.
|
||||||
void insertSourceShader(const std::string &name_of_shader,
|
void insertSourceShader(const std::string &name_of_shader,
|
||||||
const std::string &filename, const std::string &program);
|
const std::string &filename, const std::string &program) override;
|
||||||
|
|
||||||
// Rebuild shaders from the current set of source shaders
|
// Rebuild shaders from the current set of source shaders
|
||||||
// Shall be called from the main thread.
|
// Shall be called from the main thread.
|
||||||
void rebuildShaders();
|
void rebuildShaders() override;
|
||||||
|
|
||||||
void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter)
|
void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) override
|
||||||
{
|
{
|
||||||
m_setter_factories.push_back(setter);
|
m_setter_factories.push_back(std::unique_ptr<IShaderConstantSetterFactory>(setter));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -377,10 +362,11 @@ private:
|
|||||||
RequestQueue<std::string, u32, u8, u8> m_get_shader_queue;
|
RequestQueue<std::string, u32, u8, u8> m_get_shader_queue;
|
||||||
|
|
||||||
// Global constant setter factories
|
// Global constant setter factories
|
||||||
std::vector<IShaderConstantSetterFactory *> m_setter_factories;
|
std::vector<std::unique_ptr<IShaderConstantSetterFactory>> m_setter_factories;
|
||||||
|
|
||||||
// Shader callbacks
|
// Generate shader given the shader name.
|
||||||
std::vector<ShaderCallback *> m_callbacks;
|
ShaderInfo generateShader(const std::string &name,
|
||||||
|
MaterialType material_type, NodeDrawType drawtype);
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableShaderSource *createShaderSource()
|
IWritableShaderSource *createShaderSource()
|
||||||
@ -388,22 +374,6 @@ IWritableShaderSource *createShaderSource()
|
|||||||
return new ShaderSource();
|
return new ShaderSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Generate shader given the shader name.
|
|
||||||
*/
|
|
||||||
ShaderInfo generate_shader(const std::string &name,
|
|
||||||
u8 material_type, u8 drawtype, std::vector<ShaderCallback *> &callbacks,
|
|
||||||
const std::vector<IShaderConstantSetterFactory *> &setter_factories,
|
|
||||||
SourceShaderCache *sourcecache);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Load shader programs
|
|
||||||
*/
|
|
||||||
void load_shaders(const std::string &name, SourceShaderCache *sourcecache,
|
|
||||||
video::E_DRIVER_TYPE drivertype, bool enable_shaders,
|
|
||||||
std::string &vertex_program, std::string &pixel_program,
|
|
||||||
std::string &geometry_program, bool &is_highlevel);
|
|
||||||
|
|
||||||
ShaderSource::ShaderSource()
|
ShaderSource::ShaderSource()
|
||||||
{
|
{
|
||||||
m_main_thread = std::this_thread::get_id();
|
m_main_thread = std::this_thread::get_id();
|
||||||
@ -415,18 +385,8 @@ ShaderSource::ShaderSource()
|
|||||||
addShaderConstantSetterFactory(new MainShaderConstantSetterFactory());
|
addShaderConstantSetterFactory(new MainShaderConstantSetterFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderSource::~ShaderSource()
|
|
||||||
{
|
|
||||||
for (ShaderCallback *callback : m_callbacks) {
|
|
||||||
delete callback;
|
|
||||||
}
|
|
||||||
for (IShaderConstantSetterFactory *setter_factorie : m_setter_factories) {
|
|
||||||
delete setter_factorie;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 ShaderSource::getShader(const std::string &name,
|
u32 ShaderSource::getShader(const std::string &name,
|
||||||
const u8 material_type, const u8 drawtype)
|
MaterialType material_type, NodeDrawType drawtype)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Get shader
|
Get shader
|
||||||
@ -468,7 +428,7 @@ u32 ShaderSource::getShader(const std::string &name,
|
|||||||
This method generates all the shaders
|
This method generates all the shaders
|
||||||
*/
|
*/
|
||||||
u32 ShaderSource::getShaderIdDirect(const std::string &name,
|
u32 ShaderSource::getShaderIdDirect(const std::string &name,
|
||||||
const u8 material_type, const u8 drawtype)
|
MaterialType material_type, NodeDrawType drawtype)
|
||||||
{
|
{
|
||||||
//infostream<<"getShaderIdDirect(): name=\""<<name<<"\""<<std::endl;
|
//infostream<<"getShaderIdDirect(): name=\""<<name<<"\""<<std::endl;
|
||||||
|
|
||||||
@ -495,8 +455,7 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderInfo info = generate_shader(name, material_type, drawtype,
|
ShaderInfo info = generateShader(name, material_type, drawtype);
|
||||||
m_callbacks, m_setter_factories, &m_sourcecache);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Add shader to caches (add dummy shaders too)
|
Add shader to caches (add dummy shaders too)
|
||||||
@ -560,18 +519,14 @@ void ShaderSource::rebuildShaders()
|
|||||||
for (ShaderInfo &i : m_shaderinfo_cache) {
|
for (ShaderInfo &i : m_shaderinfo_cache) {
|
||||||
ShaderInfo *info = &i;
|
ShaderInfo *info = &i;
|
||||||
if (!info->name.empty()) {
|
if (!info->name.empty()) {
|
||||||
*info = generate_shader(info->name, info->material_type,
|
*info = generateShader(info->name, info->material_type, info->drawtype);
|
||||||
info->drawtype, m_callbacks,
|
|
||||||
m_setter_factories, &m_sourcecache);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtype,
|
ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||||
std::vector<ShaderCallback *> &callbacks,
|
MaterialType material_type, NodeDrawType drawtype)
|
||||||
const std::vector<IShaderConstantSetterFactory *> &setter_factories,
|
|
||||||
SourceShaderCache *sourcecache)
|
|
||||||
{
|
{
|
||||||
ShaderInfo shaderinfo;
|
ShaderInfo shaderinfo;
|
||||||
shaderinfo.name = name;
|
shaderinfo.name = name;
|
||||||
@ -604,64 +559,27 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp
|
|||||||
return shaderinfo;
|
return shaderinfo;
|
||||||
|
|
||||||
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
|
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
|
||||||
|
if (!driver->queryFeature(video::EVDF_ARB_GLSL)) {
|
||||||
|
errorstream << "Shaders are enabled but GLSL is not supported by the driver\n";
|
||||||
|
return shaderinfo;
|
||||||
|
}
|
||||||
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
|
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
|
||||||
if(!gpu){
|
|
||||||
errorstream<<"generate_shader(): "
|
|
||||||
"failed to generate \""<<name<<"\", "
|
|
||||||
"GPU programming not supported."
|
|
||||||
<<std::endl;
|
|
||||||
return shaderinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose shader language depending on driver type and settings
|
|
||||||
// Then load shaders
|
|
||||||
std::string vertex_program;
|
|
||||||
std::string pixel_program;
|
|
||||||
std::string geometry_program;
|
|
||||||
bool is_highlevel;
|
|
||||||
load_shaders(name, sourcecache, driver->getDriverType(),
|
|
||||||
enable_shaders, vertex_program, pixel_program,
|
|
||||||
geometry_program, is_highlevel);
|
|
||||||
// Check hardware/driver support
|
|
||||||
if (!vertex_program.empty() &&
|
|
||||||
!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
|
|
||||||
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)){
|
|
||||||
infostream<<"generate_shader(): vertex shaders disabled "
|
|
||||||
"because of missing driver/hardware support."
|
|
||||||
<<std::endl;
|
|
||||||
vertex_program = "";
|
|
||||||
}
|
|
||||||
if (!pixel_program.empty() &&
|
|
||||||
!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
|
|
||||||
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)){
|
|
||||||
infostream<<"generate_shader(): pixel shaders disabled "
|
|
||||||
"because of missing driver/hardware support."
|
|
||||||
<<std::endl;
|
|
||||||
pixel_program = "";
|
|
||||||
}
|
|
||||||
if (!geometry_program.empty() &&
|
|
||||||
!driver->queryFeature(video::EVDF_GEOMETRY_SHADER)){
|
|
||||||
infostream<<"generate_shader(): geometry shaders disabled "
|
|
||||||
"because of missing driver/hardware support."
|
|
||||||
<<std::endl;
|
|
||||||
geometry_program = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no shaders are used, don't make a separate material type
|
|
||||||
if (vertex_program.empty() && pixel_program.empty() && geometry_program.empty())
|
|
||||||
return shaderinfo;
|
|
||||||
|
|
||||||
// Create shaders header
|
// Create shaders header
|
||||||
bool use_gles = false;
|
bool use_gles = false;
|
||||||
#if ENABLE_GLES
|
#if ENABLE_GLES
|
||||||
use_gles = driver->getDriverType() == video::EDT_OGLES2;
|
use_gles = driver->getDriverType() == video::EDT_OGLES2;
|
||||||
#endif
|
#endif
|
||||||
std::string shaders_header, vertex_header, pixel_header; // geometry shaders aren’t supported in GLES<3
|
std::stringstream shaders_header;
|
||||||
|
shaders_header
|
||||||
|
<< std::noboolalpha
|
||||||
|
<< std::showpoint // for GLSL ES
|
||||||
|
;
|
||||||
|
std::string vertex_header, fragment_header, geometry_header;
|
||||||
if (use_gles) {
|
if (use_gles) {
|
||||||
shaders_header =
|
shaders_header << R"(
|
||||||
"#version 100\n"
|
#version 100
|
||||||
;
|
)";
|
||||||
vertex_header = R"(
|
vertex_header = R"(
|
||||||
uniform highp mat4 mWorldView;
|
uniform highp mat4 mWorldView;
|
||||||
uniform highp mat4 mWorldViewProj;
|
uniform highp mat4 mWorldViewProj;
|
||||||
@ -675,11 +593,11 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp
|
|||||||
attribute mediump vec4 inVertexTangent;
|
attribute mediump vec4 inVertexTangent;
|
||||||
attribute mediump vec4 inVertexBinormal;
|
attribute mediump vec4 inVertexBinormal;
|
||||||
)";
|
)";
|
||||||
pixel_header = R"(
|
fragment_header = R"(
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
)";
|
)";
|
||||||
} else {
|
} else {
|
||||||
shaders_header = R"(
|
shaders_header << R"(
|
||||||
#version 120
|
#version 120
|
||||||
#define lowp
|
#define lowp
|
||||||
#define mediump
|
#define mediump
|
||||||
@ -708,224 +626,97 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp
|
|||||||
use_discard = true;
|
use_discard = true;
|
||||||
#endif
|
#endif
|
||||||
if (use_discard && shaderinfo.base_material != video::EMT_SOLID)
|
if (use_discard && shaderinfo.base_material != video::EMT_SOLID)
|
||||||
shaders_header += "#define USE_DISCARD\n";
|
shaders_header << "#define USE_DISCARD 1\n";
|
||||||
|
|
||||||
static const char* drawTypes[] = {
|
#define PROVIDE(constant) shaders_header << "#define " #constant " " << (int)constant << "\n"
|
||||||
"NDT_NORMAL",
|
|
||||||
"NDT_AIRLIKE",
|
|
||||||
"NDT_LIQUID",
|
|
||||||
"NDT_FLOWINGLIQUID",
|
|
||||||
"NDT_GLASSLIKE",
|
|
||||||
"NDT_ALLFACES",
|
|
||||||
"NDT_ALLFACES_OPTIONAL",
|
|
||||||
"NDT_TORCHLIKE",
|
|
||||||
"NDT_SIGNLIKE",
|
|
||||||
"NDT_PLANTLIKE",
|
|
||||||
"NDT_FENCELIKE",
|
|
||||||
"NDT_RAILLIKE",
|
|
||||||
"NDT_NODEBOX",
|
|
||||||
"NDT_GLASSLIKE_FRAMED",
|
|
||||||
"NDT_FIRELIKE",
|
|
||||||
"NDT_GLASSLIKE_FRAMED_OPTIONAL",
|
|
||||||
"NDT_PLANTLIKE_ROOTED",
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < 14; i++){
|
PROVIDE(NDT_NORMAL);
|
||||||
shaders_header += "#define ";
|
PROVIDE(NDT_AIRLIKE);
|
||||||
shaders_header += drawTypes[i];
|
PROVIDE(NDT_LIQUID);
|
||||||
shaders_header += " ";
|
PROVIDE(NDT_FLOWINGLIQUID);
|
||||||
shaders_header += itos(i);
|
PROVIDE(NDT_GLASSLIKE);
|
||||||
shaders_header += "\n";
|
PROVIDE(NDT_ALLFACES);
|
||||||
|
PROVIDE(NDT_ALLFACES_OPTIONAL);
|
||||||
|
PROVIDE(NDT_TORCHLIKE);
|
||||||
|
PROVIDE(NDT_SIGNLIKE);
|
||||||
|
PROVIDE(NDT_PLANTLIKE);
|
||||||
|
PROVIDE(NDT_FENCELIKE);
|
||||||
|
PROVIDE(NDT_RAILLIKE);
|
||||||
|
PROVIDE(NDT_NODEBOX);
|
||||||
|
PROVIDE(NDT_GLASSLIKE_FRAMED);
|
||||||
|
PROVIDE(NDT_FIRELIKE);
|
||||||
|
PROVIDE(NDT_GLASSLIKE_FRAMED_OPTIONAL);
|
||||||
|
PROVIDE(NDT_PLANTLIKE_ROOTED);
|
||||||
|
|
||||||
|
PROVIDE(TILE_MATERIAL_BASIC);
|
||||||
|
PROVIDE(TILE_MATERIAL_ALPHA);
|
||||||
|
PROVIDE(TILE_MATERIAL_LIQUID_TRANSPARENT);
|
||||||
|
PROVIDE(TILE_MATERIAL_LIQUID_OPAQUE);
|
||||||
|
PROVIDE(TILE_MATERIAL_WAVING_LEAVES);
|
||||||
|
PROVIDE(TILE_MATERIAL_WAVING_PLANTS);
|
||||||
|
PROVIDE(TILE_MATERIAL_OPAQUE);
|
||||||
|
PROVIDE(TILE_MATERIAL_WAVING_LIQUID_BASIC);
|
||||||
|
PROVIDE(TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT);
|
||||||
|
PROVIDE(TILE_MATERIAL_WAVING_LIQUID_OPAQUE);
|
||||||
|
PROVIDE(TILE_MATERIAL_PLAIN);
|
||||||
|
PROVIDE(TILE_MATERIAL_PLAIN_ALPHA);
|
||||||
|
|
||||||
|
#undef PROVIDE
|
||||||
|
|
||||||
|
shaders_header << "#define MATERIAL_TYPE " << (int)material_type << "\n";
|
||||||
|
shaders_header << "#define DRAW_TYPE " << (int)drawtype << "\n";
|
||||||
|
|
||||||
|
bool enable_waving_water = g_settings->getBool("enable_waving_water");
|
||||||
|
shaders_header << "#define ENABLE_WAVING_WATER " << enable_waving_water << "\n";
|
||||||
|
if (enable_waving_water) {
|
||||||
|
shaders_header << "#define WATER_WAVE_HEIGHT " << g_settings->getFloat("water_wave_height") << "\n";
|
||||||
|
shaders_header << "#define WATER_WAVE_LENGTH " << g_settings->getFloat("water_wave_length") << "\n";
|
||||||
|
shaders_header << "#define WATER_WAVE_SPEED " << g_settings->getFloat("water_wave_speed") << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* materialTypes[] = {
|
shaders_header << "#define ENABLE_WAVING_LEAVES " << g_settings->getBool("enable_waving_leaves") << "\n";
|
||||||
"TILE_MATERIAL_BASIC",
|
shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n";
|
||||||
"TILE_MATERIAL_ALPHA",
|
shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n";
|
||||||
"TILE_MATERIAL_LIQUID_TRANSPARENT",
|
|
||||||
"TILE_MATERIAL_LIQUID_OPAQUE",
|
|
||||||
"TILE_MATERIAL_WAVING_LEAVES",
|
|
||||||
"TILE_MATERIAL_WAVING_PLANTS",
|
|
||||||
"TILE_MATERIAL_OPAQUE",
|
|
||||||
"TILE_MATERIAL_WAVING_LIQUID_BASIC",
|
|
||||||
"TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT",
|
|
||||||
"TILE_MATERIAL_WAVING_LIQUID_OPAQUE",
|
|
||||||
"TILE_MATERIAL_PLAIN",
|
|
||||||
"TILE_MATERIAL_PLAIN_ALPHA",
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < 12; i++){
|
shaders_header << "#define FOG_START " << core::clamp(g_settings->getFloat("fog_start"), 0.0f, 0.99f) << "\n";
|
||||||
shaders_header += "#define ";
|
|
||||||
shaders_header += materialTypes[i];
|
std::string common_header = shaders_header.str();
|
||||||
shaders_header += " ";
|
|
||||||
shaders_header += itos(i);
|
std::string vertex_shader = m_sourcecache.getOrLoad(name, "opengl_vertex.glsl");
|
||||||
shaders_header += "\n";
|
std::string fragment_shader = m_sourcecache.getOrLoad(name, "opengl_fragment.glsl");
|
||||||
|
std::string geometry_shader = m_sourcecache.getOrLoad(name, "opengl_geometry.glsl");
|
||||||
|
|
||||||
|
vertex_shader = common_header + vertex_header + vertex_shader;
|
||||||
|
fragment_shader = common_header + fragment_header + fragment_shader;
|
||||||
|
const char *geometry_shader_ptr = nullptr; // optional
|
||||||
|
if (!geometry_shader.empty()) {
|
||||||
|
geometry_shader = common_header + geometry_header + geometry_shader;
|
||||||
|
geometry_shader_ptr = geometry_shader.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
shaders_header += "#define MATERIAL_TYPE ";
|
irr_ptr<ShaderCallback> cb{new ShaderCallback(m_setter_factories)};
|
||||||
shaders_header += itos(material_type);
|
infostream<<"Compiling high level shaders for "<<name<<std::endl;
|
||||||
shaders_header += "\n";
|
s32 shadermat = gpu->addHighLevelShaderMaterial(
|
||||||
shaders_header += "#define DRAW_TYPE ";
|
vertex_shader.c_str(), nullptr, video::EVST_VS_1_1,
|
||||||
shaders_header += itos(drawtype);
|
fragment_shader.c_str(), nullptr, video::EPST_PS_1_1,
|
||||||
shaders_header += "\n";
|
geometry_shader_ptr, nullptr, video::EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLES, 0,
|
||||||
|
cb.get(), shaderinfo.base_material, 1);
|
||||||
if (g_settings->getBool("enable_waving_water")){
|
if (shadermat == -1) {
|
||||||
shaders_header += "#define ENABLE_WAVING_WATER 1\n";
|
errorstream<<"generate_shader(): "
|
||||||
shaders_header += "#define WATER_WAVE_HEIGHT ";
|
"failed to generate \""<<name<<"\", "
|
||||||
shaders_header += std::to_string(g_settings->getFloat("water_wave_height"));
|
"addHighLevelShaderMaterial failed."
|
||||||
shaders_header += "\n";
|
<<std::endl;
|
||||||
shaders_header += "#define WATER_WAVE_LENGTH ";
|
dumpShaderProgram(warningstream, "Vertex", vertex_shader);
|
||||||
shaders_header += std::to_string(g_settings->getFloat("water_wave_length"));
|
dumpShaderProgram(warningstream, "Fragment", fragment_shader);
|
||||||
shaders_header += "\n";
|
dumpShaderProgram(warningstream, "Geometry", geometry_shader);
|
||||||
shaders_header += "#define WATER_WAVE_SPEED ";
|
return shaderinfo;
|
||||||
shaders_header += std::to_string(g_settings->getFloat("water_wave_speed"));
|
|
||||||
shaders_header += "\n";
|
|
||||||
} else{
|
|
||||||
shaders_header += "#define ENABLE_WAVING_WATER 0\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shaders_header += "#define ENABLE_WAVING_LEAVES ";
|
|
||||||
if (g_settings->getBool("enable_waving_leaves"))
|
|
||||||
shaders_header += "1\n";
|
|
||||||
else
|
|
||||||
shaders_header += "0\n";
|
|
||||||
|
|
||||||
shaders_header += "#define ENABLE_WAVING_PLANTS ";
|
|
||||||
if (g_settings->getBool("enable_waving_plants"))
|
|
||||||
shaders_header += "1\n";
|
|
||||||
else
|
|
||||||
shaders_header += "0\n";
|
|
||||||
|
|
||||||
if (g_settings->getBool("tone_mapping"))
|
|
||||||
shaders_header += "#define ENABLE_TONE_MAPPING\n";
|
|
||||||
|
|
||||||
shaders_header += "#define FOG_START ";
|
|
||||||
shaders_header += std::to_string(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f));
|
|
||||||
shaders_header += "\n";
|
|
||||||
|
|
||||||
// Call addHighLevelShaderMaterial() or addShaderMaterial()
|
|
||||||
const c8* vertex_program_ptr = 0;
|
|
||||||
const c8* pixel_program_ptr = 0;
|
|
||||||
const c8* geometry_program_ptr = 0;
|
|
||||||
if (!vertex_program.empty()) {
|
|
||||||
vertex_program = shaders_header + vertex_header + vertex_program;
|
|
||||||
vertex_program_ptr = vertex_program.c_str();
|
|
||||||
}
|
|
||||||
if (!pixel_program.empty()) {
|
|
||||||
pixel_program = shaders_header + pixel_header + pixel_program;
|
|
||||||
pixel_program_ptr = pixel_program.c_str();
|
|
||||||
}
|
|
||||||
if (!geometry_program.empty()) {
|
|
||||||
geometry_program = shaders_header + geometry_program;
|
|
||||||
geometry_program_ptr = geometry_program.c_str();
|
|
||||||
}
|
|
||||||
ShaderCallback *cb = new ShaderCallback(setter_factories);
|
|
||||||
s32 shadermat = -1;
|
|
||||||
if(is_highlevel){
|
|
||||||
infostream<<"Compiling high level shaders for "<<name<<std::endl;
|
|
||||||
shadermat = gpu->addHighLevelShaderMaterial(
|
|
||||||
vertex_program_ptr, // Vertex shader program
|
|
||||||
"vertexMain", // Vertex shader entry point
|
|
||||||
video::EVST_VS_1_1, // Vertex shader version
|
|
||||||
pixel_program_ptr, // Pixel shader program
|
|
||||||
"pixelMain", // Pixel shader entry point
|
|
||||||
video::EPST_PS_1_2, // Pixel shader version
|
|
||||||
geometry_program_ptr, // Geometry shader program
|
|
||||||
"geometryMain", // Geometry shader entry point
|
|
||||||
video::EGST_GS_4_0, // Geometry shader version
|
|
||||||
scene::EPT_TRIANGLES, // Geometry shader input
|
|
||||||
scene::EPT_TRIANGLE_STRIP, // Geometry shader output
|
|
||||||
0, // Support maximum number of vertices
|
|
||||||
cb, // Set-constant callback
|
|
||||||
shaderinfo.base_material, // Base material
|
|
||||||
1 // Userdata passed to callback
|
|
||||||
);
|
|
||||||
if(shadermat == -1){
|
|
||||||
errorstream<<"generate_shader(): "
|
|
||||||
"failed to generate \""<<name<<"\", "
|
|
||||||
"addHighLevelShaderMaterial failed."
|
|
||||||
<<std::endl;
|
|
||||||
dumpShaderProgram(warningstream, "Vertex", vertex_program);
|
|
||||||
dumpShaderProgram(warningstream, "Pixel", pixel_program);
|
|
||||||
dumpShaderProgram(warningstream, "Geometry", geometry_program);
|
|
||||||
delete cb;
|
|
||||||
return shaderinfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
infostream<<"Compiling assembly shaders for "<<name<<std::endl;
|
|
||||||
shadermat = gpu->addShaderMaterial(
|
|
||||||
vertex_program_ptr, // Vertex shader program
|
|
||||||
pixel_program_ptr, // Pixel shader program
|
|
||||||
cb, // Set-constant callback
|
|
||||||
shaderinfo.base_material, // Base material
|
|
||||||
0 // Userdata passed to callback
|
|
||||||
);
|
|
||||||
|
|
||||||
if(shadermat == -1){
|
|
||||||
errorstream<<"generate_shader(): "
|
|
||||||
"failed to generate \""<<name<<"\", "
|
|
||||||
"addShaderMaterial failed."
|
|
||||||
<<std::endl;
|
|
||||||
dumpShaderProgram(warningstream, "Vertex", vertex_program);
|
|
||||||
dumpShaderProgram(warningstream,"Pixel", pixel_program);
|
|
||||||
delete cb;
|
|
||||||
return shaderinfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callbacks.push_back(cb);
|
|
||||||
|
|
||||||
// HACK, TODO: investigate this better
|
|
||||||
// Grab the material renderer once more so minetest doesn't crash on exit
|
|
||||||
driver->getMaterialRenderer(shadermat)->grab();
|
|
||||||
|
|
||||||
// Apply the newly created material type
|
// Apply the newly created material type
|
||||||
shaderinfo.material = (video::E_MATERIAL_TYPE) shadermat;
|
shaderinfo.material = (video::E_MATERIAL_TYPE) shadermat;
|
||||||
return shaderinfo;
|
return shaderinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_shaders(const std::string &name, SourceShaderCache *sourcecache,
|
|
||||||
video::E_DRIVER_TYPE drivertype, bool enable_shaders,
|
|
||||||
std::string &vertex_program, std::string &pixel_program,
|
|
||||||
std::string &geometry_program, bool &is_highlevel)
|
|
||||||
{
|
|
||||||
vertex_program = "";
|
|
||||||
pixel_program = "";
|
|
||||||
geometry_program = "";
|
|
||||||
is_highlevel = false;
|
|
||||||
|
|
||||||
if (!enable_shaders)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Look for high level shaders
|
|
||||||
switch (drivertype) {
|
|
||||||
case video::EDT_DIRECT3D9:
|
|
||||||
// Direct3D 9: HLSL
|
|
||||||
// (All shaders in one file)
|
|
||||||
vertex_program = sourcecache->getOrLoad(name, "d3d9.hlsl");
|
|
||||||
pixel_program = vertex_program;
|
|
||||||
geometry_program = vertex_program;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case video::EDT_OPENGL:
|
|
||||||
#if ENABLE_GLES
|
|
||||||
case video::EDT_OGLES2:
|
|
||||||
#endif
|
|
||||||
// OpenGL: GLSL
|
|
||||||
vertex_program = sourcecache->getOrLoad(name, "opengl_vertex.glsl");
|
|
||||||
pixel_program = sourcecache->getOrLoad(name, "opengl_fragment.glsl");
|
|
||||||
geometry_program = sourcecache->getOrLoad(name, "opengl_geometry.glsl");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// e.g. OpenGL ES 1 (with no shader support)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!vertex_program.empty() || !pixel_program.empty() || !geometry_program.empty()){
|
|
||||||
is_highlevel = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpShaderProgram(std::ostream &output_stream,
|
void dumpShaderProgram(std::ostream &output_stream,
|
||||||
const std::string &program_type, const std::string &program)
|
const std::string &program_type, const std::string &program)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <IMaterialRendererServices.h>
|
#include <IMaterialRendererServices.h>
|
||||||
#include "irrlichttypes_bloated.h"
|
#include "irrlichttypes_bloated.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "tile.h"
|
||||||
|
#include "nodedef.h"
|
||||||
|
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
|
|
||||||
@ -46,8 +48,8 @@ struct ShaderInfo {
|
|||||||
std::string name = "";
|
std::string name = "";
|
||||||
video::E_MATERIAL_TYPE base_material = video::EMT_SOLID;
|
video::E_MATERIAL_TYPE base_material = video::EMT_SOLID;
|
||||||
video::E_MATERIAL_TYPE material = video::EMT_SOLID;
|
video::E_MATERIAL_TYPE material = video::EMT_SOLID;
|
||||||
u8 drawtype = 0;
|
NodeDrawType drawtype = NDT_NORMAL;
|
||||||
u8 material_type = 0;
|
MaterialType material_type = TILE_MATERIAL_BASIC;
|
||||||
|
|
||||||
ShaderInfo() = default;
|
ShaderInfo() = default;
|
||||||
virtual ~ShaderInfo() = default;
|
virtual ~ShaderInfo() = default;
|
||||||
@ -65,8 +67,7 @@ namespace irr { namespace video {
|
|||||||
class IShaderConstantSetter {
|
class IShaderConstantSetter {
|
||||||
public:
|
public:
|
||||||
virtual ~IShaderConstantSetter() = default;
|
virtual ~IShaderConstantSetter() = default;
|
||||||
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
virtual void onSetConstants(video::IMaterialRendererServices *services) = 0;
|
||||||
bool is_highlevel) = 0;
|
|
||||||
virtual void onSetMaterial(const video::SMaterial& material)
|
virtual void onSetMaterial(const video::SMaterial& material)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@ -128,10 +129,10 @@ public:
|
|||||||
virtual ~IShaderSource() = default;
|
virtual ~IShaderSource() = default;
|
||||||
|
|
||||||
virtual u32 getShaderIdDirect(const std::string &name,
|
virtual u32 getShaderIdDirect(const std::string &name,
|
||||||
const u8 material_type, const u8 drawtype){return 0;}
|
MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;}
|
||||||
virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
|
virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
|
||||||
virtual u32 getShader(const std::string &name,
|
virtual u32 getShader(const std::string &name,
|
||||||
const u8 material_type, const u8 drawtype){return 0;}
|
MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWritableShaderSource : public IShaderSource {
|
class IWritableShaderSource : public IShaderSource {
|
||||||
@ -139,16 +140,12 @@ public:
|
|||||||
IWritableShaderSource() = default;
|
IWritableShaderSource() = default;
|
||||||
virtual ~IWritableShaderSource() = default;
|
virtual ~IWritableShaderSource() = default;
|
||||||
|
|
||||||
virtual u32 getShaderIdDirect(const std::string &name,
|
|
||||||
const u8 material_type, const u8 drawtype){return 0;}
|
|
||||||
virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
|
|
||||||
virtual u32 getShader(const std::string &name,
|
|
||||||
const u8 material_type, const u8 drawtype){return 0;}
|
|
||||||
|
|
||||||
virtual void processQueue()=0;
|
virtual void processQueue()=0;
|
||||||
virtual void insertSourceShader(const std::string &name_of_shader,
|
virtual void insertSourceShader(const std::string &name_of_shader,
|
||||||
const std::string &filename, const std::string &program)=0;
|
const std::string &filename, const std::string &program)=0;
|
||||||
virtual void rebuildShaders()=0;
|
virtual void rebuildShaders()=0;
|
||||||
|
|
||||||
|
/// @note Takes ownership of @p setter.
|
||||||
virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0;
|
virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc) :
|
|||||||
// Create materials
|
// Create materials
|
||||||
|
|
||||||
m_materials[0] = baseMaterial();
|
m_materials[0] = baseMaterial();
|
||||||
m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA, 0)).material;
|
m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA)).material;
|
||||||
m_materials[0].Lighting = true;
|
m_materials[0].Lighting = true;
|
||||||
m_materials[0].ColorMaterial = video::ECM_NONE;
|
m_materials[0].ColorMaterial = video::ECM_NONE;
|
||||||
|
|
||||||
|
@ -1633,6 +1633,13 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||||||
/* IMPORTANT: When changing this, getTextureForMesh() needs to be
|
/* IMPORTANT: When changing this, getTextureForMesh() needs to be
|
||||||
* updated too. */
|
* updated too. */
|
||||||
|
|
||||||
|
if (!baseimg) {
|
||||||
|
errorstream << "generateImagePart(): baseimg == NULL "
|
||||||
|
<< "for part_of_name=\"" << part_of_name
|
||||||
|
<< "\", cancelling." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the "clean transparent" filter, if configured.
|
// Apply the "clean transparent" filter, if configured.
|
||||||
if (g_settings->getBool("texture_clean_transparent"))
|
if (g_settings->getBool("texture_clean_transparent"))
|
||||||
imageCleanTransparent(baseimg, 127);
|
imageCleanTransparent(baseimg, 127);
|
||||||
|
@ -347,6 +347,7 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("joystick_type", "");
|
settings->setDefault("joystick_type", "");
|
||||||
settings->setDefault("repeat_joystick_button_time", "0.17");
|
settings->setDefault("repeat_joystick_button_time", "0.17");
|
||||||
settings->setDefault("joystick_frustum_sensitivity", "170");
|
settings->setDefault("joystick_frustum_sensitivity", "170");
|
||||||
|
settings->setDefault("joystick_deadzone", "2048");
|
||||||
|
|
||||||
// Main menu
|
// Main menu
|
||||||
settings->setDefault("main_menu_path", "");
|
settings->setDefault("main_menu_path", "");
|
||||||
@ -453,6 +454,8 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("chat_message_limit_per_10sec", "8.0");
|
settings->setDefault("chat_message_limit_per_10sec", "8.0");
|
||||||
settings->setDefault("chat_message_limit_trigger_kick", "50");
|
settings->setDefault("chat_message_limit_trigger_kick", "50");
|
||||||
settings->setDefault("sqlite_synchronous", "2");
|
settings->setDefault("sqlite_synchronous", "2");
|
||||||
|
settings->setDefault("map_compression_level_disk", "3");
|
||||||
|
settings->setDefault("map_compression_level_net", "-1");
|
||||||
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||||
settings->setDefault("dedicated_server_step", "0.09");
|
settings->setDefault("dedicated_server_step", "0.09");
|
||||||
settings->setDefault("active_block_mgmt_interval", "2.0");
|
settings->setDefault("active_block_mgmt_interval", "2.0");
|
||||||
@ -538,6 +541,8 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("fps_max_unfocused", "10");
|
settings->setDefault("fps_max_unfocused", "10");
|
||||||
settings->setDefault("max_objects_per_block", "20");
|
settings->setDefault("max_objects_per_block", "20");
|
||||||
settings->setDefault("sqlite_synchronous", "1");
|
settings->setDefault("sqlite_synchronous", "1");
|
||||||
|
settings->setDefault("map_compression_level_disk", "-1");
|
||||||
|
settings->setDefault("map_compression_level_net", "3");
|
||||||
settings->setDefault("server_map_save_interval", "15");
|
settings->setDefault("server_map_save_interval", "15");
|
||||||
settings->setDefault("client_mapblock_limit", "1000");
|
settings->setDefault("client_mapblock_limit", "1000");
|
||||||
settings->setDefault("active_block_range", "2");
|
settings->setDefault("active_block_range", "2");
|
||||||
|
@ -295,31 +295,26 @@ bool RecursiveDelete(const std::string &path)
|
|||||||
|
|
||||||
infostream<<"Removing \""<<path<<"\""<<std::endl;
|
infostream<<"Removing \""<<path<<"\""<<std::endl;
|
||||||
|
|
||||||
//return false;
|
|
||||||
|
|
||||||
pid_t child_pid = fork();
|
pid_t child_pid = fork();
|
||||||
|
|
||||||
if(child_pid == 0)
|
if(child_pid == 0)
|
||||||
{
|
{
|
||||||
// Child
|
// Child
|
||||||
char argv_data[3][10000];
|
const char *argv[4] = {
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
strcpy(argv_data[0], "/system/bin/rm");
|
"/system/bin/rm",
|
||||||
#else
|
#else
|
||||||
strcpy(argv_data[0], "/bin/rm");
|
"/bin/rm",
|
||||||
#endif
|
#endif
|
||||||
strcpy(argv_data[1], "-rf");
|
"-rf",
|
||||||
strncpy(argv_data[2], path.c_str(), sizeof(argv_data[2]) - 1);
|
path.c_str(),
|
||||||
char *argv[4];
|
NULL
|
||||||
argv[0] = argv_data[0];
|
};
|
||||||
argv[1] = argv_data[1];
|
|
||||||
argv[2] = argv_data[2];
|
|
||||||
argv[3] = NULL;
|
|
||||||
|
|
||||||
verbosestream<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '"
|
verbosestream<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '"
|
||||||
<<argv[2]<<"'"<<std::endl;
|
<<argv[2]<<"'"<<std::endl;
|
||||||
|
|
||||||
execv(argv[0], argv);
|
execv(argv[0], const_cast<char**>(argv));
|
||||||
|
|
||||||
// Execv shouldn't return. Failed.
|
// Execv shouldn't return. Failed.
|
||||||
_exit(1);
|
_exit(1);
|
||||||
@ -331,7 +326,6 @@ bool RecursiveDelete(const std::string &path)
|
|||||||
pid_t tpid;
|
pid_t tpid;
|
||||||
do{
|
do{
|
||||||
tpid = wait(&child_status);
|
tpid = wait(&child_status);
|
||||||
//if(tpid != child_pid) process_terminated(tpid);
|
|
||||||
}while(tpid != child_pid);
|
}while(tpid != child_pid);
|
||||||
return (child_status == 0);
|
return (child_status == 0);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ set(gui_SRCS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBox.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiFormSpecMenu.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiFormSpecMenu.cpp
|
||||||
|
95
src/gui/guiEditBox.cpp
Normal file
95
src/gui/guiEditBox.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2021 Minetest
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "guiEditBox.h"
|
||||||
|
|
||||||
|
#include "IGUISkin.h"
|
||||||
|
#include "IGUIEnvironment.h"
|
||||||
|
#include "IGUIFont.h"
|
||||||
|
|
||||||
|
GUIEditBox::~GUIEditBox()
|
||||||
|
{
|
||||||
|
if (m_override_font)
|
||||||
|
m_override_font->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GUIEditBox::setOverrideFont(IGUIFont *font)
|
||||||
|
{
|
||||||
|
if (m_override_font == font)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_override_font)
|
||||||
|
m_override_font->drop();
|
||||||
|
|
||||||
|
m_override_font = font;
|
||||||
|
|
||||||
|
if (m_override_font)
|
||||||
|
m_override_font->grab();
|
||||||
|
|
||||||
|
breakText();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the font which is used right now for drawing
|
||||||
|
IGUIFont *GUIEditBox::getActiveFont() const
|
||||||
|
{
|
||||||
|
if (m_override_font)
|
||||||
|
return m_override_font;
|
||||||
|
IGUISkin *skin = Environment->getSkin();
|
||||||
|
if (skin)
|
||||||
|
return skin->getFont();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Sets another color for the text.
|
||||||
|
void GUIEditBox::setOverrideColor(video::SColor color)
|
||||||
|
{
|
||||||
|
m_override_color = color;
|
||||||
|
m_override_color_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::SColor GUIEditBox::getOverrideColor() const
|
||||||
|
{
|
||||||
|
return m_override_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Sets if the text should use the overide color or the color in the gui skin.
|
||||||
|
void GUIEditBox::enableOverrideColor(bool enable)
|
||||||
|
{
|
||||||
|
m_override_color_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Enables or disables word wrap
|
||||||
|
void GUIEditBox::setWordWrap(bool enable)
|
||||||
|
{
|
||||||
|
m_word_wrap = enable;
|
||||||
|
breakText();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Enables or disables newlines.
|
||||||
|
void GUIEditBox::setMultiLine(bool enable)
|
||||||
|
{
|
||||||
|
m_multiline = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Enables or disables automatic scrolling with cursor position
|
||||||
|
//! \param enable: If set to true, the text will move around with the cursor position
|
||||||
|
void GUIEditBox::setAutoScroll(bool enable)
|
||||||
|
{
|
||||||
|
m_autoscroll = enable;
|
||||||
|
}
|
103
src/gui/guiEditBox.h
Normal file
103
src/gui/guiEditBox.h
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2021 Minetest
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IGUIEditBox.h"
|
||||||
|
#include "IOSOperator.h"
|
||||||
|
#include "guiScrollBar.h"
|
||||||
|
|
||||||
|
using namespace irr;
|
||||||
|
using namespace irr::gui;
|
||||||
|
|
||||||
|
class GUIEditBox : public IGUIEditBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GUIEditBox(IGUIEnvironment *environment, IGUIElement *parent, s32 id,
|
||||||
|
core::rect<s32> rectangle) :
|
||||||
|
IGUIEditBox(environment, parent, id, rectangle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~GUIEditBox();
|
||||||
|
|
||||||
|
//! Sets another skin independent font.
|
||||||
|
virtual void setOverrideFont(IGUIFont *font = 0);
|
||||||
|
|
||||||
|
virtual IGUIFont *getOverrideFont() const { return m_override_font; }
|
||||||
|
|
||||||
|
//! Get the font which is used right now for drawing
|
||||||
|
/** Currently this is the override font when one is set and the
|
||||||
|
font of the active skin otherwise */
|
||||||
|
virtual IGUIFont *getActiveFont() const;
|
||||||
|
|
||||||
|
//! Sets another color for the text.
|
||||||
|
virtual void setOverrideColor(video::SColor color);
|
||||||
|
|
||||||
|
//! Gets the override color
|
||||||
|
virtual video::SColor getOverrideColor() const;
|
||||||
|
|
||||||
|
//! Sets if the text should use the overide color or the
|
||||||
|
//! color in the gui skin.
|
||||||
|
virtual void enableOverrideColor(bool enable);
|
||||||
|
|
||||||
|
//! Checks if an override color is enabled
|
||||||
|
/** \return true if the override color is enabled, false otherwise */
|
||||||
|
virtual bool isOverrideColorEnabled(void) const
|
||||||
|
{
|
||||||
|
return m_override_color_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Enables or disables word wrap for using the edit box as multiline text editor.
|
||||||
|
virtual void setWordWrap(bool enable);
|
||||||
|
|
||||||
|
//! Checks if word wrap is enabled
|
||||||
|
//! \return true if word wrap is enabled, false otherwise
|
||||||
|
virtual bool isWordWrapEnabled() const { return m_word_wrap; }
|
||||||
|
|
||||||
|
//! Enables or disables newlines.
|
||||||
|
/** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired,
|
||||||
|
instead a newline character will be inserted. */
|
||||||
|
virtual void setMultiLine(bool enable);
|
||||||
|
|
||||||
|
//! Checks if multi line editing is enabled
|
||||||
|
//! \return true if mult-line is enabled, false otherwise
|
||||||
|
virtual bool isMultiLineEnabled() const { return m_multiline; }
|
||||||
|
|
||||||
|
//! Enables or disables automatic scrolling with cursor position
|
||||||
|
//! \param enable: If set to true, the text will move around with the cursor
|
||||||
|
//! position
|
||||||
|
virtual void setAutoScroll(bool enable);
|
||||||
|
|
||||||
|
//! Checks to see if automatic scrolling is enabled
|
||||||
|
//! \return true if automatic scrolling is enabled, false if not
|
||||||
|
virtual bool isAutoScrollEnabled() const { return m_autoscroll; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void breakText() = 0;
|
||||||
|
|
||||||
|
gui::IGUIFont *m_override_font = nullptr;
|
||||||
|
|
||||||
|
bool m_override_color_enabled = false;
|
||||||
|
bool m_word_wrap = false;
|
||||||
|
bool m_multiline = false;
|
||||||
|
bool m_autoscroll = true;
|
||||||
|
|
||||||
|
video::SColor m_override_color = video::SColor(101, 255, 255, 255);
|
||||||
|
};
|
@ -22,16 +22,14 @@ optional? dragging selected text
|
|||||||
numerical
|
numerical
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool border,
|
GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool border,
|
||||||
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
||||||
const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar)
|
const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar)
|
||||||
: IGUIEditBox(environment, parent, id, rectangle), m_mouse_marking(false),
|
: GUIEditBox(environment, parent, id, rectangle), m_mouse_marking(false),
|
||||||
m_border(border), m_background(true), m_override_color_enabled(false), m_mark_begin(0), m_mark_end(0),
|
m_border(border), m_background(true), m_mark_begin(0), m_mark_end(0), m_last_break_font(0),
|
||||||
m_override_color(video::SColor(101, 255, 255, 255)), m_override_font(0), m_last_break_font(0),
|
|
||||||
m_operator(0), m_blink_start_time(0), m_cursor_pos(0), m_hscroll_pos(0), m_vscroll_pos(0), m_max(0),
|
m_operator(0), m_blink_start_time(0), m_cursor_pos(0), m_hscroll_pos(0), m_vscroll_pos(0), m_max(0),
|
||||||
m_word_wrap(false), m_multiline(false), m_autoscroll(true), m_passwordbox(false),
|
m_passwordbox(false),
|
||||||
m_passwordchar(L'*'), m_halign(EGUIA_UPPERLEFT), m_valign(EGUIA_CENTER),
|
m_passwordchar(L'*'), m_halign(EGUIA_UPPERLEFT), m_valign(EGUIA_CENTER),
|
||||||
m_current_text_rect(0, 0, 1, 1), m_frame_rect(rectangle),
|
m_current_text_rect(0, 0, 1, 1), m_frame_rect(rectangle),
|
||||||
m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable),
|
m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable),
|
||||||
@ -69,9 +67,6 @@ GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool borde
|
|||||||
//! destructor
|
//! destructor
|
||||||
GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar()
|
GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar()
|
||||||
{
|
{
|
||||||
if (m_override_font)
|
|
||||||
m_override_font->drop();
|
|
||||||
|
|
||||||
if (m_operator)
|
if (m_operator)
|
||||||
m_operator->drop();
|
m_operator->drop();
|
||||||
|
|
||||||
@ -80,54 +75,6 @@ GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Sets another skin independent font.
|
|
||||||
void GUIEditBoxWithScrollBar::setOverrideFont(IGUIFont* font)
|
|
||||||
{
|
|
||||||
if (m_override_font == font)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_override_font)
|
|
||||||
m_override_font->drop();
|
|
||||||
|
|
||||||
m_override_font = font;
|
|
||||||
|
|
||||||
if (m_override_font)
|
|
||||||
m_override_font->grab();
|
|
||||||
|
|
||||||
breakText();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Gets the override font (if any)
|
|
||||||
IGUIFont * GUIEditBoxWithScrollBar::getOverrideFont() const
|
|
||||||
{
|
|
||||||
return m_override_font;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the font which is used right now for drawing
|
|
||||||
IGUIFont* GUIEditBoxWithScrollBar::getActiveFont() const
|
|
||||||
{
|
|
||||||
if (m_override_font)
|
|
||||||
return m_override_font;
|
|
||||||
IGUISkin* skin = Environment->getSkin();
|
|
||||||
if (skin)
|
|
||||||
return skin->getFont();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Sets another color for the text.
|
|
||||||
void GUIEditBoxWithScrollBar::setOverrideColor(video::SColor color)
|
|
||||||
{
|
|
||||||
m_override_color = color;
|
|
||||||
m_override_color_enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
video::SColor GUIEditBoxWithScrollBar::getOverrideColor() const
|
|
||||||
{
|
|
||||||
return m_override_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Turns the border on or off
|
//! Turns the border on or off
|
||||||
void GUIEditBoxWithScrollBar::setDrawBorder(bool border)
|
void GUIEditBoxWithScrollBar::setDrawBorder(bool border)
|
||||||
{
|
{
|
||||||
@ -140,24 +87,6 @@ void GUIEditBoxWithScrollBar::setDrawBackground(bool draw)
|
|||||||
m_background = draw;
|
m_background = draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets if the text should use the overide color or the color in the gui skin.
|
|
||||||
void GUIEditBoxWithScrollBar::enableOverrideColor(bool enable)
|
|
||||||
{
|
|
||||||
m_override_color_enabled = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GUIEditBoxWithScrollBar::isOverrideColorEnabled() const
|
|
||||||
{
|
|
||||||
return m_override_color_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Enables or disables word wrap
|
|
||||||
void GUIEditBoxWithScrollBar::setWordWrap(bool enable)
|
|
||||||
{
|
|
||||||
m_word_wrap = enable;
|
|
||||||
breakText();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GUIEditBoxWithScrollBar::updateAbsolutePosition()
|
void GUIEditBoxWithScrollBar::updateAbsolutePosition()
|
||||||
{
|
{
|
||||||
@ -170,26 +99,6 @@ void GUIEditBoxWithScrollBar::updateAbsolutePosition()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Checks if word wrap is enabled
|
|
||||||
bool GUIEditBoxWithScrollBar::isWordWrapEnabled() const
|
|
||||||
{
|
|
||||||
return m_word_wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Enables or disables newlines.
|
|
||||||
void GUIEditBoxWithScrollBar::setMultiLine(bool enable)
|
|
||||||
{
|
|
||||||
m_multiline = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Checks if multi line editing is enabled
|
|
||||||
bool GUIEditBoxWithScrollBar::isMultiLineEnabled() const
|
|
||||||
{
|
|
||||||
return m_multiline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GUIEditBoxWithScrollBar::setPasswordBox(bool password_box, wchar_t password_char)
|
void GUIEditBoxWithScrollBar::setPasswordBox(bool password_box, wchar_t password_char)
|
||||||
{
|
{
|
||||||
@ -850,22 +759,6 @@ void GUIEditBoxWithScrollBar::setText(const wchar_t* text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Enables or disables automatic scrolling with cursor position
|
|
||||||
//! \param enable: If set to true, the text will move around with the cursor position
|
|
||||||
void GUIEditBoxWithScrollBar::setAutoScroll(bool enable)
|
|
||||||
{
|
|
||||||
m_autoscroll = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Checks to see if automatic scrolling is enabled
|
|
||||||
//! \return true if automatic scrolling is enabled, false if not
|
|
||||||
bool GUIEditBoxWithScrollBar::isAutoScrollEnabled() const
|
|
||||||
{
|
|
||||||
return m_autoscroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Gets the area of the text in the edit box
|
//! Gets the area of the text in the edit box
|
||||||
//! \return Returns the size in pixels of the text
|
//! \return Returns the size in pixels of the text
|
||||||
core::dimension2du GUIEditBoxWithScrollBar::getTextDimension()
|
core::dimension2du GUIEditBoxWithScrollBar::getTextDimension()
|
||||||
|
@ -5,15 +5,10 @@
|
|||||||
#ifndef GUIEDITBOXWITHSCROLLBAR_HEADER
|
#ifndef GUIEDITBOXWITHSCROLLBAR_HEADER
|
||||||
#define GUIEDITBOXWITHSCROLLBAR_HEADER
|
#define GUIEDITBOXWITHSCROLLBAR_HEADER
|
||||||
|
|
||||||
#include "IGUIEditBox.h"
|
#include "guiEditBox.h"
|
||||||
#include "IOSOperator.h"
|
|
||||||
#include "guiScrollBar.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace irr;
|
class GUIEditBoxWithScrollBar : public GUIEditBox
|
||||||
using namespace irr::gui;
|
|
||||||
|
|
||||||
class GUIEditBoxWithScrollBar : public IGUIEditBox
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -25,61 +20,13 @@ public:
|
|||||||
//! destructor
|
//! destructor
|
||||||
virtual ~GUIEditBoxWithScrollBar();
|
virtual ~GUIEditBoxWithScrollBar();
|
||||||
|
|
||||||
//! Sets another skin independent font.
|
|
||||||
virtual void setOverrideFont(IGUIFont* font = 0);
|
|
||||||
|
|
||||||
//! Gets the override font (if any)
|
|
||||||
/** \return The override font (may be 0) */
|
|
||||||
virtual IGUIFont* getOverrideFont() const;
|
|
||||||
|
|
||||||
//! Get the font which is used right now for drawing
|
|
||||||
/** Currently this is the override font when one is set and the
|
|
||||||
font of the active skin otherwise */
|
|
||||||
virtual IGUIFont* getActiveFont() const;
|
|
||||||
|
|
||||||
//! Sets another color for the text.
|
|
||||||
virtual void setOverrideColor(video::SColor color);
|
|
||||||
|
|
||||||
//! Gets the override color
|
|
||||||
virtual video::SColor getOverrideColor() const;
|
|
||||||
|
|
||||||
//! Sets if the text should use the overide color or the
|
|
||||||
//! color in the gui skin.
|
|
||||||
virtual void enableOverrideColor(bool enable);
|
|
||||||
|
|
||||||
//! Checks if an override color is enabled
|
|
||||||
/** \return true if the override color is enabled, false otherwise */
|
|
||||||
virtual bool isOverrideColorEnabled(void) const;
|
|
||||||
|
|
||||||
//! Sets whether to draw the background
|
//! Sets whether to draw the background
|
||||||
virtual void setDrawBackground(bool draw);
|
virtual void setDrawBackground(bool draw);
|
||||||
|
|
||||||
//! Turns the border on or off
|
//! Turns the border on or off
|
||||||
virtual void setDrawBorder(bool border);
|
virtual void setDrawBorder(bool border);
|
||||||
|
|
||||||
//! Enables or disables word wrap for using the edit box as multiline text editor.
|
|
||||||
virtual void setWordWrap(bool enable);
|
|
||||||
|
|
||||||
//! Checks if word wrap is enabled
|
|
||||||
//! \return true if word wrap is enabled, false otherwise
|
|
||||||
virtual bool isWordWrapEnabled() const;
|
|
||||||
|
|
||||||
//! Enables or disables newlines.
|
|
||||||
/** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired,
|
|
||||||
instead a newline character will be inserted. */
|
|
||||||
virtual void setMultiLine(bool enable);
|
|
||||||
|
|
||||||
//! Checks if multi line editing is enabled
|
|
||||||
//! \return true if mult-line is enabled, false otherwise
|
|
||||||
virtual bool isMultiLineEnabled() const;
|
|
||||||
|
|
||||||
//! Enables or disables automatic scrolling with cursor position
|
|
||||||
//! \param enable: If set to true, the text will move around with the cursor position
|
|
||||||
virtual void setAutoScroll(bool enable);
|
|
||||||
|
|
||||||
//! Checks to see if automatic scrolling is enabled
|
|
||||||
//! \return true if automatic scrolling is enabled, false if not
|
|
||||||
virtual bool isAutoScrollEnabled() const;
|
|
||||||
|
|
||||||
//! Gets the size area of the text in the edit box
|
//! Gets the size area of the text in the edit box
|
||||||
//! \return Returns the size in pixels of the text
|
//! \return Returns the size in pixels of the text
|
||||||
@ -137,7 +84,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Breaks the single text line.
|
//! Breaks the single text line.
|
||||||
void breakText();
|
virtual void breakText();
|
||||||
//! sets the area of the given line
|
//! sets the area of the given line
|
||||||
void setTextRect(s32 line);
|
void setTextRect(s32 line);
|
||||||
//! returns the line number that the cursor is on
|
//! returns the line number that the cursor is on
|
||||||
@ -164,12 +111,11 @@ protected:
|
|||||||
bool m_mouse_marking;
|
bool m_mouse_marking;
|
||||||
bool m_border;
|
bool m_border;
|
||||||
bool m_background;
|
bool m_background;
|
||||||
bool m_override_color_enabled;
|
|
||||||
s32 m_mark_begin;
|
s32 m_mark_begin;
|
||||||
s32 m_mark_end;
|
s32 m_mark_end;
|
||||||
|
|
||||||
video::SColor m_override_color;
|
gui::IGUIFont *m_last_break_font;
|
||||||
gui::IGUIFont *m_override_font, *m_last_break_font;
|
|
||||||
IOSOperator* m_operator;
|
IOSOperator* m_operator;
|
||||||
|
|
||||||
u32 m_blink_start_time;
|
u32 m_blink_start_time;
|
||||||
@ -177,7 +123,7 @@ protected:
|
|||||||
s32 m_hscroll_pos, m_vscroll_pos; // scroll position in characters
|
s32 m_hscroll_pos, m_vscroll_pos; // scroll position in characters
|
||||||
u32 m_max;
|
u32 m_max;
|
||||||
|
|
||||||
bool m_word_wrap, m_multiline, m_autoscroll, m_passwordbox;
|
bool m_passwordbox;
|
||||||
wchar_t m_passwordchar;
|
wchar_t m_passwordchar;
|
||||||
EGUI_ALIGNMENT m_halign, m_valign;
|
EGUI_ALIGNMENT m_halign, m_valign;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#define MY_CHECKPOS(a,b) \
|
#define MY_CHECKPOS(a,b) \
|
||||||
if (v_pos.size() != 2) { \
|
if (v_pos.size() != 2) { \
|
||||||
errorstream<< "Invalid pos for element " << a << "specified: \"" \
|
errorstream<< "Invalid pos for element " << a << " specified: \"" \
|
||||||
<< parts[b] << "\"" << std::endl; \
|
<< parts[b] << "\"" << std::endl; \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MY_CHECKGEOM(a,b) \
|
#define MY_CHECKGEOM(a,b) \
|
||||||
if (v_geom.size() != 2) { \
|
if (v_geom.size() != 2) { \
|
||||||
errorstream<< "Invalid geometry for element " << a << \
|
errorstream<< "Invalid geometry for element " << a << \
|
||||||
"specified: \"" << parts[b] << "\"" << std::endl; \
|
" specified: \"" << parts[b] << "\"" << std::endl; \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -2725,7 +2725,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
|
|||||||
{
|
{
|
||||||
std::vector<std::string> parts = split(element, ';');
|
std::vector<std::string> parts = split(element, ';');
|
||||||
|
|
||||||
if (parts.size() < 5 || (parts.size() > 8 &&
|
if (parts.size() < 5 || (parts.size() > 9 &&
|
||||||
m_formspec_version <= FORMSPEC_API_VERSION)) {
|
m_formspec_version <= FORMSPEC_API_VERSION)) {
|
||||||
errorstream << "Invalid model element (" << parts.size() << "): '" << element
|
errorstream << "Invalid model element (" << parts.size() << "): '" << element
|
||||||
<< "'" << std::endl;
|
<< "'" << std::endl;
|
||||||
@ -2733,8 +2733,8 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid length checks by resizing
|
// Avoid length checks by resizing
|
||||||
if (parts.size() < 8)
|
if (parts.size() < 9)
|
||||||
parts.resize(8);
|
parts.resize(9);
|
||||||
|
|
||||||
std::vector<std::string> v_pos = split(parts[0], ',');
|
std::vector<std::string> v_pos = split(parts[0], ',');
|
||||||
std::vector<std::string> v_geom = split(parts[1], ',');
|
std::vector<std::string> v_geom = split(parts[1], ',');
|
||||||
@ -2744,6 +2744,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
|
|||||||
std::vector<std::string> vec_rot = split(parts[5], ',');
|
std::vector<std::string> vec_rot = split(parts[5], ',');
|
||||||
bool inf_rotation = is_yes(parts[6]);
|
bool inf_rotation = is_yes(parts[6]);
|
||||||
bool mousectrl = is_yes(parts[7]) || parts[7].empty(); // default true
|
bool mousectrl = is_yes(parts[7]) || parts[7].empty(); // default true
|
||||||
|
std::vector<std::string> frame_loop = split(parts[8], ',');
|
||||||
|
|
||||||
MY_CHECKPOS("model", 0);
|
MY_CHECKPOS("model", 0);
|
||||||
MY_CHECKGEOM("model", 1);
|
MY_CHECKGEOM("model", 1);
|
||||||
@ -2786,7 +2787,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
|
|||||||
auto meshnode = e->setMesh(mesh);
|
auto meshnode = e->setMesh(mesh);
|
||||||
|
|
||||||
for (u32 i = 0; i < textures.size() && i < meshnode->getMaterialCount(); ++i)
|
for (u32 i = 0; i < textures.size() && i < meshnode->getMaterialCount(); ++i)
|
||||||
e->setTexture(i, m_tsrc->getTexture(textures[i]));
|
e->setTexture(i, m_tsrc->getTexture(unescape_string(textures[i])));
|
||||||
|
|
||||||
if (vec_rot.size() >= 2)
|
if (vec_rot.size() >= 2)
|
||||||
e->setRotation(v2f(stof(vec_rot[0]), stof(vec_rot[1])));
|
e->setRotation(v2f(stof(vec_rot[0]), stof(vec_rot[1])));
|
||||||
@ -2794,6 +2795,16 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
|
|||||||
e->enableContinuousRotation(inf_rotation);
|
e->enableContinuousRotation(inf_rotation);
|
||||||
e->enableMouseControl(mousectrl);
|
e->enableMouseControl(mousectrl);
|
||||||
|
|
||||||
|
s32 frame_loop_begin = 0;
|
||||||
|
s32 frame_loop_end = 0x7FFFFFFF;
|
||||||
|
|
||||||
|
if (frame_loop.size() == 2) {
|
||||||
|
frame_loop_begin = stoi(frame_loop[0]);
|
||||||
|
frame_loop_end = stoi(frame_loop[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
e->setFrameLoop(frame_loop_begin, frame_loop_end);
|
||||||
|
|
||||||
auto style = getStyleForElement("model", spec.fname);
|
auto style = getStyleForElement("model", spec.fname);
|
||||||
e->setStyles(style);
|
e->setStyles(style);
|
||||||
e->drop();
|
e->drop();
|
||||||
@ -3707,7 +3718,8 @@ void GUIFormSpecMenu::showTooltip(const std::wstring &text,
|
|||||||
{
|
{
|
||||||
EnrichedString ntext(text);
|
EnrichedString ntext(text);
|
||||||
ntext.setDefaultColor(color);
|
ntext.setDefaultColor(color);
|
||||||
ntext.setBackground(bgcolor);
|
if (!ntext.hasBackground())
|
||||||
|
ntext.setBackground(bgcolor);
|
||||||
|
|
||||||
setStaticText(m_tooltip_element, ntext);
|
setStaticText(m_tooltip_element, ntext);
|
||||||
|
|
||||||
|
@ -152,6 +152,15 @@ void GUIScene::setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES> &sty
|
|||||||
setBackgroundColor(style.getColor(StyleSpec::BGCOLOR, m_bgcolor));
|
setBackgroundColor(style.getColor(StyleSpec::BGCOLOR, m_bgcolor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the frame loop range for the mesh
|
||||||
|
*/
|
||||||
|
void GUIScene::setFrameLoop(s32 begin, s32 end)
|
||||||
|
{
|
||||||
|
if (m_mesh->getStartFrame() != begin || m_mesh->getEndFrame() != end)
|
||||||
|
m_mesh->setFrameLoop(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
/* Camera control functions */
|
/* Camera control functions */
|
||||||
|
|
||||||
inline void GUIScene::calcOptimalDistance()
|
inline void GUIScene::calcOptimalDistance()
|
||||||
|
@ -36,6 +36,7 @@ public:
|
|||||||
scene::IAnimatedMeshSceneNode *setMesh(scene::IAnimatedMesh *mesh = nullptr);
|
scene::IAnimatedMeshSceneNode *setMesh(scene::IAnimatedMesh *mesh = nullptr);
|
||||||
void setTexture(u32 idx, video::ITexture *texture);
|
void setTexture(u32 idx, video::ITexture *texture);
|
||||||
void setBackgroundColor(const video::SColor &color) noexcept { m_bgcolor = color; };
|
void setBackgroundColor(const video::SColor &color) noexcept { m_bgcolor = color; };
|
||||||
|
void setFrameLoop(s32 begin, s32 end);
|
||||||
void enableMouseControl(bool enable) noexcept { m_mouse_ctrl = enable; };
|
void enableMouseControl(bool enable) noexcept { m_mouse_ctrl = enable; };
|
||||||
void setRotation(v2f rot) noexcept { m_custom_rot = rot; };
|
void setRotation(v2f rot) noexcept { m_custom_rot = rot; };
|
||||||
void enableContinuousRotation(bool enable) noexcept { m_inf_rot = enable; };
|
void enableContinuousRotation(bool enable) noexcept { m_inf_rot = enable; };
|
||||||
|
@ -59,7 +59,7 @@ namespace gui
|
|||||||
intlGUIEditBox::intlGUIEditBox(const wchar_t* text, bool border,
|
intlGUIEditBox::intlGUIEditBox(const wchar_t* text, bool border,
|
||||||
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
|
||||||
const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar)
|
const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar)
|
||||||
: IGUIEditBox(environment, parent, id, rectangle),
|
: GUIEditBox(environment, parent, id, rectangle),
|
||||||
Border(border), FrameRect(rectangle),
|
Border(border), FrameRect(rectangle),
|
||||||
m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable)
|
m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable)
|
||||||
{
|
{
|
||||||
@ -108,9 +108,6 @@ intlGUIEditBox::intlGUIEditBox(const wchar_t* text, bool border,
|
|||||||
//! destructor
|
//! destructor
|
||||||
intlGUIEditBox::~intlGUIEditBox()
|
intlGUIEditBox::~intlGUIEditBox()
|
||||||
{
|
{
|
||||||
if (OverrideFont)
|
|
||||||
OverrideFont->drop();
|
|
||||||
|
|
||||||
if (Operator)
|
if (Operator)
|
||||||
Operator->drop();
|
Operator->drop();
|
||||||
|
|
||||||
@ -118,52 +115,6 @@ intlGUIEditBox::~intlGUIEditBox()
|
|||||||
m_vscrollbar->drop();
|
m_vscrollbar->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Sets another skin independent font.
|
|
||||||
void intlGUIEditBox::setOverrideFont(IGUIFont* font)
|
|
||||||
{
|
|
||||||
if (OverrideFont == font)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (OverrideFont)
|
|
||||||
OverrideFont->drop();
|
|
||||||
|
|
||||||
OverrideFont = font;
|
|
||||||
|
|
||||||
if (OverrideFont)
|
|
||||||
OverrideFont->grab();
|
|
||||||
|
|
||||||
breakText();
|
|
||||||
}
|
|
||||||
|
|
||||||
IGUIFont * intlGUIEditBox::getOverrideFont() const
|
|
||||||
{
|
|
||||||
return OverrideFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the font which is used right now for drawing
|
|
||||||
IGUIFont* intlGUIEditBox::getActiveFont() const
|
|
||||||
{
|
|
||||||
if ( OverrideFont )
|
|
||||||
return OverrideFont;
|
|
||||||
IGUISkin* skin = Environment->getSkin();
|
|
||||||
if (skin)
|
|
||||||
return skin->getFont();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Sets another color for the text.
|
|
||||||
void intlGUIEditBox::setOverrideColor(video::SColor color)
|
|
||||||
{
|
|
||||||
OverrideColor = color;
|
|
||||||
OverrideColorEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
video::SColor intlGUIEditBox::getOverrideColor() const
|
|
||||||
{
|
|
||||||
return OverrideColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Turns the border on or off
|
//! Turns the border on or off
|
||||||
void intlGUIEditBox::setDrawBorder(bool border)
|
void intlGUIEditBox::setDrawBorder(bool border)
|
||||||
{
|
{
|
||||||
@ -175,25 +126,6 @@ void intlGUIEditBox::setDrawBackground(bool draw)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets if the text should use the overide color or the color in the gui skin.
|
|
||||||
void intlGUIEditBox::enableOverrideColor(bool enable)
|
|
||||||
{
|
|
||||||
OverrideColorEnabled = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool intlGUIEditBox::isOverrideColorEnabled() const
|
|
||||||
{
|
|
||||||
return OverrideColorEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Enables or disables word wrap
|
|
||||||
void intlGUIEditBox::setWordWrap(bool enable)
|
|
||||||
{
|
|
||||||
WordWrap = enable;
|
|
||||||
breakText();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intlGUIEditBox::updateAbsolutePosition()
|
void intlGUIEditBox::updateAbsolutePosition()
|
||||||
{
|
{
|
||||||
core::rect<s32> oldAbsoluteRect(AbsoluteRect);
|
core::rect<s32> oldAbsoluteRect(AbsoluteRect);
|
||||||
@ -204,28 +136,6 @@ void intlGUIEditBox::updateAbsolutePosition()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Checks if word wrap is enabled
|
|
||||||
bool intlGUIEditBox::isWordWrapEnabled() const
|
|
||||||
{
|
|
||||||
return WordWrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Enables or disables newlines.
|
|
||||||
void intlGUIEditBox::setMultiLine(bool enable)
|
|
||||||
{
|
|
||||||
MultiLine = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Checks if multi line editing is enabled
|
|
||||||
bool intlGUIEditBox::isMultiLineEnabled() const
|
|
||||||
{
|
|
||||||
return MultiLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intlGUIEditBox::setPasswordBox(bool passwordBox, wchar_t passwordChar)
|
void intlGUIEditBox::setPasswordBox(bool passwordBox, wchar_t passwordChar)
|
||||||
{
|
{
|
||||||
PasswordBox = passwordBox;
|
PasswordBox = passwordBox;
|
||||||
@ -464,7 +374,7 @@ bool intlGUIEditBox::processKey(const SEvent& event)
|
|||||||
case KEY_END:
|
case KEY_END:
|
||||||
{
|
{
|
||||||
s32 p = Text.size();
|
s32 p = Text.size();
|
||||||
if (WordWrap || MultiLine)
|
if (m_word_wrap || m_multiline)
|
||||||
{
|
{
|
||||||
p = getLineFromPos(CursorPos);
|
p = getLineFromPos(CursorPos);
|
||||||
p = BrokenTextPositions[p] + (s32)BrokenText[p].size();
|
p = BrokenTextPositions[p] + (s32)BrokenText[p].size();
|
||||||
@ -492,7 +402,7 @@ bool intlGUIEditBox::processKey(const SEvent& event)
|
|||||||
{
|
{
|
||||||
|
|
||||||
s32 p = 0;
|
s32 p = 0;
|
||||||
if (WordWrap || MultiLine)
|
if (m_word_wrap || m_multiline)
|
||||||
{
|
{
|
||||||
p = getLineFromPos(CursorPos);
|
p = getLineFromPos(CursorPos);
|
||||||
p = BrokenTextPositions[p];
|
p = BrokenTextPositions[p];
|
||||||
@ -514,7 +424,7 @@ bool intlGUIEditBox::processKey(const SEvent& event)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEY_RETURN:
|
case KEY_RETURN:
|
||||||
if (MultiLine)
|
if (m_multiline)
|
||||||
{
|
{
|
||||||
inputChar(L'\n');
|
inputChar(L'\n');
|
||||||
return true;
|
return true;
|
||||||
@ -567,7 +477,7 @@ bool intlGUIEditBox::processKey(const SEvent& event)
|
|||||||
BlinkStartTime = porting::getTimeMs();
|
BlinkStartTime = porting::getTimeMs();
|
||||||
break;
|
break;
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
if (MultiLine || (WordWrap && BrokenText.size() > 1) )
|
if (m_multiline || (m_word_wrap && BrokenText.size() > 1) )
|
||||||
{
|
{
|
||||||
s32 lineNo = getLineFromPos(CursorPos);
|
s32 lineNo = getLineFromPos(CursorPos);
|
||||||
s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd);
|
s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd);
|
||||||
@ -598,7 +508,7 @@ bool intlGUIEditBox::processKey(const SEvent& event)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
if (MultiLine || (WordWrap && BrokenText.size() > 1) )
|
if (m_multiline || (m_word_wrap && BrokenText.size() > 1) )
|
||||||
{
|
{
|
||||||
s32 lineNo = getLineFromPos(CursorPos);
|
s32 lineNo = getLineFromPos(CursorPos);
|
||||||
s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd);
|
s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd);
|
||||||
@ -791,8 +701,8 @@ void intlGUIEditBox::draw()
|
|||||||
|
|
||||||
// draw the text
|
// draw the text
|
||||||
|
|
||||||
IGUIFont* font = OverrideFont;
|
IGUIFont* font = m_override_font;
|
||||||
if (!OverrideFont)
|
if (!m_override_font)
|
||||||
font = skin->getFont();
|
font = skin->getFont();
|
||||||
|
|
||||||
s32 cursorLine = 0;
|
s32 cursorLine = 0;
|
||||||
@ -813,7 +723,7 @@ void intlGUIEditBox::draw()
|
|||||||
core::stringw s, s2;
|
core::stringw s, s2;
|
||||||
|
|
||||||
// get mark position
|
// get mark position
|
||||||
const bool ml = (!PasswordBox && (WordWrap || MultiLine));
|
const bool ml = (!PasswordBox && (m_word_wrap || m_multiline));
|
||||||
const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
|
const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
|
||||||
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
|
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
|
||||||
const s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0;
|
const s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0;
|
||||||
@ -822,14 +732,14 @@ void intlGUIEditBox::draw()
|
|||||||
|
|
||||||
// Save the override color information.
|
// Save the override color information.
|
||||||
// Then, alter it if the edit box is disabled.
|
// Then, alter it if the edit box is disabled.
|
||||||
const bool prevOver = OverrideColorEnabled;
|
const bool prevOver = m_override_color_enabled;
|
||||||
const video::SColor prevColor = OverrideColor;
|
const video::SColor prevColor = m_override_color;
|
||||||
|
|
||||||
if (!Text.empty()) {
|
if (!Text.empty()) {
|
||||||
if (!IsEnabled && !OverrideColorEnabled)
|
if (!IsEnabled && !m_override_color_enabled)
|
||||||
{
|
{
|
||||||
OverrideColorEnabled = true;
|
m_override_color_enabled = true;
|
||||||
OverrideColor = skin->getColor(EGDC_GRAY_TEXT);
|
m_override_color = skin->getColor(EGDC_GRAY_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s32 i=0; i < lineCount; ++i)
|
for (s32 i=0; i < lineCount; ++i)
|
||||||
@ -870,7 +780,7 @@ void intlGUIEditBox::draw()
|
|||||||
|
|
||||||
// draw normal text
|
// draw normal text
|
||||||
font->draw(txtLine->c_str(), CurrentTextRect,
|
font->draw(txtLine->c_str(), CurrentTextRect,
|
||||||
OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT),
|
m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT),
|
||||||
false, true, &localClipRect);
|
false, true, &localClipRect);
|
||||||
|
|
||||||
// draw mark and marked text
|
// draw mark and marked text
|
||||||
@ -914,20 +824,20 @@ void intlGUIEditBox::draw()
|
|||||||
|
|
||||||
if (!s.empty())
|
if (!s.empty())
|
||||||
font->draw(s.c_str(), CurrentTextRect,
|
font->draw(s.c_str(), CurrentTextRect,
|
||||||
OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_HIGH_LIGHT_TEXT),
|
m_override_color_enabled ? m_override_color : skin->getColor(EGDC_HIGH_LIGHT_TEXT),
|
||||||
false, true, &localClipRect);
|
false, true, &localClipRect);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the override color information to its previous settings.
|
// Return the override color information to its previous settings.
|
||||||
OverrideColorEnabled = prevOver;
|
m_override_color_enabled = prevOver;
|
||||||
OverrideColor = prevColor;
|
m_override_color = prevColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw cursor
|
// draw cursor
|
||||||
|
|
||||||
if (WordWrap || MultiLine)
|
if (m_word_wrap || m_multiline)
|
||||||
{
|
{
|
||||||
cursorLine = getLineFromPos(CursorPos);
|
cursorLine = getLineFromPos(CursorPos);
|
||||||
txtLine = &BrokenText[cursorLine];
|
txtLine = &BrokenText[cursorLine];
|
||||||
@ -943,7 +853,7 @@ void intlGUIEditBox::draw()
|
|||||||
CurrentTextRect.UpperLeftCorner.X += charcursorpos;
|
CurrentTextRect.UpperLeftCorner.X += charcursorpos;
|
||||||
|
|
||||||
font->draw(L"_", CurrentTextRect,
|
font->draw(L"_", CurrentTextRect,
|
||||||
OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT),
|
m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT),
|
||||||
false, true, &localClipRect);
|
false, true, &localClipRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,22 +875,6 @@ void intlGUIEditBox::setText(const wchar_t* text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Enables or disables automatic scrolling with cursor position
|
|
||||||
//! \param enable: If set to true, the text will move around with the cursor position
|
|
||||||
void intlGUIEditBox::setAutoScroll(bool enable)
|
|
||||||
{
|
|
||||||
AutoScroll = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Checks to see if automatic scrolling is enabled
|
|
||||||
//! \return true if automatic scrolling is enabled, false if not
|
|
||||||
bool intlGUIEditBox::isAutoScrollEnabled() const
|
|
||||||
{
|
|
||||||
return AutoScroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Gets the area of the text in the edit box
|
//! Gets the area of the text in the edit box
|
||||||
//! \return Returns the size in pixels of the text
|
//! \return Returns the size in pixels of the text
|
||||||
core::dimension2du intlGUIEditBox::getTextDimension()
|
core::dimension2du intlGUIEditBox::getTextDimension()
|
||||||
@ -1096,12 +990,12 @@ bool intlGUIEditBox::processMouse(const SEvent& event)
|
|||||||
|
|
||||||
s32 intlGUIEditBox::getCursorPos(s32 x, s32 y)
|
s32 intlGUIEditBox::getCursorPos(s32 x, s32 y)
|
||||||
{
|
{
|
||||||
IGUIFont* font = OverrideFont;
|
IGUIFont* font = m_override_font;
|
||||||
IGUISkin* skin = Environment->getSkin();
|
IGUISkin* skin = Environment->getSkin();
|
||||||
if (!OverrideFont)
|
if (!m_override_font)
|
||||||
font = skin->getFont();
|
font = skin->getFont();
|
||||||
|
|
||||||
const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1;
|
const u32 lineCount = (m_word_wrap || m_multiline) ? BrokenText.size() : 1;
|
||||||
|
|
||||||
core::stringw *txtLine = NULL;
|
core::stringw *txtLine = NULL;
|
||||||
s32 startPos = 0;
|
s32 startPos = 0;
|
||||||
@ -1118,8 +1012,8 @@ s32 intlGUIEditBox::getCursorPos(s32 x, s32 y)
|
|||||||
// is it inside this region?
|
// is it inside this region?
|
||||||
if (y >= CurrentTextRect.UpperLeftCorner.Y && y <= CurrentTextRect.LowerRightCorner.Y) {
|
if (y >= CurrentTextRect.UpperLeftCorner.Y && y <= CurrentTextRect.LowerRightCorner.Y) {
|
||||||
// we've found the clicked line
|
// we've found the clicked line
|
||||||
txtLine = (WordWrap || MultiLine) ? &BrokenText[curr_line_idx] : &Text;
|
txtLine = (m_word_wrap || m_multiline) ? &BrokenText[curr_line_idx] : &Text;
|
||||||
startPos = (WordWrap || MultiLine) ? BrokenTextPositions[curr_line_idx] : 0;
|
startPos = (m_word_wrap || m_multiline) ? BrokenTextPositions[curr_line_idx] : 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1144,14 +1038,14 @@ void intlGUIEditBox::breakText()
|
|||||||
{
|
{
|
||||||
IGUISkin* skin = Environment->getSkin();
|
IGUISkin* skin = Environment->getSkin();
|
||||||
|
|
||||||
if ((!WordWrap && !MultiLine) || !skin)
|
if ((!m_word_wrap && !m_multiline) || !skin)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BrokenText.clear(); // need to reallocate :/
|
BrokenText.clear(); // need to reallocate :/
|
||||||
BrokenTextPositions.set_used(0);
|
BrokenTextPositions.set_used(0);
|
||||||
|
|
||||||
IGUIFont* font = OverrideFont;
|
IGUIFont* font = m_override_font;
|
||||||
if (!OverrideFont)
|
if (!m_override_font)
|
||||||
font = skin->getFont();
|
font = skin->getFont();
|
||||||
|
|
||||||
if (!font)
|
if (!font)
|
||||||
@ -1190,7 +1084,7 @@ void intlGUIEditBox::breakText()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't break if we're not a multi-line edit box
|
// don't break if we're not a multi-line edit box
|
||||||
if (!MultiLine)
|
if (!m_multiline)
|
||||||
lineBreak = false;
|
lineBreak = false;
|
||||||
|
|
||||||
if (c == L' ' || c == 0 || i == (size-1))
|
if (c == L' ' || c == 0 || i == (size-1))
|
||||||
@ -1201,7 +1095,7 @@ void intlGUIEditBox::breakText()
|
|||||||
s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
|
s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
|
||||||
s32 worldlgth = font->getDimension(word.c_str()).Width;
|
s32 worldlgth = font->getDimension(word.c_str()).Width;
|
||||||
|
|
||||||
if (WordWrap && length + worldlgth + whitelgth > elWidth)
|
if (m_word_wrap && length + worldlgth + whitelgth > elWidth)
|
||||||
{
|
{
|
||||||
// break to next line
|
// break to next line
|
||||||
length = worldlgth;
|
length = worldlgth;
|
||||||
@ -1260,14 +1154,14 @@ void intlGUIEditBox::setTextRect(s32 line)
|
|||||||
if (!skin)
|
if (!skin)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont();
|
IGUIFont* font = m_override_font ? m_override_font : skin->getFont();
|
||||||
|
|
||||||
if (!font)
|
if (!font)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// get text dimension
|
// get text dimension
|
||||||
const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1;
|
const u32 lineCount = (m_word_wrap || m_multiline) ? BrokenText.size() : 1;
|
||||||
if (WordWrap || MultiLine)
|
if (m_word_wrap || m_multiline)
|
||||||
{
|
{
|
||||||
d = font->getDimension(BrokenText[line].c_str());
|
d = font->getDimension(BrokenText[line].c_str());
|
||||||
}
|
}
|
||||||
@ -1328,7 +1222,7 @@ void intlGUIEditBox::setTextRect(s32 line)
|
|||||||
|
|
||||||
s32 intlGUIEditBox::getLineFromPos(s32 pos)
|
s32 intlGUIEditBox::getLineFromPos(s32 pos)
|
||||||
{
|
{
|
||||||
if (!WordWrap && !MultiLine)
|
if (!m_word_wrap && !m_multiline)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s32 i=0;
|
s32 i=0;
|
||||||
@ -1387,7 +1281,7 @@ void intlGUIEditBox::inputChar(wchar_t c)
|
|||||||
|
|
||||||
void intlGUIEditBox::calculateScrollPos()
|
void intlGUIEditBox::calculateScrollPos()
|
||||||
{
|
{
|
||||||
if (!AutoScroll)
|
if (!m_autoscroll)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// calculate horizontal scroll position
|
// calculate horizontal scroll position
|
||||||
@ -1395,18 +1289,18 @@ void intlGUIEditBox::calculateScrollPos()
|
|||||||
setTextRect(cursLine);
|
setTextRect(cursLine);
|
||||||
|
|
||||||
// don't do horizontal scrolling when wordwrap is enabled.
|
// don't do horizontal scrolling when wordwrap is enabled.
|
||||||
if (!WordWrap)
|
if (!m_word_wrap)
|
||||||
{
|
{
|
||||||
// get cursor position
|
// get cursor position
|
||||||
IGUISkin* skin = Environment->getSkin();
|
IGUISkin* skin = Environment->getSkin();
|
||||||
if (!skin)
|
if (!skin)
|
||||||
return;
|
return;
|
||||||
IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont();
|
IGUIFont* font = m_override_font ? m_override_font : skin->getFont();
|
||||||
if (!font)
|
if (!font)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
core::stringw *txtLine = MultiLine ? &BrokenText[cursLine] : &Text;
|
core::stringw *txtLine = m_multiline ? &BrokenText[cursLine] : &Text;
|
||||||
s32 cPos = MultiLine ? CursorPos - BrokenTextPositions[cursLine] : CursorPos;
|
s32 cPos = m_multiline ? CursorPos - BrokenTextPositions[cursLine] : CursorPos;
|
||||||
|
|
||||||
s32 cStart = CurrentTextRect.UpperLeftCorner.X + HScrollPos +
|
s32 cStart = CurrentTextRect.UpperLeftCorner.X + HScrollPos +
|
||||||
font->getDimension(txtLine->subString(0, cPos).c_str()).Width;
|
font->getDimension(txtLine->subString(0, cPos).c_str()).Width;
|
||||||
@ -1423,7 +1317,7 @@ void intlGUIEditBox::calculateScrollPos()
|
|||||||
// todo: adjust scrollbar
|
// todo: adjust scrollbar
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WordWrap && !MultiLine)
|
if (!m_word_wrap && !m_multiline)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// vertical scroll position
|
// vertical scroll position
|
||||||
@ -1468,8 +1362,8 @@ void intlGUIEditBox::createVScrollBar()
|
|||||||
{
|
{
|
||||||
s32 fontHeight = 1;
|
s32 fontHeight = 1;
|
||||||
|
|
||||||
if (OverrideFont) {
|
if (m_override_font) {
|
||||||
fontHeight = OverrideFont->getDimension(L"").Height;
|
fontHeight = m_override_font->getDimension(L"").Height;
|
||||||
} else {
|
} else {
|
||||||
if (IGUISkin* skin = Environment->getSkin()) {
|
if (IGUISkin* skin = Environment->getSkin()) {
|
||||||
if (IGUIFont* font = skin->getFont()) {
|
if (IGUIFont* font = skin->getFont()) {
|
||||||
@ -1520,7 +1414,7 @@ void intlGUIEditBox::updateVScrollBar()
|
|||||||
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
m_vscrollbar->setPageSize(s32(getTextDimension().Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_vscrollbar->isVisible() && MultiLine) {
|
if (!m_vscrollbar->isVisible() && m_multiline) {
|
||||||
AbsoluteRect.LowerRightCorner.X -= m_scrollbar_width;
|
AbsoluteRect.LowerRightCorner.X -= m_scrollbar_width;
|
||||||
|
|
||||||
m_vscrollbar->setVisible(true);
|
m_vscrollbar->setVisible(true);
|
||||||
@ -1548,20 +1442,20 @@ void intlGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeRea
|
|||||||
{
|
{
|
||||||
// IGUIEditBox::serializeAttributes(out,options);
|
// IGUIEditBox::serializeAttributes(out,options);
|
||||||
|
|
||||||
out->addBool ("OverrideColorEnabled",OverrideColorEnabled );
|
out->addBool ("OverrideColorEnabled", m_override_color_enabled );
|
||||||
out->addColor ("OverrideColor", OverrideColor);
|
out->addColor ("OverrideColor", m_override_color);
|
||||||
// out->addFont("OverrideFont",OverrideFont);
|
// out->addFont("OverrideFont",m_override_font);
|
||||||
out->addInt ("MaxChars", Max);
|
out->addInt ("MaxChars", Max);
|
||||||
out->addBool ("WordWrap", WordWrap);
|
out->addBool ("WordWrap", m_word_wrap);
|
||||||
out->addBool ("MultiLine", MultiLine);
|
out->addBool ("MultiLine", m_multiline);
|
||||||
out->addBool ("AutoScroll", AutoScroll);
|
out->addBool ("AutoScroll", m_autoscroll);
|
||||||
out->addBool ("PasswordBox", PasswordBox);
|
out->addBool ("PasswordBox", PasswordBox);
|
||||||
core::stringw ch = L" ";
|
core::stringw ch = L" ";
|
||||||
ch[0] = PasswordChar;
|
ch[0] = PasswordChar;
|
||||||
out->addString("PasswordChar", ch.c_str());
|
out->addString("PasswordChar", ch.c_str());
|
||||||
out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames);
|
out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames);
|
||||||
out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames);
|
out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames);
|
||||||
out->addBool ("Writable", m_writable);
|
out->addBool ("Writable", m_writable);
|
||||||
|
|
||||||
IGUIEditBox::serializeAttributes(out,options);
|
IGUIEditBox::serializeAttributes(out,options);
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,15 @@
|
|||||||
#include "IrrCompileConfig.h"
|
#include "IrrCompileConfig.h"
|
||||||
//#ifdef _IRR_COMPILE_WITH_GUI_
|
//#ifdef _IRR_COMPILE_WITH_GUI_
|
||||||
|
|
||||||
#include <IGUIEditBox.h>
|
#include "guiEditBox.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
#include "IOSOperator.h"
|
#include "IOSOperator.h"
|
||||||
#include "guiScrollBar.h"
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
{
|
{
|
||||||
class intlGUIEditBox : public IGUIEditBox
|
class intlGUIEditBox : public GUIEditBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -28,32 +27,6 @@ namespace gui
|
|||||||
//! destructor
|
//! destructor
|
||||||
virtual ~intlGUIEditBox();
|
virtual ~intlGUIEditBox();
|
||||||
|
|
||||||
//! Sets another skin independent font.
|
|
||||||
virtual void setOverrideFont(IGUIFont* font=0);
|
|
||||||
|
|
||||||
//! Gets the override font (if any)
|
|
||||||
/** \return The override font (may be 0) */
|
|
||||||
virtual IGUIFont* getOverrideFont() const;
|
|
||||||
|
|
||||||
//! Get the font which is used right now for drawing
|
|
||||||
/** Currently this is the override font when one is set and the
|
|
||||||
font of the active skin otherwise */
|
|
||||||
virtual IGUIFont* getActiveFont() const;
|
|
||||||
|
|
||||||
//! Sets another color for the text.
|
|
||||||
virtual void setOverrideColor(video::SColor color);
|
|
||||||
|
|
||||||
//! Gets the override color
|
|
||||||
virtual video::SColor getOverrideColor() const;
|
|
||||||
|
|
||||||
//! Sets if the text should use the overide color or the
|
|
||||||
//! color in the gui skin.
|
|
||||||
virtual void enableOverrideColor(bool enable);
|
|
||||||
|
|
||||||
//! Checks if an override color is enabled
|
|
||||||
/** \return true if the override color is enabled, false otherwise */
|
|
||||||
virtual bool isOverrideColorEnabled(void) const;
|
|
||||||
|
|
||||||
//! Sets whether to draw the background
|
//! Sets whether to draw the background
|
||||||
virtual void setDrawBackground(bool draw);
|
virtual void setDrawBackground(bool draw);
|
||||||
|
|
||||||
@ -64,30 +37,6 @@ namespace gui
|
|||||||
|
|
||||||
virtual bool isDrawBorderEnabled() const { return Border; }
|
virtual bool isDrawBorderEnabled() const { return Border; }
|
||||||
|
|
||||||
//! Enables or disables word wrap for using the edit box as multiline text editor.
|
|
||||||
virtual void setWordWrap(bool enable);
|
|
||||||
|
|
||||||
//! Checks if word wrap is enabled
|
|
||||||
//! \return true if word wrap is enabled, false otherwise
|
|
||||||
virtual bool isWordWrapEnabled() const;
|
|
||||||
|
|
||||||
//! Enables or disables newlines.
|
|
||||||
/** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired,
|
|
||||||
instead a newline character will be inserted. */
|
|
||||||
virtual void setMultiLine(bool enable);
|
|
||||||
|
|
||||||
//! Checks if multi line editing is enabled
|
|
||||||
//! \return true if mult-line is enabled, false otherwise
|
|
||||||
virtual bool isMultiLineEnabled() const;
|
|
||||||
|
|
||||||
//! Enables or disables automatic scrolling with cursor position
|
|
||||||
//! \param enable: If set to true, the text will move around with the cursor position
|
|
||||||
virtual void setAutoScroll(bool enable);
|
|
||||||
|
|
||||||
//! Checks to see if automatic scrolling is enabled
|
|
||||||
//! \return true if automatic scrolling is enabled, false if not
|
|
||||||
virtual bool isAutoScrollEnabled() const;
|
|
||||||
|
|
||||||
//! Gets the size area of the text in the edit box
|
//! Gets the size area of the text in the edit box
|
||||||
//! \return Returns the size in pixels of the text
|
//! \return Returns the size in pixels of the text
|
||||||
virtual core::dimension2du getTextDimension();
|
virtual core::dimension2du getTextDimension();
|
||||||
@ -143,7 +92,7 @@ namespace gui
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Breaks the single text line.
|
//! Breaks the single text line.
|
||||||
void breakText();
|
virtual void breakText();
|
||||||
//! sets the area of the given line
|
//! sets the area of the given line
|
||||||
void setTextRect(s32 line);
|
void setTextRect(s32 line);
|
||||||
//! returns the line number that the cursor is on
|
//! returns the line number that the cursor is on
|
||||||
@ -169,12 +118,9 @@ namespace gui
|
|||||||
|
|
||||||
bool MouseMarking = false;
|
bool MouseMarking = false;
|
||||||
bool Border;
|
bool Border;
|
||||||
bool OverrideColorEnabled = false;
|
|
||||||
s32 MarkBegin = 0;
|
s32 MarkBegin = 0;
|
||||||
s32 MarkEnd = 0;
|
s32 MarkEnd = 0;
|
||||||
|
|
||||||
video::SColor OverrideColor = video::SColor(101,255,255,255);
|
|
||||||
gui::IGUIFont *OverrideFont = nullptr;
|
|
||||||
gui::IGUIFont *LastBreakFont = nullptr;
|
gui::IGUIFont *LastBreakFont = nullptr;
|
||||||
IOSOperator *Operator = nullptr;
|
IOSOperator *Operator = nullptr;
|
||||||
|
|
||||||
@ -184,9 +130,6 @@ namespace gui
|
|||||||
s32 VScrollPos = 0; // scroll position in characters
|
s32 VScrollPos = 0; // scroll position in characters
|
||||||
u32 Max = 0;
|
u32 Max = 0;
|
||||||
|
|
||||||
bool WordWrap = false;
|
|
||||||
bool MultiLine = false;
|
|
||||||
bool AutoScroll = true;
|
|
||||||
bool PasswordBox = false;
|
bool PasswordBox = false;
|
||||||
wchar_t PasswordChar = L'*';
|
wchar_t PasswordChar = L'*';
|
||||||
EGUI_ALIGNMENT HAlign = EGUIA_UPPERLEFT;
|
EGUI_ALIGNMENT HAlign = EGUIA_UPPERLEFT;
|
||||||
|
@ -881,8 +881,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
|
|||||||
s32 dyj = event.TouchInput.Y - m_screensize.Y + button_size * 5.0f / 2.0f;
|
s32 dyj = event.TouchInput.Y - m_screensize.Y + button_size * 5.0f / 2.0f;
|
||||||
bool inside_joystick = (dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5);
|
bool inside_joystick = (dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5);
|
||||||
|
|
||||||
if (m_joystick_has_really_moved ||
|
if (m_joystick_has_really_moved || inside_joystick ||
|
||||||
(!m_joystick_has_really_moved && inside_joystick) ||
|
|
||||||
(!m_fixed_joystick &&
|
(!m_fixed_joystick &&
|
||||||
distance_sq > m_touchscreen_threshold * m_touchscreen_threshold)) {
|
distance_sq > m_touchscreen_threshold * m_touchscreen_threshold)) {
|
||||||
m_joystick_has_really_moved = true;
|
m_joystick_has_really_moved = true;
|
||||||
|
@ -356,7 +356,7 @@ namespace gui
|
|||||||
load_flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER;
|
load_flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER;
|
||||||
if (!useHinting()) load_flags |= FT_LOAD_NO_HINTING;
|
if (!useHinting()) load_flags |= FT_LOAD_NO_HINTING;
|
||||||
if (!useAutoHinting()) load_flags |= FT_LOAD_NO_AUTOHINT;
|
if (!useAutoHinting()) load_flags |= FT_LOAD_NO_AUTOHINT;
|
||||||
if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO | FT_RENDER_MODE_MONO;
|
if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO;
|
||||||
else load_flags |= FT_LOAD_TARGET_NORMAL;
|
else load_flags |= FT_LOAD_TARGET_NORMAL;
|
||||||
}
|
}
|
||||||
u32 getWidthFromCharacter(wchar_t c) const;
|
u32 getWidthFromCharacter(wchar_t c) const;
|
||||||
|
@ -1331,7 +1331,7 @@ public:
|
|||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
const uchar16_t* oa = other.c_str();
|
const uchar16_t* oa = other.c_str();
|
||||||
for(i=0; array[i] && oa[i] && i < n; ++i)
|
for(i=0; i < n && array[i] && oa[i]; ++i)
|
||||||
if (array[i] != oa[i])
|
if (array[i] != oa[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1350,7 +1350,7 @@ public:
|
|||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
u32 i;
|
u32 i;
|
||||||
for(i=0; array[i] && str[i] && i < n; ++i)
|
for(i=0; i < n && array[i] && str[i]; ++i)
|
||||||
if (array[i] != str[i])
|
if (array[i] != str[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1250,6 +1250,8 @@ ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef,
|
|||||||
|
|
||||||
m_save_time_counter = mb->addCounter("minetest_core_map_save_time", "Map save time (in nanoseconds)");
|
m_save_time_counter = mb->addCounter("minetest_core_map_save_time", "Map save time (in nanoseconds)");
|
||||||
|
|
||||||
|
m_map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// If directory exists, check contents and load if possible
|
// If directory exists, check contents and load if possible
|
||||||
if (fs::PathExists(m_savedir)) {
|
if (fs::PathExists(m_savedir)) {
|
||||||
@ -1863,10 +1865,10 @@ void ServerMap::endSave()
|
|||||||
|
|
||||||
bool ServerMap::saveBlock(MapBlock *block)
|
bool ServerMap::saveBlock(MapBlock *block)
|
||||||
{
|
{
|
||||||
return saveBlock(block, dbase);
|
return saveBlock(block, dbase, m_map_compression_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db)
|
bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db, int compression_level)
|
||||||
{
|
{
|
||||||
v3s16 p3d = block->getPos();
|
v3s16 p3d = block->getPos();
|
||||||
|
|
||||||
@ -1886,7 +1888,7 @@ bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db)
|
|||||||
*/
|
*/
|
||||||
std::ostringstream o(std::ios_base::binary);
|
std::ostringstream o(std::ios_base::binary);
|
||||||
o.write((char*) &version, 1);
|
o.write((char*) &version, 1);
|
||||||
block->serialize(o, version, true);
|
block->serialize(o, version, true, compression_level);
|
||||||
|
|
||||||
bool ret = db->saveBlock(p3d, o.str());
|
bool ret = db->saveBlock(p3d, o.str());
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -382,7 +382,7 @@ public:
|
|||||||
MapgenParams *getMapgenParams();
|
MapgenParams *getMapgenParams();
|
||||||
|
|
||||||
bool saveBlock(MapBlock *block);
|
bool saveBlock(MapBlock *block);
|
||||||
static bool saveBlock(MapBlock *block, MapDatabase *db);
|
static bool saveBlock(MapBlock *block, MapDatabase *db, int compression_level = -1);
|
||||||
MapBlock* loadBlock(v3s16 p);
|
MapBlock* loadBlock(v3s16 p);
|
||||||
// Database version
|
// Database version
|
||||||
void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
|
void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
|
||||||
@ -417,6 +417,7 @@ private:
|
|||||||
std::string m_savedir;
|
std::string m_savedir;
|
||||||
bool m_map_saving_enabled;
|
bool m_map_saving_enabled;
|
||||||
|
|
||||||
|
int m_map_compression_level;
|
||||||
#if 0
|
#if 0
|
||||||
// Chunk size in MapSectors
|
// Chunk size in MapSectors
|
||||||
// If 0, chunks are disabled.
|
// If 0, chunks are disabled.
|
||||||
|
@ -355,7 +355,7 @@ static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
void MapBlock::serialize(std::ostream &os, u8 version, bool disk, int compression_level)
|
||||||
{
|
{
|
||||||
if(!ser_ver_supported(version))
|
if(!ser_ver_supported(version))
|
||||||
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
||||||
@ -394,7 +394,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
|||||||
writeU8(os, content_width);
|
writeU8(os, content_width);
|
||||||
writeU8(os, params_width);
|
writeU8(os, params_width);
|
||||||
MapNode::serializeBulk(os, version, tmp_nodes, nodecount,
|
MapNode::serializeBulk(os, version, tmp_nodes, nodecount,
|
||||||
content_width, params_width, true);
|
content_width, params_width, compression_level);
|
||||||
delete[] tmp_nodes;
|
delete[] tmp_nodes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -404,7 +404,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
|||||||
writeU8(os, content_width);
|
writeU8(os, content_width);
|
||||||
writeU8(os, params_width);
|
writeU8(os, params_width);
|
||||||
MapNode::serializeBulk(os, version, data, nodecount,
|
MapNode::serializeBulk(os, version, data, nodecount,
|
||||||
content_width, params_width, true);
|
content_width, params_width, compression_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -412,7 +412,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
|||||||
*/
|
*/
|
||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
m_node_metadata.serialize(oss, version, disk);
|
m_node_metadata.serialize(oss, version, disk);
|
||||||
compressZlib(oss.str(), os);
|
compressZlib(oss.str(), os, compression_level);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Data that goes to disk, but not the network
|
Data that goes to disk, but not the network
|
||||||
@ -485,7 +485,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
|
|||||||
if(params_width != 2)
|
if(params_width != 2)
|
||||||
throw SerializationError("MapBlock::deSerialize(): invalid params_width");
|
throw SerializationError("MapBlock::deSerialize(): invalid params_width");
|
||||||
MapNode::deSerializeBulk(is, version, data, nodecount,
|
MapNode::deSerializeBulk(is, version, data, nodecount,
|
||||||
content_width, params_width, true);
|
content_width, params_width);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeMetadata
|
NodeMetadata
|
||||||
|
@ -482,7 +482,7 @@ public:
|
|||||||
// These don't write or read version by itself
|
// These don't write or read version by itself
|
||||||
// Set disk to true for on-disk format, false for over-the-network format
|
// Set disk to true for on-disk format, false for over-the-network format
|
||||||
// Precondition: version >= SER_FMT_VER_LOWEST_WRITE
|
// Precondition: version >= SER_FMT_VER_LOWEST_WRITE
|
||||||
void serialize(std::ostream &os, u8 version, bool disk);
|
void serialize(std::ostream &os, u8 version, bool disk, int compression_level);
|
||||||
// If disk == true: In addition to doing other things, will add
|
// If disk == true: In addition to doing other things, will add
|
||||||
// unknown blocks from id-name mapping to wndef
|
// unknown blocks from id-name mapping to wndef
|
||||||
void deSerialize(std::istream &is, u8 version, bool disk);
|
void deSerialize(std::istream &is, u8 version, bool disk);
|
||||||
|
@ -297,7 +297,7 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
|||||||
int iters = 256;
|
int iters = 256;
|
||||||
while (iters > 0 && y <= max_spawn_y) {
|
while (iters > 0 && y <= max_spawn_y) {
|
||||||
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) {
|
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) {
|
||||||
if (y <= water_level || y > max_spawn_y)
|
if (y <= water_level)
|
||||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||||
|
|
||||||
// y + 1 due to biome 'dust'
|
// y + 1 due to biome 'dust'
|
||||||
|
@ -334,7 +334,7 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
|||||||
schemdata = new MapNode[nodecount];
|
schemdata = new MapNode[nodecount];
|
||||||
|
|
||||||
MapNode::deSerializeBulk(ss, SER_FMT_VER_HIGHEST_READ, schemdata,
|
MapNode::deSerializeBulk(ss, SER_FMT_VER_HIGHEST_READ, schemdata,
|
||||||
nodecount, 2, 2, true);
|
nodecount, 2, 2);
|
||||||
|
|
||||||
// Fix probability values for nodes that were ignore; removed in v2
|
// Fix probability values for nodes that were ignore; removed in v2
|
||||||
if (version < 2) {
|
if (version < 2) {
|
||||||
@ -376,7 +376,7 @@ bool Schematic::serializeToMts(std::ostream *os,
|
|||||||
|
|
||||||
// compressed bulk node data
|
// compressed bulk node data
|
||||||
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE,
|
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE,
|
||||||
schemdata, size.X * size.Y * size.Z, 2, 2, true);
|
schemdata, size.X * size.Y * size.Z, 2, 2, -1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +406,8 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
|||||||
v3f(position.X, position.Y, position.Z - 1),
|
v3f(position.X, position.Y, position.Z - 1),
|
||||||
tree_definition
|
tree_definition
|
||||||
);
|
);
|
||||||
} if (!stack_orientation.empty()) {
|
}
|
||||||
|
if (!stack_orientation.empty()) {
|
||||||
s16 size = 1;
|
s16 size = 1;
|
||||||
for (x = -size; x <= size; x++)
|
for (x = -size; x <= size; x++)
|
||||||
for (y = -size; y <= size; y++)
|
for (y = -size; y <= size; y++)
|
||||||
|
@ -706,7 +706,7 @@ void MapNode::deSerialize(u8 *source, u8 version)
|
|||||||
}
|
}
|
||||||
void MapNode::serializeBulk(std::ostream &os, int version,
|
void MapNode::serializeBulk(std::ostream &os, int version,
|
||||||
const MapNode *nodes, u32 nodecount,
|
const MapNode *nodes, u32 nodecount,
|
||||||
u8 content_width, u8 params_width, bool compressed)
|
u8 content_width, u8 params_width, int compression_level)
|
||||||
{
|
{
|
||||||
if (!ser_ver_supported(version))
|
if (!ser_ver_supported(version))
|
||||||
throw VersionMismatchException("ERROR: MapNode format not supported");
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
||||||
@ -737,10 +737,7 @@ void MapNode::serializeBulk(std::ostream &os, int version,
|
|||||||
Compress data to output stream
|
Compress data to output stream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (compressed)
|
compressZlib(databuf, databuf_size, os, compression_level);
|
||||||
compressZlib(databuf, databuf_size, os);
|
|
||||||
else
|
|
||||||
os.write((const char*) &databuf[0], databuf_size);
|
|
||||||
|
|
||||||
delete [] databuf;
|
delete [] databuf;
|
||||||
}
|
}
|
||||||
@ -748,7 +745,7 @@ void MapNode::serializeBulk(std::ostream &os, int version,
|
|||||||
// Deserialize bulk node data
|
// Deserialize bulk node data
|
||||||
void MapNode::deSerializeBulk(std::istream &is, int version,
|
void MapNode::deSerializeBulk(std::istream &is, int version,
|
||||||
MapNode *nodes, u32 nodecount,
|
MapNode *nodes, u32 nodecount,
|
||||||
u8 content_width, u8 params_width, bool compressed)
|
u8 content_width, u8 params_width)
|
||||||
{
|
{
|
||||||
if(!ser_ver_supported(version))
|
if(!ser_ver_supported(version))
|
||||||
throw VersionMismatchException("ERROR: MapNode format not supported");
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
||||||
@ -760,24 +757,13 @@ void MapNode::deSerializeBulk(std::istream &is, int version,
|
|||||||
|
|
||||||
// Uncompress or read data
|
// Uncompress or read data
|
||||||
u32 len = nodecount * (content_width + params_width);
|
u32 len = nodecount * (content_width + params_width);
|
||||||
SharedBuffer<u8> databuf(len);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
if(compressed)
|
decompressZlib(is, os);
|
||||||
{
|
std::string s = os.str();
|
||||||
std::ostringstream os(std::ios_base::binary);
|
if(s.size() != len)
|
||||||
decompressZlib(is, os);
|
throw SerializationError("deSerializeBulkNodes: "
|
||||||
std::string s = os.str();
|
"decompress resulted in invalid size");
|
||||||
if(s.size() != len)
|
const u8 *databuf = reinterpret_cast<const u8*>(s.c_str());
|
||||||
throw SerializationError("deSerializeBulkNodes: "
|
|
||||||
"decompress resulted in invalid size");
|
|
||||||
memcpy(&databuf[0], s.c_str(), len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
is.read((char*) &databuf[0], len);
|
|
||||||
if(is.eof() || is.fail())
|
|
||||||
throw SerializationError("deSerializeBulkNodes: "
|
|
||||||
"failed to read bulk node data");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deserialize content
|
// Deserialize content
|
||||||
if(content_width == 1)
|
if(content_width == 1)
|
||||||
|
@ -292,10 +292,10 @@ struct MapNode
|
|||||||
// compressed = true to zlib-compress output
|
// compressed = true to zlib-compress output
|
||||||
static void serializeBulk(std::ostream &os, int version,
|
static void serializeBulk(std::ostream &os, int version,
|
||||||
const MapNode *nodes, u32 nodecount,
|
const MapNode *nodes, u32 nodecount,
|
||||||
u8 content_width, u8 params_width, bool compressed);
|
u8 content_width, u8 params_width, int compression_level);
|
||||||
static void deSerializeBulk(std::istream &is, int version,
|
static void deSerializeBulk(std::istream &is, int version,
|
||||||
MapNode *nodes, u32 nodecount,
|
MapNode *nodes, u32 nodecount,
|
||||||
u8 content_width, u8 params_width, bool compressed);
|
u8 content_width, u8 params_width);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Deprecated serialization methods
|
// Deprecated serialization methods
|
||||||
|
@ -226,22 +226,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
||||||
// base64-encoded SHA-1 (27+\0).
|
// base64-encoded SHA-1 (27+\0).
|
||||||
|
|
||||||
/*
|
// See also: Formspec Version History in doc/lua_api.txt
|
||||||
Changes by FORMSPEC_API_VERSION:
|
|
||||||
|
|
||||||
FORMSPEC VERSION 1:
|
|
||||||
(too much)
|
|
||||||
FORMSPEC VERSION 2:
|
|
||||||
Forced real coordinates
|
|
||||||
background9[]: 9-slice scaling parameters
|
|
||||||
FORMSPEC VERSION 3:
|
|
||||||
Formspec elements are drawn in the order of definition
|
|
||||||
bgcolor[]: use 3 parameters (bgcolor, formspec (now an enum), fbgcolor)
|
|
||||||
box[] and image[] elements enable clipping by default
|
|
||||||
new element: scroll_container[]
|
|
||||||
FORMSPEC VERSION 4:
|
|
||||||
Allow dropdown indexing events
|
|
||||||
*/
|
|
||||||
#define FORMSPEC_API_VERSION 4
|
#define FORMSPEC_API_VERSION 4
|
||||||
|
|
||||||
#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"
|
#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"
|
||||||
|
@ -316,7 +316,7 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
|
|||||||
// Send active objects
|
// Send active objects
|
||||||
{
|
{
|
||||||
PlayerSAO *sao = getPlayerSAO(peer_id);
|
PlayerSAO *sao = getPlayerSAO(peer_id);
|
||||||
if (client && sao)
|
if (sao)
|
||||||
SendActiveObjectRemoveAdd(client, sao);
|
SendActiveObjectRemoveAdd(client, sao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,7 +617,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
|
|||||||
bool has_scale = tiledef.scale > 0;
|
bool has_scale = tiledef.scale > 0;
|
||||||
bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE ||
|
bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE ||
|
||||||
(tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale);
|
(tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale);
|
||||||
if (use_autoscale && layer->texture) {
|
if (use_autoscale) {
|
||||||
auto texture_size = layer->texture->getOriginalSize();
|
auto texture_size = layer->texture->getOriginalSize();
|
||||||
float base_size = tsettings.node_texture_size;
|
float base_size = tsettings.node_texture_size;
|
||||||
float size = std::fmin(texture_size.Width, texture_size.Height);
|
float size = std::fmin(texture_size.Width, texture_size.Height);
|
||||||
@ -774,7 +774,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||||||
|
|
||||||
bool is_liquid = false;
|
bool is_liquid = false;
|
||||||
|
|
||||||
u8 material_type = (alpha == 255) ?
|
MaterialType material_type = (alpha == 255) ?
|
||||||
TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
|
TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
|
||||||
|
|
||||||
switch (drawtype) {
|
switch (drawtype) {
|
||||||
@ -892,7 +892,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||||||
|
|
||||||
u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype);
|
u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype);
|
||||||
|
|
||||||
u8 overlay_material = material_type;
|
MaterialType overlay_material = material_type;
|
||||||
if (overlay_material == TILE_MATERIAL_OPAQUE)
|
if (overlay_material == TILE_MATERIAL_OPAQUE)
|
||||||
overlay_material = TILE_MATERIAL_BASIC;
|
overlay_material = TILE_MATERIAL_BASIC;
|
||||||
else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE)
|
else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE)
|
||||||
@ -913,7 +913,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||||||
tdef[j].backface_culling, tsettings);
|
tdef[j].backface_culling, tsettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 special_material = material_type;
|
MaterialType special_material = material_type;
|
||||||
if (drawtype == NDT_PLANTLIKE_ROOTED) {
|
if (drawtype == NDT_PLANTLIKE_ROOTED) {
|
||||||
if (waving == 1)
|
if (waving == 1)
|
||||||
special_material = TILE_MATERIAL_WAVING_PLANTS;
|
special_material = TILE_MATERIAL_WAVING_PLANTS;
|
||||||
|
@ -719,29 +719,48 @@ int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool openURL(const std::string &url)
|
static bool open_uri(const std::string &uri)
|
||||||
{
|
{
|
||||||
if ((url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") ||
|
if (uri.find_first_of("\r\n") != std::string::npos) {
|
||||||
url.find_first_of("\r\n") != std::string::npos) {
|
errorstream << "Unable to open URI as it is invalid, contains new line: " << uri << std::endl;
|
||||||
errorstream << "Invalid url: " << url << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return (intptr_t)ShellExecuteA(NULL, NULL, url.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32;
|
return (intptr_t)ShellExecuteA(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32;
|
||||||
#elif defined(__ANDROID__)
|
#elif defined(__ANDROID__)
|
||||||
openURLAndroid(url);
|
openURIAndroid(uri);
|
||||||
return true;
|
return true;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
const char *argv[] = {"open", url.c_str(), NULL};
|
const char *argv[] = {"open", uri.c_str(), NULL};
|
||||||
return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv,
|
return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv,
|
||||||
(*_NSGetEnviron())) == 0;
|
(*_NSGetEnviron())) == 0;
|
||||||
#else
|
#else
|
||||||
const char *argv[] = {"xdg-open", url.c_str(), NULL};
|
const char *argv[] = {"xdg-open", uri.c_str(), NULL};
|
||||||
return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0;
|
return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool open_url(const std::string &url)
|
||||||
|
{
|
||||||
|
if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") {
|
||||||
|
errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return open_uri(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool open_directory(const std::string &path)
|
||||||
|
{
|
||||||
|
if (!fs::IsDir(path)) {
|
||||||
|
errorstream << "Unable to open directory as it does not exist: " << path << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return open_uri(path);
|
||||||
|
}
|
||||||
|
|
||||||
// Load performance counter frequency only once at startup
|
// Load performance counter frequency only once at startup
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
@ -332,7 +332,25 @@ void attachOrCreateConsole();
|
|||||||
|
|
||||||
int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...);
|
int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...);
|
||||||
|
|
||||||
bool openURL(const std::string &url);
|
/**
|
||||||
|
* Opens URL in default web browser
|
||||||
|
*
|
||||||
|
* Must begin with http:// or https://, and not contain any new lines
|
||||||
|
*
|
||||||
|
* @param url The URL
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool open_url(const std::string &url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a directory in the default file manager
|
||||||
|
*
|
||||||
|
* The directory must exist.
|
||||||
|
*
|
||||||
|
* @param path Path to directory
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool open_directory(const std::string &path);
|
||||||
|
|
||||||
} // namespace porting
|
} // namespace porting
|
||||||
|
|
||||||
|
@ -213,13 +213,13 @@ void showInputDialog(const std::string &acceptButton, const std::string &hint,
|
|||||||
jacceptButton, jhint, jcurrent, jeditType);
|
jacceptButton, jhint, jcurrent, jeditType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void openURLAndroid(const std::string &url)
|
void openURIAndroid(const std::string &url)
|
||||||
{
|
{
|
||||||
jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURL",
|
jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURI",
|
||||||
"(Ljava/lang/String;)V");
|
"(Ljava/lang/String;)V");
|
||||||
|
|
||||||
FATAL_ERROR_IF(url_open == nullptr,
|
FATAL_ERROR_IF(url_open == nullptr,
|
||||||
"porting::openURLAndroid unable to find java openURL method");
|
"porting::openURIAndroid unable to find java openURI method");
|
||||||
|
|
||||||
jstring jurl = jnienv->NewStringUTF(url.c_str());
|
jstring jurl = jnienv->NewStringUTF(url.c_str());
|
||||||
jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl);
|
jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl);
|
||||||
|
@ -58,7 +58,7 @@ void initializePathsAndroid();
|
|||||||
void showInputDialog(const std::string &acceptButton,
|
void showInputDialog(const std::string &acceptButton,
|
||||||
const std::string &hint, const std::string ¤t, int editType);
|
const std::string &hint, const std::string ¤t, int editType);
|
||||||
|
|
||||||
void openURLAndroid(const std::string &url);
|
void openURIAndroid(const std::string &url);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WORKAROUND for not working callbacks from java -> c++
|
* WORKAROUND for not working callbacks from java -> c++
|
||||||
|
@ -38,7 +38,7 @@ ScopeProfiler::~ScopeProfiler()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
float duration_ms = m_timer->stop(true);
|
float duration_ms = m_timer->stop(true);
|
||||||
float duration = duration_ms / 1000.0;
|
float duration = duration_ms;
|
||||||
if (m_profiler) {
|
if (m_profiler) {
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case SPT_ADD:
|
case SPT_ADD:
|
||||||
|
@ -103,6 +103,32 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
|
|||||||
lua_pop(L, 2); // Pop object and error handler
|
lua_pop(L, 2); // Pop object and error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptApiEntity::luaentity_Deactivate(u16 id)
|
||||||
|
{
|
||||||
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
verbosestream << "scriptapi_luaentity_deactivate: id=" << id << std::endl;
|
||||||
|
|
||||||
|
int error_handler = PUSH_ERROR_HANDLER(L);
|
||||||
|
|
||||||
|
// Get the entity
|
||||||
|
luaentity_get(L, id);
|
||||||
|
int object = lua_gettop(L);
|
||||||
|
|
||||||
|
// Get on_deactivate
|
||||||
|
lua_getfield(L, -1, "on_deactivate");
|
||||||
|
if (!lua_isnil(L, -1)) {
|
||||||
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
lua_pushvalue(L, object);
|
||||||
|
|
||||||
|
setOriginFromTable(object);
|
||||||
|
PCALL_RES(lua_pcall(L, 1, 0, error_handler));
|
||||||
|
} else {
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 2); // Pop object and error handler
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptApiEntity::luaentity_Remove(u16 id)
|
void ScriptApiEntity::luaentity_Remove(u16 id)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
@ -33,6 +33,7 @@ public:
|
|||||||
bool luaentity_Add(u16 id, const char *name);
|
bool luaentity_Add(u16 id, const char *name);
|
||||||
void luaentity_Activate(u16 id,
|
void luaentity_Activate(u16 id,
|
||||||
const std::string &staticdata, u32 dtime_s);
|
const std::string &staticdata, u32 dtime_s);
|
||||||
|
void luaentity_Deactivate(u16 id);
|
||||||
void luaentity_Remove(u16 id);
|
void luaentity_Remove(u16 id);
|
||||||
std::string luaentity_GetStaticdata(u16 id);
|
std::string luaentity_GetStaticdata(u16 id);
|
||||||
void luaentity_GetProperties(u16 id,
|
void luaentity_GetProperties(u16 id,
|
||||||
|
@ -401,10 +401,9 @@ bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char
|
|||||||
lua_pushfstring(L, "%s: %s", path, strerror(errno));
|
lua_pushfstring(L, "%s: %s", path, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
chunk_name = new char[strlen(display_name) + 2];
|
size_t len = strlen(display_name) + 2;
|
||||||
chunk_name[0] = '@';
|
chunk_name = new char[len];
|
||||||
chunk_name[1] = '\0';
|
snprintf(chunk_name, len, "@%s", display_name);
|
||||||
strcat(chunk_name, display_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t start = 0;
|
size_t start = 0;
|
||||||
|
@ -743,6 +743,31 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_objects_in_area(pos, minp, maxp)
|
||||||
|
int ModApiEnvMod::l_get_objects_in_area(lua_State *L)
|
||||||
|
{
|
||||||
|
GET_ENV_PTR;
|
||||||
|
ScriptApiBase *script = getScriptApiBase(L);
|
||||||
|
|
||||||
|
v3f minp = read_v3f(L, 1) * BS;
|
||||||
|
v3f maxp = read_v3f(L, 2) * BS;
|
||||||
|
aabb3f box(minp, maxp);
|
||||||
|
box.repair();
|
||||||
|
std::vector<ServerActiveObject *> objs;
|
||||||
|
|
||||||
|
auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); };
|
||||||
|
env->getObjectsInArea(objs, box, include_obj_cb);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
lua_createtable(L, objs.size(), 0);
|
||||||
|
for (const auto obj : objs) {
|
||||||
|
// Insert object reference into table
|
||||||
|
script->objectrefGetOrCreate(L, obj);
|
||||||
|
lua_rawseti(L, -2, ++i);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// set_timeofday(val)
|
// set_timeofday(val)
|
||||||
// val = 0...1
|
// val = 0...1
|
||||||
int ModApiEnvMod::l_set_timeofday(lua_State *L)
|
int ModApiEnvMod::l_set_timeofday(lua_State *L)
|
||||||
@ -1571,6 +1596,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(get_node_timer);
|
API_FCT(get_node_timer);
|
||||||
API_FCT(get_connected_players);
|
API_FCT(get_connected_players);
|
||||||
API_FCT(get_player_by_name);
|
API_FCT(get_player_by_name);
|
||||||
|
API_FCT(get_objects_in_area);
|
||||||
API_FCT(get_objects_inside_radius);
|
API_FCT(get_objects_inside_radius);
|
||||||
API_FCT(set_timeofday);
|
API_FCT(set_timeofday);
|
||||||
API_FCT(get_timeofday);
|
API_FCT(get_timeofday);
|
||||||
|
@ -115,6 +115,9 @@ private:
|
|||||||
// get_objects_inside_radius(pos, radius)
|
// get_objects_inside_radius(pos, radius)
|
||||||
static int l_get_objects_inside_radius(lua_State *L);
|
static int l_get_objects_inside_radius(lua_State *L);
|
||||||
|
|
||||||
|
// get_objects_in_area(pos, minp, maxp)
|
||||||
|
static int l_get_objects_in_area(lua_State *L);
|
||||||
|
|
||||||
// set_timeofday(val)
|
// set_timeofday(val)
|
||||||
// val = 0...1
|
// val = 0...1
|
||||||
static int l_set_timeofday(lua_State *L);
|
static int l_set_timeofday(lua_State *L);
|
||||||
|
@ -686,6 +686,14 @@ int ModApiMainMenu::l_get_mapgen_names(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int ModApiMainMenu::l_get_user_path(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string path = fs::RemoveRelativePathComponents(porting::path_user);
|
||||||
|
lua_pushstring(L, path.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
int ModApiMainMenu::l_get_modpath(lua_State *L)
|
int ModApiMainMenu::l_get_modpath(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -795,6 +803,15 @@ int ModApiMainMenu::l_copy_dir(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int ModApiMainMenu::l_is_dir(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *path = luaL_checkstring(L, 1);
|
||||||
|
|
||||||
|
lua_pushboolean(L, fs::IsDir(path));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
int ModApiMainMenu::l_extract_zip(lua_State *L)
|
int ModApiMainMenu::l_extract_zip(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -1070,7 +1087,15 @@ int ModApiMainMenu::l_get_max_supp_proto(lua_State *L)
|
|||||||
int ModApiMainMenu::l_open_url(lua_State *L)
|
int ModApiMainMenu::l_open_url(lua_State *L)
|
||||||
{
|
{
|
||||||
std::string url = luaL_checkstring(L, 1);
|
std::string url = luaL_checkstring(L, 1);
|
||||||
lua_pushboolean(L, porting::openURL(url));
|
lua_pushboolean(L, porting::open_url(url));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int ModApiMainMenu::l_open_dir(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string path = luaL_checkstring(L, 1);
|
||||||
|
lua_pushboolean(L, porting::open_directory(path));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,6 +1141,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(set_background);
|
API_FCT(set_background);
|
||||||
API_FCT(set_topleft_text);
|
API_FCT(set_topleft_text);
|
||||||
API_FCT(get_mapgen_names);
|
API_FCT(get_mapgen_names);
|
||||||
|
API_FCT(get_user_path);
|
||||||
API_FCT(get_modpath);
|
API_FCT(get_modpath);
|
||||||
API_FCT(get_clientmodpath);
|
API_FCT(get_clientmodpath);
|
||||||
API_FCT(get_gamepath);
|
API_FCT(get_gamepath);
|
||||||
@ -1125,6 +1151,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(create_dir);
|
API_FCT(create_dir);
|
||||||
API_FCT(delete_dir);
|
API_FCT(delete_dir);
|
||||||
API_FCT(copy_dir);
|
API_FCT(copy_dir);
|
||||||
|
API_FCT(is_dir);
|
||||||
API_FCT(extract_zip);
|
API_FCT(extract_zip);
|
||||||
API_FCT(may_modify_path);
|
API_FCT(may_modify_path);
|
||||||
API_FCT(get_mainmenu_path);
|
API_FCT(get_mainmenu_path);
|
||||||
@ -1137,6 +1164,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(get_min_supp_proto);
|
API_FCT(get_min_supp_proto);
|
||||||
API_FCT(get_max_supp_proto);
|
API_FCT(get_max_supp_proto);
|
||||||
API_FCT(open_url);
|
API_FCT(open_url);
|
||||||
|
API_FCT(open_dir);
|
||||||
API_FCT(do_async_callback);
|
API_FCT(do_async_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,6 +1175,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
|
|||||||
API_FCT(get_games);
|
API_FCT(get_games);
|
||||||
API_FCT(get_favorites);
|
API_FCT(get_favorites);
|
||||||
API_FCT(get_mapgen_names);
|
API_FCT(get_mapgen_names);
|
||||||
|
API_FCT(get_user_path);
|
||||||
API_FCT(get_modpath);
|
API_FCT(get_modpath);
|
||||||
API_FCT(get_clientmodpath);
|
API_FCT(get_clientmodpath);
|
||||||
API_FCT(get_gamepath);
|
API_FCT(get_gamepath);
|
||||||
@ -1156,6 +1185,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
|
|||||||
API_FCT(create_dir);
|
API_FCT(create_dir);
|
||||||
API_FCT(delete_dir);
|
API_FCT(delete_dir);
|
||||||
API_FCT(copy_dir);
|
API_FCT(copy_dir);
|
||||||
|
API_FCT(is_dir);
|
||||||
//API_FCT(extract_zip); //TODO remove dependency to GuiEngine
|
//API_FCT(extract_zip); //TODO remove dependency to GuiEngine
|
||||||
API_FCT(may_modify_path);
|
API_FCT(may_modify_path);
|
||||||
API_FCT(download_file);
|
API_FCT(download_file);
|
||||||
|
@ -112,6 +112,8 @@ private:
|
|||||||
|
|
||||||
static int l_get_mainmenu_path(lua_State *L);
|
static int l_get_mainmenu_path(lua_State *L);
|
||||||
|
|
||||||
|
static int l_get_user_path(lua_State *L);
|
||||||
|
|
||||||
static int l_get_modpath(lua_State *L);
|
static int l_get_modpath(lua_State *L);
|
||||||
|
|
||||||
static int l_get_clientmodpath(lua_State *L);
|
static int l_get_clientmodpath(lua_State *L);
|
||||||
@ -130,6 +132,8 @@ private:
|
|||||||
|
|
||||||
static int l_copy_dir(lua_State *L);
|
static int l_copy_dir(lua_State *L);
|
||||||
|
|
||||||
|
static int l_is_dir(lua_State *L);
|
||||||
|
|
||||||
static int l_extract_zip(lua_State *L);
|
static int l_extract_zip(lua_State *L);
|
||||||
|
|
||||||
static int l_may_modify_path(lua_State *L);
|
static int l_may_modify_path(lua_State *L);
|
||||||
@ -148,6 +152,8 @@ private:
|
|||||||
// other
|
// other
|
||||||
static int l_open_url(lua_State *L);
|
static int l_open_url(lua_State *L);
|
||||||
|
|
||||||
|
static int l_open_dir(lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
// async
|
// async
|
||||||
static int l_do_async_callback(lua_State *L);
|
static int l_do_async_callback(lua_State *L);
|
||||||
|
@ -110,7 +110,7 @@ int ObjectRef::l_remove(lua_State *L)
|
|||||||
sao->clearParentAttachment();
|
sao->clearParentAttachment();
|
||||||
|
|
||||||
verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl;
|
verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl;
|
||||||
sao->m_pending_removal = true;
|
sao->markForRemoval();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1409,7 +1409,7 @@ int ObjectRef::l_set_physics_override(lua_State *L)
|
|||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
ObjectRef *ref = checkobject(L, 1);
|
ObjectRef *ref = checkobject(L, 1);
|
||||||
PlayerSAO *playersao = (PlayerSAO *) getobject(ref);
|
PlayerSAO *playersao = getplayersao(ref);
|
||||||
if (playersao == nullptr)
|
if (playersao == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1449,7 +1449,7 @@ int ObjectRef::l_get_physics_override(lua_State *L)
|
|||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
ObjectRef *ref = checkobject(L, 1);
|
ObjectRef *ref = checkobject(L, 1);
|
||||||
PlayerSAO *playersao = (PlayerSAO *)getobject(ref);
|
PlayerSAO *playersao = getplayersao(ref);
|
||||||
if (playersao == nullptr)
|
if (playersao == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -239,15 +239,6 @@ int ModApiUtil::l_is_yes(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_nan(arg)
|
|
||||||
int ModApiUtil::l_is_nan(lua_State *L)
|
|
||||||
{
|
|
||||||
NO_MAP_LOCK_REQUIRED;
|
|
||||||
|
|
||||||
lua_pushboolean(L, isNaN(L, 1));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_builtin_path()
|
// get_builtin_path()
|
||||||
int ModApiUtil::l_get_builtin_path(lua_State *L)
|
int ModApiUtil::l_get_builtin_path(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -493,7 +484,6 @@ void ModApiUtil::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(get_password_hash);
|
API_FCT(get_password_hash);
|
||||||
|
|
||||||
API_FCT(is_yes);
|
API_FCT(is_yes);
|
||||||
API_FCT(is_nan);
|
|
||||||
|
|
||||||
API_FCT(get_builtin_path);
|
API_FCT(get_builtin_path);
|
||||||
|
|
||||||
@ -526,7 +516,6 @@ void ModApiUtil::InitializeClient(lua_State *L, int top)
|
|||||||
API_FCT(write_json);
|
API_FCT(write_json);
|
||||||
|
|
||||||
API_FCT(is_yes);
|
API_FCT(is_yes);
|
||||||
API_FCT(is_nan);
|
|
||||||
|
|
||||||
API_FCT(compress);
|
API_FCT(compress);
|
||||||
API_FCT(decompress);
|
API_FCT(decompress);
|
||||||
|
@ -65,9 +65,6 @@ private:
|
|||||||
// is_yes(arg)
|
// is_yes(arg)
|
||||||
static int l_is_yes(lua_State *L);
|
static int l_is_yes(lua_State *L);
|
||||||
|
|
||||||
// is_nan(arg)
|
|
||||||
static int l_is_nan(lua_State *L);
|
|
||||||
|
|
||||||
// get_builtin_path()
|
// get_builtin_path()
|
||||||
static int l_get_builtin_path(lua_State *L);
|
static int l_get_builtin_path(lua_State *L);
|
||||||
|
|
||||||
|
@ -2332,9 +2332,9 @@ void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
|
|||||||
/*
|
/*
|
||||||
Create a packet with the block in the right format
|
Create a packet with the block in the right format
|
||||||
*/
|
*/
|
||||||
|
thread_local const int net_compression_level = rangelim(g_settings->getS16("map_compression_level_net"), -1, 9);
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
block->serialize(os, ver, false);
|
block->serialize(os, ver, false, net_compression_level);
|
||||||
block->serializeNetworkSpecific(os);
|
block->serializeNetworkSpecific(os);
|
||||||
std::string s = os.str();
|
std::string s = os.str();
|
||||||
|
|
||||||
|
@ -127,6 +127,21 @@ void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActiveObjectMgr::getObjectsInArea(const aabb3f &box,
|
||||||
|
std::vector<ServerActiveObject *> &result,
|
||||||
|
std::function<bool(ServerActiveObject *obj)> include_obj_cb)
|
||||||
|
{
|
||||||
|
for (auto &activeObject : m_active_objects) {
|
||||||
|
ServerActiveObject *obj = activeObject.second;
|
||||||
|
const v3f &objectpos = obj->getBasePosition();
|
||||||
|
if (!box.isPointInside(objectpos))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!include_obj_cb || include_obj_cb(obj))
|
||||||
|
result.push_back(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius,
|
void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius,
|
||||||
f32 player_radius, std::set<u16> ¤t_objects,
|
f32 player_radius, std::set<u16> ¤t_objects,
|
||||||
std::queue<u16> &added_objects)
|
std::queue<u16> &added_objects)
|
||||||
|
@ -38,6 +38,9 @@ public:
|
|||||||
void getObjectsInsideRadius(const v3f &pos, float radius,
|
void getObjectsInsideRadius(const v3f &pos, float radius,
|
||||||
std::vector<ServerActiveObject *> &result,
|
std::vector<ServerActiveObject *> &result,
|
||||||
std::function<bool(ServerActiveObject *obj)> include_obj_cb);
|
std::function<bool(ServerActiveObject *obj)> include_obj_cb);
|
||||||
|
void getObjectsInArea(const aabb3f &box,
|
||||||
|
std::vector<ServerActiveObject *> &result,
|
||||||
|
std::function<bool(ServerActiveObject *obj)> include_obj_cb);
|
||||||
|
|
||||||
void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius,
|
void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius,
|
||||||
f32 player_radius, std::set<u16> ¤t_objects,
|
f32 player_radius, std::set<u16> ¤t_objects,
|
||||||
|
@ -112,6 +112,15 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaEntitySAO::dispatchScriptDeactivate()
|
||||||
|
{
|
||||||
|
// Ensure that this is in fact a registered entity,
|
||||||
|
// and that it isn't already gone.
|
||||||
|
// The latter also prevents this from ever being called twice.
|
||||||
|
if (m_registered && !isGone())
|
||||||
|
m_env->getScriptIface()->luaentity_Deactivate(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
void LuaEntitySAO::step(float dtime, bool send_recommended)
|
void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
{
|
{
|
||||||
if(!m_properties_sent)
|
if(!m_properties_sent)
|
||||||
@ -302,7 +311,7 @@ u16 LuaEntitySAO::punch(v3f dir,
|
|||||||
{
|
{
|
||||||
if (!m_registered) {
|
if (!m_registered) {
|
||||||
// Delete unknown LuaEntities when punched
|
// Delete unknown LuaEntities when punched
|
||||||
m_pending_removal = true;
|
markForRemoval();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +344,7 @@ u16 LuaEntitySAO::punch(v3f dir,
|
|||||||
clearParentAttachment();
|
clearParentAttachment();
|
||||||
clearChildAttachments();
|
clearChildAttachments();
|
||||||
m_env->getScriptIface()->luaentity_on_death(m_id, puncher);
|
m_env->getScriptIface()->luaentity_on_death(m_id, puncher);
|
||||||
m_pending_removal = true;
|
markForRemoval();
|
||||||
}
|
}
|
||||||
|
|
||||||
actionstream << puncher->getDescription() << " (id=" << puncher->getId() <<
|
actionstream << puncher->getDescription() << " (id=" << puncher->getId() <<
|
||||||
|
@ -71,6 +71,11 @@ public:
|
|||||||
bool getSelectionBox(aabb3f *toset) const;
|
bool getSelectionBox(aabb3f *toset) const;
|
||||||
bool collideWithObjects() const;
|
bool collideWithObjects() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dispatchScriptDeactivate();
|
||||||
|
virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(); }
|
||||||
|
virtual void onMarkedForRemoval() { dispatchScriptDeactivate(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string getPropertyPacket();
|
std::string getPropertyPacket();
|
||||||
void sendPosition(bool do_interpolate, bool is_movement_end);
|
void sendPosition(bool do_interpolate, bool is_movement_end);
|
||||||
|
@ -531,7 +531,7 @@ bool PlayerSAO::setWieldedItem(const ItemStack &item)
|
|||||||
void PlayerSAO::disconnected()
|
void PlayerSAO::disconnected()
|
||||||
{
|
{
|
||||||
m_peer_id = PEER_ID_INEXISTENT;
|
m_peer_id = PEER_ID_INEXISTENT;
|
||||||
m_pending_removal = true;
|
markForRemoval();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSAO::unlinkPlayerSessionAndSave()
|
void PlayerSAO::unlinkPlayerSessionAndSave()
|
||||||
|
@ -73,3 +73,19 @@ void ServerActiveObject::dumpAOMessagesToQueue(std::queue<ActiveObjectMessage> &
|
|||||||
m_messages_out.pop();
|
m_messages_out.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerActiveObject::markForRemoval()
|
||||||
|
{
|
||||||
|
if (!m_pending_removal) {
|
||||||
|
onMarkedForRemoval();
|
||||||
|
m_pending_removal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerActiveObject::markForDeactivation()
|
||||||
|
{
|
||||||
|
if (!m_pending_deactivation) {
|
||||||
|
onMarkedForDeactivation();
|
||||||
|
m_pending_deactivation = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -70,6 +70,10 @@ public:
|
|||||||
virtual bool environmentDeletes() const
|
virtual bool environmentDeletes() const
|
||||||
{ return true; }
|
{ return true; }
|
||||||
|
|
||||||
|
// Safely mark the object for removal or deactivation
|
||||||
|
void markForRemoval();
|
||||||
|
void markForDeactivation();
|
||||||
|
|
||||||
// Create a certain type of ServerActiveObject
|
// Create a certain type of ServerActiveObject
|
||||||
static ServerActiveObject* create(ActiveObjectType type,
|
static ServerActiveObject* create(ActiveObjectType type,
|
||||||
ServerEnvironment *env, u16 id, v3f pos,
|
ServerEnvironment *env, u16 id, v3f pos,
|
||||||
@ -213,25 +217,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
u16 m_known_by_count = 0;
|
u16 m_known_by_count = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
- Whether this object is to be removed when nobody knows about
|
|
||||||
it anymore.
|
|
||||||
- Removal is delayed to preserve the id for the time during which
|
|
||||||
it could be confused to some other object by some client.
|
|
||||||
- This is usually set to true by the step() method when the object wants
|
|
||||||
to be deleted but can be set by anything else too.
|
|
||||||
*/
|
|
||||||
bool m_pending_removal = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Same purpose as m_pending_removal but for deactivation.
|
|
||||||
deactvation = save static data in block, remove active object
|
|
||||||
|
|
||||||
If this is set alongside with m_pending_removal, removal takes
|
|
||||||
priority.
|
|
||||||
*/
|
|
||||||
bool m_pending_deactivation = false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A getter that unifies the above to answer the question:
|
A getter that unifies the above to answer the question:
|
||||||
"Can the environment still interact with this object?"
|
"Can the environment still interact with this object?"
|
||||||
@ -239,6 +224,9 @@ public:
|
|||||||
inline bool isGone() const
|
inline bool isGone() const
|
||||||
{ return m_pending_removal || m_pending_deactivation; }
|
{ return m_pending_removal || m_pending_deactivation; }
|
||||||
|
|
||||||
|
inline bool isPendingRemoval() const
|
||||||
|
{ return m_pending_removal; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Whether the object's static data has been stored to a block
|
Whether the object's static data has been stored to a block
|
||||||
*/
|
*/
|
||||||
@ -250,6 +238,9 @@ public:
|
|||||||
v3s16 m_static_block = v3s16(1337,1337,1337);
|
v3s16 m_static_block = v3s16(1337,1337,1337);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void onMarkedForDeactivation() {}
|
||||||
|
virtual void onMarkedForRemoval() {}
|
||||||
|
|
||||||
virtual void onAttach(int parent_id) {}
|
virtual void onAttach(int parent_id) {}
|
||||||
virtual void onDetach(int parent_id) {}
|
virtual void onDetach(int parent_id) {}
|
||||||
|
|
||||||
@ -257,6 +248,27 @@ protected:
|
|||||||
v3f m_base_position;
|
v3f m_base_position;
|
||||||
std::unordered_set<u32> m_attached_particle_spawners;
|
std::unordered_set<u32> m_attached_particle_spawners;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Same purpose as m_pending_removal but for deactivation.
|
||||||
|
deactvation = save static data in block, remove active object
|
||||||
|
|
||||||
|
If this is set alongside with m_pending_removal, removal takes
|
||||||
|
priority.
|
||||||
|
Note: Do not assign this directly, use markForDeactivation() instead.
|
||||||
|
*/
|
||||||
|
bool m_pending_deactivation = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Whether this object is to be removed when nobody knows about
|
||||||
|
it anymore.
|
||||||
|
- Removal is delayed to preserve the id for the time during which
|
||||||
|
it could be confused to some other object by some client.
|
||||||
|
- This is usually set to true by the step() method when the object wants
|
||||||
|
to be deleted but can be set by anything else too.
|
||||||
|
Note: Do not assign this directly, use markForRemoval() instead.
|
||||||
|
*/
|
||||||
|
bool m_pending_removal = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Queue of messages to be sent to the client
|
Queue of messages to be sent to the client
|
||||||
*/
|
*/
|
||||||
|
@ -1164,7 +1164,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode)
|
|||||||
|
|
||||||
// If known by some client, don't delete immediately
|
// If known by some client, don't delete immediately
|
||||||
if (obj->m_known_by_count > 0) {
|
if (obj->m_known_by_count > 0) {
|
||||||
obj->m_pending_removal = true;
|
obj->markForRemoval();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1792,7 +1792,7 @@ void ServerEnvironment::removeRemovedObjects()
|
|||||||
/*
|
/*
|
||||||
Delete static data from block if removed
|
Delete static data from block if removed
|
||||||
*/
|
*/
|
||||||
if (obj->m_pending_removal)
|
if (obj->isPendingRemoval())
|
||||||
deleteStaticFromBlock(obj, id, MOD_REASON_REMOVE_OBJECTS_REMOVE, false);
|
deleteStaticFromBlock(obj, id, MOD_REASON_REMOVE_OBJECTS_REMOVE, false);
|
||||||
|
|
||||||
// If still known by clients, don't actually remove. On some future
|
// If still known by clients, don't actually remove. On some future
|
||||||
@ -1803,7 +1803,7 @@ void ServerEnvironment::removeRemovedObjects()
|
|||||||
/*
|
/*
|
||||||
Move static data from active to stored if deactivated
|
Move static data from active to stored if deactivated
|
||||||
*/
|
*/
|
||||||
if (!obj->m_pending_removal && obj->m_static_exists) {
|
if (!obj->isPendingRemoval() && obj->m_static_exists) {
|
||||||
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
||||||
if (block) {
|
if (block) {
|
||||||
const auto i = block->m_static_objects.m_active.find(id);
|
const auto i = block->m_static_objects.m_active.find(id);
|
||||||
@ -1991,6 +1991,7 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete)
|
|||||||
if (!force_delete && obj->m_static_exists &&
|
if (!force_delete && obj->m_static_exists &&
|
||||||
!m_active_blocks.contains(obj->m_static_block) &&
|
!m_active_blocks.contains(obj->m_static_block) &&
|
||||||
m_active_blocks.contains(blockpos_o)) {
|
m_active_blocks.contains(blockpos_o)) {
|
||||||
|
|
||||||
// Delete from block where object was located
|
// Delete from block where object was located
|
||||||
deleteStaticFromBlock(obj, id, MOD_REASON_STATIC_DATA_REMOVED, false);
|
deleteStaticFromBlock(obj, id, MOD_REASON_STATIC_DATA_REMOVED, false);
|
||||||
|
|
||||||
@ -2068,6 +2069,10 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete)
|
|||||||
force_delete = true;
|
force_delete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regardless of what happens to the object at this point, deactivate it first.
|
||||||
|
// This ensures that LuaEntity on_deactivate is always called.
|
||||||
|
obj->markForDeactivation();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If known by some client, set pending deactivation.
|
If known by some client, set pending deactivation.
|
||||||
Otherwise delete it immediately.
|
Otherwise delete it immediately.
|
||||||
@ -2077,7 +2082,6 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete)
|
|||||||
<< "object id=" << id << " is known by clients"
|
<< "object id=" << id << " is known by clients"
|
||||||
<< "; not deleting yet" << std::endl;
|
<< "; not deleting yet" << std::endl;
|
||||||
|
|
||||||
obj->m_pending_deactivation = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,6 +332,13 @@ public:
|
|||||||
return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb);
|
return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find all active objects inside a box
|
||||||
|
void getObjectsInArea(std::vector<ServerActiveObject *> &objects, const aabb3f &box,
|
||||||
|
std::function<bool(ServerActiveObject *obj)> include_obj_cb)
|
||||||
|
{
|
||||||
|
return m_ao_manager.getObjectsInArea(box, objects, include_obj_cb);
|
||||||
|
}
|
||||||
|
|
||||||
// Clear objects, loading and going through every MapBlock
|
// Clear objects, loading and going through every MapBlock
|
||||||
void clearObjects(ClearObjectsMode mode);
|
void clearObjects(ClearObjectsMode mode);
|
||||||
|
|
||||||
|
@ -1015,10 +1015,10 @@ void srp_user_process_challenge(struct SRPUser *usr,
|
|||||||
goto cleanup_and_exit;
|
goto cleanup_and_exit;
|
||||||
|
|
||||||
*bytes_M = usr->M;
|
*bytes_M = usr->M;
|
||||||
if (len_M) *len_M = hash_length(usr->hash_alg);
|
*len_M = hash_length(usr->hash_alg);
|
||||||
} else {
|
} else {
|
||||||
*bytes_M = NULL;
|
*bytes_M = NULL;
|
||||||
if (len_M) *len_M = 0;
|
*len_M = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_and_exit:
|
cleanup_and_exit:
|
||||||
|
@ -633,7 +633,7 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color
|
|||||||
color_name = value;
|
color_name = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
color_name = lowercase(value);
|
color_name = lowercase(color_name);
|
||||||
|
|
||||||
std::map<const std::string, unsigned>::const_iterator it;
|
std::map<const std::string, unsigned>::const_iterator it;
|
||||||
it = named_colors.colors.find(color_name);
|
it = named_colors.colors.find(color_name);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user