mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 03:15:32 +00:00
Add OpenMW 0.47 commits to OpenMW VR up to 4 Dec 2021
# Conflicts: # .gitlab-ci.yml # CI/before_script.msvc.sh # CI/install_debian_deps.sh # CMakeLists.txt # apps/openmw/mwrender/screenshotmanager.cpp # files/ui/advancedpage.ui
This commit is contained in:
commit
572b16af41
352 changed files with 5707 additions and 4112 deletions
|
@ -16,8 +16,6 @@ stages:
|
|||
- apt-cache/
|
||||
- ccache/
|
||||
stage: build
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "schedule"'
|
||||
script:
|
||||
- export CCACHE_BASEDIR="`pwd`"
|
||||
- export CCACHE_DIR="`pwd`/ccache" && mkdir -pv "$CCACHE_DIR"
|
||||
|
@ -27,6 +25,7 @@ stages:
|
|||
- cmake --build . -- -j $(nproc)
|
||||
- cmake --install .
|
||||
- if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_test_suite; fi
|
||||
- if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi
|
||||
- ccache -s
|
||||
artifacts:
|
||||
paths:
|
||||
|
@ -149,6 +148,7 @@ Debian_Clang_tests:
|
|||
macOS11_Xcode12:
|
||||
extends: .MacOS
|
||||
image: macos-11-xcode-12
|
||||
allow_failure: true
|
||||
cache:
|
||||
key: macOS11_Xcode12.v1
|
||||
variables:
|
||||
|
@ -157,7 +157,6 @@ macOS11_Xcode12:
|
|||
macOS10.15_Xcode11:
|
||||
extends: .MacOS
|
||||
image: macos-10.15-xcode-11
|
||||
allow_failure: true
|
||||
cache:
|
||||
key: macOS10.15_Xcode11.v1
|
||||
variables:
|
||||
|
@ -171,6 +170,10 @@ variables: &cs-targets
|
|||
targets: "openmw-cs,bsatool,esmtool,niftest"
|
||||
package: "CS"
|
||||
|
||||
variables: &tests-targets
|
||||
targets: "openmw_test_suite,openmw_detournavigator_navmeshtilescache_benchmark"
|
||||
package: "Tests"
|
||||
|
||||
.Windows_Ninja_Base:
|
||||
tags:
|
||||
- windows
|
||||
|
@ -185,13 +188,11 @@ variables: &cs-targets
|
|||
- choco install python -y
|
||||
- refreshenv
|
||||
stage: build
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "schedule"'
|
||||
script:
|
||||
- $time = (Get-Date -Format "HH:mm:ss")
|
||||
- echo ${time}
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -N
|
||||
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -N -b -t
|
||||
- cd MSVC2019_64_Ninja
|
||||
- .\ActivateMSVC.ps1
|
||||
- cmake --build . --config $config --target ($targets.Split(','))
|
||||
|
@ -203,6 +204,7 @@ variables: &cs-targets
|
|||
Get-ChildItem -Recurse *.pdb | Remove-Item
|
||||
}
|
||||
- 7z a -tzip ..\..\OpenMW_MSVC2019_64_${package}_${config}_${CI_COMMIT_REF_NAME}.zip '*'
|
||||
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
|
||||
after_script:
|
||||
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
||||
cache:
|
||||
|
@ -266,6 +268,15 @@ Windows_Ninja_CS_RelWithDebInfo:
|
|||
<<: *cs-targets
|
||||
config: "RelWithDebInfo"
|
||||
|
||||
Windows_Ninja_Tests_RelWithDebInfo:
|
||||
extends: .Windows_Ninja_Base
|
||||
stage: build
|
||||
variables:
|
||||
<<: *tests-targets
|
||||
config: "RelWithDebInfo"
|
||||
# Gitlab can't successfully execute following binaries due to unknown reason
|
||||
# executables: "openmw_test_suite.exe,openmw_detournavigator_navmeshtilescache_benchmark.exe"
|
||||
|
||||
.Windows_MSBuild_Base:
|
||||
tags:
|
||||
- windows
|
||||
|
@ -279,13 +290,11 @@ Windows_Ninja_CS_RelWithDebInfo:
|
|||
- choco install python -y
|
||||
- refreshenv
|
||||
stage: build
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "schedule"'
|
||||
script:
|
||||
- $time = (Get-Date -Format "HH:mm:ss")
|
||||
- echo ${time}
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V
|
||||
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -b -t
|
||||
- cd MSVC2019_64
|
||||
- cmake --build . --config $config --target ($targets.Split(','))
|
||||
- cd $config
|
||||
|
@ -296,6 +305,7 @@ Windows_Ninja_CS_RelWithDebInfo:
|
|||
Get-ChildItem -Recurse *.pdb | Remove-Item
|
||||
}
|
||||
- 7z a -tzip ..\..\OpenMW_MSVC2019_64_${package}_${config}_${CI_COMMIT_REF_NAME}.zip '*'
|
||||
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
|
||||
after_script:
|
||||
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
||||
cache:
|
||||
|
@ -359,6 +369,15 @@ Windows_MSBuild_CS_RelWithDebInfo:
|
|||
<<: *cs-targets
|
||||
config: "RelWithDebInfo"
|
||||
|
||||
Windows_MSBuild_Tests_RelWithDebInfo:
|
||||
extends: .Windows_MSBuild_Base
|
||||
stage: build
|
||||
variables:
|
||||
<<: *tests-targets
|
||||
config: "RelWithDebInfo"
|
||||
# Gitlab can't successfully execute following binaries due to unknown reason
|
||||
# executables: "openmw_test_suite.exe,openmw_detournavigator_navmeshtilescache_benchmark.exe"
|
||||
|
||||
#Debian_AndroidNDK_arm64-v8a:
|
||||
# tags:
|
||||
# - linux
|
||||
|
|
10
.readthedocs.yaml
Normal file
10
.readthedocs.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
version: 2
|
||||
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
|
||||
python:
|
||||
version: 3.8
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
|
@ -22,9 +22,9 @@ addons:
|
|||
]
|
||||
matrix:
|
||||
include:
|
||||
- name: OpenMW (all) on MacOS 10.15 with Xcode 10.2
|
||||
- name: OpenMW (all) on MacOS 10.15 with Xcode 11.6
|
||||
os: osx
|
||||
osx_image: xcode10.2
|
||||
osx_image: xcode11.6
|
||||
- name: OpenMW (all) on Ubuntu Focal with GCC
|
||||
os: linux
|
||||
dist: focal
|
||||
|
@ -74,7 +74,7 @@ notifications:
|
|||
irc:
|
||||
if: repository_slug = OpenMW/openmw AND branch = master
|
||||
channels:
|
||||
- "chat.freenode.net#openmw"
|
||||
- "irc.libera.chat#openmw"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
use_notice: true
|
||||
|
|
|
@ -222,6 +222,7 @@ Programmers
|
|||
Yuri Krupenin
|
||||
zelurker
|
||||
Noah Gooder
|
||||
Andrew Appuhamy (andrew-app)
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
|
38
CHANGELOG.md
38
CHANGELOG.md
|
@ -7,7 +7,6 @@
|
|||
Bug #2069: Fireflies in Fireflies invade Morrowind look wrong
|
||||
Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs
|
||||
Bug #2473: Unable to overstock merchants
|
||||
Bug #2798: Mutable ESM records
|
||||
Bug #2976: [reopened]: Issues combining settings from the command line and both config files
|
||||
Bug #3137: Walking into a wall prevents jumping
|
||||
Bug #3372: Projectiles and magic bolts go through moving targets
|
||||
|
@ -20,7 +19,6 @@
|
|||
Bug #4039: Multiple followers should have the same following distance
|
||||
Bug #4055: Local scripts don't inherit variables from their base record
|
||||
Bug #4083: Door animation freezes when colliding with actors
|
||||
Bug #4201: Projectile-projectile collision
|
||||
Bug #4247: Cannot walk up stairs in Ebonheart docks
|
||||
Bug #4357: OpenMW-CS: TopicInfos index sorting and rearranging isn't fully functional
|
||||
Bug #4363: OpenMW-CS: Defect in Clone Function for Dialogue Info records
|
||||
|
@ -64,6 +62,7 @@
|
|||
Bug #5452: Autowalk is being included in savegames
|
||||
Bug #5469: Local map is reset when re-entering certain cells
|
||||
Bug #5472: Mistify mod causes CTD in 0.46 on Mac
|
||||
Bug #5473: OpenMW-CS: Cell border lines don't update properly on terrain change
|
||||
Bug #5479: NPCs who should be walking around town are standing around without walking
|
||||
Bug #5484: Zero value items shouldn't be able to be bought or sold for 1 gold
|
||||
Bug #5485: Intimidate doesn't increase disposition on marginal wins
|
||||
|
@ -80,6 +79,7 @@
|
|||
Bug #5603: Setting constant effect cast style doesn't correct effects view
|
||||
Bug #5604: Only one valid NIF root node is loaded from a single file
|
||||
Bug #5611: Usable items with "0 Uses" should be used only once
|
||||
Bug #5619: Input events are queued during save loading
|
||||
Bug #5622: Can't properly interact with the console when in pause menu
|
||||
Bug #5627: Bookart not shown if it isn't followed by <BR> statement
|
||||
Bug #5633: Damage Spells in effect before god mode is enabled continue to hurt the player character and can kill them
|
||||
|
@ -87,7 +87,7 @@
|
|||
Bug #5644: Summon effects running on the player during game initialization cause crashes
|
||||
Bug #5656: Sneaking characters block hits while standing
|
||||
Bug #5661: Region sounds don't play at the right interval
|
||||
Bug #5675: OpenMW-cs. FRMR subrecords are saved with the wrong MastIdx
|
||||
Bug #5675: OpenMW-CS: FRMR subrecords are saved with the wrong MastIdx
|
||||
Bug #5680: Bull Netches incorrectly aim over the player character's head and always miss
|
||||
Bug #5681: Player character can clip or pass through bridges instead of colliding against them
|
||||
Bug #5687: Bound items covering the same inventory slot expiring at the same time freezes the game
|
||||
|
@ -100,6 +100,7 @@
|
|||
Bug #5739: Saving and loading the save a second or two before hitting the ground doesn't count fall damage
|
||||
Bug #5758: Paralyzed actors behavior is inconsistent with vanilla
|
||||
Bug #5762: Movement solver is insufficiently robust
|
||||
Bug #5800: Equipping a CE enchanted ring deselects an already equipped and selected enchanted ring from the spell menu
|
||||
Bug #5807: Video decoding crash on ARM
|
||||
Bug #5821: NPCs from mods getting removed if mod order was changed
|
||||
Bug #5835: OpenMW doesn't accept negative values for NPC's hello, alarm, fight, and flee
|
||||
|
@ -118,14 +119,31 @@
|
|||
Bug #5923: Clicking on empty spaces between journal entries might show random topics
|
||||
Bug #5934: AddItem command doesn't accept negative values
|
||||
Bug #5975: NIF controllers from sheath meshes are used
|
||||
Bug #5991: Activate should always be allowed for inventory items
|
||||
Bug #5995: NiUVController doesn't calculate the UV offset properly
|
||||
Bug #6007: Crash when ending cutscene is playing
|
||||
Bug #6016: Greeting interrupts Fargoth's sneak-walk
|
||||
Bug #6022: OpenMW-CS: Terrain selection is not updated when undoing/redoing terrain changes
|
||||
Bug #6023: OpenMW-CS: Clicking on a reference in "Terrain land editing" mode discards corresponding select/edit action
|
||||
Bug #6028: Particle system controller values are incorrectly used
|
||||
Bug #6035: OpenMW-CS: Circle brush in "Terrain land editing" mode sometimes includes vertices outside its radius
|
||||
Bug #6036: OpenMW-CS: Terrain selection at the border of cells omits certain corner vertices
|
||||
Bug #6043: Actor can have torch missing when torch animation is played
|
||||
Bug #6047: Mouse bindings can be triggered during save loading
|
||||
Bug #6136: Game freezes when NPCs try to open doors that are about to be closed
|
||||
Bug #6294: Game crashes with empty pathgrid
|
||||
Feature #390: 3rd person look "over the shoulder"
|
||||
Feature #832: OpenMW-CS: Handle deleted references
|
||||
Feature #1536: Show more information about level on menu
|
||||
Feature #2159: "Graying out" exhausted dialogue topics
|
||||
Feature #2386: Distant Statics in the form of Object Paging
|
||||
Feature #2404: Levelled List can not be placed into a container
|
||||
Feature #2686: Timestamps in openmw.log
|
||||
Feature #2798: Mutable ESM records
|
||||
Feature #3171: OpenMW-CS: Instance drag selection
|
||||
Feature #3983: Wizard: Add link to buy Morrowind
|
||||
Feature #4201: Projectile-projectile collision
|
||||
Feature #4486: Handle crashes on Windows
|
||||
Feature #4894: Consider actors as obstacles for pathfinding
|
||||
Feature #4899: Alpha-To-Coverage Anti-Aliasing for alpha testing
|
||||
Feature #4917: Do not trigger NavMesh update when RecastMesh update should not change NavMesh
|
||||
|
@ -138,10 +156,12 @@
|
|||
Feature #5456: Basic collada animation support
|
||||
Feature #5457: Realistic diagonal movement
|
||||
Feature #5486: Fixes trainers to choose their training skills based on their base skill points
|
||||
Feature #5500: Prepare enough navmesh tiles before scene loading ends
|
||||
Feature #5511: Add in game option to toggle HRTF support in OpenMW
|
||||
Feature #5519: Code Patch tab in launcher
|
||||
Feature #5524: Resume failed script execution after reload
|
||||
Feature #5545: Option to allow stealing from an unconscious NPC during combat
|
||||
Feature #5551: Do not reboot PC after OpenMW installation on Windows
|
||||
Feature #5563: Run physics update in background thread
|
||||
Feature #5579: MCP SetAngle enhancement
|
||||
Feature #5580: Service refusal filtering
|
||||
|
@ -156,9 +176,12 @@
|
|||
Feature #5814: Bsatool should be able to create BSA archives, not only to extract it
|
||||
Feature #5828: Support more than 8 lights
|
||||
Feature #5910: Fall back to delta time when physics can't keep up
|
||||
Feature #5980: Support Bullet with double precision instead of one with single precision
|
||||
Feature #6024: OpenMW-CS: Selecting terrain in "Terrain land editing" should support "Add to selection" and "Remove from selection" modes
|
||||
Feature #6033: Include pathgrid to navigation mesh
|
||||
Feature #6034: Find path based on area cost depending on NPC stats
|
||||
Task #5480: Drop Qt4 support
|
||||
Task #5520: Improve cell name autocompleter implementation
|
||||
Task #5844: Update 'toggle sneak' documentation
|
||||
|
||||
0.46.0
|
||||
------
|
||||
|
@ -168,7 +191,7 @@
|
|||
Bug #2395: Duplicated plugins in the launcher when multiple data directories provide the same plugin
|
||||
Bug #2679: Unable to map mouse wheel under control settings
|
||||
Bug #2969: Scripted items can stack
|
||||
Bug #2976: Data lines in global openmw.cfg take priority over user openmw.cfg
|
||||
Bug #2976: [reopened in 0.47] Data lines in global openmw.cfg take priority over user openmw.cfg
|
||||
Bug #2987: Editor: some chance and AI data fields can overflow
|
||||
Bug #3006: 'else if' operator breaks script compilation
|
||||
Bug #3109: SetPos/Position handles actors differently
|
||||
|
@ -186,7 +209,6 @@
|
|||
Bug #4009: Launcher does not show data files on the first run after installing
|
||||
Bug #4077: Enchanted items are not recharged if they are not in the player's inventory
|
||||
Bug #4141: PCSkipEquip isn't set to 1 when reading books/scrolls
|
||||
Bug #4202: Open .omwaddon files without needing toopen openmw-cs first
|
||||
Bug #4240: Ash storm origin coordinates and hand shielding animation behavior are incorrect
|
||||
Bug #4262: Rain settings are hardcoded
|
||||
Bug #4270: Closing doors while they are obstructed desyncs closing sfx
|
||||
|
@ -276,7 +298,6 @@
|
|||
Bug #4964: Multiple effect spell projectile sounds play louder than vanilla
|
||||
Bug #4965: Global light attenuation settings setup is lacking
|
||||
Bug #4969: "Miss" sound plays for any actor
|
||||
Bug #4971: OpenMW-CS: Make rotations display as degrees instead of radians
|
||||
Bug #4972: Player is able to use quickkeys while disableplayerfighting is active
|
||||
Bug #4979: AiTravel maximum range depends on "actors processing range" setting
|
||||
Bug #4980: Drowning mechanics is applied for actors indifferently from distance to player
|
||||
|
@ -374,7 +395,6 @@
|
|||
Bug #5350: An attempt to launch magic bolt causes "AL error invalid value" error
|
||||
Bug #5352: Light source items' duration is decremented while they aren't visible
|
||||
Feature #1724: Handle AvoidNode
|
||||
Feature #2159: "Graying out" exhausted dialogue topics
|
||||
Feature #2229: Improve pathfinding AI
|
||||
Feature #3025: Analogue gamepad movement controls
|
||||
Feature #3442: Default values for fallbacks from ini file
|
||||
|
@ -387,6 +407,7 @@
|
|||
Feature #4001: Toggle sneak controller shortcut
|
||||
Feature #4068: OpenMW-CS: Add a button to reset key bindings to defaults
|
||||
Feature #4129: Beta Comment to File
|
||||
Feature #4202: Open .omwaddon files without needing to open openmw-cs first
|
||||
Feature #4209: Editor: Faction rank sub-table
|
||||
Feature #4255: Handle broken RepairedOnMe script function
|
||||
Feature #4316: Implement RaiseRank/LowerRank functions properly
|
||||
|
@ -409,6 +430,7 @@
|
|||
Feature #4958: Support eight blood types
|
||||
Feature #4962: Add casting animations for magic items
|
||||
Feature #4968: Scalable UI widget skins
|
||||
Feature #4971: OpenMW-CS: Make rotations display as degrees instead of radians
|
||||
Feature #4994: Persistent pinnable windows hiding
|
||||
Feature #5000: Compressed BSA format support
|
||||
Feature #5005: Editor: Instance window via Scene window
|
||||
|
|
|
@ -38,9 +38,15 @@ Editor Bug Fixes:
|
|||
- Disabled record sorting in Topic and Journal Info tables, implemented drag-move for records (#4357)
|
||||
- Topic and Journal Info records can now be cloned with a different parent Topic/Journal Id (#4363)
|
||||
- Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400)
|
||||
- Cell borders are now properly redrawn when undoing/redoing terrain changes (#5473)
|
||||
- Loading mods now keeps the master index (#5675)
|
||||
- Flicker and crashing on XFCE4 fixed (#5703)
|
||||
- Collada models render properly in the Editor (#5713)
|
||||
- Terrain-selection grid is now properly updated when undoing/redoing terrain changes (#6022)
|
||||
- Tool outline and select/edit actions in "Terrain land editing" mode now ignore references (#6023)
|
||||
- Primary-select and secondary-select actions in "Terrain land editing" mode now behave like in "Instance editing" mode (#6024)
|
||||
- Using the circle brush to select terrain in the "Terrain land editing" mode no longer selects vertices outside the circle (#6035)
|
||||
- Vertices at the NW and SE corners of a cell can now also be selected in "Terrain land editing" mode if the adjacent cells aren't loaded yet (#6036)
|
||||
|
||||
Miscellaneous:
|
||||
- Prevent save-game bloating by using an appropriate fog texture format (#5108)
|
||||
|
|
|
@ -30,55 +30,11 @@ command -v unixPathAsWindows >/dev/null 2>&1 || function unixPathAsWindows {
|
|||
fi
|
||||
}
|
||||
|
||||
function windowsSystemPathAsUnix {
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
cygpath -u -p $1
|
||||
else
|
||||
IFS=';' read -r -a paths <<< "$1"
|
||||
declare -a convertedPaths
|
||||
for entry in paths; do
|
||||
convertedPaths+=(windowsPathAsUnix $entry)
|
||||
done
|
||||
convertedPath=printf ":%s" ${convertedPaths[@]}
|
||||
echo ${convertedPath:1}
|
||||
fi
|
||||
}
|
||||
|
||||
# capture CMD environment so we know what's been changed
|
||||
declare -A originalCmdEnv
|
||||
originalIFS="$IFS"
|
||||
IFS=$'\n\r'
|
||||
for pair in $(cmd //c "set"); do
|
||||
IFS='=' read -r -a separatedPair <<< "${pair}"
|
||||
if [ ${#separatedPair[@]} -ne 2 ]; then
|
||||
echo "Parsed '$pair' as ${#separatedPair[@]} parts, expected 2."
|
||||
continue
|
||||
fi
|
||||
originalCmdEnv["${separatedPair[0]}"]="${separatedPair[1]}"
|
||||
done
|
||||
|
||||
# capture CMD environment in a shell with MSVC activated
|
||||
cmdEnv="$(cmd //c "$(unixPathAsWindows "$(dirname "${BASH_SOURCE[0]}")")\ActivateMSVC.bat" "&&" set)"
|
||||
|
||||
declare -A cmdEnvChanges
|
||||
for pair in $cmdEnv; do
|
||||
if [ -n "$pair" ]; then
|
||||
IFS='=' read -r -a separatedPair <<< "${pair}"
|
||||
if [ ${#separatedPair[@]} -ne 2 ]; then
|
||||
echo "Parsed '$pair' as ${#separatedPair[@]} parts, expected 2."
|
||||
continue
|
||||
fi
|
||||
key="${separatedPair[0]}"
|
||||
value="${separatedPair[1]}"
|
||||
if ! [ ${originalCmdEnv[$key]+_} ] || [ "${originalCmdEnv[$key]}" != "$value" ]; then
|
||||
if [ $key != 'PATH' ] && [ $key != 'path' ] && [ $key != 'Path' ]; then
|
||||
export "$key=$value"
|
||||
else
|
||||
export PATH=$(windowsSystemPathAsUnix $value)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
cmd //c "$(unixPathAsWindows "$(dirname "${BASH_SOURCE[0]}")")\ActivateMSVC.bat" "&&" "bash" "-c" "declare -px > declared_env.sh"
|
||||
source ./declared_env.sh
|
||||
rm declared_env.sh
|
||||
|
||||
MISSINGTOOLS=0
|
||||
|
||||
|
@ -93,6 +49,4 @@ if [ $MISSINGTOOLS -ne 0 ]; then
|
|||
return 1
|
||||
fi
|
||||
|
||||
IFS="$originalIFS"
|
||||
|
||||
restoreOldSettings
|
||||
restoreOldSettings
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/sh -ex
|
||||
|
||||
# workaround python issue on travis
|
||||
[-z "${TRAVIS}"] && HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --ignore-dependencies python@3.8 || true
|
||||
[-z "${TRAVIS}"] && HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --ignore-dependencies python@3.9 || true
|
||||
[-z "${TRAVIS}"] && HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --ignore-dependencies qt@6 || true
|
||||
[ -z "${TRAVIS}" ] && HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --ignore-dependencies python@3.8 || true
|
||||
[ -z "${TRAVIS}" ] && HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --ignore-dependencies python@3.9 || true
|
||||
[ -z "${TRAVIS}" ] && HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --ignore-dependencies qt@6 || true
|
||||
|
||||
# Some of these tools can come from places other than brew, so check before installing
|
||||
command -v ccache >/dev/null 2>&1 || brew install ccache
|
||||
|
@ -15,5 +15,8 @@ ccache --version
|
|||
cmake --version
|
||||
qmake --version
|
||||
|
||||
curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-f8918dd.zip -o ~/openmw-deps.zip
|
||||
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20210617.zip -o ~/openmw-deps.zip
|
||||
unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null
|
||||
|
||||
# additional libraries
|
||||
[ -z "${TRAVIS}" ] && HOMEBREW_NO_AUTO_UPDATE=1 brew install fontconfig
|
|
@ -4,9 +4,14 @@ set -xeo pipefail
|
|||
|
||||
free -m
|
||||
|
||||
BUILD_UNITTESTS=OFF
|
||||
BUILD_BENCHMARKS=OFF
|
||||
|
||||
if [[ "${BUILD_TESTS_ONLY}" ]]; then
|
||||
export GOOGLETEST_DIR="${PWD}/googletest/build/install"
|
||||
env GENERATOR='Unix Makefiles' CONFIGURATION=Release CI/build_googletest.sh
|
||||
BUILD_UNITTESTS=ON
|
||||
BUILD_BENCHMARKS=ON
|
||||
fi
|
||||
|
||||
declare -a CMAKE_CONF_OPTS=(
|
||||
|
@ -43,7 +48,8 @@ if [[ "${BUILD_TESTS_ONLY}" ]]; then
|
|||
-DBUILD_ESSIMPORTER=OFF \
|
||||
-DBUILD_OPENCS=OFF \
|
||||
-DBUILD_WIZARD=OFF \
|
||||
-DBUILD_UNITTESTS=ON \
|
||||
-DBUILD_UNITTESTS=${BUILD_UNITTESTS} \
|
||||
-DBUILD_BENCHMARKS=${BUILD_BENCHMARKS} \
|
||||
-DGTEST_ROOT="${GOOGLETEST_DIR}" \
|
||||
-DGMOCK_ROOT="${GOOGLETEST_DIR}" \
|
||||
..
|
||||
|
|
40
CI/before_script.msvc.sh
Normal file → Executable file
40
CI/before_script.msvc.sh
Normal file → Executable file
|
@ -73,10 +73,7 @@ CONFIGURATIONS=()
|
|||
TEST_FRAMEWORK=""
|
||||
GOOGLE_INSTALL_ROOT=""
|
||||
INSTALL_PREFIX="."
|
||||
BULLET_DOUBLE=true
|
||||
BULLET_DBL=""
|
||||
BULLET_DBL_DISPLAY="Single precision"
|
||||
SKIP_VR=""
|
||||
BUILD_BENCHMARKS=""
|
||||
|
||||
ACTIVATE_MSVC=""
|
||||
SINGLE_CONFIG=""
|
||||
|
@ -103,9 +100,6 @@ while [ $# -gt 0 ]; do
|
|||
d )
|
||||
SKIP_DOWNLOAD=true ;;
|
||||
|
||||
D )
|
||||
BULLET_DOUBLE=true ;;
|
||||
|
||||
e )
|
||||
SKIP_EXTRACT=true ;;
|
||||
|
||||
|
@ -143,6 +137,9 @@ while [ $# -gt 0 ]; do
|
|||
INSTALL_PREFIX=$(echo "$1" | sed 's;\\;/;g' | sed -E 's;/+;/;g')
|
||||
shift ;;
|
||||
|
||||
b )
|
||||
BUILD_BENCHMARKS=true ;;
|
||||
|
||||
h )
|
||||
cat <<EOF
|
||||
Usage: $0 [-cdehkpuvVi]
|
||||
|
@ -153,8 +150,6 @@ Options:
|
|||
For single-config generators, several configurations can be set up at once by specifying -c multiple times.
|
||||
-d
|
||||
Skip checking the downloads.
|
||||
-D
|
||||
Use double-precision Bullet
|
||||
-e
|
||||
Skip extracting dependencies.
|
||||
-h
|
||||
|
@ -179,6 +174,8 @@ Options:
|
|||
Run verbosely
|
||||
-i
|
||||
CMake install prefix
|
||||
-b
|
||||
Build benchmarks
|
||||
EOF
|
||||
wrappedExit 0
|
||||
;;
|
||||
|
@ -437,9 +434,6 @@ if [ -n "$SINGLE_CONFIG" ]; then
|
|||
if [ -n "$SKIP_DOWNLOAD" ]; then
|
||||
RECURSIVE_OPTIONS+=("-d")
|
||||
fi
|
||||
if [ -n "$BULLET_DOUBLE" ]; then
|
||||
RECURSIVE_OPTIONS+=("-D")
|
||||
fi
|
||||
if [ -n "$SKIP_EXTRACT" ]; then
|
||||
RECURSIVE_OPTIONS+=("-e")
|
||||
fi
|
||||
|
@ -512,12 +506,6 @@ if ! [ -z $UNITY_BUILD ]; then
|
|||
add_cmake_opts "-DOPENMW_UNITY_BUILD=True"
|
||||
fi
|
||||
|
||||
if [ -n "$BULLET_DOUBLE" ]; then
|
||||
BULLET_DBL="-double"
|
||||
BULLET_DBL_DISPLAY="Double precision"
|
||||
add_cmake_opts "-DBULLET_USE_DOUBLES=True"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "==================================="
|
||||
echo "Starting prebuild on MSVC${MSVC_DISPLAY_YEAR} WIN${BITS}"
|
||||
|
@ -542,9 +530,9 @@ if [ -z $SKIP_DOWNLOAD ]; then
|
|||
fi
|
||||
|
||||
# Bullet
|
||||
download "Bullet 2.89 (${BULLET_DBL_DISPLAY})" \
|
||||
"https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" \
|
||||
"Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z"
|
||||
download "Bullet 2.89" \
|
||||
"https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}-double.7z" \
|
||||
"Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}-double.7z"
|
||||
|
||||
# FFmpeg
|
||||
download "FFmpeg 4.2.2" \
|
||||
|
@ -684,15 +672,15 @@ fi
|
|||
cd $DEPS
|
||||
echo
|
||||
# Bullet
|
||||
printf "Bullet 2.89 (${BULLET_DBL_DISPLAY})... "
|
||||
printf "Bullet 2.89... "
|
||||
{
|
||||
cd $DEPS_INSTALL
|
||||
if [ -d Bullet ]; then
|
||||
printf -- "Exists. (No version checking) "
|
||||
elif [ -z $SKIP_EXTRACT ]; then
|
||||
rm -rf Bullet
|
||||
eval 7z x -y "${DEPS}/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" $STRIP
|
||||
mv "Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}" Bullet
|
||||
eval 7z x -y "${DEPS}/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}-double.7z" $STRIP
|
||||
mv "Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}-double" Bullet
|
||||
fi
|
||||
add_cmake_opts -DBULLET_ROOT="$(real_pwd)/Bullet"
|
||||
echo Done.
|
||||
|
@ -1106,6 +1094,10 @@ fi
|
|||
done
|
||||
#fi
|
||||
|
||||
if [ "${BUILD_BENCHMARKS}" ]; then
|
||||
add_cmake_opts -DBUILD_BENCHMARKS=ON
|
||||
fi
|
||||
|
||||
if [ -n "$ACTIVATE_MSVC" ]; then
|
||||
echo -n "- Activating MSVC in the current shell... "
|
||||
command -v vswhere >/dev/null 2>&1 || { echo "Error: vswhere is not on the path."; wrappedExit 1; }
|
||||
|
|
|
@ -25,6 +25,5 @@ cmake \
|
|||
-D BUILD_BSATOOL=TRUE \
|
||||
-D BUILD_ESSIMPORTER=TRUE \
|
||||
-D BUILD_NIFTEST=TRUE \
|
||||
-D BULLET_USE_DOUBLES=TRUE \
|
||||
-G"Unix Makefiles" \
|
||||
..
|
||||
|
|
|
@ -21,14 +21,13 @@ declare -rA GROUPED_DEPS=(
|
|||
|
||||
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
|
||||
libsdl2-dev libqt5opengl5-dev libopenal-dev libunshield-dev libtinyxml-dev
|
||||
libbullet-dev liblz4-dev libpng-dev libjpeg-dev
|
||||
libxcb-glx0-dev libx11-dev
|
||||
libbullet-dev liblz4-dev libpng-dev libjpeg-dev
|
||||
ca-certificates
|
||||
"
|
||||
# TODO: add librecastnavigation-dev when debian is ready
|
||||
|
||||
# These dependencies can alternatively be built and linked statically.
|
||||
[openmw-deps-dynamic]="libmygui-dev libopenscenegraph-dev"
|
||||
|
||||
[coverity]="curl"
|
||||
|
||||
# Pre-requisites for building MyGUI and OSG for static linking.
|
||||
|
@ -65,4 +64,4 @@ export APT_CACHE_DIR="${PWD}/apt-cache"
|
|||
set -x
|
||||
mkdir -pv "$APT_CACHE_DIR"
|
||||
apt-get update -yq
|
||||
apt-get -q -o dir::cache::archives="$APT_CACHE_DIR" install -y "${deps[@]}"
|
||||
apt-get -q -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends "${deps[@]}"
|
||||
|
|
129
CMakeLists.txt
129
CMakeLists.txt
|
@ -13,9 +13,6 @@ if(POLICY CMP0083)
|
|||
cmake_policy(SET CMP0083 NEW)
|
||||
endif()
|
||||
|
||||
# Detect OS
|
||||
include(cmake/OSIdentity.cmake)
|
||||
|
||||
option(OPENMW_GL4ES_MANUAL_INIT "Manually initialize gl4es. This is more reliable on platforms without a windowing system. Requires gl4es to be configured with -DNOEGL=ON -DNO_LOADER=ON -DNO_INIT_CONSTRUCTOR=ON." OFF)
|
||||
if(OPENMW_GL4ES_MANUAL_INIT)
|
||||
add_definitions(-DOPENMW_GL4ES_MANUAL_INIT)
|
||||
|
@ -35,7 +32,7 @@ option(BUILD_DOCS "Build documentation." OFF )
|
|||
option(BUILD_OPENMW_VR "Build VR support using OpenXR" ON)
|
||||
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
|
||||
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest" OFF)
|
||||
option(BULLET_USE_DOUBLES "Use double precision for Bullet" ON)
|
||||
option(BUILD_BENCHMARKS "Build benchmarks with Google Benchmark" OFF)
|
||||
|
||||
set(OpenGL_GL_PREFERENCE LEGACY) # Use LEGACY as we use GL2; GLNVD is for GL3 and up.
|
||||
|
||||
|
@ -265,16 +262,16 @@ if(FFmpeg_FOUND)
|
|||
set(FFVER_OK FALSE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT FFVER_OK AND NOT APPLE) # unable to detect on version on MacOS < 11.0
|
||||
message(FATAL_ERROR "FFmpeg version is too old, 3.2 is required" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT FFmpeg_FOUND)
|
||||
message(FATAL_ERROR "FFmpeg was not found" )
|
||||
endif()
|
||||
|
||||
if(NOT FFVER_OK)
|
||||
message(FATAL_ERROR "FFmpeg version is too old, 3.2 is required" )
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
message("Can not detect FFmpeg version, at least the 3.2 is required" )
|
||||
endif()
|
||||
|
@ -313,7 +310,31 @@ if(OPENMW_USE_SYSTEM_BULLET)
|
|||
set(REQUIRED_BULLET_VERSION 283) # but for build testing, 283 is fine
|
||||
endif()
|
||||
|
||||
find_package(Bullet ${REQUIRED_BULLET_VERSION} REQUIRED COMPONENTS BulletCollision LinearMath)
|
||||
# First, try BulletConfig-float64.cmake which comes with Debian derivatives.
|
||||
# This file does not define the Bullet version in a CMake-friendly way.
|
||||
find_package(Bullet CONFIGS BulletConfig-float64.cmake QUIET COMPONENTS BulletCollision LinearMath)
|
||||
if (BULLET_FOUND)
|
||||
string(REPLACE "." "" _bullet_version_num ${BULLET_VERSION_STRING})
|
||||
if (_bullet_version_num VERSION_LESS REQUIRED_BULLET_VERSION)
|
||||
message(FATAL_ERROR "System bullet version too old, OpenMW requires at least ${REQUIRED_BULLET_VERSION}, got ${_bullet_version_num}")
|
||||
endif()
|
||||
# Fix the relative include:
|
||||
set(BULLET_INCLUDE_DIRS "${BULLET_ROOT_DIR}/${BULLET_INCLUDE_DIRS}")
|
||||
include(FindPackageMessage)
|
||||
find_package_message(Bullet "Found Bullet: ${BULLET_LIBRARIES} ${BULLET_VERSION_STRING}" "${BULLET_VERSION_STRING}-float64")
|
||||
else()
|
||||
find_package(Bullet ${REQUIRED_BULLET_VERSION} REQUIRED COMPONENTS BulletCollision LinearMath)
|
||||
endif()
|
||||
|
||||
# Only link the Bullet libraries that we need:
|
||||
string(REGEX MATCHALL "((optimized|debug);)?[^;]*(BulletCollision|LinearMath)[^;]*" BULLET_LIBRARIES "${BULLET_LIBRARIES}")
|
||||
|
||||
include(cmake/CheckBulletPrecision.cmake)
|
||||
if (HAS_DOUBLE_PRECISION_BULLET)
|
||||
message(STATUS "Bullet uses double precision")
|
||||
else()
|
||||
message(FATAL_ERROR "Bullet does not uses double precision")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT WIN32 AND BUILD_WIZARD) # windows users can just run the morrowind installer
|
||||
|
@ -342,6 +363,11 @@ endif()
|
|||
|
||||
if(OPENMW_USE_SYSTEM_OSG)
|
||||
find_package(OpenSceneGraph ${OSG_VERSION_REQUIRED} REQUIRED ${USED_OSG_COMPONENTS})
|
||||
|
||||
if (${OPENSCENEGRAPH_VERSION} VERSION_GREATER 3.6.2 AND ${OPENSCENEGRAPH_VERSION} VERSION_LESS 3.6.5)
|
||||
message(FATAL_ERROR "OpenSceneGraph version ${OPENSCENEGRAPH_VERSION} has critical regressions which cause crashes. Please upgrade to 3.6.5 or later. We strongly recommend using the tip of the official 'OpenSceneGraph-3.6' branch or the tip of '3.6' OpenMW/osg (OSGoS).")
|
||||
endif()
|
||||
|
||||
if(OSG_STATIC)
|
||||
find_package(OSGPlugins REQUIRED COMPONENTS ${USED_OSG_PLUGINS})
|
||||
endif()
|
||||
|
@ -424,8 +450,8 @@ endif (APPLE)
|
|||
|
||||
# Other files
|
||||
|
||||
configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
|
||||
"${OpenMW_BINARY_DIR}" "settings-default.cfg")
|
||||
pack_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
|
||||
"${OpenMW_BINARY_DIR}" "defaults.bin")
|
||||
|
||||
configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-overrides-vr.cfg
|
||||
"${OpenMW_BINARY_DIR}" "settings-overrides-vr.cfg")
|
||||
|
@ -443,8 +469,8 @@ else ()
|
|||
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||
endif ()
|
||||
|
||||
configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw-cs.cfg
|
||||
"${OpenMW_BINARY_DIR}" "openmw-cs.cfg")
|
||||
pack_resource_file(${OpenMW_SOURCE_DIR}/files/openmw-cs.cfg
|
||||
"${OpenMW_BINARY_DIR}" "defaults-cs.bin")
|
||||
|
||||
# Needs the copy version because the configure version assumes the end of the file has been reached when a null character is reached and there are no CMake expressions to evaluate.
|
||||
copy_resource_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters
|
||||
|
@ -499,16 +525,13 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
|||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.6 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.6)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-parameter")
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 5.0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override")
|
||||
endif()
|
||||
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
|
||||
# Extern
|
||||
|
||||
add_subdirectory (extern/osg-ffmpeg-videoplayer)
|
||||
add_subdirectory (extern/oics)
|
||||
add_subdirectory (extern/Base64)
|
||||
if (BUILD_OPENCS)
|
||||
add_subdirectory (extern/osgQt)
|
||||
endif()
|
||||
|
@ -559,6 +582,10 @@ if (BUILD_UNITTESTS)
|
|||
add_subdirectory( apps/openmw_test_suite )
|
||||
endif()
|
||||
|
||||
if (BUILD_BENCHMARKS)
|
||||
add_subdirectory(apps/benchmarks)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (MSVC)
|
||||
if (OPENMW_MP_BUILD)
|
||||
|
@ -606,63 +633,13 @@ if (WIN32)
|
|||
|
||||
# Play a bit with the warning levels
|
||||
|
||||
set(WARNINGS "/Wall") # Since windows can only disable specific warnings, not enable them
|
||||
set(WARNINGS "/W4")
|
||||
|
||||
set(WARNINGS_DISABLE
|
||||
# Warnings that aren't enabled normally and don't need to be enabled
|
||||
# They're unneeded and sometimes completely retarded warnings that /Wall enables
|
||||
# Not going to bother commenting them as they tend to warn on every standard library file
|
||||
4061 4263 4264 4266 4350 4371 4435 4514 4548 4571 4582 4583 4610 4619 4623 4625
|
||||
4626 4628 4640 4668 4710 4711 4768 4820 4826 4917 4946 5032 5039 5045 5219 5220
|
||||
|
||||
# Warnings that are thrown on standard libraries and not OpenMW
|
||||
4347 # Non-template function with same name and parameter count as template function
|
||||
4365 # Variable signed/unsigned mismatch
|
||||
4510 4512 # Unable to generate copy constructor/assignment operator as it's not public in the base
|
||||
4706 # Assignment in conditional expression
|
||||
4738 # Storing 32-bit float result in memory, possible loss of performance
|
||||
4774 # Format string expected in argument is not a string literal
|
||||
4986 # Undocumented warning that occurs in the crtdbg.h file
|
||||
4987 # nonstandard extension used (triggered by setjmp.h)
|
||||
4996 # Function was declared deprecated
|
||||
|
||||
# caused by OSG
|
||||
4589 # Constructor of abstract class 'osg::Operation' ignores initializer for virtual base class 'osg::Referenced' (False warning)
|
||||
|
||||
# caused by boost
|
||||
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
|
||||
4643 # Forward declaring 'X' in namespace std is not permitted by the C++ Standard. (in *_std_fwd.h files)
|
||||
5204 # Class has virtual functions, but its trivial destructor is not virtual
|
||||
|
||||
# caused by MyGUI
|
||||
4297 # function assumed not to throw an exception but does
|
||||
|
||||
# OpenMW specific warnings
|
||||
4099 # Type mismatch, declared class or struct is defined with other type
|
||||
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
||||
4101 # Unreferenced local variable (-Wunused-variable)
|
||||
4127 # Conditional expression is constant
|
||||
4242 # Storing value in a variable of a smaller type, possible loss of data
|
||||
4244 # Storing value of one type in variable of another (size_t in int, for example)
|
||||
4245 # Signed/unsigned mismatch
|
||||
4267 # Conversion from 'size_t' to 'int', possible loss of data
|
||||
4305 # Truncating value (double to float, for example)
|
||||
4309 # Variable overflow, trying to store 128 in a signed char for example
|
||||
4351 # New behavior: elements of array 'array' will be default initialized (desired behavior)
|
||||
4355 # Using 'this' in member initialization list
|
||||
4464 # relative include path contains '..'
|
||||
4505 # Unreferenced local function has been removed
|
||||
4701 # Potentially uninitialized local variable used
|
||||
4702 # Unreachable code
|
||||
4714 # function 'QString QString::trimmed(void) &&' marked as __forceinline not inlined
|
||||
4800 # Boolean optimization warning, e.g. myBool = (myInt != 0) instead of myBool = myInt
|
||||
4996 # Function was declared deprecated
|
||||
)
|
||||
|
||||
if (MSVC_VERSION GREATER 1800)
|
||||
set(WARNINGS_DISABLE ${WARNINGS_DISABLE} 5026 5027
|
||||
5031 # #pragma warning(pop): likely mismatch, popping warning state pushed in different file (config_begin.hpp, config_end.hpp)
|
||||
)
|
||||
endif()
|
||||
|
||||
if( "${MyGUI_VERSION}" VERSION_LESS_EQUAL "3.4.0" )
|
||||
set(WARNINGS_DISABLE ${WARNINGS_DISABLE}
|
||||
|
@ -730,6 +707,10 @@ if (WIN32)
|
|||
if (BUILD_WIZARD)
|
||||
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_BENCHMARKS)
|
||||
set_target_properties(openmw_detournavigator_navmeshtilescache_benchmark PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
endif(MSVC)
|
||||
|
||||
# TODO: At some point release builds should not use the console but rather write to a log file
|
||||
|
@ -869,7 +850,7 @@ elseif(NOT APPLE)
|
|||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt")
|
||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt")
|
||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/defaults.bin" DESTINATION ".")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/xrcontrollersuggestions.xml" DESTINATION ".")
|
||||
|
||||
|
@ -912,13 +893,13 @@ elseif(NOT APPLE)
|
|||
SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
|
||||
if(EXISTS ${VCREDIST32})
|
||||
INSTALL(FILES ${VCREDIST32} DESTINATION "redist")
|
||||
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q'" )
|
||||
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q /norestart'" )
|
||||
endif(EXISTS ${VCREDIST32})
|
||||
|
||||
SET(VCREDIST64 "${OpenMW_BINARY_DIR}/vcredist_x64.exe")
|
||||
if(EXISTS ${VCREDIST64})
|
||||
INSTALL(FILES ${VCREDIST64} DESTINATION "redist")
|
||||
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q'" )
|
||||
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q /norestart'" )
|
||||
endif(EXISTS ${VCREDIST64})
|
||||
|
||||
SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe")
|
||||
|
@ -978,14 +959,14 @@ elseif(NOT APPLE)
|
|||
ENDIF(BUILD_OPENCS)
|
||||
|
||||
# Install global configuration files
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/defaults.bin" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/xrcontrollersuggestions.xml" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/defaults-cs.bin" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
|
||||
ENDIF(BUILD_OPENCS)
|
||||
|
||||
# Install resources
|
||||
|
|
|
@ -12,7 +12,7 @@ OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
|
|||
* Version: 0.47.0
|
||||
* License: GPLv3 (see [LICENSE](https://github.com/OpenMW/openmw/blob/master/LICENSE) for more information)
|
||||
* Website: https://www.openmw.org
|
||||
* IRC: #openmw on irc.freenode.net
|
||||
* IRC: #openmw on irc.libera.chat
|
||||
|
||||
Font Licenses:
|
||||
* DejaVuLGCSansMono.ttf: custom (see [files/mygui/DejaVuFontLicense.txt](https://github.com/OpenMW/openmw/blob/master/files/mygui/DejaVuFontLicense.txt) for more information)
|
||||
|
|
27
apps/benchmarks/CMakeLists.txt
Normal file
27
apps/benchmarks/CMakeLists.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
set(BENCHMARK_ENABLE_TESTING OFF)
|
||||
set(BENCHMARK_ENABLE_INSTALL OFF)
|
||||
set(BENCHMARK_ENABLE_GTEST_TESTS OFF)
|
||||
|
||||
set(SAVED_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
string(REPLACE "-Wsuggest-override" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "-Wundef" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(benchmark
|
||||
URL https://github.com/google/benchmark/archive/refs/tags/v1.5.2.zip
|
||||
URL_HASH MD5=49395b757a7c4656d70f1328d93efd00
|
||||
SOURCE_DIR fetched/benchmark
|
||||
)
|
||||
FetchContent_MakeAvailableExcludeFromAll(benchmark)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${SAVED_CMAKE_CXX_FLAGS}")
|
||||
|
||||
openmw_add_executable(openmw_detournavigator_navmeshtilescache_benchmark detournavigator/navmeshtilescache.cpp)
|
||||
target_compile_features(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE cxx_std_17)
|
||||
target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark benchmark::benchmark components)
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
214
apps/benchmarks/detournavigator/navmeshtilescache.cpp
Normal file
214
apps/benchmarks/detournavigator/navmeshtilescache.cpp
Normal file
|
@ -0,0 +1,214 @@
|
|||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <components/detournavigator/navmeshtilescache.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace DetourNavigator;
|
||||
|
||||
struct Key
|
||||
{
|
||||
osg::Vec3f mAgentHalfExtents;
|
||||
TilePosition mTilePosition;
|
||||
RecastMesh mRecastMesh;
|
||||
std::vector<OffMeshConnection> mOffMeshConnections;
|
||||
};
|
||||
|
||||
struct Item
|
||||
{
|
||||
Key mKey;
|
||||
NavMeshData mValue;
|
||||
};
|
||||
|
||||
template <typename Random>
|
||||
TilePosition generateTilePosition(int max, Random& random)
|
||||
{
|
||||
std::uniform_int_distribution<int> distribution(0, max);
|
||||
return TilePosition(distribution(random), distribution(random));
|
||||
}
|
||||
|
||||
template <typename Random>
|
||||
osg::Vec3f generateAgentHalfExtents(float min, float max, Random& random)
|
||||
{
|
||||
std::uniform_int_distribution<int> distribution(min, max);
|
||||
return osg::Vec3f(distribution(random), distribution(random), distribution(random));
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void generateVertices(OutputIterator out, std::size_t number, Random& random)
|
||||
{
|
||||
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||
std::generate_n(out, 3 * (number - number % 3), [&] { return distribution(random); });
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void generateIndices(OutputIterator out, int max, std::size_t number, Random& random)
|
||||
{
|
||||
std::uniform_int_distribution<int> distribution(0, max);
|
||||
std::generate_n(out, number - number % 3, [&] { return distribution(random); });
|
||||
}
|
||||
|
||||
AreaType toAreaType(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return AreaType_null;
|
||||
case 1: return AreaType_water;
|
||||
case 2: return AreaType_door;
|
||||
case 3: return AreaType_pathgrid;
|
||||
case 4: return AreaType_ground;
|
||||
}
|
||||
return AreaType_null;
|
||||
}
|
||||
|
||||
template <typename Random>
|
||||
AreaType generateAreaType(Random& random)
|
||||
{
|
||||
std::uniform_int_distribution<int> distribution(0, 4);
|
||||
return toAreaType(distribution(random));;
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void generateAreaTypes(OutputIterator out, std::size_t triangles, Random& random)
|
||||
{
|
||||
std::generate_n(out, triangles, [&] { return generateAreaType(random); });
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void generateWater(OutputIterator out, std::size_t count, Random& random)
|
||||
{
|
||||
std::uniform_real_distribution<btScalar> distribution(0.0, 1.0);
|
||||
std::generate_n(out, count, [&] {
|
||||
const btVector3 shift(distribution(random), distribution(random), distribution(random));
|
||||
return RecastMesh::Water {1, btTransform(btMatrix3x3::getIdentity(), shift)};
|
||||
});
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void generateOffMeshConnection(OutputIterator out, std::size_t count, Random& random)
|
||||
{
|
||||
std::uniform_real_distribution<btScalar> distribution(0.0, 1.0);
|
||||
std::generate_n(out, count, [&] {
|
||||
const osg::Vec3f start(distribution(random), distribution(random), distribution(random));
|
||||
const osg::Vec3f end(distribution(random), distribution(random), distribution(random));
|
||||
return OffMeshConnection {start, end, generateAreaType(random)};
|
||||
});
|
||||
}
|
||||
|
||||
template <class Random>
|
||||
Key generateKey(std::size_t triangles, Random& random)
|
||||
{
|
||||
const osg::Vec3f agentHalfExtents = generateAgentHalfExtents(0.5, 1.5, random);
|
||||
const TilePosition tilePosition = generateTilePosition(10000, random);
|
||||
const std::size_t generation = std::uniform_int_distribution<std::size_t>(0, 100)(random);
|
||||
const std::size_t revision = std::uniform_int_distribution<std::size_t>(0, 10000)(random);
|
||||
std::vector<float> vertices;
|
||||
generateVertices(std::back_inserter(vertices), triangles * 1.98, random);
|
||||
std::vector<int> indices;
|
||||
generateIndices(std::back_inserter(indices), static_cast<int>(vertices.size() / 3) - 1, vertices.size() * 1.53, random);
|
||||
std::vector<AreaType> areaTypes;
|
||||
generateAreaTypes(std::back_inserter(areaTypes), indices.size() / 3, random);
|
||||
std::vector<RecastMesh::Water> water;
|
||||
generateWater(std::back_inserter(water), 2, random);
|
||||
RecastMesh recastMesh(generation, revision, std::move(indices), std::move(vertices),
|
||||
std::move(areaTypes), std::move(water));
|
||||
std::vector<OffMeshConnection> offMeshConnections;
|
||||
generateOffMeshConnection(std::back_inserter(offMeshConnections), 300, random);
|
||||
return Key {agentHalfExtents, tilePosition, std::move(recastMesh), std::move(offMeshConnections)};
|
||||
}
|
||||
|
||||
constexpr std::size_t trianglesPerTile = 310;
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void generateKeys(OutputIterator out, std::size_t count, Random& random)
|
||||
{
|
||||
std::generate_n(out, count, [&] { return generateKey(trianglesPerTile, random); });
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Random>
|
||||
void fillCache(OutputIterator out, Random& random, NavMeshTilesCache& cache)
|
||||
{
|
||||
std::size_t size = cache.getStats().mNavMeshCacheSize;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Key key = generateKey(trianglesPerTile, random);
|
||||
cache.set(key.mAgentHalfExtents, key.mTilePosition, key.mRecastMesh, key.mOffMeshConnections, NavMeshData());
|
||||
*out++ = std::move(key);
|
||||
const std::size_t newSize = cache.getStats().mNavMeshCacheSize;
|
||||
if (size >= newSize)
|
||||
break;
|
||||
size = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t maxCacheSize, int hitPercentage>
|
||||
void getFromFilledCache(benchmark::State& state)
|
||||
{
|
||||
NavMeshTilesCache cache(maxCacheSize);
|
||||
std::minstd_rand random;
|
||||
std::vector<Key> keys;
|
||||
fillCache(std::back_inserter(keys), random, cache);
|
||||
generateKeys(std::back_inserter(keys), keys.size() * (100 - hitPercentage) / 100, random);
|
||||
std::size_t n = 0;
|
||||
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
const auto& key = keys[n++ % keys.size()];
|
||||
const auto result = cache.get(key.mAgentHalfExtents, key.mTilePosition, key.mRecastMesh, key.mOffMeshConnections);
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto getFromFilledCache_1m_100hit = getFromFilledCache<1 * 1024 * 1024, 100>;
|
||||
constexpr auto getFromFilledCache_4m_100hit = getFromFilledCache<4 * 1024 * 1024, 100>;
|
||||
constexpr auto getFromFilledCache_16m_100hit = getFromFilledCache<16 * 1024 * 1024, 100>;
|
||||
constexpr auto getFromFilledCache_64m_100hit = getFromFilledCache<64 * 1024 * 1024, 100>;
|
||||
constexpr auto getFromFilledCache_1m_70hit = getFromFilledCache<1 * 1024 * 1024, 70>;
|
||||
constexpr auto getFromFilledCache_4m_70hit = getFromFilledCache<4 * 1024 * 1024, 70>;
|
||||
constexpr auto getFromFilledCache_16m_70hit = getFromFilledCache<16 * 1024 * 1024, 70>;
|
||||
constexpr auto getFromFilledCache_64m_70hit = getFromFilledCache<64 * 1024 * 1024, 70>;
|
||||
|
||||
template <std::size_t maxCacheSize>
|
||||
void setToBoundedNonEmptyCache(benchmark::State& state)
|
||||
{
|
||||
NavMeshTilesCache cache(maxCacheSize);
|
||||
std::minstd_rand random;
|
||||
std::vector<Key> keys;
|
||||
fillCache(std::back_inserter(keys), random, cache);
|
||||
generateKeys(std::back_inserter(keys), keys.size() * 2, random);
|
||||
std::reverse(keys.begin(), keys.end());
|
||||
std::size_t n = 0;
|
||||
|
||||
while (state.KeepRunning())
|
||||
{
|
||||
const auto& key = keys[n++ % keys.size()];
|
||||
const auto result = cache.set(key.mAgentHalfExtents, key.mTilePosition, key.mRecastMesh, key.mOffMeshConnections, NavMeshData());
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto setToBoundedNonEmptyCache_1m = setToBoundedNonEmptyCache<1 * 1024 * 1024>;
|
||||
constexpr auto setToBoundedNonEmptyCache_4m = setToBoundedNonEmptyCache<4 * 1024 * 1024>;
|
||||
constexpr auto setToBoundedNonEmptyCache_16m = setToBoundedNonEmptyCache<16 * 1024 * 1024>;
|
||||
constexpr auto setToBoundedNonEmptyCache_64m = setToBoundedNonEmptyCache<64 * 1024 * 1024>;
|
||||
} // namespace
|
||||
|
||||
BENCHMARK(getFromFilledCache_1m_100hit);
|
||||
BENCHMARK(getFromFilledCache_4m_100hit);
|
||||
BENCHMARK(getFromFilledCache_16m_100hit);
|
||||
BENCHMARK(getFromFilledCache_64m_100hit);
|
||||
BENCHMARK(getFromFilledCache_1m_70hit);
|
||||
BENCHMARK(getFromFilledCache_4m_70hit);
|
||||
BENCHMARK(getFromFilledCache_16m_70hit);
|
||||
BENCHMARK(getFromFilledCache_64m_70hit);
|
||||
BENCHMARK(setToBoundedNonEmptyCache_1m);
|
||||
BENCHMARK(setToBoundedNonEmptyCache_4m);
|
||||
BENCHMARK(setToBoundedNonEmptyCache_16m);
|
||||
BENCHMARK(setToBoundedNonEmptyCache_64m);
|
||||
|
||||
BENCHMARK_MAIN();
|
|
@ -2,6 +2,7 @@
|
|||
#include <vector>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
|
@ -322,7 +323,7 @@ int load(Arguments& info)
|
|||
std::string filename = info.filename;
|
||||
std::cout << "Loading file: " << filename << std::endl;
|
||||
|
||||
std::list<uint32_t> skipped;
|
||||
std::unordered_set<uint32_t> skipped;
|
||||
|
||||
try {
|
||||
|
||||
|
@ -364,17 +365,17 @@ int load(Arguments& info)
|
|||
// Loop through all records
|
||||
while(esm.hasMoreRecs())
|
||||
{
|
||||
ESM::NAME n = esm.getRecName();
|
||||
const ESM::NAME n = esm.getRecName();
|
||||
uint32_t flags;
|
||||
esm.getRecHeader(flags);
|
||||
|
||||
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
|
||||
if (record == nullptr)
|
||||
{
|
||||
if (std::find(skipped.begin(), skipped.end(), n.intval) == skipped.end())
|
||||
if (skipped.count(n.intval) == 0)
|
||||
{
|
||||
std::cout << "Skipping " << n.toString() << " records." << std::endl;
|
||||
skipped.push_back(n.intval);
|
||||
skipped.emplace(n.intval);
|
||||
}
|
||||
|
||||
esm.skipRecord();
|
||||
|
|
|
@ -172,7 +172,7 @@ void printTransport(const std::vector<ESM::Transport::Dest>& transport)
|
|||
namespace EsmTool {
|
||||
|
||||
RecordBase *
|
||||
RecordBase::create(ESM::NAME type)
|
||||
RecordBase::create(const ESM::NAME type)
|
||||
{
|
||||
RecordBase *record = nullptr;
|
||||
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
#include <array>
|
||||
|
||||
#include <components/config/gamesettings.hpp>
|
||||
#include <components/config/launchersettings.hpp>
|
||||
#include <QFileDialog>
|
||||
#include <QCompleter>
|
||||
#include <QProxyStyle>
|
||||
#include <QString>
|
||||
#include <components/contentselector/view/contentselector.hpp>
|
||||
#include <components/contentselector/model/esmfile.hpp>
|
||||
|
@ -15,11 +13,9 @@
|
|||
|
||||
#include "utils/openalutil.hpp"
|
||||
|
||||
Launcher::AdvancedPage::AdvancedPage(Config::GameSettings &gameSettings,
|
||||
Settings::Manager &engineSettings, QWidget *parent)
|
||||
Launcher::AdvancedPage::AdvancedPage(Config::GameSettings &gameSettings, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mGameSettings(gameSettings)
|
||||
, mEngineSettings(engineSettings)
|
||||
{
|
||||
setObjectName ("AdvancedPage");
|
||||
setupUi(this);
|
||||
|
@ -102,12 +98,12 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game");
|
||||
loadSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game");
|
||||
loadSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game");
|
||||
int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game");
|
||||
int unarmedFactorsStrengthIndex = Settings::Manager::getInt("strength influences hand to hand", "Game");
|
||||
if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2)
|
||||
unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex);
|
||||
loadSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game");
|
||||
loadSettingBool(enableNavigatorCheckBox, "enable", "Navigator");
|
||||
int numPhysicsThreads = mEngineSettings.getInt("async num threads", "Physics");
|
||||
int numPhysicsThreads = Settings::Manager::getInt("async num threads", "Physics");
|
||||
if (numPhysicsThreads >= 0)
|
||||
physicsThreadsSpinBox->setValue(numPhysicsThreads);
|
||||
loadSettingBool(allowNPCToFollowOverWaterSurfaceCheckBox, "allow actors to follow over water surface", "Game");
|
||||
|
@ -132,26 +128,20 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game");
|
||||
loadSettingBool(smoothMovementCheckBox, "smooth movement", "Game");
|
||||
|
||||
const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain");
|
||||
const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain");
|
||||
const bool distantTerrain = Settings::Manager::getBool("distant terrain", "Terrain");
|
||||
const bool objectPaging = Settings::Manager::getBool("object paging", "Terrain");
|
||||
if (distantTerrain && objectPaging) {
|
||||
distantLandCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
|
||||
loadSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain");
|
||||
viewingDistanceComboBox->setValue(convertToCells(mEngineSettings.getInt("viewing distance", "Camera")));
|
||||
|
||||
int lightingMethod = 1;
|
||||
if (mEngineSettings.getString("lighting method", "Shaders") == "legacy")
|
||||
lightingMethod = 0;
|
||||
else if (mEngineSettings.getString("lighting method", "Shaders") == "shaders")
|
||||
lightingMethod = 2;
|
||||
lightingMethodComboBox->setCurrentIndex(lightingMethod);
|
||||
viewingDistanceComboBox->setValue(convertToCells(Settings::Manager::getInt("viewing distance", "Camera")));
|
||||
objectPagingMinSizeComboBox->setValue(Settings::Manager::getDouble("object paging min size", "Terrain"));
|
||||
}
|
||||
|
||||
// Audio
|
||||
{
|
||||
std::string selectedAudioDevice = mEngineSettings.getString("device", "Sound");
|
||||
std::string selectedAudioDevice = Settings::Manager::getString("device", "Sound");
|
||||
if (selectedAudioDevice.empty() == false)
|
||||
{
|
||||
int audioDeviceIndex = audioDeviceSelectorComboBox->findData(QString::fromStdString(selectedAudioDevice));
|
||||
|
@ -160,12 +150,12 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
audioDeviceSelectorComboBox->setCurrentIndex(audioDeviceIndex);
|
||||
}
|
||||
}
|
||||
int hrtfEnabledIndex = mEngineSettings.getInt("hrtf enable", "Sound");
|
||||
int hrtfEnabledIndex = Settings::Manager::getInt("hrtf enable", "Sound");
|
||||
if (hrtfEnabledIndex >= -1 && hrtfEnabledIndex <= 1)
|
||||
{
|
||||
enableHRTFComboBox->setCurrentIndex(hrtfEnabledIndex + 1);
|
||||
}
|
||||
std::string selectedHRTFProfile = mEngineSettings.getString("hrtf", "Sound");
|
||||
std::string selectedHRTFProfile = Settings::Manager::getString("hrtf", "Sound");
|
||||
if (selectedHRTFProfile.empty() == false)
|
||||
{
|
||||
int hrtfProfileIndex = hrtfProfileSelectorComboBox->findData(QString::fromStdString(selectedHRTFProfile));
|
||||
|
@ -187,7 +177,7 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera");
|
||||
loadSettingBool(headBobbingCheckBox, "head bobbing", "Camera");
|
||||
defaultShoulderComboBox->setCurrentIndex(
|
||||
mEngineSettings.getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1);
|
||||
Settings::Manager::getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1);
|
||||
}
|
||||
|
||||
// Interface Changes
|
||||
|
@ -197,13 +187,13 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
|
||||
loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
|
||||
loadSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI");
|
||||
int showOwnedIndex = mEngineSettings.getInt("show owned", "Game");
|
||||
int showOwnedIndex = Settings::Manager::getInt("show owned", "Game");
|
||||
// Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid.
|
||||
if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
|
||||
showOwnedComboBox->setCurrentIndex(showOwnedIndex);
|
||||
loadSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI");
|
||||
loadSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game");
|
||||
scalingSpinBox->setValue(mEngineSettings.getFloat("scaling factor", "GUI"));
|
||||
scalingSpinBox->setValue(Settings::Manager::getFloat("scaling factor", "GUI"));
|
||||
}
|
||||
|
||||
// Bug fixes
|
||||
|
@ -216,10 +206,10 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
{
|
||||
// Saves
|
||||
loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
|
||||
maximumQuicksavesComboBox->setValue(mEngineSettings.getInt("max quicksaves", "Saves"));
|
||||
maximumQuicksavesComboBox->setValue(Settings::Manager::getInt("max quicksaves", "Saves"));
|
||||
|
||||
// Other Settings
|
||||
QString screenshotFormatString = QString::fromStdString(mEngineSettings.getString("screenshot format", "General")).toUpper();
|
||||
QString screenshotFormatString = QString::fromStdString(Settings::Manager::getString("screenshot format", "General")).toUpper();
|
||||
if (screenshotFormatComboBox->findText(screenshotFormatString) == -1)
|
||||
screenshotFormatComboBox->addItem(screenshotFormatString);
|
||||
screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString));
|
||||
|
@ -280,13 +270,13 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
saveSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game");
|
||||
saveSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game");
|
||||
int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex();
|
||||
if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game"))
|
||||
mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex);
|
||||
if (unarmedFactorsStrengthIndex != Settings::Manager::getInt("strength influences hand to hand", "Game"))
|
||||
Settings::Manager::setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex);
|
||||
saveSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game");
|
||||
saveSettingBool(enableNavigatorCheckBox, "enable", "Navigator");
|
||||
int numPhysicsThreads = physicsThreadsSpinBox->value();
|
||||
if (numPhysicsThreads != mEngineSettings.getInt("async num threads", "Physics"))
|
||||
mEngineSettings.setInt("async num threads", "Physics", numPhysicsThreads);
|
||||
if (numPhysicsThreads != Settings::Manager::getInt("async num threads", "Physics"))
|
||||
Settings::Manager::setInt("async num threads", "Physics", numPhysicsThreads);
|
||||
}
|
||||
|
||||
// Visuals
|
||||
|
@ -304,23 +294,23 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
saveSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game");
|
||||
saveSettingBool(smoothMovementCheckBox, "smooth movement", "Game");
|
||||
|
||||
const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain");
|
||||
const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain");
|
||||
const bool distantTerrain = Settings::Manager::getBool("distant terrain", "Terrain");
|
||||
const bool objectPaging = Settings::Manager::getBool("object paging", "Terrain");
|
||||
const bool wantDistantLand = distantLandCheckBox->checkState();
|
||||
if (wantDistantLand != (distantTerrain && objectPaging)) {
|
||||
mEngineSettings.setBool("distant terrain", "Terrain", wantDistantLand);
|
||||
mEngineSettings.setBool("object paging", "Terrain", wantDistantLand);
|
||||
Settings::Manager::setBool("distant terrain", "Terrain", wantDistantLand);
|
||||
Settings::Manager::setBool("object paging", "Terrain", wantDistantLand);
|
||||
}
|
||||
|
||||
saveSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain");
|
||||
double viewingDistance = viewingDistanceComboBox->value();
|
||||
if (viewingDistance != convertToCells(mEngineSettings.getInt("viewing distance", "Camera")))
|
||||
if (viewingDistance != convertToCells(Settings::Manager::getInt("viewing distance", "Camera")))
|
||||
{
|
||||
mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance));
|
||||
Settings::Manager::setInt("viewing distance", "Camera", convertToUnits(viewingDistance));
|
||||
}
|
||||
|
||||
static std::array<std::string, 3> lightingMethodMap = {"legacy", "shaders compatibility", "shaders"};
|
||||
mEngineSettings.setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]);
|
||||
double objectPagingMinSize = objectPagingMinSizeComboBox->value();
|
||||
if (objectPagingMinSize != Settings::Manager::getDouble("object paging min size", "Terrain"))
|
||||
Settings::Manager::setDouble("object paging min size", "Terrain", objectPagingMinSize);
|
||||
}
|
||||
|
||||
// Audio
|
||||
|
@ -328,25 +318,25 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
int audioDeviceIndex = audioDeviceSelectorComboBox->currentIndex();
|
||||
if (audioDeviceIndex != 0)
|
||||
{
|
||||
mEngineSettings.setString("device", "Sound", audioDeviceSelectorComboBox->currentText().toUtf8().constData());
|
||||
Settings::Manager::setString("device", "Sound", audioDeviceSelectorComboBox->currentText().toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
mEngineSettings.setString("device", "Sound", "");
|
||||
Settings::Manager::setString("device", "Sound", "");
|
||||
}
|
||||
int hrtfEnabledIndex = enableHRTFComboBox->currentIndex() - 1;
|
||||
if (hrtfEnabledIndex != mEngineSettings.getInt("hrtf enable", "Sound"))
|
||||
if (hrtfEnabledIndex != Settings::Manager::getInt("hrtf enable", "Sound"))
|
||||
{
|
||||
mEngineSettings.setInt("hrtf enable", "Sound", hrtfEnabledIndex);
|
||||
Settings::Manager::setInt("hrtf enable", "Sound", hrtfEnabledIndex);
|
||||
}
|
||||
int selectedHRTFProfileIndex = hrtfProfileSelectorComboBox->currentIndex();
|
||||
if (selectedHRTFProfileIndex != 0)
|
||||
{
|
||||
mEngineSettings.setString("hrtf", "Sound", hrtfProfileSelectorComboBox->currentText().toUtf8().constData());
|
||||
Settings::Manager::setString("hrtf", "Sound", hrtfProfileSelectorComboBox->currentText().toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
mEngineSettings.setString("hrtf", "Sound", "");
|
||||
Settings::Manager::setString("hrtf", "Sound", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,14 +348,14 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
saveSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera");
|
||||
saveSettingBool(headBobbingCheckBox, "head bobbing", "Camera");
|
||||
|
||||
osg::Vec2f shoulderOffset = mEngineSettings.getVector2("view over shoulder offset", "Camera");
|
||||
osg::Vec2f shoulderOffset = Settings::Manager::getVector2("view over shoulder offset", "Camera");
|
||||
if (defaultShoulderComboBox->currentIndex() != (shoulderOffset.x() >= 0 ? 0 : 1))
|
||||
{
|
||||
if (defaultShoulderComboBox->currentIndex() == 0)
|
||||
shoulderOffset.x() = std::abs(shoulderOffset.x());
|
||||
else
|
||||
shoulderOffset.x() = -std::abs(shoulderOffset.x());
|
||||
mEngineSettings.setVector2("view over shoulder offset", "Camera", shoulderOffset);
|
||||
Settings::Manager::setVector2("view over shoulder offset", "Camera", shoulderOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,13 +367,13 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
|
||||
saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI");
|
||||
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
|
||||
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game"))
|
||||
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex);
|
||||
if (showOwnedCurrentIndex != Settings::Manager::getInt("show owned", "Game"))
|
||||
Settings::Manager::setInt("show owned", "Game", showOwnedCurrentIndex);
|
||||
saveSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI");
|
||||
saveSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game");
|
||||
float uiScalingFactor = scalingSpinBox->value();
|
||||
if (uiScalingFactor != mEngineSettings.getFloat("scaling factor", "GUI"))
|
||||
mEngineSettings.setFloat("scaling factor", "GUI", uiScalingFactor);
|
||||
if (uiScalingFactor != Settings::Manager::getFloat("scaling factor", "GUI"))
|
||||
Settings::Manager::setFloat("scaling factor", "GUI", uiScalingFactor);
|
||||
}
|
||||
|
||||
// Bug fixes
|
||||
|
@ -397,15 +387,15 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
// Saves Settings
|
||||
saveSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
|
||||
int maximumQuicksaves = maximumQuicksavesComboBox->value();
|
||||
if (maximumQuicksaves != mEngineSettings.getInt("max quicksaves", "Saves"))
|
||||
if (maximumQuicksaves != Settings::Manager::getInt("max quicksaves", "Saves"))
|
||||
{
|
||||
mEngineSettings.setInt("max quicksaves", "Saves", maximumQuicksaves);
|
||||
Settings::Manager::setInt("max quicksaves", "Saves", maximumQuicksaves);
|
||||
}
|
||||
|
||||
// Other Settings
|
||||
std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString();
|
||||
if (screenshotFormatString != mEngineSettings.getString("screenshot format", "General"))
|
||||
mEngineSettings.setString("screenshot format", "General", screenshotFormatString);
|
||||
if (screenshotFormatString != Settings::Manager::getString("screenshot format", "General"))
|
||||
Settings::Manager::setString("screenshot format", "General", screenshotFormatString);
|
||||
}
|
||||
|
||||
// Testing
|
||||
|
@ -457,15 +447,15 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
|
||||
void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group)
|
||||
{
|
||||
if (mEngineSettings.getBool(setting, group))
|
||||
if (Settings::Manager::getBool(setting, group))
|
||||
checkbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
|
||||
void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group)
|
||||
{
|
||||
bool cValue = checkbox->checkState();
|
||||
if (cValue != mEngineSettings.getBool(setting, group))
|
||||
mEngineSettings.setBool(setting, group, cValue);
|
||||
if (cValue != Settings::Manager::getBool(setting, group))
|
||||
Settings::Manager::setBool(setting, group, cValue);
|
||||
}
|
||||
|
||||
void Launcher::AdvancedPage::slotLoadedCellsChanged(QStringList cellNames)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef ADVANCEDPAGE_H
|
||||
#define ADVANCEDPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QCompleter>
|
||||
#include <QStringListModel>
|
||||
|
||||
|
@ -18,8 +17,7 @@ namespace Launcher
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AdvancedPage(Config::GameSettings &gameSettings,
|
||||
Settings::Manager &engineSettings, QWidget *parent = nullptr);
|
||||
explicit AdvancedPage(Config::GameSettings &gameSettings, QWidget *parent = nullptr);
|
||||
|
||||
bool loadSettings();
|
||||
void saveSettings();
|
||||
|
@ -35,7 +33,6 @@ namespace Launcher
|
|||
|
||||
private:
|
||||
Config::GameSettings &mGameSettings;
|
||||
Settings::Manager &mEngineSettings;
|
||||
QCompleter mCellNameCompleter;
|
||||
QStringListModel mCellNameCompleterModel;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
#include <QMenu>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <thread>
|
||||
|
@ -14,7 +13,6 @@
|
|||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include <components/contentselector/model/esmfile.hpp>
|
||||
#include <components/contentselector/model/naturalsort.hpp>
|
||||
#include <components/contentselector/view/contentselector.hpp>
|
||||
|
||||
#include <components/config/gamesettings.hpp>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QStringList>
|
||||
|
||||
class QSortFilterProxyModel;
|
||||
|
|
|
@ -32,9 +32,8 @@ QString getAspect(int x, int y)
|
|||
return QString(QString::number(xaspect) + ":" + QString::number(yaspect));
|
||||
}
|
||||
|
||||
Launcher::GraphicsPage::GraphicsPage(Settings::Manager &engineSettings, QWidget *parent)
|
||||
Launcher::GraphicsPage::GraphicsPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mEngineSettings(engineSettings)
|
||||
{
|
||||
setObjectName ("GraphicsPage");
|
||||
setupUi(this);
|
||||
|
@ -93,26 +92,27 @@ bool Launcher::GraphicsPage::loadSettings()
|
|||
if (!setupSDL())
|
||||
return false;
|
||||
|
||||
if (mEngineSettings.getBool("vsync", "Video"))
|
||||
// Visuals
|
||||
if (Settings::Manager::getBool("vsync", "Video"))
|
||||
vSyncCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
if (mEngineSettings.getBool("fullscreen", "Video"))
|
||||
if (Settings::Manager::getBool("fullscreen", "Video"))
|
||||
fullScreenCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
if (mEngineSettings.getBool("window border", "Video"))
|
||||
if (Settings::Manager::getBool("window border", "Video"))
|
||||
windowBorderCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
// aaValue is the actual value (0, 1, 2, 4, 8, 16)
|
||||
int aaValue = mEngineSettings.getInt("antialiasing", "Video");
|
||||
int aaValue = Settings::Manager::getInt("antialiasing", "Video");
|
||||
// aaIndex is the index into the allowed values in the pull down.
|
||||
int aaIndex = antiAliasingComboBox->findText(QString::number(aaValue));
|
||||
if (aaIndex != -1)
|
||||
antiAliasingComboBox->setCurrentIndex(aaIndex);
|
||||
|
||||
int width = mEngineSettings.getInt("resolution x", "Video");
|
||||
int height = mEngineSettings.getInt("resolution y", "Video");
|
||||
int width = Settings::Manager::getInt("resolution x", "Video");
|
||||
int height = Settings::Manager::getInt("resolution y", "Video");
|
||||
QString resolution = QString::number(width) + QString(" x ") + QString::number(height);
|
||||
screenComboBox->setCurrentIndex(mEngineSettings.getInt("screen", "Video"));
|
||||
screenComboBox->setCurrentIndex(Settings::Manager::getInt("screen", "Video"));
|
||||
|
||||
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
||||
|
||||
|
@ -125,40 +125,49 @@ bool Launcher::GraphicsPage::loadSettings()
|
|||
customHeightSpinBox->setValue(height);
|
||||
}
|
||||
|
||||
float fpsLimit = mEngineSettings.getFloat("framerate limit", "Video");
|
||||
float fpsLimit = Settings::Manager::getFloat("framerate limit", "Video");
|
||||
if (fpsLimit != 0)
|
||||
{
|
||||
framerateLimitCheckBox->setCheckState(Qt::Checked);
|
||||
framerateLimitSpinBox->setValue(fpsLimit);
|
||||
}
|
||||
|
||||
if (mEngineSettings.getBool("actor shadows", "Shadows"))
|
||||
// Lighting
|
||||
int lightingMethod = 1;
|
||||
if (Settings::Manager::getString("lighting method", "Shaders") == "legacy")
|
||||
lightingMethod = 0;
|
||||
else if (Settings::Manager::getString("lighting method", "Shaders") == "shaders")
|
||||
lightingMethod = 2;
|
||||
lightingMethodComboBox->setCurrentIndex(lightingMethod);
|
||||
|
||||
// Shadows
|
||||
if (Settings::Manager::getBool("actor shadows", "Shadows"))
|
||||
actorShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("player shadows", "Shadows"))
|
||||
if (Settings::Manager::getBool("player shadows", "Shadows"))
|
||||
playerShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("terrain shadows", "Shadows"))
|
||||
if (Settings::Manager::getBool("terrain shadows", "Shadows"))
|
||||
terrainShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("object shadows", "Shadows"))
|
||||
if (Settings::Manager::getBool("object shadows", "Shadows"))
|
||||
objectShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
if (mEngineSettings.getBool("enable indoor shadows", "Shadows"))
|
||||
if (Settings::Manager::getBool("enable indoor shadows", "Shadows"))
|
||||
indoorShadowsCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
shadowComputeSceneBoundsComboBox->setCurrentIndex(
|
||||
shadowComputeSceneBoundsComboBox->findText(
|
||||
QString(tr(mEngineSettings.getString("compute scene bounds", "Shadows").c_str()))));
|
||||
QString(tr(Settings::Manager::getString("compute scene bounds", "Shadows").c_str()))));
|
||||
|
||||
int shadowDistLimit = mEngineSettings.getInt("maximum shadow map distance", "Shadows");
|
||||
int shadowDistLimit = Settings::Manager::getInt("maximum shadow map distance", "Shadows");
|
||||
if (shadowDistLimit > 0)
|
||||
{
|
||||
shadowDistanceCheckBox->setCheckState(Qt::Checked);
|
||||
shadowDistanceSpinBox->setValue(shadowDistLimit);
|
||||
}
|
||||
|
||||
float shadowFadeStart = mEngineSettings.getFloat("shadow fade start", "Shadows");
|
||||
float shadowFadeStart = Settings::Manager::getFloat("shadow fade start", "Shadows");
|
||||
if (shadowFadeStart != 0)
|
||||
fadeStartSpinBox->setValue(shadowFadeStart);
|
||||
|
||||
int shadowRes = mEngineSettings.getInt("shadow map resolution", "Shadows");
|
||||
int shadowRes = Settings::Manager::getInt("shadow map resolution", "Shadows");
|
||||
int shadowResIndex = shadowResolutionComboBox->findText(QString::number(shadowRes));
|
||||
if (shadowResIndex != -1)
|
||||
shadowResolutionComboBox->setCurrentIndex(shadowResIndex);
|
||||
|
@ -168,23 +177,25 @@ bool Launcher::GraphicsPage::loadSettings()
|
|||
|
||||
void Launcher::GraphicsPage::saveSettings()
|
||||
{
|
||||
// Visuals
|
||||
|
||||
// Ensure we only set the new settings if they changed. This is to avoid cluttering the
|
||||
// user settings file (which by definition should only contain settings the user has touched)
|
||||
bool cVSync = vSyncCheckBox->checkState();
|
||||
if (cVSync != mEngineSettings.getBool("vsync", "Video"))
|
||||
mEngineSettings.setBool("vsync", "Video", cVSync);
|
||||
if (cVSync != Settings::Manager::getBool("vsync", "Video"))
|
||||
Settings::Manager::setBool("vsync", "Video", cVSync);
|
||||
|
||||
bool cFullScreen = fullScreenCheckBox->checkState();
|
||||
if (cFullScreen != mEngineSettings.getBool("fullscreen", "Video"))
|
||||
mEngineSettings.setBool("fullscreen", "Video", cFullScreen);
|
||||
if (cFullScreen != Settings::Manager::getBool("fullscreen", "Video"))
|
||||
Settings::Manager::setBool("fullscreen", "Video", cFullScreen);
|
||||
|
||||
bool cWindowBorder = windowBorderCheckBox->checkState();
|
||||
if (cWindowBorder != mEngineSettings.getBool("window border", "Video"))
|
||||
mEngineSettings.setBool("window border", "Video", cWindowBorder);
|
||||
if (cWindowBorder != Settings::Manager::getBool("window border", "Video"))
|
||||
Settings::Manager::setBool("window border", "Video", cWindowBorder);
|
||||
|
||||
int cAAValue = antiAliasingComboBox->currentText().toInt();
|
||||
if (cAAValue != mEngineSettings.getInt("antialiasing", "Video"))
|
||||
mEngineSettings.setInt("antialiasing", "Video", cAAValue);
|
||||
if (cAAValue != Settings::Manager::getInt("antialiasing", "Video"))
|
||||
Settings::Manager::setInt("antialiasing", "Video", cAAValue);
|
||||
|
||||
int cWidth = 0;
|
||||
int cHeight = 0;
|
||||
|
@ -199,33 +210,38 @@ void Launcher::GraphicsPage::saveSettings()
|
|||
cHeight = customHeightSpinBox->value();
|
||||
}
|
||||
|
||||
if (cWidth != mEngineSettings.getInt("resolution x", "Video"))
|
||||
mEngineSettings.setInt("resolution x", "Video", cWidth);
|
||||
if (cWidth != Settings::Manager::getInt("resolution x", "Video"))
|
||||
Settings::Manager::setInt("resolution x", "Video", cWidth);
|
||||
|
||||
if (cHeight != mEngineSettings.getInt("resolution y", "Video"))
|
||||
mEngineSettings.setInt("resolution y", "Video", cHeight);
|
||||
if (cHeight != Settings::Manager::getInt("resolution y", "Video"))
|
||||
Settings::Manager::setInt("resolution y", "Video", cHeight);
|
||||
|
||||
int cScreen = screenComboBox->currentIndex();
|
||||
if (cScreen != mEngineSettings.getInt("screen", "Video"))
|
||||
mEngineSettings.setInt("screen", "Video", cScreen);
|
||||
if (cScreen != Settings::Manager::getInt("screen", "Video"))
|
||||
Settings::Manager::setInt("screen", "Video", cScreen);
|
||||
|
||||
if (framerateLimitCheckBox->checkState() != Qt::Unchecked)
|
||||
{
|
||||
float cFpsLimit = framerateLimitSpinBox->value();
|
||||
if (cFpsLimit != mEngineSettings.getFloat("framerate limit", "Video"))
|
||||
mEngineSettings.setFloat("framerate limit", "Video", cFpsLimit);
|
||||
if (cFpsLimit != Settings::Manager::getFloat("framerate limit", "Video"))
|
||||
Settings::Manager::setFloat("framerate limit", "Video", cFpsLimit);
|
||||
}
|
||||
else if (mEngineSettings.getFloat("framerate limit", "Video") != 0)
|
||||
else if (Settings::Manager::getFloat("framerate limit", "Video") != 0)
|
||||
{
|
||||
mEngineSettings.setFloat("framerate limit", "Video", 0);
|
||||
Settings::Manager::setFloat("framerate limit", "Video", 0);
|
||||
}
|
||||
|
||||
// Lighting
|
||||
static std::array<std::string, 3> lightingMethodMap = {"legacy", "shaders compatibility", "shaders"};
|
||||
Settings::Manager::setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]);
|
||||
|
||||
// Shadows
|
||||
int cShadowDist = shadowDistanceCheckBox->checkState() != Qt::Unchecked ? shadowDistanceSpinBox->value() : 0;
|
||||
if (mEngineSettings.getInt("maximum shadow map distance", "Shadows") != cShadowDist)
|
||||
mEngineSettings.setInt("maximum shadow map distance", "Shadows", cShadowDist);
|
||||
if (Settings::Manager::getInt("maximum shadow map distance", "Shadows") != cShadowDist)
|
||||
Settings::Manager::setInt("maximum shadow map distance", "Shadows", cShadowDist);
|
||||
float cFadeStart = fadeStartSpinBox->value();
|
||||
if (cShadowDist > 0 && mEngineSettings.getFloat("shadow fade start", "Shadows") != cFadeStart)
|
||||
mEngineSettings.setFloat("shadow fade start", "Shadows", cFadeStart);
|
||||
if (cShadowDist > 0 && Settings::Manager::getFloat("shadow fade start", "Shadows") != cFadeStart)
|
||||
Settings::Manager::setFloat("shadow fade start", "Shadows", cFadeStart);
|
||||
|
||||
bool cActorShadows = actorShadowsCheckBox->checkState();
|
||||
bool cObjectShadows = objectShadowsCheckBox->checkState();
|
||||
|
@ -233,42 +249,42 @@ void Launcher::GraphicsPage::saveSettings()
|
|||
bool cPlayerShadows = playerShadowsCheckBox->checkState();
|
||||
if (cActorShadows || cObjectShadows || cTerrainShadows || cPlayerShadows)
|
||||
{
|
||||
if (!mEngineSettings.getBool("enable shadows", "Shadows"))
|
||||
mEngineSettings.setBool("enable shadows", "Shadows", true);
|
||||
if (mEngineSettings.getBool("actor shadows", "Shadows") != cActorShadows)
|
||||
mEngineSettings.setBool("actor shadows", "Shadows", cActorShadows);
|
||||
if (mEngineSettings.getBool("player shadows", "Shadows") != cPlayerShadows)
|
||||
mEngineSettings.setBool("player shadows", "Shadows", cPlayerShadows);
|
||||
if (mEngineSettings.getBool("object shadows", "Shadows") != cObjectShadows)
|
||||
mEngineSettings.setBool("object shadows", "Shadows", cObjectShadows);
|
||||
if (mEngineSettings.getBool("terrain shadows", "Shadows") != cTerrainShadows)
|
||||
mEngineSettings.setBool("terrain shadows", "Shadows", cTerrainShadows);
|
||||
if (!Settings::Manager::getBool("enable shadows", "Shadows"))
|
||||
Settings::Manager::setBool("enable shadows", "Shadows", true);
|
||||
if (Settings::Manager::getBool("actor shadows", "Shadows") != cActorShadows)
|
||||
Settings::Manager::setBool("actor shadows", "Shadows", cActorShadows);
|
||||
if (Settings::Manager::getBool("player shadows", "Shadows") != cPlayerShadows)
|
||||
Settings::Manager::setBool("player shadows", "Shadows", cPlayerShadows);
|
||||
if (Settings::Manager::getBool("object shadows", "Shadows") != cObjectShadows)
|
||||
Settings::Manager::setBool("object shadows", "Shadows", cObjectShadows);
|
||||
if (Settings::Manager::getBool("terrain shadows", "Shadows") != cTerrainShadows)
|
||||
Settings::Manager::setBool("terrain shadows", "Shadows", cTerrainShadows);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mEngineSettings.getBool("enable shadows", "Shadows"))
|
||||
mEngineSettings.setBool("enable shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("actor shadows", "Shadows"))
|
||||
mEngineSettings.setBool("actor shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("player shadows", "Shadows"))
|
||||
mEngineSettings.setBool("player shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("object shadows", "Shadows"))
|
||||
mEngineSettings.setBool("object shadows", "Shadows", false);
|
||||
if (mEngineSettings.getBool("terrain shadows", "Shadows"))
|
||||
mEngineSettings.setBool("terrain shadows", "Shadows", false);
|
||||
if (Settings::Manager::getBool("enable shadows", "Shadows"))
|
||||
Settings::Manager::setBool("enable shadows", "Shadows", false);
|
||||
if (Settings::Manager::getBool("actor shadows", "Shadows"))
|
||||
Settings::Manager::setBool("actor shadows", "Shadows", false);
|
||||
if (Settings::Manager::getBool("player shadows", "Shadows"))
|
||||
Settings::Manager::setBool("player shadows", "Shadows", false);
|
||||
if (Settings::Manager::getBool("object shadows", "Shadows"))
|
||||
Settings::Manager::setBool("object shadows", "Shadows", false);
|
||||
if (Settings::Manager::getBool("terrain shadows", "Shadows"))
|
||||
Settings::Manager::setBool("terrain shadows", "Shadows", false);
|
||||
}
|
||||
|
||||
bool cIndoorShadows = indoorShadowsCheckBox->checkState();
|
||||
if (mEngineSettings.getBool("enable indoor shadows", "Shadows") != cIndoorShadows)
|
||||
mEngineSettings.setBool("enable indoor shadows", "Shadows", cIndoorShadows);
|
||||
if (Settings::Manager::getBool("enable indoor shadows", "Shadows") != cIndoorShadows)
|
||||
Settings::Manager::setBool("enable indoor shadows", "Shadows", cIndoorShadows);
|
||||
|
||||
int cShadowRes = shadowResolutionComboBox->currentText().toInt();
|
||||
if (cShadowRes != mEngineSettings.getInt("shadow map resolution", "Shadows"))
|
||||
mEngineSettings.setInt("shadow map resolution", "Shadows", cShadowRes);
|
||||
if (cShadowRes != Settings::Manager::getInt("shadow map resolution", "Shadows"))
|
||||
Settings::Manager::setInt("shadow map resolution", "Shadows", cShadowRes);
|
||||
|
||||
auto cComputeSceneBounds = shadowComputeSceneBoundsComboBox->currentText().toStdString();
|
||||
if (cComputeSceneBounds != mEngineSettings.getString("compute scene bounds", "Shadows"))
|
||||
mEngineSettings.setString("compute scene bounds", "Shadows", cComputeSceneBounds);
|
||||
if (cComputeSceneBounds != Settings::Manager::getString("compute scene bounds", "Shadows"))
|
||||
Settings::Manager::setString("compute scene bounds", "Shadows", cComputeSceneBounds);
|
||||
}
|
||||
|
||||
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef GRAPHICSPAGE_H
|
||||
#define GRAPHICSPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui_graphicspage.h"
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
@ -20,7 +18,7 @@ namespace Launcher
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GraphicsPage(Settings::Manager &engineSettings, QWidget *parent = nullptr);
|
||||
explicit GraphicsPage(QWidget *parent = nullptr);
|
||||
|
||||
void saveSettings();
|
||||
bool loadSettings();
|
||||
|
@ -35,8 +33,6 @@ namespace Launcher
|
|||
void slotShadowDistLimitToggled(bool checked);
|
||||
|
||||
private:
|
||||
Settings::Manager &mEngineSettings;
|
||||
|
||||
QVector<QStringList> mResolutionsPerScreen;
|
||||
|
||||
static QStringList getAvailableResolutions(int screen);
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QTextCodec>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#undef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
|
|
|
@ -5,15 +5,12 @@
|
|||
|
||||
#include <QDate>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QFontDatabase>
|
||||
#include <QInputDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QCloseEvent>
|
||||
#include <QTextCodec>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "playpage.hpp"
|
||||
#include "graphicspage.hpp"
|
||||
#include "datafilespage.hpp"
|
||||
|
@ -126,9 +123,9 @@ void Launcher::MainDialog::createPages()
|
|||
|
||||
mPlayPage = new PlayPage(this);
|
||||
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||
mGraphicsPage = new GraphicsPage(mEngineSettings, this);
|
||||
mGraphicsPage = new GraphicsPage(this);
|
||||
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||
mAdvancedPage = new AdvancedPage(mGameSettings, mEngineSettings, this);
|
||||
mAdvancedPage = new AdvancedPage(mGameSettings, this);
|
||||
|
||||
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
||||
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
|
||||
|
@ -427,11 +424,11 @@ bool Launcher::MainDialog::setupGraphicsSettings()
|
|||
mEngineSettings.clear();
|
||||
|
||||
// Create the settings manager and load default settings file
|
||||
const std::string localDefault = (mCfgMgr.getLocalPath() / "settings-default.cfg").string();
|
||||
const std::string globalDefault = (mCfgMgr.getGlobalPath() / "settings-default.cfg").string();
|
||||
const std::string localDefault = (mCfgMgr.getLocalPath() / "defaults.bin").string();
|
||||
const std::string globalDefault = (mCfgMgr.getGlobalPath() / "defaults.bin").string();
|
||||
std::string defaultPath;
|
||||
|
||||
// Prefer the settings-default.cfg in the current directory.
|
||||
// Prefer the defaults.bin in the current directory.
|
||||
if (boost::filesystem::exists(localDefault))
|
||||
defaultPath = localDefault;
|
||||
else if (boost::filesystem::exists(globalDefault))
|
||||
|
@ -439,7 +436,7 @@ bool Launcher::MainDialog::setupGraphicsSettings()
|
|||
// Something's very wrong if we can't find the file at all.
|
||||
else {
|
||||
cfgError(tr("Error reading OpenMW configuration file"),
|
||||
tr("<br><b>Could not find settings-default.cfg</b><br><br> \
|
||||
tr("<br><b>Could not find defaults.bin</b><br><br> \
|
||||
The problem may be due to an incomplete installation of OpenMW.<br> \
|
||||
Reinstalling OpenMW may resolve the problem."));
|
||||
return false;
|
||||
|
@ -450,7 +447,7 @@ bool Launcher::MainDialog::setupGraphicsSettings()
|
|||
mEngineSettings.loadDefault(defaultPath);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
std::string msg = std::string("<br><b>Error reading settings-default.cfg</b><br><br>") + e.what();
|
||||
std::string msg = std::string("<br><b>Error reading defaults.bin</b><br><br>") + e.what();
|
||||
cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef MAINDIALOG_H
|
||||
#define MAINDIALOG_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QProcess>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef PLAYPAGE_H
|
||||
#define PLAYPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui_playpage.h"
|
||||
|
||||
class QComboBox;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <signal.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_video.h>
|
||||
|
||||
bool initSDL()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef SETTINGSPAGE_HPP
|
||||
#define SETTINGSPAGE_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QProcess>
|
||||
|
||||
#include <components/process/processinvoker.hpp>
|
||||
|
||||
#include "ui_settingspage.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef OPENMW_CELLNAMELOADER_H
|
||||
#define OPENMW_CELLNAMELOADER_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#define LINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QStyle>
|
||||
#include <QStylePainter>
|
||||
#include <QToolButton>
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <QRegExpValidator>
|
||||
#include <QLineEdit>
|
||||
#include <QString>
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
|
|
|
@ -676,7 +676,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::p
|
|||
}
|
||||
|
||||
if(line[0] == '[') {
|
||||
int pos = line.find(']');
|
||||
int pos = static_cast<int>(line.find(']'));
|
||||
if(pos < 2) {
|
||||
std::cout << "Warning: ini file wrongly formatted (" << line << "). Line ignored." << std::endl;
|
||||
continue;
|
||||
|
@ -686,12 +686,12 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::p
|
|||
continue;
|
||||
}
|
||||
|
||||
int comment_pos = line.find(";");
|
||||
int comment_pos = static_cast<int>(line.find(';'));
|
||||
if(comment_pos > 0) {
|
||||
line = line.substr(0,comment_pos);
|
||||
}
|
||||
|
||||
int pos = line.find("=");
|
||||
int pos = static_cast<int>(line.find('='));
|
||||
if(pos < 1) {
|
||||
continue;
|
||||
}
|
||||
|
@ -722,7 +722,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::p
|
|||
while (std::getline(file, line)) {
|
||||
|
||||
// we cant say comment by only looking at first char anymore
|
||||
int comment_pos = line.find("#");
|
||||
int comment_pos = static_cast<int>(line.find('#'));
|
||||
if(comment_pos > 0) {
|
||||
line = line.substr(0,comment_pos);
|
||||
}
|
||||
|
@ -731,7 +731,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::p
|
|||
continue;
|
||||
}
|
||||
|
||||
int pos = line.find("=");
|
||||
int pos = static_cast<int>(line.find('='));
|
||||
if(pos < 1) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace bfs = boost::filesystem;
|
|||
///See if the file has the named extension
|
||||
bool hasExtension(std::string filename, std::string extensionToFind)
|
||||
{
|
||||
std::string extension = filename.substr(filename.find_last_of(".")+1);
|
||||
std::string extension = filename.substr(filename.find_last_of('.')+1);
|
||||
|
||||
//Convert strings to lower case for comparison
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
|
|
|
@ -89,7 +89,7 @@ opencs_units (view/render
|
|||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
||||
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw
|
||||
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw commands
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
|
@ -158,7 +158,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|||
|
||||
if(APPLE)
|
||||
set (OPENCS_MAC_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw-cs.icns")
|
||||
set (OPENCS_CFG "${OpenMW_BINARY_DIR}/openmw-cs.cfg")
|
||||
set (OPENCS_CFG "${OpenMW_BINARY_DIR}/defaults-cs.bin")
|
||||
set (OPENCS_DEFAULT_FILTERS_FILE "${OpenMW_BINARY_DIR}/resources/defaultfilters")
|
||||
set (OPENCS_OPENMW_CFG "${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||
else()
|
||||
|
@ -270,7 +270,7 @@ if (WIN32)
|
|||
SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}")
|
||||
endif ()
|
||||
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/openmw-cs.cfg" DESTINATION ".")
|
||||
INSTALL(FILES "${INSTALL_SOURCE}/defaults-cs.bin" DESTINATION ".")
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
|
|
|
@ -21,7 +21,7 @@ void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
|
|||
{
|
||||
std::vector<std::string>& list = mIds[type];
|
||||
|
||||
int size = list.size();
|
||||
size_t size = list.size();
|
||||
|
||||
list.resize (size+ids.size());
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "../tools/reportmodel.hpp"
|
||||
|
||||
#include "document.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLoaded (0), mRecordsLeft (false) {}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
#include "state.hpp"
|
||||
#include "stage.hpp"
|
||||
|
||||
void CSMDoc::Operation::prepareStages()
|
||||
|
|
|
@ -83,6 +83,8 @@ void CSMDoc::Runner::start (bool delayed)
|
|||
arguments <<
|
||||
QString::fromUtf8 (("--data=\""+mProjectPath.parent_path().string()+"\"").c_str());
|
||||
|
||||
arguments << "--replace=content";
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (mContentFiles.begin());
|
||||
iter!=mContentFiles.end(); ++iter)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ CSMFilter::NAryNode::NAryNode (const std::vector<std::shared_ptr<Node> >& nodes,
|
|||
|
||||
int CSMFilter::NAryNode::getSize() const
|
||||
{
|
||||
return mNodes.size();
|
||||
return static_cast<int>(mNodes.size());
|
||||
}
|
||||
|
||||
const CSMFilter::Node& CSMFilter::NAryNode::operator[] (int index) const
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace CSMPrefs
|
|||
{
|
||||
const int MaxKeys = 4; // A limitation of QKeySequence
|
||||
|
||||
size_t end = data.find(";");
|
||||
size_t end = data.find(';');
|
||||
size_t size = std::min(end, data.size());
|
||||
|
||||
std::string value = data.substr(0, size);
|
||||
|
@ -191,7 +191,7 @@ namespace CSMPrefs
|
|||
|
||||
while (start < value.size())
|
||||
{
|
||||
end = data.find("+", start);
|
||||
end = data.find('+', start);
|
||||
end = std::min(end, value.size());
|
||||
|
||||
std::string name = value.substr(start, end - start);
|
||||
|
@ -243,7 +243,7 @@ namespace CSMPrefs
|
|||
|
||||
void ShortcutManager::convertFromString(const std::string& data, int& modifier) const
|
||||
{
|
||||
size_t start = data.find(";") + 1;
|
||||
size_t start = data.find(';') + 1;
|
||||
start = std::min(start, data.size());
|
||||
|
||||
std::string name = data.substr(start);
|
||||
|
|
|
@ -17,15 +17,15 @@ CSMPrefs::State *CSMPrefs::State::sThis = nullptr;
|
|||
void CSMPrefs::State::load()
|
||||
{
|
||||
// default settings file
|
||||
boost::filesystem::path local = mConfigurationManager.getLocalPath() / mConfigFile;
|
||||
boost::filesystem::path global = mConfigurationManager.getGlobalPath() / mConfigFile;
|
||||
boost::filesystem::path local = mConfigurationManager.getLocalPath() / mDefaultConfigFile;
|
||||
boost::filesystem::path global = mConfigurationManager.getGlobalPath() / mDefaultConfigFile;
|
||||
|
||||
if (boost::filesystem::exists (local))
|
||||
mSettings.loadDefault (local.string());
|
||||
else if (boost::filesystem::exists (global))
|
||||
mSettings.loadDefault (global.string());
|
||||
else
|
||||
throw std::runtime_error ("No default settings file found! Make sure the file \"openmw-cs.cfg\" was properly installed.");
|
||||
throw std::runtime_error ("No default settings file found! Make sure the file \"" + mDefaultConfigFile + "\" was properly installed.");
|
||||
|
||||
// user settings file
|
||||
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
|
||||
|
@ -641,7 +641,7 @@ void CSMPrefs::State::setDefault (const std::string& key, const std::string& def
|
|||
}
|
||||
|
||||
CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager)
|
||||
: mConfigFile ("openmw-cs.cfg"), mConfigurationManager (configurationManager),
|
||||
: mConfigFile ("openmw-cs.cfg"), mDefaultConfigFile("defaults-cs.bin"), mConfigurationManager (configurationManager),
|
||||
mCurrentCategory (mCategories.end())
|
||||
{
|
||||
if (sThis)
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace CSMPrefs
|
|||
private:
|
||||
|
||||
const std::string mConfigFile;
|
||||
const std::string mDefaultConfigFile;
|
||||
const Files::ConfigurationManager& mConfigurationManager;
|
||||
ShortcutManager mShortcutManager;
|
||||
Settings::Manager mSettings;
|
||||
|
|
|
@ -11,7 +11,7 @@ CSMTools::MandatoryIdStage::MandatoryIdStage (const CSMWorld::CollectionBase& id
|
|||
|
||||
int CSMTools::MandatoryIdStage::setup()
|
||||
{
|
||||
return mIds.size();
|
||||
return static_cast<int>(mIds.size());
|
||||
}
|
||||
|
||||
void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages)
|
||||
|
|
|
@ -24,7 +24,7 @@ int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
|
|||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return mRows.size();
|
||||
return static_cast<int>(mRows.size());
|
||||
}
|
||||
|
||||
int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
|
||||
|
@ -140,7 +140,7 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
|
|||
|
||||
void CSMTools::ReportModel::add (const CSMDoc::Message& message)
|
||||
{
|
||||
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
||||
beginInsertRows (QModelIndex(), static_cast<int>(mRows.size()), static_cast<int>(mRows.size()));
|
||||
|
||||
mRows.push_back (message);
|
||||
|
||||
|
@ -176,7 +176,7 @@ void CSMTools::ReportModel::clear()
|
|||
{
|
||||
if (!mRows.empty())
|
||||
{
|
||||
beginRemoveRows (QModelIndex(), 0, mRows.size()-1);
|
||||
beginRemoveRows (QModelIndex(), 0, static_cast<int>(mRows.size())-1);
|
||||
mRows.clear();
|
||||
endRemoveRows();
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
|
|||
if (!newOrder.empty())
|
||||
if (mIdCollection->reorderRows (baseIndex, newOrder))
|
||||
emit dataChanged (index (baseIndex, 0),
|
||||
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1));
|
||||
index (baseIndex+static_cast<int>(newOrder.size())-1, mIdCollection->getColumns()-1));
|
||||
}
|
||||
|
||||
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "refcollection.hpp"
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/esm/loadcell.hpp>
|
||||
|
||||
#include "ref.hpp"
|
||||
|
@ -109,11 +108,13 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
|||
|
||||
Record<CellRef> record;
|
||||
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||
(base ? record.mBase : record.mModified) = ref;
|
||||
const ESM::RefNum refNum = ref.mRefNum;
|
||||
std::string refId = ref.mId;
|
||||
(base ? record.mBase : record.mModified) = std::move(ref);
|
||||
|
||||
appendRecord (record);
|
||||
|
||||
cache.insert (std::make_pair (ref.mRefNum, ref.mId));
|
||||
cache.emplace(refNum, std::move(refId));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -124,7 +125,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
|||
|
||||
Record<CellRef> record = getRecord (index);
|
||||
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
|
||||
(base ? record.mBase : record.mModified) = ref;
|
||||
(base ? record.mBase : record.mModified) = std::move(ref);
|
||||
|
||||
setRecord (index, record);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *
|
|||
mFiles.clear();
|
||||
mIndex.clear();
|
||||
|
||||
int baseSize = mBaseDirectory.size();
|
||||
size_t baseSize = mBaseDirectory.size();
|
||||
|
||||
const std::map<std::string, VFS::File*>& index = vfs->getIndex();
|
||||
for (std::map<std::string, VFS::File*>::const_iterator it = index.begin(); it != index.end(); ++it)
|
||||
{
|
||||
std::string filepath = it->first;
|
||||
if (static_cast<int> (filepath.size())<baseSize+1 ||
|
||||
if (filepath.size()<baseSize+1 ||
|
||||
filepath.substr (0, baseSize)!=mBaseDirectory ||
|
||||
(filepath[baseSize]!='/' && filepath[baseSize]!='\\'))
|
||||
continue;
|
||||
|
@ -60,7 +60,7 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *
|
|||
|
||||
int CSMWorld::Resources::getSize() const
|
||||
{
|
||||
return mFiles.size();
|
||||
return static_cast<int>(mFiles.size());
|
||||
}
|
||||
|
||||
std::string CSMWorld::Resources::getId (int index) const
|
||||
|
|
|
@ -30,7 +30,7 @@ void CSVDoc::Operations::setProgress (int current, int max, int type, int thread
|
|||
return;
|
||||
}
|
||||
|
||||
int oldCount = mOperations.size();
|
||||
int oldCount = static_cast<int>(mOperations.size());
|
||||
int newCount = oldCount + 1;
|
||||
|
||||
Operation *operation = new Operation (type, this);
|
||||
|
@ -51,7 +51,7 @@ void CSVDoc::Operations::quitOperation (int type)
|
|||
for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter)
|
||||
if ((*iter)->getType()==type)
|
||||
{
|
||||
int oldCount = mOperations.size();
|
||||
int oldCount = static_cast<int>(mOperations.size());
|
||||
int newCount = oldCount - 1;
|
||||
|
||||
mLayout->removeItem ((*iter)->getLayout());
|
||||
|
|
|
@ -749,7 +749,7 @@ void CSVDoc::View::infoAbout()
|
|||
"<tr><td>%4</td><td><a href=\"https://openmw.org\">https://openmw.org</a></td></tr>"
|
||||
"<tr><td>%5</td><td><a href=\"https://forum.openmw.org\">https://forum.openmw.org</a></td></tr>"
|
||||
"<tr><td>%6</td><td><a href=\"https://gitlab.com/OpenMW/openmw/issues\">https://gitlab.com/OpenMW/openmw/issues</a></td></tr>"
|
||||
"<tr><td>%7</td><td><a href=\"https://webchat.freenode.net/?channels=openmw&uio=OT10cnVlde\">irc://irc.freenode.net/#openmw</a></td></tr>"
|
||||
"<tr><td>%7</td><td><a href=\"https://web.libera.chat/#openmw\">ircs://irc.libera.chat/#openmw</a></td></tr>"
|
||||
"</table>"
|
||||
"</p>")
|
||||
.arg(versionInfo
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "../../model/doc/documentmanager.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/idcompletionmanager.hpp"
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <osg/Group>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
|
@ -13,15 +12,23 @@
|
|||
#include "../../model/world/cellcoordinates.hpp"
|
||||
|
||||
const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE;
|
||||
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 3;
|
||||
|
||||
/*
|
||||
The number of vertices per cell border is equal to the number of vertices per edge
|
||||
minus the duplicated corner vertices. An additional vertex to close the loop is NOT needed.
|
||||
*/
|
||||
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 4;
|
||||
|
||||
|
||||
CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords)
|
||||
: mParentNode(cellNode)
|
||||
{
|
||||
mBorderGeometry = new osg::Geometry();
|
||||
|
||||
mBaseNode = new osg::PositionAttitudeTransform();
|
||||
mBaseNode->setNodeMask(Mask_CellBorder);
|
||||
mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10));
|
||||
mBaseNode->addChild(mBorderGeometry);
|
||||
|
||||
mParentNode->addChild(mBaseNode);
|
||||
}
|
||||
|
@ -38,56 +45,59 @@ void CSVRender::CellBorder::buildShape(const ESM::Land& esmLand)
|
|||
if (!landData)
|
||||
return;
|
||||
|
||||
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
|
||||
mBaseNode->removeChild(mBorderGeometry);
|
||||
mBorderGeometry = new osg::Geometry();
|
||||
|
||||
// Vertices
|
||||
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
|
||||
|
||||
int x = 0, y = 0;
|
||||
for (; x < ESM::Land::LAND_SIZE; ++x)
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
/*
|
||||
Traverse the cell border counter-clockwise starting at the SW corner vertex (0, 0).
|
||||
Each loop starts at a corner vertex and ends right before the next corner vertex.
|
||||
*/
|
||||
for (; x < ESM::Land::LAND_SIZE - 1; ++x)
|
||||
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||
|
||||
x = ESM::Land::LAND_SIZE - 1;
|
||||
for (; y < ESM::Land::LAND_SIZE; ++y)
|
||||
for (; y < ESM::Land::LAND_SIZE - 1; ++y)
|
||||
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||
|
||||
y = ESM::Land::LAND_SIZE - 1;
|
||||
for (; x >= 0; --x)
|
||||
for (; x > 0; --x)
|
||||
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||
|
||||
x = 0;
|
||||
for (; y >= 0; --y)
|
||||
for (; y > 0; --y)
|
||||
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||
|
||||
geometry->setVertexArray(vertices);
|
||||
mBorderGeometry->setVertexArray(vertices);
|
||||
|
||||
// Color
|
||||
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array();
|
||||
colors->push_back(osg::Vec4f(0.f, 0.5f, 0.f, 1.f));
|
||||
|
||||
geometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
|
||||
mBorderGeometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
|
||||
|
||||
// Primitive
|
||||
osg::ref_ptr<osg::DrawElementsUShort> primitives =
|
||||
new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount+1);
|
||||
new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount + 1);
|
||||
|
||||
// Assign one primitive to each vertex.
|
||||
for (size_t i = 0; i < VertexCount; ++i)
|
||||
primitives->setElement(i, i);
|
||||
|
||||
// Assign the last primitive to the first vertex to close the loop.
|
||||
primitives->setElement(VertexCount, 0);
|
||||
|
||||
geometry->addPrimitiveSet(primitives);
|
||||
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
mBorderGeometry->addPrimitiveSet(primitives);
|
||||
mBorderGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
|
||||
geode->addDrawable(geometry);
|
||||
mBaseNode->addChild(geode);
|
||||
mBaseNode->addChild(mBorderGeometry);
|
||||
}
|
||||
|
||||
size_t CSVRender::CellBorder::landIndex(int x, int y)
|
||||
{
|
||||
return y * ESM::Land::LAND_SIZE + x;
|
||||
return static_cast<size_t>(y) * ESM::Land::LAND_SIZE + x;
|
||||
}
|
||||
|
||||
float CSVRender::CellBorder::scaleToWorld(int value)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace osg
|
||||
{
|
||||
class Geometry;
|
||||
class Group;
|
||||
class PositionAttitudeTransform;
|
||||
}
|
||||
|
@ -47,7 +48,7 @@ namespace CSVRender
|
|||
|
||||
osg::Group* mParentNode;
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||
|
||||
osg::ref_ptr<osg::Geometry> mBorderGeometry;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
44
apps/opencs/view/render/commands.cpp
Normal file
44
apps/opencs/view/render/commands.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include "commands.hpp"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
#include "editmode.hpp"
|
||||
#include "terrainselection.hpp"
|
||||
#include "terrainshapemode.hpp"
|
||||
#include "terraintexturemode.hpp"
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent)
|
||||
: mWorldspaceWidget(worldspaceWidget)
|
||||
{ }
|
||||
|
||||
void CSVRender::DrawTerrainSelectionCommand::redo()
|
||||
{
|
||||
tryUpdate();
|
||||
}
|
||||
|
||||
void CSVRender::DrawTerrainSelectionCommand::undo()
|
||||
{
|
||||
tryUpdate();
|
||||
}
|
||||
|
||||
void CSVRender::DrawTerrainSelectionCommand::tryUpdate()
|
||||
{
|
||||
if (!mWorldspaceWidget)
|
||||
{
|
||||
Log(Debug::Verbose) << "Can't update terrain selection, no WorldspaceWidget found!";
|
||||
return;
|
||||
}
|
||||
|
||||
auto terrainMode = dynamic_cast<CSVRender::TerrainShapeMode*>(mWorldspaceWidget->getEditMode());
|
||||
if (!terrainMode)
|
||||
{
|
||||
Log(Debug::Verbose) << "Can't update terrain selection in current EditMode";
|
||||
return;
|
||||
}
|
||||
|
||||
terrainMode->getTerrainSelection()->update();
|
||||
}
|
42
apps/opencs/view/render/commands.hpp
Normal file
42
apps/opencs/view/render/commands.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef CSV_RENDER_COMMANDS_HPP
|
||||
#define CSV_RENDER_COMMANDS_HPP
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class TerrainSelection;
|
||||
|
||||
/*
|
||||
Current solution to force a redrawing of the terrain-selection grid
|
||||
when undoing/redoing changes in the editor.
|
||||
This only triggers a simple redraw of the grid, so only use it in
|
||||
conjunction with actual data changes which deform the grid.
|
||||
|
||||
Please note that this command needs to be put onto the QUndoStack twice:
|
||||
at the start and at the end of the related terrain manipulation.
|
||||
This makes sure that the grid is always updated after all changes have
|
||||
been undone or redone -- but it also means that the selection is redrawn
|
||||
once at the beginning of either action. Future refinement may solve that.
|
||||
*/
|
||||
class DrawTerrainSelectionCommand : public QUndoCommand
|
||||
{
|
||||
|
||||
private:
|
||||
QPointer<WorldspaceWidget> mWorldspaceWidget;
|
||||
|
||||
public:
|
||||
DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent = nullptr);
|
||||
|
||||
void redo() override;
|
||||
void undo() override;
|
||||
|
||||
void tryUpdate();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,7 +3,6 @@
|
|||
#include <QMenu>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
|
|
|
@ -7,18 +7,14 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QApplication>
|
||||
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
#include <components/misc/constants.hpp>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
#include "../widget/scenetooltoggle2.hpp"
|
||||
#include "../widget/scenetoolmode.hpp"
|
||||
#include "../widget/scenetooltoggle2.hpp"
|
||||
|
||||
#include "editmode.hpp"
|
||||
#include "mask.hpp"
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/commandmacro.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
|
||||
#include "../widget/scenetoolbar.hpp"
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
|
||||
#include "lighting.hpp"
|
||||
#include "mask.hpp"
|
||||
|
|
|
@ -39,64 +39,23 @@ std::vector<std::pair<int, int>> CSVRender::TerrainSelection::getTerrainSelectio
|
|||
void CSVRender::TerrainSelection::onlySelect(const std::vector<std::pair<int, int>> &localPositions)
|
||||
{
|
||||
mSelection = localPositions;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void CSVRender::TerrainSelection::addSelect(const std::pair<int, int> &localPos)
|
||||
void CSVRender::TerrainSelection::addSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
|
||||
{
|
||||
if (std::find(mSelection.begin(), mSelection.end(), localPos) == mSelection.end())
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
update();
|
||||
}
|
||||
handleSelection(localPositions, toggleInProgress, SelectionMethod::AddSelect);
|
||||
}
|
||||
|
||||
void CSVRender::TerrainSelection::toggleSelect(const std::vector<std::pair<int, int>> &localPositions, bool toggleInProgress)
|
||||
void CSVRender::TerrainSelection::removeSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
|
||||
{
|
||||
if (toggleInProgress)
|
||||
{
|
||||
for(auto const& localPos: localPositions)
|
||||
{
|
||||
auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
|
||||
mDraggedOperationFlag = true;
|
||||
handleSelection(localPositions, toggleInProgress, SelectionMethod::RemoveSelect);
|
||||
}
|
||||
|
||||
if (iterTemp == mTemporarySelection.end())
|
||||
{
|
||||
auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
||||
if (iter != mSelection.end())
|
||||
{
|
||||
mSelection.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
}
|
||||
}
|
||||
|
||||
mTemporarySelection.push_back(localPos);
|
||||
}
|
||||
}
|
||||
else if (mDraggedOperationFlag == false)
|
||||
{
|
||||
for(auto const& localPos: localPositions)
|
||||
{
|
||||
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
||||
if (iter != mSelection.end())
|
||||
{
|
||||
mSelection.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mDraggedOperationFlag = false;
|
||||
mTemporarySelection.clear();
|
||||
}
|
||||
update();
|
||||
void CSVRender::TerrainSelection::toggleSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
|
||||
{
|
||||
handleSelection(localPositions, toggleInProgress, SelectionMethod::ToggleSelect);
|
||||
}
|
||||
|
||||
void CSVRender::TerrainSelection::activate()
|
||||
|
@ -239,6 +198,100 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
|
|||
}
|
||||
}
|
||||
|
||||
void CSVRender::TerrainSelection::handleSelection(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod)
|
||||
{
|
||||
if (toggleInProgress)
|
||||
{
|
||||
for (auto const& localPos : localPositions)
|
||||
{
|
||||
auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
|
||||
mDraggedOperationFlag = true;
|
||||
|
||||
if (iterTemp == mTemporarySelection.end())
|
||||
{
|
||||
auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
||||
|
||||
switch (selectionMethod)
|
||||
{
|
||||
case SelectionMethod::AddSelect:
|
||||
if (iter == mSelection.end())
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
}
|
||||
|
||||
break;
|
||||
case SelectionMethod::RemoveSelect:
|
||||
if (iter != mSelection.end())
|
||||
{
|
||||
mSelection.erase(iter);
|
||||
}
|
||||
|
||||
break;
|
||||
case SelectionMethod::ToggleSelect:
|
||||
if (iter == mSelection.end())
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelection.erase(iter);
|
||||
}
|
||||
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
mTemporarySelection.push_back(localPos);
|
||||
}
|
||||
}
|
||||
else if (mDraggedOperationFlag == false)
|
||||
{
|
||||
for (auto const& localPos : localPositions)
|
||||
{
|
||||
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
|
||||
|
||||
switch (selectionMethod)
|
||||
{
|
||||
case SelectionMethod::AddSelect:
|
||||
if (iter == mSelection.end())
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
}
|
||||
|
||||
break;
|
||||
case SelectionMethod::RemoveSelect:
|
||||
if (iter != mSelection.end())
|
||||
{
|
||||
mSelection.erase(iter);
|
||||
}
|
||||
|
||||
break;
|
||||
case SelectionMethod::ToggleSelect:
|
||||
if (iter == mSelection.end())
|
||||
{
|
||||
mSelection.emplace_back(localPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelection.erase(iter);
|
||||
}
|
||||
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mDraggedOperationFlag = false;
|
||||
|
||||
mTemporarySelection.clear();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
bool CSVRender::TerrainSelection::noCell(const std::string& cellId)
|
||||
{
|
||||
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
|
||||
|
|
|
@ -27,6 +27,14 @@ namespace CSVRender
|
|||
Shape
|
||||
};
|
||||
|
||||
enum class SelectionMethod
|
||||
{
|
||||
OnlySelect,
|
||||
AddSelect,
|
||||
RemoveSelect,
|
||||
ToggleSelect
|
||||
};
|
||||
|
||||
/// \brief Class handling the terrain selection data and rendering
|
||||
class TerrainSelection
|
||||
{
|
||||
|
@ -36,7 +44,8 @@ namespace CSVRender
|
|||
~TerrainSelection();
|
||||
|
||||
void onlySelect(const std::vector<std::pair<int, int>> &localPositions);
|
||||
void addSelect(const std::pair<int, int> &localPos);
|
||||
void addSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress);
|
||||
void removeSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress);
|
||||
void toggleSelect(const std::vector<std::pair<int, int>> &localPositions, bool toggleInProgress);
|
||||
|
||||
void activate();
|
||||
|
@ -55,6 +64,8 @@ namespace CSVRender
|
|||
|
||||
private:
|
||||
|
||||
void handleSelection(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod);
|
||||
|
||||
bool noCell(const std::string& cellId);
|
||||
|
||||
bool noLand(const std::string& cellId);
|
||||
|
|
|
@ -25,18 +25,16 @@
|
|||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/commandmacro.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
#include "../../model/world/land.hpp"
|
||||
#include "../../model/world/resourcetable.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
#include "brushdraw.hpp"
|
||||
#include "commands.hpp"
|
||||
#include "editmode.hpp"
|
||||
#include "pagedworldspacewidget.hpp"
|
||||
#include "mask.hpp"
|
||||
|
@ -45,7 +43,7 @@
|
|||
#include "worldspacewidget.hpp"
|
||||
|
||||
CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
|
||||
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain | Mask_Reference, "Terrain land editing", parent),
|
||||
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain, "Terrain land editing", parent),
|
||||
mParentNode(parentNode)
|
||||
{
|
||||
}
|
||||
|
@ -288,6 +286,9 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
|||
|
||||
undoStack.beginMacro ("Edit shape and normal records");
|
||||
|
||||
// One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes.
|
||||
undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget()));
|
||||
|
||||
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
|
||||
{
|
||||
std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY());
|
||||
|
@ -356,6 +357,9 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
|
|||
}
|
||||
pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId);
|
||||
}
|
||||
// One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes.
|
||||
undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget()));
|
||||
|
||||
undoStack.endMacro();
|
||||
clearTransientEdits();
|
||||
}
|
||||
|
@ -433,7 +437,9 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair<int, int>
|
|||
float smoothedByDistance = 0.0f;
|
||||
if (mShapeEditTool == ShapeEditTool_Drag) smoothedByDistance = calculateBumpShape(distance, r, mTotalDiffY);
|
||||
if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) smoothedByDistance = calculateBumpShape(distance, r, r + mShapeEditToolStrength);
|
||||
if (distance <= r)
|
||||
|
||||
// Using floating-point radius here to prevent selecting too few vertices.
|
||||
if (distance <= mBrushSize / 2.0f)
|
||||
{
|
||||
if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, smoothedByDistance);
|
||||
if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower)
|
||||
|
@ -1036,10 +1042,35 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob
|
|||
return;
|
||||
int selectionX = globalSelectionX;
|
||||
int selectionY = globalSelectionY;
|
||||
if (xIsAtCellBorder)
|
||||
|
||||
/*
|
||||
The northern and eastern edges don't belong to the current cell.
|
||||
If the corresponding adjacent cell is not loaded, some special handling is necessary to select border vertices.
|
||||
*/
|
||||
if (xIsAtCellBorder && yIsAtCellBorder)
|
||||
{
|
||||
/*
|
||||
Handle the NW, NE, and SE corner vertices.
|
||||
NW corner: (+1, -1) offset to reach current cell.
|
||||
NE corner: (-1, -1) offset to reach current cell.
|
||||
SE corner: (-1, +1) offset to reach current cell.
|
||||
*/
|
||||
if (isInCellSelection(globalSelectionX - 1, globalSelectionY - 1)
|
||||
|| isInCellSelection(globalSelectionX + 1, globalSelectionY - 1)
|
||||
|| isInCellSelection(globalSelectionX - 1, globalSelectionY + 1))
|
||||
{
|
||||
selections->emplace_back(globalSelectionX, globalSelectionY);
|
||||
}
|
||||
}
|
||||
else if (xIsAtCellBorder)
|
||||
{
|
||||
selectionX--;
|
||||
if (yIsAtCellBorder)
|
||||
}
|
||||
else if (yIsAtCellBorder)
|
||||
{
|
||||
selectionY--;
|
||||
}
|
||||
|
||||
if (isInCellSelection(selectionX, selectionY))
|
||||
selections->emplace_back(globalSelectionX, globalSelectionY);
|
||||
}
|
||||
|
@ -1074,8 +1105,11 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
|||
{
|
||||
int distanceX = abs(i - vertexCoords.first);
|
||||
int distanceY = abs(j - vertexCoords.second);
|
||||
int distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
|
||||
if (distance <= r) handleSelection(i, j, &selections);
|
||||
float distance = sqrt(pow(distanceX, 2)+pow(distanceY, 2));
|
||||
|
||||
// Using floating-point radius here to prevent selecting too few vertices.
|
||||
if (distance <= mBrushSize / 2.0f)
|
||||
handleSelection(i, j, &selections);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1092,9 +1126,21 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
|
|||
}
|
||||
}
|
||||
|
||||
if(selectMode == 0) mTerrainShapeSelection->onlySelect(selections);
|
||||
if(selectMode == 1) mTerrainShapeSelection->toggleSelect(selections, dragOperation);
|
||||
std::string selectAction;
|
||||
|
||||
if (selectMode == 0)
|
||||
selectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString();
|
||||
else
|
||||
selectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString();
|
||||
|
||||
if (selectAction == "Select only")
|
||||
mTerrainShapeSelection->onlySelect(selections);
|
||||
else if (selectAction == "Add to selection")
|
||||
mTerrainShapeSelection->addSelect(selections, dragOperation);
|
||||
else if (selectAction == "Remove from selection")
|
||||
mTerrainShapeSelection->removeSelect(selections, dragOperation);
|
||||
else if (selectAction == "Invert selection")
|
||||
mTerrainShapeSelection->toggleSelect(selections, dragOperation);
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,
|
||||
|
@ -1398,6 +1444,11 @@ void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event)
|
|||
mBrushDraw->hide();
|
||||
}
|
||||
|
||||
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainShapeMode::getTerrainSelection()
|
||||
{
|
||||
return mTerrainShapeSelection;
|
||||
}
|
||||
|
||||
void CSVRender::TerrainShapeMode::setBrushSize(int brushSize)
|
||||
{
|
||||
mBrushSize = brushSize;
|
||||
|
|
|
@ -92,6 +92,8 @@ namespace CSVRender
|
|||
void dragMoveEvent (QDragMoveEvent *event) override;
|
||||
void mouseMoveEvent (QMouseEvent *event) override;
|
||||
|
||||
std::shared_ptr<TerrainSelection> getTerrainSelection();
|
||||
|
||||
private:
|
||||
|
||||
/// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse
|
||||
|
@ -176,7 +178,7 @@ namespace CSVRender
|
|||
int mDragMode = InteractionType_None;
|
||||
osg::Group* mParentNode;
|
||||
bool mIsEditing = false;
|
||||
std::unique_ptr<TerrainSelection> mTerrainShapeSelection;
|
||||
std::shared_ptr<TerrainSelection> mTerrainShapeSelection;
|
||||
int mTotalDiffY = 0;
|
||||
std::vector<CSMWorld::CellCoordinates> mAlteredCells;
|
||||
osg::Vec3d mEditingPos;
|
||||
|
|
|
@ -12,23 +12,17 @@
|
|||
|
||||
#include <osg/Group>
|
||||
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
#include "../widget/modebutton.hpp"
|
||||
#include "../widget/scenetoolbar.hpp"
|
||||
#include "../widget/scenetooltexturebrush.hpp"
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/commandmacro.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
#include "../../model/world/land.hpp"
|
||||
#include "../../model/world/landtexture.hpp"
|
||||
#include "../../model/world/resourcetable.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../widget/brushshapes.hpp"
|
||||
|
@ -332,7 +326,7 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
|
|||
|
||||
int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex);
|
||||
|
||||
std::size_t hashlocation = mBrushTexture.find("#");
|
||||
std::size_t hashlocation = mBrushTexture.find('#');
|
||||
std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1);
|
||||
int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +1
|
||||
|
||||
|
@ -718,6 +712,11 @@ void CSVRender::TerrainTextureMode::mouseMoveEvent (QMouseEvent *event)
|
|||
mBrushDraw->hide();
|
||||
}
|
||||
|
||||
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainTextureMode::getTerrainSelection()
|
||||
{
|
||||
return mTerrainTextureSelection;
|
||||
}
|
||||
|
||||
|
||||
void CSVRender::TerrainTextureMode::setBrushSize(int brushSize)
|
||||
{
|
||||
|
|
|
@ -85,6 +85,8 @@ namespace CSVRender
|
|||
|
||||
void mouseMoveEvent (QMouseEvent *event) override;
|
||||
|
||||
std::shared_ptr<TerrainSelection> getTerrainSelection();
|
||||
|
||||
private:
|
||||
/// \brief Handle brush mechanics, maths regarding worldspace hit etc.
|
||||
void editTerrainTextureGrid (const WorldspaceHitResult& hit);
|
||||
|
@ -115,7 +117,7 @@ namespace CSVRender
|
|||
int mDragMode;
|
||||
osg::Group* mParentNode;
|
||||
bool mIsEditing;
|
||||
std::unique_ptr<TerrainSelection> mTerrainTextureSelection;
|
||||
std::shared_ptr<TerrainSelection> mTerrainTextureSelection;
|
||||
|
||||
const int cellSize {ESM::Land::REAL_SIZE};
|
||||
const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE};
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
|
||||
#include "../widget/scenetooltoggle.hpp"
|
||||
#include "../widget/scenetooltoggle2.hpp"
|
||||
|
||||
#include "cameracontroller.hpp"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
||||
#include "../render/orbitcameramode.hpp"
|
||||
|
@ -453,6 +452,11 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo
|
|||
return hit;
|
||||
}
|
||||
|
||||
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
|
||||
{
|
||||
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::abortDrag()
|
||||
{
|
||||
if (mDragging)
|
||||
|
@ -698,11 +702,6 @@ void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitRes
|
|||
editMode.primaryOpenPressed (hit);
|
||||
}
|
||||
|
||||
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
|
||||
{
|
||||
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::primaryOpen(bool activate)
|
||||
{
|
||||
handleInteraction(InteractionType_PrimaryOpen, activate);
|
||||
|
|
|
@ -189,6 +189,8 @@ namespace CSVRender
|
|||
/// Erase all overrides and restore the visual representation to its true state.
|
||||
virtual void reset (unsigned int elementMask) = 0;
|
||||
|
||||
EditMode *getEditMode();
|
||||
|
||||
protected:
|
||||
|
||||
/// Visual elements in a scene
|
||||
|
@ -215,8 +217,6 @@ namespace CSVRender
|
|||
|
||||
void settingChanged (const CSMPrefs::Setting *setting) override;
|
||||
|
||||
EditMode *getEditMode();
|
||||
|
||||
bool getSpeedMode();
|
||||
|
||||
private:
|
||||
|
|
|
@ -30,7 +30,7 @@ void CSVWidget::SceneToolRun::updateIcon()
|
|||
|
||||
void CSVWidget::SceneToolRun::updatePanel()
|
||||
{
|
||||
mTable->setRowCount (mProfiles.size());
|
||||
mTable->setRowCount (static_cast<int>(mProfiles.size()));
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
|
|
@ -27,11 +27,6 @@
|
|||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idcollection.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/landtexture.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
|
||||
|
||||
CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString &title, QWidget *parent)
|
||||
|
|
|
@ -80,7 +80,7 @@ QRect CSVWidget::SceneToolToggle::getIconBox (int index) const
|
|||
int y = index / xMax;
|
||||
int x = index % xMax;
|
||||
|
||||
int total = mButtons.size();
|
||||
int total = static_cast<int>(mButtons.size());
|
||||
|
||||
int actualYIcons = total/xMax;
|
||||
|
||||
|
@ -154,7 +154,7 @@ void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned in
|
|||
desc.mMask = mask;
|
||||
desc.mSmallIcon = smallIcon;
|
||||
desc.mName = name;
|
||||
desc.mIndex = mButtons.size();
|
||||
desc.mIndex = static_cast<int>(mButtons.size());
|
||||
|
||||
mButtons.insert (std::make_pair (button, desc));
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id, unsigned int mask,
|
|||
desc.mButtonId = id;
|
||||
desc.mMask = mask;
|
||||
desc.mName = name;
|
||||
desc.mIndex = mButtons.size();
|
||||
desc.mIndex = static_cast<int>(mButtons.size());
|
||||
|
||||
mButtons.insert (std::make_pair (button, desc));
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "../widget/coloreditor.hpp"
|
||||
|
||||
CSVWorld::ColorDelegate::ColorDelegate(CSMWorld::CommandDispatcher *dispatcher,
|
||||
CSMDoc::Document& document,
|
||||
QObject *parent)
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con
|
|||
|
||||
if (!mNamespace.empty())
|
||||
{
|
||||
std::string namespace_ = input.left (mNamespace.size()).toUtf8().constData();
|
||||
std::string namespace_ = input.left (static_cast<int>(mNamespace.size())).toUtf8().constData();
|
||||
|
||||
if (Misc::StringUtils::lowerCase (namespace_)!=mNamespace)
|
||||
return QValidator::Invalid; // incorrect namespace
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "../render/pagedworldspacewidget.hpp"
|
||||
#include "../render/unpagedworldspacewidget.hpp"
|
||||
#include "../render/editmode.hpp"
|
||||
|
||||
#include "../widget/scenetoolbar.hpp"
|
||||
#include "../widget/scenetoolmode.hpp"
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
|
|
@ -184,7 +184,7 @@ if(APPLE)
|
|||
|
||||
add_subdirectory(../../files/ ${CMAKE_CURRENT_BINARY_DIR}/files)
|
||||
|
||||
configure_file("${OpenMW_BINARY_DIR}/settings-default.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY)
|
||||
configure_file("${OpenMW_BINARY_DIR}/defaults.bin" ${BUNDLE_RESOURCES_DIR} COPYONLY)
|
||||
configure_file("${OpenMW_BINARY_DIR}/openmw.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY)
|
||||
configure_file("${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" ${BUNDLE_RESOURCES_DIR} COPYONLY)
|
||||
|
||||
|
|
|
@ -496,8 +496,8 @@ void OMW::Engine::setSkipMenu (bool skipMenu, bool newGame)
|
|||
std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
||||
{
|
||||
// Create the settings manager and load default settings file
|
||||
const std::string localdefault = (mCfgMgr.getLocalPath() / "settings-default.cfg").string();
|
||||
const std::string globaldefault = (mCfgMgr.getGlobalPath() / "settings-default.cfg").string();
|
||||
const std::string localdefault = (mCfgMgr.getLocalPath() / "defaults.bin").string();
|
||||
const std::string globaldefault = (mCfgMgr.getGlobalPath() / "defaults.bin").string();
|
||||
|
||||
// prefer local
|
||||
if (boost::filesystem::exists(localdefault))
|
||||
|
@ -505,7 +505,7 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
|||
else if (boost::filesystem::exists(globaldefault))
|
||||
settings.loadDefault(globaldefault);
|
||||
else
|
||||
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
|
||||
throw std::runtime_error ("No default settings file found! Make sure the file \"defaults.bin\" was properly installed.");
|
||||
|
||||
// load user settings if they exist
|
||||
const std::string settingspath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string();
|
||||
|
@ -1081,6 +1081,8 @@ void OMW::Engine::go()
|
|||
// Save user settings
|
||||
settings.saveUser(settingspath);
|
||||
|
||||
mViewer->stopThreading();
|
||||
|
||||
Log(Debug::Info) << "Quitting peacefully.";
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
desc.add_options()
|
||||
("help", "print help message")
|
||||
("version", "print version information and quit")
|
||||
|
||||
("replace", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "")
|
||||
->multitoken()->composing(), "settings where the values from the current source should replace those from lower-priority sources instead of being appended")
|
||||
|
||||
("data", bpo::value<Files::EscapePathContainer>()->default_value(Files::EscapePathContainer(), "data")
|
||||
->multitoken()->composing(), "set data directories (later directories have higher priority)")
|
||||
|
||||
|
@ -192,6 +196,15 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
Log(Debug::Error) << "No content file given (esm/esp, nor omwgame/omwaddon). Aborting...";
|
||||
return false;
|
||||
}
|
||||
std::set<std::string> contentDedupe;
|
||||
for (const auto& contentFile : content)
|
||||
{
|
||||
if (!contentDedupe.insert(contentFile).second)
|
||||
{
|
||||
Log(Debug::Error) << "Content file specified more than once: " << contentFile << ". Aborting...";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& file : content)
|
||||
{
|
||||
|
|
|
@ -301,7 +301,7 @@ namespace MWBase
|
|||
virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z, bool movePhysics=true) = 0;
|
||||
///< @return an updated Ptr
|
||||
|
||||
virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, osg::Vec3f vec, bool moveToActive) = 0;
|
||||
virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, osg::Vec3f vec, bool moveToActive, bool ignoreCollisions) = 0;
|
||||
///< @return an updated Ptr
|
||||
|
||||
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "../mwworld/failedaction.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/localscripts.hpp"
|
||||
|
||||
|
|
|
@ -132,12 +132,14 @@ namespace MWClass
|
|||
MWBase::Environment::get().getWorld()->getMaxActivationDistance())
|
||||
{
|
||||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr);
|
||||
if(animation)
|
||||
{
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
int index = ESM::MagicEffect::effectStringToId("sEffectTelekinesis");
|
||||
const ESM::MagicEffect *effect = store.get<ESM::MagicEffect>().find(index);
|
||||
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
int index = ESM::MagicEffect::effectStringToId("sEffectTelekinesis");
|
||||
const ESM::MagicEffect *effect = store.get<ESM::MagicEffect>().find(index);
|
||||
|
||||
animation->addSpellCastGlow(effect, 1); // 1 second glow to match the time taken for a door opening or closing
|
||||
animation->addSpellCastGlow(effect, 1); // 1 second glow to match the time taken for a door opening or closing
|
||||
}
|
||||
}
|
||||
|
||||
const std::string keyId = ptr.getCellRef().getKey();
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "../mwworld/failedaction.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/localscripts.hpp"
|
||||
|
||||
|
|
|
@ -343,7 +343,7 @@ namespace MWDialogue
|
|||
if(!inJournal(topicId, answer->mId))
|
||||
{
|
||||
// Does this dialogue contains some actor-specific answer?
|
||||
if (answer->mActor == mActor.getCellRef().getRefId())
|
||||
if (Misc::StringUtils::ciEqual(answer->mActor, mActor.getCellRef().getRefId()))
|
||||
flag |= MWBase::DialogueManager::TopicType::Specific;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "../mwbase/journal.hpp"
|
||||
|
||||
#include "journalentry.hpp"
|
||||
#include "quest.hpp"
|
||||
|
||||
namespace MWDialogue
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <components/widgets/widgets.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
#include <components/compiler/exception.hpp>
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
#include <components/compiler/lineparser.hpp>
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/locals.hpp>
|
||||
#include <components/interpreter/interpreter.hpp>
|
||||
|
||||
#include "../mwscript/extensions.hpp"
|
||||
|
||||
|
|
|
@ -6,12 +6,8 @@
|
|||
#include <vector>
|
||||
|
||||
#include <components/compiler/errorhandler.hpp>
|
||||
#include <components/compiler/lineparser.hpp>
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/locals.hpp>
|
||||
#include <components/compiler/output.hpp>
|
||||
#include <components/compiler/extensions.hpp>
|
||||
#include <components/interpreter/interpreter.hpp>
|
||||
|
||||
#include "../mwscript/compilercontext.hpp"
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
#include "../mwmechanics/aipackage.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/summoning.hpp"
|
||||
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
|
||||
|
@ -268,6 +270,23 @@ namespace MWGui
|
|||
for (const auto& creature : creatureMap)
|
||||
MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(ptr, creature.second);
|
||||
creatureMap.clear();
|
||||
|
||||
// Check if we are a summon and inform our master we've bit the dust
|
||||
for(const auto& package : creatureStats.getAiSequence())
|
||||
{
|
||||
if(package->followTargetThroughDoors() && !package->getTarget().isEmpty())
|
||||
{
|
||||
const auto& summoner = package->getTarget();
|
||||
auto& summons = summoner.getClass().getCreatureStats(summoner).getSummonedCreatureMap();
|
||||
auto it = std::find_if(summons.begin(), summons.end(), [&] (const auto& entry) { return entry.second == creatureStats.getActorId(); });
|
||||
if(it != summons.end())
|
||||
{
|
||||
MWMechanics::purgeSummonEffect(summoner, *it);
|
||||
summons.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWorld()->deleteObject(ptr);
|
||||
|
|
|
@ -310,7 +310,7 @@ namespace MWGui
|
|||
deleteLater();
|
||||
for (Link* link : mLinks)
|
||||
delete link;
|
||||
for (auto link : mTopicLinks)
|
||||
for (const auto& link : mTopicLinks)
|
||||
delete link.second;
|
||||
for (auto history : mHistoryContents)
|
||||
delete history;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
#include <MyGUI_FactoryManager.h>
|
||||
#include <MyGUI_Gui.h>
|
||||
#include <MyGUI_ImageBox.h>
|
||||
#include <MyGUI_TextBox.h>
|
||||
#include <MyGUI_ScrollView.h>
|
||||
#include <MyGUI_Button.h>
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex ()
|
|||
mIndexPagesCount = 2;
|
||||
}
|
||||
|
||||
unsigned char ch[2] = {0xd0, 0x90}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8
|
||||
unsigned char ch[3] = {0xd0, 0x90, 0x00}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/inputmanager.hpp"
|
||||
|
||||
#include "../mwrender/vismask.hpp"
|
||||
|
||||
#include "backgroundimage.hpp"
|
||||
|
||||
namespace MWGui
|
||||
|
@ -103,7 +101,7 @@ namespace MWGui
|
|||
Log(Debug::Warning) << "Warning: no splash screens found!";
|
||||
}
|
||||
|
||||
void LoadingScreen::setLabel(const std::string &label, bool important, bool center)
|
||||
void LoadingScreen::setLabel(const std::string &label, bool important)
|
||||
{
|
||||
mImportantLabel = important;
|
||||
|
||||
|
@ -113,7 +111,7 @@ namespace MWGui
|
|||
size.width = std::max(300, size.width);
|
||||
mLoadingBox->setSize(size);
|
||||
|
||||
if (center)
|
||||
if (MWBase::Environment::get().getWindowManager()->getMessagesCount() > 0)
|
||||
mLoadingBox->setPosition(mMainWidget->getWidth()/2 - mLoadingBox->getWidth()/2, mMainWidget->getHeight()/2 - mLoadingBox->getHeight()/2);
|
||||
else
|
||||
mLoadingBox->setPosition(mMainWidget->getWidth()/2 - mLoadingBox->getWidth()/2, mMainWidget->getHeight() - mLoadingBox->getHeight() - 8);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <osg/Camera>
|
||||
#include <osg/Timer>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
|
@ -38,7 +37,7 @@ namespace MWGui
|
|||
virtual ~LoadingScreen();
|
||||
|
||||
/// Overridden from Loading::Listener, see the Loading::Listener documentation for usage details
|
||||
void setLabel (const std::string& label, bool important, bool center) override;
|
||||
void setLabel (const std::string& label, bool important) override;
|
||||
void loadingOn(bool visible=true) override;
|
||||
void loadingOff() override;
|
||||
void setProgressRange (size_t range) override;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/pickpocket.hpp"
|
||||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue