Merge remote-tracking branch 'origin/master' into physics-tweaks
This commit is contained in:
commit
b4a4de74bb
21
.travis.yml
21
.travis.yml
@ -5,6 +5,9 @@
|
||||
#
|
||||
sudo: false
|
||||
language: cpp
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
@ -40,21 +43,17 @@ addons:
|
||||
- zlib1g-dev
|
||||
|
||||
before_script:
|
||||
# Unfortunately using all threads crashes g++: "g++: internal compiler error: Killed (program cc1plus)"
|
||||
# Use half of the available threads, gcc is memory hungry
|
||||
- 'if [ ${CC} = "gcc" ]; then
|
||||
export THREADS=$((`nproc` / 2));
|
||||
else
|
||||
export THREADS=$((`nproc` + 1));
|
||||
fi'
|
||||
- echo "THREADS = $THREADS"
|
||||
- free -mt
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew bundle; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo mkdir -p /usr/local/include/; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo ln -s /System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/ /usr/local/include/GL; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CMAKE_PREFIX_PATH=/usr/local/opt/freetype/:/usr/local/opt/curl/:/usr/local/opt/libogg/:/usr/local/opt/libogg/:/usr/local/opt/libvorbis/:/usr/local/opt/openssl\@1.1/:/usr/local/opt/glew/:/usr/local/opt/fribidi/; fi
|
||||
|
||||
script:
|
||||
- mkdir "build"
|
||||
- cd "build"
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSERVER_ONLY=$SERVER_ONLY -DCHECK_ASSETS=off -DBUILD_RECORDER=off
|
||||
- make VERBOSE=1 -j $THREADS
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then /usr/local/opt/cmake/bin/cmake .. -DFREETYPE_INCLUDE_DIRS=/usr/local/opt/freetype/include/freetype2/ -DUSE_SYSTEM_GLEW=1 -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include/ -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DFREETYPE_LIBRARY=/usr/local/opt/freetype/lib/libfreetype.dylib -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSERVER_ONLY=$SERVER_ONLY -DCHECK_ASSETS=off -DBUILD_RECORDER=off; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSERVER_ONLY=$SERVER_ONLY -DCHECK_ASSETS=off -DBUILD_RECORDER=off; fi
|
||||
- make VERBOSE=1 -j3
|
||||
|
||||
notifications:
|
||||
irc:
|
||||
|
8
Brewfile
Normal file
8
Brewfile
Normal file
@ -0,0 +1,8 @@
|
||||
brew "libogg"
|
||||
brew "libvorbis"
|
||||
brew "openal-soft"
|
||||
brew "freetype"
|
||||
brew "curl"
|
||||
brew "openssl@1.1"
|
||||
brew "fribidi"
|
||||
brew "glew"
|
137
CMakeLists.txt
137
CMakeLists.txt
@ -19,7 +19,6 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
endif()
|
||||
|
||||
option(SERVER_ONLY "Create a server only (i.e. no graphics or sound)" OFF)
|
||||
option(USE_FRIBIDI "Support for right-to-left languages" ON)
|
||||
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
|
||||
option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
|
||||
option(USE_SYSTEM_ENET "Use system ENET instead of the built-in version, when available." ON)
|
||||
@ -27,6 +26,10 @@ option(USE_SYSTEM_GLEW "Use system GLEW instead of the built-in version, when av
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(BUILD_RECORDER "Build opengl recorder" ON
|
||||
"NOT SERVER_ONLY;NOT APPLE" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(USE_FRIBIDI "Support for right-to-left languages" ON
|
||||
"NOT SERVER_ONLY" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(USE_WIIUSE "Support for wiimote input devices" ON
|
||||
"NOT SERVER_ONLY;NOT MINGW;NOT CYGWIN" OFF)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND CMAKE_PREFIX_PATH /usr/local/opt)
|
||||
@ -62,12 +65,6 @@ else()
|
||||
set(WIIUSE_BUILD ON)
|
||||
endif()
|
||||
|
||||
if(MINGW OR CYGWIN OR SERVER_ONLY)
|
||||
option(USE_WIIUSE "Support for wiimote input devices" OFF)
|
||||
else()
|
||||
option(USE_WIIUSE "Support for wiimote input devices" ON)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(USE_ASAN "Build with Leak/Address sanitizer" OFF)
|
||||
option(USE_LIBBFD "Use libbfd for crash reporting and leak check" OFF)
|
||||
@ -125,13 +122,9 @@ endif()
|
||||
|
||||
if(SERVER_ONLY)
|
||||
add_definitions(-DSERVER_ONLY)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_X11_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_X11_ -DNO_IRR_COMPILE_WITH_OPENGL_ -DNO_IRR_COMPILE_WITH_OSX_DEVICE_)
|
||||
endif()
|
||||
|
||||
#if(DISABLE_VPX)
|
||||
# add_definitions(-DNO_VPX)
|
||||
#endif()
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
if(DEBUG_SYMBOLS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
|
||||
@ -139,22 +132,30 @@ if(UNIX OR MINGW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
if(NOT PKGCONFIG_FOUND)
|
||||
message(FATAL_ERROR "Pkg-config not found.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Build the Bullet physics library
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/bullet")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/bullet/src")
|
||||
|
||||
# Find system ENet library or build it if missing
|
||||
if((UNIX AND NOT APPLE) AND USE_SYSTEM_ENET)
|
||||
find_package(ENet)
|
||||
pkg_check_modules(ENET libenet>=1.3.4)
|
||||
endif()
|
||||
|
||||
if(ENET_FOUND)
|
||||
include_directories(${ENet_INCLUDE_DIRS})
|
||||
include_directories(${ENET_INCLUDE_DIRS})
|
||||
else()
|
||||
# Fallback to built-in version
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/enet")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/enet/include")
|
||||
set(ENet_LIBRARIES "enet")
|
||||
set(ENET_LIBRARIES "enet")
|
||||
endif()
|
||||
|
||||
# Find system GLEW library or build it if missing
|
||||
@ -167,10 +168,7 @@ if (APPLE)
|
||||
elseif(NOT USE_GLES2 AND NOT SERVER_ONLY)
|
||||
add_definitions(-DGLEW_NO_GLU)
|
||||
if((UNIX AND NOT APPLE) AND USE_SYSTEM_GLEW)
|
||||
find_package(PkgConfig)
|
||||
if(PKGCONFIG_FOUND)
|
||||
pkg_check_modules(GLEW glew>=2.1)
|
||||
endif()
|
||||
pkg_check_modules(GLEW glew>=2.1)
|
||||
endif()
|
||||
|
||||
if(GLEW_FOUND)
|
||||
@ -183,37 +181,39 @@ elseif(NOT USE_GLES2 AND NOT SERVER_ONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC OR APPLE)
|
||||
if (NOT APPLE)
|
||||
if(MSVC)
|
||||
# Build zlib library
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/zlib")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/zlib")
|
||||
|
||||
set(ZLIB_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lib/zlib" "${PROJECT_BINARY_DIR}/lib/zlib/")
|
||||
set(ZLIB_LIBRARY zlibstatic)
|
||||
endif()
|
||||
|
||||
# Build png library
|
||||
set(SKIP_INSTALL_ALL TRUE)
|
||||
set(PNG_STATIC TRUE CACHE BOOL "Build static lib")
|
||||
set(PNG_TESTS FALSE CACHE BOOL "Build libpng tests")
|
||||
set(PNG_SHARED FALSE CACHE BOOL "Build shared lib")
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/libpng")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/libpng")
|
||||
|
||||
set(PNG_PNG_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lib/libpng/")
|
||||
set(PNG_LIBRARY png_static)
|
||||
endif()
|
||||
|
||||
# Add jpeg library
|
||||
if (APPLE)
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/jpeglib")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/jpeglib")
|
||||
set(JPEG_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lib/jpeglib/")
|
||||
set(JPEG_LIBRARY jpeglib)
|
||||
else()
|
||||
find_package(JPEG REQUIRED)
|
||||
include_directories(${JPEG_INCLUDE_DIR})
|
||||
if (NOT SERVER_ONLY)
|
||||
if(MSVC OR APPLE)
|
||||
# Build png library
|
||||
set(SKIP_INSTALL_ALL TRUE)
|
||||
set(PNG_STATIC TRUE CACHE BOOL "Build static lib")
|
||||
set(PNG_TESTS FALSE CACHE BOOL "Build libpng tests")
|
||||
set(PNG_SHARED FALSE CACHE BOOL "Build shared lib")
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/libpng")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/libpng")
|
||||
|
||||
set(PNG_PNG_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lib/libpng/")
|
||||
set(PNG_LIBRARY png_static)
|
||||
endif()
|
||||
|
||||
# Add jpeg library
|
||||
if (APPLE)
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/jpeglib")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/jpeglib")
|
||||
set(JPEG_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lib/jpeglib/")
|
||||
set(JPEG_LIBRARY jpeglib)
|
||||
else()
|
||||
find_package(JPEG REQUIRED)
|
||||
include_directories(${JPEG_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (BUILD_RECORDER)
|
||||
@ -297,21 +297,27 @@ else()
|
||||
set(Angelscript_LIBRARIES angelscript)
|
||||
endif()
|
||||
|
||||
# OpenAL
|
||||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
if(NOT SERVER_ONLY)
|
||||
# OpenAL
|
||||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
|
||||
# OggVorbis
|
||||
find_package(OggVorbis REQUIRED)
|
||||
include_directories(${OGGVORBIS_INCLUDE_DIRS})
|
||||
# OggVorbis
|
||||
find_package(OggVorbis REQUIRED)
|
||||
include_directories(${OGGVORBIS_INCLUDE_DIRS})
|
||||
|
||||
add_definitions(-DENABLE_SOUND)
|
||||
endif()
|
||||
|
||||
# Freetype
|
||||
find_package(Freetype)
|
||||
if(FREETYPE_FOUND)
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||
else()
|
||||
message(FATAL_ERROR "Freetype not found. "
|
||||
"Freetype is required to display characters in SuperTuxKart. ")
|
||||
if (NOT SERVER_ONLY)
|
||||
find_package(Freetype)
|
||||
if(FREETYPE_FOUND)
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||
else()
|
||||
message(FATAL_ERROR "Freetype not found. "
|
||||
"Freetype is required to display characters in SuperTuxKart. ")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Fribidi
|
||||
@ -380,8 +386,6 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# TODO: remove this switch
|
||||
add_definitions(-DHAVE_OGGVORBIS)
|
||||
|
||||
if(WIN32)
|
||||
configure_file("${STK_SOURCE_DIR}/../tools/windows_installer/icon_rc.template" "${PROJECT_BINARY_DIR}/tmp/icon.rc")
|
||||
@ -405,16 +409,10 @@ if(APPLE)
|
||||
add_executable(supertuxkart MACOSX_BUNDLE ${STK_SOURCES})
|
||||
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(QUICKTIME_LIBRARY QuickTime)
|
||||
find_library(CARBON_LIBRARY Carbon)
|
||||
find_library(AUDIOUNIT_LIBRARY AudioUnit)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
|
||||
target_link_libraries(supertuxkart
|
||||
${IOKIT_LIBRARY}
|
||||
${QUICKTIME_LIBRARY}
|
||||
${CARBON_LIBRARY}
|
||||
${AUDIOUNIT_LIBRARY}
|
||||
${COCOA_LIBRARY})
|
||||
|
||||
# configure CMake to use a custom Info.plist
|
||||
@ -481,15 +479,10 @@ target_link_libraries(supertuxkart
|
||||
bulletdynamics
|
||||
bulletcollision
|
||||
bulletmath
|
||||
${ENet_LIBRARIES}
|
||||
${ENET_LIBRARIES}
|
||||
stkirrlicht
|
||||
${Angelscript_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${OGGVORBIS_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
${FREETYPE_LIBRARIES}
|
||||
${JPEG_LIBRARIES}
|
||||
${TURBOJPEG_LIBRARY}
|
||||
${OPENSSL_CRYPTO_LIBRARY}
|
||||
)
|
||||
|
||||
@ -500,7 +493,13 @@ if(NOT SERVER_ONLY)
|
||||
target_link_libraries(supertuxkart GLESv2)
|
||||
endif()
|
||||
|
||||
target_link_libraries(supertuxkart ${SQUISH_LIBRARY} graphics_utils)
|
||||
target_link_libraries(supertuxkart
|
||||
${SQUISH_LIBRARY}
|
||||
${FREETYPE_LIBRARIES}
|
||||
${JPEG_LIBRARIES}
|
||||
${OGGVORBIS_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
graphics_utils)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
@ -195,20 +195,19 @@ Build STK
|
||||
```bash
|
||||
mkdir cmake_build
|
||||
cd cmake_build
|
||||
CMAKE_PREFIX_PATH=/usr/local/opt/freetype/:/usr/local/opt/curl/:/usr/local/opt/libogg/:/usr/local/opt/libogg/:/usr/local/opt/libvorbis/:/usr/local/opt/openssl\@1.1/:/usr/local/opt/glew/:/usr/local/opt/fribidi/ /usr/local/opt/cmake/bin/cmake .. -DFREETYPE_INCLUDE_DIRS=/usr/local/opt/freetype/include/freetype2/ -DUSE_SYSTEM_GLEW=1 -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include/ -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib
|
||||
CMAKE_PREFIX_PATH=/usr/local/opt/freetype/:/usr/local/opt/curl/:/usr/local/opt/libogg/:/usr/local/opt/libogg/:/usr/local/opt/libvorbis/:/usr/local/opt/openssl\@1.1/:/usr/local/opt/glew/:/usr/local/opt/fribidi/ /usr/local/opt/cmake/bin/cmake .. -DFREETYPE_INCLUDE_DIRS=/usr/local/opt/freetype/include/freetype2/ -DUSE_SYSTEM_GLEW=1 -DOPENAL_INCLUDE_DIR=/usr/local/opt/openal-soft/include/ -DOPENAL_LIBRARY=/usr/local/opt/openal-soft/lib/libopenal.dylib -DFREETYPE_LIBRARY=/usr/local/opt/freetype/lib/libfreetype.dylib
|
||||
make
|
||||
```
|
||||
|
||||
#### (Optional) packaging for distribution
|
||||
|
||||
By default, the executable that is produced is not ready for distribution. Install https://github.com/auriamg/macdylibbundler
|
||||
By default, the executable that is produced is not ready for distribution. Install https://github.com/auriamg/macdylibbundler and run:
|
||||
|
||||
```bash
|
||||
dylibbundler -od -b -x ./bin/SuperTuxKart.app/Contents/MacOS/supertuxkart -d ./bin/SuperTuxKart.app/Contents/libs/ -p @executable_path/../libs/
|
||||
```
|
||||
|
||||
then copy the datafiles into /SuperTuxKart.app/Contents/Resources/data
|
||||
|
||||
Afterwards, copy the contents of `stk-assets` into `/SuperTuxKart.app/Contents/Resources/data`.
|
||||
|
||||
### STK 0.9.3 or earlier
|
||||
|
||||
|
@ -161,7 +161,7 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \
|
||||
-Iobj/openssl/include \
|
||||
-I$(call my-dir)/../../sources/android/native_app_glue \
|
||||
-DUSE_GLES2 \
|
||||
-DHAVE_OGGVORBIS \
|
||||
-DENABLE_SOUND \
|
||||
-DNDEBUG \
|
||||
-DANDROID_PACKAGE_NAME=\"$(PACKAGE_NAME)\" \
|
||||
-DANDROID_APP_DIR_NAME=\"$(APP_DIR_NAME)\" \
|
||||
|
@ -77,12 +77,12 @@ check_error()
|
||||
|
||||
# Handle clean command
|
||||
if [ ! -z "$1" ] && [ "$1" = "clean" ]; then
|
||||
rm -rf bin
|
||||
rm -rf build
|
||||
rm -rf libs
|
||||
rm -rf obj
|
||||
rm -rf res
|
||||
rm -rf .gradle
|
||||
rm -rf "$DIRNAME/bin"
|
||||
rm -rf "$DIRNAME/build"
|
||||
rm -rf "$DIRNAME/libs"
|
||||
rm -rf "$DIRNAME/obj"
|
||||
rm -rf "$DIRNAME/res"
|
||||
rm -rf "$DIRNAME/.gradle"
|
||||
exit
|
||||
fi
|
||||
|
||||
@ -271,9 +271,6 @@ if [ -d "$DIRNAME/assets/data" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$PROJECT_VERSION" > "$DIRNAME/obj/project_version"
|
||||
|
||||
|
||||
# Standalone toolchain
|
||||
if [ ! -f "$DIRNAME/obj/make_standalone_toolchain.stamp" ]; then
|
||||
echo "Creating standalone toolchain"
|
||||
@ -287,6 +284,8 @@ if [ ! -f "$DIRNAME/obj/make_standalone_toolchain.stamp" ]; then
|
||||
echo $COMPILE_ARCH > "$DIRNAME/obj/compile_arch"
|
||||
fi
|
||||
|
||||
echo "$PROJECT_VERSION" > "$DIRNAME/obj/project_version"
|
||||
|
||||
# Freetype
|
||||
if [ ! -f "$DIRNAME/obj/freetype.stamp" ]; then
|
||||
echo "Compiling freetype"
|
||||
|
@ -1,48 +0,0 @@
|
||||
# - Try to find enet
|
||||
# Once done this will define
|
||||
#
|
||||
# ENET_FOUND - system has enet
|
||||
# ENet_INCLUDE_DIRS - the enet include directory
|
||||
# ENet_LIBRARIES - the libraries needed to use enet
|
||||
#
|
||||
# $ENETDIR is an environment variable used for finding enet.
|
||||
#
|
||||
# Borrowed from The Mana World
|
||||
# http://themanaworld.org/
|
||||
#
|
||||
# Several changes and additions by Fabian 'x3n' Landau
|
||||
# Lots of simplifications by Adrian Friedli
|
||||
# > www.orxonox.net <
|
||||
|
||||
FIND_PATH(ENet_INCLUDE_DIRS enet/enet.h
|
||||
PATHS
|
||||
$ENV{ENETDIR}
|
||||
/usr/local
|
||||
/usr
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(ENet_LIBRARY
|
||||
NAMES enet
|
||||
PATHS
|
||||
$ENV{ENETDIR}
|
||||
/usr/local
|
||||
/usr
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set ENET_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ENet DEFAULT_MSG ENet_LIBRARY ENet_INCLUDE_DIRS)
|
||||
|
||||
IF (ENET_FOUND)
|
||||
IF(WIN32)
|
||||
SET(WINDOWS_ENET_DEPENDENCIES "ws2_32;winmm")
|
||||
SET(ENet_LIBRARIES ${ENet_LIBRARY} ${WINDOWS_ENET_DEPENDENCIES})
|
||||
ELSE(WIN32)
|
||||
SET(ENet_LIBRARIES ${ENet_LIBRARY})
|
||||
ENDIF(WIN32)
|
||||
ENDIF (ENET_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(ENet_LIBRARY ENet_LIBRARIES ENet_INCLUDE_DIRS)
|
@ -25,6 +25,7 @@
|
||||
<card contains="Gallium" os="linux" version="<10.3" disable="DriverRecentEnough"/>
|
||||
<card contains="Gallium" os="linux" version="<11.2" disable="GeometryShader"/>
|
||||
<card contains="Gallium" os="linux" version="<11.2" disable="TextureCompressionS3TC"/>
|
||||
<card vendor="nouveau" os="linux" version=">=17.2" disable="TextureBufferObject"/>
|
||||
<!-- On osx radeon appears to have different version numbers, e.g.
|
||||
1.32.20 -->
|
||||
<card contains="Radeon" os="linux" version="<14.300" disable="DriverRecentEnough"/>
|
||||
|
@ -27,13 +27,13 @@
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<label align="center" text="SuperTuxKart can be played in multiplayer mode online...:"/>
|
||||
<label align="center" I18N="In the help menu" text="SuperTuxKart can be played in multiplayer mode online...:"/>
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/networking_icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="First, select the 'online' icon in the main menu. Choose either local networking, or global networking (requires internet to be enabled in the options). Then, you can either create your own server with custom options, or search among a list of existing servers to join. Some of them are official servers with ranked races."/>
|
||||
text="First, select the 'online' icon in the main menu. Choose either local networking, or global networking (requires internet to be enabled in the options). Then, you can either create your own server with custom options, or search among a list of existing servers to join. Some of them are official servers with optionally ranked races."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
@ -41,10 +41,10 @@
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Once in a server, a race will begin once its owner (symbolized with the crown) decide so. Official servers auto-start races when there is enough players. Then, you can choose your kart and vote for the next track to race on. An addon kart or track is allowed only if all players connected to the server have it."/>
|
||||
text="Once in a server, a race will begin once its owner (symbolized with the crown) decides so. Official servers may auto-start races only when there are enough players. Then, you can choose your kart and vote for the next track to race on. An addon kart or track is allowed only if it exists on all joinned players and the server."/>
|
||||
</div>
|
||||
|
||||
<label align="center" text="... or on the same computer:"/>
|
||||
<label align="center" I18N="In the help menu" text="... or on the same computer:"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/options_input.png"/>
|
||||
|
@ -1,236 +1,236 @@
|
||||
aa=ʿAfár af
|
||||
af=Afrikaans
|
||||
af_ZA=0
|
||||
am=ኣማርኛ
|
||||
ar=العربية
|
||||
ar_AR=0
|
||||
ar_OM=0
|
||||
ar_SA=0
|
||||
ar_SY=0
|
||||
ar_TN=0
|
||||
as=অসমীয়া
|
||||
ast=Asturianu
|
||||
ay=Aymar aru
|
||||
az=Azərbaycanca
|
||||
az_IR=0
|
||||
be=Беларуская мова
|
||||
bg=български
|
||||
bg_BG=0
|
||||
bn=বাংলা
|
||||
bn_BD=0
|
||||
bn_IN=0
|
||||
bo=བོད་སྐད་
|
||||
br=Brezhoneg
|
||||
bs=Bosanski
|
||||
bs_BA=0
|
||||
bs_BS=0
|
||||
ca_ES=0
|
||||
ca=0
|
||||
cmn=0
|
||||
co=Corsu
|
||||
cs=Čeština
|
||||
cs_CZ=Čeština (Česká Republika)
|
||||
cy=Welsh
|
||||
cy_GB=Welsh (Great Britain)
|
||||
cz=Unknown language
|
||||
da=Dansk
|
||||
da_DK=Dansk (Danmark)
|
||||
de=Deutsch
|
||||
de_AT=Deutsch (Österreich)
|
||||
de_CH=Deutsch (Schweiz)
|
||||
de_DE=Deutsch (Deutschland)
|
||||
dk=Unknown language
|
||||
dz=རྫོང་ཁ
|
||||
el=ελληνικά
|
||||
el_GR=0
|
||||
en=English
|
||||
en_AU=English (Australia)
|
||||
en_CA=English (Canada)
|
||||
en_GB=English (Great Britain)
|
||||
en_US=English (United States)
|
||||
en_ZA=English (South Africa)
|
||||
en_US=English
|
||||
eo=Esperanto
|
||||
es=Español
|
||||
es_AR=0
|
||||
es_CL=0
|
||||
es_CO=0
|
||||
es_CR=0
|
||||
es_DO=0
|
||||
es_EC=0
|
||||
es_ES=0
|
||||
es_GT=0
|
||||
es_HN=0
|
||||
es_LA=0
|
||||
es_MX=0
|
||||
es_NI=0
|
||||
es_PA=0
|
||||
es_PE=0
|
||||
es_PR=0
|
||||
es_SV=0
|
||||
es_UY=0
|
||||
es_VE=0
|
||||
et=Eesti keel
|
||||
et_EE=0
|
||||
et_ET=0
|
||||
eu=Euskara
|
||||
eu_ES=0
|
||||
fa=فارسى
|
||||
fa_AF=0
|
||||
fa_IR=0
|
||||
fi=Suomi
|
||||
fi_FI=0
|
||||
fo=Føroyskt
|
||||
fo_FO=0
|
||||
fr=Français
|
||||
fr_CA=Français (Canada)
|
||||
fr_CH=Français (Suisse)
|
||||
fr_FR=Français (France)
|
||||
fr_LU=Français (Luxembourg)
|
||||
fy=Frysk
|
||||
ga=Gaeilge
|
||||
gd=Gàidhlig
|
||||
gl=Galego
|
||||
gl_ES=0
|
||||
gn=Avañe'ẽ
|
||||
gu=ગુજરાતી
|
||||
gv=Gaelg
|
||||
ha=حَوْسَ
|
||||
he=עברית
|
||||
he_IL=0
|
||||
hi=हिन्दी
|
||||
hr=Hrvatski
|
||||
hr_HR=0
|
||||
hu=Magyar
|
||||
hu_HU=0
|
||||
hy=Հայերեն
|
||||
ia=Interlingua
|
||||
id=Bahasa Indonesia
|
||||
id_ID=0
|
||||
is=Íslenska
|
||||
is_IS=0
|
||||
it=Italiano
|
||||
it_CH=0
|
||||
it_IT=0
|
||||
iu=ᐃᓄᒃᑎᑐᑦ/inuktitut
|
||||
ja=日本語
|
||||
ja_JP=0
|
||||
ka=ქართული
|
||||
kk=Қазақша
|
||||
kl=Kalaallisut
|
||||
km=ភាសាខ្មែរ
|
||||
km_KH=0
|
||||
kn=ಕನ್ನಡ
|
||||
ko=한국어
|
||||
ko_KR=0
|
||||
krl=Karjalan kieli
|
||||
ku=Kurdî
|
||||
kw=Kernowek
|
||||
ky=кыргызча
|
||||
la=Latina
|
||||
lo=ລາວ
|
||||
lt=Lietuvių
|
||||
lt=0
|
||||
lv=Latviešu
|
||||
lv_LV=0
|
||||
jbo=La .lojban.
|
||||
mg=Malagasy
|
||||
mi=Māori
|
||||
mk=Македонски
|
||||
mk_MK=0
|
||||
ml=മലയാളം
|
||||
mn=Монгол
|
||||
mn_MN=Монгол
|
||||
mr=मराठी
|
||||
ms=Bahasa Melayu
|
||||
ms_MY=0
|
||||
mt=Malti
|
||||
my=မြန်မာဘာသာ
|
||||
my_MM=0
|
||||
nb=0
|
||||
nb_NO=0
|
||||
ne=0
|
||||
nl=Nederlands
|
||||
nl_BE=0
|
||||
nl_NL=0
|
||||
nn=Norsk nynorsk
|
||||
nn_NO=0
|
||||
no=Norsk bokmål
|
||||
no_NO=0
|
||||
no_NY=0
|
||||
nr=0
|
||||
oc=Occitan
|
||||
om=Oromoo
|
||||
or=ଓଡ଼ିଆ
|
||||
os=0
|
||||
pa=ਪੰਜਾਬੀ
|
||||
pl=Polski
|
||||
pl_PL=0
|
||||
pms=Piemontèis
|
||||
ps=پښتو
|
||||
pt=Português
|
||||
pt_BR=0
|
||||
pt_PT=0
|
||||
qu=Runa Simi
|
||||
rm=Rumantsch
|
||||
ro=Română
|
||||
ro_RO=0
|
||||
ru=Русский
|
||||
ru_RU=0
|
||||
rw=Kinyarwanda
|
||||
sa=0
|
||||
sc=Sardu
|
||||
sco=0
|
||||
sd=0
|
||||
se=Sámegiella
|
||||
se_NO=0
|
||||
si=0
|
||||
sk=Slovenčina
|
||||
sk_SK=0
|
||||
sl=Slovenščina
|
||||
sl_SI=0
|
||||
sl_SL=0
|
||||
sm=0
|
||||
so=0
|
||||
sp=0
|
||||
sq=Shqip
|
||||
sq_AL=0
|
||||
sr=Српски
|
||||
sr_YU=0
|
||||
ss=0
|
||||
st=0
|
||||
sv=Svenska
|
||||
sv_SE=0
|
||||
sv_SV=0
|
||||
sw=0
|
||||
ta=தமிழ்
|
||||
te=0
|
||||
tg=0
|
||||
th=ไทย
|
||||
th_TH=0
|
||||
ti=0
|
||||
tk=0
|
||||
tl=0
|
||||
to=0
|
||||
tr=Türkçe
|
||||
tr_TR=0
|
||||
ts=0
|
||||
tt=Татарча
|
||||
ug=0
|
||||
uk=Українська
|
||||
uk_UA=0
|
||||
ur=اردو
|
||||
ur_PK=0
|
||||
uz=0
|
||||
vi=Tiếng Việt
|
||||
vi_VN=0
|
||||
wa=0
|
||||
wo=0
|
||||
xh=0
|
||||
yi=ייִדיש
|
||||
yo=0
|
||||
zh=中文
|
||||
zh_CN=中文(简体)
|
||||
zh_HK=中文(香港)
|
||||
zh_TW=中文(繁體)
|
||||
zu=0
|
||||
aa=ʿAfár af;
|
||||
af=Afrikaans;
|
||||
af_ZA=0;
|
||||
am=ኣማርኛ;
|
||||
ar=العربية;
|
||||
ar_AR=0;
|
||||
ar_OM=0;
|
||||
ar_SA=0;
|
||||
ar_SY=0;
|
||||
ar_TN=0;
|
||||
as=অসমীয়া;
|
||||
ast=Asturianu;
|
||||
ay=Aymar aru;
|
||||
az=Azərbaycanca;
|
||||
az_IR=0;
|
||||
be=Беларуская мова;
|
||||
bg=български;
|
||||
bg_BG=0;
|
||||
bn=বাংলা;
|
||||
bn_BD=0;
|
||||
bn_IN=0;
|
||||
bo=བོད་སྐད་;
|
||||
br=Brezhoneg;
|
||||
bs=Bosanski;
|
||||
bs_BA=0;
|
||||
bs_BS=0;
|
||||
ca_ES=0;
|
||||
ca=0;
|
||||
cmn=0;
|
||||
co=Corsu;
|
||||
cs=Čeština;
|
||||
cs_CZ=Čeština (Česká Republika);
|
||||
cy=Welsh;
|
||||
cy_GB=Welsh (Great Britain);
|
||||
cz=Unknown language;
|
||||
da=Dansk;
|
||||
da_DK=Dansk (Danmark);
|
||||
de=Deutsch;
|
||||
de_AT=Deutsch (Österreich);
|
||||
de_CH=Deutsch (Schweiz);
|
||||
de_DE=Deutsch (Deutschland);
|
||||
dk=Unknown language;
|
||||
dz=རྫོང་ཁ;
|
||||
el=ελληνικά;
|
||||
el_GR=0;
|
||||
en=English;
|
||||
en_AU=English (Australia);
|
||||
en_CA=English (Canada);
|
||||
en_GB=English (Great Britain);
|
||||
en_US=English (United States);
|
||||
en_ZA=English (South Africa);
|
||||
en_US=English;
|
||||
eo=Esperanto;
|
||||
es=Español;
|
||||
es_AR=0;
|
||||
es_CL=0;
|
||||
es_CO=0;
|
||||
es_CR=0;
|
||||
es_DO=0;
|
||||
es_EC=0;
|
||||
es_ES=0;
|
||||
es_GT=0;
|
||||
es_HN=0;
|
||||
es_LA=0;
|
||||
es_MX=0;
|
||||
es_NI=0;
|
||||
es_PA=0;
|
||||
es_PE=0;
|
||||
es_PR=0;
|
||||
es_SV=0;
|
||||
es_UY=0;
|
||||
es_VE=0;
|
||||
et=Eesti keel;
|
||||
et_EE=0;
|
||||
et_ET=0;
|
||||
eu=Euskara;
|
||||
eu_ES=0;
|
||||
fa=فارسى;
|
||||
fa_AF=0;
|
||||
fa_IR=0;
|
||||
fi=Suomi;
|
||||
fi_FI=0;
|
||||
fo=Føroyskt;
|
||||
fo_FO=0;
|
||||
fr=Français;
|
||||
fr_CA=Français (Canada);
|
||||
fr_CH=Français (Suisse);
|
||||
fr_FR=Français (France);
|
||||
fr_LU=Français (Luxembourg);
|
||||
fy=Frysk;
|
||||
ga=Gaeilge;
|
||||
gd=Gàidhlig;
|
||||
gl=Galego;
|
||||
gl_ES=0;
|
||||
gn=Avañe'ẽ;
|
||||
gu=ગુજરાતી;
|
||||
gv=Gaelg;
|
||||
ha=حَوْسَ;
|
||||
he=עברית;
|
||||
he_IL=0;
|
||||
hi=हिन्दी;
|
||||
hr=Hrvatski;
|
||||
hr_HR=0;
|
||||
hu=Magyar;
|
||||
hu_HU=0;
|
||||
hy=Հայերեն;
|
||||
ia=Interlingua;
|
||||
id=Bahasa Indonesia;
|
||||
id_ID=0;
|
||||
is=Íslenska;
|
||||
is_IS=0;
|
||||
it=Italiano;
|
||||
it_CH=0;
|
||||
it_IT=0;
|
||||
iu=ᐃᓄᒃᑎᑐᑦ/inuktitut;
|
||||
ja=日本語;
|
||||
ja_JP=0;
|
||||
ka=ქართული;
|
||||
kk=Қазақша;
|
||||
kl=Kalaallisut;
|
||||
km=ភាសាខ្មែរ;
|
||||
km_KH=0;
|
||||
kn=ಕನ್ನಡ;
|
||||
ko=한국어;
|
||||
ko_KR=0;
|
||||
krl=Karjalan kieli;
|
||||
ku=Kurdî;
|
||||
kw=Kernowek;
|
||||
ky=кыргызча;
|
||||
la=Latina;
|
||||
lo=ລາວ;
|
||||
lt=Lietuvių;
|
||||
lt=0;
|
||||
lv=Latviešu;
|
||||
lv_LV=0;
|
||||
jbo=La .lojban.;
|
||||
mg=Malagasy;
|
||||
mi=Māori;
|
||||
mk=Македонски;
|
||||
mk_MK=0;
|
||||
ml=മലയാളം;
|
||||
mn=Монгол;
|
||||
mn_MN=Монгол;
|
||||
mr=मराठी;
|
||||
ms=Bahasa Melayu;
|
||||
ms_MY=0;
|
||||
mt=Malti;
|
||||
my=မြန်မာဘာသာ;
|
||||
my_MM=0;
|
||||
nb=0;
|
||||
nb_NO=0;
|
||||
ne=0;
|
||||
nl=Nederlands;
|
||||
nl_BE=0;
|
||||
nl_NL=0;
|
||||
nn=Norsk nynorsk;
|
||||
nn_NO=0;
|
||||
no=Norsk bokmål;
|
||||
no_NO=0;
|
||||
no_NY=0;
|
||||
nr=0;
|
||||
oc=Occitan;
|
||||
om=Oromoo;
|
||||
or=ଓଡ଼ିଆ;
|
||||
os=0;
|
||||
pa=ਪੰਜਾਬੀ;
|
||||
pl=Polski;
|
||||
pl_PL=0;
|
||||
pms=Piemontèis;
|
||||
ps=پښتو;
|
||||
pt=Português;
|
||||
pt_BR=0;
|
||||
pt_PT=0;
|
||||
qu=Runa Simi;
|
||||
rm=Rumantsch;
|
||||
ro=Română;
|
||||
ro_RO=0;
|
||||
ru=Русский;
|
||||
ru_RU=0;
|
||||
rw=Kinyarwanda;
|
||||
sa=0;
|
||||
sc=Sardu;
|
||||
sco=0;
|
||||
sd=0;
|
||||
se=Sámegiella;
|
||||
se_NO=0;
|
||||
si=0;
|
||||
sk=Slovenčina;
|
||||
sk_SK=0;
|
||||
sl=Slovenščina;
|
||||
sl_SI=0;
|
||||
sl_SL=0;
|
||||
sm=0;
|
||||
so=0;
|
||||
sp=0;
|
||||
sq=Shqip;
|
||||
sq_AL=0;
|
||||
sr=Српски;
|
||||
sr_YU=0;
|
||||
ss=0;
|
||||
st=0;
|
||||
sv=Svenska;
|
||||
sv_SE=0;
|
||||
sv_SV=0;
|
||||
sw=0;
|
||||
ta=தமிழ்;
|
||||
te=0;
|
||||
tg=0;
|
||||
th=ไทย;
|
||||
th_TH=0;
|
||||
ti=0;
|
||||
tk=0;
|
||||
tl=0;
|
||||
to=0;
|
||||
tr=Türkçe;
|
||||
tr_TR=0;
|
||||
ts=0;
|
||||
tt=Татарча;
|
||||
ug=0;
|
||||
uk=Українська;
|
||||
uk_UA=0;
|
||||
ur=اردو;
|
||||
ur_PK=0;
|
||||
uz=0;
|
||||
vi=Tiếng Việt;
|
||||
vi_VN=0;
|
||||
wa=0;
|
||||
wo=0;
|
||||
xh=0;
|
||||
yi=ייִדיש;
|
||||
yo=0;
|
||||
zh=中文;
|
||||
zh_CN=中文(简体);
|
||||
zh_HK=中文(香港);
|
||||
zh_TW=中文(繁體);
|
||||
zu=0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GL_ES
|
||||
#ifdef TBO_DISABLED
|
||||
uniform sampler2D skinning_tex;
|
||||
#else
|
||||
uniform samplerBuffer skinning_tex;
|
||||
@ -56,7 +56,7 @@ void main()
|
||||
vec4 skinned_tangent = vec4(0.0);
|
||||
int skinning_offset = i_misc_data.x;
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef TBO_DISABLED
|
||||
mat4 joint_matrix =
|
||||
i_weight[0] * mat4(
|
||||
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
|
||||
|
@ -203,14 +203,8 @@
|
||||
|
||||
<!-- Networking
|
||||
state-frequency: how many states the server will send per second.
|
||||
positional-smoothing: smoothing factor used in exponential smoothing
|
||||
depending on error.
|
||||
rotational-smoothing: slerp factor used in exponential smoothing
|
||||
of rotations depending on error.
|
||||
-->
|
||||
<networking state-frequency="10"
|
||||
positional-smoothing="0.25:0.95 1.0:0.85"
|
||||
rotational-smoothing="0.25:0.95 1.0:0.85" />
|
||||
<networking state-frequency="10"/>
|
||||
|
||||
<!-- The field od views for 1-4 player split screen. fov-3 is
|
||||
actually not used (since 3 player split screen uses the
|
||||
|
@ -346,6 +346,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -392,6 +395,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -468,6 +474,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -515,6 +524,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -591,6 +603,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -638,6 +653,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -723,6 +741,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -774,6 +795,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -855,6 +879,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -903,6 +930,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -986,6 +1016,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -1037,6 +1070,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -1108,6 +1144,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -1152,6 +1191,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -1239,6 +1281,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -1292,6 +1337,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
@ -1386,6 +1434,9 @@ endcopy:
|
||||
// and the epilogue below, the stack unwind works as it should.
|
||||
// TODO: runtime optimize: The prologue/epilogue shouldn't be needed if the correct cfi directives are used below
|
||||
"pushl %%ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_startproc \n"
|
||||
#endif
|
||||
".cfi_adjust_cfa_offset 4 \n"
|
||||
".cfi_rel_offset ebp, 0 \n"
|
||||
"movl %%esp, %%ebp \n"
|
||||
@ -1452,6 +1503,9 @@ endcopy:
|
||||
"popl %%ebp \n"
|
||||
".cfi_adjust_cfa_offset -4 \n"
|
||||
".cfi_restore ebp \n"
|
||||
#ifndef __ANDROID__
|
||||
".cfi_endproc \n"
|
||||
#endif
|
||||
#endif
|
||||
// Copy EAX:EDX to retQW. As the stack pointer has been
|
||||
// restored it is now safe to access the local variable
|
||||
|
@ -58,6 +58,14 @@ if(NOT SERVER_ONLY)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_LIBPNG_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_LIBJPEG_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_BMP_LOADER_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_PNG_LOADER_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_JPG_LOADER_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_BMP_WRITER_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_PNG_WRITER_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_JPG_WRITER_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_OPENGL_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_X11_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_WAYLAND_DEVICE_)
|
||||
@ -591,9 +599,10 @@ endif()
|
||||
|
||||
add_library(stkirrlicht STATIC ${IRRLICHT_SOURCES})
|
||||
|
||||
target_link_libraries(stkirrlicht ${PNG_LIBRARY} ${JPEG_LIBRARY} ${ZLIB_LIBRARY})
|
||||
target_link_libraries(stkirrlicht ${ZLIB_LIBRARY})
|
||||
|
||||
if(NOT SERVER_ONLY)
|
||||
target_link_libraries(stkirrlicht ${PNG_LIBRARY} ${JPEG_LIBRARY})
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(stkirrlicht ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
||||
endif()
|
||||
|
@ -91,6 +91,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Disable macOS/OSX device
|
||||
#ifdef NO_IRR_COMPILE_WITH_OSX_DEVICE_
|
||||
#undef _IRR_COMPILE_WITH_OSX_DEVICE_
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID)
|
||||
#define _IRR_ANDROID_PLATFORM_
|
||||
#define _IRR_POSIX_API_
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -46,6 +46,7 @@ AnimationBase::AnimationBase(const XMLNode &node)
|
||||
m_playing = false;
|
||||
}
|
||||
reset();
|
||||
calculateAnimationDuration();
|
||||
} // AnimationBase
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Special constructor which takes one IPO (or curve). This is used by the
|
||||
@ -56,8 +57,20 @@ AnimationBase::AnimationBase(Ipo *ipo)
|
||||
m_playing = true;
|
||||
m_all_ipos.push_back(ipo);
|
||||
reset();
|
||||
calculateAnimationDuration();
|
||||
} // AnimationBase(Ipo)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void AnimationBase::calculateAnimationDuration()
|
||||
{
|
||||
m_animation_duration = -1.0f;
|
||||
for (const Ipo* currIpo : m_all_ipos)
|
||||
{
|
||||
m_animation_duration = std::max(m_animation_duration,
|
||||
currIpo->getEndTime());
|
||||
}
|
||||
} // calculateAnimationDuration
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Stores the initial transform (in the IPOs actually). This is necessary
|
||||
* for relative IPOs.
|
||||
|
@ -56,13 +56,17 @@ private:
|
||||
/** The initial rotation of this object. */
|
||||
Vec3 m_initial_hpr;
|
||||
|
||||
void calculateAnimationDuration();
|
||||
|
||||
protected:
|
||||
/** All IPOs for this animation. */
|
||||
PtrVector<Ipo> m_all_ipos;
|
||||
|
||||
/** True if the animation is currently playing. */
|
||||
bool m_playing;
|
||||
|
||||
|
||||
float m_animation_duration;
|
||||
|
||||
public:
|
||||
AnimationBase(const XMLNode &node);
|
||||
AnimationBase(Ipo *ipo);
|
||||
@ -85,18 +89,7 @@ public:
|
||||
void setPlaying(bool playing) {m_playing = playing; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
float getAnimationDuration() const
|
||||
{
|
||||
float duration = -1;
|
||||
|
||||
for (const Ipo* currIpo : m_all_ipos)
|
||||
{
|
||||
duration = std::max(duration, currIpo->getEndTime());
|
||||
}
|
||||
|
||||
return duration;
|
||||
}
|
||||
float getAnimationDuration() const { return m_animation_duration; }
|
||||
|
||||
}; // AnimationBase
|
||||
|
||||
|
@ -69,17 +69,21 @@ ThreeDAnimation::~ThreeDAnimation()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates position and rotation of this model. Called once per time step.
|
||||
* \param dt Time since last call.
|
||||
*/
|
||||
void ThreeDAnimation::update(float dt)
|
||||
void ThreeDAnimation::updateWithWorldTicks()
|
||||
{
|
||||
Vec3 xyz = m_object->getPosition();
|
||||
Vec3 scale = m_object->getScale();
|
||||
|
||||
//make the object think no time has passed to pause it's animation
|
||||
if (m_is_paused)dt = 0;
|
||||
float position = 0.0f;
|
||||
if (!m_is_paused)
|
||||
{
|
||||
int cur_ticks = World::getWorld()->getTicksSinceStart();
|
||||
float cur_time = stk_config->ticks2Time(cur_ticks);
|
||||
position = fmodf(cur_time, m_animation_duration);
|
||||
}
|
||||
|
||||
AnimationBase::update(dt, &xyz, &m_hpr, &scale); //updates all IPOs
|
||||
AnimationBase::getAt(position, &xyz, &m_hpr, &scale); //updates all IPOs
|
||||
//m_node->setPosition(xyz.toIrrVector());
|
||||
//m_node->setScale(scale.toIrrVector());
|
||||
|
||||
|
@ -68,12 +68,13 @@ private:
|
||||
*/
|
||||
bool m_important_animation;
|
||||
|
||||
//scene::ISceneNode* m_node;
|
||||
|
||||
public:
|
||||
ThreeDAnimation(const XMLNode &node, TrackObject* object);
|
||||
virtual ~ThreeDAnimation();
|
||||
virtual void update(float dt);
|
||||
virtual void update(float dt) {}
|
||||
// ------------------------------------------------------------------------
|
||||
void updateWithWorldTicks();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if a collision with this object should
|
||||
* trigger a rescue. */
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define HEADER_DUMMY_SFX_HPP
|
||||
|
||||
#include "audio/sfx_base.hpp"
|
||||
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
/**
|
||||
* \brief Dummy sound when ogg or openal aren't available
|
||||
@ -32,41 +32,41 @@ class DummySFX : public SFXBase
|
||||
public:
|
||||
DummySFX(SFXBuffer* buffer, bool positional,
|
||||
float gain) {}
|
||||
virtual ~DummySFX() {}
|
||||
virtual ~DummySFX() {}
|
||||
|
||||
/** Late creation, if SFX was initially disabled */
|
||||
virtual bool init() { return true; }
|
||||
virtual bool isLooped() { return false; }
|
||||
virtual void updatePlayingSFX(float dt) {}
|
||||
virtual void setLoop(bool status) {}
|
||||
virtual void reallySetLoop(bool status) {}
|
||||
virtual void setPosition(const Vec3 &p) {}
|
||||
virtual void reallySetPosition(const Vec3 &p) {}
|
||||
virtual bool init() OVERRIDE { return true; }
|
||||
virtual bool isLooped() OVERRIDE { return false; }
|
||||
virtual void updatePlayingSFX(float dt) OVERRIDE {}
|
||||
virtual void setLoop(bool status) OVERRIDE {}
|
||||
virtual void reallySetLoop(bool status) OVERRIDE {}
|
||||
virtual void setPosition(const Vec3 &p) OVERRIDE {}
|
||||
virtual void reallySetPosition(const Vec3 &p) OVERRIDE {}
|
||||
virtual void setSpeedPosition(float factor,
|
||||
const Vec3 &p) {}
|
||||
const Vec3 &p) OVERRIDE {}
|
||||
virtual void reallySetSpeedPosition(float f,
|
||||
const Vec3 &p) {}
|
||||
virtual void play() {}
|
||||
virtual void reallyPlayNow(SFXBuffer* buffer = NULL) {}
|
||||
virtual void play(const Vec3 &xyz, SFXBuffer* buffer = NULL) {}
|
||||
virtual void reallyPlayNow(const Vec3 &xyz, SFXBuffer* buffer = NULL) {}
|
||||
virtual void stop() {}
|
||||
virtual void reallyStopNow() {}
|
||||
virtual void pause() {}
|
||||
virtual void reallyPauseNow() {}
|
||||
virtual void resume() {}
|
||||
virtual void reallyResumeNow() {}
|
||||
virtual void deleteSFX() { delete this; }
|
||||
virtual void setSpeed(float factor) {}
|
||||
virtual void reallySetSpeed(float factor) {}
|
||||
virtual void setVolume(float gain) {}
|
||||
virtual void reallySetVolume(float gain) {}
|
||||
virtual void setMasterVolume(float gain) {}
|
||||
virtual void reallySetMasterVolumeNow(float gain) {}
|
||||
virtual SFXStatus getStatus() { return SFX_STOPPED; }
|
||||
virtual void onSoundEnabledBack() {}
|
||||
virtual void setRolloff(float rolloff) {}
|
||||
virtual const SFXBuffer* getBuffer() const { return NULL; }
|
||||
const Vec3 &p) OVERRIDE {}
|
||||
virtual void play() OVERRIDE {}
|
||||
virtual void reallyPlayNow(SFXBuffer* buffer = NULL) OVERRIDE {}
|
||||
virtual void play(const Vec3 &xyz, SFXBuffer* buffer = NULL) OVERRIDE {}
|
||||
virtual void reallyPlayNow(const Vec3 &xyz, SFXBuffer* buffer = NULL) OVERRIDE {}
|
||||
virtual void stop() OVERRIDE {}
|
||||
virtual void reallyStopNow() OVERRIDE {}
|
||||
virtual void pause() OVERRIDE {}
|
||||
virtual void reallyPauseNow() OVERRIDE {}
|
||||
virtual void resume() OVERRIDE {}
|
||||
virtual void reallyResumeNow() OVERRIDE {}
|
||||
virtual void deleteSFX() OVERRIDE {}
|
||||
virtual void setSpeed(float factor) OVERRIDE {}
|
||||
virtual void reallySetSpeed(float factor) OVERRIDE {}
|
||||
virtual void setVolume(float gain) OVERRIDE {}
|
||||
virtual void reallySetVolume(float gain) OVERRIDE {}
|
||||
virtual void setMasterVolume(float gain) OVERRIDE {}
|
||||
virtual void reallySetMasterVolumeNow(float gain) OVERRIDE {}
|
||||
virtual SFXStatus getStatus() OVERRIDE { return SFX_STOPPED; }
|
||||
virtual void onSoundEnabledBack() OVERRIDE {}
|
||||
virtual void setRolloff(float rolloff) OVERRIDE {}
|
||||
virtual const SFXBuffer* getBuffer() const OVERRIDE { return NULL; }
|
||||
|
||||
}; // DummySFX
|
||||
|
||||
|
@ -169,7 +169,7 @@ void MusicInformation::startMusic()
|
||||
return;
|
||||
}
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
m_normal_music = new MusicOggStream(m_normal_loop_start);
|
||||
#else
|
||||
m_normal_music = new MusicDummy();
|
||||
@ -200,7 +200,7 @@ void MusicInformation::startMusic()
|
||||
return;
|
||||
}
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
m_fast_music = new MusicOggStream(m_fast_loop_start);
|
||||
#else
|
||||
m_fast_music = new MusicDummy();
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <assert.h>
|
||||
#include <fstream>
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
# ifdef __APPLE__
|
||||
# include <OpenAL/al.h>
|
||||
# include <OpenAL/alc.h>
|
||||
@ -33,6 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include "audio/music_ogg.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "audio/sfx_openal.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
@ -44,10 +45,11 @@ MusicManager* music_manager= NULL;
|
||||
MusicManager::MusicManager()
|
||||
{
|
||||
m_current_music= NULL;
|
||||
m_initialized = false;
|
||||
setMasterMusicVolume(UserConfigParams::m_music_volume);
|
||||
|
||||
//FIXME: I'm not sure that this code goes here
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
|
||||
#if defined(__APPLE__) && !defined(NDEBUG)
|
||||
// HACK: On OSX, when OpenAL is initialized, breaking in a debugger causes
|
||||
@ -100,7 +102,7 @@ MusicManager::~MusicManager()
|
||||
i->second = NULL;
|
||||
}
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
if(m_initialized)
|
||||
{
|
||||
ALCcontext* context = alcGetCurrentContext();
|
||||
|
@ -16,7 +16,7 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
|
||||
#include "audio/music_ogg.hpp"
|
||||
|
||||
@ -391,4 +391,4 @@ std::string MusicOggStream::errorString(int code)
|
||||
}
|
||||
} // errorString
|
||||
|
||||
#endif // HAVE_OGGVORBIS
|
||||
#endif // ENABLE_SOUND
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef HEADER_MUSICOGG_HPP
|
||||
#define HEADER_MUSICOGG_HPP
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
# include <vorbis/codec.h>
|
||||
# include <vorbis/vorbisfile.h>
|
||||
# ifdef __APPLE__
|
||||
@ -96,7 +96,7 @@ bool SFXBuffer::load()
|
||||
{
|
||||
if (UserConfigParams::m_sfx == false) return false;
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
if (m_loaded) return false;
|
||||
|
||||
alGetError(); // clear errors from previously
|
||||
@ -130,7 +130,7 @@ bool SFXBuffer::load()
|
||||
|
||||
void SFXBuffer::unload()
|
||||
{
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
if (m_loaded)
|
||||
{
|
||||
alDeleteBuffers(1, &m_buffer);
|
||||
@ -147,7 +147,7 @@ void SFXBuffer::unload()
|
||||
*/
|
||||
bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer)
|
||||
{
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
const int ogg_endianness = (IS_LITTLE_ENDIAN ? 0 : 1);
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef HEADER_SFX_BUFFER_HPP
|
||||
#define HEADER_SFX_BUFFER_HPP
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
# ifdef __APPLE__
|
||||
# include <OpenAL/al.h>
|
||||
# else
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
# ifdef __APPLE__
|
||||
# include <OpenAL/al.h>
|
||||
# include <OpenAL/alc.h>
|
||||
@ -97,6 +97,7 @@ SFXManager::SFXManager()
|
||||
|
||||
loadSfx();
|
||||
|
||||
#ifdef ENABLE_SOUND
|
||||
pthread_cond_init(&m_cond_request, NULL);
|
||||
|
||||
pthread_attr_t attr;
|
||||
@ -123,7 +124,7 @@ SFXManager::SFXManager()
|
||||
m_sfx_commands.lock();
|
||||
m_sfx_commands.getData().clear();
|
||||
m_sfx_commands.unlock();
|
||||
|
||||
#endif
|
||||
} // SoundManager
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -131,11 +132,13 @@ SFXManager::SFXManager()
|
||||
*/
|
||||
SFXManager::~SFXManager()
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
m_thread_id.lock();
|
||||
pthread_join(*m_thread_id.getData(), NULL);
|
||||
delete m_thread_id.getData();
|
||||
m_thread_id.unlock();
|
||||
pthread_cond_destroy(&m_cond_request);
|
||||
#endif
|
||||
|
||||
// ---- clear m_all_sfx
|
||||
// not strictly necessary, but might avoid copy&paste problems
|
||||
@ -185,8 +188,10 @@ SFXManager::~SFXManager()
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, SFXBase *sfx)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, sfx);
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -199,8 +204,10 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx)
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, sfx, f);
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue(float)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -213,17 +220,21 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f)
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, sfx, p);
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue (Vec3)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p, SFXBuffer* buffer)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, sfx, p);
|
||||
sfx_command->m_buffer = buffer;
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue (Vec3)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -238,8 +249,10 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p, SFXBuff
|
||||
void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f,
|
||||
const Vec3 &p)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, sfx, f, p);
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue(float, Vec3)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -248,8 +261,10 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f,
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, MusicInformation *mi)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, mi);
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue(MusicInformation)
|
||||
//----------------------------------------------------------------------------
|
||||
/** Queues a command for the music manager that takes a floating point value
|
||||
@ -259,8 +274,10 @@ void SFXManager::queue(SFXCommands command, MusicInformation *mi)
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, MusicInformation *mi, float f)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
SFXCommand *sfx_command = new SFXCommand(command, mi, f);
|
||||
queueCommand(sfx_command);
|
||||
#endif
|
||||
} // queue(MusicInformation)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -270,6 +287,7 @@ void SFXManager::queue(SFXCommands command, MusicInformation *mi, float f)
|
||||
*/
|
||||
void SFXManager::queueCommand(SFXCommand *command)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
m_sfx_commands.lock();
|
||||
if(World::getWorld() &&
|
||||
m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20 &&
|
||||
@ -293,6 +311,7 @@ void SFXManager::queueCommand(SFXCommand *command)
|
||||
}
|
||||
m_sfx_commands.getData().push_back(command);
|
||||
m_sfx_commands.unlock();
|
||||
#endif
|
||||
} // queueCommand
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -301,9 +320,13 @@ void SFXManager::queueCommand(SFXCommand *command)
|
||||
*/
|
||||
void SFXManager::stopThread()
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
queue(SFX_EXIT);
|
||||
// Make sure the thread wakes up.
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
#else
|
||||
setCanBeDeleted();
|
||||
#endif
|
||||
} // stopThread
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -314,6 +337,7 @@ void SFXManager::stopThread()
|
||||
*/
|
||||
void* SFXManager::mainLoop(void *obj)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
VS::setThreadName("SFXManager");
|
||||
SFXManager *me = (SFXManager*)obj;
|
||||
|
||||
@ -436,6 +460,7 @@ void* SFXManager::mainLoop(void *obj)
|
||||
me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin());
|
||||
}
|
||||
me->m_sfx_commands.unlock();
|
||||
#endif
|
||||
return NULL;
|
||||
} // mainLoop
|
||||
|
||||
@ -649,11 +674,13 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer,
|
||||
positional = buffer->isPositional();
|
||||
}
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
//assert( alIsBuffer(buffer->getBufferID()) ); crashes on server
|
||||
SFXBase* sfx = new SFXOpenAL(buffer, positional, buffer->getGain(), owns_buffer);
|
||||
#else
|
||||
SFXBase* sfx = new DummySFX(buffer, positional, buffer->getGain(), owns_buffer);
|
||||
SFXBase* sfx = new DummySFX(buffer, positional, buffer->getGain());
|
||||
if (owns_buffer)
|
||||
delete buffer;
|
||||
#endif
|
||||
|
||||
sfx->setMasterVolume(m_master_gain);
|
||||
@ -738,9 +765,11 @@ void SFXManager::deleteSFXMapping(const std::string &name)
|
||||
*/
|
||||
void SFXManager::update()
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
queue(SFX_UPDATE, (SFXBase*)NULL);
|
||||
// Wake up the sfx thread to handle all queued up audio commands.
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
#endif
|
||||
} // update
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -750,6 +779,7 @@ void SFXManager::update()
|
||||
*/
|
||||
void SFXManager::reallyUpdateNow(SFXCommand *current)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
if (m_last_update_time < 0.0)
|
||||
{
|
||||
// first time
|
||||
@ -782,7 +812,7 @@ void SFXManager::reallyUpdateNow(SFXCommand *current)
|
||||
i->second->updatePlayingSFX(dt);
|
||||
} // for i in m_all_sfx
|
||||
m_quick_sounds.unlock();
|
||||
|
||||
#endif
|
||||
} // reallyUpdateNow
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -875,7 +905,7 @@ void SFXManager::reallyResumeAllNow()
|
||||
*/
|
||||
bool SFXManager::checkError(const std::string &context)
|
||||
{
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
// Check (and clear) the error flag
|
||||
int error = alGetError();
|
||||
|
||||
@ -927,7 +957,7 @@ void SFXManager::setMasterSFXVolume(float gain)
|
||||
//-----------------------------------------------------------------------------
|
||||
const std::string SFXManager::getErrorString(int err)
|
||||
{
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
switch(err)
|
||||
{
|
||||
case AL_NO_ERROR: return std::string("AL_NO_ERROR" );
|
||||
@ -967,7 +997,7 @@ void SFXManager::positionListener(const Vec3 &position, const Vec3 &front,
|
||||
*/
|
||||
void SFXManager::reallyPositionListenerNow()
|
||||
{
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
if (!sfxAllowed()) return;
|
||||
|
||||
m_listener_position.lock();
|
||||
@ -1002,6 +1032,7 @@ void SFXManager::reallyPositionListenerNow()
|
||||
*/
|
||||
SFXBase* SFXManager::quickSound(const std::string &sound_type)
|
||||
{
|
||||
#ifdef ENABLE_SOUND
|
||||
if (!sfxAllowed()) return NULL;
|
||||
|
||||
MutexLockerHelper lock(m_quick_sounds);
|
||||
@ -1024,6 +1055,8 @@ SFXBase* SFXManager::quickSound(const std::string &sound_type)
|
||||
base_sound->play();
|
||||
return base_sound;
|
||||
}
|
||||
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
} // quickSound
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
# ifdef __APPLE__
|
||||
# include <OpenAL/al.h>
|
||||
# else
|
||||
|
@ -18,7 +18,7 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
|
||||
#include "audio/sfx_openal.hpp"
|
||||
|
||||
@ -544,4 +544,4 @@ void SFXOpenAL::setRolloff(float rolloff)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif //if HAVE_OGGVORBIS
|
||||
#endif //ifdef ENABLE_SOUND
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef HEADER_SFX_OPENAL_HPP
|
||||
#define HEADER_SFX_OPENAL_HPP
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
#ifdef ENABLE_SOUND
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef __APPLE__
|
||||
@ -81,43 +81,44 @@ public:
|
||||
bool owns_buffer = false);
|
||||
virtual ~SFXOpenAL();
|
||||
|
||||
virtual void updatePlayingSFX(float dt);
|
||||
virtual void updatePlayingSFX(float dt) OVERRIDE;
|
||||
virtual bool init() OVERRIDE;
|
||||
virtual void play() OVERRIDE;
|
||||
virtual void reallyPlayNow(SFXBuffer* buffer = NULL) OVERRIDE;
|
||||
virtual void play(const Vec3 &xyz, SFXBuffer* buffer = NULL) OVERRIDE;
|
||||
virtual void reallyPlayNow(const Vec3 &xyz, SFXBuffer* buffer = NULL) OVERRIDE;
|
||||
virtual void setLoop(bool status);
|
||||
virtual void reallySetLoop(bool status);
|
||||
virtual void stop();
|
||||
virtual void reallyStopNow();
|
||||
virtual void pause();
|
||||
virtual void reallyPauseNow();
|
||||
virtual void resume();
|
||||
virtual void reallyResumeNow();
|
||||
virtual void deleteSFX();
|
||||
virtual void setSpeed(float factor);
|
||||
virtual void reallySetSpeed(float factor);
|
||||
virtual void setPosition(const Vec3 &position);
|
||||
virtual void reallySetPosition(const Vec3 &p);
|
||||
virtual void setSpeedPosition(float factor, const Vec3 &p);
|
||||
virtual void reallySetSpeedPosition(float f,const Vec3 &p);
|
||||
virtual void setVolume(float volume);
|
||||
virtual void reallySetVolume(float volume);
|
||||
virtual void setMasterVolume(float volume);
|
||||
virtual void reallySetMasterVolumeNow(float volue);
|
||||
virtual void onSoundEnabledBack();
|
||||
virtual void setRolloff(float rolloff);
|
||||
virtual void setLoop(bool status) OVERRIDE;
|
||||
virtual void reallySetLoop(bool status) OVERRIDE;
|
||||
virtual void stop() OVERRIDE;
|
||||
virtual void reallyStopNow() OVERRIDE;
|
||||
virtual void pause() OVERRIDE;
|
||||
virtual void reallyPauseNow() OVERRIDE;
|
||||
virtual void resume() OVERRIDE;
|
||||
virtual void reallyResumeNow() OVERRIDE;
|
||||
virtual void deleteSFX() OVERRIDE;
|
||||
virtual void setSpeed(float factor) OVERRIDE;
|
||||
virtual void reallySetSpeed(float factor) OVERRIDE;
|
||||
virtual void setPosition(const Vec3 &position) OVERRIDE;
|
||||
virtual void reallySetPosition(const Vec3 &p) OVERRIDE;
|
||||
virtual void setSpeedPosition(float factor, const Vec3 &p) OVERRIDE;
|
||||
virtual void reallySetSpeedPosition(float f,const Vec3 &p) OVERRIDE;
|
||||
virtual void setVolume(float volume) OVERRIDE;
|
||||
virtual void reallySetVolume(float volume) OVERRIDE;
|
||||
virtual void setMasterVolume(float volume) OVERRIDE;
|
||||
virtual void reallySetMasterVolumeNow(float volue) OVERRIDE;
|
||||
virtual void onSoundEnabledBack() OVERRIDE;
|
||||
virtual void setRolloff(float rolloff) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this sfx is looped or not. */
|
||||
virtual bool isLooped() { return m_loop; }
|
||||
virtual bool isLooped() OVERRIDE { return m_loop; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the status of this sfx. */
|
||||
virtual SFXStatus getStatus() { return m_status; }
|
||||
virtual SFXStatus getStatus() OVERRIDE { return m_status; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the buffer associated with this sfx. */
|
||||
virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; }
|
||||
virtual const SFXBuffer* getBuffer() const OVERRIDE
|
||||
{ return m_sound_buffer; }
|
||||
|
||||
}; // SFXOpenAL
|
||||
|
||||
|
@ -326,8 +326,9 @@ void PlayerManager::enforceCurrentPlayer()
|
||||
{
|
||||
if (!player->isGuestAccount())
|
||||
{
|
||||
Log::info("PlayerManager", "Enforcing current player '%ls'.",
|
||||
player->getName(true/*ignoreRTL*/).c_str());
|
||||
Log::info("PlayerManager", "Enforcing current player '%s'.",
|
||||
StringUtils::wideToUtf8(player->getName(true/*ignoreRTL*/))
|
||||
.c_str());
|
||||
m_current_player = player;
|
||||
return;
|
||||
}
|
||||
@ -341,7 +342,8 @@ void PlayerManager::enforceCurrentPlayer()
|
||||
if (!player->isGuestAccount())
|
||||
{
|
||||
Log::info("PlayerManager", "Enforcing current player '%s'.",
|
||||
player->getName(true/*ignoreRTL*/).c_str());
|
||||
StringUtils::wideToUtf8(player->getName(true/*ignoreRTL*/))
|
||||
.c_str());
|
||||
m_current_player = player;
|
||||
return;
|
||||
}
|
||||
|
@ -117,15 +117,6 @@ void STKConfig::load(const std::string &filename)
|
||||
Log::fatal("StkConfig", "Wrong number of item switches defined in stk_config");
|
||||
}
|
||||
|
||||
if (m_positional_smoothing.size() == 0)
|
||||
{
|
||||
Log::fatal("StkConfig", "No positional smoothing defined in stk_config.");
|
||||
}
|
||||
if (m_rotational_smoothing.size() == 0)
|
||||
{
|
||||
Log::fatal("StkConfig", "No rotationalsmoothing defined in stk_config.");
|
||||
}
|
||||
|
||||
if (m_client_port == 0 || m_server_port == 0 || m_server_discovery_port == 0 ||
|
||||
m_client_port == m_server_port || m_client_port == m_server_discovery_port ||
|
||||
m_server_port == m_server_discovery_port)
|
||||
@ -441,9 +432,7 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
|
||||
if (const XMLNode *networking_node = root->getNode("networking"))
|
||||
{
|
||||
networking_node->get("state-frequency", &m_network_state_frequeny);
|
||||
networking_node->get("positional-smoothing", &m_positional_smoothing );
|
||||
networking_node->get("rotational-smoothing", &m_rotational_smoothing );
|
||||
networking_node->get("state-frequency", &m_network_state_frequeny);
|
||||
}
|
||||
|
||||
if(const XMLNode *replay_node = root->getNode("replay"))
|
||||
|
@ -89,13 +89,6 @@ public:
|
||||
/** How many state updates per second the server will send. */
|
||||
int m_network_state_frequeny;
|
||||
|
||||
/** Smoothing of prediction errors for position, defined as an
|
||||
* InterpolationArray. */
|
||||
InterpolationArray m_positional_smoothing;
|
||||
/** Smoothing of prediction errors for rotations, defined as an
|
||||
* InterpolationArray. */
|
||||
InterpolationArray m_rotational_smoothing;
|
||||
|
||||
/** If the angle between a normal on a vertex and the normal of the
|
||||
* triangle are more than this value, the physics will use the normal
|
||||
* of the triangle in smoothing normal. */
|
||||
|
@ -373,6 +373,9 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_soccer_use_time_limit
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "soccer-use-time-limit",
|
||||
&m_race_setup_group, "Enable time limit in soccer mode.") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_random_arena_item
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "random-arena-item",
|
||||
&m_race_setup_group, "Enable random location of items in an arena.") );
|
||||
PARAM_PREFIX IntUserConfigParam m_difficulty
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "difficulty",
|
||||
&m_race_setup_group,
|
||||
@ -466,10 +469,11 @@ namespace UserConfigParams
|
||||
"A parameter in range [0.5, 1.5] that determines the scale of the "
|
||||
"multitouch interface."));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_screen_keyboard
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "screen_keyboard",
|
||||
PARAM_PREFIX IntUserConfigParam m_screen_keyboard
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "screen_keyboard_mode",
|
||||
&m_multitouch_group,
|
||||
"Enable screen keyboard.") );
|
||||
"Screen keyboard mode: 0 = disabled, 1 = enabled if no hardware "
|
||||
"keyboard, 2 = always enabled") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_hidpi_enabled
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "hidpi_enabled",
|
||||
@ -638,9 +642,6 @@ namespace UserConfigParams
|
||||
/** If track debugging is enabled. */
|
||||
PARAM_PREFIX int m_track_debug PARAM_DEFAULT( false );
|
||||
|
||||
/** If random number of items is used in an arena. */
|
||||
PARAM_PREFIX bool m_random_arena_item PARAM_DEFAULT( false );
|
||||
|
||||
/** True if check structures should be debugged. */
|
||||
PARAM_PREFIX bool m_check_debug PARAM_DEFAULT( false );
|
||||
|
||||
@ -721,7 +722,7 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT(FloatUserConfigParam(20.0f, "validation-timeout",
|
||||
&m_network_group, "Timeout in seconds for validation of clients."));
|
||||
PARAM_PREFIX IntUserConfigParam m_server_max_players
|
||||
PARAM_DEFAULT(IntUserConfigParam(12, "server_max_players",
|
||||
PARAM_DEFAULT(IntUserConfigParam(8, "server_max_players",
|
||||
&m_network_group, "Maximum number of players on the server."));
|
||||
PARAM_PREFIX BoolUserConfigParam m_firewalled_server
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "firewalled-server",
|
||||
|
@ -59,7 +59,9 @@ void BoldFace::reset()
|
||||
/** Embolden the glyph to make bold font using FT_Outline_Embolden.
|
||||
* \return A FT_Error value.
|
||||
*/
|
||||
#ifndef SERVER_ONLY
|
||||
int BoldFace::shapeOutline(FT_Outline* outline) const
|
||||
{
|
||||
return FT_Outline_Embolden(outline, getDPI() * 2);
|
||||
} // shapeOutline
|
||||
#endif
|
||||
|
@ -38,7 +38,9 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool isBold() const OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
#ifndef SERVER_ONLY
|
||||
virtual int shapeOutline(FT_Outline* outline) const OVERRIDE;
|
||||
#endif
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
@ -27,6 +27,7 @@
|
||||
*/
|
||||
FaceTTF::FaceTTF(const std::vector<std::string>& ttf_list)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (const std::string& font : ttf_list)
|
||||
{
|
||||
FT_Face face = NULL;
|
||||
@ -36,6 +37,7 @@ FaceTTF::FaceTTF(const std::vector<std::string>& ttf_list)
|
||||
loc.c_str(), 0, &face), loc + " is loaded");
|
||||
m_faces.push_back(face);
|
||||
}
|
||||
#endif
|
||||
} // FaceTTF
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -43,17 +45,10 @@ FaceTTF::FaceTTF(const std::vector<std::string>& ttf_list)
|
||||
*/
|
||||
FaceTTF::~FaceTTF()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (unsigned int i = 0; i < m_faces.size(); i++)
|
||||
{
|
||||
font_manager->checkFTError(FT_Done_Face(m_faces[i]), "removing face");
|
||||
}
|
||||
#endif
|
||||
} // ~FaceTTF
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Return a TTF in \ref m_faces.
|
||||
* \param i index of TTF file in \ref m_faces.
|
||||
*/
|
||||
FT_Face FaceTTF::getFace(unsigned int i) const
|
||||
{
|
||||
assert(i < m_faces.size());
|
||||
return m_faces[i];
|
||||
} // getFace
|
||||
|
@ -22,11 +22,14 @@
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
/** This class will load a list of TTF files from \ref STKConfig, and save
|
||||
* them inside \ref m_faces for \ref FontWithFace to load glyph.
|
||||
@ -37,21 +40,31 @@
|
||||
*/
|
||||
class FaceTTF : public NoCopy
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
private:
|
||||
/** Contains all TTF files loaded. */
|
||||
std::vector<FT_Face> m_faces;
|
||||
|
||||
#endif
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
FaceTTF(const std::vector<std::string>& ttf_list);
|
||||
// ------------------------------------------------------------------------
|
||||
~FaceTTF();
|
||||
#ifndef SERVER_ONLY
|
||||
// ------------------------------------------------------------------------
|
||||
FT_Face getFace(unsigned int i) const;
|
||||
/** Return a TTF in \ref m_faces.
|
||||
* \param i index of TTF file in \ref m_faces.
|
||||
*/
|
||||
FT_Face getFace(unsigned int i) const
|
||||
{
|
||||
assert(i < m_faces.size());
|
||||
return m_faces[i];
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the total TTF files loaded. */
|
||||
unsigned int getTotalFaces() const { return (unsigned int)m_faces.size(); }
|
||||
#endif
|
||||
|
||||
}; // FaceTTF
|
||||
|
||||
|
@ -32,7 +32,9 @@ FontManager *font_manager = NULL;
|
||||
*/
|
||||
FontManager::FontManager()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
checkFTError(FT_Init_FreeType(&m_ft_library), "loading freetype library");
|
||||
#endif
|
||||
} // FontManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -49,8 +51,10 @@ FontManager::~FontManager()
|
||||
delete m_digit_ttf;
|
||||
m_digit_ttf = NULL;
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
checkFTError(FT_Done_FreeType(m_ft_library), "removing freetype library");
|
||||
m_ft_library = NULL;
|
||||
#endif
|
||||
} // ~FontManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -87,6 +91,7 @@ void FontManager::loadFonts()
|
||||
*/
|
||||
void FontManager::unitTesting()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
std::vector<std::string> list = *(translations->getLanguageList());
|
||||
const int cur_log_level = Log::getLogLevel();
|
||||
for (const std::string& lang : list)
|
||||
@ -134,5 +139,5 @@ void FontManager::unitTesting()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
} // unitTesting
|
||||
|
@ -32,8 +32,10 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
class FaceTTF;
|
||||
class FontWithFace;
|
||||
@ -47,8 +49,10 @@ private:
|
||||
/** Stores all \ref FontWithFace used in STK. */
|
||||
std::vector<FontWithFace*> m_fonts;
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
/** A FreeType library, it holds the FT_Face internally inside freetype. */
|
||||
FT_Library m_ft_library;
|
||||
#endif
|
||||
|
||||
/** TTF files used in \ref BoldFace and \ref RegularFace. */
|
||||
FaceTTF* m_normal_ttf;
|
||||
@ -81,6 +85,7 @@ public:
|
||||
return out;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
#ifndef SERVER_ONLY
|
||||
/** Check for any error discovered in a freetype function that will return
|
||||
* a FT_Error value, and log into the terminal.
|
||||
* \param err The Freetype function.
|
||||
@ -93,13 +98,15 @@ public:
|
||||
"code was %d.", desc.c_str(), err);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the \ref m_ft_library. */
|
||||
FT_Library getFTLibrary() const { return m_ft_library; }
|
||||
#endif
|
||||
// ------------------------------------------------------------------------
|
||||
void loadFonts();
|
||||
// ------------------------------------------------------------------------
|
||||
void unitTesting();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the \ref m_ft_library. */
|
||||
FT_Library getFTLibrary() const { return m_ft_library; }
|
||||
|
||||
|
||||
}; // FontManager
|
||||
|
||||
|
@ -76,6 +76,7 @@ FontWithFace::~FontWithFace()
|
||||
void FontWithFace::init()
|
||||
{
|
||||
setDPI();
|
||||
#ifndef SERVER_ONLY
|
||||
// Get the max height for this face
|
||||
assert(m_face_ttf->getTotalFaces() > 0);
|
||||
FT_Face cur_face = m_face_ttf->getFace(0);
|
||||
@ -94,7 +95,7 @@ void FontWithFace::init()
|
||||
if (height > m_glyph_max_height)
|
||||
m_glyph_max_height = height;
|
||||
}
|
||||
|
||||
#endif
|
||||
reset();
|
||||
} // init
|
||||
|
||||
@ -125,6 +126,7 @@ void FontWithFace::reset()
|
||||
*/
|
||||
void FontWithFace::loadGlyphInfo(wchar_t c)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
unsigned int font_number = 0;
|
||||
unsigned int glyph_index = 0;
|
||||
while (font_number < m_face_ttf->getTotalFaces())
|
||||
@ -134,6 +136,7 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
|
||||
font_number++;
|
||||
}
|
||||
m_character_glyph_info_map[c] = GlyphInfo(font_number, glyph_index);
|
||||
#endif
|
||||
} // loadGlyphInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -169,6 +172,7 @@ void FontWithFace::createNewGlyphPage()
|
||||
*/
|
||||
void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
assert(gi.glyph_index > 0);
|
||||
assert(gi.font_number < m_face_ttf->getTotalFaces());
|
||||
FT_Face cur_face = m_face_ttf->getFace(gi.font_number);
|
||||
@ -209,7 +213,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
}
|
||||
|
||||
const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
|
||||
#ifndef SERVER_ONLY
|
||||
if (bits->buffer != NULL && !ProfileWorld::isNoGraphics())
|
||||
{
|
||||
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
|
||||
@ -237,7 +240,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Store the rectangle of current glyph
|
||||
gui::SGUISpriteFrame f;
|
||||
@ -269,6 +271,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
m_used_width += texture_size.Width;
|
||||
if (m_current_height < texture_size.Height)
|
||||
m_current_height = texture_size.Height;
|
||||
#endif
|
||||
} // insertGlyph
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -296,6 +299,7 @@ void FontWithFace::updateCharactersList()
|
||||
*/
|
||||
void FontWithFace::dumpGlyphPage(const std::string& name)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
||||
{
|
||||
video::ITexture* tex = m_spritebank->getTexture(i);
|
||||
@ -310,6 +314,7 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
|
||||
(name + "_" + StringUtils::toString(i) + ".png").c_str());
|
||||
image->drop();
|
||||
}
|
||||
#endif
|
||||
} // dumpGlyphPage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -393,6 +398,10 @@ const FontWithFace::FontArea&
|
||||
core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
||||
FontSettings* font_settings)
|
||||
{
|
||||
#ifdef SERVER_ONLY
|
||||
return core::dimension2d<u32>(1, 1);
|
||||
#else
|
||||
|
||||
const float scale = font_settings ? font_settings->getScale() : 1.0f;
|
||||
// Test if lazy load char is needed
|
||||
insertCharacters(text);
|
||||
@ -431,6 +440,7 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
||||
ret_dim.Height = (u32)(dim.Height + 0.9f);
|
||||
|
||||
return ret_dim;
|
||||
#endif
|
||||
} // getDimension
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -29,9 +29,11 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#endif
|
||||
|
||||
#include <irrlicht.h>
|
||||
|
||||
@ -261,10 +263,12 @@ private:
|
||||
/** Override it if sub-class has bold outline. */
|
||||
virtual bool isBold() const { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
#ifndef SERVER_ONLY
|
||||
/** Override it if any outline shaping is needed to be done before
|
||||
* rendering the glyph into bitmap.
|
||||
* \return A FT_Error value if needed. */
|
||||
virtual int shapeOutline(FT_Outline* outline) const { return 0; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
@ -196,8 +196,8 @@ void Camera::setMode(Mode mode)
|
||||
(m_mode==CM_FALLING && mode==CM_NORMAL) )
|
||||
{
|
||||
Vec3 start_offset(0, 1.6f, -3);
|
||||
Vec3 current_position = m_kart->getTrans()(start_offset);
|
||||
Vec3 target_position = m_kart->getTrans()(Vec3(0, 0, 1));
|
||||
Vec3 current_position = m_kart->getSmoothedTrans()(start_offset);
|
||||
Vec3 target_position = m_kart->getSmoothedTrans()(Vec3(0, 0, 1));
|
||||
// Don't set position and target the same, otherwise
|
||||
// nan values will be calculated in ViewArea of camera
|
||||
m_camera->setPosition(current_position.toIrrVector());
|
||||
@ -236,7 +236,7 @@ void Camera::setInitialTransform()
|
||||
{
|
||||
if (m_kart == NULL) return;
|
||||
Vec3 start_offset(0, 1.6f, -3);
|
||||
Vec3 current_position = m_kart->getTrans()(start_offset);
|
||||
Vec3 current_position = m_kart->getSmoothedTrans()(start_offset);
|
||||
assert(!std::isnan(current_position.getX()));
|
||||
assert(!std::isnan(current_position.getY()));
|
||||
assert(!std::isnan(current_position.getZ()));
|
||||
@ -246,7 +246,7 @@ void Camera::setInitialTransform()
|
||||
// direction till smoothMoveCamera has corrected this. Setting target
|
||||
// to position doesn't make sense, but smoothMoves will adjust the
|
||||
// value before the first frame is rendered
|
||||
Vec3 target_position = m_kart->getTrans()(Vec3(0, 0, 1));
|
||||
Vec3 target_position = m_kart->getSmoothedTrans()(Vec3(0, 0, 1));
|
||||
m_camera->setTarget(target_position.toIrrVector());
|
||||
m_camera->setRotation(core::vector3df(0, 0, 0));
|
||||
m_camera->setFOV(m_fov);
|
||||
@ -274,7 +274,7 @@ void Camera::update(float dt)
|
||||
if (race_manager->getNumLocalPlayers() < 2)
|
||||
{
|
||||
Vec3 heading(sin(m_kart->getHeading()), 0.0f, cos(m_kart->getHeading()));
|
||||
SFXManager::get()->positionListener(m_kart->getXYZ(),
|
||||
SFXManager::get()->positionListener(m_kart->getSmoothedXYZ(),
|
||||
heading,
|
||||
Vec3(0, 1, 0));
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ void CameraDebug::update(float dt)
|
||||
// high above the kart straight down.
|
||||
if (m_default_debug_Type==CM_DEBUG_TOP_OF_KART)
|
||||
{
|
||||
core::vector3df xyz = m_kart->getXYZ().toIrrVector();
|
||||
core::vector3df xyz = m_kart->getSmoothedXYZ().toIrrVector();
|
||||
m_camera->setTarget(xyz);
|
||||
#define CLOSE_TO_KART
|
||||
#ifdef CLOSE_TO_KART
|
||||
@ -118,9 +118,9 @@ void CameraDebug::update(float dt)
|
||||
}
|
||||
else if (m_default_debug_Type==CM_DEBUG_SIDE_OF_KART)
|
||||
{
|
||||
core::vector3df xyz = m_kart->getXYZ().toIrrVector();
|
||||
core::vector3df xyz = m_kart->getSmoothedXYZ().toIrrVector();
|
||||
Vec3 offset(3, 0, 0);
|
||||
offset = m_kart->getTrans()(offset);
|
||||
offset = m_kart->getSmoothedTrans()(offset);
|
||||
m_camera->setTarget(xyz);
|
||||
m_camera->setPosition(offset.toIrrVector());
|
||||
}
|
||||
@ -136,7 +136,7 @@ void CameraDebug::update(float dt)
|
||||
// above the kart).
|
||||
// Note: this code is replicated from smoothMoveCamera so that
|
||||
// the camera keeps on pointing to the same spot.
|
||||
core::vector3df current_target = (m_kart->getXYZ().toIrrVector()
|
||||
core::vector3df current_target = (m_kart->getSmoothedXYZ().toIrrVector()
|
||||
+core::vector3df(0, above_kart, 0));
|
||||
m_camera->setTarget(current_target);
|
||||
}
|
||||
@ -158,7 +158,7 @@ void CameraDebug::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
float side_way, float distance )
|
||||
{
|
||||
Vec3 wanted_position;
|
||||
Vec3 wanted_target = m_kart->getXYZ();
|
||||
Vec3 wanted_target = m_kart->getSmoothedXYZ();
|
||||
if(m_default_debug_Type==CM_DEBUG_GROUND)
|
||||
{
|
||||
const btWheelInfo &w = m_kart->getVehicle()->getWheelInfo(2);
|
||||
@ -170,7 +170,7 @@ void CameraDebug::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
Vec3 relative_position(side_way,
|
||||
fabsf(distance)*tan_up+above_kart,
|
||||
distance);
|
||||
btTransform t=m_kart->getTrans();
|
||||
btTransform t=m_kart->getSmoothedTrans();
|
||||
if(stk_config->m_camera_follow_skid &&
|
||||
m_kart->getSkidding()->getVisualSkidRotation()!=0)
|
||||
{
|
||||
@ -196,7 +196,7 @@ void CameraDebug::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
if (kart && !kart->isFlying())
|
||||
{
|
||||
// Rotate the up vector (0,1,0) by the rotation ... which is just column 1
|
||||
Vec3 up = m_kart->getTrans().getBasis().getColumn(1);
|
||||
Vec3 up = m_kart->getSmoothedTrans().getBasis().getColumn(1);
|
||||
float f = 0.04f; // weight for new up vector to reduce shaking
|
||||
m_camera->setUpVector( f * up.toIrrVector() +
|
||||
(1.0f - f) * m_camera->getUpVector());
|
||||
|
@ -87,7 +87,7 @@ void CameraEnd::update(float dt)
|
||||
// First test if the kart is close enough to the next end camera, and
|
||||
// if so activate it.
|
||||
if( m_end_cameras.size()>0 &&
|
||||
m_end_cameras[m_next_end_camera].isReached(m_kart->getXYZ()))
|
||||
m_end_cameras[m_next_end_camera].isReached(m_kart->getSmoothedXYZ()))
|
||||
{
|
||||
m_current_end_camera = m_next_end_camera;
|
||||
if(m_end_cameras[m_current_end_camera].m_type
|
||||
@ -116,7 +116,7 @@ void CameraEnd::update(float dt)
|
||||
// after changing the relative position in order to get the right
|
||||
// position here).
|
||||
const core::vector3df &cp = m_camera->getPosition();
|
||||
const Vec3 &kp = m_kart->getXYZ();
|
||||
const Vec3 &kp = m_kart->getSmoothedXYZ();
|
||||
// Estimate the fov, assuming that the vector from the camera to
|
||||
// the kart and the kart length are orthogonal to each other
|
||||
// --> tan (fov) = kart_length / camera_kart_distance
|
||||
@ -125,7 +125,7 @@ void CameraEnd::update(float dt)
|
||||
float fov = 6*atan2(m_kart->getKartLength(),
|
||||
(cp-kp.toIrrVector()).getLength());
|
||||
m_camera->setFOV(fov);
|
||||
m_camera->setTarget(m_kart->getXYZ().toIrrVector());
|
||||
m_camera->setTarget(m_kart->getSmoothedXYZ().toIrrVector());
|
||||
break;
|
||||
}
|
||||
case EndCameraInformation::EC_AHEAD_OF_KART:
|
||||
|
@ -224,7 +224,7 @@ void CameraFPS::update(float dt)
|
||||
m_local_up = up;
|
||||
|
||||
// Move the camera with the kart
|
||||
btTransform t = m_kart->getTrans();
|
||||
btTransform t = m_kart->getSmoothedTrans();
|
||||
if (stk_config->m_camera_follow_skid &&
|
||||
m_kart->getSkidding()->getVisualSkidRotation() != 0)
|
||||
{
|
||||
|
@ -53,13 +53,13 @@ CameraNormal::CameraNormal(Camera::CameraType type, int camera_index,
|
||||
m_rotation_range = 0.4f;
|
||||
m_rotation_range = 0.0f;
|
||||
m_kart_position = btVector3(0, 0, 0);
|
||||
m_kart_rotation = btQuaternion(0, 0, 0, 0);
|
||||
m_kart_rotation = btQuaternion(0, 0, 0, 1);
|
||||
reset();
|
||||
m_camera->setNearValue(1.0f);
|
||||
|
||||
if (kart)
|
||||
{
|
||||
btTransform btt = kart->getTrans();
|
||||
btTransform btt = kart->getSmoothedTrans();
|
||||
m_kart_position = btt.getOrigin();
|
||||
m_kart_rotation = btt.getRotation();
|
||||
}
|
||||
@ -74,24 +74,23 @@ CameraNormal::CameraNormal(Camera::CameraType type, int camera_index,
|
||||
void CameraNormal::moveCamera(float dt, bool smooth)
|
||||
{
|
||||
if(!m_kart) return;
|
||||
|
||||
|
||||
Kart *kart = dynamic_cast<Kart*>(m_kart);
|
||||
if (kart->isFlying())
|
||||
{
|
||||
Vec3 vec3 = m_kart->getXYZ() + Vec3(sin(m_kart->getHeading()) * -4.0f,
|
||||
Vec3 vec3 = m_kart->getSmoothedXYZ() + Vec3(sin(m_kart->getHeading()) * -4.0f,
|
||||
0.5f,
|
||||
cos(m_kart->getHeading()) * -4.0f);
|
||||
m_camera->setTarget(m_kart->getXYZ().toIrrVector());
|
||||
m_camera->setTarget(m_kart->getSmoothedXYZ().toIrrVector());
|
||||
m_camera->setPosition(vec3.toIrrVector());
|
||||
return;
|
||||
} // kart is flying
|
||||
|
||||
|
||||
core::vector3df current_position = m_camera->getPosition();
|
||||
// Smoothly interpolate towards the position and target
|
||||
const KartProperties *kp = m_kart->getKartProperties();
|
||||
float max_speed_without_zipper = kp->getEngineMaxSpeed();
|
||||
float current_speed = m_kart->getSmoothedSpeed();
|
||||
float current_speed = m_kart->getSpeed();
|
||||
|
||||
const Skidding *ks = m_kart->getSkidding();
|
||||
float skid_factor = ks->getVisualSkidRotation();
|
||||
@ -110,27 +109,24 @@ void CameraNormal::moveCamera(float dt, bool smooth)
|
||||
(0.85f + ratio / 2.5f),
|
||||
camera_distance * cos(skid_angle / 2));
|
||||
|
||||
|
||||
//m_smooth_dt = 0.3f * dt + 0.7f * m_smooth_dt;
|
||||
float delta = 1;
|
||||
float delta2 = 1;
|
||||
if (smooth)
|
||||
{
|
||||
{
|
||||
delta = (dt*5.0f);
|
||||
if (delta < 0.0f)
|
||||
delta = 0.0f;
|
||||
else if (delta > 1.0f)
|
||||
delta = 1.0f;
|
||||
|
||||
|
||||
delta2 = dt * 8.0f;
|
||||
if (delta2 < 0)
|
||||
delta2 = 0;
|
||||
else if (delta2 > 1)
|
||||
delta2 = 1;
|
||||
}
|
||||
m_camera_offset += (wanted_camera_offset - m_camera_offset) * delta;
|
||||
|
||||
btTransform btt = m_kart->getTrans();
|
||||
btTransform btt = m_kart->getSmoothedTrans();
|
||||
m_kart_position = btt.getOrigin();
|
||||
btQuaternion q1, q2;
|
||||
q1 = m_kart_rotation.normalized();
|
||||
@ -141,19 +137,20 @@ void CameraNormal::moveCamera(float dt, bool smooth)
|
||||
m_kart_rotation = q1.slerp(q2, delta2);
|
||||
|
||||
btt.setOrigin(m_kart_position);
|
||||
btt.setRotation(m_kart_rotation);
|
||||
btt.setRotation(q1);
|
||||
|
||||
Vec3 kart_camera_position_with_offset = btt(m_camera_offset);
|
||||
m_camera_offset += (wanted_camera_offset - m_camera_offset) * delta;
|
||||
|
||||
Vec3 m_kart_camera_position_with_offset = btt(m_camera_offset);
|
||||
// next target
|
||||
Vec3 current_target = btt(Vec3(0, 0.5f, 0));
|
||||
// new required position of camera
|
||||
current_position = m_kart_camera_position_with_offset.toIrrVector();
|
||||
|
||||
current_position = kart_camera_position_with_offset.toIrrVector();
|
||||
|
||||
//Log::info("CAM_DEBUG", "OFFSET: %f %f %f TRANSFORMED %f %f %f TARGET %f %f %f",
|
||||
// wanted_camera_offset.x(), wanted_camera_offset.y(), wanted_camera_offset.z(),
|
||||
// m_kart_camera_position_with_offset.x(), m_kart_camera_position_with_offset.y(),
|
||||
// m_kart_camera_position_with_offset.z(), current_target.x(), current_target.y(),
|
||||
// kart_camera_position_with_offset.x(), kart_camera_position_with_offset.y(),
|
||||
// kart_camera_position_with_offset.z(), current_target.x(), current_target.y(),
|
||||
// current_target.z());
|
||||
|
||||
if(getMode()!=CM_FALLING)
|
||||
@ -164,11 +161,14 @@ void CameraNormal::moveCamera(float dt, bool smooth)
|
||||
assert(!std::isnan(m_camera->getPosition().Y));
|
||||
assert(!std::isnan(m_camera->getPosition().Z));
|
||||
|
||||
} // MoveCamera
|
||||
} // moveCamera
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CameraNormal::snapToPosition()
|
||||
{
|
||||
moveCamera(1, false);
|
||||
}
|
||||
moveCamera(1.0f, false);
|
||||
} // snapToPosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Determine the camera settings for the current frame.
|
||||
* \param above_kart How far above the camera should aim at.
|
||||
@ -261,7 +261,7 @@ void CameraNormal::update(float dt)
|
||||
// above the kart).
|
||||
// Note: this code is replicated from smoothMoveCamera so that
|
||||
// the camera keeps on pointing to the same spot.
|
||||
core::vector3df current_target = (m_kart->getXYZ().toIrrVector()
|
||||
core::vector3df current_target = (m_kart->getSmoothedXYZ().toIrrVector()
|
||||
+ core::vector3df(0, above_kart, 0));
|
||||
m_camera->setTarget(current_target);
|
||||
}
|
||||
@ -286,13 +286,13 @@ void CameraNormal::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
float side_way, float distance, float smoothing)
|
||||
{
|
||||
Vec3 wanted_position;
|
||||
Vec3 wanted_target = m_kart->getTrans()(Vec3(0, above_kart, 0));
|
||||
Vec3 wanted_target = m_kart->getSmoothedTrans()(Vec3(0, above_kart, 0));
|
||||
|
||||
float tan_up = tan(cam_angle);
|
||||
Vec3 relative_position(side_way,
|
||||
fabsf(distance)*tan_up+above_kart,
|
||||
distance);
|
||||
btTransform t=m_kart->getTrans();
|
||||
btTransform t=m_kart->getSmoothedTrans();
|
||||
if(stk_config->m_camera_follow_skid &&
|
||||
m_kart->getSkidding()->getVisualSkidRotation()!=0)
|
||||
{
|
||||
@ -325,7 +325,7 @@ void CameraNormal::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
if (kart && !kart->isFlying())
|
||||
{
|
||||
// Rotate the up vector (0,1,0) by the rotation ... which is just column 1
|
||||
Vec3 up = m_kart->getTrans().getBasis().getColumn(1);
|
||||
Vec3 up = m_kart->getSmoothedTrans().getBasis().getColumn(1);
|
||||
float f = 0.04f; // weight for new up vector to reduce shaking
|
||||
m_camera->setUpVector( f * up.toIrrVector() +
|
||||
(1.0f - f) * m_camera->getUpVector());
|
||||
|
@ -56,6 +56,7 @@ void CentralVideoSettings::init()
|
||||
hasInstancedArrays = false;
|
||||
hasBGRA = false;
|
||||
hasColorBufferFloat = false;
|
||||
hasTextureBufferObject = false;
|
||||
m_need_vertex_id_workaround = false;
|
||||
|
||||
// Call to glGetIntegerv should not be made if --no-graphics is used
|
||||
@ -157,6 +158,12 @@ void CentralVideoSettings::init()
|
||||
hasGS = true;
|
||||
Log::info("GLDriver", "Geometry Shaders Present");
|
||||
}
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_BUFFER_OBJECT) &&
|
||||
m_glsl == true)
|
||||
{
|
||||
hasTextureBufferObject = true;
|
||||
Log::info("GLDriver", "ARB Texture Buffer Object Present");
|
||||
}
|
||||
if (hasGLExtension("GL_ARB_texture_swizzle"))
|
||||
{
|
||||
hasTextureSwizzle = true;
|
||||
@ -216,7 +223,7 @@ void CentralVideoSettings::init()
|
||||
hasUBO = true;
|
||||
Log::info("GLDriver", "ARB Uniform Buffer Object Present");
|
||||
}
|
||||
|
||||
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
|
||||
(hasGLExtension("GL_IMG_texture_format_BGRA8888") ||
|
||||
hasGLExtension("GL_EXT_texture_format_BGRA8888")))
|
||||
@ -449,4 +456,9 @@ bool CentralVideoSettings::isARBInstancedArraysUsable() const
|
||||
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 2));
|
||||
}
|
||||
|
||||
bool CentralVideoSettings::isARBTextureBufferObjectUsable() const
|
||||
{
|
||||
return hasTextureBufferObject;
|
||||
}
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -48,6 +48,7 @@ private:
|
||||
bool hasInstancedArrays;
|
||||
bool hasBGRA;
|
||||
bool hasColorBufferFloat;
|
||||
bool hasTextureBufferObject;
|
||||
bool m_need_vertex_id_workaround;
|
||||
public:
|
||||
static bool m_supports_sp;
|
||||
@ -81,6 +82,7 @@ public:
|
||||
bool isARBInstancedArraysUsable() const;
|
||||
bool isEXTTextureFormatBGRA8888Usable() const;
|
||||
bool isEXTColorBufferFloatUsable() const;
|
||||
bool isARBTextureBufferObjectUsable() const;
|
||||
|
||||
// Are all required extensions available for feature support
|
||||
bool supportsComputeShadersFiltering() const;
|
||||
|
@ -44,7 +44,7 @@ namespace GraphicsRestrictions
|
||||
/** The list of names used in the XML file for the graphics
|
||||
* restriction types. They must be in the same order as the types. */
|
||||
|
||||
std::array<std::string, 30> m_names_of_restrictions =
|
||||
std::array<std::string, 31> m_names_of_restrictions =
|
||||
{
|
||||
{
|
||||
"UniformBufferObject",
|
||||
@ -76,7 +76,8 @@ namespace GraphicsRestrictions
|
||||
"ForceLegacyDevice",
|
||||
"VertexIdWorking",
|
||||
"HardwareSkinning",
|
||||
"NpotTextures"
|
||||
"NpotTextures",
|
||||
"TextureBufferObject"
|
||||
}
|
||||
};
|
||||
} // namespace Private
|
||||
|
@ -64,6 +64,7 @@ namespace GraphicsRestrictions
|
||||
GR_VERTEX_ID_WORKING,
|
||||
GR_HARDWARE_SKINNING,
|
||||
GR_NPOT_TEXTURES,
|
||||
GR_TEXTURE_BUFFER_OBJECT,
|
||||
GR_COUNT /** MUST be last entry. */
|
||||
} ;
|
||||
|
||||
|
@ -59,10 +59,10 @@
|
||||
#include "main_loop.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "scriptengine/property_animator.hpp"
|
||||
#include "states_screens/dialogs/confirm_resolution_dialog.hpp"
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
@ -1729,13 +1729,15 @@ void IrrDriver::displayFPS()
|
||||
prev_state = current_state;
|
||||
}
|
||||
|
||||
uint32_t ping = 0;
|
||||
if (STKHost::existHost())
|
||||
ping = STKHost::get()->getClientPingToServer();
|
||||
if (no_trust)
|
||||
{
|
||||
no_trust--;
|
||||
|
||||
static video::SColor fpsColor = video::SColor(255, 0, 0, 0);
|
||||
font->draw(StringUtils::insertValues (L"FPS: ... Ping: %dms",
|
||||
NetworkingLobby::getInstance()->getServerPing()),
|
||||
font->draw(StringUtils::insertValues (L"FPS: ... Ping: %dms", ping),
|
||||
core::rect< s32 >(100,0,400,50), fpsColor, false);
|
||||
return;
|
||||
}
|
||||
@ -1761,22 +1763,19 @@ void IrrDriver::displayFPS()
|
||||
"Ping: %dms",
|
||||
min, fps, max, SP::sp_solid_poly_count,
|
||||
SP::sp_shadow_poly_count, m_last_light_bucket_distance,
|
||||
m_skinning_joint,
|
||||
NetworkingLobby::getInstance()->getServerPing());
|
||||
m_skinning_joint, ping);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
fps_string = _("FPS: %d/%d/%d - %d KTris, Ping: %dms", min, fps,
|
||||
max, SP::sp_solid_poly_count / 1000,
|
||||
NetworkingLobby::getInstance()->getServerPing());
|
||||
max, SP::sp_solid_poly_count / 1000, ping);
|
||||
}
|
||||
else
|
||||
{
|
||||
fps_string = _("FPS: %d/%d/%d - %d KTris, Ping: %dms", min, fps,
|
||||
max, (int)roundf(kilotris),
|
||||
NetworkingLobby::getInstance()->getServerPing());
|
||||
max, (int)roundf(kilotris), ping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,8 @@ ShaderFilesManager::SharedShader ShaderFilesManager::loadShader
|
||||
code << "//" << full_path << "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
code << "#define UBO_DISABLED\n";
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
code << "#define TBO_DISABLED\n";
|
||||
if (CVS->needsVertexIdWorkaround())
|
||||
code << "#define Needs_Vertex_Id_Workaround\n";
|
||||
if (CVS->isDeferredEnabled())
|
||||
|
@ -82,7 +82,7 @@ void Shadow::update(bool enabled)
|
||||
v[1].m_position.X = 1; v[1].m_position.Z = 1; v[1].m_position.Y = 0;
|
||||
v[2].m_position.X = -1; v[2].m_position.Z = -1; v[2].m_position.Y = 0;
|
||||
v[3].m_position.X = 1; v[3].m_position.Z = -1; v[3].m_position.Y = 0;
|
||||
btTransform kart_trans = m_kart.getTrans();
|
||||
btTransform kart_trans = m_kart.getSmoothedTrans();
|
||||
btTransform skidding_rotation;
|
||||
skidding_rotation.setOrigin(Vec3(0, 0, 0));
|
||||
skidding_rotation.setRotation
|
||||
@ -93,8 +93,8 @@ void Shadow::update(bool enabled)
|
||||
const btWheelInfo& wi = m_kart.getVehicle()->getWheelInfo(i);
|
||||
Vec3 up_vector = kart_trans.getBasis().getColumn(1);
|
||||
up_vector = up_vector * (wi.m_raycastInfo.m_suspensionLength - 0.02f);
|
||||
v[i].m_position =
|
||||
Vec3(kart_trans(Vec3(v[i].m_position)) - up_vector).toIrrVector();
|
||||
Vec3 pos = kart_trans(Vec3(v[i].m_position)) - up_vector;
|
||||
v[i].m_position = pos.toIrrVector();
|
||||
v[i].m_normal = MiniGLM::compressVector3
|
||||
(Vec3(wi.m_raycastInfo.m_contactNormalWS).toIrrVector());
|
||||
}
|
||||
|
@ -21,14 +21,17 @@
|
||||
|
||||
#include "config/stk_config.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_per_object_uniform.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_per_object_uniform.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
|
||||
@ -46,6 +49,9 @@ SkidMarks::SkidMarks(const AbstractKart& kart, float width) : m_kart(kart)
|
||||
"alphablend");
|
||||
m_shader = SP::SPShaderManager::get()->getSPShader("alphablend");
|
||||
assert(m_shader);
|
||||
auto texture = SP::SPTextureManager::get()->getTexture(
|
||||
m_material->getSamplerPath(0), m_material,
|
||||
m_shader->isSrgbForTextureLayer(0), m_material->getContainerId());
|
||||
m_skid_marking = false;
|
||||
} // SkidMark
|
||||
|
||||
@ -109,8 +115,18 @@ void SkidMarks::update(float dt, bool force_skid_marks,
|
||||
|
||||
Vec3 raycast_right;
|
||||
Vec3 raycast_left;
|
||||
vehicle->getVisualContactPoint(m_kart.getSkidding()->getVisualSkidRotation(),
|
||||
&raycast_left, &raycast_right);
|
||||
vehicle->getVisualContactPoint(m_kart.getSmoothedTrans(), &raycast_left,
|
||||
&raycast_right);
|
||||
|
||||
btTransform smoothed_inv = m_kart.getSmoothedTrans().inverse();
|
||||
Vec3 lc_l = smoothed_inv(raycast_left);
|
||||
Vec3 lc_r = smoothed_inv(raycast_right);
|
||||
btTransform skidding_rotation = m_kart.getSmoothedTrans();
|
||||
skidding_rotation.setRotation(m_kart.getSmoothedTrans().getRotation() *
|
||||
btQuaternion(m_kart.getSkidding()->getVisualSkidRotation(), 0.0f, 0.0f));
|
||||
raycast_left = skidding_rotation(lc_l);
|
||||
raycast_right = skidding_rotation(lc_r);
|
||||
|
||||
Vec3 delta = raycast_right - raycast_left;
|
||||
|
||||
// The kart is making skid marks when it's:
|
||||
@ -151,10 +167,11 @@ void SkidMarks::update(float dt, bool force_skid_marks,
|
||||
// but it produces good enough results
|
||||
float distance = (newPoint - start).length();
|
||||
|
||||
m_left.back()->add(raycast_left-delta, raycast_left+delta,
|
||||
m_kart.getNormal(), distance);
|
||||
m_right.back()->add(raycast_right-delta, raycast_right+delta,
|
||||
m_kart.getNormal(), distance);
|
||||
const Vec3 up_offset = (m_kart.getNormal() * 0.05f);
|
||||
m_left.back()->add(raycast_left - delta + up_offset,
|
||||
raycast_left + delta + up_offset, m_kart.getNormal(), distance);
|
||||
m_right.back()->add(raycast_right - delta + up_offset,
|
||||
raycast_right + delta + up_offset, m_kart.getNormal(), distance);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -185,14 +202,14 @@ void SkidMarks::update(float dt, bool force_skid_marks,
|
||||
}
|
||||
|
||||
m_left.emplace_back(
|
||||
new SkidMarkQuads(raycast_left-delta, raycast_left+delta,
|
||||
m_kart.getNormal(), m_material, m_shader,
|
||||
m_avoid_z_fighting, custom_color));
|
||||
new SkidMarkQuads(raycast_left - delta, raycast_left + delta,
|
||||
m_kart.getNormal(), m_material, m_shader, m_avoid_z_fighting,
|
||||
custom_color));
|
||||
|
||||
m_right.emplace_back(
|
||||
new SkidMarkQuads(raycast_right-delta, raycast_right+delta,
|
||||
m_kart.getNormal(), m_material, m_shader,
|
||||
m_avoid_z_fighting, custom_color));
|
||||
new SkidMarkQuads(raycast_right - delta, raycast_right + delta,
|
||||
m_kart.getNormal(), m_material, m_shader, m_avoid_z_fighting,
|
||||
custom_color));
|
||||
|
||||
m_skid_marking = true;
|
||||
} // update
|
||||
|
@ -218,7 +218,7 @@ void Skybox::generateSpecularCubemap()
|
||||
}
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
if (!CVS->isDeferredEnabled())
|
||||
if (!CVS->isDeferredEnabled() || !CVS->isARBTextureBufferObjectUsable())
|
||||
return;
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
|
@ -349,6 +349,7 @@ SP::SPMesh* SlipStream::createMesh(Material* material, bool bonus_mesh)
|
||||
buffer->setSPMVertices(vertices);
|
||||
buffer->setIndices(indices);
|
||||
buffer->setSTKMaterial(material);
|
||||
buffer->uploadGLMesh();
|
||||
|
||||
spm = new SP::SPMesh();
|
||||
spm->addSPMeshBuffer(buffer);
|
||||
|
@ -237,43 +237,47 @@ void resizeSkinning(unsigned number)
|
||||
const irr::core::matrix4 m;
|
||||
g_skinning_size = number;
|
||||
|
||||
#ifdef USE_GLES2
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, number, 0, GL_RGBA,
|
||||
GL_FLOAT, NULL);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL_RGBA, GL_FLOAT,
|
||||
m.pointer());
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
static std::vector<std::array<float, 16> >
|
||||
tmp_buf(stk_config->m_max_skinning_bones);
|
||||
g_joint_ptr = tmp_buf.data();
|
||||
|
||||
#else
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
if (CVS->isARBBufferStorageUsable())
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
glBufferStorage(GL_TEXTURE_BUFFER, number << 6, NULL,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 0, 64,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
memcpy(g_joint_ptr, m.pointer(), 64);
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 64, (number - 1) << 6,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, number, 0, GL_RGBA,
|
||||
GL_FLOAT, NULL);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL_RGBA, GL_FLOAT,
|
||||
m.pointer());
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
static std::vector<std::array<float, 16> >
|
||||
tmp_buf(stk_config->m_max_skinning_bones);
|
||||
g_joint_ptr = tmp_buf.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_TEXTURE_BUFFER, number << 6, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, 64, m.pointer());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_BUFFER, g_skinning_tex);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, g_skinning_buf);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
#ifndef USE_GLES2
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
if (CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glBufferStorage(GL_TEXTURE_BUFFER, number << 6, NULL,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 0, 64,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
memcpy(g_joint_ptr, m.pointer(), 64);
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 64, (number - 1) << 6,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_TEXTURE_BUFFER, number << 6, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, 64, m.pointer());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_BUFFER, g_skinning_tex);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, g_skinning_buf);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // resizeSkinning
|
||||
|
||||
@ -283,30 +287,35 @@ void initSkinning()
|
||||
static_assert(sizeof(std::array<float, 16>) == 64, "No padding");
|
||||
|
||||
int max_size = 0;
|
||||
#ifdef USE_GLES2
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
|
||||
|
||||
if (stk_config->m_max_skinning_bones > (unsigned)max_size)
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size);
|
||||
stk_config->m_max_skinning_bones = max_size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
|
||||
|
||||
if (stk_config->m_max_skinning_bones > (unsigned)max_size)
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size);
|
||||
stk_config->m_max_skinning_bones = max_size;
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: %u"
|
||||
" (max bones) * 16 RGBA float texture",
|
||||
stk_config->m_max_skinning_bones);
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: %u"
|
||||
" (max bones) * 16 RGBA float texture",
|
||||
stk_config->m_max_skinning_bones);
|
||||
#else
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size);
|
||||
if (stk_config->m_max_skinning_bones << 6 > (unsigned)max_size)
|
||||
else
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size >> 6);
|
||||
stk_config->m_max_skinning_bones = max_size >> 6;
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: TBO, "
|
||||
"max bones: %u", stk_config->m_max_skinning_bones);
|
||||
#ifndef USE_GLES2
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size);
|
||||
if (stk_config->m_max_skinning_bones << 6 > (unsigned)max_size)
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size >> 6);
|
||||
stk_config->m_max_skinning_bones = max_size >> 6;
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: TBO, "
|
||||
"max bones: %u", stk_config->m_max_skinning_bones);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Reserve 1 identity matrix for non-weighted vertices
|
||||
@ -314,7 +323,10 @@ void initSkinning()
|
||||
const irr::core::matrix4 m;
|
||||
glGenTextures(1, &g_skinning_tex);
|
||||
#ifndef USE_GLES2
|
||||
glGenBuffers(1, &g_skinning_buf);
|
||||
if (CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
glGenBuffers(1, &g_skinning_buf);
|
||||
}
|
||||
#endif
|
||||
resizeSkinning(stk_config->m_max_skinning_bones);
|
||||
|
||||
@ -581,7 +593,8 @@ void destroy()
|
||||
SPTextureManager::destroy();
|
||||
|
||||
#ifndef USE_GLES2
|
||||
if (CVS->isARBBufferStorageUsable())
|
||||
if (CVS->isARBTextureBufferObjectUsable() &&
|
||||
CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
@ -1160,7 +1173,8 @@ void uploadSkinningMatrices()
|
||||
|
||||
unsigned buffer_offset = 0;
|
||||
#ifndef USE_GLES2
|
||||
if (!CVS->isARBBufferStorageUsable())
|
||||
if (CVS->isARBTextureBufferObjectUsable() &&
|
||||
!CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
g_joint_ptr = (std::array<float, 16>*)
|
||||
@ -1178,13 +1192,17 @@ void uploadSkinningMatrices()
|
||||
buffer_offset += g_skinning_mesh[i]->getTotalJoints();
|
||||
}
|
||||
|
||||
#ifdef USE_GLES2
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 1, 4, buffer_offset, GL_RGBA,
|
||||
GL_FLOAT, g_joint_ptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#else
|
||||
if (!CVS->isARBBufferStorageUsable())
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 1, 4, buffer_offset, GL_RGBA,
|
||||
GL_FLOAT, g_joint_ptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
#ifndef USE_GLES2
|
||||
if (CVS->isARBTextureBufferObjectUsable() &&
|
||||
!CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
|
@ -28,17 +28,39 @@
|
||||
|
||||
namespace SP
|
||||
{
|
||||
const std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
g_prefilled_names =
|
||||
{
|
||||
#ifdef USE_GLES2
|
||||
{ "skinning_tex", { 0, ST_NEAREST_CLAMPED } }
|
||||
#else
|
||||
{ "skinning_tex", { 0, ST_TEXTURE_BUFFER } }
|
||||
#endif
|
||||
};
|
||||
std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
SPShader::m_prefilled_names;
|
||||
bool SPShader::m_sp_shader_debug = false;
|
||||
|
||||
SPShader::SPShader(const std::string& name,
|
||||
const std::function<void(SPShader*)>& init_func,
|
||||
bool transparent_shader, int drawing_priority,
|
||||
bool use_alpha_channel, bool use_tangents,
|
||||
const std::array<bool, 6>& srgb)
|
||||
: m_name(name), m_init_function(init_func),
|
||||
m_drawing_priority(drawing_priority),
|
||||
m_transparent_shader(transparent_shader),
|
||||
m_use_alpha_channel(use_alpha_channel),
|
||||
m_use_tangents(use_tangents), m_srgb(srgb)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
#ifndef USE_GLES2
|
||||
m_prefilled_names["skinning_tex"] = std::make_pair<unsigned,
|
||||
SamplerType>(0, ST_TEXTURE_BUFFER);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
m_prefilled_names["skinning_tex"] = std::make_pair<unsigned,
|
||||
SamplerType>(0, ST_NEAREST_CLAMPED);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(m_program, 0, 12);
|
||||
m_init_function(this);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::addShaderFile(const std::string& name, GLint shader_type,
|
||||
RenderPass rp)
|
||||
@ -104,7 +126,7 @@ void SPShader::addAllTextures(RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
// Built-in prefilled shaders first
|
||||
for (auto &p : g_prefilled_names)
|
||||
for (auto &p : m_prefilled_names)
|
||||
{
|
||||
const char* s = p.first.c_str();
|
||||
GLuint loc = glGetUniformLocation(m_program[rp], s);
|
||||
@ -175,8 +197,8 @@ void SPShader::bindPrefilledTextures(RenderPass rp) const
|
||||
for (auto& p : m_prefilled_samplers[rp])
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + std::get<0>(p));
|
||||
auto it = g_prefilled_names.find(std::get<1>(p));
|
||||
if (it != g_prefilled_names.end())
|
||||
auto it = m_prefilled_names.find(std::get<1>(p));
|
||||
if (it != m_prefilled_names.end())
|
||||
{
|
||||
glBindTexture(std::get<3>(p), sp_prefilled_tex[it->second.first]);
|
||||
glBindSampler(std::get<0>(p), getSampler(std::get<2>(p)));
|
||||
|
@ -113,22 +113,15 @@ private:
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
static bool m_sp_shader_debug;
|
||||
static std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
m_prefilled_names;
|
||||
// ------------------------------------------------------------------------
|
||||
SPShader(const std::string& name,
|
||||
const std::function<void(SPShader*)>& init_func,
|
||||
bool transparent_shader = false, int drawing_priority = 0,
|
||||
bool use_alpha_channel = false, bool use_tangents = false,
|
||||
const std::array<bool, 6>& srgb =
|
||||
{{ true, true, false, false, false, false }})
|
||||
: m_name(name), m_init_function(init_func),
|
||||
m_drawing_priority(drawing_priority),
|
||||
m_transparent_shader(transparent_shader),
|
||||
m_use_alpha_channel(use_alpha_channel),
|
||||
m_use_tangents(use_tangents), m_srgb(srgb)
|
||||
{
|
||||
memset(m_program, 0, 12);
|
||||
m_init_function(this);
|
||||
}
|
||||
{{ true, true, false, false, false, false }});
|
||||
// ------------------------------------------------------------------------
|
||||
~SPShader()
|
||||
{
|
||||
|
@ -87,8 +87,10 @@ void ScalableFont::draw(const core::stringw& text,
|
||||
bool hcenter, bool vcenter,
|
||||
const core::rect<s32>* clip)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
m_face->render(text, position, color, hcenter, vcenter, clip,
|
||||
m_font_settings);
|
||||
#endif
|
||||
} // draw
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -98,7 +100,6 @@ void ScalableFont::draw(const core::stringw& text,
|
||||
const core::rect<s32>* clip, bool ignoreRTL)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
bool previousRTL = m_font_settings->isRTL();
|
||||
if (ignoreRTL)
|
||||
m_font_settings->setRTL(false);
|
||||
|
@ -100,9 +100,7 @@ void Screen::init()
|
||||
*/
|
||||
void Screen::push()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
StateManager::get()->pushScreen(this);
|
||||
#endif
|
||||
} // push
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1262,15 +1262,15 @@ bool CGUIEditBox::processMouse(const SEvent& event)
|
||||
}
|
||||
else if (!m_rtl)
|
||||
{
|
||||
bool use_screen_keyboard = UserConfigParams::m_screen_keyboard;
|
||||
bool use_screen_keyboard = UserConfigParams::m_screen_keyboard > 1;
|
||||
|
||||
#ifdef ANDROID
|
||||
int32_t keyboard = AConfiguration_getKeyboard(
|
||||
global_android_app->config);
|
||||
|
||||
if (keyboard == ACONFIGURATION_KEYBOARD_QWERTY)
|
||||
if (UserConfigParams::m_screen_keyboard == 1)
|
||||
{
|
||||
use_screen_keyboard = false;
|
||||
int32_t keyboard = AConfiguration_getKeyboard(
|
||||
global_android_app->config);
|
||||
|
||||
use_screen_keyboard = (keyboard != ACONFIGURATION_KEYBOARD_QWERTY);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -154,11 +154,11 @@ namespace GUIEngine
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** \brief override from base class */
|
||||
virtual EventPropagation focused(const int playerID);
|
||||
virtual EventPropagation focused(const int playerID) OVERRIDE;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** \brief override from base class */
|
||||
virtual void unfocused(const int playerID, Widget* new_focus);
|
||||
virtual void unfocused(const int playerID, Widget* new_focus) OVERRIDE;
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the texture of this button. */
|
||||
const video::ITexture* getTexture();
|
||||
|
@ -35,7 +35,6 @@ using namespace irr::core;
|
||||
using namespace irr;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
std::string kart_group, bool multiplayer,
|
||||
bool display_icons) : Widget(WTYPE_DIV)
|
||||
@ -87,7 +86,6 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
} // KartStatsWidget
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void KartStatsWidget::setValues(const KartProperties* props,
|
||||
PerPlayerDifficulty d)
|
||||
{
|
||||
@ -99,7 +97,9 @@ void KartStatsWidget::setValues(const KartProperties* props,
|
||||
race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD);
|
||||
KartProperties kp_computed;
|
||||
kp_computed.copyForPlayer(props, d);
|
||||
|
||||
for (SkillLevelWidget* skills : m_skills)
|
||||
skills->setVisible(true);
|
||||
|
||||
// Scale the values so they look better
|
||||
// The scaling factor and offset were found by trial and error.
|
||||
// It should look nice and you should be able to see the difference between
|
||||
@ -122,17 +122,25 @@ void KartStatsWidget::setValues(const KartProperties* props,
|
||||
m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id);
|
||||
|
||||
race_manager->setDifficulty(previous_difficulty);
|
||||
}
|
||||
} // setValues
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void KartStatsWidget::hideAll()
|
||||
{
|
||||
for (SkillLevelWidget* skills : m_skills)
|
||||
skills->setVisible(false);
|
||||
} // hideAll
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void KartStatsWidget::add()
|
||||
{
|
||||
for (int i = 0; i < SKILL_COUNT; ++i) {
|
||||
for (int i = 0; i < SKILL_COUNT; ++i)
|
||||
{
|
||||
m_skills[i]->add();
|
||||
}
|
||||
}
|
||||
} // add
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void KartStatsWidget::move(int x, int y, int w, int h)
|
||||
{
|
||||
Widget::move(x,y,w,h);
|
||||
@ -148,25 +156,27 @@ void KartStatsWidget::move(int x, int y, int w, int h)
|
||||
m_skill_bar_w,
|
||||
m_skill_bar_h);
|
||||
}
|
||||
} //move
|
||||
} // move
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// ---- set value for given type
|
||||
/** Set value for given type
|
||||
*/
|
||||
void KartStatsWidget::setValue(Stats type, int value)
|
||||
{
|
||||
m_skills[type]->setValue(value);
|
||||
} //setValue
|
||||
} // setValue
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// ---- get value for given type
|
||||
/** Get value for given type
|
||||
*/
|
||||
int KartStatsWidget::getValue(Stats type)
|
||||
{
|
||||
return m_skills[type]->getValue();
|
||||
} // getVAlue
|
||||
|
||||
// ---- set size for widgets inside KartStatsWidget
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Set size for widgets inside KartStatsWidget
|
||||
*/
|
||||
void KartStatsWidget::setSize(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
m_x = x;
|
||||
@ -189,6 +199,7 @@ void KartStatsWidget::setSize(const int x, const int y, const int w, const int h
|
||||
m_skill_bar_y = y + h/2 - m_skill_bar_h/2;
|
||||
} // setSize
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void KartStatsWidget::setDisplayIcons(bool display_icons)
|
||||
{
|
||||
for (int i = 0; i < SKILL_COUNT; ++i)
|
||||
@ -196,6 +207,3 @@ void KartStatsWidget::setDisplayIcons(bool display_icons)
|
||||
m_skills[i]->setDisplayIcon(display_icons);
|
||||
}
|
||||
} // setDisplayText
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
@ -97,6 +97,8 @@ namespace GUIEngine
|
||||
|
||||
void setValues(const KartProperties* props, PerPlayerDifficulty d);
|
||||
|
||||
void hideAll();
|
||||
|
||||
/** Change the value of the widget, it must be a percent. */
|
||||
void setValue(Stats type, int value);
|
||||
|
||||
|
@ -302,9 +302,9 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
fgets(s, 256, stdin);
|
||||
int t;
|
||||
StringUtils::fromString(s,t);
|
||||
RewindManager::get()->rewindTo(t, world->getTimeTicks());
|
||||
RewindManager::get()->rewindTo(t, world->getTicksSinceStart());
|
||||
Log::info("Rewind", "Rewinding from %d to %d",
|
||||
world->getTimeTicks(), t);
|
||||
world->getTicksSinceStart(), t);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -340,11 +340,13 @@ void MultitouchDevice::updateAxisX(float value)
|
||||
if (value < -m_deadzone_center)
|
||||
{
|
||||
float factor = getSteeringFactor(std::abs(value));
|
||||
m_controller->action(PA_STEER_RIGHT, 0);
|
||||
m_controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
|
||||
}
|
||||
else if (value > m_deadzone_center)
|
||||
{
|
||||
float factor = getSteeringFactor(std::abs(value));
|
||||
m_controller->action(PA_STEER_LEFT, 0);
|
||||
m_controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
|
||||
}
|
||||
else
|
||||
@ -398,6 +400,10 @@ void MultitouchDevice::handleControls(MultitouchButton* button)
|
||||
{
|
||||
updateAxisY(button->axis_y);
|
||||
}
|
||||
else if (button->type == MultitouchButtonType::BUTTON_ESCAPE)
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button->action != PA_BEFORE_FIRST)
|
||||
|
@ -70,6 +70,7 @@ namespace irr {
|
||||
|
||||
std::vector<std::string> FileManager::m_root_dirs;
|
||||
std::string FileManager::m_stdout_filename = "stdout.log";
|
||||
std::string FileManager::m_stdout_dir;
|
||||
|
||||
#ifdef __APPLE__
|
||||
// dynamic data path detection onmac
|
||||
@ -927,6 +928,12 @@ void FileManager::checkAndCreateConfigDir()
|
||||
"falling back to '.'.", m_user_config_dir.c_str());
|
||||
m_user_config_dir = "./";
|
||||
}
|
||||
|
||||
if (m_stdout_dir.empty())
|
||||
{
|
||||
m_stdout_dir = m_user_config_dir;
|
||||
}
|
||||
|
||||
return;
|
||||
} // checkAndCreateConfigDir
|
||||
|
||||
@ -1165,6 +1172,20 @@ void FileManager::setStdoutName(const std::string& filename)
|
||||
m_stdout_filename = filename;
|
||||
} // setStdoutName
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the directory for the stdout log file.
|
||||
* \param dir Directory to use
|
||||
*/
|
||||
void FileManager::setStdoutDir(const std::string& dir)
|
||||
{
|
||||
m_stdout_dir = dir;
|
||||
|
||||
if (!m_stdout_dir.empty() && m_stdout_dir[m_stdout_dir.size() - 1] != '/')
|
||||
{
|
||||
m_stdout_dir += "/";
|
||||
}
|
||||
} // setStdoutDir
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Redirects output to go into files in the user's config directory
|
||||
* instead of to the console. It keeps backup copies of previous stdout files
|
||||
@ -1174,7 +1195,7 @@ void FileManager::redirectOutput()
|
||||
{
|
||||
// Do a simple log rotate: stdout.log.2 becomes stdout.log.3 etc
|
||||
const int NUM_BACKUPS=3;
|
||||
std::string logoutfile = getUserConfigFile(m_stdout_filename);
|
||||
std::string logoutfile = m_stdout_dir + m_stdout_filename;
|
||||
for(int i=NUM_BACKUPS; i>1; i--)
|
||||
{
|
||||
std::ostringstream out_old;
|
||||
|
@ -83,6 +83,9 @@ private:
|
||||
|
||||
/** Name of stdout file. */
|
||||
static std::string m_stdout_filename;
|
||||
|
||||
/** Directory of stdout file. */
|
||||
static std::string m_stdout_dir;
|
||||
|
||||
/** Directory to store screenshots in. */
|
||||
std::string m_screenshot_dir;
|
||||
@ -133,6 +136,7 @@ public:
|
||||
void init();
|
||||
static void addRootDirs(const std::string &roots);
|
||||
static void setStdoutName(const std::string &name);
|
||||
static void setStdoutDir(const std::string &dir);
|
||||
io::IXMLReader *createXMLReader(const std::string &filename);
|
||||
XMLNode *createXMLTree(const std::string &filename);
|
||||
XMLNode *createXMLTreeFromString(const std::string & content);
|
||||
|
@ -148,11 +148,6 @@ void Attachment::set(AttachmentType type, int ticks,
|
||||
case ATTACH_BOMB:
|
||||
m_node->setMesh(attachment_manager->getMesh(type));
|
||||
m_node->setAnimationSpeed(0);
|
||||
if (m_bomb_sound) m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = SFXManager::get()->createSoundSource("clock");
|
||||
m_bomb_sound->setLoop(true);
|
||||
m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
m_bomb_sound->play();
|
||||
break;
|
||||
default:
|
||||
m_node->setMesh(attachment_manager->getMesh(type));
|
||||
@ -229,23 +224,12 @@ void Attachment::clear()
|
||||
m_plugin = NULL;
|
||||
}
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
m_type=ATTACH_NOTHING;
|
||||
|
||||
m_ticks_left = 0;
|
||||
m_node->setVisible(false);
|
||||
m_node->setPosition(core::vector3df());
|
||||
m_node->setRotation(core::vector3df());
|
||||
|
||||
// Resets the weight of the kart if the previous attachment affected it
|
||||
// (e.g. anvil). This must be done *after* setting m_type to
|
||||
// ATTACH_NOTHING in order to reset the physics parameters.
|
||||
m_kart->updateWeight();
|
||||
} // clear
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -287,16 +271,7 @@ void Attachment::rewindTo(BareNetworkString *buffer)
|
||||
|
||||
int ticks_left = buffer->getUInt32();
|
||||
|
||||
// Attaching an object can be expensive (loading new models, ...)
|
||||
// so avoid doing this if there is no change in attachment type
|
||||
if(new_type == m_type)
|
||||
{
|
||||
setTicksLeft(ticks_left);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now it is a new attachment:
|
||||
|
||||
if (type == (ATTACH_BOMB | 0x80)) // we have previous owner information
|
||||
{
|
||||
uint8_t kart_id = buffer->getUInt8();
|
||||
@ -306,8 +281,22 @@ void Attachment::rewindTo(BareNetworkString *buffer)
|
||||
{
|
||||
m_previous_owner = NULL;
|
||||
}
|
||||
|
||||
// Attaching an object can be expensive (loading new models, ...)
|
||||
// so avoid doing this if there is no change in attachment type
|
||||
// Don't use set to reset a model on local player if it's already cleared
|
||||
// (or m_initial_speed is redone / model is re-shown again when rewinding)
|
||||
if (m_type == new_type || m_type == ATTACH_NOTHING)
|
||||
{
|
||||
setTicksLeft(ticks_left);
|
||||
if (m_type != new_type)
|
||||
m_type = new_type;
|
||||
return;
|
||||
}
|
||||
|
||||
set(new_type, ticks_left, m_previous_owner);
|
||||
} // rewindTo
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Called when going forwards in time during a rewind.
|
||||
* \param buffer Buffer with the rewind information.
|
||||
@ -356,7 +345,7 @@ void Attachment::hitBanana(ItemState *item_state)
|
||||
// Use this as a basic random number to make sync with server easier.
|
||||
// Divide by 16 to increase probablity to have same time as server in
|
||||
// case of a few physics frames different between client and server.
|
||||
int ticks = World::getWorld()->getTimeTicks() / 16;
|
||||
int ticks = World::getWorld()->getTicksSinceStart() / 16;
|
||||
switch(getType()) // If there already is an attachment, make it worse :)
|
||||
{
|
||||
case ATTACH_BOMB:
|
||||
@ -412,7 +401,7 @@ void Attachment::hitBanana(ItemState *item_state)
|
||||
// if going very slowly or backwards,
|
||||
// braking won't remove parachute
|
||||
if(m_initial_speed <= 1.5) m_initial_speed = 1.5;
|
||||
break ;
|
||||
break;
|
||||
case ATTACH_ANVIL:
|
||||
set(ATTACH_ANVIL, stk_config->time2Ticks(kp->getAnvilDuration())
|
||||
+ leftover_ticks );
|
||||
@ -421,13 +410,13 @@ void Attachment::hitBanana(ItemState *item_state)
|
||||
// Reduce speed once (see description above), all other changes are
|
||||
// handled in Kart::updatePhysics
|
||||
m_kart->adjustSpeed(kp->getAnvilSpeedFactor());
|
||||
m_kart->updateWeight();
|
||||
break ;
|
||||
break;
|
||||
case ATTACH_BOMB:
|
||||
set( ATTACH_BOMB, stk_config->time2Ticks(stk_config->m_bomb_time)
|
||||
+ leftover_ticks );
|
||||
|
||||
break ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
} // hitBanana
|
||||
@ -510,12 +499,10 @@ void Attachment::update(int ticks)
|
||||
|
||||
m_ticks_left -= ticks;
|
||||
|
||||
|
||||
bool is_shield = m_type == ATTACH_BUBBLEGUM_SHIELD ||
|
||||
m_type == ATTACH_NOLOK_BUBBLEGUM_SHIELD;
|
||||
float m_wanted_node_scale = is_shield
|
||||
? std::max(1.0f, m_kart->getHighestPoint()*1.1f)
|
||||
: 1.0f;
|
||||
float wanted_node_scale = is_shield ?
|
||||
std::max(1.0f, m_kart->getHighestPoint() * 1.1f) : 1.0f;
|
||||
int slow_flashes = stk_config->time2Ticks(3.0f);
|
||||
if (is_shield && m_ticks_left < slow_flashes)
|
||||
{
|
||||
@ -532,11 +519,11 @@ void Attachment::update(int ticks)
|
||||
}
|
||||
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
if (m_node_scale < m_wanted_node_scale)
|
||||
if (m_node_scale < wanted_node_scale)
|
||||
{
|
||||
m_node_scale += dt*1.5f;
|
||||
if (m_node_scale > m_wanted_node_scale)
|
||||
m_node_scale = m_wanted_node_scale;
|
||||
if (m_node_scale > wanted_node_scale)
|
||||
m_node_scale = wanted_node_scale;
|
||||
m_node->setScale(core::vector3df(m_node_scale,m_node_scale,
|
||||
m_node_scale) );
|
||||
}
|
||||
@ -589,8 +576,6 @@ void Attachment::update(int ticks)
|
||||
break;
|
||||
case ATTACH_BOMB:
|
||||
{
|
||||
if (m_bomb_sound) m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
|
||||
// Mesh animation frames are 1 to 61 frames (60 steps)
|
||||
// The idea is change second by second, counterclockwise 60 to 0 secs
|
||||
// If longer times needed, it should be a surprise "oh! bomb activated!"
|
||||
@ -608,12 +593,6 @@ void Attachment::update(int ticks)
|
||||
he->setLocalPlayerKartHit();
|
||||
projectile_manager->addHitEffect(he);
|
||||
ExplosionAnimation::create(m_kart);
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -621,11 +600,14 @@ void Attachment::update(int ticks)
|
||||
case ATTACH_NOLOK_BUBBLEGUM_SHIELD:
|
||||
if (m_ticks_left <= 0)
|
||||
{
|
||||
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
|
||||
m_bubble_explode_sound =
|
||||
SFXManager::get()->createSoundSource("bubblegum_explode");
|
||||
m_bubble_explode_sound->setPosition(m_kart->getXYZ());
|
||||
m_bubble_explode_sound->play();
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
{
|
||||
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
|
||||
m_bubble_explode_sound =
|
||||
SFXManager::get()->createSoundSource("bubblegum_explode");
|
||||
m_bubble_explode_sound->setPosition(m_kart->getXYZ());
|
||||
m_bubble_explode_sound->play();
|
||||
}
|
||||
|
||||
ItemManager::get()->dropNewItem(Item::ITEM_BUBBLEGUM, m_kart);
|
||||
}
|
||||
@ -633,10 +615,38 @@ void Attachment::update(int ticks)
|
||||
} // switch
|
||||
|
||||
// Detach attachment if its time is up.
|
||||
if ( m_ticks_left <= 0)
|
||||
if (m_ticks_left <= 0)
|
||||
clear();
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Attachment::updateGraphics(float dt)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case ATTACH_BOMB:
|
||||
{
|
||||
if (!m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound = SFXManager::get()->createSoundSource("clock");
|
||||
m_bomb_sound->setLoop(true);
|
||||
m_bomb_sound->play();
|
||||
}
|
||||
m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
} // updateGraphics
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Return the additional weight of the attachment (some attachments slow
|
||||
* karts down by also making them heavier).
|
||||
|
@ -116,6 +116,8 @@ public:
|
||||
~Attachment();
|
||||
void clear ();
|
||||
void hitBanana(ItemState *item);
|
||||
void updateGraphics(float dt);
|
||||
|
||||
void update(int ticks);
|
||||
void handleCollisionWithKart(AbstractKart *other);
|
||||
void set (AttachmentType type, int ticks,
|
||||
@ -154,6 +156,15 @@ public:
|
||||
/** Nothing to undo when going back during a rewind, the full state info
|
||||
* will take care of creating the right attachment. */
|
||||
virtual void undo(BareNetworkString *buffer) { }
|
||||
// ------------------------------------------------------------------------
|
||||
float getInitialSpeed() const { return m_initial_speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setInitialSpeed(float speed) { m_initial_speed = speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
float getNodeScale() const { return m_node_scale; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setNodeScale(float scale) { m_node_scale = scale; }
|
||||
|
||||
}; // Attachment
|
||||
|
||||
#endif
|
||||
|
@ -378,7 +378,8 @@ void Flyable::setAnimation(AbstractKartAnimation *animation)
|
||||
*/
|
||||
void Flyable::updateGraphics(float dt)
|
||||
{
|
||||
Moveable::updateGraphics(dt, Vec3(0, 0, 0), btQuaternion(0, 0, 0, 1));
|
||||
updateSmoothedGraphics(dt);
|
||||
Moveable::updateGraphics();
|
||||
} // updateGraphics
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -204,7 +204,7 @@ public:
|
||||
void setHasHit () { m_has_hit_something = true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Resets this flyable. */
|
||||
void reset () { Moveable::reset(); }
|
||||
void reset() OVERRIDE { Moveable::reset(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the type of flyable. */
|
||||
PowerupManager::PowerupType getType() const {return m_type;}
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "tracks/arena_graph.hpp"
|
||||
#include "tracks/arena_node.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <IMesh.h>
|
||||
@ -49,7 +48,7 @@ std::vector<scene::IMesh *> ItemManager::m_item_lowres_mesh;
|
||||
std::vector<video::SColorf> ItemManager::m_glow_color;
|
||||
bool ItemManager::m_disable_item_collection = false;
|
||||
ItemManager * ItemManager::m_item_manager = NULL;
|
||||
|
||||
std::mt19937 ItemManager::m_random_engine;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Creates one instance of the item manager. */
|
||||
@ -577,11 +576,11 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
||||
invalid_location.push_back(node);
|
||||
}
|
||||
|
||||
RandomGenerator random;
|
||||
const unsigned int ALL_NODES = ag->getNumNodes();
|
||||
const unsigned int MIN_DIST = int(sqrt(ALL_NODES));
|
||||
const unsigned int TOTAL_ITEM = MIN_DIST / 2;
|
||||
|
||||
std::vector<uint32_t> random_numbers;
|
||||
Log::info("[ItemManager]","Creating %d random items for arena", TOTAL_ITEM);
|
||||
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
|
||||
{
|
||||
@ -595,8 +594,9 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
||||
"Use default item location.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const int node = random.get(ALL_NODES);
|
||||
uint32_t number = m_random_engine();
|
||||
Log::debug("[ItemManager]", "%u from random engine.", number);
|
||||
const int node = number % ALL_NODES;
|
||||
|
||||
// Check if tried
|
||||
std::vector<int>::iterator it = std::find(invalid_location.begin(),
|
||||
@ -622,6 +622,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
||||
{
|
||||
chosen_node = node;
|
||||
invalid_location.push_back(node);
|
||||
random_numbers.push_back(number);
|
||||
break;
|
||||
}
|
||||
else
|
||||
@ -635,7 +636,8 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
||||
for (unsigned int i = 0; i < pos.size(); i++)
|
||||
used_location.erase(used_location.begin());
|
||||
|
||||
assert (used_location.size() == TOTAL_ITEM);
|
||||
assert(used_location.size() == TOTAL_ITEM);
|
||||
assert(random_numbers.size() == TOTAL_ITEM);
|
||||
|
||||
// Hard-coded ratio for now
|
||||
const int BONUS_BOX = 4;
|
||||
@ -644,7 +646,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
||||
|
||||
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
|
||||
{
|
||||
const int j = random.get(10);
|
||||
const unsigned j = random_numbers[i] % 10;
|
||||
ItemState::ItemType type = (j > BONUS_BOX ? ItemState::ITEM_BONUS_BOX :
|
||||
j > NITRO_BIG ? ItemState::ITEM_NITRO_BIG :
|
||||
j > NITRO_SMALL ? ItemState::ITEM_NITRO_SMALL : ItemState::ITEM_BANANA);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -56,6 +57,7 @@ private:
|
||||
/** Disable item collection (for debugging purposes). */
|
||||
static bool m_disable_item_collection;
|
||||
|
||||
static std::mt19937 m_random_engine;
|
||||
protected:
|
||||
/** The instance of ItemManager while a race is on. */
|
||||
static ItemManager *m_item_manager;
|
||||
@ -64,6 +66,11 @@ public:
|
||||
static void removeTextures();
|
||||
static void create();
|
||||
static void destroy();
|
||||
static void updateRandomSeed(uint32_t seed_number)
|
||||
{
|
||||
m_random_engine.seed(seed_number);
|
||||
} // updateRandomSeed
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** Disable item collection, useful to test client mispreditions or
|
||||
* client/server disagreements. */
|
||||
@ -115,7 +122,6 @@ protected:
|
||||
virtual ~ItemManager();
|
||||
|
||||
public:
|
||||
|
||||
virtual Item* placeItem (ItemState::ItemType type, const Vec3& xyz,
|
||||
const Vec3 &normal);
|
||||
virtual Item* dropNewItem (ItemState::ItemType type,
|
||||
|
@ -39,7 +39,7 @@ void NetworkItemManager::create()
|
||||
/** Creates a new instance of the item manager. This is done at startup
|
||||
* of each race. */
|
||||
NetworkItemManager::NetworkItemManager()
|
||||
: Rewinder(/*can be deleted*/false),
|
||||
: Rewinder("N", /*can be deleted*/false),
|
||||
ItemManager()
|
||||
{
|
||||
m_last_confirmed_item_ticks.clear();
|
||||
@ -62,6 +62,10 @@ NetworkItemManager::NetworkItemManager()
|
||||
*/
|
||||
NetworkItemManager::~NetworkItemManager()
|
||||
{
|
||||
for (ItemState* is : m_confirmed_state)
|
||||
{
|
||||
delete is;
|
||||
}
|
||||
} // ~NetworkItemManager
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -71,9 +75,9 @@ void NetworkItemManager::reset()
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Copies the initial state at the start of a race as confirmed state.
|
||||
/** Initialize state at the start of a race.
|
||||
*/
|
||||
void NetworkItemManager::saveInitialState()
|
||||
void NetworkItemManager::initClientConfirmState()
|
||||
{
|
||||
m_confirmed_state_time = 0;
|
||||
|
||||
@ -83,7 +87,7 @@ void NetworkItemManager::saveInitialState()
|
||||
ItemState *is = new ItemState(*i);
|
||||
m_confirmed_state.push_back(is);
|
||||
}
|
||||
} // saveInitialState
|
||||
} // initClientConfirmState
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart collects an item. In network games only the server
|
||||
@ -97,7 +101,7 @@ void NetworkItemManager::collectedItem(Item *item, AbstractKart *kart)
|
||||
{
|
||||
// The server saves the collected item as item event info
|
||||
m_item_events.lock();
|
||||
m_item_events.getData().emplace_back(World::getWorld()->getTimeTicks(),
|
||||
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
||||
item->getItemId(),
|
||||
kart->getWorldKartId());
|
||||
m_item_events.unlock();
|
||||
@ -132,7 +136,7 @@ Item* NetworkItemManager::dropNewItem(ItemState::ItemType type,
|
||||
|
||||
// Server: store the data for this event:
|
||||
m_item_events.lock();
|
||||
m_item_events.getData().emplace_back(World::getWorld()->getTimeTicks(),
|
||||
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
||||
type, item->getItemId(),
|
||||
kart->getWorldKartId(),
|
||||
kart->getXYZ());
|
||||
@ -193,14 +197,9 @@ void NetworkItemManager::setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
||||
* to save the initial state, which is the first confirmed state by all
|
||||
* clients.
|
||||
*/
|
||||
BareNetworkString* NetworkItemManager::saveState()
|
||||
BareNetworkString* NetworkItemManager::saveState(std::vector<std::string>* ru)
|
||||
{
|
||||
if(NetworkConfig::get()->isClient())
|
||||
{
|
||||
saveInitialState();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ru->push_back(getUniqueIdentity());
|
||||
// On the server:
|
||||
// ==============
|
||||
m_item_events.lock();
|
||||
@ -247,7 +246,7 @@ void NetworkItemManager::forwardTime(int ticks)
|
||||
void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
{
|
||||
assert(NetworkConfig::get()->isClient());
|
||||
// The state at World::getTimeTicks() needs to be restored. The confirmed
|
||||
// The state at World::getTicksSinceStart() needs to be restored. The confirmed
|
||||
// state in this instance was taken at m_confirmed_state_time. First
|
||||
// forward this confirmed state to the current time (i.e. world time).
|
||||
// This is done in several steps:
|
||||
@ -279,6 +278,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
|
||||
// 2) Apply all events to current confirmed state:
|
||||
int current_time = m_confirmed_state_time;
|
||||
bool has_state = count > 0;
|
||||
while(count > 0)
|
||||
{
|
||||
// 1) Decode the event in the message
|
||||
@ -332,11 +332,14 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
} // while count >0
|
||||
|
||||
// Inform the server which events have been received.
|
||||
if (auto gp = GameProtocol::lock())
|
||||
gp->sendItemEventConfirmation(World::getWorld()->getTimeTicks());
|
||||
if (has_state)
|
||||
{
|
||||
if (auto gp = GameProtocol::lock())
|
||||
gp->sendItemEventConfirmation(World::getWorld()->getTicksSinceStart());
|
||||
}
|
||||
|
||||
// Forward the confirmed item state till the world time:
|
||||
int dt = World::getWorld()->getTimeTicks() - current_time;
|
||||
int dt = World::getWorld()->getTicksSinceStart() - current_time;
|
||||
if(dt>0) forwardTime(dt);
|
||||
|
||||
// Restore the state to the current world time:
|
||||
@ -364,6 +367,6 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
}
|
||||
|
||||
// Now we save the current local
|
||||
m_confirmed_state_time = World::getWorld()->getTimeTicks();
|
||||
m_confirmed_state_time = World::getWorld()->getTicksSinceStart();
|
||||
} // restoreState
|
||||
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
|
||||
void setSwitchItems(const std::vector<int> &switch_items);
|
||||
void sendItemUpdate();
|
||||
void saveInitialState();
|
||||
void initClientConfirmState();
|
||||
|
||||
virtual void reset() OVERRIDE;
|
||||
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
||||
@ -76,7 +76,8 @@ public:
|
||||
virtual void collectedItem(Item *item, AbstractKart *kart) OVERRIDE;
|
||||
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
||||
const Vec3 *xyz=NULL) OVERRIDE;
|
||||
virtual BareNetworkString* saveState() OVERRIDE;
|
||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
||||
OVERRIDE;
|
||||
virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void rewindToEvent(BareNetworkString *bns) OVERRIDE {};
|
||||
|
@ -348,7 +348,6 @@ void Powerup::use()
|
||||
kart->getAttachment()->set(Attachment::ATTACH_ANVIL,
|
||||
stk_config->
|
||||
time2Ticks(kp->getAnvilDuration()) );
|
||||
kart->updateWeight();
|
||||
kart->adjustSpeed(kp->getAnvilSpeedFactor() * 0.5f);
|
||||
|
||||
// should we position the sound at the kart that is hit,
|
||||
@ -505,7 +504,7 @@ void Powerup::hitBonusBox(const ItemState &item_state)
|
||||
// number to spread the random values across the (typically 200)
|
||||
// weights used in the PowerupManager - same for the position.
|
||||
int random_number = item_state.getItemId()*31
|
||||
+ world->getTimeTicks() / 10 + position*23;
|
||||
+ world->getTicksSinceStart() / 10 + position*23;
|
||||
new_powerup =
|
||||
powerup_manager->getRandomPowerup(position, &n, random_number);
|
||||
if (new_powerup != PowerupManager::POWERUP_RUBBERBALL ||
|
||||
@ -515,7 +514,7 @@ void Powerup::hitBonusBox(const ItemState &item_state)
|
||||
}
|
||||
|
||||
if(new_powerup == PowerupManager::POWERUP_RUBBERBALL)
|
||||
powerup_manager->setBallCollectTicks(world->getTimeTicks());
|
||||
powerup_manager->setBallCollectTicks(world->getTicksSinceStart());
|
||||
|
||||
// Always add a new powerup in ITEM_MODE_NEW (or if the kart
|
||||
// doesn't have a powerup atm).
|
||||
|
@ -416,7 +416,7 @@ int PowerupManager::WeightsData::getRandomItem(int rank, int random_number)
|
||||
// We don't do more, because it would need to be decoded from enum later
|
||||
#ifdef ITEM_DISTRIBUTION_DEBUG
|
||||
Log::verbose("Powerup", "World %d rank %d random %d %d item %d",
|
||||
World::getWorld()->getTimeTicks(), rank, random_number,
|
||||
World::getWorld()->getTicksSinceStart(), rank, random_number,
|
||||
original_random_number, powerup);
|
||||
#endif
|
||||
|
||||
|
@ -204,8 +204,8 @@ public:
|
||||
virtual ~RubberBall();
|
||||
static void init(const XMLNode &node, scene::IMesh *rubberball);
|
||||
virtual bool updateAndDelete(int ticks) OVERRIDE;
|
||||
virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL);
|
||||
virtual void setAnimation(AbstractKartAnimation *animation);
|
||||
virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL) OVERRIDE;
|
||||
virtual void setAnimation(AbstractKartAnimation *animation) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns time (in ticks) between rubberballs, to avoid that in games
|
||||
* with many karts too many rubber balls are in play at the same time. */
|
||||
|
@ -47,7 +47,7 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||
{
|
||||
m_attached_state = RB_TO_PLUNGER;
|
||||
#ifndef SERVER_ONLY
|
||||
if (ProfileWorld::isNoGraphics())
|
||||
if (ProfileWorld::isNoGraphics() || !CVS->isGLSL())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
return m_animation_phase == SWATTER_AIMING;
|
||||
} // isSwatterReady
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void onAnimationEnd();
|
||||
virtual void onAnimationEnd() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
// Functions related to controlling the kart
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current steering value for this kart. */
|
||||
float getSteerPercent() const { return m_controls.getSteer(); }
|
||||
virtual float getSteerPercent() const { return m_controls.getSteer(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns all controls of this kart. */
|
||||
KartControl& getControls() { return m_controls; }
|
||||
@ -140,7 +140,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a unique identifier for this kart (name of the directory the
|
||||
* kart was loaded from). */
|
||||
const std::string& getIdent() const;
|
||||
virtual const std::string& getIdent() const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the maximum steering angle for this kart, which depends on the
|
||||
* speed. */
|
||||
@ -279,10 +279,6 @@ public:
|
||||
* like Ghost. */
|
||||
virtual float getSpeed() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the exponentially smoothened speed of the kart in
|
||||
* which is removes shaking from camera. */
|
||||
virtual float getSmoothedSpeed() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current maximum speed for this kart, this includes all
|
||||
* bonus and maluses that are currently applied. */
|
||||
virtual float getCurrentMaxSpeed() const = 0;
|
||||
@ -434,10 +430,6 @@ public:
|
||||
* over. */
|
||||
virtual void startEngineSFX() = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** This method is to be called every time the mass of the kart is updated,
|
||||
* which includes attaching an anvil to the kart (and detaching). */
|
||||
virtual void updateWeight() = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Multiplies the velocity of the kart by a factor f (both linear
|
||||
* and angular). This is used by anvils, which suddenly slow down the kart
|
||||
* when they are attached. */
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
|
||||
/** Constructor. Note that kart can be NULL in case that the animation is
|
||||
@ -81,6 +83,28 @@ AbstractKartAnimation::~AbstractKartAnimation()
|
||||
{
|
||||
m_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
|
||||
Physics::getInstance()->addKart(m_kart);
|
||||
if (RewindManager::get()->useLocalEvent())
|
||||
{
|
||||
AbstractKart* kart = m_kart;
|
||||
Vec3 linear_velocity = kart->getBody()->getLinearVelocity();
|
||||
Vec3 angular_velocity = kart->getBody()->getAngularVelocity();
|
||||
btTransform transform = kart->getBody()->getWorldTransform();
|
||||
RewindManager::get()->getRewindQueue().insertRewindInfo(new
|
||||
RewindInfoEventFunction(
|
||||
World::getWorld()->getTicksSinceStart(),
|
||||
[kart]()
|
||||
{
|
||||
Physics::getInstance()->removeKart(kart);
|
||||
},
|
||||
[kart, linear_velocity, angular_velocity, transform]()
|
||||
{
|
||||
Physics::getInstance()->addKart(kart);
|
||||
kart->getBody()->setLinearVelocity(linear_velocity);
|
||||
kart->getBody()->setAngularVelocity(angular_velocity);
|
||||
kart->getBody()->proceedToTransform(transform);
|
||||
kart->setTrans(transform);
|
||||
}));
|
||||
}
|
||||
}
|
||||
} // ~AbstractKartAnimation
|
||||
|
||||
|
@ -335,7 +335,7 @@ void AIBaseController::saveState(BareNetworkString *buffer) const
|
||||
{
|
||||
// Endcontroller needs this for proper offset in kart rewinder
|
||||
// Must match the number of bytes in Playercontroller.
|
||||
buffer->addUInt32(0).addUInt32(0).addUInt32(0).addUInt8(0).addUInt32(0);
|
||||
buffer->addUInt32(0).addUInt32(0).addUInt8(0);
|
||||
} // copyToBuffer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -343,5 +343,5 @@ void AIBaseController::rewindTo(BareNetworkString *buffer)
|
||||
{
|
||||
// Endcontroller needs this for proper offset in kart rewinder.
|
||||
// Skip the same number of bytes as PlayerController.
|
||||
buffer->skip(4 * 4 + 1);
|
||||
buffer->skip(4 * 2 + 1);
|
||||
} // rewindTo
|
||||
|
@ -65,7 +65,7 @@ protected:
|
||||
* for AI testing only. */
|
||||
static int m_test_ai;
|
||||
|
||||
void setControllerName(const std::string &name);
|
||||
void setControllerName(const std::string &name) OVERRIDE;
|
||||
float steerToPoint(const Vec3 &point);
|
||||
float normalizeAngle(float angle);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -75,7 +75,7 @@ protected:
|
||||
// ------------------------------------------------------------------------
|
||||
void determineTurnRadius(const Vec3 &end, Vec3 *center,
|
||||
float *radius) const;
|
||||
virtual void update(int ticks);
|
||||
virtual void update(int ticks) OVERRIDE;
|
||||
virtual void setSteering (float angle, float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return true if AI can skid now. */
|
||||
@ -84,7 +84,7 @@ protected:
|
||||
public:
|
||||
AIBaseController(AbstractKart *kart);
|
||||
virtual ~AIBaseController() {};
|
||||
virtual void reset();
|
||||
virtual void reset() OVERRIDE;
|
||||
virtual bool disableSlipstreamBonus() const OVERRIDE;
|
||||
virtual void crashed(const Material *m) OVERRIDE;
|
||||
static void enableDebug() {m_ai_debug = true; }
|
||||
@ -98,11 +98,11 @@ public:
|
||||
virtual void setPosition(int p) OVERRIDE {};
|
||||
virtual bool isPlayerController() const OVERRIDE { return false; }
|
||||
virtual bool isLocalPlayerController() const OVERRIDE { return false; }
|
||||
virtual bool action(PlayerAction action, int value, bool dry_run=false) OVERRIDE
|
||||
virtual bool action(PlayerAction action, int value, bool dry_run=false) OVERRIDE
|
||||
{
|
||||
return true;
|
||||
};
|
||||
virtual void skidBonusTriggered() {};
|
||||
virtual void skidBonusTriggered() OVERRIDE {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void saveState(BareNetworkString *buffer) const OVERRIDE;
|
||||
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE;
|
||||
|
@ -163,12 +163,14 @@ void EndController::newLap(int lap)
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The end controller must forward 'fire' presses to the race gui.
|
||||
*/
|
||||
void EndController::action(PlayerAction action, int value)
|
||||
bool EndController::action(PlayerAction action, int value, bool dry_run)
|
||||
{
|
||||
if(action!=PA_FIRE) return;
|
||||
RaceResultGUI *race_result_gui = dynamic_cast<RaceResultGUI*>(World::getWorld()->getRaceGUI());
|
||||
if(!race_result_gui) return;
|
||||
if(action!=PA_FIRE) return true;
|
||||
RaceResultGUI *race_result_gui =
|
||||
dynamic_cast<RaceResultGUI*>(World::getWorld()->getRaceGUI());
|
||||
if(!race_result_gui) return true;
|
||||
race_result_gui->nextPhase();
|
||||
return true;
|
||||
} // action
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -86,7 +86,8 @@ public:
|
||||
~EndController();
|
||||
virtual void update (int ticks) ;
|
||||
virtual void reset ();
|
||||
virtual void action (PlayerAction action, int value);
|
||||
virtual bool action (PlayerAction action, int value,
|
||||
bool dry_run = false);
|
||||
virtual void newLap (int lap);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool canGetAchievements() const
|
||||
|
@ -62,8 +62,8 @@ public:
|
||||
bool dry_run=false) OVERRIDE;
|
||||
virtual void skidBonusTriggered() OVERRIDE {}
|
||||
virtual void newLap(int lap) OVERRIDE {}
|
||||
virtual void saveState(BareNetworkString *buffer) const {};
|
||||
virtual void rewindTo(BareNetworkString *buffer) {};
|
||||
virtual void saveState(BareNetworkString *buffer) const OVERRIDE {}
|
||||
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE {}
|
||||
|
||||
void addReplayTime(float time);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -150,6 +150,13 @@ void LocalPlayerController::resetInputState()
|
||||
bool LocalPlayerController::action(PlayerAction action, int value,
|
||||
bool dry_run)
|
||||
{
|
||||
// Pause race doesn't need to be sent to server
|
||||
if (action == PA_PAUSE_RACE)
|
||||
{
|
||||
PlayerController::action(action, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this event does not change the control state (e.g.
|
||||
// it's a (auto) repeat event), do nothing. This especially
|
||||
// optimises traffic to the server and other clients.
|
||||
@ -160,9 +167,9 @@ bool LocalPlayerController::action(PlayerAction action, int value,
|
||||
history->addEvent(m_kart->getWorldKartId(), action, value);
|
||||
|
||||
// If this is a client, send the action to networking layer
|
||||
if (World::getWorld()->isNetworkWorld() &&
|
||||
NetworkConfig::get()->isClient() &&
|
||||
!RewindManager::get()->isRewinding() )
|
||||
if (World::getWorld()->isNetworkWorld() &&
|
||||
NetworkConfig::get()->isClient() &&
|
||||
!RewindManager::get()->isRewinding())
|
||||
{
|
||||
if (auto gp = GameProtocol::lock())
|
||||
{
|
||||
@ -305,7 +312,7 @@ void LocalPlayerController::setPosition(int p)
|
||||
d*/
|
||||
void LocalPlayerController::finishedRace(float time)
|
||||
{
|
||||
// This will implicitely trigger setting the first end camera to be active
|
||||
// This will implicitly trigger setting the first end camera to be active
|
||||
Camera::changeCamera(m_camera_index, Camera::CM_TYPE_END);
|
||||
} // finishedRace
|
||||
|
||||
|
@ -62,6 +62,7 @@ private:
|
||||
virtual void steer(int, int) OVERRIDE;
|
||||
virtual void displayPenaltyWarning() OVERRIDE;
|
||||
void nitroNotFullSound();
|
||||
|
||||
public:
|
||||
LocalPlayerController(AbstractKart *kart,
|
||||
const int local_player_id,
|
||||
@ -87,7 +88,6 @@ public:
|
||||
/** Returns the name of the player profile. */
|
||||
core::stringw getName() const OVERRIDE;
|
||||
|
||||
|
||||
}; // LocalPlayerController
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "karts/rescue_animation.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_player_profile.hpp"
|
||||
#include "network/protocols/lobby_protocol.hpp"
|
||||
@ -107,7 +108,12 @@ void PlayerController::resetInputState()
|
||||
*/
|
||||
bool PlayerController::action(PlayerAction action, int value, bool dry_run)
|
||||
{
|
||||
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
!NetworkConfig::get()->isServer())
|
||||
{
|
||||
if (m_penalty_ticks > 0)
|
||||
return false;
|
||||
}
|
||||
/** If dry_run (parameter) is true, this macro tests if this action would
|
||||
* trigger a state change in the specified variable (without actually
|
||||
* doing it). If it will trigger a state change, the macro will
|
||||
@ -171,7 +177,7 @@ bool PlayerController::action(PlayerAction action, int value, bool dry_run)
|
||||
break;
|
||||
case PA_ACCEL:
|
||||
SET_OR_TEST(m_prev_accel, value);
|
||||
if (value && !(m_penalty_ticks > 0))
|
||||
if (value)
|
||||
{
|
||||
SET_OR_TEST_GETTER(Accel, value/32768.0f);
|
||||
SET_OR_TEST_GETTER(Brake, false);
|
||||
@ -247,7 +253,7 @@ void PlayerController::actionFromNetwork(PlayerAction p_action, int value,
|
||||
{
|
||||
m_steer_val_l = value_l;
|
||||
m_steer_val_r = value_r;
|
||||
action(p_action, value);
|
||||
PlayerController::action(p_action, value, /*dry_run*/false);
|
||||
} // actionFromNetwork
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -322,13 +328,6 @@ void PlayerController::update(int ticks)
|
||||
{
|
||||
steer(ticks, m_steer_val);
|
||||
|
||||
if (World::getWorld()->getPhase() == World::GOAL_PHASE)
|
||||
{
|
||||
m_controls->setBrake(false);
|
||||
m_controls->setAccel(0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (World::getWorld()->isStartPhase())
|
||||
{
|
||||
if (m_controls->getAccel() || m_controls->getBrake()||
|
||||
@ -351,9 +350,11 @@ void PlayerController::update(int ticks)
|
||||
return;
|
||||
} // if isStartPhase
|
||||
|
||||
if (m_penalty_ticks>0)
|
||||
if (!RewindManager::get()->isRewinding() && m_penalty_ticks > 0)
|
||||
{
|
||||
m_penalty_ticks-=ticks;
|
||||
m_penalty_ticks -= ticks;
|
||||
m_controls->setBrake(false);
|
||||
m_controls->setAccel(0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -380,9 +381,8 @@ void PlayerController::saveState(BareNetworkString *buffer) const
|
||||
{
|
||||
// NOTE: when the size changes, the AIBaseController::saveState and
|
||||
// restore state MUST be adjusted!!
|
||||
buffer->addUInt32(m_steer_val).addUInt32(m_steer_val_l)
|
||||
.addUInt32(m_steer_val_r).addUInt8(m_prev_brake)
|
||||
.addUInt32(m_prev_accel);
|
||||
buffer->addUInt32(m_steer_val).addUInt32(m_prev_accel)
|
||||
.addUInt8(m_prev_brake);
|
||||
} // copyToBuffer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -390,11 +390,9 @@ void PlayerController::rewindTo(BareNetworkString *buffer)
|
||||
{
|
||||
// NOTE: when the size changes, the AIBaseController::saveState and
|
||||
// restore state MUST be adjusted!!
|
||||
m_steer_val = buffer->getUInt32();
|
||||
m_steer_val_l = buffer->getUInt32();
|
||||
m_steer_val_r = buffer->getUInt32();
|
||||
m_prev_brake = buffer->getUInt8();
|
||||
m_prev_accel = buffer->getUInt32();
|
||||
m_steer_val = buffer->getUInt32();
|
||||
m_prev_accel = buffer->getUInt32();
|
||||
m_prev_brake = buffer->getUInt8();
|
||||
} // rewindTo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -26,6 +26,7 @@ class Player;
|
||||
|
||||
class PlayerController : public Controller
|
||||
{
|
||||
friend class KartRewinder;
|
||||
protected:
|
||||
int m_steer_val, m_steer_val_l, m_steer_val_r;
|
||||
int m_prev_accel;
|
||||
|
@ -89,7 +89,8 @@ void GhostKart::updateGraphics(float dt)
|
||||
|
||||
// Don't call Kart's updateGraphics, since it assumes physics. Instead
|
||||
// immediately call Moveable's updateGraphics.
|
||||
Moveable::updateGraphics(dt, center_shift, btQuaternion(0, 0, 0, 1));
|
||||
Moveable::updateSmoothedGraphics(dt);
|
||||
Moveable::updateGraphics(center_shift, btQuaternion(0, 0, 0, 1));
|
||||
} // updateGraphics
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -59,9 +59,6 @@ public:
|
||||
virtual void updateGraphics(float dt) OVERRIDE;
|
||||
virtual void reset() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** No physics body for ghost kart, so nothing to adjust. */
|
||||
virtual void updateWeight() OVERRIDE {};
|
||||
// ------------------------------------------------------------------------
|
||||
/** No physics for ghost kart. */
|
||||
virtual void applyEngineForce (float force) OVERRIDE {};
|
||||
// ------------------------------------------------------------------------
|
||||
@ -93,7 +90,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time at which the kart was at a given distance.
|
||||
* Returns -1.0f if none */
|
||||
float getTimeForDistance(float distance);
|
||||
virtual float getTimeForDistance(float distance) OVERRIDE;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the smallest time at which the kart had the required number of eggs
|
||||
|
@ -165,7 +165,6 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
||||
// Set position and heading:
|
||||
m_reset_transform = init_transform;
|
||||
m_speed = 0.0f;
|
||||
m_smoothed_speed = 0.0f;
|
||||
m_last_factor_engine_sound = 0.0f;
|
||||
|
||||
m_kart_model->setKart(this);
|
||||
@ -352,6 +351,9 @@ void Kart::reset()
|
||||
m_kart_gfx->reset();
|
||||
m_skidding->reset();
|
||||
|
||||
m_weight = 0.0f;
|
||||
updateWeight();
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_collision_particles)
|
||||
m_collision_particles->setCreationRateAbsolute(0.0f);
|
||||
@ -372,7 +374,6 @@ void Kart::reset()
|
||||
m_brake_ticks = 0;
|
||||
m_ticks_last_crash = 0;
|
||||
m_speed = 0.0f;
|
||||
m_smoothed_speed = 0.0f;
|
||||
m_current_lean = 0.0f;
|
||||
m_falling_time = 0.0f;
|
||||
m_view_blocked_by_plunger = 0;
|
||||
@ -858,10 +859,13 @@ void Kart::adjustSpeed(float f)
|
||||
void Kart::updateWeight()
|
||||
{
|
||||
float mass = m_kart_properties->getMass() + m_attachment->weightAdjust();
|
||||
|
||||
btVector3 inertia;
|
||||
m_kart_chassis.calculateLocalInertia(mass, inertia);
|
||||
m_body->setMassProps(mass, inertia);
|
||||
if (m_weight != mass)
|
||||
{
|
||||
m_weight = mass;
|
||||
btVector3 inertia;
|
||||
m_kart_chassis.calculateLocalInertia(mass, inertia);
|
||||
m_body->setMassProps(mass, inertia);
|
||||
}
|
||||
} // updateWeight
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -1276,9 +1280,6 @@ void Kart::update(int ticks)
|
||||
// Reset any instand speed increase in the bullet kart
|
||||
m_vehicle->setMinSpeed(0);
|
||||
|
||||
// update star effect (call will do nothing if stars are not activated)
|
||||
m_stars_effect->update(stk_config->ticks2Time(ticks));
|
||||
|
||||
if(m_squash_ticks>=0)
|
||||
{
|
||||
m_squash_ticks-=ticks;
|
||||
@ -1317,22 +1318,25 @@ void Kart::update(int ticks)
|
||||
// Moveable::update() ), otherwise 'stuttering' can happen (caused by
|
||||
// graphical and physical position not being the same).
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
if (has_animation_before)
|
||||
if (has_animation_before && !RewindManager::get()->isRewinding())
|
||||
{
|
||||
m_kart_animation->update(dt);
|
||||
}
|
||||
|
||||
m_time_previous_counter += dt;
|
||||
while (m_time_previous_counter > stk_config->ticks2Time(1))
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
{
|
||||
m_previous_xyz[0] = getXYZ();
|
||||
m_previous_xyz_times[0] = World::getWorld()->getTime();
|
||||
for (int i=m_xyz_history_size-1;i>0;i--)
|
||||
m_time_previous_counter += dt;
|
||||
while (m_time_previous_counter > stk_config->ticks2Time(1))
|
||||
{
|
||||
m_previous_xyz[i] = m_previous_xyz[i-1];
|
||||
m_previous_xyz_times[i] = m_previous_xyz_times[i-1];
|
||||
m_previous_xyz[0] = getXYZ();
|
||||
m_previous_xyz_times[0] = World::getWorld()->getTime();
|
||||
for (int i=m_xyz_history_size-1;i>0;i--)
|
||||
{
|
||||
m_previous_xyz[i] = m_previous_xyz[i-1];
|
||||
m_previous_xyz_times[i] = m_previous_xyz_times[i-1];
|
||||
}
|
||||
m_time_previous_counter -= stk_config->ticks2Time(1);
|
||||
}
|
||||
m_time_previous_counter -= stk_config->ticks2Time(1);
|
||||
}
|
||||
|
||||
// Update the position and other data taken from the physics (or
|
||||
@ -1391,7 +1395,8 @@ void Kart::update(int ticks)
|
||||
m_invulnerable_ticks -= ticks;
|
||||
}
|
||||
|
||||
m_slipstream->update(ticks);
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
m_slipstream->update(ticks);
|
||||
|
||||
// TODO: hiker said this probably will be moved to btKart or so when updating bullet engine.
|
||||
// Neutralize any yaw change if the kart leaves the ground, so the kart falls more or less
|
||||
@ -1424,8 +1429,6 @@ void Kart::update(int ticks)
|
||||
|
||||
m_attachment->update(ticks);
|
||||
|
||||
m_kart_gfx->update(dt);
|
||||
if (m_collision_particles) m_collision_particles->update(dt);
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Kart::updatePhysics", 0x60, 0x34, 0x7F);
|
||||
updatePhysics(ticks);
|
||||
@ -1446,19 +1449,6 @@ void Kart::update(int ticks)
|
||||
m_fire_clicked = 1;
|
||||
}
|
||||
|
||||
/* (TODO: add back when properly done)
|
||||
for (int n = 0; n < SFXManager::NUM_CUSTOMS; n++)
|
||||
{
|
||||
if (m_custom_sounds[n] != NULL) m_custom_sounds[n]->position ( getXYZ() );
|
||||
}
|
||||
*/
|
||||
|
||||
for (int i = 0; i < EMITTER_COUNT; i++)
|
||||
m_emitters[i]->setPosition(getXYZ());
|
||||
|
||||
m_skid_sound->setPosition ( getXYZ() );
|
||||
m_nitro_sound->setPosition ( getXYZ() );
|
||||
|
||||
// Check if a kart is (nearly) upside down and not moving much -->
|
||||
// automatic rescue
|
||||
// But only do this if auto-rescue is enabled (i.e. it will be disabled in
|
||||
@ -1509,7 +1499,7 @@ void Kart::update(int ticks)
|
||||
"maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f "
|
||||
"noderot(45) %f suslen %f",
|
||||
getIdent().c_str(),
|
||||
World::getWorld()->getTime(), World::getWorld()->getTimeTicks(),
|
||||
World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(),
|
||||
getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(),
|
||||
m_body->getWorldTransform().getOrigin().getX(),
|
||||
m_body->getWorldTransform().getOrigin().getY(),
|
||||
@ -1581,7 +1571,7 @@ void Kart::update(int ticks)
|
||||
Track::getCurrentTrack()->getAABB(&min, &max);
|
||||
|
||||
if((min->getY() - getXYZ().getY() > 17 || dist_to_sector > 25) && !m_flying &&
|
||||
!getKartAnimation())
|
||||
!has_animation_before)
|
||||
{
|
||||
new RescueAnimation(this);
|
||||
m_last_factor_engine_sound = 0.0f;
|
||||
@ -1602,7 +1592,7 @@ void Kart::update(int ticks)
|
||||
}
|
||||
body->setGravity(gravity);
|
||||
} // if !flying
|
||||
if (material->isDriveReset() && isOnGround())
|
||||
if (!has_animation_before && material->isDriveReset() && isOnGround())
|
||||
{
|
||||
new RescueAnimation(this);
|
||||
m_last_factor_engine_sound = 0.0f;
|
||||
@ -1621,7 +1611,7 @@ void Kart::update(int ticks)
|
||||
if(UserConfigParams::m_material_debug)
|
||||
{
|
||||
Log::info("Kart","World %d %s\tfraction %f\ttime %d.",
|
||||
World::getWorld()->getTimeTicks(),
|
||||
World::getWorld()->getTicksSinceStart(),
|
||||
material->getTexFname().c_str(),
|
||||
material->getMaxSpeedFraction(),
|
||||
material->getSlowDownTicks() );
|
||||
@ -1633,7 +1623,7 @@ void Kart::update(int ticks)
|
||||
|
||||
ItemManager::get()->checkItemHit(this);
|
||||
|
||||
const bool emergency = getKartAnimation()!=NULL;
|
||||
const bool emergency = has_animation_before;
|
||||
|
||||
if (emergency)
|
||||
{
|
||||
@ -1645,11 +1635,13 @@ void Kart::update(int ticks)
|
||||
}
|
||||
}
|
||||
|
||||
if (RewindManager::get()->isRewinding())
|
||||
return;
|
||||
// Remove the shadow if the kart is not on the ground (if a kart
|
||||
// is rescued isOnGround might still be true, since the kart rigid
|
||||
// body was removed from the physics, but still retain the old
|
||||
// values for the raycasts).
|
||||
if (!isOnGround() && !getKartAnimation())
|
||||
if (!isOnGround() && !has_animation_before)
|
||||
{
|
||||
const Material *m = getMaterial();
|
||||
const Material *last_m = getLastMaterial();
|
||||
@ -1684,7 +1676,7 @@ void Kart::update(int ticks)
|
||||
m_is_jumping = false;
|
||||
m_kart_model->setAnimation(KartModel::AF_DEFAULT);
|
||||
|
||||
if (!getKartAnimation())
|
||||
if (!has_animation_before)
|
||||
{
|
||||
HitEffect *effect = new Explosion(getXYZ(), "jump",
|
||||
"jump_explosion.xml");
|
||||
@ -1694,21 +1686,6 @@ void Kart::update(int ticks)
|
||||
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Kart::handleRewoundTransform()
|
||||
{
|
||||
if (!m_controller->isLocalPlayerController())
|
||||
{
|
||||
if (RewindManager::get()->isRewinding())
|
||||
m_rewound_transforms.push_back(getTrans());
|
||||
else if (!m_rewound_transforms.empty())
|
||||
{
|
||||
setTrans(m_rewound_transforms.front());
|
||||
m_rewound_transforms.pop_front();
|
||||
}
|
||||
}
|
||||
} // handleRewoundTransform
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the local speed based on the current physical velocity. The value
|
||||
* is smoothed exponentially to avoid camera stuttering (camera distance
|
||||
@ -1740,9 +1717,6 @@ void Kart::updateSpeed()
|
||||
m_speed = -m_speed;
|
||||
}
|
||||
|
||||
float f = 0.3f;
|
||||
m_smoothed_speed = f*m_speed + (1.0f - f)*m_smoothed_speed;
|
||||
|
||||
// At low velocity, forces on kart push it back and forth so we ignore this
|
||||
// - quick'n'dirty workaround for bug 1776883
|
||||
if (fabsf(m_speed) < 0.2f ||
|
||||
@ -1750,7 +1724,6 @@ void Kart::updateSpeed()
|
||||
dynamic_cast<ExplosionAnimation*>( getKartAnimation() ) )
|
||||
{
|
||||
m_speed = 0;
|
||||
m_smoothed_speed = 0;
|
||||
}
|
||||
} // updateSpeed
|
||||
|
||||
@ -2077,8 +2050,12 @@ void Kart::handleZipper(const Material *material, bool play_sound)
|
||||
stk_config->time2Ticks(duration),
|
||||
stk_config->time2Ticks(fade_out_time));
|
||||
// Play custom character sound (weee!)
|
||||
playCustomSFX(SFXManager::CUSTOM_ZIPPER);
|
||||
m_controller->handleZipper(play_sound);
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
{
|
||||
playCustomSFX(SFXManager::CUSTOM_ZIPPER);
|
||||
m_controller->handleZipper(play_sound);
|
||||
}
|
||||
|
||||
} // handleZipper
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -2103,10 +2080,11 @@ void Kart::updateNitro(int ticks)
|
||||
m_min_nitro_ticks = 1;
|
||||
}
|
||||
|
||||
bool rewinding = RewindManager::get()->isRewinding();
|
||||
bool increase_speed = (m_min_nitro_ticks > 0 && isOnGround());
|
||||
if (!increase_speed && m_min_nitro_ticks <= 0)
|
||||
{
|
||||
if (m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
if (m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING && !rewinding)
|
||||
m_nitro_sound->stop();
|
||||
return;
|
||||
}
|
||||
@ -2115,7 +2093,7 @@ void Kart::updateNitro(int ticks)
|
||||
m_collected_energy -= dt * m_kart_properties->getNitroConsumption();
|
||||
if (m_collected_energy < 0)
|
||||
{
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING && !rewinding)
|
||||
m_nitro_sound->stop();
|
||||
m_collected_energy = 0;
|
||||
return;
|
||||
@ -2123,7 +2101,7 @@ void Kart::updateNitro(int ticks)
|
||||
|
||||
if (increase_speed)
|
||||
{
|
||||
if(m_nitro_sound->getStatus() != SFXBase::SFX_PLAYING)
|
||||
if(m_nitro_sound->getStatus() != SFXBase::SFX_PLAYING && !rewinding)
|
||||
m_nitro_sound->play();
|
||||
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
|
||||
m_kart_properties->getNitroMaxSpeedIncrease(),
|
||||
@ -2133,7 +2111,7 @@ void Kart::updateNitro(int ticks)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING && !rewinding)
|
||||
m_nitro_sound->stop();
|
||||
}
|
||||
} // updateNitro
|
||||
@ -2364,7 +2342,8 @@ void Kart::playCrashSFX(const Material* m, AbstractKart *k)
|
||||
void Kart::beep()
|
||||
{
|
||||
// If the custom horn can't play (isn't defined) then play the default one
|
||||
if (!playCustomSFX(SFXManager::CUSTOM_HORN))
|
||||
if (!playCustomSFX(SFXManager::CUSTOM_HORN) &&
|
||||
!RewindManager::get()->isRewinding())
|
||||
{
|
||||
getNextEmitter()->play(getXYZ(), m_horn_sound);
|
||||
}
|
||||
@ -2558,6 +2537,7 @@ void Kart::updateEngineSFX(float dt)
|
||||
*/
|
||||
void Kart::updateEnginePowerAndBrakes(int ticks)
|
||||
{
|
||||
updateWeight();
|
||||
updateNitro(ticks);
|
||||
float engine_power = getActualWheelForce();
|
||||
|
||||
@ -2576,7 +2556,7 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
|
||||
{
|
||||
// For a short time after a collision disable the engine,
|
||||
// so that the karts can bounce back a bit from the obstacle.
|
||||
if(m_bounce_back_ticks>0.0f)
|
||||
if (m_bounce_back_ticks > 0)
|
||||
engine_power = 0.0f;
|
||||
// let a player going backwards accelerate quickly (e.g. if a player
|
||||
// hits a wall, he needs to be able to start again quickly after
|
||||
@ -2960,25 +2940,27 @@ SFXBase* Kart::getNextEmitter()
|
||||
*/
|
||||
void Kart::updateGraphics(float dt)
|
||||
{
|
||||
static video::SColor pink(255, 255, 133, 253);
|
||||
static video::SColor green(255, 61, 87, 23);
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
// draw skidmarks if relevant (we force pink skidmarks on when hitting
|
||||
// a bubblegum)
|
||||
if (m_kart_properties->getSkidEnabled() && m_skidmarks)
|
||||
/* (TODO: add back when properly done)
|
||||
for (int n = 0; n < SFXManager::NUM_CUSTOMS; n++)
|
||||
{
|
||||
m_skidmarks->update(dt,
|
||||
m_bubblegum_ticks > 0,
|
||||
(m_bubblegum_ticks > 0
|
||||
? (m_has_caught_nolok_bubblegum ? &green
|
||||
: &pink)
|
||||
: NULL));
|
||||
if (m_custom_sounds[n] != NULL) m_custom_sounds[n]->position(getXYZ());
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
for (int i = 0; i < EMITTER_COUNT; i++)
|
||||
m_emitters[i]->setPosition(getXYZ());
|
||||
m_skid_sound->setPosition(getXYZ());
|
||||
m_nitro_sound->setPosition(getXYZ());
|
||||
|
||||
m_attachment->updateGraphics(dt);
|
||||
|
||||
// update star effect (call will do nothing if stars are not activated)
|
||||
m_stars_effect->update(dt);
|
||||
|
||||
// Upate particle effects (creation rate, and emitter size
|
||||
// depending on speed)
|
||||
m_kart_gfx->update(dt);
|
||||
if (m_collision_particles) m_collision_particles->update(dt);
|
||||
|
||||
// --------------------------------------------------------
|
||||
float nitro_frac = 0;
|
||||
if ( (m_controls.getNitro() || m_min_nitro_ticks > 0) &&
|
||||
@ -2992,7 +2974,7 @@ void Kart::updateGraphics(float dt)
|
||||
if(nitro_frac>1.0f) nitro_frac = 1.0f;
|
||||
}
|
||||
m_kart_gfx->updateNitroGraphics(nitro_frac);
|
||||
|
||||
|
||||
// Handle leaning of karts
|
||||
// -----------------------
|
||||
// Note that we compare with maximum speed of the kart, not
|
||||
@ -3054,16 +3036,34 @@ void Kart::updateGraphics(float dt)
|
||||
// To avoid this, raise the kart enough to offset the leaning.
|
||||
float lean_height = tan(m_current_lean) * getKartWidth()*0.5f;
|
||||
|
||||
Vec3 center_shift(0, 0, 0);
|
||||
Moveable::updateSmoothedGraphics(dt);
|
||||
|
||||
// Update the skidding jump height:
|
||||
Vec3 center_shift(0, 0, 0);
|
||||
float jump_height = m_skidding->updateGraphics(dt);
|
||||
center_shift.setY(jump_height + fabsf(lean_height) + m_graphical_y_offset);
|
||||
center_shift = getTrans().getBasis() * center_shift;
|
||||
center_shift = getSmoothedTrans().getBasis() * center_shift;
|
||||
|
||||
float heading = m_skidding->getVisualSkidRotation();
|
||||
Moveable::updateGraphics(dt, center_shift,
|
||||
btQuaternion(heading, 0, -m_current_lean));
|
||||
Moveable::updateGraphics(center_shift,
|
||||
btQuaternion(heading, 0, -m_current_lean));
|
||||
|
||||
static video::SColor pink(255, 255, 133, 253);
|
||||
static video::SColor green(255, 61, 87, 23);
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
// draw skidmarks if relevant (we force pink skidmarks on when hitting
|
||||
// a bubblegum)
|
||||
if (m_kart_properties->getSkidEnabled() && m_skidmarks)
|
||||
{
|
||||
m_skidmarks->update(dt,
|
||||
m_bubblegum_ticks > 0,
|
||||
(m_bubblegum_ticks > 0
|
||||
? (m_has_caught_nolok_bubblegum ? &green
|
||||
: &pink)
|
||||
: NULL));
|
||||
}
|
||||
#endif
|
||||
|
||||
// m_speed*dt is the distance the kart has moved, which determines
|
||||
// how much the wheels need to rotate.
|
||||
@ -3172,7 +3172,8 @@ const float Kart::getRecentPreviousXYZTime() const
|
||||
// ------------------------------------------------------------------------
|
||||
void Kart::playSound(SFXBuffer* buffer)
|
||||
{
|
||||
getNextEmitter()->play(getXYZ(), buffer);
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
getNextEmitter()->play(getXYZ(), buffer);
|
||||
} // playSound
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <SColor.h>
|
||||
|
||||
class AbstractKartAnimation;
|
||||
@ -215,6 +214,8 @@ protected:
|
||||
|
||||
float m_falling_time;
|
||||
|
||||
float m_weight;
|
||||
|
||||
/** When a kart has its view blocked by the plunger, this variable will be
|
||||
* > 0 the number it contains is the time left before removing plunger. */
|
||||
int m_view_blocked_by_plunger;
|
||||
@ -251,10 +252,8 @@ protected:
|
||||
int m_ticks_last_crash;
|
||||
RaceManager::KartType m_type;
|
||||
|
||||
std::deque<btTransform> m_rewound_transforms;
|
||||
|
||||
/** To prevent using nitro in too short bursts */
|
||||
int m_min_nitro_ticks;
|
||||
int8_t m_min_nitro_ticks;
|
||||
|
||||
void updatePhysics(int ticks);
|
||||
void handleMaterialSFX();
|
||||
@ -268,7 +267,7 @@ protected:
|
||||
float getActualWheelForce();
|
||||
void playCrashSFX(const Material* m, AbstractKart *k);
|
||||
void loadData(RaceManager::KartType type, bool animatedModel);
|
||||
|
||||
void updateWeight();
|
||||
public:
|
||||
Kart(const std::string& ident, unsigned int world_kart_id,
|
||||
int position, const btTransform& init_transform,
|
||||
@ -279,7 +278,6 @@ public:
|
||||
virtual void kartIsInRestNow() OVERRIDE;
|
||||
virtual void updateGraphics(float dt) OVERRIDE;
|
||||
virtual void createPhysics ();
|
||||
virtual void updateWeight () OVERRIDE;
|
||||
virtual float getSpeedForTurnRadius(float radius) const OVERRIDE;
|
||||
virtual float getMaxSteerAngle(float speed) const;
|
||||
virtual bool isInRest () const OVERRIDE;
|
||||
@ -423,7 +421,7 @@ public:
|
||||
* skidding related values) - non-const. */
|
||||
virtual Skidding *getSkidding() OVERRIDE { return m_skidding; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual RaceManager::KartType getType() const { return m_type; }
|
||||
virtual RaceManager::KartType getType() const OVERRIDE { return m_type; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the bullet vehicle which represents this kart. */
|
||||
virtual btKart *getVehicle() const OVERRIDE { return m_vehicle; }
|
||||
@ -431,12 +429,9 @@ public:
|
||||
/** Returns the speed of the kart in meters/second. */
|
||||
virtual float getSpeed() const OVERRIDE { return m_speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the speed of the kart in meters/second. */
|
||||
virtual float getSmoothedSpeed() const OVERRIDE { return m_smoothed_speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** This is used on the client side only to set the speed of the kart
|
||||
* from the server information. */
|
||||
virtual void setSpeed(float s) OVERRIDE { m_speed = s; }
|
||||
* from the server information. */
|
||||
virtual void setSpeed(float s) OVERRIDE { m_speed = s; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual btQuaternion getVisualRotation() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
@ -456,7 +451,7 @@ public:
|
||||
virtual Controller* getController() OVERRIDE { return m_controller; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the controller of this kart (const version). */
|
||||
const Controller* getController() const { return m_controller; }
|
||||
const Controller* getController() const OVERRIDE { return m_controller; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** True if the wheels are touching the ground. */
|
||||
virtual bool isOnGround() const OVERRIDE;
|
||||
@ -528,7 +523,7 @@ public:
|
||||
virtual const Vec3& getRecentPreviousXYZ() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time at which the recent previous position occured */
|
||||
virtual const float getRecentPreviousXYZTime() const;
|
||||
virtual const float getRecentPreviousXYZTime() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** For debugging only: check if a kart is flying. */
|
||||
bool isFlying() const { return m_flying; }
|
||||
@ -550,9 +545,6 @@ public:
|
||||
virtual void playSound(SFXBuffer* buffer) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool isVisible() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
void handleRewoundTransform();
|
||||
|
||||
}; // Kart
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_color = video::SColor(255, 0, 0, 0);
|
||||
m_shape = 32; // close enough to a circle.
|
||||
m_engine_sfx_type = "engine_small";
|
||||
m_nitro_min_consumption = 0.53f;
|
||||
m_nitro_min_consumption = 64;
|
||||
// The default constructor for stk_config uses filename=""
|
||||
if (filename != "")
|
||||
{
|
||||
@ -1003,15 +1003,6 @@ float KartProperties::getNitroDuration() const
|
||||
} // getNitroDuration
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns minimum time during which nitro is consumed when pressing nitro
|
||||
* key, to prevent using nitro in very short bursts
|
||||
*/
|
||||
int KartProperties::getNitroMinConsumptionTicks() const
|
||||
{
|
||||
return stk_config->time2Ticks(m_nitro_min_consumption);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
float KartProperties::getNitroEngineForce() const
|
||||
{
|
||||
return m_cached_characteristic->getNitroEngineForce();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user