sm64pc / sm64ex

Fork of https://github.com/sm64-port/sm64-port with additional features.
1.56k stars 480 forks source link

Feature Request: Load meshes and textures from external files at runtime #81

Open opusGlass opened 4 years ago

opusGlass commented 4 years ago

User story As a user who does not know how to compile the project, and a modder who would like to replace the meshes (models) and textures used in the game: I would like to be able to place a file with a certain name, in a certain folder location, such that it will be loaded by the game instead of the original asset.

This will greatly help modding efforts, as seen in other games such as Skyrim.

Description of feature When loading an asset (in particular any Mesh or Texture), first check for a corresponding file in an external location. If file is present, load that. If file is NOT present, load the compiled (ROM) data.

For a vanilla user, this would have no effect - no external files are present and therefore only the compiled assets are used. But users can then choose to override a specific model or texture (for example - Mario's head model) with a higher-poly model, or another model entirely.

Expected behavior Out of the box, user-facing behavior does not change. When a user places a file of the correct format in the correct location, it will then be loaded in place of the corresponding model at runtime.

Example Folder structure, file name, and file format are just placeholders:

Root folder

mario.exe Data folder

MarioModel folder

MarioHead.obj

Notes There would need to be a convention for folder structures and/or filenames. Hopefully the original ROM has assets organized by human readable names, in which case those filenames could be re-used for loading external assets. If the ROM does not have any such human-readable organization for assets, either a new convention could be created, or the non-human-readable memory addresses could be used as filenames if necessary. In the latter case, the community would need to create a list of these addresses and their contents.

BenMcLean commented 3 years ago

I think the entire build process and program startup needs to be changed so that all assets are loaded in from the Super Mario 64 ROM at runtime, not at build time.

That's how my Wolfenstein 3-D VR port works. It loads in all textures, sounds, game maps, everything at runtime, with only an absolute minimum of assets needed to build the program.

fgsfdsfgs commented 3 years ago

That's easier said than done due to the geometry nodes having code references and other complicating factors. Textures and sound data already can be loaded at runtime and work similarly to what OP wants.

BenMcLean commented 3 years ago

Hmm, geometry nodes having code references?? That sounds super weird! Got any link to more information on that?

I am writing an XML file to add to each supported game so that my Wolfenstein engine knows how to read it. Maybe something similar could help separate out the code from the assets here?

fgsfdsfgs commented 3 years ago

E.g. this calls a function when that node is reached. They can be used for various interactive animations, to switch parts of the model on and off, etc. Of course you can just make a table of code pointers and convert the pointers in the geo data to indices in that table, but that all requires quite a bit of work. The main type of model data is display lists, which also contain pointers to textures and vertex data. Those can be written into the same file and changed into offsets, but again, that's quite a lot of work. Everything is also hard referenced everywhere because the game expects to be contained in memory mapped ROM (segment system aside).

BenMcLean commented 3 years ago

The big advantage I think we were looking for from loading as much as possible at runtime is to make the program easily distributable without Nintendo copyrighted assets and perhaps even moving towards a content package like "FreeDoom" where all the proprietary stuff is replaced, yet the same program can also run the commercial game and mods. But I guess everything's different on consoles.