Skip to content

NWN file formats in C++

LiarethLiareth Member Posts: 74
edited March 2018 in Tools & Plugin Developers
I wanted a decent way to read NWN file formats in C++ for personal NWN-related projects so I decided to write a library to handle it. It's open source and completely free for anyone to copy, use, and change with or without attribution. It should compile and work on all platforms and x86 architectures (probably not on ARM though) but I haven't tried it on Linux so there may be a few compile fixes needed there.

Note that this is a library for C++ developers who want to parse Aurora engine file formats, and right now only GFF is implemented.

https://github.com/Liareth/NWNFileFormats

You can see how it works here:

https://github.com/Liareth/NWNFileFormats/blob/master/Examples/Example_Gff.cpp
shadguytbone1GreenWarlocksquattingmonkzunathJuliusBorisov

Comments

  • LiarethLiareth Member Posts: 74
  • tgxtgx Member Posts: 40
    I like how you call it "Friendly API". Looks good. Hopefully we'll see some useful applications down the road that make use of these. Better to have an API than to do it again and again. I suspect this will be useful.
  • GreenWarlockGreenWarlock Member Posts: 1,354
    my personal peeve - you could avoid a lot of 'assert(not null)', and be correct by-design, by passing references rather than pointers. Not a good idea for arrays, where iteration/indexing is expected, but when reading/writing a single object, for example, it usually leads to slightly cleaner code.

    Of course, coding convention is in the eye of the beholder, and I am stuck with this asserting null pointers at work too, which might be why I am so sensitive ;)
  • GreenWarlockGreenWarlock Member Posts: 1,354
    BTW, love that you are using C++17 features already - I am a standards geek and love to see our stuff being adopted, even if in only a small way :)
  • LiarethLiareth Member Posts: 74
    edited March 2018
    @GreenWarlock Good feedback, thanks! (And for the PR too, assuming that was you!)

    I do prefer references in most cases, but for functions that take out parameters, I prefer raw pointers because it's more explicit to me that the intent is to return a value that way. In this library, I've used raw pointers only for out parameters (Gff/Erf::ReadFromBytes and Gff::ReadField), and everything else takes references. I'm not allowed to use exceptions at work :( so I find myself writing code in this way rather and returning error codes rather than returning by value.
  • GreenWarlockGreenWarlock Member Posts: 1,354
    We have the same conventions where I work too, so totally understood, and yes, those were my PRs as well :)
  • GreenWarlockGreenWarlock Member Posts: 1,354
    Darn - struggling to get this to build on my Mac as I cannot persuade cmake to use my latest Clang checkout, which has the C++17 libraries. Any pointers on configuring make for noobies appreciated! In the meantime, you probably want to change the file permissions on the build.sh file to add the execution bit on Unix platforms.
  • LiarethLiareth Member Posts: 74
    edited March 2018
    @GreenWarlock I think CMake uses the CC and CXX environment variables, so if you set those to the path of clang and clang++, that should work. You can do also cmake -DCMAKE_C_COMPILER=/my/clang -DCMAKE_CXX_COMPILER/my/clang++ .. theoretically but I've never tried it.
    tbone1
  • LiarethLiareth Member Posts: 74
    This now has TLK support. I've also optimized the BIF and ERF support to be much more memory efficient. The implementations now use memory mapped files and don't duplicate data all over the place. When extracting all of the game resources, this reduced my peak memory usage to 250 mb from 900 mb.

    @GreenWarlock I played around with compiling it on Clang today. You need Clang 5.0 or later. I use the unstable branch of Debian which has Clang 6.0 and GCC 7.2 available as a package, both of which compile the library out of the box.

    If you have a manual compiler install, you can do it like:

    CC=/usr/bin/clang-6.0 CXX=/usr/bin/clang++-6.0 ./build.sh
  • TarotRedhandTarotRedhand Member Posts: 1,177
    Any updates on this? Pity it's on Unix from my perspective, being a windows user. Do you plan on tackling the .mdl format?

    TR

  • SherincallSherincall Member Posts: 387
    It should work on Windows just fine. You just need to install the latest visual studio and compile it from source.
  • LiarethLiareth Member Posts: 74
    @TarotRedhand Yes it should work out of the box in latest VS2017 - that's how I developed it, with Linux support coming secondary. I'm done with the project for now as I'm able to read all of the NWN formats I need. I will be adding support for writing GFF at some point in the future.
    GreenWarlockdunahan
  • TarotRedhandTarotRedhand Member Posts: 1,177
    Thanks for the update.

    TR
  • LiarethLiareth Member Posts: 74
    I've been adding some more support to this library lately. It now supports editing and saving GFF, TLK, and 2DA. I've also added a couple of tools to the repository - most notably a utility to merge two 2DAs together.
    dunahanTarotRedhand
  • hmudd67hmudd67 Member Posts: 1
    Now you just need to have .uti file support.
  • shadguyshadguy Member Posts: 154
    @hmudd67 .uti and most of the other module assets are GFF format with a filelname extension change to help specify what they're used for.

    -Dave
  • TrasdTrasd Member Posts: 62
    edited December 2018
    @Liareth

    Is your code based on bioware_aurora_engine_file_formats.zip? Or, is there an updated reference I missed somewhere?

    Thanks and, thanks for the work!
  • SherincallSherincall Member Posts: 387
    There have been no updates to those formats since 1.69, so the spec is still valid.
  • TrasdTrasd Member Posts: 62
    @Sherincall

    Thanks.

    That's what I thought (backwards compatible and all). But, I wanted to confirm.
Sign In or Register to comment.