Merge branch 'master' into Characteristics
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
@@ -0,0 +1,8 @@
|
||||
brew "libogg"
|
||||
brew "libvorbis"
|
||||
brew "openal-soft"
|
||||
brew "freetype"
|
||||
brew "curl"
|
||||
brew "openssl@1.1"
|
||||
brew "fribidi"
|
||||
brew "glew"
|
||||
138
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)
|
||||
@@ -116,6 +113,7 @@ if(WIN32)
|
||||
set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/${DEPENDENCIES})
|
||||
add_definitions(-D_IRR_STATIC_LIB_)
|
||||
add_definitions(-DNO_IRR_COMPILE_WITH_X11_)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/include)
|
||||
endif()
|
||||
|
||||
if(USE_GLES2)
|
||||
@@ -125,13 +123,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 +133,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 +169,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 +182,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 +298,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 +387,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 +410,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 +480,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 +494,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)
|
||||
|
||||
34
INSTALL.md
@@ -98,17 +98,26 @@ location, specify `CMAKE_INSTALL_PREFIX` when running cmake, e.g.:
|
||||
## Building SuperTuxKart on Windows
|
||||
To Build SuperTuxKart on Windows, follow these instructions:
|
||||
|
||||
1. Download and install Visual Studio from here: [Visual Studio - Download](https://www.visualstudio.com/downloads/). The free Visual Studio Community edition works fine.
|
||||
2. Download the SuperTuxKart source package from either [SuperTuxKart download area - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart/) or [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), and unpack it.
|
||||
*Note: If you downloaded the source package from here: [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control), then both `stk-code` and `stk-assets` **must** be in the same directory, otherwise the build can result in failure*
|
||||
3. Download the Windows dependencies package from either [SuperTuxKart download area: Dependencies - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/)
|
||||
or [SuperTuxKart on GitHub - Dependencies](https://github.com/supertuxkart/dependencies), and unpack it; then, copy the `dependencies` directory from either the `windows` or the `windows_64bit` directories into the `stk-code` directory, rename it to `dependencies-64bit` if you want to compile a 64bit build.
|
||||
4. Download CMake from here: [CMake - download page](https://cmake.org/download/), install it; once CMake is installed, double click on the CMake icon on your desktop, and point it towards your `stk-code` directory in the 'Where is the source code' field, and point it to a directory called `build` or `bld` inside the stk-code directory.
|
||||
1. Download and install Visual Studio from here: [Visual Studio - Download](https://www.visualstudio.com/downloads/). The free Visual Studio Community edition works fine. Remember to select "Desktop development with C++" in the installer.
|
||||
|
||||
2a. If you want the stable version, download the SuperTuxKart source package from the latest stable version [SuperTuxKart download area - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart/) and unpack it.
|
||||
2b. If you want the development version, you will need a Git client and a SVN client. More information can be found here: [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control).
|
||||
Open your file browser and find somewhere you want to put the development version of SuperTuxKart. For example in C:\Users\<Your Username> as the Git and SVN clients will have write permissions there, and you should create its own directory, for example SuperTuxKart-dev. Enter that directory, and create a directory inside called stk-assets, and enter it. If you installed TortoiseSVN, right-click, select TortoiseSVN -> Checkout... and paste the correspodning URL found in [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control). While it is downloading the game assets, go back to your file browser and one level up. Right-click again somewhere empty and select "Git clone..." and paste the corresponding link found in [SuperTuxKart.net - Source Control](https://supertuxkart.net/Source_control).
|
||||
*Note: Both `stk-code` and `stk-assets` **must** be in the same directory, otherwise the build will likely fail!*
|
||||
|
||||
3a. If you got the stable version, download the Windows dependencies package from [SuperTuxKart download area: Dependencies - SourceForge.net](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/Windows/) and unpack it.
|
||||
3b. If you got the development version go to SuperTuxKart-dev in your file browser, right-click somewhere empty, select "Git clone..." and paste https://github.com/supertuxkart/dependencies.git in the URL field; click OK. When finished, copy the `dependencies` directory from either the `windows` or the `windows_64bit` directories into the `stk-code` directory; rename the latter to `dependencies-64bit` if you want to compile a 64-bit build.
|
||||
|
||||
4. Download CMake from here: [CMake - download page](https://cmake.org/download/), install it; once CMake is installed, double click on the CMake icon on your desktop, and point it towards your `stk-code` directory in the 'Where is the source code' field, and point it to a new directory called `build` or `bld` inside the stk-code directory.
|
||||
|
||||
5. Press 'Configure'; CMake will ask you if it is OK to create the aforementioned directory, press `Yes`. CMake will then ask you about your version of Visual Studio.
|
||||
Confirm your selection; *Please look at the table below to avoid confusion between version numbers and releases of Visual Studio*;
|
||||
CMake will begin creating the required files for the build in the directory.
|
||||
|
||||
Confirm your selection; *Please look at the table below to avoid confusion between version numbers and releases of Visual Studio*; CMake will begin creating the required files for the build in the directory. If you want to do a 64-bit build, select the version of Visual Studio you installed with "Win64" appended.
|
||||
|
||||
6. Navigate to your build directory and open the `SuperTuxKart.sln` file; Visual Studio will now load the solution.
|
||||
7. In the 'Solution Explorer', right click on the `supertuxkart` project and select "Set as StartUp project"
|
||||
|
||||
7. In the 'Solution Explorer', right click on the `supertuxkart` project and select "Set as StartUp project".
|
||||
|
||||
8. Open the 'Build' menu and select 'Build Solution'; or, press the default keyboard shortcut: `CTRL + SHIFT + B` to build the solution.
|
||||
|
||||
*Note: To avoid confusion between releases and versions, refer to this table:*
|
||||
@@ -195,20 +204,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
|
||||
|
||||
|
||||
@@ -124,15 +124,15 @@ include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := irrlicht
|
||||
LOCAL_PATH := .
|
||||
LOCAL_CPP_FEATURES += rtti
|
||||
LOCAL_SRC_FILES := $(wildcard ../lib/irrlicht/source/Irrlicht/*.cpp) \
|
||||
$(wildcard ../lib/irrlicht/source/Irrlicht/Android/*.cpp)
|
||||
LOCAL_SRC_FILES := $(wildcard ../lib/irrlicht/source/Irrlicht/*.cpp) \
|
||||
$(wildcard ../lib/irrlicht/source/Irrlicht/Android/*.cpp) \
|
||||
../lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c
|
||||
LOCAL_CFLAGS := -I../lib/irrlicht/source/Irrlicht/ \
|
||||
-I../lib/irrlicht/include/ \
|
||||
-Iobj/jpeglib/ \
|
||||
-Iobj/libpng/ \
|
||||
-Iobj/zlib/ \
|
||||
-I$(call my-dir)/../../sources/android/native_app_glue
|
||||
-std=gnu++0x
|
||||
-Iobj/zlib/
|
||||
LOCAL_CPPFLAGS := -std=gnu++0x
|
||||
LOCAL_STATIC_LIBRARIES := jpeglib png zlib
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
@@ -159,20 +159,17 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \
|
||||
-Iobj/libvorbis/include \
|
||||
-Iobj/openal/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)\" \
|
||||
-DSUPERTUXKART_VERSION=\"$(PROJECT_VERSION)\" \
|
||||
-std=gnu++0x
|
||||
-DSUPERTUXKART_VERSION=\"$(PROJECT_VERSION)\"
|
||||
LOCAL_CPPFLAGS := -std=gnu++0x
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := irrlicht bullet enet freetype ifaddrs angelscript \
|
||||
vorbisfile vorbis ogg openal curl libssl libcrypto \
|
||||
gnustl_static android_native_app_glue
|
||||
gnustl_static
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
$(call import-module,android/native_app_glue)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
android:banner="@drawable/banner"
|
||||
android:hasCode="false"
|
||||
android:isGame="true"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor"
|
||||
android:hardwareAccelerated="true"
|
||||
android:resizeableActivity="false">
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -373,8 +372,8 @@ if [ ! -f "$DIRNAME/obj/curl.stamp" ]; then
|
||||
cp -a -f "$DIRNAME/../lib/curl/"* "$DIRNAME/obj/curl"
|
||||
|
||||
cd "$DIRNAME/obj/curl"
|
||||
CPPFLAGS="-I$DIRNAME/obj/openssl/include $CPPFLAGS" \
|
||||
LDFLAGS="-L$DIRNAME/obj/openssl/ $LDFLAGS" \
|
||||
CPPFLAGS="-I$DIRNAME/obj/openssl/include -I$DIRNAME/obj/zlib $CPPFLAGS" \
|
||||
LDFLAGS="-L$DIRNAME/obj/openssl/ -L$DIRNAME/obj/zlib $LDFLAGS" \
|
||||
./configure --host=$HOST \
|
||||
--with-ssl \
|
||||
--disable-shared \
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -40,6 +40,8 @@ crown.png by glitch, from https://openclipart.org/detail/210257/misc-game-crown,
|
||||
|
||||
ghost_plus.png by Alayan, based on https://openclipart.org/detail/17847/cartoon-ghost by lemmling, released under CC-O
|
||||
|
||||
options_language.png by Alayan, based on http://www.languageicon.org/, released under CC-BY-SA 3+
|
||||
|
||||
====
|
||||
|
||||
Glass Skin by Auria, under CC-BY-SA 3+
|
||||
|
||||
BIN
data/gui/bomb_icon.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
@@ -1,69 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header align="center" width="80%" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<tabs id="category" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Weapons"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
</tabs>
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="5" height="15"/>
|
||||
<button id="startTutorial" text="Start the tutorial" align="center"/>
|
||||
<spacer width="5" height="15"/>
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/gift.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="6" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="Collect blue boxes. They will give you weapons or other powerups."/>
|
||||
<spacer width="25" height="25"/>
|
||||
<icon align="center" width="64" height="64" icon="gui/banana.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="4" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="Avoid bananas!"/>
|
||||
</div>
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<div width="100%" proportion="3" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/nitro.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="3" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="Collecting nitro allows you to get speed boosts whenever you wish by pressing the appropriate key. You can see your current level of nitro in the bar at the right of the game screen."/>
|
||||
<spacer width="5" height="1%"/>
|
||||
<div width="50%" proportion="2" align="center" layout="horizontal-row">
|
||||
<icon id="tutorialIcon" width="64" height="64" align="center" icon="gui/tutorial.png"/>
|
||||
<button id="startTutorial" align="center" text="Start the tutorial"/>
|
||||
</div>
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<div width="100%" proportion="5" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/gift.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="7" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="Collect blue gift boxes, they will give you powerups."/>
|
||||
<spacer width="25" height="25"/>
|
||||
<icon align="center" width="64" height="64" icon="gui/banana.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="3" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="Avoid bananas!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/gui_lock.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="2" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="If you see a button with a lock like this one, you need to complete a challenge to unlock it."/>
|
||||
</div>
|
||||
<div width="100%" proportion="6" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/nitro.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="3" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="Collecting nitro allows you to get speed boosts whenever you wish by pressing the appropriate key. You can see your current level of nitro in the gauge at the bottom-right of the race screen."/>
|
||||
</div>
|
||||
|
||||
<bubble align="left" word_wrap="true" width="100%" proportion="1"
|
||||
I18N="in the help menu"
|
||||
text="The 'skidding' key allows you to skid in sharp turns and get a boost."/>
|
||||
<div width="100%" proportion="4" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/gui_lock.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="2" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="If you see a button with a lock like this one, you need to complete a challenge to unlock it."/>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="10"/>
|
||||
<div width="100%" proportion="6" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/android/drift.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="2" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="The 'skidding' key allows you to skid. Short skids help to take sharp turns. If you skid long enough, you will get a boost. You can't stop turning while skidding, so orient your kart carefully before !"/>
|
||||
</div>
|
||||
|
||||
<label align="center" I18N="in the help screen" text="* Current key bindings can be seen/changed in menu Options"/>
|
||||
<spacer height="10" width="10"/>
|
||||
<spacer height="3%" width="10"/>
|
||||
|
||||
</box>
|
||||
<label align="center" word_wrap="true" I18N="in the help screen" text="* Current key bindings can be seen/changed in menu Options"/>
|
||||
<spacer height="1%" width="10"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,77 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header align="center" width="80%" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="category" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Weapons"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<label align="center" I18N="In the help menu" text="To help you win, there are some powerups you can collect:"/>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/bubblegum-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="BubbleGum - protect yourself with a shield, or use while looking back to leave a sticky pink puddle behind you."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/cake-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
text="Cake - thrown at the closest rival, best on short ranges and long straights."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/plunger-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Plunger - throw straight to pull an opponent back, or throw while looking back to make one lose sight."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/bowling-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
text="Bowling Ball - bounces off walls. If you are looking back, it will be thrown backwards."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/parachute-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Parachute - slows down all karts in a better position."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/swap-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Swapper - gift boxes are transformed into bananas and vice versa for a short time."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/rubber_ball-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Basket Ball - bounces after the leader, and might squash and slow down karts down on the way."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/swatter-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Swatter - will squash karts close by, slowing them down."/>
|
||||
</div>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<spacer height="1%" width="10"/>
|
||||
<label align="center" word_wrap="true" text="SuperTuxKart features several game modes:"/>
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_normal.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Regular Race: All blows allowed, so collect powerups and use them smartly!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_tt.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Time Trial: Contains no powerups, so only your driving skills matter!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_ftl.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Follow the leader: Run for second place, as the last kart will be disqualified every time the counter hits zero. Beware: going in front of the leader will get you eliminated too!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_3strikes.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="3 Strikes Battle: Hit others with weapons until they lose all their lives."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_soccer.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Soccer: Use your kart to push the ball into the goal."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_easter.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Egg hunt: Explore tracks to find all hidden eggs."/>
|
||||
</div>
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_ghost.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Ghost replay: Race against ghost replays in time-trial or egg hunt mode, and record your own!"/>
|
||||
</div>
|
||||
|
||||
<bubble proportion="4" width="100%" I18N="In the help menu"
|
||||
text="* Most of these game modes can also be played in a Grand Prix fashion: instead of playing a single race, you play many in a row. The better you rank, the more points you get. In the end, the player with the most points wins the cup."/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,78 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header align="center" width="80%" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="category" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Weapons"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<label align="center" text="SuperTuxKart features several game modes"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_normal.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Regular Race: All blows allowed, so catch weapons and make clever use of them!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_tt.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Time Trial: Contains no powerups, so only your driving skills matter! This mode allows you to record the race for replaying."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_ftl.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Follow the leader: Run for second place, as the last kart will be disqualified every time the counter hits zero. Beware: going in front of the leader will get you eliminated too!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_3strikes.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="3 Strikes Battle: Hit others with weapons until they lose all their lives."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_soccer.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Soccer: Use your kart to push the ball into the goal."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mode_easter.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Egg hunt: Explore tracks to find all hidden eggs."/>
|
||||
</div>
|
||||
|
||||
<bubble proportion="3" width="100%" I18N="In the help menu"
|
||||
text="* Most of these game modes can also be played in a Grand Prix fashion: instead of playing a single race, you play many in a row. The better you rank, the more points you get. In the end, the player with the most points wins the cup."/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<spacer height="1%" width="10"/>
|
||||
<label align="center" word_wrap="true" I18N="In the help menu" text="To help you win, there are some powerups you can collect:"/>
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/bubblegum-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="BubbleGum - protect yourself with a shield, or use while looking back to leave a sticky pink puddle behind you."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/zipper_collect.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Zipper - will give you a strong speed boost. But beware of not losing control of your kart !"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/cake-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
text="Cake - thrown at the closest rival, best on short ranges and long straights. It also affects other karts close to the explosion."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/plunger-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Plunger - throw straight to pull an opponent back, or throw while looking back to make one lose sight."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/bowling-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
text="Bowling Ball - goes straight until it strikes, it can bounce off walls. If you are looking back, it will be thrown backwards."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/parachute-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Parachute - slows down all karts in a better position."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/swap-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Swapper - gift boxes are transformed into bananas, nitro cans into bubblegums, and vice versa for a short time."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/rubber_ball-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Basket Ball - bounces after the leader, and might squash and slow down karts down on the way."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="1" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/swatter-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" text="Swatter - will squash karts close by, slowing them down. Can also be used to remove parachutes and bombs."/>
|
||||
</div>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,44 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header align="center" width="80%" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="category" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Weapons"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<label align="center" text="SuperTuxKart can be played in multiplayer mode on the same computer"/>
|
||||
<label align="center" text="(network play is not yet available)"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/options_input.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="First, you will need several input devices (having multiple gamepads or joysticks is the best way to play with several people). Go in the input configuration screen and setup the gamepads. It is also possible to play on keyboard(s), however each player will need a different set of keys, and keep in mind that most keyboards are not appropriate for multiplayer gameplay because they do not support large number of keypresses."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/random_kart.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="When input devices are configured, you are ready to play. Select the 'multiplayer race' icon in the main menu. When it is time to choose a kart, each player can press on the 'fire' key of their gamepad or keyboard to join the game. Each player can use their input device to select their kart. The game continues when everyone selected their kart. Note that the mouse may not be used for this operation."/>
|
||||
</div>
|
||||
<spacer width="50" height="25" />
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<spacer height="1%" width="10"/>
|
||||
<label align="center" word_wrap="true" text="Hitting a banana can result in one of the following being attached to the kart:"/>
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/anchor-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Anchor - slows down the kart suddenly."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/parachute-icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Parachute - slows down the kart, more progressively than the anchor. The faster you go, the stronger it slows you down."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/bomb_icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Bomb - detonates after some amount of time, throwing the kart up in the air. Bump into another kart to transfer the bomb to it."/>
|
||||
</div>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,49 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header align="center" width="80%" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="category" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="page1" width="100" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="100" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Weapons"/>
|
||||
<icon-button id="page3" width="100" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page4" width="100" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
<icon-button id="page5" width="100" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<label align="center" text="Hitting a banana can result in one of the following being attached to the kart:"/>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/anchor-icon.png"/>
|
||||
<spacer width="64" height="64"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Anchor - slows down the kart."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="models/parachute-icon.png"/>
|
||||
<spacer width="64" height="64"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Parachute - slows down the kart less than the anchor."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="128" height="128" icon="models/bomb-attach-icon.png"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Bomb - detonates after a short amount of time to throw the kart up in the air. Bump into another kart to transfer the bomb to another player."/>
|
||||
</div>
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<spacer height="1%" width="10"/>
|
||||
<label align="center" word_wrap="true" text="The evil Nolok has captured Gnu! Here are a few tips to help you:"/>
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<div width="100%" proportion="5" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/challenge.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="This icon on the minimap shows the available challenges you've not completed. In the top-right of the screen, it also tells you how many points you currently have. Complete as many challenges as possible, and Nolok will accept to race against you. Win to liberate Gnu!"/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="4" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/cup_gold.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="When you complete a challenge, you get a cup. Each cup is worth several points. The higher the difficulty you completed the challenge in, the better the cup and the more points it is worth."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="3" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mystery_unlock.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="When you get the number of points indicated below this icon, you'll be gifted a surprise. There are several to collect."/>
|
||||
</div>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
77
data/gui/help6.stkgui
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<spacer height="1%" width="10"/>
|
||||
<label align="center" word_wrap="true" text="Not all karts drive the same! They belong to classes with several differences:"/>
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<div width="100%" proportion="4" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/mass.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Mass - there are three classes of karts, depending of their mass: light, medium and heavy. Heavier karts are less affected by parachutes and are more resistant to explosions."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="4" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/power.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Acceleration - especially useful at start, after an accident, or in tracks with a lot of sharp curves. The lighter the kart, the faster it accelerates, especially at low speeds."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="4" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/speed.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Max speed - the higher it is, the faster the kart can go. Especially useful in tracks with straight lines and gentle curves. Heavier karts have a higher top speed."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="3" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/nitro.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="Nitro consumption - the lower it is, the more speed you can get from a can of nitro. The lighter the kart, the lower its nitro consumption."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="4" layout="horizontal-row">
|
||||
<icon align="center" width="128" height="128" icon="gui/slipstream_icon.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%" word_wrap="true"
|
||||
I18N="In the help menu"
|
||||
text="If you follow closely another kart for a few seconds, you'll get a slipstream speed bonus when you overtake it. The lighter your kart, the easier it is."/>
|
||||
</div>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
69
data/gui/help7.stkgui
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Help" text_align="center"/>
|
||||
<spacer height="1%" width="100%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="category" height="100%" width="18%">
|
||||
<icon-button id="page1" width="128" height="128" icon="gui/track_random.png"
|
||||
I18N="Tab in help menu" text="General"/>
|
||||
<icon-button id="page2" width="128" height="128" icon="gui/mode_ftl.png"
|
||||
I18N="Tab in help menu" text="Game Modes"/>
|
||||
<icon-button id="page3" width="128" height="128" icon="gui/weapons.png"
|
||||
I18N="Tab in help menu" text="Powerups"/>
|
||||
<icon-button id="page4" width="128" height="128" icon="gui/banana.png"
|
||||
I18N="Tab in help menu" text="Bananas"/>
|
||||
<icon-button id="page5" width="128" height="128" icon="gui/story_mode_book.png"
|
||||
I18N="Tab in help menu" text="Story Mode"/>
|
||||
<icon-button id="page6" width="128" height="128" icon="gui/mass.png"
|
||||
I18N="Tab in help menu" text="Kart classes"/>
|
||||
<icon-button id="page7" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Tab in help menu" text="Multi-player"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<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 optionally ranked races."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/crown.png"/>
|
||||
<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) 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" 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"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="First, you will need several input devices. Use the input configuration screen to set them up. Multiple gamepads or joysticks are ideal: on keyboard(s), each player will need a different set of keys, and most keyboards are not appropriate for multiplayer because they don't support multiple simultaneous keypresses."/>
|
||||
</div>
|
||||
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<icon align="center" width="64" height="64" icon="gui/random_kart.png"/>
|
||||
<spacer width="25" height="25"/>
|
||||
<bubble proportion="1" height="100%"
|
||||
I18N="In the help menu"
|
||||
text="When input devices are configured, select the 'multiplayer race' icon in the main menu. Each player can press the 'fire' key of their gamepad or keyboard to join the game, and use their input device to select their kart. The game continues when everyone selected their kart. Note that the mouse may not be used for this operation."/>
|
||||
</div>
|
||||
<spacer width="50" height="25" />
|
||||
</box>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
BIN
data/gui/networking_icon.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
@@ -19,7 +19,7 @@
|
||||
<spacer height="10" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Password (optional)"/>
|
||||
<label proportion="1" text_align="left" I18N="In the server creation screen" text="Password for private server (optional)"/>
|
||||
<textbox proportion="1" id="password" I18N="In the server creation screen"/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,67 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row">
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<!-- ******** Music ******** -->
|
||||
<label width="100%" I18N="In the audio options screen" text="Music"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Enabled"/>
|
||||
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<!-- FIXME: don't hardcode height -->
|
||||
<checkbox id="music_enabled"/>
|
||||
</div>
|
||||
</div>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Volume"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="music_volume" proportion="1" min_value="1" max_value="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<!-- ******** SFX ******** -->
|
||||
<label width="100%" I18N="In the audio options screen" text="Sound Effects"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Enabled"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<!-- FIXME: don't hardcode height -->
|
||||
<checkbox id="sfx_enabled"/>
|
||||
</div>
|
||||
</div>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Volume"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="sfx_volume" proportion="1" min_value="1" max_value="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="10"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<!-- ******** Music ******** -->
|
||||
<label width="100%" I18N="In the audio options screen" text="Music"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Enabled"/>
|
||||
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<!-- FIXME: don't hardcode height -->
|
||||
<checkbox id="music_enabled"/>
|
||||
</div>
|
||||
</div>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Volume"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="music_volume" proportion="1" min_value="1" max_value="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<!-- ******** SFX ******** -->
|
||||
<label width="100%" I18N="In the audio options screen" text="Sound Effects"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Enabled"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<!-- FIXME: don't hardcode height -->
|
||||
<checkbox id="sfx_enabled"/>
|
||||
</div>
|
||||
</div>
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the audio options screen" text="Volume"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="sfx_volume" proportion="1" min_value="1" max_value="10"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="2%"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,49 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
<!-- Configuration name -->
|
||||
<spacer height="6" width="10"/>
|
||||
<label id="title" width="100%" text_align="center" />
|
||||
<spacer height="16" width="10"/>
|
||||
|
||||
<!-- List of key bindings -->
|
||||
<box proportion="8" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="actions" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<!-- Bottom buttons -->
|
||||
|
||||
<spacer width="50" height="20" />
|
||||
<div proportion="2" width="100%" layout="horizontal-row">
|
||||
<spacer width="7" height="5"/>
|
||||
<div height="100%" width="fit" layout="vertical-row">
|
||||
<button id="delete"
|
||||
I18N="In the input configuration screen" text="Delete Configuration"/>
|
||||
<spacer width="50" height="10" />
|
||||
<button id="back_to_device_list" I18N="In the input configuration screen" text="Back to device list"/>
|
||||
|
||||
<spacer width="50" height="10" />
|
||||
</div>
|
||||
<spacer width="20" height="10" />
|
||||
<label id="conflict" proportion="1" text="" word_wrap="true" align="center"/>
|
||||
</div>
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<!-- Configuration name -->
|
||||
<spacer height="6" width="10"/>
|
||||
<label id="title" width="100%" text_align="center" />
|
||||
<spacer height="16" width="10"/>
|
||||
|
||||
<!-- List of key bindings -->
|
||||
<box proportion="8" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="actions" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<!-- Bottom buttons -->
|
||||
|
||||
<spacer width="50" height="20" />
|
||||
<div proportion="2" width="100%" layout="horizontal-row">
|
||||
<spacer width="7" height="5"/>
|
||||
<div height="100%" width="fit" layout="vertical-row">
|
||||
<button id="delete"
|
||||
I18N="In the input configuration screen" text="Delete Configuration"/>
|
||||
<spacer width="50" height="10" />
|
||||
<button id="back_to_device_list" I18N="In the input configuration screen" text="Back to device list"/>
|
||||
|
||||
<spacer width="50" height="10" />
|
||||
</div>
|
||||
<spacer width="20" height="10" />
|
||||
<label id="conflict" proportion="1" text="" word_wrap="true" align="center"/>
|
||||
</div>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,39 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
<label width="100%"
|
||||
I18N="In the input configuration screen"
|
||||
text="Press enter or double-click on a device to configure it"
|
||||
text_align="center" />
|
||||
|
||||
<spacer width="5" height="20"/>
|
||||
|
||||
<box proportion="5" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="devices" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<spacer width="50" height="25" />
|
||||
|
||||
<button id="add_device" I18N="In the input configuration screen" text="Add a device" align="center"/>
|
||||
|
||||
<label I18N="In the input configuration screen" text="* Which config to use will be inferred from which 'Select' key is pressed to join the game."
|
||||
proportion="2" word_wrap="true"/>
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
<label width="100%"
|
||||
I18N="In the input configuration screen"
|
||||
text="Press enter or double-click on a device to configure it"
|
||||
text_align="center" />
|
||||
|
||||
<spacer width="5" height="20"/>
|
||||
|
||||
<box proportion="5" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="devices" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<spacer width="50" height="25" />
|
||||
|
||||
<button id="add_device" I18N="In the input configuration screen" text="Add a device" align="center"/>
|
||||
|
||||
<label I18N="In the input configuration screen" text="* Which config to use will be inferred from which 'Select' key is pressed to join the game."
|
||||
proportion="2" word_wrap="true"/>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
BIN
data/gui/options_language.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
42
data/gui/options_language.stkgui
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
|
||||
<!-- ************ LANGUAGE CHOICE ************ -->
|
||||
|
||||
<box proportion="1" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="language" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
@@ -1,107 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
<spacer height="5" width="10" />
|
||||
|
||||
<!-- ************ SKIN CHOICE ************ -->
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label I18N="In the ui settings" text="Skin" align="center"/>
|
||||
<spacer width="20" height="20"/>
|
||||
<spinner id="skinchoice" width="30%"/>
|
||||
</div>
|
||||
|
||||
<spacer width="20" height="18" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row">
|
||||
<checkbox id="showfps"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Display FPS"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="show-login"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Always show login screen"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="enable-hw-report"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" id="label-hw-report" I18N="In the ui settings"
|
||||
text="Send anonymous HW statistics"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="perPlayerDifficulty"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Enable per-player handicaps"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-internet"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Connect to the Internet"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="split_screen_horizontally"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Multiplayer splits screen horizontally"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-lobby-chat"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" id="label-lobby-chat" I18N="In the ui settings" text="Enable chatting in networking lobby"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="18" width="4"/>
|
||||
|
||||
<!-- ************ LANGUAGE CHOICE ************ -->
|
||||
|
||||
<box proportion="1" width="75%" align="center" layout="vertical-row" padding="8">
|
||||
<list id="language" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
<spacer height="18" width="4"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<!-- ************ SKIN CHOICE ************ -->
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<label I18N="In the ui settings" text="Skin" align="center"/>
|
||||
<spacer width="2%" height="20"/>
|
||||
<spinner id="skinchoice" width="30%"/>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row">
|
||||
<checkbox id="showfps"/>
|
||||
<spacer width="1%" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Display FPS" word_wrap="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="split_screen_horizontally"/>
|
||||
<spacer width="1%" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Multiplayer splits screen horizontally" word_wrap="true"/>
|
||||
</div>
|
||||
|
||||
<spacer width="2%" height="5"/>
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="perPlayerDifficulty"/>
|
||||
<spacer width="2%" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Enable per-player handicaps" word_wrap="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-internet"/>
|
||||
<spacer width="1%" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Connect to the Internet" word_wrap="true"/>
|
||||
</div>
|
||||
|
||||
<spacer width="2%" height="5"/>
|
||||
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="enable-hw-report"/>
|
||||
<spacer width="1%" height="100%" />
|
||||
<label height="100%" id="label-hw-report" I18N="In the ui settings"
|
||||
text="Send anonymous hardware statistics" word_wrap="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="show-login"/>
|
||||
<spacer width="1%" height="100%" />
|
||||
<label height="100%" I18N="In the ui settings" text="Always show login screen" word_wrap="true"/>
|
||||
</div>
|
||||
|
||||
<spacer width="2%" height="5"/>
|
||||
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<checkbox id="enable-lobby-chat"/>
|
||||
<spacer width="1%" height="100%" />
|
||||
<label height="100%" id="label-lobby-chat" I18N="In the ui settings" text="Enable chatting in networking lobby" word_wrap="true"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="3%"/>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -1,83 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<!-- ************ GRAPHICAL EFFECTS SETTINGS ************ -->
|
||||
<div width="75%" height="fit" layout="horizontal-row" id="outer_box" >
|
||||
<label I18N="In the video settings" text="Graphical Effects Level" align="center"/>
|
||||
<spacer width="20" height="20"/>
|
||||
|
||||
<div layout="vertical-row" proportion="1" height="fit" id="inner_box">
|
||||
<gauge id="gfx_level" min_value="1" max_value="8" width="300" align="center" />
|
||||
<spacer height="5" width="10"/>
|
||||
<button id="custom" text="Custom settings..." I18N="In the video settings" align="center"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="10"/>
|
||||
|
||||
<!-- ************ VSYNC ************ -->
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="2" />
|
||||
<checkbox id="vsync"/>
|
||||
<spacer width="20" height="2" />
|
||||
<label height="100%" I18N="In the video settings" text="Vertical Sync (requires restart)"/>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="10"/>
|
||||
|
||||
<!-- ************ RESOLUTION CHOICE ************ -->
|
||||
<spacer height="10" width="10"/>
|
||||
<label width="100%" I18N="In the video settings" text="Resolution"/>
|
||||
|
||||
<scrollable_ribbon id="resolutions" proportion="1" label_location="each"
|
||||
width="100%" square_items="false"
|
||||
align="center" child_width="128" child_height="128" max_height="150" />
|
||||
|
||||
<spacer height="10" width="10"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<checkbox id="fullscreen"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the video settings" text="Fullscreen"/>
|
||||
</div>
|
||||
|
||||
<div width="75%" layout="horizontal-row" height="fit">
|
||||
<spacer width="40" height="100%" />
|
||||
<checkbox id="rememberWinpos"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label I18N="In the video settings" text="Remember window location"/>
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="10"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<button id="apply_resolution"
|
||||
I18N="In the video settings" text="Apply new resolution" />
|
||||
</div>
|
||||
|
||||
<spacer height="15" width="4"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<!-- ************ GRAPHICAL EFFECTS SETTINGS ************ -->
|
||||
<div width="75%" height="fit" layout="horizontal-row" id="outer_box" >
|
||||
<label I18N="In the video settings" text="Graphical Effects Level" align="center"/>
|
||||
<spacer width="20" height="20"/>
|
||||
|
||||
<div layout="vertical-row" proportion="1" height="fit" id="inner_box">
|
||||
<gauge id="gfx_level" min_value="1" max_value="8" width="300" align="center" />
|
||||
<spacer height="5" width="10"/>
|
||||
<button id="custom" text="Custom settings..." I18N="In the video settings" align="center"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<!-- ************ VSYNC ************ -->
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="2" />
|
||||
<checkbox id="vsync"/>
|
||||
<spacer width="20" height="2" />
|
||||
<label height="100%" I18N="In the video settings" text="Vertical Sync (requires restart)"/>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<!-- ************ RESOLUTION CHOICE ************ -->
|
||||
<spacer width="5" height="1%"/>
|
||||
<label width="100%" I18N="In the video settings" text="Resolution"/>
|
||||
|
||||
<scrollable_ribbon id="resolutions" proportion="1" label_location="each"
|
||||
width="100%" square_items="false"
|
||||
align="center" child_width="128" child_height="128" max_height="150" />
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<checkbox id="fullscreen"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label height="100%" I18N="In the video settings" text="Fullscreen"/>
|
||||
</div>
|
||||
|
||||
<div width="75%" layout="horizontal-row" height="fit">
|
||||
<spacer width="40" height="100%" />
|
||||
<checkbox id="rememberWinpos"/>
|
||||
<spacer width="20" height="100%" />
|
||||
<label I18N="In the video settings" text="Remember window location"/>
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<button id="apply_resolution"
|
||||
I18N="In the video settings" text="Apply new resolution" />
|
||||
</div>
|
||||
|
||||
<spacer width="5" height="1%"/>
|
||||
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
BIN
data/gui/slipstream_icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
data/gui/story_mode_book.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
@@ -1,90 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
|
||||
</tabs>
|
||||
|
||||
<box proportion="1" width="98%" layout="vertical-row">
|
||||
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<scrollable_ribbon id="players" height="18%" y="10" x="10" width="98%" align="center" label_location="each"
|
||||
square_items="true" child_width="128" child_height="128" />
|
||||
|
||||
<spacer height="2%" width="10"/>
|
||||
<div width="90%" align="center" layout="vertical-row" proportion="1">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="online" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the user screen" text="Online"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="remember-user" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" id="label_remember" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Remember password"/>
|
||||
</div>
|
||||
<!-- Disable guest accounts for now
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label width="40%" id="label_guest" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the user screen" text_align="left"/>
|
||||
</div>
|
||||
-->
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label width="40%" id="label_username" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the user screen"/>
|
||||
</div>
|
||||
<spacer height="5%" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_password" width="40%" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Password"/>
|
||||
<textbox id="password" proportion="2" height="fit" I18N="In the user screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5%" width="20"/>
|
||||
|
||||
<button id="password_reset" width="fit" text="Reset password"/>
|
||||
|
||||
<spacer height="5%" width="20"/>
|
||||
|
||||
<label id="message" width="100%" text_align="center"/>
|
||||
</div>
|
||||
|
||||
<spacer width="20" height="2%"/>
|
||||
|
||||
<div width="90%" align="center" layout="vertical-row" height="18%">
|
||||
<buttonbar id="options" width="100%" height="100%" align="center">
|
||||
<icon-button id="ok" width="fit" height="fit" icon="gui/green_check.png"
|
||||
I18N="In the user screen" text="OK" label_location="bottom"/>
|
||||
<icon-button id="new_user" width="fit" height="fit" icon="gui/blue_plus.png"
|
||||
I18N="In the user screen" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="fit" height="fit" icon="gui/remove.png"
|
||||
I18N="In the user screen" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="rename" width="fit" height="fit" icon="gui/rename.png"
|
||||
I18N="In the user screen" text="Rename" label_location="bottom"/>
|
||||
<icon-button id="default_kart_color" width="fit" height="fit" icon="gui/edit.png"
|
||||
I18N="In the user screen" text="Default kart color" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="fit" height="fit" icon="gui/main_quit.png"
|
||||
I18N="In the user screen" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
</div>
|
||||
<spacer width="20" height="5%"/>
|
||||
</box>
|
||||
<spacer width="20" height="15"/>
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
|
||||
<header width="80%" height="7%" align="center" text="SuperTuxKart Options" text_align="center"/>
|
||||
<spacer width="100%" height="1%"/>
|
||||
|
||||
<div width="100%" height="92%" layout="horizontal-row" >
|
||||
|
||||
<vertical-tabs id="options_choice" height="100%" width="18%">
|
||||
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
|
||||
I18N="Section in the settings menu" text="Graphics"/>
|
||||
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
|
||||
I18N="Section in the settings menu" text="Audio"/>
|
||||
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"
|
||||
I18N="Section in the settings menu" text="User Interface"/>
|
||||
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
|
||||
I18N="Section in the settings menu" text="Players"/>
|
||||
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"
|
||||
I18N="Section in the settings menu" text="Controls"/>
|
||||
<icon-button id="tab_language" width="128" height="128" icon="gui/options_language.png"
|
||||
I18N="Section in the settings menu" text="Language"/>
|
||||
</vertical-tabs>
|
||||
|
||||
<spacer width="2%" height="100%"/>
|
||||
|
||||
<box width="80%" height="100%" layout="vertical-row">
|
||||
|
||||
<spacer height="2%" width="10"/>
|
||||
|
||||
<scrollable_ribbon id="players" height="18%" y="10" x="10" width="98%" align="center" label_location="each"
|
||||
square_items="true" child_width="128" child_height="128" />
|
||||
|
||||
<spacer height="2%" width="10"/>
|
||||
<div width="90%" align="center" layout="vertical-row" proportion="1">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="online" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the user screen" text="Online"/>
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<checkbox width="fit" id="remember-user" I18N="In the user screen" text_align="left"/>
|
||||
<spacer width="10"/>
|
||||
<label proportion="1" id="label_remember" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Remember password"/>
|
||||
</div>
|
||||
<!-- Disable guest accounts for now
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label width="40%" id="label_guest" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Guest login"/>
|
||||
<checkbox id="guest" I18N="In the user screen" text_align="left"/>
|
||||
</div>
|
||||
-->
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label width="40%" id="label_username" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Username"/>
|
||||
<textbox id="username" proportion="2" height="fit" I18N="In the user screen"/>
|
||||
</div>
|
||||
<spacer height="5%" width="20"/>
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="label_password" width="40%" height="100%" text_align="left"
|
||||
I18N="In the user screen" text="Password"/>
|
||||
<textbox id="password" proportion="2" height="fit" I18N="In the user screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="5%" width="20"/>
|
||||
|
||||
<button id="password_reset" width="fit" text="Reset password"/>
|
||||
|
||||
<spacer height="5%" width="20"/>
|
||||
|
||||
<label id="message" width="100%" text_align="center"/>
|
||||
</div>
|
||||
|
||||
<spacer width="20" height="2%"/>
|
||||
|
||||
<div width="90%" align="center" layout="vertical-row" height="18%">
|
||||
<buttonbar id="options" width="100%" height="100%" align="center">
|
||||
<icon-button id="ok" width="fit" height="fit" icon="gui/green_check.png"
|
||||
I18N="In the user screen" text="OK" label_location="bottom"/>
|
||||
<icon-button id="new_user" width="fit" height="fit" icon="gui/blue_plus.png"
|
||||
I18N="In the user screen" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="fit" height="fit" icon="gui/remove.png"
|
||||
I18N="In the user screen" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="rename" width="fit" height="fit" icon="gui/rename.png"
|
||||
I18N="In the user screen" text="Rename" label_location="bottom"/>
|
||||
<icon-button id="default_kart_color" width="fit" height="fit" icon="gui/edit.png"
|
||||
I18N="In the user screen" text="Default kart color" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="fit" height="fit" icon="gui/main_quit.png"
|
||||
I18N="In the user screen" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
</div>
|
||||
<spacer width="20" height="5%"/>
|
||||
</box>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
target-max-angle: Once the ball is aiming for its
|
||||
target, it can at most change the angle
|
||||
this much per second(!).
|
||||
time-between-balls: Reduces the frequency with which rubber
|
||||
balls are found to 1 every 'timer' seconds.
|
||||
min-interpolation-distance: how far the control
|
||||
points (which are center of squads)
|
||||
must be from each other. A large value
|
||||
@@ -63,7 +61,6 @@
|
||||
early-target-factor="1"
|
||||
target-distance="15" target-max-angle = "90"
|
||||
min-interpolation-distance="5"
|
||||
time-between-balls="15"
|
||||
squash-slowdown="0.5" squash-duration="2"
|
||||
delete-time="5.0" max-height-difference="10" />
|
||||
<item name="parachute" icon="parachute-icon.png"
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
@@ -101,12 +101,35 @@
|
||||
any track/library pbject.
|
||||
default-moveable-friction: Default friction to be used for any moveable,
|
||||
e.g. karts, bowling balls, ...
|
||||
solver-iteation: Number of solver iterations. A lower number reduces
|
||||
the quality, but can reduce bouncing effect.
|
||||
solver-split-impulse:: by default bullet solves for velocity and
|
||||
position at the same time, which can introduce bounce. Setting
|
||||
this to 1 can reduce bounce.
|
||||
solver-split-impulse-threshold: Penetration threshold for using split
|
||||
impulse (ignored if solver-split-impulse is false).
|
||||
solver-mode: Bullet's solver mode is a bit mask, which can be modified.
|
||||
This entry contains a space-separated list of mode-names to either
|
||||
set or unset in this bit mask. Any name starting with a '-' indicate
|
||||
that the bit is to be set to 0, otherwise the bit will be set.
|
||||
|
||||
This field takes two
|
||||
values: the first value is 'and'ed with bullet's default values
|
||||
(i.e. it can be used to unset bullet defaults), the second value
|
||||
is 'or'ed (i.e. is used to set a bit). A value of -1 for 'and'
|
||||
means to keep all bits. The valid names are listed in stk_config.cpp
|
||||
and correspond to the definitions in btContactSolverInfo.h, e.g.:
|
||||
'randomized_order' corresponds to the bit SOLVER_RANDMIZE_ORDER.
|
||||
-->
|
||||
<physics smooth-normals="true"
|
||||
smooth-angle-limit="0.65"
|
||||
fps="120"
|
||||
default-track-friction="0.5"
|
||||
default-moveable-friction="0.5" />
|
||||
default-moveable-friction="0.5"
|
||||
solver-iterations="4"
|
||||
solver-split-impulse="true"
|
||||
solver-split-impulse-threshold="-0.00001"
|
||||
solver-mode=""/>
|
||||
|
||||
<!-- The title music. -->
|
||||
<music title="main_theme.music"/>
|
||||
@@ -180,14 +203,11 @@
|
||||
|
||||
<!-- 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.
|
||||
steering-reduction: Reduce a remote kart's steering by this factor
|
||||
each frame. This helps reduces oversteering by high latency
|
||||
clients when they only do minor steering adjustments.
|
||||
-->
|
||||
<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" steering-reduction="1.0"/>
|
||||
|
||||
<!-- The field od views for 1-4 player split screen. fov-3 is
|
||||
actually not used (since 3 player split screen uses the
|
||||
@@ -415,6 +435,11 @@
|
||||
period, which results in less abrupt changes. If set to 0,
|
||||
the impulse is only applied once.
|
||||
resitution: restitution value to be used for the kart rigid bodies.
|
||||
The restitution used depends on the speed to avoid physics issues
|
||||
(a collision with high speed and high restitution will push the
|
||||
kart high up into the air). The values specified are
|
||||
speed:restitution pairs, the actual restitution will be
|
||||
interpolated based on the points specified here.
|
||||
bevel-factor: for each point of the chassis collision box one
|
||||
additional point is added, resulting in a bevelled box shape.
|
||||
The original Z coordinate of the chassis is multiplied by
|
||||
@@ -434,7 +459,7 @@
|
||||
behaviour of the karts. -->
|
||||
<collision impulse-type="normal"
|
||||
impulse="3000" impulse-time="0.1" terrain-impulse="160"
|
||||
restitution="1.0" bevel-factor="0.5 0.0 0.3"
|
||||
restitution="0:1.0 5:1.0 20:0.2" bevel-factor="0.5 0.0 0.3"
|
||||
physical-wheel-position="0" />
|
||||
|
||||
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
|
||||
@@ -506,17 +531,15 @@
|
||||
Use a slow but high quality colour compressor.
|
||||
kColourClusterFit = (32),
|
||||
Use a fast but low quality colour compressor.
|
||||
kColourRangeFit = (64),
|
||||
kColourRangeFit = (64),
|
||||
Use a very slow but very high quality colour compressor.
|
||||
kColourIterativeClusterFit = (256),
|
||||
STK default the low quality.
|
||||
-->
|
||||
<texture-compression quality="64"/>
|
||||
|
||||
<!-- List of default ports used, by default STK use random ports
|
||||
for client and server, disable it in user config to allow
|
||||
port forward. The server discovery port has to be the same
|
||||
across all clients and servers.
|
||||
<!-- List of default ports used, by default STK use random ports for client.
|
||||
The server discovery port has to be the same across all clients and servers.
|
||||
-->
|
||||
<network server-discovery-port="2757" client-port="2758" server-port="2759"/>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
# CMakeLists.txt for Irrlicht in STK
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(JPEG REQUIRED)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
"${JPEG_INCLUDE_DIR}"
|
||||
"${PNG_INCLUDE_DIRS}"
|
||||
"${ZLIB_INCLUDE_DIR}")
|
||||
|
||||
if(MSVC OR APPLE)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/../zlib/" # For zconf.h on WIN32
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../libpng/")
|
||||
endif()
|
||||
|
||||
if(NOT SERVER_ONLY)
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(JPEG REQUIRED)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
"${JPEG_INCLUDE_DIR}"
|
||||
"${PNG_INCLUDE_DIRS}"
|
||||
"${ZLIB_INCLUDE_DIR}")
|
||||
|
||||
if(MSVC)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/../zlib/") # For zconf.h on WIN32
|
||||
endif()
|
||||
|
||||
if(MSVC OR APPLE)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/../libpng/")
|
||||
endif()
|
||||
|
||||
if(NOT USE_GLES2)
|
||||
find_package(OpenGL REQUIRED)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
@@ -58,6 +61,21 @@ if(NOT SERVER_ONLY)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/")
|
||||
if(MSVC)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/../zlib/")
|
||||
else()
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories("${ZLIB_INCLUDE_DIR}")
|
||||
endif()
|
||||
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 +609,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_
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <vector>
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
|
||||
#include <android_native_app_glue.h>
|
||||
#include "stk_android_native_app_glue.h"
|
||||
#endif
|
||||
|
||||
#include "CContextEGL.h"
|
||||
|
||||
@@ -64,6 +64,7 @@ CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param)
|
||||
|
||||
Android->userData = this;
|
||||
Android->onAppCmd = handleAndroidCommand;
|
||||
Android->onAppCmdDirect = handleAndroidCommandDirect;
|
||||
Android->onInputEvent = handleInput;
|
||||
|
||||
printConfig();
|
||||
@@ -365,6 +366,20 @@ E_DEVICE_TYPE CIrrDeviceAndroid::getType() const
|
||||
return EIDT_ANDROID;
|
||||
}
|
||||
|
||||
void CIrrDeviceAndroid::handleAndroidCommandDirect(ANativeActivity* activity,
|
||||
int32_t cmd)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case APP_CMD_RESUME:
|
||||
os::Printer::log("Android command direct APP_CMD_RESUME", ELL_DEBUG);
|
||||
hideNavBar(activity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CIrrDeviceAndroid::handleAndroidCommand(android_app* app, int32_t cmd)
|
||||
{
|
||||
CIrrDeviceAndroid* device = (CIrrDeviceAndroid *)app->userData;
|
||||
@@ -1133,15 +1148,107 @@ void CIrrDeviceAndroid::getKeyChar(SEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
void CIrrDeviceAndroid::hideNavBar(ANativeActivity* activity)
|
||||
{
|
||||
if (activity == NULL)
|
||||
return;
|
||||
|
||||
if (activity->sdkVersion < 19)
|
||||
return;
|
||||
|
||||
bool was_detached = false;
|
||||
JNIEnv* env = NULL;
|
||||
|
||||
jint status = activity->vm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||
|
||||
if (status == JNI_EDETACHED)
|
||||
{
|
||||
JavaVMAttachArgs args;
|
||||
args.version = JNI_VERSION_1_6;
|
||||
args.name = "NativeThread";
|
||||
args.group = NULL;
|
||||
|
||||
status = activity->vm->AttachCurrentThread(&env, &args);
|
||||
was_detached = true;
|
||||
}
|
||||
|
||||
if (status != JNI_OK)
|
||||
{
|
||||
os::Printer::log("Cannot hide navbar.", ELL_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
jobject activity_obj = activity->clazz;
|
||||
|
||||
jclass activity_class = env->GetObjectClass(activity_obj);
|
||||
jclass window_class = env->FindClass("android/view/Window");
|
||||
jclass view_class = env->FindClass("android/view/View");
|
||||
|
||||
jmethodID get_window = env->GetMethodID(activity_class, "getWindow",
|
||||
"()Landroid/view/Window;");
|
||||
jmethodID get_decor_view = env->GetMethodID(window_class, "getDecorView",
|
||||
"()Landroid/view/View;");
|
||||
jmethodID set_system_ui_visibility = env->GetMethodID(view_class,
|
||||
"setSystemUiVisibility", "(I)V");
|
||||
|
||||
jobject window_obj = env->CallObjectMethod(activity_obj, get_window);
|
||||
jobject decor_view_obj = env->CallObjectMethod(window_obj, get_decor_view);
|
||||
|
||||
jfieldID fullscreen_field = env->GetStaticFieldID(view_class,
|
||||
"SYSTEM_UI_FLAG_FULLSCREEN", "I");
|
||||
jfieldID hide_navigation_field = env->GetStaticFieldID(view_class,
|
||||
"SYSTEM_UI_FLAG_HIDE_NAVIGATION", "I");
|
||||
jfieldID immersive_sticky_field = env->GetStaticFieldID(view_class,
|
||||
"SYSTEM_UI_FLAG_IMMERSIVE_STICKY", "I");
|
||||
jfieldID layout_stable_field = env->GetStaticFieldID(view_class,
|
||||
"SYSTEM_UI_FLAG_LAYOUT_STABLE", "I");
|
||||
jfieldID layout_hide_navigation_field = env->GetStaticFieldID(view_class,
|
||||
"SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION", "I");
|
||||
jfieldID layout_fullscreen_field = env->GetStaticFieldID(view_class,
|
||||
"SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN", "I");
|
||||
|
||||
jint fullscreen = env->GetStaticIntField(view_class, fullscreen_field);
|
||||
jint hide_navigation = env->GetStaticIntField(view_class,
|
||||
hide_navigation_field);
|
||||
jint immersive_sticky = env->GetStaticIntField(view_class,
|
||||
immersive_sticky_field);
|
||||
jint layout_stable = env->GetStaticIntField(view_class,
|
||||
layout_stable_field);
|
||||
jint layout_hide_navigation = env->GetStaticIntField(view_class,
|
||||
layout_hide_navigation_field);
|
||||
jint layout_fullscreen = env->GetStaticIntField(view_class,
|
||||
layout_fullscreen_field);
|
||||
|
||||
jint flags = fullscreen | hide_navigation | immersive_sticky |
|
||||
layout_stable | layout_hide_navigation | layout_fullscreen;
|
||||
|
||||
env->CallVoidMethod(decor_view_obj, set_system_ui_visibility, flags);
|
||||
|
||||
if (was_detached)
|
||||
{
|
||||
activity->vm->DetachCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
int CIrrDeviceAndroid::getRotation()
|
||||
{
|
||||
JavaVMAttachArgs args;
|
||||
args.version = JNI_VERSION_1_6;
|
||||
args.name = "NativeThread";
|
||||
args.group = NULL;
|
||||
JNIEnv* env;
|
||||
bool was_detached = false;
|
||||
JNIEnv* env = NULL;
|
||||
|
||||
jint status = Android->activity->vm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||
|
||||
if (status == JNI_EDETACHED)
|
||||
{
|
||||
JavaVMAttachArgs args;
|
||||
args.version = JNI_VERSION_1_6;
|
||||
args.name = "NativeThread";
|
||||
args.group = NULL;
|
||||
|
||||
status = Android->activity->vm->AttachCurrentThread(&env, &args);
|
||||
was_detached = true;
|
||||
}
|
||||
|
||||
if (Android->activity->vm->AttachCurrentThread(&env, &args) != JNI_OK)
|
||||
if (status != JNI_OK)
|
||||
{
|
||||
os::Printer::log("Cannot find rotation.", ELL_DEBUG);
|
||||
return 0;
|
||||
@@ -1172,13 +1279,11 @@ int CIrrDeviceAndroid::getRotation()
|
||||
jobject display_obj = env->CallObjectMethod(window_manager_obj, get_default_display);
|
||||
|
||||
int rotation = env->CallIntMethod(display_obj, get_rotation);
|
||||
|
||||
env->DeleteLocalRef(activity);
|
||||
env->DeleteLocalRef(context);
|
||||
env->DeleteLocalRef(window_manager);
|
||||
env->DeleteLocalRef(display);
|
||||
|
||||
Android->activity->vm->DetachCurrentThread();
|
||||
|
||||
if (was_detached)
|
||||
{
|
||||
Android->activity->vm->DetachCurrentThread();
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <android/window.h>
|
||||
#include <android/sensor.h>
|
||||
#include <android_native_app_glue.h>
|
||||
#include "stk_android_native_app_glue.h"
|
||||
#include "CIrrDeviceStub.h"
|
||||
#include "IrrlichtDevice.h"
|
||||
#include "IImagePresenter.h"
|
||||
@@ -142,10 +142,13 @@ namespace irr
|
||||
void createKeyMap();
|
||||
void createVideoModeList();
|
||||
void getKeyChar(SEvent& event);
|
||||
static void hideNavBar(ANativeActivity* activity);
|
||||
int getRotation();
|
||||
DeviceOrientation getDefaultOrientation();
|
||||
video::SExposedVideoData& getExposedVideoData();
|
||||
|
||||
static void handleAndroidCommandDirect(ANativeActivity* activity,
|
||||
int32_t cmd);
|
||||
static void handleAndroidCommand(android_app* app, int32_t cmd);
|
||||
static s32 handleInput(android_app* app, AInputEvent* event);
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
|
||||
#include <GLES2/gl2.h>
|
||||
#include "android_native_app_glue.h"
|
||||
#include "stk_android_native_app_glue.h"
|
||||
#endif
|
||||
|
||||
#include "CNullDriver.h"
|
||||
|
||||
465
lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.c
Normal file
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2018 Dawid Gan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "stk_android_native_app_glue.h"
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
|
||||
|
||||
/* For debug builds, always enable the debug traces in this library */
|
||||
#ifndef NDEBUG
|
||||
# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__))
|
||||
#else
|
||||
# define LOGV(...) ((void)0)
|
||||
#endif
|
||||
|
||||
static void free_saved_state(struct android_app* android_app) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->savedState != NULL) {
|
||||
free(android_app->savedState);
|
||||
android_app->savedState = NULL;
|
||||
android_app->savedStateSize = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
int8_t android_app_read_cmd(struct android_app* android_app) {
|
||||
int8_t cmd;
|
||||
if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_SAVE_STATE:
|
||||
free_saved_state(android_app);
|
||||
break;
|
||||
}
|
||||
return cmd;
|
||||
} else {
|
||||
LOGE("No data on command pipe!");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void print_cur_config(struct android_app* android_app) {
|
||||
char lang[2], country[2];
|
||||
AConfiguration_getLanguage(android_app->config, lang);
|
||||
AConfiguration_getCountry(android_app->config, country);
|
||||
|
||||
LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
|
||||
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
|
||||
"modetype=%d modenight=%d",
|
||||
AConfiguration_getMcc(android_app->config),
|
||||
AConfiguration_getMnc(android_app->config),
|
||||
lang[0], lang[1], country[0], country[1],
|
||||
AConfiguration_getOrientation(android_app->config),
|
||||
AConfiguration_getTouchscreen(android_app->config),
|
||||
AConfiguration_getDensity(android_app->config),
|
||||
AConfiguration_getKeyboard(android_app->config),
|
||||
AConfiguration_getNavigation(android_app->config),
|
||||
AConfiguration_getKeysHidden(android_app->config),
|
||||
AConfiguration_getNavHidden(android_app->config),
|
||||
AConfiguration_getSdkVersion(android_app->config),
|
||||
AConfiguration_getScreenSize(android_app->config),
|
||||
AConfiguration_getScreenLong(android_app->config),
|
||||
AConfiguration_getUiModeType(android_app->config),
|
||||
AConfiguration_getUiModeNight(android_app->config));
|
||||
}
|
||||
|
||||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_INPUT_CHANGED:
|
||||
LOGV("APP_CMD_INPUT_CHANGED\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->inputQueue != NULL) {
|
||||
AInputQueue_detachLooper(android_app->inputQueue);
|
||||
}
|
||||
android_app->inputQueue = android_app->pendingInputQueue;
|
||||
if (android_app->inputQueue != NULL) {
|
||||
LOGV("Attaching input queue to looper");
|
||||
AInputQueue_attachLooper(android_app->inputQueue,
|
||||
android_app->looper, LOOPER_ID_INPUT, NULL,
|
||||
&android_app->inputPollSource);
|
||||
}
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_INIT_WINDOW:
|
||||
LOGV("APP_CMD_INIT_WINDOW\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->window = android_app->pendingWindow;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
LOGV("APP_CMD_TERM_WINDOW\n");
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
break;
|
||||
|
||||
case APP_CMD_RESUME:
|
||||
case APP_CMD_START:
|
||||
case APP_CMD_PAUSE:
|
||||
case APP_CMD_STOP:
|
||||
LOGV("activityState=%d\n", cmd);
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->activityState = cmd;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_CONFIG_CHANGED:
|
||||
LOGV("APP_CMD_CONFIG_CHANGED\n");
|
||||
AConfiguration_fromAssetManager(android_app->config,
|
||||
android_app->activity->assetManager);
|
||||
print_cur_config(android_app);
|
||||
break;
|
||||
|
||||
case APP_CMD_DESTROY:
|
||||
LOGV("APP_CMD_DESTROY\n");
|
||||
android_app->destroyRequested = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
LOGV("APP_CMD_TERM_WINDOW\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->window = NULL;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_SAVE_STATE:
|
||||
LOGV("APP_CMD_SAVE_STATE\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->stateSaved = 1;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_RESUME:
|
||||
free_saved_state(android_app);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void app_dummy() {
|
||||
|
||||
}
|
||||
|
||||
static void android_app_destroy(struct android_app* android_app) {
|
||||
LOGV("android_app_destroy!");
|
||||
free_saved_state(android_app);
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->inputQueue != NULL) {
|
||||
AInputQueue_detachLooper(android_app->inputQueue);
|
||||
}
|
||||
AConfiguration_delete(android_app->config);
|
||||
android_app->destroyed = 1;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
// Can't touch android_app object after this.
|
||||
}
|
||||
|
||||
static void process_input(struct android_app* app, struct android_poll_source* source) {
|
||||
AInputEvent* event = NULL;
|
||||
while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
|
||||
LOGV("New input event: type=%d\n", AInputEvent_getType(event));
|
||||
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
|
||||
continue;
|
||||
}
|
||||
int32_t handled = 0;
|
||||
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
|
||||
AInputQueue_finishEvent(app->inputQueue, event, handled);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_cmd(struct android_app* app, struct android_poll_source* source) {
|
||||
int8_t cmd = android_app_read_cmd(app);
|
||||
android_app_pre_exec_cmd(app, cmd);
|
||||
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
|
||||
android_app_post_exec_cmd(app, cmd);
|
||||
}
|
||||
|
||||
static void* android_app_entry(void* param) {
|
||||
struct android_app* android_app = (struct android_app*)param;
|
||||
|
||||
android_app->config = AConfiguration_new();
|
||||
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
|
||||
|
||||
print_cur_config(android_app);
|
||||
|
||||
android_app->cmdPollSource.id = LOOPER_ID_MAIN;
|
||||
android_app->cmdPollSource.app = android_app;
|
||||
android_app->cmdPollSource.process = process_cmd;
|
||||
android_app->inputPollSource.id = LOOPER_ID_INPUT;
|
||||
android_app->inputPollSource.app = android_app;
|
||||
android_app->inputPollSource.process = process_input;
|
||||
|
||||
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
|
||||
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
|
||||
&android_app->cmdPollSource);
|
||||
android_app->looper = looper;
|
||||
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->running = 1;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
android_main(android_app);
|
||||
|
||||
android_app_destroy(android_app);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Native activity interaction (called from main thread)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
static struct android_app* android_app_create(ANativeActivity* activity,
|
||||
void* savedState, size_t savedStateSize) {
|
||||
struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
|
||||
memset(android_app, 0, sizeof(struct android_app));
|
||||
android_app->activity = activity;
|
||||
|
||||
pthread_mutex_init(&android_app->mutex, NULL);
|
||||
pthread_cond_init(&android_app->cond, NULL);
|
||||
|
||||
if (savedState != NULL) {
|
||||
android_app->savedState = malloc(savedStateSize);
|
||||
android_app->savedStateSize = savedStateSize;
|
||||
memcpy(android_app->savedState, savedState, savedStateSize);
|
||||
}
|
||||
|
||||
int msgpipe[2];
|
||||
if (pipe(msgpipe)) {
|
||||
LOGE("could not create pipe: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
android_app->msgread = msgpipe[0];
|
||||
android_app->msgwrite = msgpipe[1];
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
|
||||
|
||||
// Wait for thread to start.
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
while (!android_app->running) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
return android_app;
|
||||
}
|
||||
|
||||
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->pendingInputQueue = inputQueue;
|
||||
android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
|
||||
while (android_app->inputQueue != android_app->pendingInputQueue) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->pendingWindow != NULL) {
|
||||
android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
|
||||
}
|
||||
android_app->pendingWindow = window;
|
||||
if (window != NULL) {
|
||||
android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
|
||||
}
|
||||
while (android_app->window != android_app->pendingWindow) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app_write_cmd(android_app, cmd);
|
||||
while (android_app->activityState != cmd) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
static void android_app_free(struct android_app* android_app) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app_write_cmd(android_app, APP_CMD_DESTROY);
|
||||
while (!android_app->destroyed) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
close(android_app->msgread);
|
||||
close(android_app->msgwrite);
|
||||
pthread_cond_destroy(&android_app->cond);
|
||||
pthread_mutex_destroy(&android_app->mutex);
|
||||
free(android_app);
|
||||
}
|
||||
|
||||
static void onDestroy(ANativeActivity* activity) {
|
||||
LOGV("Destroy: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_DESTROY);
|
||||
android_app_free(app);
|
||||
}
|
||||
|
||||
static void onStart(ANativeActivity* activity) {
|
||||
LOGV("Start: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_START);
|
||||
android_app_set_activity_state(app, APP_CMD_START);
|
||||
}
|
||||
|
||||
static void onResume(ANativeActivity* activity) {
|
||||
LOGV("Resume: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_RESUME);
|
||||
android_app_set_activity_state(app, APP_CMD_RESUME);
|
||||
}
|
||||
|
||||
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_SAVE_STATE);
|
||||
void* savedState = NULL;
|
||||
|
||||
LOGV("SaveInstanceState: %p\n", activity);
|
||||
pthread_mutex_lock(&app->mutex);
|
||||
app->stateSaved = 0;
|
||||
android_app_write_cmd(app, APP_CMD_SAVE_STATE);
|
||||
while (!app->stateSaved) {
|
||||
pthread_cond_wait(&app->cond, &app->mutex);
|
||||
}
|
||||
|
||||
if (app->savedState != NULL) {
|
||||
savedState = app->savedState;
|
||||
*outLen = app->savedStateSize;
|
||||
app->savedState = NULL;
|
||||
app->savedStateSize = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&app->mutex);
|
||||
|
||||
return savedState;
|
||||
}
|
||||
|
||||
static void onPause(ANativeActivity* activity) {
|
||||
LOGV("Pause: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_PAUSE);
|
||||
android_app_set_activity_state(app, APP_CMD_PAUSE);
|
||||
}
|
||||
|
||||
static void onStop(ANativeActivity* activity) {
|
||||
LOGV("Stop: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_STOP);
|
||||
android_app_set_activity_state(app, APP_CMD_STOP);
|
||||
}
|
||||
|
||||
static void onConfigurationChanged(ANativeActivity* activity) {
|
||||
LOGV("ConfigurationChanged: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_CONFIG_CHANGED);
|
||||
android_app_write_cmd(app, APP_CMD_CONFIG_CHANGED);
|
||||
}
|
||||
|
||||
static void onLowMemory(ANativeActivity* activity) {
|
||||
LOGV("LowMemory: %p\n", activity);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_LOW_MEMORY);
|
||||
android_app_write_cmd(app, APP_CMD_LOW_MEMORY);
|
||||
}
|
||||
|
||||
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
|
||||
LOGV("WindowFocusChanged: %p -- %d\n", activity, focused);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
int cmd = focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, cmd);
|
||||
android_app_write_cmd(app, cmd);
|
||||
}
|
||||
|
||||
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
|
||||
LOGV("NativeWindowCreated: %p -- %p\n", activity, window);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_INIT_WINDOW);
|
||||
android_app_set_window(app, window);
|
||||
}
|
||||
|
||||
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
|
||||
LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_TERM_WINDOW);
|
||||
android_app_set_window(app, NULL);
|
||||
}
|
||||
|
||||
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
|
||||
LOGV("InputQueueCreated: %p -- %p\n", activity, queue);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_INPUT_CHANGED);
|
||||
android_app_set_input(app, queue);
|
||||
}
|
||||
|
||||
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
|
||||
LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue);
|
||||
struct android_app* app = (struct android_app*)activity->instance;
|
||||
if (app->onAppCmdDirect != NULL) app->onAppCmdDirect(activity, APP_CMD_INPUT_CHANGED);
|
||||
android_app_set_input(app, NULL);
|
||||
}
|
||||
|
||||
void ANativeActivity_onCreate(ANativeActivity* activity,
|
||||
void* savedState, size_t savedStateSize) {
|
||||
LOGV("Creating: %p\n", activity);
|
||||
activity->callbacks->onDestroy = onDestroy;
|
||||
activity->callbacks->onStart = onStart;
|
||||
activity->callbacks->onResume = onResume;
|
||||
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
|
||||
activity->callbacks->onPause = onPause;
|
||||
activity->callbacks->onStop = onStop;
|
||||
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
|
||||
activity->callbacks->onLowMemory = onLowMemory;
|
||||
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
|
||||
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
|
||||
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
|
||||
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
|
||||
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
|
||||
|
||||
activity->instance = android_app_create(activity, savedState, savedStateSize);
|
||||
}
|
||||
353
lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.h
Normal file
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2018 Dawid Gan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_NATIVE_APP_GLUE_H
|
||||
#define _ANDROID_NATIVE_APP_GLUE_H
|
||||
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <android/configuration.h>
|
||||
#include <android/looper.h>
|
||||
#include <android/native_activity.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The native activity interface provided by <android/native_activity.h>
|
||||
* is based on a set of application-provided callbacks that will be called
|
||||
* by the Activity's main thread when certain events occur.
|
||||
*
|
||||
* This means that each one of this callbacks _should_ _not_ block, or they
|
||||
* risk having the system force-close the application. This programming
|
||||
* model is direct, lightweight, but constraining.
|
||||
*
|
||||
* The 'android_native_app_glue' static library is used to provide a different
|
||||
* execution model where the application can implement its own main event
|
||||
* loop in a different thread instead. Here's how it works:
|
||||
*
|
||||
* 1/ The application must provide a function named "android_main()" that
|
||||
* will be called when the activity is created, in a new thread that is
|
||||
* distinct from the activity's main thread.
|
||||
*
|
||||
* 2/ android_main() receives a pointer to a valid "android_app" structure
|
||||
* that contains references to other important objects, e.g. the
|
||||
* ANativeActivity obejct instance the application is running in.
|
||||
*
|
||||
* 3/ the "android_app" object holds an ALooper instance that already
|
||||
* listens to two important things:
|
||||
*
|
||||
* - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX
|
||||
* declarations below.
|
||||
*
|
||||
* - input events coming from the AInputQueue attached to the activity.
|
||||
*
|
||||
* Each of these correspond to an ALooper identifier returned by
|
||||
* ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
|
||||
* respectively.
|
||||
*
|
||||
* Your application can use the same ALooper to listen to additional
|
||||
* file-descriptors. They can either be callback based, or with return
|
||||
* identifiers starting with LOOPER_ID_USER.
|
||||
*
|
||||
* 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
|
||||
* the returned data will point to an android_poll_source structure. You
|
||||
* can call the process() function on it, and fill in android_app->onAppCmd
|
||||
* and android_app->onInputEvent to be called for your own processing
|
||||
* of the event.
|
||||
*
|
||||
* Alternatively, you can call the low-level functions to read and process
|
||||
* the data directly... look at the process_cmd() and process_input()
|
||||
* implementations in the glue to see how to do this.
|
||||
*
|
||||
* See the sample named "native-activity" that comes with the NDK with a
|
||||
* full usage example. Also look at the JavaDoc of NativeActivity.
|
||||
*/
|
||||
|
||||
struct android_app;
|
||||
|
||||
/**
|
||||
* Data associated with an ALooper fd that will be returned as the "outData"
|
||||
* when that source has data ready.
|
||||
*/
|
||||
struct android_poll_source {
|
||||
// The identifier of this source. May be LOOPER_ID_MAIN or
|
||||
// LOOPER_ID_INPUT.
|
||||
int32_t id;
|
||||
|
||||
// The android_app this ident is associated with.
|
||||
struct android_app* app;
|
||||
|
||||
// Function to call to perform the standard processing of data from
|
||||
// this source.
|
||||
void (*process)(struct android_app* app, struct android_poll_source* source);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the interface for the standard glue code of a threaded
|
||||
* application. In this model, the application's code is running
|
||||
* in its own thread separate from the main thread of the process.
|
||||
* It is not required that this thread be associated with the Java
|
||||
* VM, although it will need to be in order to make JNI calls any
|
||||
* Java objects.
|
||||
*/
|
||||
struct android_app {
|
||||
// The application can place a pointer to its own state object
|
||||
// here if it likes.
|
||||
void* userData;
|
||||
|
||||
// Fill this in with the function to process main app commands (APP_CMD_*)
|
||||
void (*onAppCmd)(struct android_app* app, int32_t cmd);
|
||||
|
||||
// Fill this in with the function to process input events. At this point
|
||||
// the event has already been pre-dispatched, and it will be finished upon
|
||||
// return. Return 1 if you have handled the event, 0 for any default
|
||||
// dispatching.
|
||||
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
|
||||
|
||||
// Function that allows to process (APP_CMD_*) directly in main thread
|
||||
void (*onAppCmdDirect)(ANativeActivity* activity, int32_t cmd);
|
||||
|
||||
// The ANativeActivity object instance that this app is running in.
|
||||
ANativeActivity* activity;
|
||||
|
||||
// The current configuration the app is running in.
|
||||
AConfiguration* config;
|
||||
|
||||
// This is the last instance's saved state, as provided at creation time.
|
||||
// It is NULL if there was no state. You can use this as you need; the
|
||||
// memory will remain around until you call android_app_exec_cmd() for
|
||||
// APP_CMD_RESUME, at which point it will be freed and savedState set to NULL.
|
||||
// These variables should only be changed when processing a APP_CMD_SAVE_STATE,
|
||||
// at which point they will be initialized to NULL and you can malloc your
|
||||
// state and place the information here. In that case the memory will be
|
||||
// freed for you later.
|
||||
void* savedState;
|
||||
size_t savedStateSize;
|
||||
|
||||
// The ALooper associated with the app's thread.
|
||||
ALooper* looper;
|
||||
|
||||
// When non-NULL, this is the input queue from which the app will
|
||||
// receive user input events.
|
||||
AInputQueue* inputQueue;
|
||||
|
||||
// When non-NULL, this is the window surface that the app can draw in.
|
||||
ANativeWindow* window;
|
||||
|
||||
// Current content rectangle of the window; this is the area where the
|
||||
// window's content should be placed to be seen by the user.
|
||||
ARect contentRect;
|
||||
|
||||
// Current state of the app's activity. May be either APP_CMD_START,
|
||||
// APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
|
||||
int activityState;
|
||||
|
||||
// This is non-zero when the application's NativeActivity is being
|
||||
// destroyed and waiting for the app thread to complete.
|
||||
int destroyRequested;
|
||||
|
||||
// -------------------------------------------------
|
||||
// Below are "private" implementation of the glue code.
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
|
||||
int msgread;
|
||||
int msgwrite;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
struct android_poll_source cmdPollSource;
|
||||
struct android_poll_source inputPollSource;
|
||||
|
||||
int running;
|
||||
int stateSaved;
|
||||
int destroyed;
|
||||
int redrawNeeded;
|
||||
AInputQueue* pendingInputQueue;
|
||||
ANativeWindow* pendingWindow;
|
||||
ARect pendingContentRect;
|
||||
};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Looper data ID of commands coming from the app's main thread, which
|
||||
* is returned as an identifier from ALooper_pollOnce(). The data for this
|
||||
* identifier is a pointer to an android_poll_source structure.
|
||||
* These can be retrieved and processed with android_app_read_cmd()
|
||||
* and android_app_exec_cmd().
|
||||
*/
|
||||
LOOPER_ID_MAIN = 1,
|
||||
|
||||
/**
|
||||
* Looper data ID of events coming from the AInputQueue of the
|
||||
* application's window, which is returned as an identifier from
|
||||
* ALooper_pollOnce(). The data for this identifier is a pointer to an
|
||||
* android_poll_source structure. These can be read via the inputQueue
|
||||
* object of android_app.
|
||||
*/
|
||||
LOOPER_ID_INPUT = 2,
|
||||
|
||||
/**
|
||||
* Start of user-defined ALooper identifiers.
|
||||
*/
|
||||
LOOPER_ID_USER = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Command from main thread: the AInputQueue has changed. Upon processing
|
||||
* this command, android_app->inputQueue will be updated to the new queue
|
||||
* (or NULL).
|
||||
*/
|
||||
APP_CMD_INPUT_CHANGED,
|
||||
|
||||
/**
|
||||
* Command from main thread: a new ANativeWindow is ready for use. Upon
|
||||
* receiving this command, android_app->window will contain the new window
|
||||
* surface.
|
||||
*/
|
||||
APP_CMD_INIT_WINDOW,
|
||||
|
||||
/**
|
||||
* Command from main thread: the existing ANativeWindow needs to be
|
||||
* terminated. Upon receiving this command, android_app->window still
|
||||
* contains the existing window; after calling android_app_exec_cmd
|
||||
* it will be set to NULL.
|
||||
*/
|
||||
APP_CMD_TERM_WINDOW,
|
||||
|
||||
/**
|
||||
* Command from main thread: the current ANativeWindow has been resized.
|
||||
* Please redraw with its new size.
|
||||
*/
|
||||
APP_CMD_WINDOW_RESIZED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the system needs that the current ANativeWindow
|
||||
* be redrawn. You should redraw the window before handing this to
|
||||
* android_app_exec_cmd() in order to avoid transient drawing glitches.
|
||||
*/
|
||||
APP_CMD_WINDOW_REDRAW_NEEDED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the content area of the window has changed,
|
||||
* such as from the soft input window being shown or hidden. You can
|
||||
* find the new content rect in android_app::contentRect.
|
||||
*/
|
||||
APP_CMD_CONTENT_RECT_CHANGED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity window has gained
|
||||
* input focus.
|
||||
*/
|
||||
APP_CMD_GAINED_FOCUS,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity window has lost
|
||||
* input focus.
|
||||
*/
|
||||
APP_CMD_LOST_FOCUS,
|
||||
|
||||
/**
|
||||
* Command from main thread: the current device configuration has changed.
|
||||
*/
|
||||
APP_CMD_CONFIG_CHANGED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the system is running low on memory.
|
||||
* Try to reduce your memory use.
|
||||
*/
|
||||
APP_CMD_LOW_MEMORY,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been started.
|
||||
*/
|
||||
APP_CMD_START,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been resumed.
|
||||
*/
|
||||
APP_CMD_RESUME,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app should generate a new saved state
|
||||
* for itself, to restore from later if needed. If you have saved state,
|
||||
* allocate it with malloc and place it in android_app.savedState with
|
||||
* the size in android_app.savedStateSize. The will be freed for you
|
||||
* later.
|
||||
*/
|
||||
APP_CMD_SAVE_STATE,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been paused.
|
||||
*/
|
||||
APP_CMD_PAUSE,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been stopped.
|
||||
*/
|
||||
APP_CMD_STOP,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity is being destroyed,
|
||||
* and waiting for the app thread to clean up and exit before proceeding.
|
||||
*/
|
||||
APP_CMD_DESTROY,
|
||||
};
|
||||
|
||||
/**
|
||||
* Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next
|
||||
* app command message.
|
||||
*/
|
||||
int8_t android_app_read_cmd(struct android_app* android_app);
|
||||
|
||||
/**
|
||||
* Call with the command returned by android_app_read_cmd() to do the
|
||||
* initial pre-processing of the given command. You can perform your own
|
||||
* actions for the command after calling this function.
|
||||
*/
|
||||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
|
||||
|
||||
/**
|
||||
* Call with the command returned by android_app_read_cmd() to do the
|
||||
* final post-processing of the given command. You must have done your own
|
||||
* actions for the command before calling this function.
|
||||
*/
|
||||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
|
||||
|
||||
/**
|
||||
* Dummy function you can call to ensure glue code isn't stripped.
|
||||
*/
|
||||
void app_dummy();
|
||||
|
||||
/**
|
||||
* This is the function that application code must implement, representing
|
||||
* the main entry to the app.
|
||||
*/
|
||||
extern void android_main(struct android_app* app);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ANDROID_NATIVE_APP_GLUE_H */
|
||||
@@ -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.
|
||||
|
||||
@@ -47,22 +47,26 @@ private:
|
||||
* one time only (which might get triggered more than once). */
|
||||
enum AnimTimeType { ATT_CYCLIC, ATT_CYCLIC_ONCE } m_anim_type;
|
||||
|
||||
/** The current time used in the IPOs. */
|
||||
float m_current_time;
|
||||
|
||||
/** The inital position of this object. */
|
||||
Vec3 m_initial_xyz;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** The current time used in the IPOs. */
|
||||
float m_current_time;
|
||||
|
||||
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,19 @@ 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;
|
||||
if (!m_is_paused)
|
||||
{
|
||||
int cur_ticks = World::getWorld()->getTicksSinceStart();
|
||||
m_current_time = stk_config->ticks2Time(cur_ticks);
|
||||
}
|
||||
|
||||
AnimationBase::update(dt, &xyz, &m_hpr, &scale); //updates all IPOs
|
||||
AnimationBase::getAt(m_current_time, &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
|
||||
|
||||
|
||||
@@ -274,8 +274,9 @@ void StoryModeStatus::unlockFeature(ChallengeStatus* c, RaceManager::Difficulty
|
||||
m_locked_features.erase(p);
|
||||
}
|
||||
|
||||
// Add to list of recently unlocked features if the challenge is newly completed
|
||||
if (!c->isSolvedAtAnyDifficulty())
|
||||
// Add to list of recently unlocked features
|
||||
// if the challenge is newly completed at the current difficulty
|
||||
if (!c->isSolved(d))
|
||||
m_unlocked_features.push_back(c->getData());
|
||||
|
||||
c->setSolved(d); // reset isActive flag
|
||||
|
||||
@@ -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)
|
||||
@@ -161,7 +152,11 @@ void STKConfig::load(const std::string &filename)
|
||||
CHECK_NEG(m_default_track_friction, "physics default-track-friction");
|
||||
CHECK_NEG(m_physics_fps, "physics fps" );
|
||||
CHECK_NEG(m_network_state_frequeny, "network state-frequency" );
|
||||
CHECK_NEG(m_network_steering_reduction,"network steering-reduction" );
|
||||
CHECK_NEG(m_default_moveable_friction, "physics default-moveable-friction");
|
||||
CHECK_NEG(m_solver_iterations, "physics: solver-iterations" );
|
||||
CHECK_NEG(m_network_state_frequeny, "network solver-state-frequency" );
|
||||
CHECK_NEG(m_solver_split_impulse_thresh,"physics: solver-split-impulse-threshold");
|
||||
|
||||
// Square distance to make distance checks cheaper (no sqrt)
|
||||
m_default_kart_properties->checkAllSet(filename);
|
||||
@@ -174,11 +169,11 @@ void STKConfig::load(const std::string &filename)
|
||||
*/
|
||||
void STKConfig::init_defaults()
|
||||
{
|
||||
m_bomb_time = m_bomb_time_increase =
|
||||
m_explosion_impulse_objects = m_music_credit_time =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_near_ground =
|
||||
m_smooth_angle_limit = m_default_track_friction =
|
||||
m_bomb_time = m_bomb_time_increase =
|
||||
m_explosion_impulse_objects = m_music_credit_time =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_near_ground = m_solver_split_impulse_thresh =
|
||||
m_smooth_angle_limit = m_default_track_friction =
|
||||
m_default_moveable_friction = UNDEFINED;
|
||||
m_item_switch_ticks = -100;
|
||||
m_penalty_ticks = -100;
|
||||
@@ -204,7 +199,12 @@ void STKConfig::init_defaults()
|
||||
m_donate_url = "";
|
||||
m_password_reset_url = "";
|
||||
m_network_state_frequeny = -100;
|
||||
m_solver_iterations = -100;
|
||||
m_solver_set_flags = 0;
|
||||
m_solver_reset_flags = 0;
|
||||
m_network_steering_reduction = -100;
|
||||
m_title_music = NULL;
|
||||
m_solver_split_impulse = false;
|
||||
m_smooth_normals = false;
|
||||
m_same_powerup_mode = POWERUP_MODE_ONLY_IF_SAME;
|
||||
m_ai_acceleration = 1.0f;
|
||||
@@ -289,6 +289,42 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
physics_node->get("default-moveable-friction",
|
||||
&m_default_moveable_friction);
|
||||
physics_node->get("fps", &m_physics_fps );
|
||||
physics_node->get("solver-iterations", &m_solver_iterations );
|
||||
physics_node->get("solver-split-impulse", &m_solver_split_impulse );
|
||||
physics_node->get("solver-split-impulse-threshold",
|
||||
&m_solver_split_impulse_thresh);
|
||||
std::vector<std::string> solver_modes;
|
||||
physics_node->get("solver-mode", &solver_modes );
|
||||
m_solver_set_flags=0, m_solver_reset_flags = 0;
|
||||
int *p;
|
||||
for (auto mode : solver_modes)
|
||||
{
|
||||
std::string s = mode;
|
||||
p = &m_solver_set_flags;
|
||||
if (s[0] == '-')
|
||||
{
|
||||
s.erase(s.begin());
|
||||
p = &m_solver_reset_flags;
|
||||
}
|
||||
s = StringUtils::toLowerCase(s);
|
||||
if (s == "randmize_order" ) *p |= 1;
|
||||
else if (s == "friction_separate" ) *p |= 2;
|
||||
else if (s == "use_warmstarting" ) *p |= 4;
|
||||
else if (s == "use_friction_warmstarting" ) *p |= 8;
|
||||
else if (s == "use_2_friction_directions" ) *p |= 16;
|
||||
else if (s == "enable_friction_direction_caching" ) *p |= 32;
|
||||
else if (s == "disable_velocity_dependent_friction_direction") *p |= 64;
|
||||
else if (s == "cache_friendly" ) *p |= 128;
|
||||
else if (s == "simd" ) *p |= 256;
|
||||
else if (s == "cuda" ) *p |= 512;
|
||||
else
|
||||
{
|
||||
Log::fatal("STK-Config",
|
||||
"Unknown option '%s' for solver-mode - ignored.",
|
||||
s.c_str());
|
||||
}
|
||||
} // for mode in solver_modes
|
||||
|
||||
}
|
||||
|
||||
if (const XMLNode *startup_node= root->getNode("startup"))
|
||||
@@ -399,9 +435,8 @@ 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);
|
||||
networking_node->get("steering-reduction", &m_network_steering_reduction);
|
||||
}
|
||||
|
||||
if(const XMLNode *replay_node = root->getNode("replay"))
|
||||
|
||||
@@ -89,12 +89,10 @@ 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;
|
||||
/** In case of a network race, remote karts will get their steering somewhat
|
||||
* reduced each frame. This reduces stutter when a kart only does small
|
||||
* steering adjustments. */
|
||||
float m_network_steering_reduction;
|
||||
|
||||
/** 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
|
||||
@@ -107,6 +105,19 @@ public:
|
||||
/** Default friction to be used for any moveable, e.g. karts, balls. */
|
||||
float m_default_moveable_friction;
|
||||
|
||||
/** Number of solver iterations. */
|
||||
int m_solver_iterations;
|
||||
|
||||
/** If position and velocity constraints are solved separately. */
|
||||
bool m_solver_split_impulse;
|
||||
|
||||
/** Threshold when to use the split impulse approach. */
|
||||
float m_solver_split_impulse_thresh;
|
||||
|
||||
/** Bit flags to modify the solver mode. Bits set in set_flags are
|
||||
* added to the solver mode, bits set in reset_flags are removed. */
|
||||
int m_solver_set_flags, m_solver_reset_flags;
|
||||
|
||||
int m_max_skidmarks; /**<Maximum number of skid marks/kart. */
|
||||
float m_skid_fadeout_time; /**<Time till skidmarks fade away. */
|
||||
float m_near_ground; /**<Determines when a kart is not near
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -679,10 +680,6 @@ namespace UserConfigParams
|
||||
/** True if graphical profiler should be displayed */
|
||||
PARAM_PREFIX bool m_profiler_enabled PARAM_DEFAULT( false );
|
||||
|
||||
/** How many seconds worth of data the circular profile buffer
|
||||
* can store. */
|
||||
PARAM_PREFIX float m_profiler_buffer_duration PARAM_DEFAULT(20.0f);
|
||||
|
||||
// ---- Networking
|
||||
PARAM_PREFIX StringToUIntUserConfigParam m_stun_list
|
||||
PARAM_DEFAULT(StringToUIntUserConfigParam("stun_list",
|
||||
@@ -707,9 +704,14 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_log_packets
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "log-network-packets",
|
||||
&m_network_group, "If all network packets should be logged"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_random_ports
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "random-ports",
|
||||
&m_network_group, "Use random ports for client and server connection"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_random_client_port
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "random-client-port",
|
||||
&m_network_group, "Use random port for client connection "
|
||||
"(check stk_config.xml for default value)"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_random_server_port
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "random-server-port",
|
||||
&m_network_group, "Use random port for server connection "
|
||||
"(check stk_config.xml for default value)"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_lobby_chat
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "lobby-chat",
|
||||
&m_network_group, "Enable chatting in networking lobby, if off than "
|
||||
@@ -721,7 +723,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",
|
||||
@@ -744,6 +746,15 @@ namespace UserConfigParams
|
||||
"from this IP will be banned.",
|
||||
{ { "0.0.0.0", 0u } }
|
||||
));
|
||||
PARAM_PREFIX IntUserConfigParam m_max_ping
|
||||
PARAM_DEFAULT(IntUserConfigParam(300, "max-ping",
|
||||
&m_network_group, "Maximum ping allowed for a player (in ms)."));
|
||||
PARAM_PREFIX IntUserConfigParam m_jitter_tolerance
|
||||
PARAM_DEFAULT(IntUserConfigParam(100, "jitter-tolerance",
|
||||
&m_network_group, "Tolerance of jitter in network allowed (in ms)."));
|
||||
PARAM_PREFIX BoolUserConfigParam m_kick_high_ping_players
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "kick-high-ping-players",
|
||||
&m_network_group, "Kick players whose ping is above max-ping."));
|
||||
|
||||
// ---- Gamemode setup
|
||||
PARAM_PREFIX UIntToUIntUserConfigParam m_num_karts_per_gamemode
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android_native_app_glue.h>
|
||||
#include "../../../lib/irrlicht/source/Irrlicht/stk_android_native_app_glue.h"
|
||||
#endif
|
||||
|
||||
using GUIEngine::EventHandler;
|
||||
@@ -387,8 +387,6 @@ void EventHandler::deallocate()
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const bool NAVIGATION_DEBUG = false;
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark Private methods
|
||||
@@ -496,7 +494,8 @@ void EventHandler::navigate(const NavigationDirection nav, const int playerID)
|
||||
|
||||
} // navigate
|
||||
|
||||
/* This function use simple heuristic to find the closest widget
|
||||
/**
|
||||
* This function use simple heuristic to find the closest widget
|
||||
* in the requested direction,
|
||||
* It prioritize widgets close vertically to widget close horizontally,
|
||||
* as it is expected behavior in any direction.
|
||||
@@ -536,6 +535,22 @@ int EventHandler::findIDClosestWidget(const NavigationDirection nav, const int p
|
||||
(playerID != PLAYER_ID_GAME_MASTER && !w_test->m_supports_multiplayer))
|
||||
continue;
|
||||
|
||||
// Ignore empty ribbon widgets and lists
|
||||
if (w_test->m_type == GUIEngine::WTYPE_RIBBON)
|
||||
{
|
||||
RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(w_test);
|
||||
assert(ribbon != NULL);
|
||||
if (ribbon->getActiveChildrenNumber(playerID) == 0)
|
||||
continue;
|
||||
}
|
||||
else if (w_test->m_type == WTYPE_LIST)
|
||||
{
|
||||
ListWidget* list = (ListWidget*) w_test;
|
||||
assert(list != NULL);
|
||||
if (list->getItemCount() == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
// if a dialog is shown, restrict to items in the dialog
|
||||
if (ScreenKeyboard::isActive())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -912,19 +912,19 @@ void Skin::drawRibbon(const core::recti &rect, Widget* widget,
|
||||
{
|
||||
} // drawRibbon
|
||||
|
||||
SColorf GetPlayerColor(int player_id)
|
||||
// ----------------------------------------------------------------------------
|
||||
SColorf Skin::getPlayerColor(int player_id)
|
||||
{
|
||||
|
||||
SColorHSL col = { 0,100,50 };
|
||||
col.Hue += (360 / 4) * (player_id % 4);
|
||||
int color_id = player_id % 4;
|
||||
SColorf color_rgb = { 0,0,0,1 };
|
||||
|
||||
|
||||
col.Saturation = col.Saturation * (1.0f / (floorf(float(player_id / 4)) + 1) );
|
||||
|
||||
col.Saturation = col.Saturation *
|
||||
(1.0f / (floorf(float(player_id / 4)) + 1));
|
||||
col.toRGB(color_rgb);
|
||||
return color_rgb;
|
||||
}
|
||||
} // getPlayerColor
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
* @param focused whether this element is focus by the master player (whether
|
||||
@@ -1198,7 +1198,7 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
|
||||
} // end if mark_focused
|
||||
|
||||
//Handle drawing for everyone else
|
||||
for (int i = 1; i < MAX_PLAYER_COUNT; i++)
|
||||
for (unsigned i = 1; i < MAX_PLAYER_COUNT; i++)
|
||||
{
|
||||
// ---- Draw selection for other players than player 1
|
||||
if (parentRibbon->isFocusedForPlayer(i) &&
|
||||
@@ -1209,8 +1209,8 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget,
|
||||
short green_previous = parentRibbonWidget->m_skin_g;
|
||||
short blue_previous = parentRibbonWidget->m_skin_b;
|
||||
|
||||
SColorf color_rgb = GetPlayerColor(i);
|
||||
|
||||
SColorf color_rgb = getPlayerColor(i);
|
||||
|
||||
parentRibbonWidget->m_skin_r = short(color_rgb.r * 255.0f);
|
||||
parentRibbonWidget->m_skin_g = short(color_rgb.g * 255.0f);
|
||||
parentRibbonWidget->m_skin_b = short(color_rgb.b * 255.0f);
|
||||
@@ -1304,7 +1304,7 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
|
||||
params = &SkinConfig::m_render_params[
|
||||
"spinner::deactivated"];
|
||||
|
||||
color_rgb = GetPlayerColor(player_id);
|
||||
color_rgb = getPlayerColor(player_id);
|
||||
|
||||
texture = "squareFocusHaloBW::neutral";
|
||||
}
|
||||
@@ -1324,23 +1324,20 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
|
||||
widget->m_skin_g = short(color_rgb.g * 255.0f);
|
||||
widget->m_skin_b = short(color_rgb.b * 255.0f);
|
||||
|
||||
for (int i = 1; i < MAX_PLAYER_COUNT + 1; i++)
|
||||
for (unsigned i = 1; i < MAX_PLAYER_COUNT + 1; i++)
|
||||
{
|
||||
if (widget->isFocusedForPlayer(i - 1)) {
|
||||
if (widget->isFocusedForPlayer(i - 1))
|
||||
{
|
||||
core::recti rect2 = rect;
|
||||
rect2.UpperLeftCorner.X += 2;
|
||||
rect2.UpperLeftCorner.Y -= 3;
|
||||
rect2.LowerRightCorner.X -= 2;
|
||||
rect2.LowerRightCorner.Y += 5;
|
||||
|
||||
|
||||
drawBoxFromStretchableTexture(widget, rect2,
|
||||
SkinConfig::m_render_params[texture]);
|
||||
//TODO add squarefocushalo0
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
core::recti sized_rect = rect;
|
||||
if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL &&
|
||||
@@ -1516,6 +1513,18 @@ void Skin::drawIconButton(const core::recti &rect, Widget* widget,
|
||||
|
||||
IconButtonWidget* icon_widget = (IconButtonWidget*) widget;
|
||||
|
||||
if (icon_widget->hasTooltip() > 0)
|
||||
{
|
||||
const core::position2di mouse_position =
|
||||
irr_driver->getDevice()->getCursorControl()->getPosition();
|
||||
|
||||
if (rect.isPointInside(mouse_position))
|
||||
{
|
||||
m_tooltip_at_mouse.push_back(true);
|
||||
m_tooltips.push_back(widget);
|
||||
}
|
||||
}
|
||||
|
||||
if (widget->m_type == WTYPE_MODEL_VIEW)
|
||||
{
|
||||
// Model view widgets don't generate mipmaps so disable material 2D
|
||||
|
||||
@@ -316,7 +316,7 @@ namespace GUIEngine
|
||||
const bool pressed, const bool bottomArrow);
|
||||
|
||||
void drawTooltip(Widget* widget, bool atMouse);
|
||||
|
||||
irr::video::SColorf getPlayerColor(int player_id);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -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,52 +86,81 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
} // KartStatsWidget
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void KartStatsWidget::setValues(const KartProperties* props,
|
||||
PerPlayerDifficulty d)
|
||||
{
|
||||
// Use kart properties computed for "hard" difficulty to show the user, so
|
||||
// Use kart properties computed for best difficulty to show the user, so
|
||||
// that properties don't change according to the the last used difficulty
|
||||
// (And because this code uses arbitrary scaling factors to make them look
|
||||
// nice and the arbitrary factors were optimised for hard difficulty)
|
||||
RaceManager::Difficulty previous_difficulty = race_manager->getDifficulty();
|
||||
race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD);
|
||||
race_manager->setDifficulty(RaceManager::DIFFICULTY_BEST);
|
||||
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
|
||||
// different masses or velocities.
|
||||
// A value of 100 takes the whole bar width, including borders.
|
||||
// So values should be in the 0-99 range
|
||||
|
||||
// The base mass is of 350 ; 350/3.89 ~= 90
|
||||
m_skills[SKILL_MASS]->setValue((int)
|
||||
((kp_computed.getCombinedCharacteristic()->getMass() - 20) / 4));
|
||||
(kp_computed.getCombinedCharacteristic()->getMass()/3.89f));
|
||||
m_skills[SKILL_MASS]->setIcon(irr::core::stringc(
|
||||
file_manager->getAsset(FileManager::GUI, "mass.png").c_str()));
|
||||
m_skills[SKILL_MASS]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_mass", m_player_id);
|
||||
m_skills[SKILL_MASS]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_mass", m_player_id);
|
||||
m_skills[SKILL_MASS]->m_iconbutton->setTooltip( _("Mass") );
|
||||
|
||||
// The base speed is of 25
|
||||
// Here we are not fully proportional, because small differences matter more
|
||||
m_skills[SKILL_SPEED]->setValue((int)
|
||||
((kp_computed.getCombinedCharacteristic()->getEngineMaxSpeed() - 15) * 6));
|
||||
((kp_computed.getCombinedCharacteristic()->getEngineMaxSpeed() - 20) * 15));
|
||||
m_skills[SKILL_SPEED]->setIcon(irr::core::stringc(
|
||||
file_manager->getAsset(FileManager::GUI, "speed.png").c_str()));
|
||||
m_skills[SKILL_SPEED]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_speed", m_player_id);
|
||||
m_skills[SKILL_SPEED]->m_iconbutton->setTooltip( _("Maximum speed") );
|
||||
|
||||
m_skills[SKILL_POWER]->setValue((int)((kp_computed.getAvgPower() - 30) / 20));
|
||||
m_skills[SKILL_POWER]->setIcon(irr::core::stringc(
|
||||
// The acceleration depend on power and mass, and it changes depending on speed
|
||||
// We call a function which gives us a single number to represent it
|
||||
// power/mass gives numbers in the 1-10 range, so we multiply it by 10.
|
||||
|
||||
m_skills[SKILL_ACCELERATION]->setValue((int)(kp_computed.getAccelerationEfficiency()*10));
|
||||
m_skills[SKILL_ACCELERATION]->setIcon(irr::core::stringc(
|
||||
file_manager->getAsset(FileManager::GUI, "power.png").c_str()));
|
||||
m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id);
|
||||
m_skills[SKILL_ACCELERATION]->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_acceleration", m_player_id);
|
||||
m_skills[SKILL_ACCELERATION]->m_iconbutton->setTooltip( _("Acceleration") );
|
||||
|
||||
// The base nitro consumption is 1, higher for heavier karts.
|
||||
// Nitro efficiency is hence 90/nitro_consumption
|
||||
|
||||
m_skills[SKILL_NITRO_EFFICIENCY]->setValue((int)
|
||||
(90.0f/kp_computed.getCombinedCharacteristic()->getNitroConsumption()));
|
||||
m_skills[SKILL_NITRO_EFFICIENCY]->setIcon(irr::core::stringc(
|
||||
file_manager->getAsset(FileManager::GUI, "nitro.png").c_str()));
|
||||
m_skills[SKILL_NITRO_EFFICIENCY]->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_nitro_efficiency", m_player_id);
|
||||
m_skills[SKILL_NITRO_EFFICIENCY]->m_iconbutton->setTooltip( _("Nitro efficiency") );
|
||||
|
||||
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 +176,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 +219,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 +227,3 @@ void KartStatsWidget::setDisplayIcons(bool display_icons)
|
||||
m_skills[i]->setDisplayIcon(display_icons);
|
||||
}
|
||||
} // setDisplayText
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||