Merge remote-tracking branch 'origin/master' into network-items,

fixed conflicts.
This commit is contained in:
hiker 2018-06-08 10:55:14 +10:00
commit b0da0f640a
259 changed files with 7953 additions and 3205 deletions

View File

@ -26,13 +26,28 @@ option(USE_SYSTEM_ENET "Use system ENET instead of the built-in version, when av
option(USE_SYSTEM_GLEW "Use system GLEW instead of the built-in version, when available." ON)
CMAKE_DEPENDENT_OPTION(BUILD_RECORDER "Build opengl recorder" ON
"NOT SERVER_ONLY;NOT USE_GLES2;NOT APPLE" OFF)
"NOT SERVER_ONLY;NOT APPLE" OFF)
if(APPLE)
list(APPEND CMAKE_PREFIX_PATH /usr/local/opt)
include_directories(/usr/local/opt/fribidi/include/)
include_directories(/usr/local/opt/openssl@1.1/include/)
include_directories(/usr/local/opt/openssl@1.1/include/openssl/)
include_directories(/usr/local/opt/freetype/include/freetype2/)
endif()
if((UNIX AND NOT APPLE) AND NOT SERVER_ONLY)
option(ENABLE_WAYLAND_DEVICE "Enable Wayland device for linux build" ON)
if((${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") OR
(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64"))
option(USE_GLES2 "Use OpenGL ES2 renderer" ON)
else()
option(USE_GLES2 "Use OpenGL ES2 renderer" OFF)
endif()
endif()
if(UNIX OR MINGW)
option(DEBUG_SYMBOLS "Compile with debug symbols" OFF)
endif()
@ -143,7 +158,13 @@ else()
endif()
# Find system GLEW library or build it if missing
if(NOT USE_GLES2 AND NOT SERVER_ONLY)
if (APPLE)
find_package(glew)
if(GLEW_FOUND)
include_directories(${GLEW_INCLUDE_DIRS})
endif()
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)
@ -216,12 +237,12 @@ if (BUILD_RECORDER)
endif()
endif()
if(NOT SERVER_ONLY AND NOT USE_GLES2)
if(NOT SERVER_ONLY)
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/graphics_utils")
include_directories("${PROJECT_SOURCE_DIR}/lib/graphics_utils")
endif()
if(NOT SERVER_ONLY AND NOT USE_GLES2)
if(NOT SERVER_ONLY)
find_library(SQUISH_LIBRARY NAMES squish libsquish)
find_path(SQUISH_INCLUDEDIR NAMES squish.h PATHS)
if (NOT SQUISH_LIBRARY OR NOT SQUISH_INCLUDEDIR)
@ -277,29 +298,12 @@ else()
endif()
# OpenAL
if(APPLE)
# In theory it would be cleaner to let CMake detect the right dependencies. In practice, this means that if a OSX user has
# unix-style installs of Vorbis/Ogg/OpenAL/etc. they will be picked up over our frameworks. This is blocking when I make releases :
# the mac I use to make STK releases does have other installs of vorbis/ogg/etc. which aren't compatible with STK, so letting
# CMake pick the library it wants essentially means I can't build.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework OpenAL")
set(OPENAL_LIBRARY)
else()
find_package(OpenAL REQUIRED)
include_directories(${OPENAL_INCLUDE_DIR})
endif()
# OggVorbis
if(APPLE)
# In theory it would be cleaner to let CMake detect the right dependencies. In practice, this means that if a OSX user has
# unix-style installs of Vorbis/Ogg/OpenAL/etc. they will be picked up over our frameworks. This is blocking when I make releases :
# the mac I use to make STK releases does have other installs of vorbis/ogg/etc. which aren't compatible with STK, so letting
# CMake pick the library it wants essentially means I can't build.
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -I/Library/Frameworks/Ogg.framework/Versions/A/Headers -I/Library/Frameworks/Vorbis.framework/Versions/A/Headers")
else()
find_package(OggVorbis REQUIRED)
include_directories(${OGGVORBIS_INCLUDE_DIRS})
endif()
# Freetype
find_package(Freetype)
@ -450,14 +454,26 @@ else()
target_link_libraries(supertuxkart ${PTHREAD_LIBRARY})
endif()
# CURL
# CURL and OpenSSL
# 1.0.1d for compatible AES GCM handling
SET(OPENSSL_MINIMUM_VERSION "1.0.1d")
if(MSVC)
target_link_libraries(supertuxkart ${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib/libcurl.lib)
target_link_libraries(supertuxkart ${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib/libeay32.lib)
elseif(MINGW)
target_link_libraries(supertuxkart ${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib/libcurldll.a)
target_link_libraries(supertuxkart ${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib/libeay32.dll)
else()
find_package(CURL REQUIRED)
find_package(OpenSSL REQUIRED)
if(${OPENSSL_VERSION} VERSION_LESS ${OPENSSL_MINIMUM_VERSION} OR
(${OPENSSL_VERSION} VERSION_EQUAL ${OPENSSL_MINIMUM_VERSION} AND ${OPENSSL_VERSION} STRLESS ${OPENSSL_MINIMUM_VERSION}))
message(FATAL_ERROR "OpenSSL version found (${OPENSSL_VERSION}) is less then the minimum required (${OPENSSL_MINIMUM_VERSION}), aborting.")
endif()
include_directories(${CURL_INCLUDE_DIRS})
include_directories(${OpenSSL_INCLUDE_DIRS})
endif()
# Common library dependencies
@ -474,19 +490,17 @@ target_link_libraries(supertuxkart
${FREETYPE_LIBRARIES}
${JPEG_LIBRARIES}
${TURBOJPEG_LIBRARY}
#${VPX_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY}
)
if(NOT SERVER_ONLY)
if(NOT USE_GLES2)
target_link_libraries(supertuxkart ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARIES} graphics_utils)
target_link_libraries(supertuxkart ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARIES})
else()
target_link_libraries(supertuxkart GLESv2)
endif()
endif()
if(NOT SERVER_ONLY AND NOT USE_GLES2)
target_link_libraries(supertuxkart ${SQUISH_LIBRARY})
target_link_libraries(supertuxkart ${SQUISH_LIBRARY} graphics_utils)
endif()
if(UNIX AND NOT APPLE)
@ -508,15 +522,6 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
endif()
if(APPLE)
# In theory it would be cleaner to let CMake detect the right dependencies. In practice, this means that if a OSX user has
# unix-style installs of Vorbis/Ogg/OpenAL/etc. they will be picked up over our frameworks. This is blocking when I make releases :
# the mac I use to make STK releases does have other installs of vorbis/ogg/etc. which aren't compatible with STK, so letting
# CMake pick the library it wants essentially means I can't build.
set_target_properties(supertuxkart PROPERTIES LINK_FLAGS "-arch x86_64 -F/Library/Frameworks -framework OpenAL -framework Ogg -framework Vorbis")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/Library/Frameworks/OpenAL.framework/Versions/A/Headers")
endif()
if(USE_FRIBIDI)
target_link_libraries(supertuxkart ${FRIBIDI_LIBRARIES})
add_definitions(-DENABLE_BIDI)

View File

@ -188,20 +188,55 @@ On OS X 10.9.5, you might need the following workaround:
sudo ln -s `xcrun --show-sdk-path`/usr/include/ /usr/include
sudo ln -s `xcrun --show-sdk-path`/System/Library/Frameworks/OpenGL.framework/Headers/ /usr/local/include/OpenGL
```
The first link is required in order to find libcurl, the second to find opengl.
Download pre-built dependencies from [here](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/OSX/) and put the frameworks in [hard disk root]/Library/Frameworks
### CMake
CMake is used to build STK. At this time CMake will not make a binary that is ready for distribution.
You'll have to run these commands inside your stk-code directory.
### Building
With clang:
### STK 0.9.4 or later (or latest git)
Install homebrew ( https://brew.sh/)
Install all of the dependencies using homebrew :
```bash
brew install libogg
brew install libvorbis
brew install openal-soft
brew install freetype
brew install curl
brew install openssl@1.1
brew install fribidi
brew install glew
```
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
make
```
#### (Optional) packaging for distribution
By default, the executable that is produced is not ready for distribution. Install https://github.com/auriamg/macdylibbundler
```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
### STK 0.9.3 or earlier
Download pre-built dependencies from [here](https://sourceforge.net/projects/supertuxkart/files/SuperTuxKart%20Dependencies/OSX/) and put the frameworks in [hard disk root]/Library/Frameworks
Building with clang:
```bash
mkdir cmake_build
@ -210,7 +245,7 @@ cmake ..
make
```
With GCC:
Building with GCC:
```bash
mkdir cmake_build
cd cmake_build
@ -223,7 +258,7 @@ Building on 10.10 with 10.9 compatibility:
cmake .. -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9
```
### Xcode
#### Xcode
Place an additional copy of the dependencies into `Users/<YOUR_USERNAME>/Library/Frameworks`.
Then cd to your cloned stk-code directory and execute the following commands:

View File

@ -158,6 +158,7 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \
-Iobj/libogg/include \
-Iobj/libvorbis/include \
-Iobj/openal/include \
-Iobj/openssl/include \
-I$(call my-dir)/../../sources/android/native_app_glue \
-DUSE_GLES2 \
-DHAVE_OGGVORBIS \

View File

@ -39,8 +39,6 @@
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@ -237,7 +237,7 @@ if [ -f "$DIRNAME/obj/project_version" ]; then
PROJECT_VERSION_PREV=$(cat "$DIRNAME/obj/project_version")
if [ -z "$PROJECT_VERSION" ]; then
PROJECT_VERSION="$PROJECT_VERSION_PREV"
export PROJECT_VERSION="$PROJECT_VERSION_PREV"
elif [ "$PROJECT_VERSION" != "$PROJECT_VERSION_PREV" ]; then
echo "Different project version has been set. Forcing recompilation..."
touch -c "$DIRNAME/Android.mk"
@ -246,7 +246,7 @@ fi
if [ -z "$PROJECT_VERSION" ]; then
if [ $IS_DEBUG_BUILD -ne 0 ]; then
PROJECT_VERSION="git"
export PROJECT_VERSION="git"
else
echo "Error: Variable PROJECT_VERSION is not set. It must have unique" \
"value for release build."
@ -479,6 +479,10 @@ convert -scale 48x48 "$APP_ICON" "$DIRNAME/res/drawable-mdpi/icon.png"
convert -scale 96x96 "$APP_ICON" "$DIRNAME/res/drawable-xhdpi/icon.png"
convert -scale 144x144 "$APP_ICON" "$DIRNAME/res/drawable-xxhdpi/icon.png"
if [ -f "/usr/lib/jvm/java-8-openjdk-amd64/bin/java" ]; then
export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
export PATH=$JAVA_HOME/bin:$PATH
fi
if [ "$BUILD_TOOL" = "gradle" ]; then
export ANDROID_HOME="$SDK_PATH"

View File

@ -9,14 +9,7 @@
# FRIBIDI_LIBRARIES
# Fribidi library list
if(APPLE)
set(FRIBIDI_INCLUDE_DIR NAMES fribidi/fribidi.h PATHS /Library/Frameworks/fribidi.framework/Headers)
find_library(FRIBIDI_LIBRARY NAMES fribidi PATHS /Library/Frameworks/fribidi.framework)
set(FRIBIDI_LIBRARIES ${FRIBIDI_LIBRARY})
include_directories(/Library/Frameworks/fribidi.framework/Headers)
#add_definitions(-framework fribidi)
set(FRIBIDI_FOUND 1)
elseif(UNIX)
if(UNIX)
include(FindPkgConfig)
pkg_check_modules(FRIBIDI fribidi)
else()

View File

@ -17,20 +17,6 @@ find_library(OGGVORBIS_VORBIS_LIBRARY NAMES vorbis Vorbis libvorbis PATHS "${PRO
find_library(OGGVORBIS_VORBISFILE_LIBRARY NAMES vorbisfile libvorbisfile PATHS "${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib")
find_library(OGGVORBIS_VORBISENC_LIBRARY NAMES vorbisenc libvorbisenc PATHS "${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/lib")
if (APPLE)
set(OGGVORBIS_OGG_INCLUDE_DIR "/Library/Frameworks/Ogg.framework/Headers/")
set(OGGVORBIS_VORBIS_INCLUDE_DIR "/Library/Frameworks/Vorbis.framework/Headers/")
endif()
if(APPLE AND NOT OGGVORBIS_VORBISFILE_LIBRARY)
# Seems to be the same on Apple systems
set(OGGVORBIS_VORBISFILE_LIBRARY ${OGGVORBIS_VORBIS_LIBRARY})
endif()
if(APPLE AND NOT OGGVORBIS_VORBISENC_LIBRARY)
# Seems to be the same on Apple systems
set(OGGVORBIS_VORBISENC_LIBRARY ${OGGVORBIS_VORBIS_LIBRARY})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OggVorbis DEFAULT_MSG

View File

@ -1,15 +1,20 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="abyss" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="0"/>
<best>
<karts number="7"/>
<requirements position="1" time="150"/>
</best>
<hard>
<karts number="5"/>
<requirements position="1" time="160"/>
<karts number="6"/>
<requirements position="1" time="165"/>
</hard>
<medium>
<karts number="4"/>
<karts number="5"/>
<requirements time="197"/>
</medium>
<easy>

View File

@ -1,21 +1,26 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="candela_city" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="70"/>
<requirements trophies="75"/>
<best>
<karts number="9"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="8"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="7"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="6"/>
<requirements position="1"/>
</easy>
<unlock kart="sara_the_wizard"/>
<unlock kart="sara_the_racer"/>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="cocoa_temple" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="5"/>
<best>
<karts number="8"/>
<requirements position="1" time="140"/>
</best>
<hard>
<karts number="5"/>
<karts number="7"/>
<requirements position="1" time="170"/>
</hard>
<medium>
<karts number="4"/>
<karts number="6"/>
<requirements time="210"/>
</medium>
<easy>
<karts number="4"/>
<karts number="5"/>
<requirements time="300"/>
</easy>
</challenge>

View File

@ -1,15 +1,20 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="cornfield_crossing" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="0"/>
<best>
<karts number="7"/>
<requirements position="1" time="140"/>
</best>
<hard>
<karts number="5"/>
<karts number="6"/>
<requirements position="1" time="165"/>
</hard>
<medium>
<karts number="4"/>
<karts number="5"/>
<requirements time="195"/>
</medium>
<easy>

View File

@ -1,9 +1,14 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="fortmagma" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="180"/>
<requirements trophies="190"/>
<best>
<karts number="2" aiIdent="nolok" superPower="nolokBoss"/>
<requirements position="1"/>
</best>
<hard>
<karts number="2" aiIdent="nolok" superPower="nolokBoss"/>
<requirements position="1"/>
@ -19,6 +24,5 @@
<unlock kart="gnu"/>
<unlock kart="nolok"/>
<unlock difficulty="difficulty_best"/>
<unlock track="fortmagma"/>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<grandprix id="1_penguinplayground"/>
<mode major="grandprix" minor="quickrace"/>
<requirements trophies="40"/>
<requirements trophies="30"/>
<best>
<karts number="7"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="6"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="5"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="4"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<grandprix id="2_offthebeatentrack"/>
<mode major="grandprix" minor="quickrace"/>
<requirements trophies="85"/>
<requirements trophies="70"/>
<best>
<karts number="8"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="7"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="6"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="5"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<grandprix id="3_tothemoonandback"/>
<mode major="grandprix" minor="quickrace"/>
<requirements trophies="125"/>
<requirements trophies="120"/>
<best>
<karts number="9"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="8"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="7"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="6"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<grandprix id="4_atworldsend"/>
<mode major="grandprix" minor="quickrace"/>
<requirements trophies="165"/>
<best>
<karts number="10"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="9"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="8"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="7"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,20 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="gran_paradiso_island" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="95"/>
<requirements trophies="80"/>
<best>
<karts number="9"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="8"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="7"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="6"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="greenvalley" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="95"/>
<requirements trophies="90"/>
<best>
<karts number="9"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="8"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="7"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="4"/>
<karts number="6"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="hacienda" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="45"/>
<requirements trophies="25"/>
<best>
<karts number="8"/>
<requirements position="1" time="130"/>
</best>
<hard>
<karts number="5"/>
<requirements position="2" time="170"/>
<karts number="7"/>
<requirements position="1" time="160"/>
</hard>
<medium>
<karts number="4"/>
<requirements time="187"/>
<karts number="6"/>
<requirements position="2" time="187"/>
</medium>
<easy>
<karts number="4"/>
<karts number="5"/>
<requirements time="260"/>
</easy>
</challenge>

View File

@ -1,20 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="lighthouse" laps="3"/>
<challenge version="3">
<unlock_list list="false"/>
<track id="lighthouse" laps="4"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="135"/>
<requirements trophies="125"/>
<best>
<karts number="10"/>
<requirements position="1" time="120"/>
</best>
<hard>
<karts number="5"/>
<requirements time="110" position="1"/>
<karts number="9"/>
<requirements position="1" time="140"/>
</hard>
<medium>
<karts number="4"/>
<requirements time="145" position="1"/>
<karts number="8"/>
<requirements position="1" time="190"/>
</medium>
<easy>
<karts number="3"/>
<requirements time="185"/>
<karts number="7"/>
<requirements time="250"/>
</easy>
</challenge>

View File

@ -1,18 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="mansion" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="110"/>
<requirements trophies="100"/>
<best>
<karts number="9"/>
<requirements position="1" time="100"/>
</best>
<hard>
<karts number="5"/>
<requirements time="110"/>
<karts number="8"/>
<requirements position="1" time="115"/>
</hard>
<medium>
<karts number="4"/>
<requirements time="130"/>
<karts number="7"/>
<requirements time="140"/>
</medium>
<easy>
<karts number="4"/>
<requirements time="160"/>
<karts number="6"/>
<requirements time="180"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="mines" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="150"/>
<requirements trophies="140"/>
<best>
<karts number="10"/>
<requirements position="1" time="140"/>
</best>
<hard>
<karts number="4"/>
<requirements time="160"/>
<karts number="9"/>
<requirements position="1" time="160"/>
</hard>
<medium>
<karts number="4"/>
<requirements time="190"/>
<karts number="8"/>
<requirements position="2" time="190"/>
</medium>
<easy>
<karts number="4"/>
<karts number="7"/>
<requirements time="255"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="minigolf" laps="3"/>
<challenge version="3">
<unlock_list list="false"/>
<track id="minigolf" laps="4"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="150"/>
<requirements trophies="130"/>
<best>
<karts number="10"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="9"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="8"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="3"/>
<karts number="7"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,20 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="olivermath" laps="3"/>
<challenge version="3">
<unlock_list list="false"/>
<track id="olivermath" laps="5"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="0"/>
<best>
<karts number="7"/>
<requirements position="1" time="95"/>
</best>
<hard>
<karts number="5"/>
<requirements position="1" time="65"/>
<karts number="6"/>
<requirements position="1" time="110"/>
</hard>
<medium>
<karts number="5"/>
<requirements position="1" time="85"/>
<requirements position="1" time="140"/>
</medium>
<easy>
<karts number="5"/>
<requirements position="1" time="130"/>
<karts number="4"/>
<requirements position="1" time="210"/>
</easy>
</challenge>

View File

@ -1,12 +1,17 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="sandtrack" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="0"/>
<best>
<karts number="1"/>
<requirements energy="20" time="135"/>
</best>
<hard>
<karts number="1"/>
<requirements energy="18" time="167"/>
<requirements energy="18" time="165"/>
</hard>
<medium>
<karts number="1"/>

View File

@ -1,15 +1,20 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="scotland" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="0"/>
<best>
<karts number="7"/>
<requirements position="1" time="140"/>
</best>
<hard>
<karts number="5"/>
<karts number="6"/>
<requirements position="1" time="165"/>
</hard>
<medium>
<karts number="4"/>
<karts number="5"/>
<requirements time="185"/>
</medium>
<easy>

View File

@ -1,18 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="snowmountain" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="60"/>
<requirements trophies="115"/>
<best>
<karts number="10"/>
<requirements position="1" time="120"/>
</best>
<hard>
<karts number="5"/>
<requirements time="145"/>
<karts number="9"/>
<requirements position="2" time="145"/>
</hard>
<medium>
<karts number="4"/>
<karts number="8"/>
<requirements time="187"/>
</medium>
<easy>
<karts number="4"/>
<karts number="7"/>
<requirements time="250"/>
</easy>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="snowtuxpeak" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="60"/>
<requirements trophies="45"/>
<best>
<karts number="8"/>
<requirements position="1" time="120"/>
</best>
<hard>
<karts number="5"/>
<requirements position="1" time="145"/>
<karts number="7"/>
<requirements position="1" time="140"/>
</hard>
<medium>
<karts number="4"/>
<karts number="6"/>
<requirements time="170"/>
</medium>
<easy>
<karts number="4"/>
<requirements time="195"/>
<karts number="5"/>
<requirements time="210"/>
</easy>
</challenge>

View File

@ -1,19 +0,0 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="stk_enterprise" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="110"/>
<hard>
<karts number="6"/>
<requirements position="2"/>
</hard>
<medium>
<karts number="6"/>
<requirements position="2"/>
</medium>
<easy>
<karts number="5"/>
<requirements position="2"/>
</easy>
</challenge>

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<challenge version="3">
<unlock_list list="false"/>
<track id="stk_enterprise" laps="3"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="105"/>
<best>
<karts number="9"/>
<requirements position="1"/>
</best>
<hard>
<karts number="8"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="7"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="6"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<challenge version="3">
<unlock_list list="true"/>
<!-- This is the (rounded) point equivalent of finishing all challenges
in easy, except the final challenge -->
<requirements trophies="190"/>
<unlock kart="amanda"/>
</challenge>

View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<challenge version="3">
<unlock_list list="true"/>
<!-- This is the point equivalent of finishing the
story mode with 8 supertux challenges and the rest in gold -->
<requirements trophies="280"/>
<unlock kart="sara_the_wizard"/>
</challenge>

View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<challenge version="3">
<unlock_list list="true"/>
<!-- This is the point equivalent of finishing the
story mode with all gold except 14 silver challenges -->
<requirements trophies="250"/>
<unlock difficulty="difficulty_best"/>
</challenge>

View File

@ -1,19 +1,24 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="volcano_island" laps="2"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="15"/>
<best>
<karts number="8"/>
<requirements position="1"/>
</best>
<hard>
<karts number="5"/>
<karts number="7"/>
<requirements position="1"/>
</hard>
<medium>
<karts number="4"/>
<karts number="6"/>
<requirements position="1"/>
</medium>
<easy>
<karts number="4"/>
<karts number="5"/>
<requirements position="1"/>
</easy>
</challenge>

View File

@ -1,12 +1,17 @@
<?xml version="1.0"?>
<challenge version="2">
<challenge version="3">
<unlock_list list="false"/>
<track id="xr591" laps="2"/>
<mode major="single" minor="quickrace"/>
<requirements trophies="135"/>
<best>
<karts number="1"/>
<requirements energy="20" time="100"/>
</best>
<hard>
<karts number="1"/>
<requirements energy="18" time="120"/>
<requirements energy="18" time="115"/>
</hard>
<medium>
<karts number="1"/>
@ -17,5 +22,3 @@
<requirements energy="12" time="180"/>
</easy>
</challenge>

View File

@ -1,9 +1,14 @@
<?xml version="1.0"?>
<challenge version="2">
<track id="zengarden" laps="3"/>
<challenge version="3">
<unlock_list list="false"/>
<track id="zengarden" laps="4"/>
<mode major="single" minor="timetrial"/>
<requirements trophies="45"/>
<requirements trophies="35"/>
<best>
<karts number="3"/>
<requirements position="1"/>
</best>
<hard>
<karts number="2"/>
<requirements position="1"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<particles emitter="box" box_x="0.05" box_y="0.05" box_z="0.60">
<particles emitter="box" box_x="0.05" box_y="0.05" box_z="0.05">
<spreading angle="2" />

29
data/gfx/skid0.xml Normal file
View File

@ -0,0 +1,29 @@
<?xml version="1.0"?>
<particles emitter="sphere" radius="0.03">
<spreading angle="25" />
<velocity x="0.0"
y="0.008"
z="-0.015" />
<material file="skid-particle1.png" />
<!-- Amount of particles emitted per second. The minimum rate
is used to show that the skidding bonus is now available,
the maximum is used when the skid bonus is applied to the kart -->
<rate min="200"
max="200" />
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
<lifetime min="60"
max="70" />
<!-- Size of the particles -->
<size min="0.20"
max="0.20" />
<color min="253 253 253"
max="254 254 254" />
</particles>

View File

@ -1,29 +1,29 @@
<?xml version="1.0"?>
<particles emitter="box" box_x="0.023" box_y="0.023" box_z="-0.5">
<particles emitter="sphere" radius="0.03">
<spreading angle="5" />
<spreading angle="15" />
<velocity x="0.0"
y="0.0"
z="-0.003" />
y="0.008"
z="-0.015" />
<material file="skid-particle1.png" />
<!-- Amount of particles emitted per second. The minimum rate
is used to show that the skidding bonus is now available,
the maximum is used when the skid bonus is applied to the kart -->
<rate min="1400"
max="1500" />
<rate min="2000"
max="2000" />
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
<lifetime min="15"
max="25" />
<lifetime min="60"
max="70" />
<!-- Size of the particles -->
<size min="0.35"
max="0.45" />
<size min="0.18"
max="0.18" />
<color min="255 255 255"
<color min="254 254 254"
max="255 255 255" />
</particles>

View File

@ -1,29 +1,29 @@
<?xml version="1.0"?>
<particles emitter="box" box_x="0.023" box_y="0.023" box_z="-0.5">
<particles emitter="sphere" radius="0.03">
<spreading angle="5" />
<spreading angle="15" />
<velocity x="0.0"
y="0.0"
z="-0.003" />
y="0.008"
z="-0.015" />
<material file="skid-particle2.png" />
<!-- Amount of particles emitted per second. The minimum rate
is used to show that the skidding bonus is now available,
the maximum is used when the skid bonus is applied to the kart -->
<rate min="1400"
max="1500" />
<rate min="2500"
max="2500" />
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
<lifetime min="15"
max="25" />
<lifetime min="65"
max="75" />
<!-- Size of the particles -->
<size min="0.35"
max="0.45" />
<size min="0.20"
max="0.20" />
<color min="255 255 255"
max="255 255 255" />
<color min="255 0 255"
max="255 100 255" />
</particles>

View File

@ -3,7 +3,7 @@
<track id="sandtrack" laps="3" reverse="false" />
<track id="cornfield_crossing" laps="3" reverse="false" />
<track id="olivermath" laps="4" reverse="false" />
<track id="olivermath" laps="5" reverse="false" />
<track id="abyss" laps="3" reverse="false" />
<track id="scotland" laps="3" reverse="false" />

View File

@ -1,10 +1,10 @@
<supertuxkart_grand_prix name="Off the beaten track">
<supertuxkart_grand_prix name="Off the Beaten Track">
<track id="cocoa_temple" laps="3" reverse="false" />
<track id="snowmountain" laps="3" reverse="false" />
<track id="hacienda" laps="3" reverse="false" />
<track id="zengarden" laps="4" reverse="false" />
<track id="volcano_island" laps="2" reverse="false" />
<track id="snowtuxpeak" laps="3" reverse="false" />
</supertuxkart_grand_prix>

View File

@ -1,11 +1,10 @@
<supertuxkart_grand_prix name="To the moon and back">
<supertuxkart_grand_prix name="To the Moon and Back">
<track id="gran_paradiso_island" laps="3" reverse="false" />
<track id="greenvalley" laps="2" reverse="false" />
<track id="greenvalley" laps="3" reverse="false" />
<track id="mansion" laps="3" reverse="false" />
<track id="stk_enterprise" laps="3" reverse="false" />
<track id="volcano_island" laps="2" reverse="false" />
<track id="candela_city" laps="3" reverse="false" />
</supertuxkart_grand_prix>

View File

@ -1,11 +1,10 @@
<supertuxkart_grand_prix name="At World's End">
<track id="fortmagma" laps="3" reverse="false" />
<track id="minigolf" laps="3" reverse="false" />
<track id="lighthouse" laps="4" reverse="false" />
<track id="snowmountain" laps="3" reverse="false" />
<track id="minigolf" laps="4" reverse="false" />
<track id="xr591" laps="3" reverse="false" />
<track id="mines" laps="3" reverse="false" />
<track id="lighthouse" laps="4" reverse="false" />
</supertuxkart_grand_prix>

View File

@ -33,6 +33,7 @@
<card contains="ATI" os="windows" version="<=3.1.8787" disable="ForceLegacyDevice"/>
<card os="android" disable="TextureFormatBGRA8888"/>
<card os="android" disable="ColorBufferFloat"/>
<card os="android" disable="TextureCompressionS3TC"/>
<card contains="Adreno" os="android" version="<=19" disable="VertexIdWorking"/>
<card contains="Android Emulator" os="android" disable="ForceLegacyDevice"/>
<card contains="Android Emulator" os="android" disable="NpotTextures"/>

View File

@ -38,6 +38,8 @@ power.png by Auria, based on https://openclipart.org/detail/193925/check-engine
crown.png by glitch, from https://openclipart.org/detail/210257/misc-game-crown, released under public domain
ghost_plus.png by Alayan, based on https://openclipart.org/detail/17847/cartoon-ghost by lemmling, released under CC-O
====
Glass Skin by Auria, under CC-BY-SA 3+

BIN
data/gui/cup_platinum.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -9,7 +9,7 @@
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="pixelshaders"/>
<spacer width="10" height="10"/>
<label text="Pixel Shaders" I18N="Video settings"/>
<label text="Pixel shaders" I18N="Video settings"/>
</div>
<spacer height="4" width="10" />
@ -61,7 +61,7 @@
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="ssao"/>
<spacer width="10" height="10"/>
<label text="Ambient Occlusion" I18N="Video settings"/>
<label text="Ambient occlusion" I18N="Video settings"/>
</div>
<spacer height="4" width="10" />
@ -81,7 +81,7 @@
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="glow"/>
<spacer width="10" height="10"/>
<label text="Glow (outlines)" I18N="Video settings"/>
<label text="Glow (Outlines)" I18N="Video settings"/>
</div>
<spacer height="4" width="10" />
@ -119,7 +119,7 @@
<div layout="horizontal-row" proportion="1" height="fit">
<checkbox id="animated_characters"/>
<spacer width="10" height="10"/>
<label text="Animated Characters" I18N="Video settings"/>
<label text="Animated characters" I18N="Video settings"/>
</div>
<spacer height="4" width="10" />
@ -134,9 +134,9 @@
<spacer height="20" width="10" />
<div layout="horizontal-row" width="100%" proportion="1">
<label text="Particles Effects" I18N="Video settings" width="40%"/>
<label text="Particle effects" I18N="Video settings" width="40%"/>
<spacer width="10" height="10"/>
<gauge id="particles_effects" min_value="0" max_value="2" width="50%" />
<gauge id="particles_effects" min_value="1" max_value="2" width="50%" />
</div>
<spacer height="4" width="10" />

BIN
data/gui/ghost_plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,15 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="5%" y="5%" width="90%" height="90%" layout="vertical-row">
<div x="5%" y="0%" width="90%" proportion="6" layout="horizontal-row">
<div width="40%" height="100%" layout="vertical-row">
<icon id="icon" align="center" width="100%" icon="gui/loading.png" />
<div y="2%" width="100%" height="96%" layout="vertical-row">
<div width="100%" height="50%" proportion="6" layout="horizontal-row">
<div width="25%" height="100%" layout="vertical-row">
<icon-button proportion="1" width="100%" height="100%" id="track_screenshot" custom_ratio="1.33333"/>
</div>
<div width="60%" height="50%" layout="vertical-row">
<label id="name" width="100%" text_align="left"/>
<div width="75%" height="100%" layout="vertical-row">
<div width="100%" height="25%" layout="vertical-row" >
<label id="name" width="100%" text_align="center"/>
</div>
<!-- This is filled in programmatically -->
<box width="98%" height="75%" align="center" layout="vertical-row" padding="1">
<list id="current_replay_info" x="0" y="0" width="100%" height="100%"/>
</box>
</div>
</div>
<div width="90%" align="center" layout="vertical-row" height="fit">
<div width="100%" height="fit" layout="horizontal-row" >
<checkbox width="fit" id="record-race" I18N="Ghost replay info action" text_align="left"/>
@ -21,13 +29,21 @@
<spacer width="10"/>
<label proportion="1" id="watch-only-text" height="100%" text_align="left" I18N="Ghost replay info action" text="Watch replay only"/>
</div>
<div width="100%" height="fit" layout="horizontal-row" >
<checkbox width="fit" id="compare-ghost" I18N="Ghost replay info action" text_align="left"/>
<spacer width="10"/>
<label proportion="1" id="compare-ghost-text" height="100%" text_align="left" I18N="Ghost replay info action" text="Compare to another ghost"/>
</div>
</div>
<div width="80%" proportion="5" align="center">
<div width="90%" proportion="5" align="center">
<buttonbar id="actions" x="0" y="0" height="100%" width="100%" align="center">
<icon-button id="start" width="128" height="128"
icon="gui/green_check.png"
I18N="Ghost replay info screen action" text="Start Race" />
<icon-button id="add-ghost-to-compare" width="128" height="128"
icon="gui/ghost_plus.png"
I18N="Ghost replay info screen action" text="Compare ghost" />
<icon-button id="remove" width="128" height="128"
icon="gui/remove.png"
I18N="Ghost replay info action" text="Remove" />

View File

@ -8,19 +8,50 @@
<icon-button id="reload" height="90%" icon="gui/restart.png"/>
</div>
<!-- This is filled in programmatically -->
<box proportion="1" width="98%" align="center" layout="vertical-row" padding="6">
<list id="replay_list" x="0" y="0" width="100%" height="100%"/>
</box>
<div width="99%" align="center" layout="vertical-row" height="fit">
<div width="100%" height="fit" layout="horizontal-row" >
<tabs id="race_mode" height="6%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_time_trial" width="128" height="128" icon="gui/mode_tt.png"
I18N="In the ghost replay selection screen" text="Time trial"/>
<icon-button id="tab_egg_hunt" width="128" height="128" icon="gui/mode_easter.png"
I18N="In the ghost replay selection screen" text="Egg hunt"/>
</tabs>
<spacer width="100%" height="1.5%" />
<div width="99%" align="center" layout="horizontal-row" height="fit">
<div proportion="1" height="fit" layout="horizontal-row" >
<checkbox width="fit" id="best_times_toggle" text_align="left"/>
<spacer width="2%" height="fit"/>
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show the best times"/>
</div>
<div proportion="1" height="fit" layout="horizontal-row" >
<checkbox width="fit" id="compare_toggle" text_align="left"/>
<spacer width="2%" height="fit"/>
<label height="100%" id="compare-toggle-text" text_align="left" I18N="In the ghost replay selection screen" text="Compare replay"/>
</div>
</div>
<div width="99%" align="center" layout="horizontal-row" height="fit">
<div proportion="2" height="fit" layout="horizontal-row" >
<checkbox width="fit" id="replay_difficulty_toggle" text_align="left"/>
<spacer width="10"/>
<label proportion="1" height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current difficulty"/>
<spacer width="1%" height="fit"/>
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current difficulty"/>
</div>
</div>
<spacer width="100%" height="1%" />
<button x="1%" id="record-ghost" I18N="In the ghost replay selection screen" text="Record ghost replay"/>
<div width="99%" align="center" layout="horizontal-row" height="fit">
<div proportion="1" height="fit" layout="horizontal-row" >
<checkbox width="fit" id="replay_version_toggle" text_align="left"/>
<spacer width="1%" height="fit" />
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current version"/>
</div>
</div>
<button x="1%" id="record-ghost" I18N="In the ghost replay selection screen" text="Record a ghost replay"/>
</div>
</stkgui>

BIN
data/gui/mystery_unlock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -14,13 +14,17 @@
</box>
</div>
</div>
<spacer height="10"/>
<spacer height="20"/>
<div width="100%" proportion="1" layout="horizontal-row">
<spacer width="20" height="20"/>
<box proportion="2" height="100%" layout="vertical-row">
<textbox id="chat" width="100%" height="30%"/>
<spacer height="20"/>
<button id="send" height="30%" width="fit" I18N="In the network lobby" text="Send" />
<spacer height="10"/>
<div width="100%" height="30%" proportion="1" layout="horizontal-row">
<button id="send" width="10%" height="fit" I18N="In the network lobby" text="Send" />
<spacer width="10"/>
<label id="timeout-message" width="80%" height="fit"/>
</div>
</box>
<spacer width="40"/>
<buttonbar id="actions" proportion="1" width="75%" height="75%">

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="2%" width="100%" height="96%" layout="vertical-row">
<header id="title" width="96%" height="fit" text_align="center"
word_wrap="true" I18N="In player rankings dialog"
text="Top 10 players"/>
<box x="2%" width="90%" height="60%" align="center" layout="vertical-row"
padding="6">
<list id="top-ten" x="0" y="0" width="100%" height="100%"/>
</box>
<label id="cur-rank" proportion="1" width="90%" align="center"
text_align="center" word_wrap="true" text=""/>
<buttonbar id="options" width="90%" height="10%" align="center">
<icon-button id="ok" width="16" height="16"
icon="gui/green_check.png" text="OK"
label_location="bottom"/>
<icon-button id="refresh" width="16" height="16"
icon="gui/restart.png"
text="Refresh" label_location="bottom"/>
</buttonbar>
<spacer width="20" height="2%" />
</div>
</stkgui>

View File

@ -18,5 +18,6 @@
<box proportion="1" width="100%" layout="vertical-row" padding="6">
<list id="achievements_list" x="0" y="0" width="100%" height="100%"/>
</box>
<button id="rankings" I18N="In the achievements screen" text="Player rankings"/>
</div>
</stkgui>

View File

@ -21,7 +21,7 @@
<label id="novice_label" proportion="1" height="100%"/>
</div>
<spacer height="8%" width="1"/>
<spacer height="6%" width="1"/>
<div width="100%" proportion="1" layout="horizontal-row">
<icon-button id="intermediate" icon="gui/difficulty_medium.png"
@ -30,7 +30,7 @@
<label id="intermediate_label" proportion="1" height="100%"/>
</div>
<spacer height="8%" width="1"/>
<spacer height="6%" width="1"/>
<div width="100%" proportion="1" layout="horizontal-row">
<icon-button id="expert" icon="gui/difficulty_hard.png"
@ -39,7 +39,16 @@
<label id="difficult_label" proportion="1" height="100%"/>
</div>
<spacer height="8%" width="1"/>
<spacer height="6%" width="1"/>
<div width="100%" proportion="1" layout="horizontal-row">
<icon-button id="supertux" icon="gui/difficulty_best.png"
I18N="Difficulty" text="SuperTux" height="100%"/>
<spacer width="5%" height="1"/>
<label id="supertux_label" proportion="1" height="100%"/>
</div>
<spacer height="2%" width="1"/>
</div>
</stkgui>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="5%" y="5%" width="90%" height="90%" layout="vertical-row" >
<header id="title" width="100%" text="Race Setup" align="center" text_align="center" />
<spacer height="2%" width="1"/>
<div width="100%" layout="horizontal-row" height="fit">
<label id="race_type" text="Type:" I18N="Type of race, in a challenge"/>
<spacer width="5" height="1"/>
<label id="race_type_val" proportion="1"/>
</div>
<spacer height="2%" width="1"/>
<div width="100%" proportion="1" layout="horizontal-row">
<icon-button id="novice" icon="gui/difficulty_easy.png"
I18N="Difficulty" text="Novice" height="100%"/>
<spacer width="5%" height="1"/>
<label id="novice_label" proportion="1" height="100%"/>
</div>
<spacer height="8%" width="1"/>
<div width="100%" proportion="1" layout="horizontal-row">
<icon-button id="intermediate" icon="gui/difficulty_medium.png"
I18N="Difficulty" text="Intermediate" height="100%"/>
<spacer width="5%" height="1"/>
<label id="intermediate_label" proportion="1" height="100%"/>
</div>
<spacer height="8%" width="1"/>
<div width="100%" proportion="1" layout="horizontal-row">
<icon-button id="expert" icon="gui/difficulty_hard.png"
I18N="Difficulty" text="Expert" height="100%"/>
<spacer width="5%" height="1"/>
<label id="difficult_label" proportion="1" height="100%"/>
</div>
<spacer height="8%" width="1"/>
</div>
</stkgui>

View File

@ -41,7 +41,7 @@
<div id="vote" x="63%" y="1%" width="37%" height="96%" layout="vertical-row">
<div width="95%" proportion="2" layout="horizontal-row">
<box proportion="2" height="100%" layout="vertical-row">
<label id="vote-text" word_wrap="true" id="text" proportion="3" width="100%" height="100%" text_valign="top"/>
<label id="vote-text" word_wrap="true" proportion="3" width="100%" height="100%" text_valign="top"/>
</box>
</div>
</div>

View File

@ -403,17 +403,17 @@
<player-characteristics>
<characteristic name="normal" />
<characteristic name="handicap">
<engine brake-factor="*0.8" brake-time-increase="*0.85" max-speed-reverse-ratio="*0.8" />
<bubblegum duration="*1.5" speed-fraction="*1.5" torque="*1.5" />
<zipper duration="*0.8" force="*0.8" speed-gain="*0.8" max-speed-increase="*0.8" />
<swatter duration="*0.8" squash-duration="*1.5" squash-slowdown="*1.8" />
<engine power="*0.9" max-speed="*0.9" brake-factor="*0.8" brake-time-increase="*0.85" max-speed-reverse-ratio="*0.8" />
<skid time-till-bonus="*1.2 1.0" bonus-speed="*0.9 0.8" bonus-force="*0.9 0.9" />
<bubblegum duration="*1.5" torque="*1.5" />
<zipper force="*0.8" speed-gain="*0.8" max-speed-increase="*0.8" />
<swatter duration="*0.8" squash-duration="*1.3" />
<plunger band-max-length="*0.8" band-speed-increase="*0.8" in-face-time="*1.3" />
<startup time="*0.8 0.8" boost="*0.8 0.8" />
<rescue duration="*1.5" />
<explosion duration="*1.3" invulnerability-time="*0.7" />
<nitro engine-force="*0.8" consumption="*1.1" max-speed-increase="*0.9" max="*0.8" />
<slipstream length="*0.8" width="*0.8" collect-time="*1.5" use-time="*0.8"
add-power="*0.8" min-speed="*0.8" max-speed-increase="*0.9" duration="*0.8" />
<nitro engine-force="*0.8" max-speed-increase="*0.9" max="*0.8" />
<slipstream min-collect-time="*1.2" add-power="*0.9"
max-speed-increase="*0.9" duration-factor="*0.9" />
</characteristic>
</player-characteristics>
</characteristics>

File diff suppressed because it is too large Load Diff

View File

@ -113,14 +113,25 @@
<!-- Replay related values, mostly concerned with saving less data
and using interpolation instead.
max-time: Maximum race time that can be saved in a replay/history file.
delta-t Minumum time between saving consecutive transform events.
delta-pos If the interpolated position is within this delta, a
transform event is not generated.
delta-angle If the interpolated angle is within this delta,
a transform event is not generated. -->
<replay max-time="600" delta-t="0.05" delta-pos="0.1"
delta-angle="0.5" />
max-frames: Maximum number of transform events that can be saved
in a replay/history file. With normal play, 900 are
enough to store at least one minute, usually more.
delta-t Maximum time between saving consecutive transform events.
The recording will do more transform events when some kart data
changes significantly.
delta-speed If the speed difference exceeds this delta, a
new transform event is generated before maximum time.
delta-steering If the steering angle difference exceeds this delta,
new transform event is generated before maximum time. -->
<replay max-frames="12000" delta-t="0.200" delta-speed="0.6"
delta-steering="0.35" />
<!-- Determines the minimap related values.
size: The size of the minimap (scaled afterwards) 480 = full screen height)
ai-icon: The size of the icons for the AI karts on the minimap.
player-icon: The size of the icons for the player karts. -->
<minimap size="180.0" ai-icon="16.0" player-icon="20.0"/>
<!-- Skidmark data: maximum number of skid marks, and
time for skidmarks to fade out. Maximum number will over
@ -284,10 +295,12 @@
distance ahead, the value for the largest distance is used,
and similarly if the kart is more than the minimum value
behind).
speed-cap: Fraction of maximum speed the kart should drive
at. Used to slow down karts that are ahead of the player.
Note that setting this to a value >1 does NOT increase
the speed the kart can drive at!
first-speed-cap: Fraction of maximum speed the first AI kart
should drive at. Used to slow down karts that are ahead of
the player. Note that setting this to a value >1 does NOT
increase the speed the kart can drive at!
last-speed-cap: same as first-speed-cap, but for last AI kart.
AI karts in-between use an average of it with first-speed-cap.
collect-item-probability: Probability of the AI actually
trying to collect an item (if an item is selected for
collection in the first place).
@ -304,7 +317,8 @@
item-skill="1"
collect-avoid-items="false"
handle-bomb="false"
speed-cap="-10:1.0 -5:0.9 5:0.8 20:0.7 50:0.6"
first-speed-cap="-100:1.0 -50:0.9 0:0.85 100:0.65"
last-speed-cap="-150:0.92 -50:0.75 50:0.6"
max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6"
collect-item-probability="0:0"
@ -322,7 +336,8 @@
item-skill="2"
collect-avoid-items="true"
handle-bomb="false"
speed-cap="10:1.0 50:0.8"
first-speed-cap="20:1.0 60:0.9 100:0.85"
last-speed-cap="-50:0.94 0:0.85 100:0.75"
max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6"
collect-item-probability="-10:1.0 0:0"
@ -340,7 +355,8 @@
item-skill="3"
collect-avoid-items="true"
handle-bomb="true"
speed-cap="20:1.0 50:0.8"
first-speed-cap="50:1.0 150:0.9"
last-speed-cap="0:0.96 80:0.8"
max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6"
collect-item-probability="10:1.0 20:0"
@ -358,7 +374,8 @@
item-skill="4"
collect-avoid-items="true"
handle-bomb="true"
speed-cap="0:1.0"
first-speed-cap="0:1.0"
last-speed-cap="0:1.0"
max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6"
collect-item-probability="0:1.0"

View File

@ -21,11 +21,6 @@ add_library(enet STATIC
win32.c
)
if(MINGW)
if(WIN32)
target_link_libraries(enet wsock32 ws2_32 winmm)
endif()
#if(WIN32)
# find_library(WS2_LIBRARY NAMES "ws2_32" PATHS "C:/Windows/System32")
# target_link_libraries(enet ${WS2_LIBRARY})
#endif()

View File

@ -8,9 +8,6 @@
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
static enet_uint32 timeBase = 0;
int

29
lib/graphics_utils/mipmap/cpusimd.c Normal file → Executable file
View File

@ -45,11 +45,6 @@
#include "cpusimd.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
////
@ -66,7 +61,9 @@ const uint32_t CPU_ALIGN16 simd4uOneInv[4] = { ~1, ~1, ~1, ~1 };
const uint32_t CPU_ALIGN16 simd4uTwo[4] = { 2, 2, 2, 2 };
const uint32_t CPU_ALIGN16 simd4uFour[4] = { 4, 4, 4, 4 };
const float CPU_ALIGN16 simd4fQuarter[4] = { 0.25, 0.25, 0.25, 0.25 };
const float CPU_ALIGN16 simd4fPi[4] = { M_PI, M_PI, M_PI, M_PI };
// Avoid double to float conversion warnings when using M_PI --> use our own PI
#define PI 3.14159265358979323846f
const float CPU_ALIGN16 simd4fPi[4] = { PI, PI, PI, PI };
const float CPU_ALIGN16 simd4fZeroOneTwoThree[4] = { 0.0, 1.0, 2.0, 3.0 };
const uint32_t CPU_ALIGN16 simd4fAlphaMask[4] = { 0x00000000, 0x00000000, 0x00000000, 0xffffffff };
const float CPU_ALIGN16 simd4f255[4] = { 255.0f, 255.0f, 255.0f, 255.0f };
@ -102,16 +99,16 @@ const float CPU_ALIGN16 simd4f255Inv[4] = { 1.0f/255.0f, 1.0f/255.0f, 1.0f/255.0
(this is the zlib license)
*/
static const float CPU_ALIGN16 simd4f_cephes_FOPI[4] = { 1.27323954473516, 1.27323954473516, 1.27323954473516, 1.27323954473516 };
static const float CPU_ALIGN16 simd4f_cephes_FOPI[4] = { 1.27323954473516f, 1.27323954473516f, 1.27323954473516f, 1.27323954473516f };
static const float CPU_ALIGN16 simd4f_minus_cephes_DP1[4] = { -0.78515625, -0.78515625, -0.78515625, -0.78515625 };
static const float CPU_ALIGN16 simd4f_minus_cephes_DP2[4] = { -2.4187564849853515625e-4, -2.4187564849853515625e-4, -2.4187564849853515625e-4, -2.4187564849853515625e-4 };
static const float CPU_ALIGN16 simd4f_minus_cephes_DP3[4] = { -3.77489497744594108e-8, -3.77489497744594108e-8, -3.77489497744594108e-8, -3.77489497744594108e-8 };
static const float CPU_ALIGN16 simd4f_sincof_p0[4] = { -1.9515295891E-4, -1.9515295891E-4, -1.9515295891E-4, -1.9515295891E-4 };
static const float CPU_ALIGN16 simd4f_sincof_p1[4] = { 8.3321608736E-3, 8.3321608736E-3, 8.3321608736E-3, 8.3321608736E-3 };
static const float CPU_ALIGN16 simd4f_sincof_p2[4] = { -1.6666654611E-1, -1.6666654611E-1, -1.6666654611E-1, -1.6666654611E-1 };
static const float CPU_ALIGN16 simd4f_coscof_p0[4] = { 2.443315711809948E-005, 2.443315711809948E-005, 2.443315711809948E-005, 2.443315711809948E-005 };
static const float CPU_ALIGN16 simd4f_coscof_p1[4] = { -1.388731625493765E-003, -1.388731625493765E-003, -1.388731625493765E-003, -1.388731625493765E-003 };
static const float CPU_ALIGN16 simd4f_coscof_p2[4] = { 4.166664568298827E-002, 4.166664568298827E-002, 4.166664568298827E-002, 4.166664568298827E-002 };
static const float CPU_ALIGN16 simd4f_minus_cephes_DP3[4] = { -3.77489497744594108e-8f, -3.77489497744594108e-8f, -3.77489497744594108e-8f, -3.77489497744594108e-8f };
static const float CPU_ALIGN16 simd4f_sincof_p0[4] = { -1.9515295891E-4f, -1.9515295891E-4f, -1.9515295891E-4f, -1.9515295891E-4f };
static const float CPU_ALIGN16 simd4f_sincof_p1[4] = { 8.3321608736E-3f, 8.3321608736E-3f, 8.3321608736E-3f, 8.3321608736E-3f };
static const float CPU_ALIGN16 simd4f_sincof_p2[4] = { -1.6666654611E-1f, -1.6666654611E-1f, -1.6666654611E-1f, -1.6666654611E-1f };
static const float CPU_ALIGN16 simd4f_coscof_p0[4] = { 2.443315711809948E-005f, 2.443315711809948E-005f, 2.443315711809948E-005f, 2.443315711809948E-005f };
static const float CPU_ALIGN16 simd4f_coscof_p1[4] = { -1.388731625493765E-003f, -1.388731625493765E-003f, -1.388731625493765E-003f, -1.388731625493765E-003f };
static const float CPU_ALIGN16 simd4f_coscof_p2[4] = { 4.166664568298827E-002f, 4.166664568298827E-002f, 4.166664568298827E-002f, 4.166664568298827E-002f };
__m128 simd4f_sin_ps( __m128 x )
{
@ -516,8 +513,8 @@ static inline CC_ALWAYSINLINE __m128 simd4f_fastpow_ps( __m128 arg, uint32_t exp
__m128 ret = arg;
float corrfactor, powfactor;
/* Apply a constant pre-correction factor. */
corrfactor = exp2( 127.0 * expden / expnum - 127.0 ) * pow( 1.0 * coeffnum / coeffden, 1.0 * expden / expnum );
powfactor = 1.0 * expnum / expden;
corrfactor = (float)(exp2( 127.0 * expden / expnum - 127.0 ) * pow( 1.0 * coeffnum / coeffden, 1.0 * expden / expnum ));
powfactor = 1.0f * expnum / expden;
ret = _mm_mul_ps( ret, _mm_set1_ps( corrfactor ) );
/* Reinterpret arg as integer to obtain logarithm. */
ret = _mm_cvtepi32_ps( _mm_castps_si128( ret ) );

View File

@ -199,7 +199,24 @@ namespace irr
IRR_KEY_BUTTON_SELECT = 0x111,
IRR_KEY_BUTTON_MODE = 0x112,
IRR_KEY_CODES_COUNT = 0x113 // this is not a key, but the amount of keycodes there are.
// For Azerty layout
IRR_KEY_AMPERSAND = 0x113,
IRR_KEY_EACUTE = 0x114,
IRR_KEY_QUOTEDBL = 0x115,
IRR_KEY_PARENLEFT = 0x116,
IRR_KEY_EGRAVE = 0x117,
IRR_KEY_CCEDILLA = 0x118,
IRR_KEY_AGRAVE = 0x119,
IRR_KEY_PARENRIGHT = 0x120,
IRR_KEY_UGRAVE = 0x121,
IRR_KEY_COLON = 0x122,
IRR_KEY_DOLLAR = 0x123,
IRR_KEY_EXCLAM = 0x124,
IRR_KEY_TWOSUPERIOR = 0x125,
IRR_KEY_MU = 0x126,
IRR_KEY_SECTION = 0x127,
IRR_KEY_CODES_COUNT = 0x128 // this is not a key, but the amount of keycodes there are.
};
} // end namespace irr

View File

@ -13,7 +13,7 @@ namespace gui
//You can add more characters if needed
//For full list please visit http://webapp.docx4java.org/OnlineDemo/ecma376/WordML/kinsoku.html
bool UtfNoStarting (wchar_t c)
inline bool UtfNoStarting (wchar_t c)
{
switch (c)
{
@ -66,7 +66,7 @@ bool UtfNoStarting (wchar_t c)
}
}
bool UtfNoEnding (wchar_t c)
inline bool UtfNoEnding (wchar_t c)
{
switch (c)
{
@ -99,7 +99,7 @@ bool UtfNoEnding (wchar_t c)
//Helper function
bool breakable (wchar_t c)
inline bool breakable (wchar_t c)
{
if ((c > 12287 && c < 40960) || //Common CJK words
(c > 44031 && c < 55204) || //Hangul

View File

@ -105,7 +105,8 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param)
Width(param.WindowSize.Width), Height(param.WindowSize.Height),
WindowHasFocus(false), WindowMinimized(false),
UseXVidMode(false), UseXRandR(false), UseGLXWindow(false),
ExternalWindow(false), AutorepeatSupport(0)
ExternalWindow(false), AutorepeatSupport(0), SupportsNetWM(false),
NeedsGrabPointer(false)
{
#ifdef _DEBUG
setDebugName("CIrrDeviceLinux");
@ -478,6 +479,19 @@ bool CIrrDeviceLinux::changeResolution()
if (s == Success)
UseXRandR = true;
if (UseXRandR && SupportsNetWM)
{
XRRPanning* panning = XRRGetPanning(display, res, output->crtc);
if ((panning->width != Width && panning->width != 0) ||
(panning->height != Height && panning->height != 0))
{
NeedsGrabPointer = true;
}
XRRFreePanning(panning);
}
XRRFreeCrtcInfo(crtc);
XRRFreeOutputInfo(output);
XRRFreeScreenResources(res);
@ -614,6 +628,40 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig, boo
#endif
#endif
void CIrrDeviceLinux::grabPointer(bool grab)
{
#ifdef _IRR_COMPILE_WITH_X11_
if (grab)
{
int result = 0;
for (int i = 0; i < 500; i++)
{
const unsigned int mask = ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | FocusChangeMask;
int result = XGrabPointer(display, window, True, mask,
GrabModeAsync, GrabModeAsync,
window, None, CurrentTime);
if (result == GrabSuccess)
break;
usleep(1000);
}
if (result != GrabSuccess)
{
os::Printer::log("Couldn't grab pointer.", ELL_WARNING);
}
}
else
{
XUngrabPointer(display, CurrentTime);
}
#endif
}
bool CIrrDeviceLinux::createWindow()
{
#ifdef _IRR_COMPILE_WITH_X11_
@ -633,6 +681,24 @@ bool CIrrDeviceLinux::createWindow()
screennr = DefaultScreen(display);
Atom *list;
Atom type;
int form;
unsigned long remain, len;
Atom WMCheck = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", false);
Status s = XGetWindowProperty(display, DefaultRootWindow(display),
WMCheck, 0L, 1L, False, XA_WINDOW,
&type, &form, &len, &remain,
(unsigned char **)&list);
if (s == Success)
{
XFree(list);
SupportsNetWM = (len > 0);
}
changeResolution();
#ifdef _IRR_COMPILE_WITH_OPENGL_
@ -955,29 +1021,9 @@ bool CIrrDeviceLinux::createWindow()
ButtonPressMask | KeyPressMask |
ButtonReleaseMask | KeyReleaseMask;
bool netWM = false;
Atom *list;
Atom type;
int form;
unsigned long remain, len;
Atom WMCheck = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", false);
Status s = XGetWindowProperty(display, DefaultRootWindow(display),
WMCheck, 0L, 1L, False, XA_WINDOW,
&type, &form, &len, &remain,
(unsigned char **)&list);
if (s == Success)
{
XFree(list);
netWM = (len > 0);
}
if (!CreationParams.WindowId)
{
attributes.override_redirect = !netWM && CreationParams.Fullscreen;
attributes.override_redirect = !SupportsNetWM && CreationParams.Fullscreen;
// create new Window
window = XCreateWindow(display,
@ -1010,7 +1056,7 @@ bool CIrrDeviceLinux::createWindow()
bool has_display_size = (Width == display_width && Height == display_height);
if (netWM && (CreationParams.Fullscreen || has_display_size))
if (SupportsNetWM && (CreationParams.Fullscreen || has_display_size))
{
Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true);
Atom WMStateAtom1 = None;
@ -1078,9 +1124,14 @@ bool CIrrDeviceLinux::createWindow()
{
os::Printer::log("Warning! Got timeout when changing window state", ELL_WARNING);
}
if (NeedsGrabPointer)
{
grabPointer(true);
}
}
if (!netWM && CreationParams.Fullscreen)
if (!SupportsNetWM && CreationParams.Fullscreen)
{
XSetInputFocus(display, window, RevertToParent, CurrentTime);
int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
@ -1178,7 +1229,7 @@ bool CIrrDeviceLinux::createWindow()
CreationParams.WindowSize.Width = Width;
CreationParams.WindowSize.Height = Height;
if (netWM == true)
if (SupportsNetWM == true)
{
Atom opaque_region = XInternAtom(display, "_NET_WM_OPAQUE_REGION", true);
@ -1493,7 +1544,7 @@ int CIrrDeviceLinux::getNumlockMask(Display* display)
EKEY_CODE CIrrDeviceLinux::getKeyCode(XEvent &event)
{
EKEY_CODE keyCode = (EKEY_CODE)0;
int keyCode = 0;
SKeyMap mp;
// First check for numpad keys
@ -1515,30 +1566,25 @@ EKEY_CODE CIrrDeviceLinux::getKeyCode(XEvent &event)
const s32 idx = KeyMap.binary_search(mp);
if (idx != -1)
{
keyCode = (EKEY_CODE)KeyMap[idx].Win32Key;
keyCode = KeyMap[idx].Win32Key;
}
if (keyCode == 0)
{
// Any value is better than none, that allows at least using the keys.
// Worst case is that some keys will be identical, still better than _all_
// unknown keys being identical.
if ( !mp.X11Key )
if (mp.X11Key)
{
keyCode = (EKEY_CODE)event.xkey.keycode;
os::Printer::log("No such X11Key, using event keycode", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION);
}
else if (idx == -1)
{
keyCode = (EKEY_CODE)mp.X11Key;
os::Printer::log("EKEY_CODE not found, using orig. X11 keycode", core::stringc(mp.X11Key).c_str(), ELL_INFORMATION);
keyCode = (int)IRR_KEY_CODES_COUNT + mp.X11Key;
}
else
{
keyCode = (EKEY_CODE)mp.X11Key;
os::Printer::log("EKEY_CODE is 0, using orig. X11 keycode", core::stringc(mp.X11Key).c_str(), ELL_INFORMATION);
keyCode = (int)IRR_KEY_CODES_COUNT + event.xkey.keycode;
}
os::Printer::log("EKEY_CODE is 0, fallback keycode", core::stringc(keyCode).c_str(), ELL_INFORMATION);
}
return keyCode;
return (EKEY_CODE)keyCode;
}
#endif
@ -1619,10 +1665,18 @@ bool CIrrDeviceLinux::run()
break;
case FocusIn:
if (NeedsGrabPointer)
{
grabPointer(true);
}
WindowHasFocus=true;
break;
case FocusOut:
if (NeedsGrabPointer)
{
grabPointer(false);
}
WindowHasFocus=false;
break;
@ -2441,16 +2495,16 @@ void CIrrDeviceLinux::createKeyMap()
KeyMap.push_back(SKeyMap(XK_ISO_Level3_Shift, IRR_KEY_RMENU));
KeyMap.push_back(SKeyMap(XK_Menu, IRR_KEY_MENU));
KeyMap.push_back(SKeyMap(XK_space, IRR_KEY_SPACE));
KeyMap.push_back(SKeyMap(XK_exclam, 0)); //?
KeyMap.push_back(SKeyMap(XK_quotedbl, 0)); //?
KeyMap.push_back(SKeyMap(XK_section, 0)); //?
KeyMap.push_back(SKeyMap(XK_exclam, IRR_KEY_EXCLAM));
KeyMap.push_back(SKeyMap(XK_quotedbl, IRR_KEY_QUOTEDBL));
KeyMap.push_back(SKeyMap(XK_section, IRR_KEY_SECTION)); //?
KeyMap.push_back(SKeyMap(XK_numbersign, IRR_KEY_OEM_2));
KeyMap.push_back(SKeyMap(XK_dollar, 0)); //?
KeyMap.push_back(SKeyMap(XK_dollar, IRR_KEY_DOLLAR));
KeyMap.push_back(SKeyMap(XK_percent, 0)); //?
KeyMap.push_back(SKeyMap(XK_ampersand, 0)); //?
KeyMap.push_back(SKeyMap(XK_ampersand, IRR_KEY_AMPERSAND));
KeyMap.push_back(SKeyMap(XK_apostrophe, IRR_KEY_OEM_7));
KeyMap.push_back(SKeyMap(XK_parenleft, 0)); //?
KeyMap.push_back(SKeyMap(XK_parenright, 0)); //?
KeyMap.push_back(SKeyMap(XK_parenleft, IRR_KEY_PARENLEFT));
KeyMap.push_back(SKeyMap(XK_parenright, IRR_KEY_PARENRIGHT));
KeyMap.push_back(SKeyMap(XK_asterisk, 0)); //?
KeyMap.push_back(SKeyMap(XK_plus, IRR_KEY_PLUS)); //?
KeyMap.push_back(SKeyMap(XK_comma, IRR_KEY_COMMA)); //?
@ -2467,14 +2521,14 @@ void CIrrDeviceLinux::createKeyMap()
KeyMap.push_back(SKeyMap(XK_7, IRR_KEY_7));
KeyMap.push_back(SKeyMap(XK_8, IRR_KEY_8));
KeyMap.push_back(SKeyMap(XK_9, IRR_KEY_9));
KeyMap.push_back(SKeyMap(XK_colon, 0)); //?
KeyMap.push_back(SKeyMap(XK_colon, IRR_KEY_COLON));
KeyMap.push_back(SKeyMap(XK_semicolon, IRR_KEY_OEM_1));
KeyMap.push_back(SKeyMap(XK_less, IRR_KEY_OEM_102));
KeyMap.push_back(SKeyMap(XK_equal, IRR_KEY_PLUS));
KeyMap.push_back(SKeyMap(XK_greater, 0)); //?
KeyMap.push_back(SKeyMap(XK_question, 0)); //?
KeyMap.push_back(SKeyMap(XK_at, IRR_KEY_2)); //?
KeyMap.push_back(SKeyMap(XK_mu, 0)); //?
KeyMap.push_back(SKeyMap(XK_mu, IRR_KEY_MU)); //?
KeyMap.push_back(SKeyMap(XK_EuroSign, 0)); //?
KeyMap.push_back(SKeyMap(XK_A, IRR_KEY_A));
KeyMap.push_back(SKeyMap(XK_B, IRR_KEY_B));
@ -2542,6 +2596,12 @@ void CIrrDeviceLinux::createKeyMap()
KeyMap.push_back(SKeyMap(XK_udiaeresis, IRR_KEY_OEM_1));
KeyMap.push_back(SKeyMap(XK_Super_L, IRR_KEY_LWIN));
KeyMap.push_back(SKeyMap(XK_Super_R, IRR_KEY_RWIN));
KeyMap.push_back(SKeyMap(XK_agrave, IRR_KEY_AGRAVE));
KeyMap.push_back(SKeyMap(XK_ccedilla, IRR_KEY_CCEDILLA ));
KeyMap.push_back(SKeyMap(XK_eacute, IRR_KEY_EACUTE));
KeyMap.push_back(SKeyMap(XK_egrave, IRR_KEY_EGRAVE));
KeyMap.push_back(SKeyMap(XK_ugrave, IRR_KEY_UGRAVE));
KeyMap.push_back(SKeyMap(XK_twosuperior, IRR_KEY_TWOSUPERIOR));
KeyMap.sort();
#endif

View File

@ -158,6 +158,7 @@ namespace irr
bool restoreResolution();
bool changeResolution();
void grabPointer(bool grab);
#ifdef _IRR_COMPILE_WITH_X11_
bool createInputContext();
@ -434,6 +435,8 @@ namespace irr
bool UseGLXWindow;
bool ExternalWindow;
int AutorepeatSupport;
bool SupportsNetWM;
bool NeedsGrabPointer;
struct SKeyMap
{

View File

@ -13,7 +13,13 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
OPTION(BUILD_SQUISH_WITH_OPENMP "Build with OpenMP." OFF)
if((${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") OR
(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64"))
OPTION(BUILD_SQUISH_WITH_SSE2 "Build with SSE2." OFF)
else()
OPTION(BUILD_SQUISH_WITH_SSE2 "Build with SSE2." ON)
endif()
OPTION(BUILD_SQUISH_WITH_ALTIVEC "Build with Altivec." OFF)
OPTION(BUILD_SHARED_LIBS "Build shared libraries." OFF)

View File

@ -68,8 +68,8 @@ void Achievement::load(const XMLNode *node)
*/
void Achievement::save(UTFWriter &out)
{
out << L" <achievement id=\"" << m_id << L"\" "
<< L"achieved=\"" << m_achieved << "\"";
out << " <achievement id=\"" << m_id << "\" "
<< "achieved=\"" << m_achieved << "\"";
if (isAchieved())
{
out << "/>\n";

View File

@ -94,14 +94,14 @@ void AchievementsStatus::add(Achievement *achievement)
*/
void AchievementsStatus::save(UTFWriter &out)
{
out << L" <achievements online=\"" << m_online << L"\"> \n";
out << " <achievements online=\"" << m_online << "\"> \n";
std::map<uint32_t, Achievement*>::const_iterator i;
for(i = m_achievements.begin(); i != m_achievements.end(); i++)
{
if (i->second != NULL)
i->second->save(out);
}
out << L" </achievements>\n";
out << " </achievements>\n";
} // save
// ----------------------------------------------------------------------------

View File

@ -43,6 +43,7 @@ ChallengeData::ChallengeData(const std::string& filename)
m_gp_id = "";
m_version = 0;
m_num_trophies = 0;
m_is_unlock_list = false;
m_is_ghost_replay = false;
for (int d=0; d<RaceManager::DIFFICULTY_COUNT; d++)
@ -66,7 +67,7 @@ ChallengeData::ChallengeData(const std::string& filename)
throw std::runtime_error(msg.str());
}
setId(StringUtils::removeExtension(StringUtils::getBasename(filename)));
setChallengeId(StringUtils::removeExtension(StringUtils::getBasename(filename)));
root->get("version", &m_version);
// No need to get the rest of the data if this challenge
@ -79,7 +80,48 @@ ChallengeData::ChallengeData(const std::string& filename)
return;
}
m_is_unlock_list = false;
const XMLNode* unlock_list_node = root->getNode("unlock_list");
if (unlock_list_node != NULL)
{
std::string list;
unlock_list_node->get("list", &list);
m_is_unlock_list = (list=="true");
}
std::vector<XMLNode*> unlocks;
root->getNodes("unlock", unlocks);
for(unsigned int i=0; i<unlocks.size(); i++)
{
std::string s;
if(unlocks[i]->get("kart", &s))
setUnlocks(s, ChallengeData::UNLOCK_KART);
else if(unlocks[i]->get("track", &s))
addUnlockTrackReward(s);
else if(unlocks[i]->get("gp", &s))
setUnlocks(s, ChallengeData::UNLOCK_GP);
else if(unlocks[i]->get("mode", &s))
setUnlocks(s, ChallengeData::UNLOCK_MODE);
else if(unlocks[i]->get("difficulty", &s))
setUnlocks(s, ChallengeData::UNLOCK_DIFFICULTY);
else
{
Log::warn("ChallengeData", "Unknown unlock entry. Must be one of kart, track, gp, mode, difficulty.");
throw std::runtime_error("Unknown unlock entry");
}
}
const XMLNode* requirements_node = root->getNode("requirements");
if (requirements_node == NULL)
{
throw std::runtime_error("Challenge file " + filename +
" has no <requirements> node!");
}
requirements_node->get("trophies", &m_num_trophies);
//Don't check further if this is an unlock list
if(m_is_unlock_list)
return;
const XMLNode* mode_node = root->getNode("mode");
if (mode_node == NULL)
@ -149,27 +191,19 @@ ChallengeData::ChallengeData(const std::string& filename)
}
}
const XMLNode* requirements_node = root->getNode("requirements");
if (requirements_node == NULL)
{
throw std::runtime_error("Challenge file " + filename +
" has no <requirements> node!");
}
requirements_node->get("trophies", &m_num_trophies);
const XMLNode* difficulties[RaceManager::DIFFICULTY_COUNT];
difficulties[0] = root->getNode("easy");
difficulties[1] = root->getNode("medium");
difficulties[2] = root->getNode("hard");
difficulties[3] = root->getNode("best");
// Note that the challenges can only be done in three difficulties
if (difficulties[0] == NULL || difficulties[1] == NULL ||
difficulties[2] == NULL)
difficulties[2] == NULL || difficulties[3] == NULL)
{
error("<easy> or <medium> or <hard>");
error("<easy> or <medium> or <hard> or <best>");
}
for (int d=0; d<=RaceManager::DIFFICULTY_HARD; d++)
for (int d=0; d<=RaceManager::DIFFICULTY_BEST; d++)
{
const XMLNode* karts_node = difficulties[d]->getNode("karts");
if (karts_node == NULL) error("<karts .../>");
@ -229,28 +263,6 @@ ChallengeData::ChallengeData(const std::string& filename)
if (requirements_node->get("energy", &energy)) m_energy[d] = energy;
}
std::vector<XMLNode*> unlocks;
root->getNodes("unlock", unlocks);
for(unsigned int i=0; i<unlocks.size(); i++)
{
std::string s;
if(unlocks[i]->get("kart", &s))
setUnlocks(s, ChallengeData::UNLOCK_KART);
else if(unlocks[i]->get("track", &s))
addUnlockTrackReward(s);
else if(unlocks[i]->get("gp", &s))
setUnlocks(s, ChallengeData::UNLOCK_GP);
else if(unlocks[i]->get("mode", &s))
setUnlocks(s, ChallengeData::UNLOCK_MODE);
else if(unlocks[i]->get("difficulty", &s))
setUnlocks(s, ChallengeData::UNLOCK_DIFFICULTY);
else
{
Log::warn("ChallengeData", "Unknown unlock entry. Must be one of kart, track, gp, mode, difficulty.");
throw std::runtime_error("Unknown unlock entry");
}
}
} // ChallengeData
// ----------------------------------------------------------------------------
@ -486,7 +498,7 @@ bool ChallengeData::isChallengeFulfilled() const
// ----------------------------------------------------------------------------
/** Returns true if this GP challenge is fulfilled.
*/
bool ChallengeData::isGPFulfilled() const
ChallengeData::GPLevel ChallengeData::isGPFulfilled() const
{
int d = race_manager->getDifficulty();
@ -496,14 +508,25 @@ bool ChallengeData::isGPFulfilled() const
race_manager->getMinorMode() != m_minor ||
race_manager->getGrandPrix().getId() != m_gp_id ||
race_manager->getNumberOfKarts() < (unsigned int)m_default_num_karts[d] ||
race_manager->getNumPlayers() > 1) return false;
race_manager->getNumPlayers() > 1) return GP_NONE;
// check if the player came first.
// rank == 0 if first, 1 if second, etc.
const int rank = race_manager->getLocalPlayerGPRank(0);
if (rank != 0) return false;
return true;
// In superior difficulty levels, losing a place means
// getting a cup of the inferior level rather than
// nothing at all
int unlock_level = d - rank;
if (unlock_level == 3)
return GP_BEST;
if (unlock_level == 2)
return GP_HARD;
if (unlock_level == 1)
return GP_MEDIUM;
if (unlock_level == 0)
return GP_EASY;
return GP_NONE;
} // isGPFulfilled
// ----------------------------------------------------------------------------
@ -641,4 +664,3 @@ void ChallengeData::addUnlockKartReward(const std::string &internal_name,
feature.m_user_name = user_name;
m_feature.push_back(feature);
} // addUnlockKartReward

View File

@ -44,6 +44,17 @@ public:
UNLOCK_KART,
UNLOCK_DIFFICULTY
};
/** The level of completion of a GP challenge
*/
enum GPLevel
{
GP_NONE,
GP_EASY,
GP_MEDIUM,
GP_HARD,
GP_BEST
};
// ------------------------------------------------------------------------
class UnlockableFeature
{
@ -95,6 +106,7 @@ private:
std::string m_filename;
/** Version number of the challenge. */
int m_version;
bool m_is_unlock_list;
bool m_is_ghost_replay;
void setUnlocks(const std::string &id,
@ -120,7 +132,7 @@ public:
virtual void check() const;
virtual bool isChallengeFulfilled() const;
virtual bool isGPFulfilled() const;
virtual GPLevel isGPFulfilled() const;
void addUnlockTrackReward(const std::string &track_name);
void addUnlockModeReward(const std::string &internal_mode_name,
const irr::core::stringw &user_mode_name);
@ -142,11 +154,11 @@ public:
// ------------------------------------------------------------------------
/** Returns the id of the challenge. */
const std::string &getId() const { return m_id; }
const std::string &getChallengeId() const { return m_id; }
// ------------------------------------------------------------------------
/** Sets the id of this challenge. */
void setId(const std::string& s) { m_id = s; }
void setChallengeId(const std::string& s) { m_id = s; }
// ------------------------------------------------------------------------
/** Returns the track associated with this challenge. */
@ -185,6 +197,9 @@ public:
/** Returns if this challenge is using ghost replay. */
bool isGhostReplay() const { return m_is_ghost_replay; }
// ------------------------------------------------------------------------
/** Returns if this challenge is an unlock list. */
bool isUnlockList() const { return m_is_unlock_list; }
// ------------------------------------------------------------------------
/** Returns the challenge mode of this challenge. */
ChallengeModeType getMode() const { return m_mode; }
// ------------------------------------------------------------------------
@ -196,9 +211,9 @@ public:
const irr::core::stringw getChallengeDescription() const;
// ------------------------------------------------------------------------
/** Returns the minimum position the player must have in order to win.
/** Returns the maximum position the player must have in order to win.
*/
int getPosition(RaceManager::Difficulty difficulty) const
int getMaxPosition(RaceManager::Difficulty difficulty) const
{
return m_position[difficulty];
} // getPosition

View File

@ -35,18 +35,19 @@
*/
void ChallengeStatus::load(const XMLNode* challenges_node)
{
const XMLNode* node = challenges_node->getNode( m_data->getId() );
const XMLNode* node = challenges_node->getNode( m_data->getChallengeId() );
if(node == NULL)
{
Log::info("ChallengeStatus", "Couldn't find node <%s> in challenge list."
"(If this is the first time you play this is normal)\n",
m_data->getId().c_str());
m_data->getChallengeId().c_str());
return;
}
m_state[0] = CH_INACTIVE;
m_state[1] = CH_INACTIVE;
m_state[2] = CH_INACTIVE;
m_state[3] = CH_INACTIVE;
std::string solved;
if (node->get("solved", &solved))
@ -64,6 +65,13 @@ void ChallengeStatus::load(const XMLNode* challenges_node)
m_state[1] = CH_SOLVED;
m_state[2] = CH_SOLVED;
}
else if (solved == "best")
{
m_state[0] = CH_SOLVED;
m_state[1] = CH_SOLVED;
m_state[2] = CH_SOLVED;
m_state[3] = CH_SOLVED;
}
} // if has 'solved' attribute
} // load
@ -78,19 +86,33 @@ void ChallengeStatus::setSolved(RaceManager::Difficulty d)
{
m_state[curr] = CH_SOLVED;
}
}
} // setSolved
// ------------------------------------------------------------------------
bool ChallengeStatus::isUnlockList()
{
return m_data->isUnlockList();
} // isUnlockList
// ------------------------------------------------------------------------
bool ChallengeStatus::isGrandPrix()
{
return m_data->isGrandPrix();
} // isUnlockList
//-----------------------------------------------------------------------------
void ChallengeStatus::save(UTFWriter& writer)
{
writer << L" <" << m_data->getId();
if (isSolved(RaceManager::DIFFICULTY_HARD))
writer << L" solved=\"hard\"/>\n";
writer << " <" << m_data->getChallengeId();
if (isSolved(RaceManager::DIFFICULTY_BEST))
writer << " solved=\"best\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_HARD))
writer << " solved=\"hard\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_MEDIUM))
writer << L" solved=\"medium\"/>\n";
writer << " solved=\"medium\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_EASY))
writer << L" solved=\"easy\"/>\n";
writer << " solved=\"easy\"/>\n";
else
writer << L" solved=\"none\"/>\n";
writer << " solved=\"none\"/>\n";
} // save

View File

@ -57,6 +57,7 @@ private:
enum {CH_INACTIVE, // challenge not yet possible
CH_ACTIVE, // challenge possible, but not yet solved
CH_SOLVED} // challenge was solved
m_state[RaceManager::DIFFICULTY_COUNT];
/** Pointer to the original challenge data. */
@ -69,6 +70,7 @@ public:
m_state[RaceManager::DIFFICULTY_EASY] = CH_INACTIVE;
m_state[RaceManager::DIFFICULTY_MEDIUM] = CH_INACTIVE;
m_state[RaceManager::DIFFICULTY_HARD] = CH_INACTIVE;
m_state[RaceManager::DIFFICULTY_BEST] = CH_INACTIVE;
}
virtual ~ChallengeStatus() {};
void load(const XMLNode* config);
@ -88,7 +90,7 @@ public:
bool isSolvedAtAnyDifficulty() const
{
return m_state[0]==CH_SOLVED || m_state[1]==CH_SOLVED ||
m_state[2]==CH_SOLVED;
m_state[2]==CH_SOLVED || m_state[3]==CH_SOLVED;
} // isSolvedAtAnyDifficulty
// ------------------------------------------------------------------------
/** True if this challenge is active at the given difficulty.
@ -105,6 +107,13 @@ public:
m_state[d] = CH_ACTIVE;
} // setActive
// ------------------------------------------------------------------------
/** Returns if this challenge is only an unlock list */
bool isUnlockList();
// ------------------------------------------------------------------------
/** Returns if this challenge is a grand prix */
bool isGrandPrix();
// ------------------------------------------------------------------------
/** Returns a pointer to the actual Challenge data.
*/
const ChallengeData* getData() const { return m_data; }

View File

@ -31,10 +31,12 @@
StoryModeStatus::StoryModeStatus(const XMLNode *node)
{
m_points = 0;
m_next_unlock_points = 0;
m_first_time = true;
m_easy_challenges = 0;
m_medium_challenges = 0;
m_hard_challenges = 0;
m_best_challenges = 0;
m_current_challenge = NULL;
// If there is saved data, load it
@ -62,7 +64,7 @@ StoryModeStatus::~StoryModeStatus()
*/
void StoryModeStatus::addStatus(ChallengeStatus *cs)
{
m_challenges_state[cs->getData()->getId()] = cs;
m_challenges_state[cs->getData()->getChallengeId()] = cs;
} // addStatus
//-----------------------------------------------------------------------------
@ -78,9 +80,11 @@ bool StoryModeStatus::isLocked(const std::string& feature)
void StoryModeStatus::computeActive()
{
m_points = 0;
m_next_unlock_points = 0;
m_easy_challenges = 0;
m_medium_challenges = 0;
m_hard_challenges = 0;
m_best_challenges = 0;
m_locked_features.clear(); // start afresh
@ -111,20 +115,32 @@ void StoryModeStatus::computeActive()
unlockFeature(i->second, RaceManager::DIFFICULTY_HARD,
/*save*/ false);
}
if (i->second->isSolved(RaceManager::DIFFICULTY_HARD))
if (i->second->isSolved(RaceManager::DIFFICULTY_BEST))
{
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD];
unlockFeature(i->second, RaceManager::DIFFICULTY_BEST,
/*save*/ false);
}
int gp_factor = i->second->isGrandPrix() ? GP_FACTOR : 1;
if (i->second->isSolved(RaceManager::DIFFICULTY_BEST) && !i->second->isUnlockList())
{
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_BEST]*gp_factor;
m_best_challenges++;
}
else if (i->second->isSolved(RaceManager::DIFFICULTY_HARD) && !i->second->isUnlockList())
{
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]*gp_factor;
m_hard_challenges++;
}
else if (i->second->isSolved(RaceManager::DIFFICULTY_MEDIUM))
else if (i->second->isSolved(RaceManager::DIFFICULTY_MEDIUM) && !i->second->isUnlockList())
{
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM];
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM]*gp_factor;
m_medium_challenges++;
}
else if (i->second->isSolved(RaceManager::DIFFICULTY_EASY))
else if (i->second->isSolved(RaceManager::DIFFICULTY_EASY) && !i->second->isUnlockList())
{
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY];
m_points += CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY]*gp_factor;
m_easy_challenges++;
}
}
@ -135,29 +151,40 @@ void StoryModeStatus::computeActive()
lockFeature(i->second);
}
if (i->second->isSolved(RaceManager::DIFFICULTY_HARD))
if (i->second->isSolved(RaceManager::DIFFICULTY_BEST))
{
// challenge beaten at hardest, nothing more to do here
continue;
}
else if (i->second->isSolved(RaceManager::DIFFICULTY_HARD))
{
i->second->setActive(RaceManager::DIFFICULTY_BEST);
}
else if (i->second->isSolved(RaceManager::DIFFICULTY_MEDIUM))
{
i->second->setActive(RaceManager::DIFFICULTY_BEST);
i->second->setActive(RaceManager::DIFFICULTY_HARD);
}
else if (i->second->isSolved(RaceManager::DIFFICULTY_EASY))
{
i->second->setActive(RaceManager::DIFFICULTY_BEST);
i->second->setActive(RaceManager::DIFFICULTY_HARD);
i->second->setActive(RaceManager::DIFFICULTY_MEDIUM);
}
else
{
i->second->setActive(RaceManager::DIFFICULTY_BEST);
i->second->setActive(RaceManager::DIFFICULTY_HARD);
i->second->setActive(RaceManager::DIFFICULTY_MEDIUM);
i->second->setActive(RaceManager::DIFFICULTY_EASY);
}
} // for i
// now we have the number of points. Actually lock the tracks
// now we have the number of points.
unlockFeatureByList();
//Actually lock the tracks
for (i = m_challenges_state.begin(); i != m_challenges_state.end(); i++)
{
if (m_points < i->second->getData()->getNumTrophies())
@ -173,12 +200,37 @@ void StoryModeStatus::computeActive()
}
}
}
clearUnlocked();
} // computeActive
//-----------------------------------------------------------------------------
void StoryModeStatus::unlockFeatureByList()
{
// test if we have unlocked a feature requiring a certain number of points
std::map<std::string, ChallengeStatus*>::const_iterator i;
for(i = m_challenges_state.begin();
i != m_challenges_state.end(); i++)
{
if (i->second->isUnlockList())
{
if (i->second->isSolvedAtAnyDifficulty())
continue;
bool newly_solved = unlock_manager->unlockByPoints(m_points,i->second);
// Add to list of recently unlocked features
if(newly_solved)
m_unlocked_features.push_back(i->second->getData());
//Retrieve the smallest number of points for the next unlockable
if (i->second->getData()->getNumTrophies() > m_points && (m_next_unlock_points == 0
|| i->second->getData()->getNumTrophies() < m_next_unlock_points) )
m_next_unlock_points = i->second->getData()->getNumTrophies();
}
}
} //unlockFeatureByList
//-----------------------------------------------------------------------------
void StoryModeStatus::lockFeature(ChallengeStatus *challenge_status)
@ -216,8 +268,10 @@ void StoryModeStatus::unlockFeature(ChallengeStatus* c, RaceManager::Difficulty
m_locked_features.erase(p);
}
// Add to list of recently unlocked features
// Add to list of recently unlocked features if the challenge is newly completed
if (!c->isSolvedAtAnyDifficulty())
m_unlocked_features.push_back(c->getData());
c->setSolved(d); // reset isActive flag
// Save the new unlock information
@ -250,6 +304,10 @@ void StoryModeStatus::raceFinished()
unlockFeature(const_cast<ChallengeStatus*>(m_current_challenge),
race_manager->getDifficulty());
} // if isActive && challenge solved
//This updates the number of points.
//It then calls unlockFeatureByList which checks the specially unlocked features (by points, etc)
computeActive();
} // raceFinished
//-----------------------------------------------------------------------------
@ -259,11 +317,33 @@ void StoryModeStatus::raceFinished()
void StoryModeStatus::grandPrixFinished()
{
if(m_current_challenge &&
m_current_challenge->isActive(race_manager->getDifficulty()) &&
m_current_challenge->getData()->isGPFulfilled() )
m_current_challenge->isActive(race_manager->getDifficulty()) )
{
unlockFeature(const_cast<ChallengeStatus*>(m_current_challenge),
race_manager->getDifficulty());
ChallengeData::GPLevel unlock_level = m_current_challenge->getData()->isGPFulfilled();
RaceManager::Difficulty difficulty = RaceManager::DIFFICULTY_EASY;
switch (unlock_level)
{
case ChallengeData::GP_NONE:
race_manager->setCoinTarget(0);
return; //No cup unlocked
case ChallengeData::GP_EASY:
difficulty = RaceManager::DIFFICULTY_EASY;
break;
case ChallengeData::GP_MEDIUM:
difficulty = RaceManager::DIFFICULTY_MEDIUM;
break;
case ChallengeData::GP_HARD:
difficulty = RaceManager::DIFFICULTY_HARD;
break;
case ChallengeData::GP_BEST:
difficulty = RaceManager::DIFFICULTY_BEST;
break;
}
race_manager->setDifficulty(difficulty);
unlockFeature(const_cast<ChallengeStatus*>(m_current_challenge), difficulty);
} // if isActive && challenge solved
race_manager->setCoinTarget(0);
@ -275,7 +355,7 @@ void StoryModeStatus::grandPrixFinished()
*/
void StoryModeStatus::save(UTFWriter &out)
{
out << L" <story-mode first-time=\"" << m_first_time << L"\">\n";
out << " <story-mode first-time=\"" << m_first_time << L"\">\n";
std::map<std::string, ChallengeStatus*>::const_iterator i;
for(i = m_challenges_state.begin();
i != m_challenges_state.end(); i++)
@ -283,5 +363,5 @@ void StoryModeStatus::save(UTFWriter &out)
if (i->second != NULL)
i->second->save(out);
}
out << L" </story-mode>\n";
out << " </story-mode>\n";
} // save

View File

@ -19,6 +19,7 @@
#ifndef GAME_SLOT_HPP
#define GAME_SLOT_HPP
#include "challenges/challenge_data.hpp"
#include "race/race_manager.hpp"
#include <irrString.h>
@ -33,7 +34,8 @@ class ChallengeStatus;
class UTFWriter;
class XMLNode;
const int CHALLENGE_POINTS[] = { 8, 9, 10 };
const int CHALLENGE_POINTS[] = { 6, 7, 8, 10 };
const int GP_FACTOR = 3;
/** This class contains the progression through challenges for the story mode.
* It maintains a list of all challenges in a mapping of challenge id to
@ -60,6 +62,7 @@ private:
const ChallengeStatus *m_current_challenge;
int m_points;
int m_next_unlock_points;
/** Set to false after the initial stuff (intro, select kart, etc.) */
bool m_first_time;
@ -67,6 +70,7 @@ private:
int m_easy_challenges;
int m_medium_challenges;
int m_hard_challenges;
int m_best_challenges;
public:
@ -75,6 +79,7 @@ public:
void computeActive();
bool isLocked (const std::string& feature);
void unlockFeatureByList();
void lockFeature (ChallengeStatus *challenge);
void unlockFeature (ChallengeStatus* c, RaceManager::Difficulty d,
bool do_save=true);
@ -96,15 +101,21 @@ public:
/** Returns the number of points accumulated. */
int getPoints () const { return m_points; }
// ------------------------------------------------------------------------
/** Returns the number of points needed by the next unlockable. 0 if none. */
int getNextUnlockPoints () const { return m_next_unlock_points; }
// ------------------------------------------------------------------------
/** Returns the number of fulfilled challenges at easy level. */
int getNumEasyTrophies () const { return m_easy_challenges; }
// ------------------------------------------------------------------------
/* Returns the number of fulfilled challenges at medium level. */
int getNumMediumTrophies() const { return m_medium_challenges; }
// ------------------------------------------------------------------------
/** Returns the number of fulfilled challenges at har level. */
/** Returns the number of fulfilled challenges at hard level. */
int getNumHardTrophies () const { return m_hard_challenges; }
// ------------------------------------------------------------------------
/** Returns the number of fulfilled challenges at best level. */
int getNumBestTrophies () const { return m_best_challenges; }
// ------------------------------------------------------------------------
/** Sets if this is the first time the intro is shown. */
void setFirstTime(bool ft) { m_first_time = ft; }
// ------------------------------------------------------------------------

View File

@ -23,6 +23,7 @@
#include "audio/sfx_manager.hpp"
#include "challenges/challenge_data.hpp"
#include "challenges/challenge_status.hpp"
#include "challenges/story_mode_status.hpp"
#include "config/player_manager.hpp"
#include "config/player_profile.hpp"
#include "config/user_config.hpp"
@ -142,19 +143,30 @@ void UnlockManager::addOrFreeChallenge(ChallengeData *c)
{
if(isSupportedVersion(*c))
{
m_all_challenges[c->getId()]=c;
m_all_challenges[c->getChallengeId()]=c;
if (c->isUnlockList())
addListChallenge(c);
}
else
{
Log::warn("Challenge", "Challenge '%s' is not supported - ignored.",
c->getId().c_str());
c->getChallengeId().c_str());
delete c;
}
} // addOrFreeChallenge
//-----------------------------------------------------------------------------
/** Add a challenge to the unlock challenges list
* \param c The challenge that is either stored or freed.
*/
void UnlockManager::addListChallenge(ChallengeData *c)
{
m_list_challenges[c->getChallengeId()]=c;
} // addListChallenge
//-----------------------------------------------------------------------------
/** Reads a challenge from the given filename. The challenge will then either
* be stored, or (if the challenge version is not supported anymore
* be stored, or (if the challenge version is not supported anymore, freed)
* \param filename Name of the challenge file to read.
*/
void UnlockManager::addChallenge(const std::string& filename)
@ -228,20 +240,25 @@ bool UnlockManager::isSupportedVersion(const ChallengeData &challenge)
{
// Test if challenge version number is in between minimum
// and maximum supported version.
return (challenge.getVersion()>=2 && challenge.getVersion()<=2);
return (challenge.getVersion()>=3 && challenge.getVersion()<=3);
} // isSupportedVersion
//-----------------------------------------------------------------------------
/** This functions finds what new tracks, GP and karts have been unlocked
*/
void UnlockManager::findWhatWasUnlocked(int points_before, int points_now,
std::vector<std::string>& tracks,
std::vector<std::string>& gps)
std::vector<std::string>& gps,
std::vector<std::string>& karts,
std::vector<const ChallengeData*>& unlocked)
{
ChallengeData* c = NULL;
for (AllChallengesType::iterator it = m_all_challenges.begin();
it != m_all_challenges.end(); it++)
{
ChallengeData* c = it->second;
c = it->second;
if (c->getNumTrophies() > points_before &&
c->getNumTrophies() <= points_now )
{
@ -257,4 +274,36 @@ void UnlockManager::findWhatWasUnlocked(int points_before, int points_now,
}
}
}
for (unsigned int n = 0; n < unlocked.size(); n++)
{
std::vector<ChallengeData::UnlockableFeature> features = unlocked[n]->getFeatures();
for (unsigned int i = 0; i < features.size(); i++)
{
if( features[i].m_type == ChallengeData::UNLOCK_KART )
karts.push_back(features[i].m_name);
}
}
//std::vector<const ChallengeData*>
// getRecentlyCompletedChallenges()
} // findWhatWasUnlocked
//-----------------------------------------------------------------------------
/** This functions sets as completed the "challenges" requiring a certain number
* of points, to unlock features.
* Returns true if the challenge has been completed
*/
bool UnlockManager::unlockByPoints(int points, ChallengeStatus* unlock_list)
{
//TODO : add support for other conditions (achievements...) for alternative unlock paths
if( unlock_list!=NULL && unlock_list->getData()->getNumTrophies() <= points)
{
unlock_list->setSolved(RaceManager::DIFFICULTY_BEST);
return true;
}
return false;
} // unlockByPoints
/* EOF */

View File

@ -44,12 +44,16 @@ private:
typedef std::map<std::string, ChallengeData*> AllChallengesType;
AllChallengesType m_all_challenges;
/* The challenges who don't have a race, only unlockables */
AllChallengesType m_list_challenges;
void readAllChallengesInDirs(const std::vector<std::string>* all_dirs);
public:
UnlockManager ();
~UnlockManager ();
void addOrFreeChallenge(ChallengeData *c);
void addListChallenge(ChallengeData *c);
void addChallenge (const std::string& filename);
const ChallengeData *getChallengeData(const std::string& id);
@ -61,7 +65,10 @@ public:
void findWhatWasUnlocked(int pointsBefore, int pointsNow,
std::vector<std::string>& tracks,
std::vector<std::string>& gps);
std::vector<std::string>& gps,
std::vector<std::string>& karts,
std::vector<const ChallengeData*>& unlocked);
bool unlockByPoints(int points, ChallengeStatus* unlock_list);
StoryModeStatus *createStoryModeStatus(const XMLNode *node=NULL);

View File

@ -261,14 +261,14 @@ void PlayerManager::save()
std::string filename = file_manager->getUserConfigFile("players.xml");
try
{
UTFWriter players_file(filename.c_str());
UTFWriter players_file(filename.c_str(), false);
players_file << L"<?xml version=\"1.0\"?>\n";
players_file << L"<players version=\"1\" >\n";
players_file << "<?xml version=\"1.0\"?>\n";
players_file << "<players version=\"1\" >\n";
if(m_current_player)
{
players_file << L" <current player=\""
players_file << " <current player=\""
<< StringUtils::xmlEncode(m_current_player->getName(true/*ignoreRTL*/)) << L"\"/>\n";
}
@ -278,7 +278,7 @@ void PlayerManager::save()
if(!player->isGuestAccount())
player->save(players_file);
}
players_file << L"</players>\n";
players_file << "</players>\n";
players_file.close();
}
catch (std::runtime_error& e)

View File

@ -87,7 +87,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token );
node->get("last-online-name", &m_last_online_name );
node->getAndDecode("last-online-name", &m_last_online_name );
node->get("last-was-online", &m_last_was_online );
node->get("remember-password", &m_remember_password);
node->get("icon-filename", &m_icon_filename );
@ -200,21 +200,21 @@ const std::string PlayerProfile::getIconFilename() const
*/
void PlayerProfile::save(UTFWriter &out)
{
out << L" <player name=\"" << StringUtils::xmlEncode(m_local_name)
<< L"\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
out << " <player name=\"" << StringUtils::xmlEncode(m_local_name)
<< "\" guest=\"" << m_is_guest_account
<< "\" use-frequency=\"" << m_use_frequency << "\"\n";
out << L" icon-filename=\"" << m_icon_filename << L"\"\n";
out << " icon-filename=\"" << m_icon_filename << "\"\n";
out << L" unique-id=\"" << m_unique_id
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
out << " unique-id=\"" << m_unique_id
<< "\" saved-session=\"" << m_saved_session << "\"\n";
out << L" saved-user=\"" << m_saved_user_id
<< L"\" saved-token=\"" << m_saved_token << L"\"\n";
out << L" last-online-name=\"" << m_last_online_name
<< L"\" last-was-online=\"" << m_last_was_online << L"\"\n";
out << L" remember-password=\"" << m_remember_password << L"\"\n";
out << L" default-kart-color=\"" << m_default_kart_color << L"\">\n";
out << " saved-user=\"" << m_saved_user_id
<< "\" saved-token=\"" << m_saved_token << "\"\n";
out << " last-online-name=\"" << StringUtils::xmlEncode(m_last_online_name)
<< "\" last-was-online=\"" << m_last_was_online << "\"\n";
out << " remember-password=\"" << m_remember_password << "\"\n";
out << " default-kart-color=\"" << m_default_kart_color << "\">\n";
{
if(m_story_mode_status)
m_story_mode_status->save(out);
@ -222,7 +222,7 @@ void PlayerProfile::save(UTFWriter &out)
if(m_achievements_status)
m_achievements_status->save(out);
}
out << L" </player>\n";
out << " </player>\n";
} // save
//------------------------------------------------------------------------------

View File

@ -230,6 +230,8 @@ public:
// ------------------------------------------------------------------------
unsigned int getPoints() const { return m_story_mode_status->getPoints(); }
// ------------------------------------------------------------------------
unsigned int getNextUnlockPoints() const { return m_story_mode_status->getNextUnlockPoints(); }
// ------------------------------------------------------------------------
void setFirstTime(bool b) { m_story_mode_status->setFirstTime(b); }
// ------------------------------------------------------------------------
bool isFirstTime() const { return m_story_mode_status->isFirstTime(); }
@ -263,7 +265,11 @@ public:
unsigned int getNumHardTrophies() const
{
return m_story_mode_status->getNumHardTrophies();
} // getNumHardTropies
} // getNumHardTrophies
unsigned int getNumBestTrophies() const
{
return m_story_mode_status->getNumBestTrophies();
} // getNumBestTrophies
// ------------------------------------------------------------------------
AchievementsStatus* getAchievementsStatus()
{

View File

@ -150,10 +150,13 @@ void STKConfig::load(const std::string &filename)
CHECK_NEG(m_leader_time_per_kart, "leader time-per-kart" );
CHECK_NEG(m_penalty_ticks, "penalty-time" );
CHECK_NEG(m_max_display_news, "max-display-news" );
CHECK_NEG(m_replay_max_time, "replay max-time" );
CHECK_NEG(m_replay_delta_angle, "replay delta-angle" );
CHECK_NEG(m_replay_delta_pos2, "replay delta-position" );
CHECK_NEG(m_replay_max_frames, "replay max-frames" );
CHECK_NEG(m_replay_delta_steering, "replay delta-steering" );
CHECK_NEG(m_replay_delta_speed, "replay delta-speed " );
CHECK_NEG(m_replay_dt, "replay delta-t" );
CHECK_NEG(m_minimap_size, "minimap size" );
CHECK_NEG(m_minimap_ai_icon, "minimap ai_icon" );
CHECK_NEG(m_minimap_player_icon, "minimap player_icon" );
CHECK_NEG(m_smooth_angle_limit, "physics smooth-angle-limit" );
CHECK_NEG(m_default_track_friction, "physics default-track-friction");
CHECK_NEG(m_physics_fps, "physics fps" );
@ -161,7 +164,6 @@ void STKConfig::load(const std::string &filename)
CHECK_NEG(m_default_moveable_friction, "physics default-moveable-friction");
// Square distance to make distance checks cheaper (no sqrt)
m_replay_delta_pos2 *= m_replay_delta_pos2;
m_default_kart_properties->checkAllSet(filename);
} // load
@ -192,10 +194,13 @@ void STKConfig::init_defaults()
m_min_server_version = -100;
m_max_server_version = -100;
m_max_display_news = -100;
m_replay_max_time = -100;
m_replay_delta_angle = -100;
m_replay_delta_pos2 = -100;
m_replay_max_frames = -100;
m_replay_delta_steering = -100;
m_replay_delta_speed = -100;
m_replay_dt = -100;
m_minimap_size = -100;
m_minimap_ai_icon = -100;
m_minimap_player_icon = -100;
m_network_state_frequeny = -100;
m_title_music = NULL;
m_smooth_normals = false;
@ -399,13 +404,20 @@ void STKConfig::getAllData(const XMLNode * root)
if(const XMLNode *replay_node = root->getNode("replay"))
{
replay_node->get("delta-angle", &m_replay_delta_angle);
replay_node->get("delta-pos", &m_replay_delta_pos2 );
replay_node->get("delta-steering", &m_replay_delta_steering);
replay_node->get("delta-speed", &m_replay_delta_speed );
replay_node->get("delta-t", &m_replay_dt );
replay_node->get("max-time", &m_replay_max_time );
replay_node->get("max-frames", &m_replay_max_frames );
}
if(const XMLNode *replay_node = root->getNode("minimap"))
{
replay_node->get("size", &m_minimap_size );
replay_node->get("ai-icon", &m_minimap_ai_icon );
replay_node->get("player-icon", &m_minimap_player_icon );
}
if (const XMLNode *fonts_list = root->getNode("fonts-list"))
{
fonts_list->get("normal-ttf", &m_normal_ttf);

View File

@ -149,19 +149,26 @@ public:
/** Filename of the title music to play.*/
MusicInformation *m_title_music;
/** Maximum time of a replay. */
int m_replay_max_time;
/** Maximum number of transform events of a replay. */
int m_replay_max_frames;
/** Minimum time between consecutive saved tranform events. */
/** Maximum time between consecutive saved tranform events. */
float m_replay_dt;
/** Maximum difference between interpolated and actual position. If the
* difference is larger than this, a new event is generated. */
float m_replay_delta_pos2;
/** If the speed difference with the last transform event
* is larger than this, a new event is generated. */
float m_replay_delta_speed;
/** A heading difference of more than that will trigger a new event to
/** A steering difference of more than that will trigger a new event to
* be generated. */
float m_replay_delta_angle;
float m_replay_delta_steering;
/** The minimap size */
float m_minimap_size;
/* The size of icons for AIs and human players, respectively */
float m_minimap_ai_icon;
float m_minimap_player_icon;
/** The field of view for 1, 2, 3, 4 player split screen. */
float m_camera_fov[MAX_PLAYER_COUNT];

View File

@ -715,11 +715,28 @@ namespace UserConfigParams
&m_network_group, "Enable chatting in networking lobby, if off than "
"no chat message will be displayed from any players."));
PARAM_PREFIX FloatUserConfigParam m_voting_timeout
PARAM_DEFAULT(FloatUserConfigParam(10.0f, "voting-timeout",
PARAM_DEFAULT(FloatUserConfigParam(20.0f, "voting-timeout",
&m_network_group, "Timeout in seconds for voting tracks in server."));
PARAM_PREFIX FloatUserConfigParam m_validation_timeout
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",
&m_network_group, "Maximum number of players on the server."));
PARAM_PREFIX BoolUserConfigParam m_firewalled_server
PARAM_DEFAULT(BoolUserConfigParam(true, "firewalled-server",
&m_network_group, "Disable it to turn off all stun related code "
"in server, for official server hosting use only."));
PARAM_PREFIX FloatUserConfigParam m_start_game_counter
PARAM_DEFAULT(FloatUserConfigParam(30.0f, "start-game-counter",
&m_network_group, "Time to wait before entering kart selection screen "
"if satisfied start-game-threshold below for owner less or ranked "
"server."));
PARAM_PREFIX FloatUserConfigParam m_start_game_threshold
PARAM_DEFAULT(FloatUserConfigParam(0.7f, "start-game-threshold",
&m_network_group, "Only auto start kart selection when number of "
"connected player is larger than max player * this value, for "
"owner less or ranked server, after start-game-counter."));
PARAM_PREFIX StringToUIntUserConfigParam m_server_ban_list
PARAM_DEFAULT(StringToUIntUserConfigParam("server_ban_list",

View File

@ -44,6 +44,7 @@ void CentralVideoSettings::init()
hasSSBO = false;
hasImageLoadStore = false;
hasTextureCompression = false;
hasTextureCompressionSRGB = false;
hasUBO = false;
hasExplicitAttribLocation = false;
hasGS = false;
@ -53,19 +54,12 @@ void CentralVideoSettings::init()
hasSamplerObjects = false;
hasVertexType2101010Rev = false;
hasInstancedArrays = false;
#if defined(USE_GLES2)
hasBGRA = false;
hasColorBufferFloat = false;
#endif
m_need_vertex_id_workaround = false;
// Call to glGetIntegerv should not be made if --no-graphics is used
if (!ProfileWorld::isNoGraphics())
{
}
if (!ProfileWorld::isNoGraphics())
{
glGetIntegerv(GL_MAJOR_VERSION, &m_gl_major_version);
glGetIntegerv(GL_MINOR_VERSION, &m_gl_minor_version);
@ -194,6 +188,10 @@ void CentralVideoSettings::init()
isARBVertexType2101010RevUsable() && isARBSamplerObjectsUsable() &&
isARBExplicitAttribLocationUsable();
hasTextureCompressionSRGB = true;
hasBGRA = true;
hasColorBufferFloat = true;
#else
if (m_glsl == true)
{
@ -202,6 +200,7 @@ void CentralVideoSettings::init()
hasSamplerObjects = true;
hasVertexType2101010Rev = true;
hasInstancedArrays = true;
hasPixelBufferObject = true;
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXPLICIT_ATTRIB_LOCATION) &&
@ -233,6 +232,22 @@ void CentralVideoSettings::init()
Log::info("GLDriver", "EXT Color Buffer Float Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
(hasGLExtension("GL_EXT_texture_compression_s3tc") ||
hasGLExtension("GL_ANGLE_texture_compression_dxt5")))
{
hasTextureCompression = true;
Log::info("GLDriver", "EXT Texture Compression S3TC Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
(hasGLExtension("GL_EXT_texture_compression_s3tc_srgb") ||
hasGLExtension("GL_NV_sRGB_formats")))
{
hasTextureCompressionSRGB = true;
Log::info("GLDriver", "EXT Texture Compression S3TC sRGB Present");
}
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_VERTEX_ID_WORKING))
{
m_need_vertex_id_workaround = true;
@ -315,6 +330,11 @@ bool CentralVideoSettings::isEXTTextureCompressionS3TCUsable() const
return hasTextureCompression;
}
bool CentralVideoSettings::isEXTTextureCompressionS3TCSRGBUsable() const
{
return hasTextureCompression && hasTextureCompressionSRGB;
}
bool CentralVideoSettings::isARBBufferStorageUsable() const
{
@ -361,7 +381,6 @@ bool CentralVideoSettings::isEXTTextureFilterAnisotropicUsable() const
return hasTextureFilterAnisotropic;
}
#if defined(USE_GLES2)
bool CentralVideoSettings::isEXTTextureFormatBGRA8888Usable() const
{
return hasBGRA;
@ -371,7 +390,6 @@ bool CentralVideoSettings::isEXTColorBufferFloatUsable() const
{
return hasColorBufferFloat;
}
#endif
bool CentralVideoSettings::supportsComputeShadersFiltering() const
{

View File

@ -36,6 +36,7 @@ private:
bool hasExplicitAttribLocation;
bool hasGS;
bool hasTextureCompression;
bool hasTextureCompressionSRGB;
bool hasAtomics;
bool hasSSBO;
bool hasImageLoadStore;
@ -45,12 +46,8 @@ private:
bool hasSamplerObjects;
bool hasVertexType2101010Rev;
bool hasInstancedArrays;
#if defined(USE_GLES2)
bool hasBGRA;
bool hasColorBufferFloat;
#endif
bool m_need_vertex_id_workaround;
public:
static bool m_supports_sp;
@ -65,6 +62,7 @@ public:
// Extension is available and safe to use
bool isARBUniformBufferObjectUsable() const;
bool isEXTTextureCompressionS3TCUsable() const;
bool isEXTTextureCompressionS3TCSRGBUsable() const;
bool isARBTextureViewUsable() const;
bool isARBGeometryShadersUsable() const;
bool isARBTextureStorageUsable() const;
@ -81,11 +79,8 @@ public:
bool isARBSamplerObjectsUsable() const;
bool isARBVertexType2101010RevUsable() const;
bool isARBInstancedArraysUsable() const;
#if defined(USE_GLES2)
bool isEXTTextureFormatBGRA8888Usable() const;
bool isEXTColorBufferFloatUsable() const;
#endif
// Are all required extensions available for feature support
bool supportsComputeShadersFiltering() const;

View File

@ -62,6 +62,12 @@ extern "C" {
#define GL_BGRA 0x80E1
#define GL_BGR 0x80E0
#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE
#ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
#endif
#else

View File

@ -62,6 +62,7 @@
#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"
@ -615,6 +616,7 @@ void IrrDriver::initDevice()
(int x, int y, int w, int h, unsigned int f, unsigned int t, void* d)
{ glReadPixels(x, y, w, h, f, t, d); });
#ifndef USE_GLES2
ogrRegPBOFunctions([](int n, unsigned int* b) { glGenBuffers(n, b); },
[](unsigned int t, unsigned int b) { glBindBuffer(t, b); },
[](unsigned int t, ptrdiff_t s, const void* d, unsigned int u)
@ -622,6 +624,16 @@ void IrrDriver::initDevice()
[](int n, const unsigned int* b) { glDeleteBuffers(n, b); },
[](unsigned int t, unsigned int a) { return glMapBuffer(t, a); },
[](unsigned int t) { return glUnmapBuffer(t); });
#else
ogrRegPBOFunctionsRange([](int n, unsigned int* b) { glGenBuffers(n, b); },
[](unsigned int t, unsigned int b) { glBindBuffer(t, b); },
[](unsigned int t, ptrdiff_t s, const void* d, unsigned int u)
{ glBufferData(t, s, d, u); },
[](int n, const unsigned int* b) { glDeleteBuffers(n, b); },
[](unsigned int t, ptrdiff_t o, ptrdiff_t l, unsigned int a)
{ return glMapBufferRange(t, o, l, a); },
[](unsigned int t) { return glUnmapBuffer(t); });
#endif
#endif
@ -728,6 +740,13 @@ void IrrDriver::setMaxTextureSize()
att.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(max, max));
} // setMaxTextureSize
// ----------------------------------------------------------------------------
void IrrDriver::unsetMaxTextureSize()
{
io::IAttributes &att = m_video_driver->getNonConstDriverAttributes();
att.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(2048, 2048));
} // unsetMaxTextureSize
// ----------------------------------------------------------------------------
void IrrDriver::cleanSunInterposer()
{
@ -1715,9 +1734,9 @@ void IrrDriver::displayFPS()
no_trust--;
static video::SColor fpsColor = video::SColor(255, 0, 0, 0);
font->draw( L"FPS: ...", core::rect< s32 >(100,0,400,50), fpsColor,
false );
font->draw(StringUtils::insertValues (L"FPS: ... Ping: %dms",
NetworkingLobby::getInstance()->getServerPing()),
core::rect< s32 >(100,0,400,50), fpsColor, false);
return;
}
@ -1738,22 +1757,26 @@ void IrrDriver::displayFPS()
{
fps_string = StringUtils::insertValues
(L"FPS: %d/%d/%d - PolyCount: %d Solid, "
"%d Shadows - LightDist : %d, Total skinning joints: %d",
"%d Shadows - LightDist : %d, Total skinning joints: %d, "
"Ping: %dms",
min, fps, max, SP::sp_solid_poly_count,
SP::sp_shadow_poly_count, m_last_light_bucket_distance,
m_skinning_joint);
m_skinning_joint,
NetworkingLobby::getInstance()->getServerPing());
}
else
{
if (CVS->isGLSL())
{
fps_string = _("FPS: %d/%d/%d - %d KTris", min, fps, max,
SP::sp_solid_poly_count / 1000);
fps_string = _("FPS: %d/%d/%d - %d KTris, Ping: %dms", min, fps,
max, SP::sp_solid_poly_count / 1000,
NetworkingLobby::getInstance()->getServerPing());
}
else
{
fps_string = _("FPS: %d/%d/%d - %d KTris", min, fps, max,
(int)roundf(kilotris));
fps_string = _("FPS: %d/%d/%d - %d KTris, Ping: %dms", min, fps,
max, (int)roundf(kilotris),
NetworkingLobby::getInstance()->getServerPing());
}
}
@ -1944,6 +1967,12 @@ void IrrDriver::setRecording(bool val)
{
ogrStopCapture();
}
#else
Log::error("Recorder", "Recording unavailable, STK was compiled without "
"recording support. Please re-compile STK with libopenglrecorder "
"to enable recording. If you got SuperTuxKart from your distribution's "
"repositories, please use the official binaries, or contact your "
"distributions's package mantainers.");
#endif
} // setRecording

View File

@ -197,6 +197,7 @@ public:
void initDevice();
void reset();
void setMaxTextureSize();
void unsetMaxTextureSize();
void getOpenGLData(std::string *vendor, std::string *renderer,
std::string *version);

View File

@ -92,7 +92,6 @@ RTT::RTT(unsigned int width, unsigned int height, float rtt_scale,
GLint diffuse_specular_internal_format = GL_R11F_G11F_B10F;
GLint type = GL_FLOAT;
#if defined(USE_GLES2)
if (!CVS->isEXTColorBufferFloatUsable())
{
rgba_internal_format = GL_RGBA8;
@ -104,7 +103,7 @@ RTT::RTT(unsigned int width, unsigned int height, float rtt_scale,
diffuse_specular_internal_format = GL_RGBA8;
type = GL_UNSIGNED_BYTE;
}
#endif
if (!CVS->isDeferredEnabled())
{
// RTT is used in only deferred shading which need hdr framebuffer

View File

@ -123,10 +123,8 @@ void ShaderBasedRenderer::renderSkybox(const scene::ICameraSceneNode *camera) co
// ----------------------------------------------------------------------------
void ShaderBasedRenderer::renderSSAO() const
{
#if defined(USE_GLES2)
if (!CVS->isEXTColorBufferFloatUsable())
return;
#endif
m_rtts->getFBO(FBO_SSAO).bind();
glClearColor(1., 1., 1., 1.);

View File

@ -421,6 +421,8 @@ void SPMeshBuffer::enableTextureMatrix(unsigned mat_id)
assert(mat_id < m_stk_material.size());
// Make the 31 bit in normal to be 1
uploadGLMesh();
if (m_vbo == 0 || m_ibo == 0)
return;
auto& ret = m_stk_material[mat_id];
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
std::set<uint16_t> used_vertices;

View File

@ -29,14 +29,14 @@
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !(defined(SERVER_ONLY) || defined(ANDROID))
#include <squish.h>
static_assert(squish::kColourClusterFit == (1 << 5), "Wrong header");
static_assert(squish::kColourRangeFit == (1 << 6), "Wrong header");
static_assert(squish::kColourIterativeClusterFit == (1 << 8), "Wrong header");
#endif
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !(defined(SERVER_ONLY) || defined(ANDROID))
extern "C"
{
#include <mipmap/img.h>
@ -46,7 +46,7 @@ extern "C"
#include <numeric>
#if !defined(USE_GLES2)
#if !defined(ANDROID)
static const uint8_t CACHE_VERSION = 1;
#endif
@ -68,18 +68,26 @@ SPTexture::SPTexture(const std::string& path, Material* m, bool undo_srgb,
return;
}
std::string cache_subdir = "hd/";
std::string cache_subdir = "hd";
if ((UserConfigParams::m_high_definition_textures & 0x01) == 0x01)
{
cache_subdir = "hd/";
cache_subdir = "hd";
}
else
{
cache_subdir = StringUtils::insertValues("resized_%i/",
cache_subdir = StringUtils::insertValues("resized_%i",
(int)UserConfigParams::m_max_texture_size);
}
#ifdef USE_GLES2
if (m_undo_srgb && !CVS->isEXTTextureCompressionS3TCSRGBUsable())
{
cache_subdir += "-linear";
}
#endif
m_cache_directory = file_manager->getCachedTexturesDir() +
cache_subdir + container_id;
cache_subdir + "/" + container_id;
file_manager->checkAndCreateDirectoryP(m_cache_directory);
#endif
@ -204,7 +212,11 @@ std::shared_ptr<video::IImage> SPTexture::getTextureImage() const
#ifndef USE_GLES2
}
#endif
if (m_undo_srgb && !use_tex_compress)
bool force_undo_srgb = use_tex_compress &&
!CVS->isEXTTextureCompressionS3TCSRGBUsable();
if (m_undo_srgb && (!use_tex_compress || force_undo_srgb))
{
data[i * 4] = srgb255ToLinear(data[i * 4]);
data[i * 4 + 1] = srgb255ToLinear(data[i * 4 + 1]);
@ -221,9 +233,9 @@ bool SPTexture::compressedTexImage2d(std::shared_ptr<video::IImage> texture,
<core::dimension2du, unsigned> >&
mipmap_sizes)
{
#if !defined(SERVER_ONLY) && !defined(USE_GLES2)
#if !defined(SERVER_ONLY) && !defined(ANDROID)
unsigned format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
if (m_undo_srgb)
if (m_undo_srgb && CVS->isEXTTextureCompressionS3TCSRGBUsable())
{
format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
}
@ -319,7 +331,7 @@ bool SPTexture::saveCompressedTexture(std::shared_ptr<video::IImage> texture,
<core::dimension2du, unsigned> >& sizes,
const std::string& cache_location)
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !defined(SERVER_ONLY) && !defined(ANDROID)
const unsigned total_size = std::accumulate(sizes.begin(), sizes.end(), 0,
[] (const unsigned int previous, const std::pair
<core::dimension2du, unsigned>& cur_sizes)
@ -384,7 +396,7 @@ std::shared_ptr<video::IImage> SPTexture::getTextureCache(const std::string& p,
std::vector<std::pair<core::dimension2du, unsigned> >* sizes)
{
std::shared_ptr<video::IImage> cache;
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !(defined(SERVER_ONLY) || defined(ANDROID))
io::IReadFile* file = irr::io::createReadFile(p.c_str());
if (file == NULL)
{
@ -444,6 +456,8 @@ bool SPTexture::threadedLoad()
std::shared_ptr<video::IImage> image = getTextureImage();
if (!image)
{
m_width.store(2);
m_height.store(2);
return true;
}
std::shared_ptr<video::IImage> mask = getMask(image->getDimension());
@ -472,7 +486,7 @@ bool SPTexture::threadedLoad()
}
else
{
#ifndef USE_GLES2
#ifndef ANDROID
if (UserConfigParams::m_hq_mipmap && image->getDimension().Width > 1 &&
image->getDimension().Height > 1)
{
@ -642,12 +656,6 @@ void SPTexture::applyMask(video::IImage* texture, video::IImage* mask)
}
} // applyMask
// ----------------------------------------------------------------------------
bool SPTexture::initialized() const
{
return m_width.load() != 0 && m_height.load() != 0;
} // initialized
// ----------------------------------------------------------------------------
void SPTexture::generateQuickMipmap(std::shared_ptr<video::IImage> first_image,
const std::vector<std::pair
@ -676,7 +684,7 @@ void SPTexture::generateHQMipmap(void* in,
<core::dimension2du, unsigned> >& mms,
uint8_t* out)
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !(defined(SERVER_ONLY) || defined(ANDROID))
imMipmapCascade cascade;
imReduceOptions options;
imReduceSetOptions(&options,
@ -708,7 +716,7 @@ void SPTexture::generateHQMipmap(void* in,
void SPTexture::squishCompressImage(uint8_t* rgba, int width, int height,
int pitch, void* blocks, unsigned flags)
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !(defined(SERVER_ONLY) || defined(ANDROID))
// This function is copied from CompressImage in libsquish to avoid omp
// if enabled by shared libsquish, because we are already using
// multiple thread
@ -758,7 +766,7 @@ std::vector<std::pair<core::dimension2du, unsigned> >
{
std::vector<std::pair<core::dimension2du, unsigned> > mipmap_sizes;
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
#if !(defined(SERVER_ONLY) || defined(ANDROID))
unsigned width = image->getDimension().Width;
unsigned height = image->getDimension().Height;
mipmap_sizes.emplace_back(core::dimension2du(width, height), 0);

View File

@ -183,7 +183,8 @@ public:
// ------------------------------------------------------------------------
GLuint getOpenGLTextureName() const { return m_texture_name; }
// ------------------------------------------------------------------------
bool initialized() const;
bool initialized() const
{ return m_width.load() != 0 && m_height.load() != 0; }
// ------------------------------------------------------------------------
unsigned getWidth() const { return m_width.load(); }
// ------------------------------------------------------------------------

View File

@ -1327,7 +1327,8 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
const float value = (float)(w->getValue() - w->getMin())
/ (w->getMax() - w->getMin());
if (value > 0.0f)
{
const core::recti dest_area(rect.UpperLeftCorner.X + handle_size,
rect.UpperLeftCorner.Y,
rect.UpperLeftCorner.X + handle_size +
@ -1342,11 +1343,9 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
const core::recti source_area(0, 0, texture_w, texture_h);
draw2DImage(texture,
dest_area, source_area,
0 /* no clipping */, 0,
draw2DImage(texture, dest_area, source_area, 0 /* no clipping */, 0,
true /* alpha */);
}
}
if (focused && widget->hasTooltip())

View File

@ -1099,14 +1099,14 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID,
int row;
int id;
int iterations = 0; // a safeguard to avoid infinite loops (should not happen normally)
unsigned int iterations = 0; // a safeguard to avoid infinite loops (should not happen normally)
while (!findItemInRows(name.c_str(), &row, &id))
{
// if we get here it means the item is scrolled out. Try to find it.
scroll(1, evenIfDeactivated);
if (iterations > 50)
if (iterations > m_items.size())
{
Log::error("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str());
return false;

View File

@ -94,7 +94,7 @@ namespace GUIEngine
virtual ~IconButtonWidget() {};
/** \brief Implement callback from base class Widget */
virtual void add();
virtual void add() OVERRIDE;
/**
* \brief Call this if scale mode is SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO.

Some files were not shown because too many files have changed in this diff Show More