Skip to content

feat: QOS (007: Quantum of Solace) support#894

Open
michaeloliverx wants to merge 8 commits into
Laupetin:mainfrom
michaeloliverx:qos
Open

feat: QOS (007: Quantum of Solace) support#894
michaeloliverx wants to merge 8 commits into
Laupetin:mainfrom
michaeloliverx:qos

Conversation

@michaeloliverx

@michaeloliverx michaeloliverx commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
image image

Summary

Adds initial support for QOS / 007: Quantum of Solace PC fastfiles.

Closes #349.

The current goal is not to claim that every QoS struct is fully understood. It is to make the retail PC fastfiles loadable, unlinkable, and inspectable while keeping the inferred parts of the layouts obvious for future work.

Notes

QoS is close to the IW3/T4 engine family. The structs in this PR are mostly inferred from the QoS PC and Wii loader/decomp, with IW3/T4 used as a guide where the code paths clearly line up.

Some details that may be useful while reviewing:

  • The QoS fastfile header does not seem to use the usual ASCII magic string. The first header word is the little-endian zone version, and the following header words are used for xblock sizes.
  • The xfile blocks found in the executable are temp, runtime, virtual, large, and physical.
  • The QoS asset enum comes from the executable asset-name table.
  • A Wii decomp with some symbol names was useful for function cross-reference, but struct sizes/offsets were not copied from Wii.
  • The executable still has IWD support, but the retail PC image data checked here is bundled in fastfiles.
  • Embedded QoS image data needed smallest-to-largest mip handling, matching IWI-style ordering.
  • QoS xmodels needed some QoS-specific handling around packed vertex/material data rather than using the IW3/T4 assumptions directly.

Unknown fields are intentionally left as unknown/padding rather than given confident names too early. The current names can be tightened as more QoS-specific code paths are reversed.

Current coverage

Added a few easy wins for dumpers and loaders and fleshed out the zone writing as well.

QoS is also wired into ModMan; images and xmodels can be inspected there.

Validation

  • Only tested on Windows
  • Unlinked all 57 fastfiles from the English version successfully.
  • Verified the final unlink output had all expected zone folders and generated .zone files.
  • Linked a small QoS test zone using disk-loaded rawfiles and --load-referenced existing assets, then listed/unlinked the result as a basic roundtrip check.
  • Tested ModMan inspection with QoS zones and confirmed images/xmodels render.

One known dump-time filename collision can happen with ui_mp.ff:

ERROR: Failed to open file 'ui_mp'
Dumped rawfile "ui_mp"
Unloaded zone "ui_mp"

This happens because the dump output can contain a nested ui_mp directory and a trailing rawfile asset also named ui_mp.

I guess this can happen with any game in OAT.

Useful Resources

if (potentialTextureDefs.size() == 1)
return GetImageFromTextureDef(*potentialTextureDefs[0]);

#ifdef FEATURE_QOS

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels hacky, you can probably find a better solution than me

@@ -0,0 +1,142 @@
#include "ZoneLoaderFactoryQOS.h"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QoS seems to be the odd one out here because its fastfile header does not have the usual ASCII magic string. The first 4 bytes of ZoneHeader::m_magic are the zone version (470), while ZoneHeader::m_version is actually the first xblock size. The remaining xblock sizes follow directly after the normal header.

That is why this factory does not use the usual StepLoadZoneSizes/StepAllocXBlocks sequence and has a small QoS-specific allocation step instead.

Feel free to refactor it

@michaeloliverx
michaeloliverx marked this pull request as ready for review July 10, 2026 09:48
Comment thread src/Common/Game/QOS/QOS.h
XAsset* assets;
};

using AssetXModelPieces = Asset<ASSET_TYPE_XMODELPIECES, XModelPieces>;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I did not clean these up, I will leave that to you 😛


namespace
{
constexpr const char* ASSET_TYPE_NAMES[]{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I forgot to normalise these

@Laupetin Laupetin added the enhancement New feature or request label Jul 11, 2026
@ujicos

ujicos commented Jul 16, 2026

Copy link
Copy Markdown

Tested and confirmed working on QoS PC version 1.1, via @ProjectConsolation .
Generated a test fastfile "patch_consolation.ff", which successfully overrode dm.gsc from zone.
Thank you for your work, Michael!
image

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Support for Quantum of Solace (2008)

3 participants