Skip to content

SDL - #3431

Draft
philocalyst wants to merge 31 commits into
RigsOfRods:masterfrom
philocalyst:oh-more
Draft

SDL#3431
philocalyst wants to merge 31 commits into
RigsOfRods:masterfrom
philocalyst:oh-more

Conversation

@philocalyst

Copy link
Copy Markdown

No description provided.

ohlidalp and others added 26 commits June 23, 2026 14:30
Joint effort by @ohlidalp, @tritonas00, @CuriousMike56 and @AnotherFoxGuy (Edgar)

This is a minimal viable port - no RTSS, no change to existing Cg shaders (nicemetal, Caelum, PSSM).

NOTE: under Dx11 be sure to have 'diag_warning_texture=Yes' otherwise you get crash at startup.

Changes made:
* OgreAngelscript.cpp: fixed build error - with OGRE_FAST_MATH defined functions `isNAN()` aren't present.
* TerrainGeometryManager.cpp: OTC file format: made normalheight texture optional.
* Update dependency fmt to v12
* Building OGRE with resourcemanager_strict=off
* Disabled OGRE build option `OGRE_NODELESS_POSITIONING` (no longer needed - scene nodes are used everywhere)
* Media: fix corrupted DDS texture crashing under D3D9
* Caelum time slider: restored original code (it works with latest Ogre master branch)
* Fixed Imgui inverted colours on DirectX 9
* Fixed missing MyGUI shaders and rendering issues
* MyGUI RTT layers, originally removed, got restored and extended.

Changes to OGRE-AngelScript bindings, reflecting changes in OGRE API:
* OverlayManager::getTemplates() // removed
* OverlayManager::isTemplate() // removed
* SceneNode::getAttachedObject() // now const
* SceneNode::hideBoundingBox() // removed
* SceneNode::getAutoTrackTarget() // now const
* SceneNode::getAutoTrackOffset() // now const
* SceneNode::getAutoTrackLocalDirection() // now const
* SceneNode::setVisible() // now const
* SceneNode::flipVisibility() // now const
* SceneNode::setDebugDisplayEnabled() // now const

Co-authored-by: Edgar <Edgar@AnotherFoxGuy.com>
Co-authored-by: tritonas00 <tritonas00@gmail.com>
Co-authored-by: CuriousMike56 <46073351+CuriousMike56@users.noreply.github.com>
User-facing features:
- new cvar `diag_profiler_enabled` (bool) - always false on startup, can be activated via console `set diag_profiler_enabled 1`
- new cvar `diag_profiler_rate` (int) - sampling rate of the profiler, defaults to 10 frames. Strored in RoR.cfg.
Notes:
- '3d_*.overlay' files were unused - leftovers from recent removal of renderdash, see RigsOfRods#3423
- file 'managed_submesh.material' was unused
- '*.asm' shaders are no longer supported by OGRE
Leftovers from unused truck & boat overlays were deleted - both from resources and code.
Materials of remaining overlays (aerial, pressure, directionarrow, racing) were split from 'materials/ror.material' to 'overlays/*.material', one to one with overlay files.
All material/overlay warnings in RoR.log were adressed.
Turns out I've misunderstood the 'inGlobalPool' flag - I thought it exposed the resources to every other group, but it only creates single "virtual supergroup" where all files must be unique.
Thus for most of our gamefiles loading to global pool has no meaning - to make them visible to mods without mods clashing, each mod must have private RG and all game data must be loaded into it.
This wastes some memory and processing time to repeatedly parse OGRE scripts, but simplifies usage - only one lookup covers all. All present code works this way.
In contrast, using global pool for game data would require game to do 2 lookups: in the per-actor RG first and then fallback to global pool - technically feasible but not worth the work (?).

CHANGES:
* I've manually distributed this flag to all RGs we create, so now we don't rely on OGRE_RESOURCEGROUP_STRICT=OFF for the global fallback - we may still need this option for case-insensitivity though.
* I've also created new RGN_UI_ICONS resource group which merges 'icons','famicons' and 'flags' resource dirs. This prompted me to delete duplicate images from '/icons' that came from '/famicons'.
* In 'ContentManager.h/cpp', I removed the per-resourcepack RGs, all RGs are now covered by `RGN_*` defs in Application.h; Some gamefiles are loaded to `Ogre::RGN_DEFAULT`, others are commented ad-hoc.
* Managed materials for actors were split to 'nicemetal' and 'alternate' dirs, because OGRE complained we can't have `EnvironmentTexture` both use shaders (nicemetal) and not use shaders (alternate). RoR.log: `Error: ScriptCompiler - invalid parameters in texture_manager.material(16):  overriding previous declarations of texture 'EnvironmentTexture' with different parameters`
* Finally, I added a new docs page to clarify how the stuff works and why we use it the way we do.
BEWARE: MyGUI::UString has a constructor that takes a char[N] and buffers up all N chars, even if NULLs. This breaks rendering.
ror.log:
```
00:59:10: Initialising resource group {bundle BIN:\resources\dashboards.zip}
00:59:10: Parsing scripts for resource group {bundle BIN:\resources\dashboards.zip}
00:59:10: Parsing script pssm_shared.program
00:59:10: [RoR] Error while loading 'D:\!RoR builds\ror-win-ogre14minupgrade\resources\dashboards.zip', message: Ogre::InvalidParametersException::InvalidParametersException: The shared parameter set 'pssm_params' already exists! in GpuProgramManager::createSharedParameters at C:\Users\runneradmin\.conan2\p\b\ogre3c74730b67b947\b\OgreMain\src\OgreGpuProgramManager.cpp (line 244)
00:59:10: Destroying resource group {bundle BIN:\resources\dashboards.zip}
```

also:
```
00:59:09: Parsing script pssm_shared.program
00:59:09: Warning: ScriptCompiler - deprecated symbol in pssm_shared.program(3): shared_param_named is deprecated. Use param_named instead
```
Base is initialized for all mod types, Actor only for actors ;)

This also fixes imperfections in the nicemetal/alternate split - common actor materials were separated out, specific labeled accordingly.
Majority of data in 'meshes'/'materials'/'textures' resource dirs were terrain objects, it makes no sense to add them to per-actor resource groups.

Also removed RoR.log message "[RoR|ContentManager] Loading resource pack ..." because it just duplicates OGRE's own "Added resource location ..."
Status: builds and runs OK, but there is no input.

This is a brainless 1:1 replacement of OIS API and events with SDL API and OgreBites input events. I preserved our (very outdated) DearIMGUI integration. All our (quite convoluted) input processing stayed mostly intact. Only mouse/keyboard input is handled, joysticks + controllers + forcefeedback are temporarily disabled.
Status: build and runs, keyboard+mouse working, window is somehow oversized but responsive.

Codechanges:
* creating render window via OgreBites::ApplicationContext instead of OGRE Root directly - needed to receive events
* overriding OgreBites::ApplicationContext::createRoot() with our pre-existing setup code, to initialize `mRoot` as expected.
* calling `OgreBites::ApplicationContext::addInputListener()` to receive events.
Deleted the windows-specific code setting ["monitorIndex"]- apparently OGRE does it by itself in `ApplicationContextSDL::createWindow()`, see OgreApplicationContextSDL.cpp line 56.
Original commit: 128a8e2 - "Attempt to fix the 'Rendering Device' setting" - Ulteq, 4 years ago (29.12.2018 13:53:57)

Also deleted setting ["windowProc"] - doesn't seem to have any effect, perhaps an OIS leftover.
@ohlidalp

ohlidalp commented Jun 23, 2026

Copy link
Copy Markdown
Member

I took the liberty to rebase & force-push, adding minor fixes (to fixup later).
So far I tested keyboard & mouse only - I found minor issues:

  • keyboard navigation in main/pause menu isn't working.
  • in the actor-loader UI, the list navigation and Enter confirmation doesn't work. Typing to searchbox works, though.
  • 3rd person camera orbiting doesn't work. That's on me, the camera manager is awful.
  • 1st person cinecam movement doesn't work. Likely the same issue.

@philocalyst

Copy link
Copy Markdown
Author

THINK the new commit is a fix, will you push changes for the camera work?

@ohlidalp

ohlidalp commented Jun 24, 2026

Copy link
Copy Markdown
Member

Keys are fixed: menu navigations, Enter/Backspace in input boxes, all works.

I've looked to the camera and it turns out SDL_GetMouseState() constantly returns zero. imgui only works because it uses OgreBites events to inject mouse buttons.

I've also hooked my vintage Thrustmaster T100 wheel and... SDL_JoystickGetAxis() returns bogus values. The 'Thrustmaster Control Panel' works OK though.

I'm seeing a pattern here... at least under Windows10 x64 using sdl/2.30.9 we can't rely on direct input querying and have to listen to OgreBites events exclusively. I take it that under your system at least the mouse camera orbit worked?

Update: SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) returns 0, so joystick should work.

@philocalyst

Copy link
Copy Markdown
Author

I'm seeing a pattern here... at least under Windows10 x64 using sdl/2.30.9 we can't rely on direct input querying and have to listen to OgreBites events exclusively. I take it that under your system at least the mouse camera orbit worked?

It did!

So where does this leave us on the PR?

ohlidalp added 2 commits June 24, 2026 23:48
…'t reliable.

at least under Windows10 x64 using sdl/2.30.9, `SDL_GetMouseState()` constantly returns zero.
The mouse button states are actually queried from InputEngine.
@ohlidalp

Copy link
Copy Markdown
Member

I've worked around the mouse buttons by caching states from events.

Next, we need to scavenge for info.

I need to create some test app with just OGRE+SDL and see if it works there. It may be RoR, but it may be windows, too.

@ohlidalp

ohlidalp commented Jun 25, 2026

Copy link
Copy Markdown
Member

Conclusion... it works when done right.
I built OGRE 14.5.2 from source and modified it's 'CharacterSample' to display mouse buttons via SDL_GetMouseState(). I used the same include and lib that OGRE was built against (I built with 'OGRE_BUILD_DEPENDENCIES=ON').
The image below shows a diff with all my edits... I didn't touch SDL_InitSubSystem() at all.

image

@ohlidalp

ohlidalp commented Jun 25, 2026

Copy link
Copy Markdown
Member

@AnotherFoxGuy How can I make sure there's no mixup happening between OGRE conan package and my game devbuild?
I looked into the conanfile and it seems it should match:

  • conan cache path ogre3d/14.5.2@anotherfoxguy/stable returned "C:\Users\ohlidalp.conan2\p\ogre3903876674e29f\e"
  • the conanfile.py says self.requires("sdl/[~2]")
  • conan list *sdl* returns just "sdl/2.30.9" so I assume it got used for both.

I didn't find a way to match a conan build dir to a package, so by trial and error I landed at "c:\Users\ohlidalp.conan2\p\b\ogre3900a2f6d0d7de\b\build" which shows "14-5-2" in 'version.txt'

  • I opened the OGRE.sln ... strangely OgreBites.vcxproj didn't have SDL2 in 'Linker/Input/Additional Dependencies' at all.
  • my OGRE build has SDL2.dll in /bin subdir of builddir, the conan build doesn't. Maybe the problem is static/dynamic linkage.
  • CMakeCache in the conan build showed
    //The directory containing a CMake configuration file for SDL2. SDL2_DIR:PATH=C:/Users/ohlidalp/.conan2/p/b/ogre3900a2f6d0d7de/b/build/generators and the 'SDL2Targets.cmake' suggested there are 3 possible targets: SDL2::SDL2main, SDL2::SDL2-static and SDL2::SDL2
  • I fulltexted my OGRE devbuild dirs (built with 'OGRE_BUILD_DEPENDENCIES=ON') and found this under 'builddir/Dependencies/cmake':
---- SDL2mainTargets.cmake ----
# Create imported target SDL2::SDL2main
add_library(SDL2::SDL2main STATIC IMPORTED)

set_target_properties(SDL2::SDL2main PROPERTIES
  COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include/SDL2"
  INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:shell32>"
  INTERFACE_SDL_VERSION "SDL2"
)
---- SDL2Targets.cmake ----
# Create imported target SDL2::SDL2
add_library(SDL2::SDL2 SHARED IMPORTED)

set_target_properties(SDL2::SDL2 PROPERTIES
  COMPATIBLE_INTERFACE_BOOL "SDL2_SHARED"
  COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include/SDL2"
  INTERFACE_SDL2_SHARED "TRUE"
  INTERFACE_SDL_VERSION "SDL2"
)
---- SDLConfig.cmake ----
# Create SDL2::SDL2 alias for static-only builds
if(TARGET SDL2::SDL2-static AND NOT TARGET SDL2::SDL2)
    add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static)

Finally I opened RoR project properties and saw this:

C:\Users\ohlidalp\.conan2\p\b\sdl2b5f435e448f5\p\lib\SDL2maind.lib
C:\Users\ohlidalp\.conan2\p\b\sdl2b5f435e448f5\p\lib\SDL2-staticd.lib

Removing 'maind' had no effect. Removing '-staticd' caused linking errors because apparently the headers I'm pulling in (C:\Users\ohlidalp.conan2\p\b\sdl2b5f435e448f5\p\include\SDL2\SDL_mouse.h) don't have __declspec(dllimport) on them (the DECLSPEC macro is empty).

Also https://github.com/libsdl-org/SDL/blob/main/docs/README-dynapi.md linked from https://wiki.libsdl.org/SDL2/Installation.

Complicated stuff.

@philocalyst For the time being, I say let's fall back to using OgreBites input events for everything. We may have to cache some inputs locally which isn't ellegant and we'll lose forcefeedback/haptics, but that can be done later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants