Open Erotemic opened 1 month ago
you'd need to reverse the rom extraction commits
Here is what I have discovered so far. If you search fd asset
in the repo you see these files:
assets/
assets.json
extract_assets.py
sound/samples_assets.c
sound/sequences_assets.c
src/pc/rom_assets.c
src/pc/rom_assets.h
text/us/courses_assets.inc.c
text/us/dialog_assets.inc.c
tools/gen_asset_list.cpp
And src/pc/rom_assets.c
seems like it is doing a lot of the major work. It looks like it is seeking to a location in the ROM, reading the bytes and then directly placing them into memory somewhere. This seems to be a lot more challenging to extend than I was originally hoping. If I wanted to re-use this logic I think I would need to ensure the generated assets I use are the exact same size, which might be difficult if there is compression.
Does anyone know if there might be an easier way to hook into assets read from disk?
I'm trying to find a good place to start tackling this, and I'm hoping someone can help me get my bearings.
you'd need to reverse the rom extraction commits
Is it that simple? Are these a set of commits I can revert to enable the original asset generation which I believe is baked into the executable?
I see:
but I imagine there are other commits that impact those files, and there might be conflicts that need to be resolved.
@Erotemic Do you think you might be able to implement an exporter in your random asset generator that exports all of your random assets packed inside of a dummy ROM that is empty/nonessential except for all the addresses that ROM extractors read in order to extract assets from the vanilla US ROM? You could probably isolate and import the code from https://github.com/n64decomp/sm64.git that's used to convert matching assets into a matching ROM in order to do it more easily than if you had to do it completely from scratch.
If you end up figuring out how to make something like that, maybe your generator would become more easily compatible with all forks of the US game by just disabling the ROM checksum verification, rather than making a bunch of really different changes for every different fork of the game.
I can build a ROM that includes the random assets. Both the sm64 and sm64-port repo work fine with my asset generator on Linux (on MinGW there is an issue).
If you run my code as:
sudo apt install -y binutils-mips-linux-gnu build-essential git libcapstone-dev pkgconf python3
# Build and run the ROM in an emulator (m64py)
export ASSET_CONFIG='
png: generate
aiff: generate
m64: generate
bin: generate
'
export NUM_CPUS=all
export TARGET=sm64
./build.sh
This produces a ROM, which contains no copyrighted assets, which I've uploaded here if you want to take a look sm64-random-assets.us.zip (you may need to unzip it)
I have tried to use this by disabling the hash check, but when I drag and drop it into sm64coopdx I get a segfault.
Most likely your random assets are not in exactly the memory addresses of the ROM that the US ROM has them at. When you run the normal decomp build process but change some things, it's like you create another variant ROM that is similar to the EU, JP, US and SH versions but not identical to any specific one any longer. I think there's probably a way to insert custom assets into the exact memory addresses they are supposed to be in the US ROM, but I haven't set up a whole system for doing that. If I end up making a demonstration of it that seems helpful, I'll show it to you. These are my favorite hex editors, which might help you with manually writing and comparing binary files byte by byte.
https://linux.die.net/man/1/hexedit https://github.com/WerWolv/ImHex
I expect you're right about it placing the assets. One thing I've noticed is that the randomly generated assets can be much larger than the originals (you can't runtime length compress random data with png as well as structured data). This actually caused an issue when I put the ROM on my everdrive and tried to put it on the N64. The texture size blew out memory!
To diff binaries I typically just use :%!xxd
in vim. I can take a look at ImHex if that makes navigating larger files easier.
I would be interested in any code that would help put data in the correct memory locations, but I also think I need to ensure the random assets are no larger than the original ones. I believe they are stored in some compressed format in the ROM (otherwise there would be no memory difference between the random and original assets), so getting this right may be tricky.
We originally had an idea to have the game extract and dump the assets into a compressed (and more robust) file. But it hasn't been implemented. Your idea seems to line up with the idea of that (and may be a good reason to support it).
It would help if we can break down what needs to be done into smaller pieces.
The formats are likely going to be in what the engine natively accepts-Likely packed into a new format (A container) and not loose because having them loose will just cause confusion. (And make mods more file hefty then they already are.)
This also means we won't need anything special for encoding or decoding them.
The original idea was too read all of the data from all the language ROMs are pack them into one file. (Allowing you play multiple versions without ROM swapping in theory). But we didn't go through with it.
The only thing that will have more complicated issues. Is sounds and music (probably the best reason to even load from disk at this point too) Sounds are very specifically made and coded and while just swapping the audio data is easy. The other data is tough and hard to work with. (There is a big lack of existing tools) I'm not sure how that could be done easily.
I'm interested in doing some development on this repo in order to support my randomized assets project. The issue I'm having right now is that sm64coopdx seems to rely on extracting assets from an official ROM at runtime. However, I want to supply my own assets. I attempted a workaround where I compiled a sm64 ROM with my custom assets and tried to give it to sm64coopdx, but it strictly checks for hash equality to the us ROM.
Link to asset generation project: https://github.com/Erotemic/sm64-random-assets
Is there a reasonably simple development path to supporting loading pre-extracted (or generated) assets from png, aiff, m64, and bin files on disk instead of from the ROM? I imagine if there is some construct to get a particular asset from the ROM, a little polymorphic magic (although perhaps that is difficult in C?) can be used to pre-extracted assets from disk?
I originally posted this on discord, but I'd like to have an asynchronous development discussion and figure out the technical details behind accomplishing this.