garyttierney / me3

A framework for modding and instrumenting games.
75 stars 6 forks source link

Loading assets from disk #22

Open vswarte opened 1 month ago

vswarte commented 1 month ago

Messy draft PR to track work on the file-loading hook.

The end goal is to allow asset overrides like modengine2 allows while supporting the same folder structure such that we can load existing mods. Unfortunately the hook(s) used to achieve this in modengine2 is kinda smelly and ideally dropped for something a bit easier to maintain.

This PR implements a similar feature by hooking RSResourceFileRequest::vtable[1] (RSResourceFileRequest::IsPathStringEmpty unofficial name). Which seems to be called before actually handling file requests, granting us consistent access to the files path before the actual IO system does its thing.

In order to operate on the DLWstring that hosts the file path @Dasaav-dsv has modeled DLWString in C++ using std::basic_string. This PR introduces cxx as a dependency and a bunch of C++ code for that reason.

An important difference between me2 and me3's approach is that me2 was receiving fully expanded paths mapped to dataX and the like directly. This hook unfortunately gets us unexpanded paths eg: event:/common.emevd.dcx. This can be solved by asking the game to resolve it for us, acquiring the mapping from the games memory ourselves or keeping a manual table per game.

What still needs to happen:

To cap it all off, I couldn't immediately get the code to run with the dependency and package ordering code on, still need to look into that 😄

vswarte commented 1 month ago

The new hook had some nasty edge-cases around finalizing map loads causing the user to indefinitely be stuck in the loading screen under certain conditions. I'm updating the code to use the old hook again but since the old hook is taking in a DLWString (allocator included) we no longer need the second CreateFileW hook.

As a plus we can consider the virtual root mapping tasks done I suppose.