1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2016 EDuke32 developers and contributors
4 
5 This file is part of EDuke32.
6 
7 EDuke32 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 //-------------------------------------------------------------------------
22 
23 #include "duke3d.h"
24 #include "demo.h"
25 #include "screens.h"
26 #include "renderlayer.h"
27 #include "cmdline.h"
28 
29 int32_t g_commandSetup = 0;
30 int32_t g_noSetup = 0;
31 int32_t g_noAutoLoad = 0;
32 int32_t g_noSound = 0;
33 int32_t g_noMusic = 0;
34 const char *CommandMap = NULL;
35 const char *CommandName = NULL;
36 int32_t g_forceWeaponChoice = 0;
37 int32_t g_fakeMultiMode = 0;
38 
G_ShowParameterHelp(void)39 void G_ShowParameterHelp(void)
40 {
41     static char const s[] = "Usage: " APPBASENAME " [files] [options]\n"
42         "Example: " APPBASENAME " -usecwd -cfg myconfig.cfg -map nukeland.map\n\n"
43         "Files can be of type [grp|zip|map|con|def]\n"
44         "\n"
45         "-cfg [file.cfg]\tUse an alternate configuration file\n"
46 #ifdef HAVE_CLIPSHAPE_FEATURE
47         "-clipmap [file.map]\tLoad an additional clipping map for use with clipshape\n"
48 #endif
49         "-connect [host]\tConnect to a multiplayer game\n"
50         "-c#\t\tMultiplayer mode #, 1 = DM, 2 = Co-op, 3 = DM(no spawn)\n"
51         "-d [file.edm or #]\tPlay a demo\n"
52         "-g [file.grp]\tLoad additional game data\n"
53         "-h [file.def]\tLoad an alternate definitions file\n"
54         "-j [dir]\t\tAdd a directory to " APPNAME "'s search list\n"
55         "-l#\t\tStart game on level #, see -v\n"
56         "-map [file.map]\tLoad an external map file\n"
57         "-mh [file.def]\tInclude an additional definitions module\n"
58         "-mx [file.con]\tInclude an additional CON script module\n"
59         "-m\t\tDisable enemies\n"
60         "-rts [file.rts]\tLoad a custom Remote Ridicule sound bank\n"
61         "-r\t\tRecord demo\n"
62         "-s#\t\tStart game on skill level #\n"
63         "-server\t\tStart a multiplayer server\n"
64 #ifdef STARTUP_SETUP_WINDOW
65         "-setup/nosetup\tEnable or disable startup window\n"
66 #endif
67         "-t#\t\tRespawn mode: 1 = enemies, 2 = weapons, 3 = items, x = all\n"
68         "-usecwd\t\tRead data and configuration from current directory\n"
69         "-u#########\tUser's favorite weapon order (default: 3425689071)\n"
70         "-v#\t\tStart game on episode #, see -l\n"
71         "-x [game.con]\tLoad custom CON script\n"
72         "-#\t\tLoad and run a game from slot # (0-9)\n"
73         //              "\n-?/--help\tDisplay this help message and exit\n"
74         "\nSee " APPBASENAME " -debughelp for additional parameters for debugging"
75         ;
76 #ifdef WM_MSGBOX_WINDOW
77     Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev);
78     wm_msgbox(tempbuf, s);
79 #else
80     initprintf("%s\n", s);
81 #endif
82 }
83 
G_ShowDebugHelp(void)84 void G_ShowDebugHelp(void)
85 {
86     static char const s[] = "Usage: " APPBASENAME " [files] [options]\n"
87         "\n"
88 #if 0
89         "-a\t\tUse fake player AI (fake multiplayer only)\n"
90 #endif
91         "-cachesize #\tSet cache size in kB\n"
92         "-game_dir [dir]\tSpecify game data directory\n"
93         "-gamegrp   \tSelect main grp file\n"
94         "-name [name]\tPlayer name in multiplayer\n"
95         "-noautoload\tDisable loading from autoload directory\n"
96 #if defined RENDERTYPEWIN
97         "-nodinput\t\tDisable DirectInput (joystick) support\n"
98 #endif
99         "-nologo\t\tSkip intro anim\n"
100         "-ns\t\tDisable sound\n"
101         "-nm\t\tDisable music\n"
102         "-q#\t\tFake multiplayer with # players\n"
103         "-z#/-condebug\tEnable line-by-line CON compile debugging at level #\n"
104         "-conversion YYYYMMDD\tSelects CON script version for compatibility with older mods\n"
105         "-rotatesprite-no-widescreen\tStretch screen drawing from scripts to fullscreen\n"
106         ;
107 #ifdef WM_MSGBOX_WINDOW
108     Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev);
109     wm_msgbox(tempbuf, s);
110 #else
111     initprintf("%s\n", s);
112 #endif
113 }
114 
G_AddDemo(const char * param)115 static void G_AddDemo(const char* param)
116 {
117     Bstrncpy(tempbuf, param, sizeof(tempbuf));
118     char * colon = (char *) Bstrchr(tempbuf, ':');
119     int32_t framespertic=-1, numrepeats=1;
120 
121     if (colon && colon != tempbuf)
122     {
123         // -d<filename>:<num>[,<num>]
124         // profiling options
125         *(colon++) = 0;
126         Bsscanf(colon, "%d,%d", &framespertic, &numrepeats);
127     }
128 
129     Demo_SetFirst(tempbuf);
130 
131     if (framespertic < 0)
132     {
133         initprintf("Play demo %s.\n", g_firstDemoFile);
134     }
135     else
136     {
137         framespertic = clamp(framespertic, 0, 8)+1;
138         // TODO: repeat count and gathering statistics.
139         initprintf("Profile demo %s, %d frames/gametic, repeated 1x.\n", g_firstDemoFile,
140             framespertic-1);
141         Demo_PlayFirst(framespertic, 1);
142         g_noLogo = 1;
143     }
144 }
145 
G_CheckCommandLine(int32_t argc,char const * const * argv)146 void G_CheckCommandLine(int32_t argc, char const * const * argv)
147 {
148     int16_t i = 1, j;
149     const char *c, *k;
150 
151     ud.fta_on = 1;
152     ud.god = 0;
153     ud.m_respawn_items = 0;
154     ud.m_respawn_monsters = 0;
155     ud.m_respawn_inventory = 0;
156     ud.warp_on = 0;
157     ud.cashman = 0;
158     ud.m_player_skill = ud.player_skill = 2;
159     g_player[0].wchoice[0] = 3;
160     g_player[0].wchoice[1] = 4;
161     g_player[0].wchoice[2] = 5;
162     g_player[0].wchoice[3] = 7;
163     g_player[0].wchoice[4] = 8;
164     g_player[0].wchoice[5] = 6;
165     g_player[0].wchoice[6] = 0;
166     g_player[0].wchoice[7] = 2;
167     g_player[0].wchoice[8] = 9;
168     g_player[0].wchoice[9] = 1;
169     Bsprintf(ud.wchoice, "3457860291");
170 
171 #ifdef HAVE_CLIPSHAPE_FEATURE
172     // pre-form the default 10 clipmaps
173     for (j = '0'; j<='9'; ++j)
174     {
175         char clipshape[16] = "_clipshape0.map";
176 
177         clipshape[10] = j;
178         g_clipMapFiles.append(Xstrdup(clipshape));
179     }
180 #endif
181 
182     if (argc > 1)
183     {
184         initprintf("Application parameters: ");
185         while (i < argc)
186             initprintf("%s ", argv[i++]);
187         initprintf("\n");
188 
189         i = 1;
190         do
191         {
192             const char *const oc = argv[i];
193             int32_t shortopt = 0, ignored_short_opt = 0;
194 
195             c = oc;
196 
197             if ((*c == '-')
198 #ifdef _WIN32
199                 || (*c == '/')
200 #endif
201                 )
202             {
203                 shortopt = 0;
204 
205                 if (!Bstrcasecmp(c+1, "?") || !Bstrcasecmp(c+1, "help") || !Bstrcasecmp(c+1, "-help"))
206                 {
207                     G_ShowParameterHelp();
208                     Bexit(0);
209                 }
210                 if (!Bstrcasecmp(c+1, "addon"))
211                 {
212                     if (argc > i+1)
213                     {
214                         g_addonNum = Batoi(argv[i+1]);
215 
216                         if (g_addonNum > ADDON_NONE && g_addonNum < NUMADDONS)
217                             g_noSetup = 1;
218                         else g_addonNum = ADDON_NONE;
219 
220                         i++;
221                     }
222                     i++;
223                     continue;
224                 }
225                 if (!Bstrcasecmp(c+1, "debughelp") || !Bstrcasecmp(c+1, "-debughelp"))
226                 {
227                     G_ShowDebugHelp();
228                     Bexit(0);
229                 }
230                 if (!Bstrcasecmp(c+1, "grp") || !Bstrcasecmp(c+1, "g"))
231                 {
232                     if (argc > i+1)
233                     {
234                         G_AddGroup(argv[i+1]);
235                         i++;
236                     }
237                     i++;
238                     continue;
239                 }
240                 if (!Bstrcasecmp(c+1, "game_dir"))
241                 {
242                     if (argc > i+1)
243                     {
244                         Bstrncpyz(g_modDir, argv[i+1], sizeof(g_modDir));
245                         G_AddPath(argv[i+1]);
246                         i++;
247                     }
248                     i++;
249                     continue;
250                 }
251                 if (!Bstrcasecmp(c+1, "cfg"))
252                 {
253                     if (argc > i+1)
254                     {
255                         Bstrcpy(g_setupFileName, argv[i+1]);
256                         i++;
257                     }
258                     i++;
259                     continue;
260                 }
261                 if (!Bstrcasecmp(c+1, "gamegrp"))
262                 {
263                     if (argc > i+1)
264                     {
265                         clearGrpNamePtr();
266                         g_grpNamePtr = dup_filename(argv[i+1]);
267                         i++;
268                     }
269                     i++;
270                     continue;
271                 }
272                 if (!Bstrcasecmp(c+1, "nam"))
273                 {
274                     g_gameType = GAMEFLAG_NAM;
275                     i++;
276                     continue;
277                 }
278                 if (!Bstrcasecmp(c+1, "napalm"))
279                 {
280                     g_gameType = GAMEFLAG_NAM|GAMEFLAG_NAPALM;
281                     i++;
282                     continue;
283                 }
284                 if (!Bstrcasecmp(c+1, "setup"))
285                 {
286                     g_commandSetup = TRUE;
287                     i++;
288                     continue;
289                 }
290                 if (!Bstrcasecmp(c+1, "nosetup"))
291                 {
292                     g_noSetup = 1;
293                     g_commandSetup = 0;
294                     i++;
295                     continue;
296                 }
297 #if defined RENDERTYPEWIN
298                 if (!Bstrcasecmp(c+1, "nodinput"))
299                 {
300                     initprintf("DirectInput (joystick) support disabled\n");
301                     di_disabled = 1;
302                     i++;
303                     continue;
304                 }
305 #endif
306                 if (!Bstrcasecmp(c+1, "noautoload"))
307                 {
308                     initprintf("Autoload disabled\n");
309                     g_noAutoLoad = 1;
310                     i++;
311                     continue;
312                 }
313 #ifndef NETCODE_DISABLE
314                 if (!Bstrcasecmp(c+1, "net"))
315                 {
316                     G_GameExit("EDuke32 no longer supports legacy networking.\n\n"
317                         "If using YANG or other launchers that only support legacy netplay, download an older build of EDuke32. "
318                         "Otherwise, run the following:\n\n"
319                         "eduke32 -server\n\n"
320                         "Other clients can then connect by typing \"connect [host]\" in the console.\n\n"
321                         "EDuke32 will now close.");
322                 }
323 #endif
324                 if (!Bstrcasecmp(c+1, "port"))
325                 {
326                     if (argc > i+1)
327                     {
328                         g_netPort = Batoi(argv[i+1]);
329                         i++;
330                     }
331                     i++;
332                     continue;
333                 }
334 #ifndef NETCODE_DISABLE
335                 if (!Bstrcasecmp(c+1, "server"))
336                 {
337                     g_networkMode = NET_SERVER;
338                     g_noSetup = g_noLogo = TRUE;
339                     i++;
340                     continue;
341                 }
342                 //if (!Bstrcasecmp(c+1, "dedicated"))
343                 //{
344                 //    g_networkMode = NET_DEDICATED_SERVER;
345                 //    g_noSetup = g_noLogo = TRUE;
346                 //    i++;
347                 //    continue;
348                 //}
349                 if (!Bstrcasecmp(c+1, "connect"))
350                 {
351                     if (argc > i+1)
352                     {
353                         Net_Connect(argv[i+1]);
354                         g_noSetup = g_noLogo = TRUE;
355                         i++;
356                     }
357                     i++;
358                     continue;
359                 }
360                 if (!Bstrcasecmp(c+1, "password"))
361                 {
362                     if (argc > i+1)
363                     {
364                         Bstrncpyz(g_netPassword, argv[i+1], sizeof(g_netPassword));
365                         i++;
366                     }
367                     i++;
368                     continue;
369                 }
370 #endif
371                 if (!Bstrcasecmp(c+1, "name"))
372                 {
373                     if (argc > i+1)
374                     {
375                         CommandName = argv[i+1];
376                         i++;
377                     }
378                     i++;
379                     continue;
380                 }
381                 if (!Bstrcasecmp(c+1, "map"))
382                 {
383                     if (argc > i+1)
384                     {
385                         CommandMap = argv[i+1];
386                         i++;
387                     }
388                     i++;
389                     continue;
390                 }
391                 if (!Bstrcasecmp(c+1, "rts"))
392                 {
393                     if (argc > i+1)
394                     {
395                         free(g_rtsNamePtr);
396                         g_rtsNamePtr = dup_filename(argv[i+1]);
397                         initprintf("Using RTS file \"%s\".\n", g_rtsNamePtr);
398                         i++;
399                     }
400                     i++;
401                     continue;
402                 }
403                 if (!Bstrcasecmp(c+1, "x"))
404                 {
405                     if (argc > i+1)
406                     {
407                         G_AddCon(argv[i+1]);
408                         i++;
409                     }
410                     i++;
411                     continue;
412                 }
413                 if (!Bstrcasecmp(c+1, "mx"))
414                 {
415                     if (argc > i+1)
416                     {
417                         G_AddConModule(argv[i+1]);
418                         i++;
419                     }
420                     i++;
421                     continue;
422                 }
423                 if (!Bstrcasecmp(c+1, "h"))
424                 {
425                     if (argc > i+1)
426                     {
427                         G_AddDef(argv[i+1]);
428                         i++;
429                     }
430                     i++;
431                     continue;
432                 }
433                 if (!Bstrcasecmp(c+1, "mh"))
434                 {
435                     if (argc > i+1)
436                     {
437                         G_AddDefModule(argv[i+1]);
438                         i++;
439                     }
440                     i++;
441                     continue;
442                 }
443                 if (!Bstrcasecmp(c+1, "j"))
444                 {
445                     if (argc > i+1)
446                     {
447                         G_AddPath(argv[i+1]);
448                         i++;
449                     }
450                     i++;
451                     continue;
452                 }
453                 if (!Bstrcasecmp(c+1, "d"))
454                 {
455                     if (argc > i+1)
456                     {
457                         G_AddDemo(argv[i+1]);
458                         i++;
459                     }
460                     i++;
461                     continue;
462                 }
463 #ifdef HAVE_CLIPSHAPE_FEATURE
464                 if (!Bstrcasecmp(c+1, "clipmap"))
465                 {
466                     if (argc > i+1)
467                     {
468                         G_AddClipMap(argv[i+1]);
469                         i++;
470                     }
471                     i++;
472                     continue;
473                 }
474 #endif
475                 if (!Bstrcasecmp(c+1, "condebug"))
476                 {
477                     g_scriptDebug = 1;
478                     i++;
479                     continue;
480                 }
481                 if (!Bstrcasecmp(c+1, "nologo"))
482                 {
483                     g_noLogo = 1;
484                     i++;
485                     continue;
486                 }
487                 if (!Bstrcasecmp(c+1, "rotatesprite-no-widescreen"))
488                 {
489                     g_rotatespriteNoWidescreen = 1;
490                     i++;
491                     continue;
492                 }
493                 if (!Bstrcasecmp(c+1, "usecwd"))
494                 {
495                     g_useCwd = 1;
496                     i++;
497                     continue;
498                 }
499                 if (!Bstrcasecmp(c+1, "cachesize"))
500                 {
501                     if (argc > i+1)
502                     {
503                         uint32_t j = Batol(argv[i+1]);
504                         MAXCACHE1DSIZE = j<<10;
505                         initprintf("Cache size: %dkB\n", j);
506                         i++;
507                     }
508                     i++;
509                     continue;
510                 }
511                 if (!Bstrcasecmp(c+1, "noinstancechecking"))
512                 {
513                     i++;
514                     continue;
515                 }
516 #if defined(RENDERTYPEWIN) && defined(USE_OPENGL)
517                 if (!Bstrcasecmp(c+1, "forcegl"))
518                 {
519                     forcegl = 1;
520                     i++;
521                     continue;
522                 }
523 #endif
524                 // the following two dummy entries allow us to serve as a drop-in replacement for NAM on Steam
525                 if (!Bstrcasecmp(c+1, "noconsole"))
526                 {
527                     i++;
528                     continue;
529                 }
530                 if (!Bstrcasecmp(c+1, "conf"))
531                 {
532                     if (argc > i+1)
533                         i++;
534                     i++;
535                     continue;
536                 }
537             }
538 
539             if ((*c == '-')
540 #ifdef _WIN32
541                 || (*c == '/')
542 #endif
543                 )
544             {
545                 shortopt = 1;
546 
547                 c++;
548                 switch (Btolower(*c))
549                 {
550                 case 'a':
551                     ud.playerai = 1;
552                     initprintf("Other player AI.\n");
553                     break;
554                 case 'c':
555                     c++;
556                     ud.m_coop = 0;
557                     while ((*c >= '0')&&(*c <= '9'))
558                     {
559                         ud.m_coop *= 10;
560                         ud.m_coop += *c - '0';
561                         c++;
562                     }
563                     ud.m_coop--;
564                     break;
565                 case 'd':
566                 {
567                     c++;
568                     if (*c)
569                         G_AddDemo(c);
570                     break;
571                 }
572                 case 'g':
573                     c++;
574                     if (*c)
575                         G_AddGroup(c);
576                     break;
577                 case 'h':
578                     c++;
579                     if (*c)
580                         G_AddDef(c);
581                     break;
582                 case 'j':
583                     c++;
584                     if (*c)
585                         G_AddPath(c);
586                     break;
587                 case 'l':
588                     // NOTE: Overlaid with -Lopts=... options for Lunatic, hence the check.
589                     if (Bisdigit(c[1]))
590                     {
591                         ud.warp_on = 1;
592                         c++;
593                         ud.m_level_number = ud.level_number = ((unsigned) (Batoi(c)-1))%MAXLEVELS;
594                     }
595                     break;
596                 case 'm':
597                     if (*(c+1) != 'a' && *(c+1) != 'A')
598                     {
599                         ud.m_monsters_off = 1;
600                         ud.m_player_skill = ud.player_skill = 0;
601                         initprintf("Monsters off.\n");
602                     }
603                     break;
604                 case 'n':
605                     c++;
606                     if (*c == 's' || *c == 'S')
607                     {
608                         g_noSound = 2;
609                         initprintf("Sound off.\n");
610                     }
611                     else if (*c == 'm' || *c == 'M')
612                     {
613                         g_noMusic = 1;
614                         initprintf("Music off.\n");
615                     }
616                     else
617                     {
618                         G_ShowParameterHelp();
619                         exit(-1);
620                     }
621                     break;
622                 case 'q':
623                     if (*(++c) == 0)
624                     {
625                         ud.multimode = 1;
626                         initprintf("Fake multiplayer mode: expected number after -q, falling back to 1 player.\n");
627                     }
628                     else
629                     {
630                         int32_t numpl = Batoi(c);
631 
632                         if (numpl < 2 || numpl > MAXPLAYERS)
633                         {
634                             initprintf("Fake multiplayer mode: expected 2-%d players, falling back to 1.\n",
635                                 MAXPLAYERS);
636                         }
637                         else
638                         {
639                             ud.multimode = numpl;
640                             initprintf("Fake multiplayer mode: %d players.\n", ud.multimode);
641 
642                             g_fakeMultiMode = numpl;
643                         }
644                     }
645 
646                     ud.m_coop = ud.coop = 0;
647                     ud.m_marker = ud.marker = 1;
648                     ud.m_respawn_monsters = ud.respawn_monsters = 1;
649                     ud.m_respawn_items = ud.respawn_items = 1;
650                     ud.m_respawn_inventory = ud.respawn_inventory = 1;
651                     break;
652                 case 'r':
653                     ud.m_recstat = 1;
654                     initprintf("Demo record mode on.\n");
655                     break;
656                 case 's':
657                     c++;
658                     ud.m_player_skill = ud.player_skill = (Batoi(c)%5);
659                     if (ud.m_player_skill == 4)
660                         ud.m_respawn_monsters = ud.respawn_monsters = 1;
661                     break;
662                 case 't':
663                     c++;
664                     if (*c == '1') ud.m_respawn_monsters = 1;
665                     else if (*c == '2') ud.m_respawn_items = 1;
666                     else if (*c == '3') ud.m_respawn_inventory = 1;
667                     else
668                     {
669                         ud.m_respawn_monsters = 1;
670                         ud.m_respawn_items = 1;
671                         ud.m_respawn_inventory = 1;
672                     }
673                     initprintf("Respawn on.\n");
674                     break;
675                 case 'u':
676                     g_forceWeaponChoice = 1;
677                     c++;
678                     j = 0;
679                     if (*c)
680                     {
681                         initprintf("Using favorite weapon order(s).\n");
682                         while (*c)
683                         {
684                             g_player[0].wchoice[j] = *c-'0';
685                             ud.wchoice[j] = *c;
686                             c++;
687                             j++;
688                         }
689 
690                         while (j < 10)
691                         {
692                             if (j == 9)
693                             {
694                                 g_player[0].wchoice[9] = 1;
695                                 ud.wchoice[9] = '1';
696                             }
697                             else
698                             {
699                                 g_player[0].wchoice[j] = 2;
700                                 ud.wchoice[j] = '2';
701                             }
702 
703                             j++;
704                         }
705                     }
706                     else
707                     {
708                         initprintf("Using default weapon orders.\n");
709                         g_player[0].wchoice[0] = 3;
710                         g_player[0].wchoice[1] = 4;
711                         g_player[0].wchoice[2] = 5;
712                         g_player[0].wchoice[3] = 7;
713                         g_player[0].wchoice[4] = 8;
714                         g_player[0].wchoice[5] = 6;
715                         g_player[0].wchoice[6] = 0;
716                         g_player[0].wchoice[7] = 2;
717                         g_player[0].wchoice[8] = 9;
718                         g_player[0].wchoice[9] = 1;
719 
720                         Bsprintf(ud.wchoice, "3457860291");
721                     }
722                     break;
723                 case 'v':
724                     c++;
725                     ud.warp_on = 1;
726                     ud.m_volume_number = ud.volume_number = ((unsigned) (Batoi(c)-1))%MAXVOLUMES;
727                     break;
728                 case 'w':
729                     ud.coords = 1;
730                     break;
731                 case 'x':
732                     c++;
733                     if (*c)
734                         G_AddCon(c);
735                     break;
736                 case 'z':
737                     c++;
738                     g_scriptDebug = Batoi(c);
739                     if (!g_scriptDebug)
740                         g_scriptDebug = 1;
741                     break;
742                 default:
743                     ignored_short_opt = 1;
744                     break;
745                 }
746             }
747             else
748             {
749                 shortopt = 0;
750 
751                 k = Bstrrchr(c, '.');
752                 if (k)
753                 {
754                     if (!Bstrcasecmp(k, ".map"))
755                     {
756                         CommandMap = argv[i++];
757                         continue;
758                     }
759                     if (!Bstrcasecmp(k, ".grp") || !Bstrcasecmp(k, ".zip") || !Bstrcasecmp(k, ".pk3") || !Bstrcasecmp(k, ".pk4"))
760                     {
761                         G_AddGroup(argv[i++]);
762                         continue;
763                     }
764                     if (!Bstrcasecmp(k, ".con"))
765                     {
766                         clearScriptNamePtr();
767                         g_scriptNamePtr = dup_filename(argv[i++]);
768                         initprintf("Using CON file \"%s\".\n", g_scriptNamePtr);
769                         continue;
770                     }
771                     if (!Bstrcasecmp(k, ".def"))
772                     {
773                         clearDefNamePtr();
774                         g_defNamePtr = dup_filename(argv[i++]);
775                         initprintf("Using DEF file \"%s\".\n", g_defNamePtr);
776                         continue;
777                     }
778                     if (!Bstrcasecmp(k, ".rts"))
779                     {
780                         free(g_rtsNamePtr);
781                         g_rtsNamePtr = dup_filename(argv[i++]);
782                         initprintf("Using RTS file \"%s\".\n", g_rtsNamePtr);
783                         continue;
784                     }
785                 }
786             }
787 
788             if (!shortopt || ignored_short_opt)
789                 initprintf("Warning: ignored application parameter \"%s\".\n", oc);
790 
791             i++;
792         } while (i < argc);
793     }
794 }
795