OpenBRF Redux — A de-rusted, maintained, bug-fixed version of OpenBRF with 64-bit support and dark mode

Users who are viewing this thread

Swyter

Grandmaster Knight
This is a de-rusted version of Marco Tarini's OpenBRF tool for modding Mount&Blade 1.011 and Warband; it comes with bug fixes and enhancements.

ico48.png
Download and change log here: https://github.com/Swyter/openbrf-redux

The idea is to keep the program well-maintained, develop it openly, and accept suggestions and improvements from the community. :party:

  • Fix the code that registers OpenBRF as the one that opens files with .brf extension for the current user account.
    • It will automatically detect, register the current OpenBRF instance and path, so that even when not set as default the entry is listed among the compatible options in right-click > Open with....
    • And then tries to assign itself as the default handler even on Windows 10+, where Microsoft makes this very awkward.
  • Fix showing the .exe version information and application name on Windows.
    • Improve said information to automatically set the build date as the public version. Add better metadata.
    • Important so that OpenBRF Redux is correctly displayed in the Open with... dialogs, and other places.
  • 64-bit portability improvements, fix some compiler warnings for saving 64-bit integers into 32-bit variables.
  • Improve cross-platform support in the codebase, make it compile and run on Linux out of the box.
    • Remove wide char support for paths when opening files, use UTF-8 everywhere.
    • Fix failing to load the carry_positions.txt on startup on Linux when the locale is non-English, due to how commas are used as separators in other languages like French or Spanish.
  • Make it so that inserted things get added below the selected object and not above, when done for multiple objects caused it to insert backwards.
    • Fixes Separate all frames showing the last frame first on top of the original mesh and the other frames in reverse order after that.
    • Requested by @Dalion and @Erundil.
    • Marco mentions this in the comment, but still does it backwards, there has to be a reason. We'll see. ¯\_(ツ)_/¯
  • Protect against crashes that happened when selecting the last elements of a long BRF and editing the reference data, or when creating at new one in similar circumstances.
  • Port most of the OpenBRF codebase to Qt 6 from Qt 5, use 64-bits versions of things and go from Visual Studio 2017 to 2019. This took a while.
    • Fix vcglib, which is used for the 3D format exp/import. To make it work on modern C++ versions
    • Upgrade the Eigen math library, add a stripped down version of v3.4.0.
  • Completely get rid of my multi-select Qt 5 workaround. No longer needed here.
    • The Qt 6 library authors seemingly fixed the deselect bug. Great!
  • Use the «fusion» theme/Qt style; in Qt 6 this theme will auto-detect system-wide dark mode and change as needed.
  • Improve the 3D view with MSAA x4, and the drawing quality in general:
    • Add multisampling antialiasing, reducing jaggies.
    • Raise the needed version to OpenGL 3.0 and fix the floating probe not working when using MSAA.
    • Use adaptive vsync, so that the framerate is locked only when the graphics card can keep up, if things are slow allow screen tearing, so that we don't get slowdowns.
  • Fix length being written as lenght all over the codebase. Update the translation files manually.
    • Small typo fix: WarBandWarband in the file picker. Update the translation files.
    • Fix a typo in the code: FemininzationFeminization.
  • Fix the view-mode status bar buttons not firing or doing anything on Qt 6 as well as the animation playback controls not showing/hiding/refreshing properly on events.
  • Improve "Retina"-style/4K screen support. Fix the floating probe cursor click position when scaling up the interface.
    • Disable the WindowsArguments = dpiawareness=0 in qt.conf that Marco added.
    • Add a handy explanation of how to disable dark mode instead.
  • Make the list elements appear with light-over-dark colors while the rest of the interface is in dark mode.
    • Keep the original black-on-white colors otherwise.
    • Should improve the color contrast of the scrollbar issues reported by @kraggrim and @heino.
    • Use a light blue for the elements that are being used in the mod and a less dark gray for the unused ones.
  • Make OpenBRF accept Unicode/non-English glyphs for paths when importing or saving OBJ files.
    • Plus, avoid mojibake in imported names for meshes and collision bodies. Suggested by @Erundil.
  • Make the roto-translate tool alignment icons vertical for the Y axis, making them way more intuitive to use. Suggested by @tos1.
  • Expand the weapon-measuring ruler tool to show up to 9 meters instead of 3 by default. By using the numeric input one can enlarge it and measure up to 99 meters. :fruity:
  • Add a new contextual option to reverse any skeletal animations, making them go backwards. Suggested by @Dalion.
  • Add a similar option for reversing the timeline of vertex animations in meshes. This also flips their frame times.
  • Make it so that we can move all LODs to the end of the list by holding Shift while clicking on Tools > Sort entries. Useful to make room and gaining extra clarity in big files. Suggested by @Cokjan.
  • Fix a crash reported by @NouH when reading textures with an incomplete mipmap chain, where the last mip (index 6) is 2x8 pixels.
    • Leave a bit of secret extra padding for alignment just in case glGetTexImage() tries to write past the end of the decoded mipmap texture buffer and overflows the stack. Go figure.
  • Fix a few typos: action.txtactions.txt, globlalglobal, shiftShift.
  • Fix a bunch of typos found by @tos1 while translating, make a few hardcoded English strings translatable.
  • Add the initial version of @tos1's Japanese translation. It already covers 100% of the GUI.
  • Improve and update my Spanish translation from 2010. Go figure.
  • Fix a regression that made it impossible to change vertex animation frames on skinned meshes when the skeletal animation is set to «no animation», female armor variants still play skeletal animations just fine. Reported by @Dalion.
  • Avoid mojibake in non-English text that is hardcoded in the source code by loading the strings with UTF-8 encoding instead of Latin1.
  • Hopefully fix another regression with redo/undo/repeat in the roto-translate tool after making it possible to move the 3D camera while editing.
    • Also fix the 3D view not refreshing on Ctrl + R, when repeating the action. All this took a lot of research.
  • Make the repeat action/Ctrl+R functionality more apparent by moving it from the Tools menu to the end of the Editmenu.
    • It was almost hidden, not even long-time modders knew about it, me included. Suggested by @kraggrim.
  • Improve the green (RGBA/0X0Y) or blue (RGBA/XY__) normal map detection by looking at the averaged texture pixel values and analyzing which one is more likely. Fixes the bride_dressmesh showing in pure black with glitchy white sparkles when bump mapping is enabled in the viewer, reported by @Erundil.
    • Marco just assumed every normal map texture with an alpha channel (so DDS files with DXT3 or DXT5 encoding) would be of the green kind, which is often the case as blue ones are often DXT1, but bride_dress_normalmap is a standard blue/magenta one with the same alpha channel as in the diffuse texture, probably put there by mistake.
    • Keep in mind that the analysis only works for textures with mipmaps. You generally don't want normal maps with only a single mip, because they will look pixelated and weird in the distance.
  • Conditionally enable anisotropic filtering with the maximum amount of taps for a less blurry viewport at oblique angles, like when looking at walls sideways.
  • Fix a few typos: DeafultDefault.
  • Allow live editing with the Roto-scale-translatetool while using the 3D view, moving the camera and being able to change the view modes like texture/wireframe.
    • Mentioned by @kraggrim but it's something I've always wanted to do.
    • Had to bend the rules around modal windows a bit, and disable a bunch of menus and GUI panels to avoid breaking everything.
  • Improve «Import > Anything from a BRF file» to support selecting (and importing) multiple BRF files in the open dialog at once.
    • Suggested by @madsci on Discord.
  • Add Alt+R as the key shortcut to open Roto-translate-rescale. Suggested by @kraggrim.
  • Add the Ctrl+Shift+S shortcut to File > Save As. Also suggested by @kraggrim.
  • Fix multi-selection with Ctrl and Shiftwhen combined with my double-click LOD/multipart selection hack.
    • Now we can select all the meshes from multiple objects without deselecting what came before. Reported by @kraggrim.
  • Add the Redux moniker to the main title bar, to distinguish it from the original program.
  • Fix OpenBRF switching to female versions of armour mesh when playing back skeletal animations. Suggested by @Earendil.
  • Fix the double right-clicking multi-mesh selection reset bug via some cursed workaround.
    • After trying for days to diagnose and track down this weird mix of Qt/OpenBRF bugs.
  • Add a new button in the transform texture coords tool to invert the texture UV coordinates in the horizontal dimension, not only vertically. Suggested by @kraggrim.
    • I believe the button actions were inverted from the start, Flipping U should flip it horizontally (X coordinate) and V vertically (Y coordinate). So changed that, too.
  • Fix a few typos: Transfrom ⇢ Transform, trasnfer ⇢ transfer.
  • Add an «Apply to last selected object only» checkbox to the vertex color tool, similar to the one in the roto-rescale tool. Suggested by @kraggrim.
  • Add two checkboxes to the roto-translate-rescale dialog tool, to independently switch between local and global rotation/scaling. By default everything is local, until now OpenBRF only supported global transforms.
    • Use the center point of all the selected elements when the «Apply to last element» checkbox is off, and keep using the center of just the last element when on. That way everything rotates nicely around their own shapes as expected.
    • Change the order of operations in the roto-translate-rescale tool from translation ⇢ rotation ⇢ scaling, to translation ⇢ scaling ⇢ rotation to avoid shearing.
  • Rename the customPreviewShaders.xml file to avoid throwing GLSL errors, for the time being. That way it stays there but doesn't get loaded.
  • Add the build time and a small | Redux suffix into the «About» menu.
  • Reduce the limitations when there are long lists of elements in text files. Raise the maximum .txt file reader line length and parser token count (to 512).
    • The limit for tokens in a single line for the OpenBRF .txt file parser was 256, which may fall short when there are many faces or materials in skins.txt and other similar files; raise it to 512. Dedicated to @Tocan.
  • Add support for detecting meshes with the _fem suffix as being used/mark them as blue, suggested by @Erundil.
  • Add the hardcoded strategic map tree meshes to the engine usage list, suggested by @Erundil.
  • Fix mixed-mode 1.011/Warband mods like TLD that have both older and newer-style .txt files.
    • Fix parsing the flora_kinds.txt and skyboxes.txt as M&B 1.011 just because item_kinds1.txt is using the older format; if the actions.txt file has the Warband format (that one doesn't have retro-compatibility support) then treat subsequent files as a Warband mod.
    • This gets rid of the parsing errors in the Data folder when opening the Warband version of The Last Days of the Third Age.
  • Add support for actually grabbing the hardcoded core_*.brf resources from the mod's Resourcefolder first, if they exist. This functionality was added after the first Warband patches.
    • This should fix any misleading «unknown shader» issue, when using custom shaders, and the like.
  • Fix the «Module > Open module folder in explorer» menu option, which didn't do anything.
  • Improve the actions.txt format auto-detection to find if the file has the Warband or the M&B 1.011 format, by counting how many space-separated elements are in an animation entry line.
  • Raise to 255 the 10 or 40-element limitation for hair and beard materials, as well as the item variants limit, in the @mtarini parser.
  • Make building the source code more straightforward, bundle slimmed down versions of the needed libraries.

0f6cf26a-e9c6-486e-aaf8-ee5b84024916
 
Last edited:
Both Redux and old OpenBRF are prone to crashes when undoing changes with Ctrl+Z while check for usage is on, especially if we do it quickly by holding Ctrl+Z.
Without usage checking, Ctrl+Z works without problems usually.

Maybe fixable.
 
Swyter suggested moving this out of PM to this thread, so here goes.

I tested the thing where _fem meshes are not marked as used, but should be.
Basically if mesh abcd is used, then mesh abcd_fem should also be marked as used (if it exists).
Swyter fixed that, but my tests show that results are partial - mesh abcd_fem will be shown as used only if it's in the same file as mesh abcd.

Swyter pointed out that he's hooked the _fem mesh detection into the same logic that marks LODs as used or not - function/procedure/whatever called noDot.

So I went to test how OpenBRF marks LODs and discovered some weirdness there too (same results in both original OpenBRF and Redux).
Here are my findings:

Basically, in file A I had:
mesh_A
mesh_A.lod1
mesh_A.lod2
mesh_A.lod3
All were showing as used, so far so good.

I split it into 2 files.
File A:
mesh_A
mesh_A.lod1
File B:
mesh_A.lod2
mesh_A.lod3
Now in file B I see lods 2-3 marked as used, but in file A - lod1 and even mesh_A now show as unused.

Conclusion: the fix for _fem meshes didn't work well because the whole function was flawed to begin with and might need fixing.

Due to limited time I only tested on 1 file though. I hope there are people with more time than I have to test it better.
 
Thanks for testing, mate. Yeah, the function that marks suffixed versions of used meshes is kind of funky.

Marco probably had his good reasons to do it like this, but I've just expanded the original mechanism a bit. If someone has some time to investigate subtly broken bits and hence make fixing them easier, please post that here. Knowing is half the battle.

A bunch of the Warband regulars on the Discord server also had other potential suggestions to make OpenBRF a bit less annoying to use; yesterday I implemented support for local rotations/scaling, an option to only color tint the last selected mesh, raised the material/beard/hair limits for skins.txt and the other text files, added the map tree meshes to the hardcoded list, and made it use the mod's core_*.brf files in the resource usage finder if they exist, so custom shaders don't cause errors anymore.

Please post yours here, happy to discuss them and see what can be done, even if it's just small, quality-of-life stuff. Don't be shy. :fruity:
 
Edit: This is fixed in the latest version.

There's currently a regression in the double-click on a mesh name to select all parts and LODs in one go function. For some reason the second click fires a single-click Qt signal/event that resets the double-click event, kind of tricky to fix.

But it seems like double-clicking with the mouse wheel/middle button works just fine.

Holding Shift while double right-clicking also works. There's something wrong with single left clicks. 🐥

--

@kraggrim suggested adding another button in the texture coordinate tool to flip the UVs vertically and horizontally, so I added that yesterday. Keep them coming.
 
Last edited:
Perhaps you could fix the issue with the custom feminizer morpher files as described by mtarini here:

Some basic informations of frame differences between M&B and Warband are described at this section here, at the top "Female frame", although you might be aware of them:
https://earendil_ardamire.gitlab.io/modding-guide/Subpages/New_at_modding_Warband/BRF_Resource_Management.html#Skeletons
 
There's currently a regression in the double-click on a mesh name to select all parts and LODs in one go function. For some reason the second click fires a single-click Qt signal/event that resets the double-click event, kind of tricky to fix.

But it seems like double-clicking with the mouse wheel/middle button works just fine.

Holding Shift while double right-clicking also works. There's something wrong with single left clicks. 🐥
Just managed to "fix" this using a funky workaround after a very long and arduous debugging and testing session, didn't manage to find the root cause. So hopefully isn't any worse than any of the official versions, no more drawbacks! Please re-download from here.

Perhaps you could fix the issue with the custom feminizer morpher files as described by mtarini here:

Some basic informations of frame differences between M&B and Warband are described at this section here, at the top "Female frame", although you might be aware of them:
https://earendil_ardamire.gitlab.io/modding-guide/Subpages/New_at_modding_Warband/BRF_Resource_Management.html#Skeletons
Darn, sounds a bit messy, but added it to my to-do list anyway. Thanks for the suggestion! :grin:
 
Ah, before I forget, here was the workaround for it suggested by mtarini:
https://forums.taleworlds.com/index.php?threads/faq-and-troubleshooting.173577/#post-8345513

Another issue which you could perhaps fix the issue described here:
Not sure if anyone asked this before,
but does your latest version of OpenBRF always automatically switch to a female version of armour mesh while you're trying to play one of the preset animations?
I simply can't get my male armour meshes to play preset animations unless I separate their frames.

Is there any way to fix this problem?
Maroon wrote a little workaround for it:
As far as I can tell the "Play" button is used both for vertex frames and frames of an animation. So if you try to play an animation on a skinned armor that has multiple body types (and thus vertex frames), it'll play the animation and "play" the vertex frames, moving it to the last frame there is, in your case the female version. I think all you can do for now is remove the vertex frames when you're testing it and readding it afterwards. Or keep a copy of the armor with just the normal frame for testing purposes.
There are probably not many people around who have multiple frames at the armouries and tried to play the animations. It is also only broken in the "newer" OpenBRF version iirc since I have never had the problem at my older version (I use the version 0.0.79 at my old laptop).
 
Another issue which you could perhaps fix the issue described here:

Maroon wrote a little workaround for it:

There are probably not many people around who have multiple frames at the armouries and tried to play the animations. It is also only broken in the "newer" OpenBRF version iirc since I have never had the problem at my older version (I use the version 0.0.79 at my old laptop).
Hopefully fixed, please check the latest version. Surprisingly easy to find and fix, at least compared to the double-click bug above, just had to tweak a single line.
 
Last edited:
More updates. Download the latest version from here.
  • Add Alt+R as the key shortcut to open Roto-translate-rescale. Suggested by @kraggrim.
  • Add the Ctrl+Shift+S shortcut to File > Save As. Also suggested by @kraggrim.
  • Fix multi-selection with Ctrl and Shift when combined with my double-click LOD/multipart selection hack.
    • Now we can select all the meshes from multiple objects without deselecting what came before. Reported by @kraggrim.
  • Add the Redux moniker to the main title bar, to distinguish it from the original program.
 
Thanks for the kind words. Glad that the improvements are useful. Just added a new feature:
  • Improve «Import > Anything from a BRF file» to support selecting (and importing) multiple BRF files in the open dialog at once. Suggested by @madsci on Discord.
 
Would be cool to improve rendering in openBRF.
As it stands, if the texture isn't DXT1 and BumpMap is enabled in View, it looks like this:
image.png

(it's the bride_dress mesh, so it should look mostly white)
 
More updates. Download the latest version from here.
  • Improve the green (RGBA/0X0Y) or blue (RGBA/XY__) normal map detection by looking at the averaged texture pixel values and analyzing which one is more likely. Fixes the bride_dress mesh showing in pure black with glitchy white sparkles when bump mapping is enabled in the viewer, reported by @Erundil.
    • Marco just assumed every normal map texture with an alpha channel (so DDS files with DXT3 or DXT5 encoding) would be of the green kind, which is often the case as blue ones are often DXT1, but bride_dress_normalmap is a standard blue/magenta one with the same alpha channel as in the diffuse texture, probably put there by mistake.
    • Keep in mind that the analysis only works for textures with mipmaps. You generally don't want normal maps with only a single mip, because they will look pixelated and weird in the distance.
  • Conditionally enable anisotropic filtering with the maximum amount of taps for a less blurry viewport at oblique angles, like when looking at walls sideways.
  • Fix a few typos: DeafultDefault.
 
Last edited:
Back
Top Bottom