Subversion Repositories eduke32

Rev

Rev 4789 | Rev 4801 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2542 helixhorne 1
//
2
// Common non-engine code/data for EDuke32 and Mapster32
3
//
4
 
5
#include "compat.h"
2726 hendricks2 6
#include "build.h"
4584 helixhorne 7
#include "baselayer.h"
4559 hendricks2 8
 
4557 hendricks2 9
#include "grpscan.h"
2542 helixhorne 10
 
3581 hendricks2 11
#ifdef _WIN32
12
# include "winbits.h"
3671 hendricks2 13
# include <shlwapi.h>
14
# include <winnt.h>
15
# ifndef KEY_WOW64_32KEY
16
#  define KEY_WOW64_32KEY 0x0200
17
# endif
3581 hendricks2 18
#endif
19
 
2542 helixhorne 20
#include "common.h"
2726 hendricks2 21
#include "common_game.h"
2542 helixhorne 22
 
2789 hendricks2 23
int32_t g_gameType = GAMEFLAG_DUKE;
2542 helixhorne 24
 
4557 hendricks2 25
int32_t g_dependencyCRC = 0;
26
int32_t g_usingAddon = 0;
27
 
28
// g_gameNamePtr can point to one of: grpfiles[].name (string literal), string
29
// literal, malloc'd block (XXX: possible leak)
30
const char *g_gameNamePtr = NULL;
31
 
4559 hendricks2 32
// grp/con handling
2726 hendricks2 33
 
4789 hendricks2 34
static const char *defaultgamegrp[GAMECOUNT] = { "DUKE3D.GRP", "NAM.GRP", "NAPALM.GRP", "WW2GI.GRP" };
35
static const char *defaultdeffilename[GAMECOUNT] = { "duke3d.def", "nam.def", "napalm.def", "ww2gi.def" };
36
static const char *defaultconfilename = "GAME.CON";
37
static const char *defaultgameconfilename[GAMECOUNT] = { "EDUKE.CON", "NAM.CON", "NAPALM.CON", "WW2GI.CON" };
2726 hendricks2 38
 
39
// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
40
char *g_grpNamePtr = NULL;
41
// g_scriptNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
42
char *g_scriptNamePtr = NULL;
43
 
44
void clearGrpNamePtr(void)
45
{
46
    if (g_grpNamePtr != NULL)
47
        Bfree(g_grpNamePtr);
48
    // g_grpNamePtr assumed to be assigned to right after
49
}
50
 
51
void clearScriptNamePtr(void)
52
{
53
    if (g_scriptNamePtr != NULL)
54
        Bfree(g_scriptNamePtr);
55
    // g_scriptNamePtr assumed to be assigned to right after
56
}
57
 
2796 helixhorne 58
const char *G_DefaultGrpFile(void)
2726 hendricks2 59
{
60
    if (DUKE)
61
        return defaultgamegrp[GAME_DUKE];
62
    // order is important for the following three because GAMEFLAG_NAM overlaps all
63
    else if (NAPALM)
64
        return defaultgamegrp[GAME_NAPALM];
65
    else if (WW2GI)
66
        return defaultgamegrp[GAME_WW2GI];
67
    else if (NAM)
68
        return defaultgamegrp[GAME_NAM];
69
 
70
    return defaultgamegrp[0];
71
}
2796 helixhorne 72
const char *G_DefaultDefFile(void)
2726 hendricks2 73
{
74
    if (DUKE)
75
        return defaultdeffilename[GAME_DUKE];
76
    else if (WW2GI)
77
        return defaultdeffilename[GAME_WW2GI];
78
    else if (NAPALM)
79
    {
2752 helixhorne 80
        if (!testkopen(defaultdeffilename[GAME_NAPALM],0) && testkopen(defaultdeffilename[GAME_NAM],0))
3618 hendricks2 81
            return defaultdeffilename[GAME_NAM]; // NAM/NAPALM Sharing
2726 hendricks2 82
        else
83
            return defaultdeffilename[GAME_NAPALM];
84
    }
85
    else if (NAM)
86
    {
2752 helixhorne 87
        if (!testkopen(defaultdeffilename[GAME_NAM],0) && testkopen(defaultdeffilename[GAME_NAPALM],0))
3618 hendricks2 88
            return defaultdeffilename[GAME_NAPALM]; // NAM/NAPALM Sharing
2726 hendricks2 89
        else
90
            return defaultdeffilename[GAME_NAM];
91
    }
92
 
93
    return defaultdeffilename[0];
94
}
2796 helixhorne 95
const char *G_DefaultConFile(void)
2726 hendricks2 96
{
2752 helixhorne 97
    if (DUKE && testkopen(defaultgameconfilename[GAME_DUKE],0))
2726 hendricks2 98
        return defaultgameconfilename[GAME_DUKE];
2752 helixhorne 99
    else if (WW2GI && testkopen(defaultgameconfilename[GAME_WW2GI],0))
2726 hendricks2 100
        return defaultgameconfilename[GAME_WW2GI];
101
    else if (NAPALM)
102
    {
2752 helixhorne 103
        if (!testkopen(defaultgameconfilename[GAME_NAPALM],0))
2726 hendricks2 104
        {
2752 helixhorne 105
            if (testkopen(defaultgameconfilename[GAME_NAM],0))
3618 hendricks2 106
                return defaultgameconfilename[GAME_NAM]; // NAM/NAPALM Sharing
2726 hendricks2 107
        }
108
        else
109
            return defaultgameconfilename[GAME_NAPALM];
110
    }
111
    else if (NAM)
112
    {
2752 helixhorne 113
        if (!testkopen(defaultgameconfilename[GAME_NAM],0))
2726 hendricks2 114
        {
2752 helixhorne 115
            if (testkopen(defaultgameconfilename[GAME_NAPALM],0))
3618 hendricks2 116
                return defaultgameconfilename[GAME_NAPALM]; // NAM/NAPALM Sharing
2726 hendricks2 117
        }
118
        else
119
            return defaultgameconfilename[GAME_NAM];
120
    }
121
 
122
    return defaultconfilename;
123
}
124
 
2796 helixhorne 125
const char *G_GrpFile(void)
2726 hendricks2 126
{
127
    if (g_grpNamePtr == NULL)
128
        return G_DefaultGrpFile();
129
    else
130
        return g_grpNamePtr;
131
}
3654 terminx 132
 
2796 helixhorne 133
const char *G_DefFile(void)
2726 hendricks2 134
{
135
    if (g_defNamePtr == NULL)
136
        return G_DefaultDefFile();
137
    else
138
        return g_defNamePtr;
139
}
3654 terminx 140
 
2796 helixhorne 141
const char *G_ConFile(void)
2726 hendricks2 142
{
143
    if (g_scriptNamePtr == NULL)
144
        return G_DefaultConFile();
145
    else
146
        return g_scriptNamePtr;
147
}
148
 
149
//////////
150
 
3976 helixhorne 151
#define NUMPSKYMULTIS 5
152
EDUKE32_STATIC_ASSERT(NUMPSKYMULTIS <= MAXPSKYMULTIS);
153
EDUKE32_STATIC_ASSERT(PSKYOFF_MAX <= MAXPSKYTILES);
154
 
3975 helixhorne 155
// Set up new-style multi-psky handling.
3976 helixhorne 156
void G_InitMultiPsky(int32_t CLOUDYOCEAN__DYN, int32_t MOONSKY1__DYN, int32_t BIGORBIT1__DYN, int32_t LA__DYN)
3220 hendricks2 157
{
158
    int32_t i;
159
 
3976 helixhorne 160
    psky_t *defaultsky = &multipsky[0];
161
    psky_t *oceansky = &multipsky[1];
162
    psky_t *moonsky = &multipsky[2];
163
    psky_t *spacesky = &multipsky[3];
164
    psky_t *citysky = &multipsky[4];
3220 hendricks2 165
 
3975 helixhorne 166
    static int32_t inited;
167
    if (inited)
168
        return;
169
    inited = 1;
3220 hendricks2 170
 
3976 helixhorne 171
    multipskytile[0] = -1;
172
    multipskytile[1] = CLOUDYOCEAN__DYN;
173
    multipskytile[2] = MOONSKY1__DYN;
174
    multipskytile[3] = BIGORBIT1__DYN;
175
    multipskytile[4] = LA__DYN;
3220 hendricks2 176
 
3976 helixhorne 177
    pskynummultis = NUMPSKYMULTIS;
3220 hendricks2 178
 
3975 helixhorne 179
    // When adding other multi-skies, take care that the tileofs[] values are
180
    // <= PSKYOFF_MAX. (It can be increased up to MAXPSKYTILES, but should be
181
    // set as tight as possible.)
182
 
3976 helixhorne 183
    // The default sky properties (all others are implicitly zero):
184
    defaultsky->lognumtiles = 3;
185
    defaultsky->horizfrac = 32768;
186
 
187
    // CLOUDYOCEAN
188
    // Aligns with the drawn scene horizon because it has one itself.
189
    oceansky->lognumtiles = 3;
190
    oceansky->horizfrac = 65536;
191
 
3220 hendricks2 192
    // MOONSKY1
193
    //        earth          mountain   mountain         sun
3975 helixhorne 194
    moonsky->lognumtiles = 3;
195
    moonsky->horizfrac = 32768;
196
    moonsky->tileofs[6] = 1;
197
    moonsky->tileofs[1] = 2;
198
    moonsky->tileofs[4] = 2;
199
    moonsky->tileofs[2] = 3;
3220 hendricks2 200
 
201
    // BIGORBIT1   // orbit
202
    //       earth1         2           3           moon/sun
3975 helixhorne 203
    spacesky->lognumtiles = 3;
204
    spacesky->horizfrac = 32768;
205
    spacesky->tileofs[5] = 1;
206
    spacesky->tileofs[6] = 2;
207
    spacesky->tileofs[7] = 3;
208
    spacesky->tileofs[2] = 4;
3220 hendricks2 209
 
210
    // LA // la city
211
    //       earth1         2           3           moon/sun
3975 helixhorne 212
    citysky->lognumtiles = 3;
213
    citysky->horizfrac = 16384+1024;
214
    citysky->tileofs[0] = 1;
215
    citysky->tileofs[1] = 2;
216
    citysky->tileofs[2] = 1;
217
    citysky->tileofs[3] = 3;
218
    citysky->tileofs[4] = 4;
219
    citysky->tileofs[5] = 0;
220
    citysky->tileofs[6] = 2;
221
    citysky->tileofs[7] = 3;
3220 hendricks2 222
 
3975 helixhorne 223
    for (i=0; i<pskynummultis; ++i)
224
    {
225
        int32_t j;
226
        for (j=0; j<(1<<multipsky[i].lognumtiles); ++j)
227
            Bassert(multipsky[i].tileofs[j] <= PSKYOFF_MAX);
228
    }
3976 helixhorne 229
}
3220 hendricks2 230
 
3976 helixhorne 231
void G_SetupGlobalPsky(void)
232
{
233
    int32_t i, mskyidx=0;
234
 
235
    // NOTE: Loop must be running backwards for the same behavior as the game
236
    // (greatest sector index with matching parallaxed sky takes precedence).
237
    for (i=numsectors-1; i>=0; i--)
238
    {
239
        if (sector[i].ceilingstat & 1)
240
        {
4006 helixhorne 241
            mskyidx = getpskyidx(sector[i].ceilingpicnum);
3976 helixhorne 242
            if (mskyidx > 0)
243
                break;
244
        }
245
    }
246
 
247
    g_pskyidx = mskyidx;
3220 hendricks2 248
}
249
 
250
//////////
251
 
4557 hendricks2 252
static char g_rootDir[BMAX_PATH];
253
char g_modDir[BMAX_PATH] = "/";
254
 
255
int32_t kopen4loadfrommod(const char *filename, char searchfirst)
256
{
257
    int32_t r=-1;
258
 
259
    if (g_modDir[0]!='/' || g_modDir[1]!=0)
260
    {
261
        static char fn[BMAX_PATH];
262
 
263
        Bsnprintf(fn, sizeof(fn), "%s/%s",g_modDir,filename);
264
        r = kopen4load(fn,searchfirst);
265
    }
266
 
267
    if (r < 0)
268
        r = kopen4load(filename,searchfirst);
269
 
270
    return r;
271
}
272
 
273
int32_t usecwd;
274
static void G_LoadAddon(void);
275
int32_t g_groupFileHandle;
276
 
277
void G_ExtPreInit(int32_t argc,const char **argv)
278
{
279
    usecwd = G_CheckCmdSwitch(argc, argv, "-usecwd");
280
 
281
#ifdef _WIN32
282
    GetModuleFileName(NULL,g_rootDir,BMAX_PATH);
283
    Bcorrectfilename(g_rootDir,1);
284
    //chdir(g_rootDir);
285
#else
286
    getcwd(g_rootDir,BMAX_PATH);
287
    strcat(g_rootDir,"/");
3582 hendricks2 288
#endif
4557 hendricks2 289
}
3582 hendricks2 290
 
4557 hendricks2 291
void G_ExtInit(void)
3582 hendricks2 292
{
4557 hendricks2 293
    char cwd[BMAX_PATH];
294
 
295
    if (getcwd(cwd,BMAX_PATH))
296
    {
297
#if defined(__APPLE__)
298
        /* Dirty hack on OS X to also look for gamedata inside the application bundle - rhoenie 08/08 */
299
        char seekinappcontainer[BMAX_PATH];
300
        Bsnprintf(seekinappcontainer,sizeof(seekinappcontainer),"%s/EDuke32.app/", cwd);
301
        addsearchpath(seekinappcontainer);
3582 hendricks2 302
#endif
4557 hendricks2 303
        addsearchpath(cwd);
304
    }
305
 
306
    if (CommandPaths)
307
    {
308
        int32_t i;
309
        struct strllist *s;
310
        while (CommandPaths)
311
        {
312
            s = CommandPaths->next;
313
            i = addsearchpath(CommandPaths->str);
314
            if (i < 0)
315
            {
316
                initprintf("Failed adding %s for game data: %s\n", CommandPaths->str,
317
                           i==-1 ? "not a directory" : "no such directory");
318
            }
319
 
320
            Bfree(CommandPaths->str);
321
            Bfree(CommandPaths);
322
            CommandPaths = s;
323
        }
324
    }
325
 
326
#if defined(_WIN32)
327
    if (!access("user_profiles_enabled", F_OK))
328
#else
329
    if (usecwd == 0 && access("user_profiles_disabled", F_OK))
330
#endif
331
    {
332
        char *homedir;
333
        int32_t asperr;
334
 
335
        if ((homedir = Bgethomedir()))
336
        {
337
            Bsnprintf(cwd,sizeof(cwd),"%s/"
338
#if defined(_WIN32)
339
                      "EDuke32 Settings"
340
#elif defined(__APPLE__)
341
                      "Library/Application Support/EDuke32"
342
#elif defined(GEKKO)
343
                      "apps/eduke32"
344
#else
345
                      ".eduke32"
346
#endif
347
                      ,homedir);
348
            asperr = addsearchpath(cwd);
349
            if (asperr == -2)
350
            {
351
                if (Bmkdir(cwd,S_IRWXU) == 0) asperr = addsearchpath(cwd);
352
                else asperr = -1;
353
            }
354
            if (asperr == 0)
4697 terminx 355
                Bchdir(cwd);
4557 hendricks2 356
            Bfree(homedir);
357
        }
358
    }
359
 
360
    // JBF 20031220: Because it's annoying renaming GRP files whenever I want to test different game data
361
    if (g_grpNamePtr == NULL)
362
    {
363
        const char *cp = getenv("DUKE3DGRP");
364
        if (cp)
365
        {
366
            clearGrpNamePtr();
367
            g_grpNamePtr = dup_filename(cp);
368
            initprintf("Using \"%s\" as main GRP file\n", g_grpNamePtr);
369
        }
370
    }
3582 hendricks2 371
}
372
 
4557 hendricks2 373
void G_ExtPreStartupWindow(void)
374
{
375
    ScanGroups();
376
    {
377
        // try and identify the 'defaultgamegrp' in the set of GRPs.
378
        // if it is found, set up the environment accordingly for the game it represents.
379
        // if it is not found, choose the first GRP from the list
380
        struct grpfile *fg, *first = NULL;
381
 
382
        for (fg = foundgrps; fg; fg=fg->next)
383
        {
384
            struct grpfile *grp;
385
            for (grp = listgrps; grp; grp=grp->next)
386
                if (fg->crcval == grp->crcval) break;
387
 
388
            if (grp == NULL)
389
                continue;
390
 
391
            fg->game = grp->game;
392
            if (!first) first = fg;
393
            if (!Bstrcasecmp(fg->name, G_DefaultGrpFile()))
394
            {
395
                g_gameType = grp->game;
396
                g_gameNamePtr = grp->name;
397
                break;
398
            }
399
        }
400
        if (!fg && first)
401
        {
402
            if (g_grpNamePtr == NULL)
403
            {
404
                clearGrpNamePtr();
405
                g_grpNamePtr = dup_filename(first->name);
406
            }
407
            g_gameType = first->game;
408
            g_gameNamePtr = listgrps->name;
409
        }
410
        else if (!fg) g_gameNamePtr = NULL;
411
    }
412
}
413
 
414
void G_ExtPostStartupWindow(int32_t autoload)
415
{
416
    if (g_modDir[0] != '/')
417
    {
418
        char cwd[BMAX_PATH];
419
 
420
        Bstrcat(g_rootDir,g_modDir);
421
        addsearchpath(g_rootDir);
422
//        addsearchpath(mod_dir);
423
 
424
        if (getcwd(cwd,BMAX_PATH))
425
        {
426
            Bsprintf(cwd,"%s/%s",cwd,g_modDir);
427
            if (!Bstrcmp(g_rootDir, cwd))
428
            {
429
                if (addsearchpath(cwd) == -2)
430
                    if (Bmkdir(cwd,S_IRWXU) == 0) addsearchpath(cwd);
431
            }
432
        }
433
 
434
#ifdef USE_OPENGL
435
        Bsprintf(cwd,"%s/%s",g_modDir,TEXCACHEFILE);
436
        Bstrcpy(TEXCACHEFILE,cwd);
437
#endif
438
    }
439
 
440
    if (g_usingAddon)
441
        G_LoadAddon();
442
 
443
    {
444
        int32_t i;
445
        const char *grpfile = G_GrpFile();
446
 
447
        if (g_dependencyCRC)
448
        {
449
            struct grpfile * grp = FindGroup(g_dependencyCRC);
450
            if (grp)
451
            {
452
                if ((i = initgroupfile(grp->name)) == -1)
453
                    initprintf("Warning: could not find main data file \"%s\"!\n",grp->name);
454
                else
455
                    initprintf("Using \"%s\" as main game data file.\n", grp->name);
456
            }
457
        }
458
 
459
        if ((i = initgroupfile(grpfile)) == -1)
460
            initprintf("Warning: could not find main data file \"%s\"!\n",grpfile);
461
        else
462
            initprintf("Using \"%s\" as main game data file.\n", grpfile);
463
 
464
        if (autoload)
465
        {
466
            G_LoadGroupsInDir("autoload");
467
 
468
            if (i != -1)
469
                G_DoAutoload(grpfile);
470
        }
471
    }
472
 
473
    if (g_modDir[0] != '/')
474
        G_LoadGroupsInDir(g_modDir);
475
 
476
    if (g_defNamePtr == NULL)
477
    {
478
        const char *tmpptr = getenv("DUKE3DDEF");
479
        if (tmpptr)
480
        {
481
            clearDefNamePtr();
482
            g_defNamePtr = dup_filename(tmpptr);
483
            initprintf("Using \"%s\" as definitions file\n", g_defNamePtr);
484
        }
485
    }
486
 
487
    loaddefinitions_game(G_DefFile(), TRUE);
488
 
489
    {
490
        struct strllist *s;
491
 
492
        pathsearchmode = 1;
493
        while (CommandGrps)
494
        {
495
            int32_t j;
496
 
497
            s = CommandGrps->next;
498
 
499
            if ((j = initgroupfile(CommandGrps->str)) == -1)
500
                initprintf("Could not find file \"%s\".\n",CommandGrps->str);
501
            else
502
            {
503
                g_groupFileHandle = j;
504
                initprintf("Using file \"%s\" as game data.\n",CommandGrps->str);
505
                if (autoload)
506
                    G_DoAutoload(CommandGrps->str);
507
            }
508
 
509
            Bfree(CommandGrps->str);
510
            Bfree(CommandGrps);
511
            CommandGrps = s;
512
        }
513
        pathsearchmode = 0;
514
    }
515
}
516
 
3622 terminx 517
#ifdef _WIN32
3637 terminx 518
const char * G_GetInstallPath(int32_t insttype)
3622 terminx 519
{
3637 terminx 520
    static char spath[NUMINSTPATHS][BMAX_PATH];
4790 hendricks2 521
    static int32_t success[NUMINSTPATHS] = { -1, -1, -1, -1, -1 };
3622 terminx 522
    int32_t siz = BMAX_PATH;
523
 
3637 terminx 524
    if (success[insttype] == -1)
525
    {
3671 hendricks2 526
        HKEY HKLM32;
527
        LONG keygood = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ | KEY_WOW64_32KEY, &HKLM32);
528
        // KEY_WOW64_32KEY gets us around Wow6432Node on 64-bit builds
529
 
530
        if (keygood == ERROR_SUCCESS)
4127 hendricks2 531
        {
3671 hendricks2 532
            switch (insttype)
533
            {
4790 hendricks2 534
            case INSTPATH_STEAM_DUKE3D:
3671 hendricks2 535
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 225140", "InstallLocation", NULL, spath[insttype], (LPDWORD)&siz);
536
                break;
4790 hendricks2 537
            case INSTPATH_GOG_DUKE3D:
3671 hendricks2 538
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", NULL, spath[insttype], (LPDWORD)&siz);
539
                break;
4790 hendricks2 540
            case INSTPATH_3DR_DUKE3D:
541
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\3DRealms\\Duke Nukem 3D", NULL, NULL, spath[insttype], (LPDWORD)&siz);
542
                break;
543
            case INSTPATH_3DR_ANTH:
544
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\3DRealms\\Anthology", NULL, NULL, spath[insttype], (LPDWORD)&siz);
545
                break;
546
            case INSTPATH_STEAM_NAM:
547
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 329650", "InstallLocation", NULL, spath[insttype], (LPDWORD)&siz);
548
                break;
3671 hendricks2 549
            }
4127 hendricks2 550
 
551
            RegCloseKey(HKLM32);
552
        }
3637 terminx 553
    }
3622 terminx 554
 
3637 terminx 555
    if (success[insttype] == ERROR_SUCCESS)
556
        return spath[insttype];
3622 terminx 557
 
558
    return NULL;
559
}
560
#endif
561
 
4557 hendricks2 562
static void G_LoadAddon(void)
563
{
564
    struct grpfile * grp;
565
    int32_t crc = 0;  // compiler-happy
566
 
567
    switch (g_usingAddon)
568
    {
569
    case ADDON_DUKEDC:
570
        crc = DUKEDC_CRC;
571
        break;
572
    case ADDON_NWINTER:
573
        crc = DUKENW_CRC;
574
        break;
575
    case ADDON_CARIBBEAN:
576
        crc = DUKECB_CRC;
577
        break;
578
    }
579
 
580
    if (!crc) return;
581
 
582
    grp = FindGroup(crc);
583
 
584
    if (grp && FindGroup(DUKE15_CRC))
585
    {
586
        clearGrpNamePtr();
587
        g_grpNamePtr = dup_filename(FindGroup(DUKE15_CRC)->name);
588
 
589
        G_AddGroup(grp->name);
590
 
591
        for (grp = listgrps; grp; grp=grp->next)
592
            if (crc == grp->crcval) break;
593
 
594
        if (grp != NULL && grp->scriptname)
595
        {
596
            clearScriptNamePtr();
597
            g_scriptNamePtr = dup_filename(grp->scriptname);
598
        }
599
 
600
        if (grp != NULL && grp->defname)
601
        {
602
            clearDefNamePtr();
603
            g_defNamePtr = dup_filename(grp->defname);
604
        }
605
    }
606
}
607
 
3581 hendricks2 608
void G_AddSearchPaths(void)
609
{
610
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
611
    addsearchpath("/usr/share/games/jfduke3d");
612
    addsearchpath("/usr/local/share/games/jfduke3d");
613
    addsearchpath("/usr/share/games/eduke32");
614
    addsearchpath("/usr/local/share/games/eduke32");
615
#elif defined(__APPLE__)
616
    addsearchpath("/Library/Application Support/JFDuke3D");
617
    addsearchpath("/Library/Application Support/EDuke32");
618
#elif defined (_WIN32)
3615 terminx 619
    // detect Steam and GOG versions of Duke3D
620
    char buf[BMAX_PATH];
3671 hendricks2 621
    const char* instpath;
3615 terminx 622
 
4790 hendricks2 623
    if ((instpath = G_GetInstallPath(INSTPATH_STEAM_DUKE3D)))
3622 terminx 624
    {
4557 hendricks2 625
        Bsnprintf(buf, sizeof(buf), "%s/gameroot", instpath);
3622 terminx 626
        addsearchpath(buf);
3615 terminx 627
 
4594 hendricks2 628
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/dc", instpath);
3622 terminx 629
        addsearchpath(buf);
4594 hendricks2 630
 
631
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/nw", instpath);
632
        addsearchpath(buf);
633
 
634
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/vacation", instpath);
635
        addsearchpath(buf);
3615 terminx 636
    }
637
 
4790 hendricks2 638
    if ((instpath = G_GetInstallPath(INSTPATH_GOG_DUKE3D)))
3671 hendricks2 639
        addsearchpath(instpath);
4790 hendricks2 640
 
641
    if ((instpath = G_GetInstallPath(INSTPATH_3DR_DUKE3D)))
642
    {
643
        Bsnprintf(buf, sizeof(buf), "%s/Duke Nukem 3D", instpath);
644
        addsearchpath(buf);
645
    }
646
 
647
    if ((instpath = G_GetInstallPath(INSTPATH_3DR_ANTH)))
648
    {
649
        Bsnprintf(buf, sizeof(buf), "%s/Duke Nukem 3D", instpath);
650
        addsearchpath(buf);
651
    }
652
 
653
    if ((instpath = G_GetInstallPath(INSTPATH_STEAM_NAM)))
654
    {
655
        Bsnprintf(buf, sizeof(buf), "%s/NAM", instpath);
656
        addsearchpath(buf);
657
    }
3581 hendricks2 658
#endif
659
}
660
 
3654 terminx 661
void G_CleanupSearchPaths(void)
662
{
663
#ifdef _WIN32
664
    char buf[BMAX_PATH];
3671 hendricks2 665
    const char* instpath;
3654 terminx 666
 
4790 hendricks2 667
    if ((instpath = G_GetInstallPath(INSTPATH_STEAM_DUKE3D)))
3654 terminx 668
    {
4557 hendricks2 669
        Bsnprintf(buf, sizeof(buf), "%s/gameroot", instpath);
3654 terminx 670
        removesearchpath(buf);
671
 
4594 hendricks2 672
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/dc", instpath);
3654 terminx 673
        removesearchpath(buf);
4594 hendricks2 674
 
675
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/nw", instpath);
676
        removesearchpath(buf);
677
 
678
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/vacation", instpath);
679
        removesearchpath(buf);
3654 terminx 680
    }
681
 
4790 hendricks2 682
    if ((instpath = G_GetInstallPath(INSTPATH_GOG_DUKE3D)))
3671 hendricks2 683
        removesearchpath(instpath);
4790 hendricks2 684
 
685
    if ((instpath = G_GetInstallPath(INSTPATH_3DR_DUKE3D)))
686
    {
687
        Bsnprintf(buf, sizeof(buf), "%s/Duke Nukem 3D", instpath);
688
        removesearchpath(buf);
689
    }
690
 
691
    if ((instpath = G_GetInstallPath(INSTPATH_3DR_ANTH)))
692
    {
693
        Bsnprintf(buf, sizeof(buf), "%s/Duke Nukem 3D", instpath);
694
        removesearchpath(buf);
695
    }
696
 
697
    if (g_gameType != GAMEFLAG_NAM && (instpath = G_GetInstallPath(INSTPATH_STEAM_NAM)))
698
    {
699
        Bsnprintf(buf, sizeof(buf), "%s/NAM", instpath);
700
        removesearchpath(buf);
701
    }
3654 terminx 702
#endif
703
}
704
 
3581 hendricks2 705
//////////
706
 
2542 helixhorne 707
struct strllist *CommandPaths, *CommandGrps;
708
 
4128 hendricks2 709
char **g_scriptModules = NULL;
710
int32_t g_scriptModulesNum = 0;
711
 
2542 helixhorne 712
void G_AddGroup(const char *buffer)
713
{
714
    char buf[BMAX_PATH];
715
 
4491 helixhorne 716
    struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
2542 helixhorne 717
 
718
    Bstrcpy(buf, buffer);
719
 
720
    if (Bstrchr(buf,'.') == 0)
721
        Bstrcat(buf,".grp");
722
 
4491 helixhorne 723
    s->str = Xstrdup(buf);
2542 helixhorne 724
 
725
    if (CommandGrps)
726
    {
727
        struct strllist *t;
728
        for (t = CommandGrps; t->next; t=t->next) ;
729
        t->next = s;
730
        return;
731
    }
732
    CommandGrps = s;
733
}
734
 
735
void G_AddPath(const char *buffer)
736
{
4491 helixhorne 737
    struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
738
    s->str = Xstrdup(buffer);
2542 helixhorne 739
 
740
    if (CommandPaths)
741
    {
742
        struct strllist *t;
743
        for (t = CommandPaths; t->next; t=t->next) ;
744
        t->next = s;
745
        return;
746
    }
747
    CommandPaths = s;
748
}
2549 helixhorne 749
 
4128 hendricks2 750
void G_AddCon(const char *buffer)
751
{
752
    clearScriptNamePtr();
753
    g_scriptNamePtr = dup_filename(buffer);
754
    initprintf("Using CON file \"%s\".\n",g_scriptNamePtr);
755
}
756
 
757
void G_AddConModule(const char *buffer)
758
{
4491 helixhorne 759
    g_scriptModules = (char **) Xrealloc (g_scriptModules, (g_scriptModulesNum+1) * sizeof(char *));
760
    g_scriptModules[g_scriptModulesNum] = Xstrdup(buffer);
4128 hendricks2 761
    ++g_scriptModulesNum;
762
}
763
 
2549 helixhorne 764
//////////
765
 
3269 terminx 766
// loads all group (grp, zip, pk3/4) files in the given directory
2555 helixhorne 767
void G_LoadGroupsInDir(const char *dirname)
768
{
3269 terminx 769
    static const char *extensions[4] = { "*.grp", "*.zip", "*.pk3", "*.pk4" };
2555 helixhorne 770
 
771
    char buf[BMAX_PATH];
772
    int32_t i;
773
 
774
    fnlist_t fnlist = FNLIST_INITIALIZER;
775
 
3269 terminx 776
    for (i=0; i<4; i++)
2555 helixhorne 777
    {
778
        CACHE1D_FIND_REC *rec;
779
 
780
        fnlist_getnames(&fnlist, dirname, extensions[i], -1, 0);
781
 
782
        for (rec=fnlist.findfiles; rec; rec=rec->next)
783
        {
784
            Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name);
785
            initprintf("Using group file \"%s\".\n", buf);
786
            initgroupfile(buf);
787
        }
788
 
789
        fnlist_clearnames(&fnlist);
790
    }
791
}
792
 
793
void G_DoAutoload(const char *dirname)
794
{
795
    char buf[BMAX_PATH];
796
 
797
    Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname);
798
    G_LoadGroupsInDir(buf);
799
}
4564 hendricks2 800
 
801
//////////
802
 
803
static uint8_t water_pal[768], slime_pal[768], title_pal[768], dre_alms[768], ending_pal[768];
804
 
805
uint8_t *basepaltable[BASEPALCOUNT] = {
806
    palette, water_pal, slime_pal,
807
    dre_alms, title_pal, ending_pal,
808
    NULL /*anim_pal*/
809
};
810
 
811
int32_t g_firstFogPal;
812
 
813
int32_t G_LoadLookups(void)
814
{
815
    int32_t fp, j;
816
 
817
    if ((fp=kopen4loadfrommod("lookup.dat",0)) == -1)
818
    {
819
        if ((fp=kopen4loadfrommod("lookup.dat",1)) == -1)
820
        {
821
            initprintf("ERROR: File \"lookup.dat\" not found.\n");
822
            return 1;
823
        }
824
    }
825
 
826
    j = loadlookups(fp);
827
 
828
    if (j < 0)
829
    {
830
        if (j == -1)
831
            initprintf("ERROR loading \"lookup.dat\": failed reading enough data.\n");
832
        return 1;
833
    }
834
 
835
    for (j=1; j<=5; j++)
836
    {
837
        // Account for TITLE and REALMS swap between basepal number and on-disk order.
838
        // XXX: this reordering is better off as an argument to us.
839
        int32_t basepalnum = (j == 3 || j == 4) ? 4+3-j : j;
840
 
841
        if (kread(fp, basepaltable[basepalnum], 768) != 768)
842
            return -1;
843
    }
844
 
845
    kclose(fp);
846
 
847
    g_firstFogPal = generatefogpals();
848
 
849
    fillemptylookups();
850
 
851
    return 0;
852
}