diff --git a/rott/rt_datadir.c b/rott/rt_datadir.c index c7589fa..36442bc 100644 --- a/rott/rt_datadir.c +++ b/rott/rt_datadir.c @@ -15,11 +15,80 @@ See the GNU General Public License for more details. */ -#include "SDL_filesystem.h" +#include + +#include "SDL.h" #include "m_misc2.h" #include "rt_util.h" +#ifndef _WIN32 +#include +#endif + +/* + * storefronts + * + * retrieve ROTT data directories from various digital storefronts + * + * supported: + * - steam + * - heroic + * - gog + */ + +#ifdef _WIN32 + +/* format strings for potential data paths relative to a drive */ +/* TODO: use the registry to query some of these */ +static const char *storefront_paths[] = { + /* steam - classic rott */ + "\\Program Files (x86)\\Steam\\steamapps\\common\\Rise of the Triad Dark War\\Rise of the Triad - Dark War\\", + /* steam - ludicrous edition */ + "\\Program Files (x86)\\Steam\\steamapps\\common\\Rise of the Triad - Ludicrous Edition\\assets\\", + /* gog - ludicrous edition */ + "\\GOG Games\\Rise of the Triad - Ludicrous Edition\\", + /* gog - classic rott */ + "\\GOG Games\\Rise of the Triad\\", + /* original ms-dos installers */ + "\\ROTT\\" +}; + +#else + +/* format strings for potential data paths relative to $HOME */ +/* these are all the default or expected paths, if the user customized it, oh well... */ +static const char *storefront_paths[] = { + /* steam - classic rott */ + "/.steam/steam/steamapps/common/Rise of the Triad Dark War/Rise of the Triad - Dark War/", + /* steam - ludicrous edition */ + "/.steam/steam/steamapps/common/Rise of the Triad - Ludicrous Edition/assets/", + /* steam - ludicrous edition (savegames) */ + "/.steam/steam/steamapps/compatdata/1421490/pfx/drive_c/users/steamuser/Saved Games/Nightdive Studios/Rise of the Triad - Ludicrous Edition/", + /* steam - ludicrous edition (user mapsets) */ + "/.steam/steam/steamapps/compatdata/1421490/pfx/drive_c/users/steamuser/Saved Games/Nightdive Studios/Rise of the Triad - Ludicrous Edition/projects/", + /* heroic - classic rott */ + "/Games/Heroic/Rise of the Triad/data/", + /* gog - ludicrous edition (wine) */ + "/.wine/drive_c/GOG Games/Rise of the Triad - Ludicrous Edition/", + /* gog - ludicrous edition (native) */ + "/GOG Games/Rise of the Triad - Ludicrous Edition/", + /* gog - classic rott (wine) */ + "/.wine/drive_c/GOG Games/Rise of the Triad/", + /* gog - classic rott (native) */ + "/GOG Games/Rise of the Triad Dark War/" +}; + +#endif + +static const int num_storefront_paths = sizeof(storefront_paths) / sizeof(const char *); + +/* + * + * we now return to your regularly scheduled programming + * + */ + static char *GetExeDir (void) { static char *dir; @@ -165,6 +234,39 @@ static void AddXdgDirs(void) } #endif +static void AddStorefrontDirs(void) +{ + struct stat st; + char path[1024]; + +#ifndef _WIN32 + char *prefix = getenv("HOME"); + + if (prefix == NULL) + { + struct passwd *pwd = getpwuid(getuid()); + + if (pwd == NULL) + { + perror("getpwuid"); + return; + } + + prefix = pwd->pw_dir; + } +#else + const char prefix[] = "C:"; +#endif + + for (int i = 0; i < num_storefront_paths; i++) + { + M_snprintf(path, sizeof(path), "%s%s", prefix, storefront_paths[i]); + + if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) + AddDataDir(M_StringDuplicate(path)); + } +} + static void BuildDataDirList(void) { if (datadirs[0]) @@ -186,6 +288,8 @@ static void BuildDataDirList(void) #ifndef _WIN32 AddXdgDirs(); #endif + + AddStorefrontDirs(); } char *FindFileByName(const char *name) diff --git a/rott/rt_menu.c b/rott/rt_menu.c index 6da7da1..c9101c6 100644 --- a/rott/rt_menu.c +++ b/rott/rt_menu.c @@ -7974,7 +7974,7 @@ void ShowBattleOptions } ShowBattleOption( inmenu, PosX, PosY, 0, 9, "Danger Damage", string ); - GetMapFileName ( text ); + GetMapFileName ( text, sizeof(text) ); ShowBattleOption( inmenu, PosX, PosY, 0, 10, "Filename", text ); itoa( numplayers, text, 10 ); diff --git a/rott/rt_net.c b/rott/rt_net.c index 558cfc2..79309b5 100644 --- a/rott/rt_net.c +++ b/rott/rt_net.c @@ -2420,7 +2420,7 @@ void SendGameDescription( void ) desc->teamplay = gamestate.teamplay; memcpy( &desc->SpecialsTimes, &gamestate.SpecialsTimes, sizeof( specials ) ); BATTLE_GetOptions( &( desc->options ) ); - GetMapFileName( &(desc->battlefilename[0]) ); + GetMapFileName( &(desc->battlefilename[0]), sizeof(desc->battlefilename) ); desc->randomseed=GetRNGindex ( ); gamestate.randomseed=desc->randomseed; desc->ludicrousgibs=battlegibs; diff --git a/rott/rt_ted.c b/rott/rt_ted.c index 21ba783..12aabf5 100644 --- a/rott/rt_ted.c +++ b/rott/rt_ted.c @@ -1622,24 +1622,20 @@ void GetMapFileInfo = ====================== */ -void GetMapFileName ( char * filename ) +void GetMapFileName ( char * filename, size_t n ) { - if ( ( BATTLEMODE ) && (BattleLevels.avail == true) ) - { - strcpy(filename,BattleLevels.file); - } - else if (GameLevels.avail == true) - { - strcpy(filename,GameLevels.file); - } - else if ( BATTLEMODE ) - { - strcpy(filename,BATTMAPS); - } - else - { - strcpy(filename,ROTTMAPS); - } + const char *src; + + if (BATTLEMODE && BattleLevels.avail == true) + src = M_BaseName(BattleLevels.file); + else if (GameLevels.avail == true) + src = M_BaseName(GameLevels.file); + else if (BATTLEMODE) + src = M_BaseName(BATTMAPS); + else + src = M_BaseName(ROTTMAPS); + + strncpy(filename,src,n); } /* @@ -1673,7 +1669,7 @@ unsigned short GetMapCRC RTLMAP RTLMap; size_t mapsoffset; - GetMapFileName( &filename[ 0 ] ); + GetMapFileName( &filename[ 0 ], sizeof(filename) ); CheckRTLVersion( filename ); filehandle = SafeOpenRead( filename ); mapsoffset = GetMapArrayOffset( filehandle ); diff --git a/rott/rt_ted.h b/rott/rt_ted.h index 0b28cbe..1b4c177 100644 --- a/rott/rt_ted.h +++ b/rott/rt_ted.h @@ -168,7 +168,7 @@ void PrintMapStats (void); void PrintTileStats (void); void GetMapInfo (mapfileinfo_t * mapinfo); -void GetMapFileName ( char * filename ); +void GetMapFileName ( char * filename, size_t n ); void SetBattleMapFileName ( char * filename ); unsigned short GetMapCRC ( int num );