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!
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
(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.