]> git.xonotic.org Git - xonotic/darkplaces.git/blob - com_game.c
common: Split off the gameinfo stuff to com_game.c
[xonotic/darkplaces.git] / com_game.c
1 #include "quakedef.h"
2
3 // Game mods
4
5 gamemode_t gamemode;
6 const char *gamename;
7 const char *gamenetworkfiltername; // same as gamename currently but with _ in place of spaces so that "getservers" packets parse correctly (this also means the 
8 const char *gamedirname1;
9 const char *gamedirname2;
10 const char *gamescreenshotname;
11 const char *gameuserdirname;
12 char com_modname[MAX_OSPATH] = "";
13
14 gamemode_t com_startupgamemode;
15 gamemode_t com_startupgamegroup;
16
17 typedef struct gamemode_info_s
18 {
19         gamemode_t mode; // this gamemode
20         gamemode_t group; // different games with same group can switch automatically when gamedirs change
21         const char* prog_name; // not null
22         const char* cmdline; // not null
23         const char* gamename; // not null
24         const char*     gamenetworkfiltername; // not null
25         const char* gamedirname1; // not null
26         const char* gamedirname2; // null
27         const char* gamescreenshotname; // not nul
28         const char* gameuserdirname; // not null
29 } gamemode_info_t;
30
31 static const gamemode_info_t gamemode_info [GAME_COUNT] =
32 {// game                                                basegame                                        prog_name                               cmdline                                         gamename                                        gamenetworkfilername            basegame        modgame                 screenshot                      userdir                                    // commandline option
33 { GAME_NORMAL,                                  GAME_NORMAL,                            "",                                             "-quake",                                       "DarkPlaces-Quake",                     "DarkPlaces-Quake",                     "id1",          NULL,                   "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -quake runs the game Quake (default)
34 { GAME_HIPNOTIC,                                GAME_NORMAL,                            "hipnotic",                             "-hipnotic",                            "Darkplaces-Hipnotic",          "Darkplaces-Hipnotic",          "id1",          "hipnotic",             "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -hipnotic runs Quake mission pack 1: The Scourge of Armagon
35 { GAME_ROGUE,                                   GAME_NORMAL,                            "rogue",                                "-rogue",                                       "Darkplaces-Rogue",                     "Darkplaces-Rogue",                     "id1",          "rogue",                "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -rogue runs Quake mission pack 2: The Dissolution of Eternity
36 { GAME_NEHAHRA,                                 GAME_NORMAL,                            "nehahra",                              "-nehahra",                                     "DarkPlaces-Nehahra",           "DarkPlaces-Nehahra",           "id1",          "nehahra",              "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -nehahra runs The Seal of Nehahra movie and game
37 { GAME_QUOTH,                                   GAME_NORMAL,                            "quoth",                                "-quoth",                                       "Darkplaces-Quoth",                     "Darkplaces-Quoth",                     "id1",          "quoth",                "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -quoth runs the Quoth mod for playing community maps made for it
38 { GAME_NEXUIZ,                                  GAME_NEXUIZ,                            "nexuiz",                               "-nexuiz",                                      "Nexuiz",                                       "Nexuiz",                                       "data",         NULL,                   "nexuiz",                       "nexuiz"                                }, // COMMANDLINEOPTION: Game: -nexuiz runs the multiplayer game Nexuiz
39 { GAME_XONOTIC,                                 GAME_XONOTIC,                           "xonotic",                              "-xonotic",                                     "Xonotic",                                      "Xonotic",                                      "data",         NULL,                   "xonotic",                      "xonotic"                               }, // COMMANDLINEOPTION: Game: -xonotic runs the multiplayer game Xonotic
40 { GAME_TRANSFUSION,                             GAME_TRANSFUSION,                       "transfusion",                  "-transfusion",                         "Transfusion",                          "Transfusion",                          "basetf",       NULL,                   "transfusion",          "transfusion"                   }, // COMMANDLINEOPTION: Game: -transfusion runs Transfusion (the recreation of Blood in Quake)
41 { GAME_GOODVSBAD2,                              GAME_GOODVSBAD2,                        "gvb2",                                 "-goodvsbad2",                          "GoodVs.Bad2",                          "GoodVs.Bad2",                          "rts",          NULL,                   "gvb2",                         "gvb2"                                  }, // COMMANDLINEOPTION: Game: -goodvsbad2 runs the psychadelic RTS FPS game Good Vs Bad 2
42 { GAME_TEU,                                             GAME_TEU,                                       "teu",                                  "-teu",                                         "TheEvilUnleashed",                     "TheEvilUnleashed",                     "baseteu",      NULL,                   "teu",                          "teu"                                   }, // COMMANDLINEOPTION: Game: -teu runs The Evil Unleashed (this option is obsolete as they are not using darkplaces)
43 { GAME_BATTLEMECH,                              GAME_BATTLEMECH,                        "battlemech",                   "-battlemech",                          "Battlemech",                           "Battlemech",                           "base",         NULL,                   "battlemech",           "battlemech"                    }, // COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
44 { GAME_ZYMOTIC,                                 GAME_ZYMOTIC,                           "zymotic",                              "-zymotic",                                     "Zymotic",                                      "Zymotic",                                      "basezym",      NULL,                   "zymotic",                      "zymotic"                               }, // COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic
45 { GAME_SETHERAL,                                GAME_SETHERAL,                          "setheral",                             "-setheral",                            "Setheral",                                     "Setheral",                                     "data",         NULL,                   "setheral",                     "setheral"                              }, // COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
46 { GAME_TENEBRAE,                                GAME_NORMAL,                            "tenebrae",                             "-tenebrae",                            "DarkPlaces-Tenebrae",          "DarkPlaces-Tenebrae",          "id1",          "tenebrae",             "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -tenebrae runs the graphics test mod known as Tenebrae (some features not implemented)
47 { GAME_NEOTERIC,                                GAME_NORMAL,                            "neoteric",                             "-neoteric",                            "Neoteric",                                     "Neoteric",                                     "id1",          "neobase",              "neo",                          "darkplaces"                    }, // COMMANDLINEOPTION: Game: -neoteric runs the game Neoteric
48 { GAME_OPENQUARTZ,                              GAME_NORMAL,                            "openquartz",                   "-openquartz",                          "OpenQuartz",                           "OpenQuartz",                           "id1",          NULL,                   "openquartz",           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -openquartz runs the game OpenQuartz, a standalone GPL replacement of the quake content
49 { GAME_PRYDON,                                  GAME_NORMAL,                            "prydon",                               "-prydon",                                      "PrydonGate",                           "PrydonGate",                           "id1",          "prydon",               "prydon",                       "darkplaces"                    }, // COMMANDLINEOPTION: Game: -prydon runs the topdown point and click action-RPG Prydon Gate
50 { GAME_DELUXEQUAKE,                             GAME_DELUXEQUAKE,                       "dq",                                   "-dq",                                          "Deluxe Quake",                         "Deluxe_Quake",                         "basedq",       "extradq",              "basedq",                       "dq"                                    }, // COMMANDLINEOPTION: Game: -dq runs the game Deluxe Quake
51 { GAME_THEHUNTED,                               GAME_THEHUNTED,                         "thehunted",                    "-thehunted",                           "The Hunted",                           "The_Hunted",                           "thdata",       NULL,                   "th",                           "thehunted"                             }, // COMMANDLINEOPTION: Game: -thehunted runs the game The Hunted
52 { GAME_DEFEATINDETAIL2,                 GAME_DEFEATINDETAIL2,           "did2",                                 "-did2",                                        "Defeat In Detail 2",           "Defeat_In_Detail_2",           "data",         NULL,                   "did2_",                        "did2"                                  }, // COMMANDLINEOPTION: Game: -did2 runs the game Defeat In Detail 2
53 { GAME_DARSANA,                                 GAME_DARSANA,                           "darsana",                              "-darsana",                                     "Darsana",                                      "Darsana",                                      "ddata",        NULL,                   "darsana",                      "darsana"                               }, // COMMANDLINEOPTION: Game: -darsana runs the game Darsana
54 { GAME_CONTAGIONTHEORY,                 GAME_CONTAGIONTHEORY,           "contagiontheory",              "-contagiontheory",                     "Contagion Theory",                     "Contagion_Theory",                     "ctdata",       NULL,                   "ct",                           "contagiontheory"               }, // COMMANDLINEOPTION: Game: -contagiontheory runs the game Contagion Theory
55 { GAME_EDU2P,                                   GAME_EDU2P,                                     "edu2p",                                "-edu2p",                                       "EDU2 Prototype",                       "EDU2_Prototype",                       "id1",          "edu2",                 "edu2_p",                       "edu2prototype"                 }, // COMMANDLINEOPTION: Game: -edu2p runs the game Edu2 prototype
56 { GAME_PROPHECY,                                GAME_PROPHECY,                          "prophecy",                             "-prophecy",                            "Prophecy",                                     "Prophecy",                                     "gamedata",     NULL,                   "phcy",                         "prophecy"                              }, // COMMANDLINEOPTION: Game: -prophecy runs the game Prophecy
57 { GAME_BLOODOMNICIDE,                   GAME_BLOODOMNICIDE,                     "omnicide",                             "-omnicide",                            "Blood Omnicide",                       "Blood_Omnicide",                       "kain",         NULL,                   "omnicide",                     "omnicide"                              }, // COMMANDLINEOPTION: Game: -omnicide runs the game Blood Omnicide
58 { GAME_STEELSTORM,                              GAME_STEELSTORM,                        "steelstorm",                   "-steelstorm",                          "Steel-Storm",                          "Steel-Storm",                          "gamedata",     NULL,                   "ss",                           "steelstorm"                    }, // COMMANDLINEOPTION: Game: -steelstorm runs the game Steel Storm
59 { GAME_STEELSTORM2,                             GAME_STEELSTORM2,                       "steelstorm2",                  "-steelstorm2",                         "Steel Storm 2",                        "Steel_Storm_2",                        "gamedata",     NULL,                   "ss2",                          "steelstorm2"                   }, // COMMANDLINEOPTION: Game: -steelstorm2 runs the game Steel Storm 2
60 { GAME_SSAMMO,                                  GAME_SSAMMO,                            "steelstorm-ammo",              "-steelstormammo",                      "Steel Storm A.M.M.O.",         "Steel_Storm_A.M.M.O.",         "gamedata", NULL,                       "ssammo",                       "steelstorm-ammo"               }, // COMMANDLINEOPTION: Game: -steelstormammo runs the game Steel Storm A.M.M.O.
61 { GAME_STEELSTORMREVENANTS,             GAME_STEELSTORMREVENANTS,       "steelstorm-revenants", "-steelstormrev",                       "Steel Storm: Revenants",       "Steel_Storm_Revenants",        "base", NULL,                           "ssrev",                        "steelstorm-revenants"  }, // COMMANDLINEOPTION: Game: -steelstormrev runs the game Steel Storm: Revenants
62 { GAME_TOMESOFMEPHISTOPHELES,   GAME_TOMESOFMEPHISTOPHELES,     "tomesofmephistopheles","-tomesofmephistopheles",       "Tomes of Mephistopheles",      "Tomes_of_Mephistopheles",      "gamedata",     NULL,                   "tom",                          "tomesofmephistopheles" }, // COMMANDLINEOPTION: Game: -tomesofmephistopheles runs the game Tomes of Mephistopheles
63 { GAME_STRAPBOMB,                               GAME_STRAPBOMB,                         "strapbomb",                    "-strapbomb",                           "Strap-on-bomb Car",            "Strap-on-bomb_Car",            "id1",          NULL,                   "strap",                        "strapbomb"                             }, // COMMANDLINEOPTION: Game: -strapbomb runs the game Strap-on-bomb Car
64 { GAME_MOONHELM,                                GAME_MOONHELM,                          "moonhelm",                             "-moonhelm",                            "MoonHelm",                                     "MoonHelm",                                     "data",         NULL,                   "mh",                           "moonhelm"                              }, // COMMANDLINEOPTION: Game: -moonhelm runs the game MoonHelm
65 { GAME_VORETOURNAMENT,                  GAME_VORETOURNAMENT,            "voretournament",               "-voretournament",                      "Vore Tournament",                      "Vore_Tournament",                      "data",         NULL,                   "voretournament",       "voretournament"                }, // COMMANDLINEOPTION: Game: -voretournament runs the multiplayer game Vore Tournament
66 { GAME_DOOMBRINGER,                             GAME_DOOMBRINGER,                       "doombringer",                  "-doombringer",                         "DOOMBRINGER",                          "DOOMBRINGER",                          "dbdata",       NULL,                   "doombringer",          "doombringer"                   }, // COMMANDLINEOPTION: Game: -doombringer runs the game DOOMBRINGER
67 };
68
69 static void COM_SetGameType(int index);
70 void COM_InitGameType (void)
71 {
72         char name [MAX_OSPATH];
73         int i;
74         int index = 0;
75
76 #ifdef FORCEGAME
77         COM_ToLowerString(FORCEGAME, name, sizeof (name));
78 #else
79         // check executable filename for keywords, but do it SMARTLY - only check the last path element
80         FS_StripExtension(FS_FileWithoutPath(sys.argv[0]), name, sizeof (name));
81         COM_ToLowerString(name, name, sizeof (name));
82 #endif
83         for (i = 1;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
84                 if (gamemode_info[i].prog_name && gamemode_info[i].prog_name[0] && strstr (name, gamemode_info[i].prog_name))
85                         index = i;
86
87         // check commandline options for keywords
88         for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
89                 if (COM_CheckParm (gamemode_info[i].cmdline))
90                         index = i;
91
92         com_startupgamemode = gamemode_info[index].mode;
93         com_startupgamegroup = gamemode_info[index].group;
94         COM_SetGameType(index);
95 }
96
97 void COM_ChangeGameTypeForGameDirs(void)
98 {
99         int i;
100         int index = -1;
101         // this will not not change the gamegroup
102         // first check if a base game (single gamedir) matches
103         for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
104         {
105                 if (gamemode_info[i].group == com_startupgamegroup && !(gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]))
106                 {
107                         index = i;
108                         break;
109                 }
110         }
111         // now that we have a base game, see if there is a matching derivative game (two gamedirs)
112         if (fs_numgamedirs)
113         {
114                 for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
115                 {
116                         if (gamemode_info[i].group == com_startupgamegroup && (gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]) && !strcasecmp(fs_gamedirs[0], gamemode_info[i].gamedirname2))
117                         {
118                                 index = i;
119                                 break;
120                         }
121                 }
122         }
123         // we now have a good guess at which game this is meant to be...
124         if (index >= 0 && gamemode != gamemode_info[index].mode)
125                 COM_SetGameType(index);
126 }
127
128 static void COM_SetGameType(int index)
129 {
130         static char gamenetworkfilternamebuffer[64];
131         int i, t;
132         if (index < 0 || index >= (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0])))
133                 index = 0;
134         gamemode = gamemode_info[index].mode;
135         gamename = gamemode_info[index].gamename;
136         gamenetworkfiltername = gamemode_info[index].gamenetworkfiltername;
137         gamedirname1 = gamemode_info[index].gamedirname1;
138         gamedirname2 = gamemode_info[index].gamedirname2;
139         gamescreenshotname = gamemode_info[index].gamescreenshotname;
140         gameuserdirname = gamemode_info[index].gameuserdirname;
141
142         if (gamemode == com_startupgamemode)
143         {
144                 if((t = COM_CheckParm("-customgamename")) && t + 1 < sys.argc)
145                         gamename = gamenetworkfiltername = sys.argv[t+1];
146                 if((t = COM_CheckParm("-customgamenetworkfiltername")) && t + 1 < sys.argc)
147                         gamenetworkfiltername = sys.argv[t+1];
148                 if((t = COM_CheckParm("-customgamedirname1")) && t + 1 < sys.argc)
149                         gamedirname1 = sys.argv[t+1];
150                 if((t = COM_CheckParm("-customgamedirname2")) && t + 1 < sys.argc)
151                         gamedirname2 = *sys.argv[t+1] ? sys.argv[t+1] : NULL;
152                 if((t = COM_CheckParm("-customgamescreenshotname")) && t + 1 < sys.argc)
153                         gamescreenshotname = sys.argv[t+1];
154                 if((t = COM_CheckParm("-customgameuserdirname")) && t + 1 < sys.argc)
155                         gameuserdirname = sys.argv[t+1];
156         }
157
158         if (gamedirname2 && gamedirname2[0])
159                 Con_Printf("Game is %s using base gamedirs %s %s", gamename, gamedirname1, gamedirname2);
160         else
161                 Con_Printf("Game is %s using base gamedir %s", gamename, gamedirname1);
162         for (i = 0;i < fs_numgamedirs;i++)
163         {
164                 if (i == 0)
165                         Con_Printf(", with mod gamedirs");
166                 Con_Printf(" %s", fs_gamedirs[i]);
167         }
168         Con_Printf("\n");
169
170         if (strchr(gamenetworkfiltername, ' '))
171         {
172                 char *s;
173                 // if there are spaces in the game's network filter name it would
174                 // cause parse errors in getservers in dpmaster, so we need to replace
175                 // them with _ characters
176                 strlcpy(gamenetworkfilternamebuffer, gamenetworkfiltername, sizeof(gamenetworkfilternamebuffer));
177                 while ((s = strchr(gamenetworkfilternamebuffer, ' ')) != NULL)
178                         *s = '_';
179                 gamenetworkfiltername = gamenetworkfilternamebuffer;
180         }
181
182         Con_Printf("gamename for server filtering: %s\n", gamenetworkfiltername);
183 }