key_dest = key_game;
m_state = m_none;
//cls.demonum = m_save_demonum;
+ //if(!cl_startdemos.integer)
+ // break;
//if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected)
// CL_NextDemo ();
break;
//=============================================================================
/* MODLIST MENU */
-// same limit of mod dirs as in fs.c
-#define MODLIST_MAXDIRS 16
-static int modlist_enabled [MODLIST_MAXDIRS]; //array of indexs to modlist
+// same limit of mod dirs as in fs.c (allowing that one is used by gamedirname1)
+#define MODLIST_MAXDIRS MAX_GAMEDIRS - 1
static int modlist_numenabled; //number of enabled (or in process to be..) mods
typedef struct modlist_entry_s
{
qbool loaded; // used to determine whether this entry is loaded and running
- int enabled; // index to array of modlist_enabled
- // name of the modification, this is (will...be) displayed on the menu entry
+ // name of the modification, this is displayed on the menu entry
char name[128];
// directory where we will find it
char dir[MAX_QPATH];
int i,j;
stringlist_t list;
const char *description;
+ int desc_len;
stringlistinit(&list);
listdirectory(&list, fs_basedir, "");
stringlistsort(&list, true);
modlist_count = 0;
- modlist_numenabled = fs_numgamedirs;
+ modlist_numenabled = 0;
for (i = 0;i < list.numstrings && modlist_count < MODLIST_TOTALSIZE;i++)
{
- // quickly skip names with dot characters - generally these are files, not directories
- if (strchr(list.strings[i], '.')) continue;
-
// reject any dirs that are part of the base game
if (gamedirname1 && !strcasecmp(gamedirname1, list.strings[i])) continue;
//if (gamedirname2 && !strcasecmp(gamedirname2, list.strings[i])) continue;
description = FS_CheckGameDir(list.strings[i]);
if (description == NULL || description == fs_checkgamedir_missing) continue;
+ desc_len = min(strlen(description), sizeof(modlist[modlist_count].name));
+ for (j = 0; j < desc_len; ++j)
+ if (!ISWHITESPACE(description[j]))
+ {
+ dp_strlcpy(modlist[modlist_count].name, description, sizeof(modlist[modlist_count].name));
+ break;
+ }
+
dp_strlcpy (modlist[modlist_count].dir, list.strings[i], sizeof(modlist[modlist_count].dir));
- //check currently loaded mods
+
+ // check if this mod is currently loaded
modlist[modlist_count].loaded = false;
- if (fs_numgamedirs)
- for (j = 0; j < fs_numgamedirs; j++)
- if (!strcasecmp(fs_gamedirs[j], modlist[modlist_count].dir))
- {
- modlist[modlist_count].loaded = true;
- modlist[modlist_count].enabled = j;
- modlist_enabled[j] = modlist_count;
- break;
- }
+ for (j = 0; j < fs_numgamedirs; j++)
+ if (!strcasecmp(fs_gamedirs[j], modlist[modlist_count].dir))
+ {
+ modlist[modlist_count].loaded = true;
+ modlist_numenabled++;
+ break;
+ }
+
modlist_count ++;
}
stringlistfreecontents(&list);
{
int i;
int numgamedirs;
- char gamedirs[MODLIST_MAXDIRS][MAX_QPATH];
-
- // copy our mod list into an array for FS_ChangeGameDirs
- numgamedirs = modlist_numenabled;
- for (i = 0; i < modlist_numenabled; i++)
- dp_strlcpy (gamedirs[i], modlist[modlist_enabled[i]].dir,sizeof (gamedirs[i]));
-
- // this code snippet is from FS_ChangeGameDirs
- if (fs_numgamedirs == numgamedirs)
- {
- for (i = 0;i < numgamedirs;i++)
- if (strcasecmp(fs_gamedirs[i], gamedirs[i]))
- break;
- if (i == numgamedirs)
- return; // already using this set of gamedirs, do nothing
- }
+ const char *gamedirs[MODLIST_MAXDIRS];
// this part is basically the same as the FS_GameDir_f function
if ((cls.state == ca_connected && !cls.demoplayback) || sv.active)
return;
}
- FS_ChangeGameDirs (modlist_numenabled, gamedirs, true, true);
+ // copy our mod list into an array for FS_ChangeGameDirs
+ for (i = 0, numgamedirs = 0; i < modlist_count && numgamedirs < MODLIST_MAXDIRS; i++)
+ if (modlist[i].loaded)
+ gamedirs[numgamedirs++] = modlist[i].dir;
+ // allow disabling all active mods using the menu
+ if (numgamedirs == 0)
+ {
+ numgamedirs = 1;
+ gamedirs[0] = gamedirname1;
+ }
+
+ FS_ChangeGameDirs(numgamedirs, gamedirs, true);
}
void M_Menu_ModList_f(cmd_state_t *cmd)
static void M_Menu_ModList_AdjustSliders (int dir)
{
- int i;
S_LocalSound ("sound/misc/menu3.wav");
// stop adding mods, we reach the limit
if (!modlist[modlist_cursor].loaded && (modlist_numenabled == MODLIST_MAXDIRS)) return;
+
modlist[modlist_cursor].loaded = !modlist[modlist_cursor].loaded;
- if (modlist[modlist_cursor].loaded)
- {
- modlist[modlist_cursor].enabled = modlist_numenabled;
- //push the value on the enabled list
- modlist_enabled[modlist_numenabled++] = modlist_cursor;
- }
- else
- {
- //eliminate the value from the enabled list
- for (i = modlist[modlist_cursor].enabled; i < modlist_numenabled; i++)
- {
- modlist_enabled[i] = modlist_enabled[i+1];
- modlist[modlist_enabled[i]].enabled--;
- }
- modlist_numenabled--;
- }
+ modlist_numenabled += modlist[modlist_cursor].loaded ? 1 : -1;
}
static void M_ModList_Draw (void)
M_PrintRed(432, 32, s_enabled);
// Draw a list box with all enabled mods
DrawQ_Pic(menu_x + 432, menu_y + 48, NULL, 172, 8 * modlist_numenabled, 0, 0, 0, 0.5, 0);
- for (y = 0; y < modlist_numenabled; y++)
- M_PrintRed(432, 48 + y * 8, modlist[modlist_enabled[y]].dir);
+ for (n = 0, y = 48; n < modlist_count; n++)
+ if (modlist[n].loaded)
+ {
+ M_PrintRed(432, y, modlist[n].dir);
+ y += 8;
+ }
if (*cl_connect_status)
M_Print(16, menu_height - 8, cl_connect_status);
{
for (n = start;n < end;n++)
{
+ const char *item_label = (modlist[n].name[0] != '\0') ? modlist[n].name : modlist[n].dir;
+
DrawQ_Pic(menu_x + 40, menu_y + y, NULL, 360, 8, n == modlist_cursor ? (0.5 + 0.2 * sin(host.realtime * M_PI)) : 0, 0, 0, 0.5, 0);
- M_ItemPrint(80, y, modlist[n].dir, true);
+ M_ItemPrint(80, y, item_label, true);
M_DrawCheckbox(48, y, modlist[n].loaded);
y +=8;
}
{
if(MR_Shutdown)
MR_Shutdown ();
- MR_SetRouting (false);
+ MR_Init();
}
static void MR_Restart_f(cmd_state_t *cmd)