Dolphin, the GameCube and Wii emulator - Forums

Full Version: Give ELF files unique game IDs
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I would like to create a fork of Dolphin that assigns every .elf and .dol file a unique gameID for the purposes of Custom Texture Pack loading and gameini's (currently they are either not assigned a gameID or all assigned the same gameID so that you can't give each their own configuration and texture pack -- I think they might be given a string of zeros as their id, or at least that used to be the case).

Up to this point I have been creating WAD forwarder channels for any elf I wanted to run (typically smash bros brawl mods) but this is unsatisfactory for several reasons:
  • it is difficult
  • it doesn't always work
  • it takes up space in the NAND that I would rather not take up
The reason I am posting here rather than just doing it is because I would like suggestions as to how I should go about this; should I actually attempt to give the elf/dol files a gameID at a very low level (eg in Core/Core/Boot) or should I make the change at a higher level of abstraction? Should I use the name of file to create it? Is this actually a terrible idea that will break things?

Thanks for your help!
You would want to call SetRunningGameMetadata here: https://github.com/dolphin-emu/dolphin/blob/361bf25cf88026c384dc43ac8ee0cdd04b6e359c/Source/Core/Core/ConfigManager.cpp#L837-L841

And if you want the game ID to be reported in the game list too, you should also set m_game_id here: https://github.com/dolphin-emu/dolphin/blob/2e86e1a9989340a41388e48d04ca9acd31e0b0d0/Source/Core/UICommon/GameFile.cpp#L158-L164

Using the file name probably works, but I can't swear on it. (The main problem I can think of is that DTM file headers truncate all game IDs to six characters, but that probably isn't too much of an issue.)
(01-20-2021, 06:07 AM)JosJuice Wrote: [ -> ]You would want to call SetRunningGameMetadata here: https://github.com/dolphin-emu/dolphin/blob/361bf25cf88026c384dc43ac8ee0cdd04b6e359c/Source/Core/Core/ConfigManager.cpp#L837-L841

And if you want the game ID to be reported in the game list too, you should also set m_game_id here: https://github.com/dolphin-emu/dolphin/blob/2e86e1a9989340a41388e48d04ca9acd31e0b0d0/Source/Core/UICommon/GameFile.cpp#L158-L164

Using the file name probably works, but I can't swear on it. (The main problem I can think of is that DTM file headers truncate all game IDs to six characters, but that probably isn't too much of an issue.)

Thank you so much! I will get right on this.
(01-20-2021, 06:07 AM)JosJuice Wrote: [ -> ]You would want to call SetRunningGameMetadata here: https://github.com/dolphin-emu/dolphin/blob/361bf25cf88026c384dc43ac8ee0cdd04b6e359c/Source/Core/Core/ConfigManager.cpp#L837-L841

And if you want the game ID to be reported in the game list too, you should also set m_game_id here: https://github.com/dolphin-emu/dolphin/blob/2e86e1a9989340a41388e48d04ca9acd31e0b0d0/Source/Core/UICommon/GameFile.cpp#L158-L164

Using the file name probably works, but I can't swear on it. (The main problem I can think of is that DTM file headers truncate all game IDs to six characters, but that probably isn't too much of an issue.)

Should I make the first eight characters of the gameID 00010001 like they are for WADs or does it not matter? Currently my plan is to just hash the file name and take the first 16 characters of the hash as the gameID.
I don't see any reason to do that. Any code in Dolphin that infers any meaning from those bits checks the title ID rather than the game ID.
You may want to review the various rules we've worked out regarding how GameIDs are assigned...
https://wiki.dolphin-emu.org/index.php?title=GameIDs

That will likely help you identify appropriate patterns to not overlap pre-existing GameIDs. For instance prefixing them with a "Y" or other character besides: C,D,E,F,G,H,J,L,M,N,P,Q,R,S,W,X,r,s,w; would be good.
Just using the full filename (without hashing it) should be a pretty good way of avoiding collisions with actual game IDs. Both the length and the used set of characters will typically be very different.
(01-20-2021, 09:38 AM)JosJuice Wrote: [ -> ]Just using the full filename (without hashing it) should be a pretty good way of avoiding collisions with actual game IDs. Both the length and the used set of characters will typically be very different.

I feel like the issue with that is I leave room for the user to do something dumb like name a launcher for a smash mod RSBE01.elf. Maybe I will do something like (Y + hash(filename)).substr(0,16)
(01-20-2021, 10:20 AM)cbartondock Wrote: [ -> ]I feel like the issue with that is I leave room for the user to do something dumb like name a launcher for a smash mod RSBE01.elf. Maybe I will do something like (Y + hash(filename)).substr(0,16)

How about something like this?
Code:
#include <iostream>
#include <string>
using namespace std;
   
unsigned long my_hash(const char *str)
{
   unsigned long hash = 5381;
   int c;

   while (c = *str++)
       hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

   return hash;
}

std::string make_game_id(std::string m_file_name) {
   size_t hash = my_hash(m_file_name.c_str()) %(1000000000000000);
   return "Y"+to_string(hash);
}

int main()
{
   std::string m_file_name="Super Smash Bros Project+.elf";
   std::string m_game_id=make_game_id(m_file_name);
   std::cout << "Name: " << m_file_name << '\n';
   std::cout << "GameID: " << m_game_id << '\n';
   return 0;
}
The above outputs

Name: Super Smash Bros Project+.elf                                                           
GameID: Y379404873427821   
And is a deterministic hash with quite a low collision rate. If I go this route where should I put the helper functions? I assume there is a sensible location?
(01-20-2021, 10:20 AM)cbartondock Wrote: [ -> ]I feel like the issue with that is I leave room for the user to do something dumb like name a launcher for a smash mod RSBE01.elf. Maybe I will do something like (Y + hash(filename)).substr(0,16)

That is why my suggestion is the full file name including the extension Wink

(01-20-2021, 11:49 AM)cbartondock Wrote: [ -> ]The above outputs

Name: Super Smash Bros Project+.elf                                                           
GameID: Y379404873427821   
And is a deterministic hash with quite a low collision rate. If I go this route where should I put the helper functions? I assume there is a sensible location?

Hm... Somewhere in Common, I guess? Can't think of any place that fits perfectly.
Pages: 1 2