Subversion Repositories eduke32

Rev

Rev 4697 | Rev 4790 | 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];
521
    static int32_t success[NUMINSTPATHS] = { -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
            {
534
            case INSTPATH_STEAM:
535
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 225140", "InstallLocation", NULL, spath[insttype], (LPDWORD)&siz);
536
                break;
537
            case INSTPATH_GOG:
538
                success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", NULL, spath[insttype], (LPDWORD)&siz);
539
                break;
540
            }
4127 hendricks2 541
 
542
            RegCloseKey(HKLM32);
543
        }
3637 terminx 544
    }
3622 terminx 545
 
3637 terminx 546
    if (success[insttype] == ERROR_SUCCESS)
547
        return spath[insttype];
3622 terminx 548
 
549
    return NULL;
550
}
551
#endif
552
 
4557 hendricks2 553
static void G_LoadAddon(void)
554
{
555
    struct grpfile * grp;
556
    int32_t crc = 0;  // compiler-happy
557
 
558
    switch (g_usingAddon)
559
    {
560
    case ADDON_DUKEDC:
561
        crc = DUKEDC_CRC;
562
        break;
563
    case ADDON_NWINTER:
564
        crc = DUKENW_CRC;
565
        break;
566
    case ADDON_CARIBBEAN:
567
        crc = DUKECB_CRC;
568
        break;
569
    }
570
 
571
    if (!crc) return;
572
 
573
    grp = FindGroup(crc);
574
 
575
    if (grp && FindGroup(DUKE15_CRC))
576
    {
577
        clearGrpNamePtr();
578
        g_grpNamePtr = dup_filename(FindGroup(DUKE15_CRC)->name);
579
 
580
        G_AddGroup(grp->name);
581
 
582
        for (grp = listgrps; grp; grp=grp->next)
583
            if (crc == grp->crcval) break;
584
 
585
        if (grp != NULL && grp->scriptname)
586
        {
587
            clearScriptNamePtr();
588
            g_scriptNamePtr = dup_filename(grp->scriptname);
589
        }
590
 
591
        if (grp != NULL && grp->defname)
592
        {
593
            clearDefNamePtr();
594
            g_defNamePtr = dup_filename(grp->defname);
595
        }
596
    }
597
}
598
 
3581 hendricks2 599
void G_AddSearchPaths(void)
600
{
601
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
602
    addsearchpath("/usr/share/games/jfduke3d");
603
    addsearchpath("/usr/local/share/games/jfduke3d");
604
    addsearchpath("/usr/share/games/eduke32");
605
    addsearchpath("/usr/local/share/games/eduke32");
606
#elif defined(__APPLE__)
607
    addsearchpath("/Library/Application Support/JFDuke3D");
608
    addsearchpath("/Library/Application Support/EDuke32");
609
#elif defined (_WIN32)
3615 terminx 610
    // detect Steam and GOG versions of Duke3D
611
    char buf[BMAX_PATH];
3671 hendricks2 612
    const char* instpath;
3615 terminx 613
 
3671 hendricks2 614
    if ((instpath = G_GetInstallPath(INSTPATH_STEAM)))
3622 terminx 615
    {
4557 hendricks2 616
        Bsnprintf(buf, sizeof(buf), "%s/gameroot", instpath);
3622 terminx 617
        addsearchpath(buf);
3615 terminx 618
 
4594 hendricks2 619
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/dc", instpath);
3622 terminx 620
        addsearchpath(buf);
4594 hendricks2 621
 
622
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/nw", instpath);
623
        addsearchpath(buf);
624
 
625
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/vacation", instpath);
626
        addsearchpath(buf);
3615 terminx 627
    }
628
 
3671 hendricks2 629
    if ((instpath = G_GetInstallPath(INSTPATH_GOG)))
630
        addsearchpath(instpath);
3581 hendricks2 631
#endif
632
}
633
 
3654 terminx 634
void G_CleanupSearchPaths(void)
635
{
636
#ifdef _WIN32
637
    char buf[BMAX_PATH];
3671 hendricks2 638
    const char* instpath;
3654 terminx 639
 
3671 hendricks2 640
    if ((instpath = G_GetInstallPath(INSTPATH_STEAM)))
3654 terminx 641
    {
4557 hendricks2 642
        Bsnprintf(buf, sizeof(buf), "%s/gameroot", instpath);
3654 terminx 643
        removesearchpath(buf);
644
 
4594 hendricks2 645
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/dc", instpath);
3654 terminx 646
        removesearchpath(buf);
4594 hendricks2 647
 
648
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/nw", instpath);
649
        removesearchpath(buf);
650
 
651
        Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons/vacation", instpath);
652
        removesearchpath(buf);
3654 terminx 653
    }
654
 
3671 hendricks2 655
    if ((instpath = G_GetInstallPath(INSTPATH_GOG)))
656
        removesearchpath(instpath);
3654 terminx 657
#endif
658
}
659
 
3581 hendricks2 660
//////////
661
 
2542 helixhorne 662
struct strllist *CommandPaths, *CommandGrps;
663
 
4128 hendricks2 664
char **g_scriptModules = NULL;
665
int32_t g_scriptModulesNum = 0;
666
 
2542 helixhorne 667
void G_AddGroup(const char *buffer)
668
{
669
    char buf[BMAX_PATH];
670
 
4491 helixhorne 671
    struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
2542 helixhorne 672
 
673
    Bstrcpy(buf, buffer);
674
 
675
    if (Bstrchr(buf,'.') == 0)
676
        Bstrcat(buf,".grp");
677
 
4491 helixhorne 678
    s->str = Xstrdup(buf);
2542 helixhorne 679
 
680
    if (CommandGrps)
681
    {
682
        struct strllist *t;
683
        for (t = CommandGrps; t->next; t=t->next) ;
684
        t->next = s;
685
        return;
686
    }
687
    CommandGrps = s;
688
}
689
 
690
void G_AddPath(const char *buffer)
691
{
4491 helixhorne 692
    struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
693
    s->str = Xstrdup(buffer);
2542 helixhorne 694
 
695
    if (CommandPaths)
696
    {
697
        struct strllist *t;
698
        for (t = CommandPaths; t->next; t=t->next) ;
699
        t->next = s;
700
        return;
701
    }
702
    CommandPaths = s;
703
}
2549 helixhorne 704
 
4128 hendricks2 705
void G_AddCon(const char *buffer)
706
{
707
    clearScriptNamePtr();
708
    g_scriptNamePtr = dup_filename(buffer);
709
    initprintf("Using CON file \"%s\".\n",g_scriptNamePtr);
710
}
711
 
712
void G_AddConModule(const char *buffer)
713
{
4491 helixhorne 714
    g_scriptModules = (char **) Xrealloc (g_scriptModules, (g_scriptModulesNum+1) * sizeof(char *));
715
    g_scriptModules[g_scriptModulesNum] = Xstrdup(buffer);
4128 hendricks2 716
    ++g_scriptModulesNum;
717
}
718
 
2549 helixhorne 719
//////////
720
 
3269 terminx 721
// loads all group (grp, zip, pk3/4) files in the given directory
2555 helixhorne 722
void G_LoadGroupsInDir(const char *dirname)
723
{
3269 terminx 724
    static const char *extensions[4] = { "*.grp", "*.zip", "*.pk3", "*.pk4" };
2555 helixhorne 725
 
726
    char buf[BMAX_PATH];
727
    int32_t i;
728
 
729
    fnlist_t fnlist = FNLIST_INITIALIZER;
730
 
3269 terminx 731
    for (i=0; i<4; i++)
2555 helixhorne 732
    {
733
        CACHE1D_FIND_REC *rec;
734
 
735
        fnlist_getnames(&fnlist, dirname, extensions[i], -1, 0);
736
 
737
        for (rec=fnlist.findfiles; rec; rec=rec->next)
738
        {
739
            Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name);
740
            initprintf("Using group file \"%s\".\n", buf);
741
            initgroupfile(buf);
742
        }
743
 
744
        fnlist_clearnames(&fnlist);
745
    }
746
}
747
 
748
void G_DoAutoload(const char *dirname)
749
{
750
    char buf[BMAX_PATH];
751
 
752
    Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname);
753
    G_LoadGroupsInDir(buf);
754
}
4564 hendricks2 755
 
756
//////////
757
 
758
static uint8_t water_pal[768], slime_pal[768], title_pal[768], dre_alms[768], ending_pal[768];
759
 
760
uint8_t *basepaltable[BASEPALCOUNT] = {
761
    palette, water_pal, slime_pal,
762
    dre_alms, title_pal, ending_pal,
763
    NULL /*anim_pal*/
764
};
765
 
766
int32_t g_firstFogPal;
767
 
768
int32_t G_LoadLookups(void)
769
{
770
    int32_t fp, j;
771
 
772
    if ((fp=kopen4loadfrommod("lookup.dat",0)) == -1)
773
    {
774
        if ((fp=kopen4loadfrommod("lookup.dat",1)) == -1)
775
        {
776
            initprintf("ERROR: File \"lookup.dat\" not found.\n");
777
            return 1;
778
        }
779
    }
780
 
781
    j = loadlookups(fp);
782
 
783
    if (j < 0)
784
    {
785
        if (j == -1)
786
            initprintf("ERROR loading \"lookup.dat\": failed reading enough data.\n");
787
        return 1;
788
    }
789
 
790
    for (j=1; j<=5; j++)
791
    {
792
        // Account for TITLE and REALMS swap between basepal number and on-disk order.
793
        // XXX: this reordering is better off as an argument to us.
794
        int32_t basepalnum = (j == 3 || j == 4) ? 4+3-j : j;
795
 
796
        if (kread(fp, basepaltable[basepalnum], 768) != 768)
797
            return -1;
798
    }
799
 
800
    kclose(fp);
801
 
802
    g_firstFogPal = generatefogpals();
803
 
804
    fillemptylookups();
805
 
806
    return 0;
807
}