Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

Commit

Permalink
Tweak comments for readability
Browse files Browse the repository at this point in the history
  • Loading branch information
vswarte committed Jan 7, 2024
1 parent 8a36e3b commit 94a71f5
Showing 1 changed file with 31 additions and 20 deletions.
51 changes: 31 additions & 20 deletions src/modengine/ext/mod_loader/wwise_file_overrides.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,37 @@

namespace modengine::ext {

// This hook the IAkFileLocationResolver::open() method. It takes in a path and a so-called openMode. This openMode parameter
// is of type AkOpenMode which is an enum with 4 states: Read, Write, WriteOverwrite and ReadWrite. Based on this parameter
// the IAkFileLocationResolver implementation might acquire the file bytes different. Passing in any of these 4 invariants
// will cause this function to yield an FileOperator used for sourcing the file bytes. FromSoftware funnily enough added
// another invariant to AKOpenMode, dec 9, which will instead yield an EBLFileOperator, causing the reads to happen from
// the bhd/bdt. This unfortunately happens without touching the usual virtual path lookup which ME2 already hooks.
// In order to selectively make it read from disk again this checks if an override file exists and sets the openMode
// back from 9 to Read. Then an absolute path must be passed as a parameter.
// This hook the IAkFileLocationResolver::open() method. It takes in a path
// and a so-called openMode. This openMode parameter is of type AkOpenMode
// which is an enum with 4 states: Read, Write, WriteOverwrite and ReadWrite.
// Passing in any of these 4 invariants will cause this function to yield a
// FileOperator used for sourcing the file bytes. FromSoftware added another
// possible state to AKOpenMode, decimal 9. which will make this fn yield an
// EBLFileOperator, this implementation does all its fetching from the BDTs.
// EBLFileOperator does not use the usual virtual path lookup that ME2 already
// hooks. Hence we need this hook here.
//
// In order to selectively make it read from disk again this hook checks if an
// override file exists and sets the openMode back from 9 to Read and replaces
// the virtual path parameter string with an absolute path.
//
// This is a messy one though:
// Figuring out if there is an override isn't straight forward. The hooked function gets invoked with a virtual path string
// ex: `sd:/50846376.wem`. Wwise uses subdirectories for localized content, meaning that the WEM example makes Wwise look
// in `/50846376.wem` but also in `enus/50846376.wem` (or `ja/50846376.wem` for AC6 which has `ja` as an extra locale
// for some audio and BNKs). To make matters even worse, Elden Ring sorts the WEMs into a subdir (`wem/`) and then
// another subdir based on the first two digits of the WEM. So above example will spawn lookups in `/wem/50/50846376.wem`
// and `enus/wem/50/50846376.wem`. In order to figure out if there is an override we will need to look in multiple directories
// per request. Luckily, aside from boot, it doesn't load a lot of files.
// Figuring out if there is an override isn't straight forward. The hooked
// function gets invoked with a virtual path string ex: `sd:/50846376.wem`.
// Wwise uses subdirectories for localized content, meaning that the "simple"
// WEM example makes Wwise look in `/50846376.wem` but also in
// `enus/50846376.wem` (or `ja/50846376.wem` for AC6 which has `ja` as an extra
// locale for some audio and BNKs). To make matters even worse, Elden Ring
// specifically sorts the WEMs into a subdir (`wem/`) and then another subdir
// based on the first two digits of the WEM. So above example will spawn
// lookups in `/wem/50/50846376.wem` and `enus/wem/50/50846376.wem`. In order
// to figure out if there is an override we will need to look in multiple
// directories per request. Luckily, aside from boot, this routine is called
// quite infrequently.
//
// Also, worth pointing out that not all paths passed to this hook will have the `sd:/` prefix. So we cannot get away with the
// usual prefix / rewrite trick and will have to allocate a completely new string.
// Also, worth pointing out that not all paths passed to this hook will have
// the `sd:/` prefix. So we cannot get away with the usual prefix / rewrite
// trick and will have to allocate a completely new string.

namespace fs = std::filesystem;

Expand Down Expand Up @@ -62,8 +73,8 @@ std::optional<fs::path> check_paths(const std::wstring filename) {

std::optional<fs::path> find_override(const std::wstring filename)
{
// TODO: can be based on game specified instead of always applied.
// Check wem/<first to digits of filename>/<filename> too since ER uses this format
// Check wem/<first to digits of filename>/<filename> too since ER uses
// this format
if (filename.ends_with(L".wem")) {
auto wem_path = L"wem/" + filename.substr(0,2) + L"/" + filename;
auto wem_path_result = check_paths(wem_path);
Expand Down Expand Up @@ -106,4 +117,4 @@ void* __cdecl ak_file_location_resolver_open(UINT64 p1, wchar_t* path, UINT64 op
return hooked_ak_file_location_resolver_open.original(p1, override_path_string.data(), 0, p4, p5, p6);
}

}
}

0 comments on commit 94a71f5

Please sign in to comment.