2012-03-26 22:03:20 +00:00
|
|
|
//
|
|
|
|
// Common non-engine code/data for EDuke32 and Mapster32
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "compat.h"
|
2012-06-03 16:09:33 +00:00
|
|
|
#include "build.h"
|
2012-03-26 22:05:23 +00:00
|
|
|
#include "scriptfile.h"
|
2012-03-28 19:41:39 +00:00
|
|
|
#include "cache1d.h"
|
|
|
|
#include "kplib.h"
|
|
|
|
#include "baselayer.h"
|
2012-11-25 04:25:31 +00:00
|
|
|
#include "names.h"
|
2014-07-28 06:42:28 +00:00
|
|
|
#include "grpscan.h"
|
2012-03-26 22:03:20 +00:00
|
|
|
|
2013-03-21 09:48:21 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
# include "winbits.h"
|
2013-04-13 03:50:37 +00:00
|
|
|
# include <shlwapi.h>
|
|
|
|
# include <winnt.h>
|
|
|
|
# ifndef KEY_WOW64_32KEY
|
|
|
|
# define KEY_WOW64_32KEY 0x0200
|
|
|
|
# endif
|
2013-03-21 09:48:21 +00:00
|
|
|
#endif
|
|
|
|
|
2012-03-26 22:03:20 +00:00
|
|
|
#include "common.h"
|
2012-06-03 16:09:33 +00:00
|
|
|
#include "common_game.h"
|
2012-03-26 22:03:20 +00:00
|
|
|
|
2014-05-31 12:26:13 +00:00
|
|
|
const char* s_buildInfo =
|
|
|
|
#ifdef BITNESS64
|
|
|
|
"(64-bit)"
|
|
|
|
#else
|
|
|
|
"(32-bit)"
|
|
|
|
#endif
|
|
|
|
#if defined (_MSC_VER) || defined(__cplusplus)
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
" MSVC"
|
|
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
|
|
" C++"
|
|
|
|
#endif
|
|
|
|
" build"
|
|
|
|
#endif
|
|
|
|
;
|
|
|
|
|
2012-06-27 17:45:52 +00:00
|
|
|
int32_t g_gameType = GAMEFLAG_DUKE;
|
2012-06-03 16:09:33 +00:00
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
int32_t g_dependencyCRC = 0;
|
|
|
|
int32_t g_usingAddon = 0;
|
|
|
|
|
|
|
|
// g_gameNamePtr can point to one of: grpfiles[].name (string literal), string
|
|
|
|
// literal, malloc'd block (XXX: possible leak)
|
|
|
|
const char *g_gameNamePtr = NULL;
|
|
|
|
|
2012-06-03 16:09:33 +00:00
|
|
|
// grp/con/def handling
|
|
|
|
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *defaultgamegrp[GAMECOUNT] = { "DUKE3D.GRP", "NAM.GRP", "NAPALM.GRP", "WW2GI.GRP" };
|
|
|
|
const char *defaultdeffilename[GAMECOUNT] = { "duke3d.def", "nam.def", "napalm.def", "ww2gi.def" };
|
|
|
|
const char *defaultconfilename = "GAME.CON";
|
|
|
|
const char *defaultgameconfilename[GAMECOUNT] = { "EDUKE.CON", "NAM.CON", "NAPALM.CON", "WW2GI.CON" };
|
2012-06-03 16:09:33 +00:00
|
|
|
|
|
|
|
// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
|
|
|
|
char *g_grpNamePtr = NULL;
|
|
|
|
// g_defNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
|
|
|
|
char *g_defNamePtr = NULL;
|
|
|
|
// g_scriptNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
|
|
|
|
char *g_scriptNamePtr = NULL;
|
|
|
|
|
|
|
|
void clearGrpNamePtr(void)
|
|
|
|
{
|
|
|
|
if (g_grpNamePtr != NULL)
|
|
|
|
Bfree(g_grpNamePtr);
|
|
|
|
// g_grpNamePtr assumed to be assigned to right after
|
|
|
|
}
|
|
|
|
|
|
|
|
void clearDefNamePtr(void)
|
|
|
|
{
|
|
|
|
if (g_defNamePtr != NULL)
|
|
|
|
Bfree(g_defNamePtr);
|
|
|
|
// g_defNamePtr assumed to be assigned to right after
|
|
|
|
}
|
|
|
|
|
|
|
|
void clearScriptNamePtr(void)
|
|
|
|
{
|
|
|
|
if (g_scriptNamePtr != NULL)
|
|
|
|
Bfree(g_scriptNamePtr);
|
|
|
|
// g_scriptNamePtr assumed to be assigned to right after
|
|
|
|
}
|
|
|
|
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *G_DefaultGrpFile(void)
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
|
|
|
if (DUKE)
|
|
|
|
return defaultgamegrp[GAME_DUKE];
|
|
|
|
// order is important for the following three because GAMEFLAG_NAM overlaps all
|
|
|
|
else if (NAPALM)
|
|
|
|
return defaultgamegrp[GAME_NAPALM];
|
|
|
|
else if (WW2GI)
|
|
|
|
return defaultgamegrp[GAME_WW2GI];
|
|
|
|
else if (NAM)
|
|
|
|
return defaultgamegrp[GAME_NAM];
|
|
|
|
|
|
|
|
return defaultgamegrp[0];
|
|
|
|
}
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *G_DefaultDefFile(void)
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
|
|
|
if (DUKE)
|
|
|
|
return defaultdeffilename[GAME_DUKE];
|
|
|
|
else if (WW2GI)
|
|
|
|
return defaultdeffilename[GAME_WW2GI];
|
|
|
|
else if (NAPALM)
|
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (!testkopen(defaultdeffilename[GAME_NAPALM],0) && testkopen(defaultdeffilename[GAME_NAM],0))
|
2013-03-28 09:05:18 +00:00
|
|
|
return defaultdeffilename[GAME_NAM]; // NAM/NAPALM Sharing
|
2012-06-03 16:09:33 +00:00
|
|
|
else
|
|
|
|
return defaultdeffilename[GAME_NAPALM];
|
|
|
|
}
|
|
|
|
else if (NAM)
|
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (!testkopen(defaultdeffilename[GAME_NAM],0) && testkopen(defaultdeffilename[GAME_NAPALM],0))
|
2013-03-28 09:05:18 +00:00
|
|
|
return defaultdeffilename[GAME_NAPALM]; // NAM/NAPALM Sharing
|
2012-06-03 16:09:33 +00:00
|
|
|
else
|
|
|
|
return defaultdeffilename[GAME_NAM];
|
|
|
|
}
|
|
|
|
|
|
|
|
return defaultdeffilename[0];
|
|
|
|
}
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *G_DefaultConFile(void)
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (DUKE && testkopen(defaultgameconfilename[GAME_DUKE],0))
|
2012-06-03 16:09:33 +00:00
|
|
|
return defaultgameconfilename[GAME_DUKE];
|
2012-06-11 20:35:47 +00:00
|
|
|
else if (WW2GI && testkopen(defaultgameconfilename[GAME_WW2GI],0))
|
2012-06-03 16:09:33 +00:00
|
|
|
return defaultgameconfilename[GAME_WW2GI];
|
|
|
|
else if (NAPALM)
|
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (!testkopen(defaultgameconfilename[GAME_NAPALM],0))
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (testkopen(defaultgameconfilename[GAME_NAM],0))
|
2013-03-28 09:05:18 +00:00
|
|
|
return defaultgameconfilename[GAME_NAM]; // NAM/NAPALM Sharing
|
2012-06-03 16:09:33 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return defaultgameconfilename[GAME_NAPALM];
|
|
|
|
}
|
|
|
|
else if (NAM)
|
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (!testkopen(defaultgameconfilename[GAME_NAM],0))
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
2012-06-11 20:35:47 +00:00
|
|
|
if (testkopen(defaultgameconfilename[GAME_NAPALM],0))
|
2013-03-28 09:05:18 +00:00
|
|
|
return defaultgameconfilename[GAME_NAPALM]; // NAM/NAPALM Sharing
|
2012-06-03 16:09:33 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return defaultgameconfilename[GAME_NAM];
|
|
|
|
}
|
|
|
|
|
|
|
|
return defaultconfilename;
|
|
|
|
}
|
|
|
|
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *G_GrpFile(void)
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
|
|
|
if (g_grpNamePtr == NULL)
|
|
|
|
return G_DefaultGrpFile();
|
|
|
|
else
|
|
|
|
return g_grpNamePtr;
|
|
|
|
}
|
2013-04-08 18:30:39 +00:00
|
|
|
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *G_DefFile(void)
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
|
|
|
if (g_defNamePtr == NULL)
|
|
|
|
return G_DefaultDefFile();
|
|
|
|
else
|
|
|
|
return g_defNamePtr;
|
|
|
|
}
|
2013-04-08 18:30:39 +00:00
|
|
|
|
2012-07-01 22:11:33 +00:00
|
|
|
const char *G_ConFile(void)
|
2012-06-03 16:09:33 +00:00
|
|
|
{
|
|
|
|
if (g_scriptNamePtr == NULL)
|
|
|
|
return G_DefaultConFile();
|
|
|
|
else
|
|
|
|
return g_scriptNamePtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////
|
2012-03-26 22:03:20 +00:00
|
|
|
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
#define NUMPSKYMULTIS 5
|
|
|
|
EDUKE32_STATIC_ASSERT(NUMPSKYMULTIS <= MAXPSKYMULTIS);
|
|
|
|
EDUKE32_STATIC_ASSERT(PSKYOFF_MAX <= MAXPSKYTILES);
|
|
|
|
|
2013-08-04 20:37:45 +00:00
|
|
|
// Set up new-style multi-psky handling.
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
void G_InitMultiPsky(int32_t CLOUDYOCEAN__DYN, int32_t MOONSKY1__DYN, int32_t BIGORBIT1__DYN, int32_t LA__DYN)
|
2012-11-25 04:25:31 +00:00
|
|
|
{
|
|
|
|
int32_t i;
|
|
|
|
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
psky_t *defaultsky = &multipsky[0];
|
|
|
|
psky_t *oceansky = &multipsky[1];
|
|
|
|
psky_t *moonsky = &multipsky[2];
|
|
|
|
psky_t *spacesky = &multipsky[3];
|
|
|
|
psky_t *citysky = &multipsky[4];
|
2012-11-25 04:25:31 +00:00
|
|
|
|
2013-08-04 20:37:45 +00:00
|
|
|
static int32_t inited;
|
|
|
|
if (inited)
|
|
|
|
return;
|
|
|
|
inited = 1;
|
2012-11-25 04:25:31 +00:00
|
|
|
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
multipskytile[0] = -1;
|
|
|
|
multipskytile[1] = CLOUDYOCEAN__DYN;
|
|
|
|
multipskytile[2] = MOONSKY1__DYN;
|
|
|
|
multipskytile[3] = BIGORBIT1__DYN;
|
|
|
|
multipskytile[4] = LA__DYN;
|
2013-08-04 20:37:45 +00:00
|
|
|
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
pskynummultis = NUMPSKYMULTIS;
|
2012-11-25 04:25:31 +00:00
|
|
|
|
2013-08-04 20:37:45 +00:00
|
|
|
// When adding other multi-skies, take care that the tileofs[] values are
|
|
|
|
// <= PSKYOFF_MAX. (It can be increased up to MAXPSKYTILES, but should be
|
|
|
|
// set as tight as possible.)
|
2012-11-25 04:25:31 +00:00
|
|
|
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
// The default sky properties (all others are implicitly zero):
|
|
|
|
defaultsky->lognumtiles = 3;
|
|
|
|
defaultsky->horizfrac = 32768;
|
|
|
|
|
|
|
|
// CLOUDYOCEAN
|
|
|
|
// Aligns with the drawn scene horizon because it has one itself.
|
|
|
|
oceansky->lognumtiles = 3;
|
|
|
|
oceansky->horizfrac = 65536;
|
|
|
|
|
2012-11-25 04:25:31 +00:00
|
|
|
// MOONSKY1
|
|
|
|
// earth mountain mountain sun
|
2013-08-04 20:37:45 +00:00
|
|
|
moonsky->lognumtiles = 3;
|
|
|
|
moonsky->horizfrac = 32768;
|
|
|
|
moonsky->tileofs[6] = 1;
|
|
|
|
moonsky->tileofs[1] = 2;
|
|
|
|
moonsky->tileofs[4] = 2;
|
|
|
|
moonsky->tileofs[2] = 3;
|
2012-11-25 04:25:31 +00:00
|
|
|
|
|
|
|
// BIGORBIT1 // orbit
|
|
|
|
// earth1 2 3 moon/sun
|
2013-08-04 20:37:45 +00:00
|
|
|
spacesky->lognumtiles = 3;
|
|
|
|
spacesky->horizfrac = 32768;
|
|
|
|
spacesky->tileofs[5] = 1;
|
|
|
|
spacesky->tileofs[6] = 2;
|
|
|
|
spacesky->tileofs[7] = 3;
|
|
|
|
spacesky->tileofs[2] = 4;
|
2012-11-25 04:25:31 +00:00
|
|
|
|
|
|
|
// LA // la city
|
|
|
|
// earth1 2 3 moon/sun
|
2013-08-04 20:37:45 +00:00
|
|
|
citysky->lognumtiles = 3;
|
|
|
|
citysky->horizfrac = 16384+1024;
|
|
|
|
citysky->tileofs[0] = 1;
|
|
|
|
citysky->tileofs[1] = 2;
|
|
|
|
citysky->tileofs[2] = 1;
|
|
|
|
citysky->tileofs[3] = 3;
|
|
|
|
citysky->tileofs[4] = 4;
|
|
|
|
citysky->tileofs[5] = 0;
|
|
|
|
citysky->tileofs[6] = 2;
|
|
|
|
citysky->tileofs[7] = 3;
|
|
|
|
|
|
|
|
for (i=0; i<pskynummultis; ++i)
|
|
|
|
{
|
|
|
|
int32_t j;
|
|
|
|
for (j=0; j<(1<<multipsky[i].lognumtiles); ++j)
|
|
|
|
Bassert(multipsky[i].tileofs[j] <= PSKYOFF_MAX);
|
|
|
|
}
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void G_SetupGlobalPsky(void)
|
|
|
|
{
|
|
|
|
int32_t i, mskyidx=0;
|
|
|
|
|
|
|
|
// NOTE: Loop must be running backwards for the same behavior as the game
|
|
|
|
// (greatest sector index with matching parallaxed sky takes precedence).
|
|
|
|
for (i=numsectors-1; i>=0; i--)
|
|
|
|
{
|
|
|
|
if (sector[i].ceilingstat & 1)
|
|
|
|
{
|
2013-08-11 15:28:51 +00:00
|
|
|
mskyidx = getpskyidx(sector[i].ceilingpicnum);
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
if (mskyidx > 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-25 04:25:31 +00:00
|
|
|
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
g_pskyidx = mskyidx;
|
2012-11-25 04:25:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////
|
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
static char g_rootDir[BMAX_PATH];
|
|
|
|
char g_modDir[BMAX_PATH] = "/";
|
|
|
|
|
|
|
|
int32_t kopen4loadfrommod(const char *filename, char searchfirst)
|
|
|
|
{
|
|
|
|
int32_t r=-1;
|
|
|
|
|
|
|
|
if (g_modDir[0]!='/' || g_modDir[1]!=0)
|
|
|
|
{
|
|
|
|
static char fn[BMAX_PATH];
|
|
|
|
|
|
|
|
Bsnprintf(fn, sizeof(fn), "%s/%s",g_modDir,filename);
|
|
|
|
r = kopen4load(fn,searchfirst);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r < 0)
|
|
|
|
r = kopen4load(filename,searchfirst);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t usecwd;
|
|
|
|
static void G_LoadAddon(void);
|
|
|
|
int32_t g_groupFileHandle;
|
|
|
|
|
|
|
|
void G_ExtPreInit(int32_t argc,const char **argv)
|
|
|
|
{
|
|
|
|
usecwd = G_CheckCmdSwitch(argc, argv, "-usecwd");
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
GetModuleFileName(NULL,g_rootDir,BMAX_PATH);
|
|
|
|
Bcorrectfilename(g_rootDir,1);
|
|
|
|
//chdir(g_rootDir);
|
|
|
|
#else
|
|
|
|
getcwd(g_rootDir,BMAX_PATH);
|
|
|
|
strcat(g_rootDir,"/");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void G_ExtInit(void)
|
|
|
|
{
|
|
|
|
char cwd[BMAX_PATH];
|
|
|
|
|
|
|
|
if (getcwd(cwd,BMAX_PATH))
|
|
|
|
{
|
|
|
|
#if defined(__APPLE__)
|
|
|
|
/* Dirty hack on OS X to also look for gamedata inside the application bundle - rhoenie 08/08 */
|
|
|
|
char seekinappcontainer[BMAX_PATH];
|
|
|
|
Bsnprintf(seekinappcontainer,sizeof(seekinappcontainer),"%s/EDuke32.app/", cwd);
|
|
|
|
addsearchpath(seekinappcontainer);
|
|
|
|
#endif
|
|
|
|
addsearchpath(cwd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CommandPaths)
|
|
|
|
{
|
|
|
|
int32_t i;
|
|
|
|
struct strllist *s;
|
|
|
|
while (CommandPaths)
|
|
|
|
{
|
|
|
|
s = CommandPaths->next;
|
|
|
|
i = addsearchpath(CommandPaths->str);
|
|
|
|
if (i < 0)
|
|
|
|
{
|
|
|
|
initprintf("Failed adding %s for game data: %s\n", CommandPaths->str,
|
|
|
|
i==-1 ? "not a directory" : "no such directory");
|
|
|
|
}
|
|
|
|
|
|
|
|
Bfree(CommandPaths->str);
|
|
|
|
Bfree(CommandPaths);
|
|
|
|
CommandPaths = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
if (!access("user_profiles_enabled", F_OK))
|
|
|
|
#else
|
|
|
|
if (usecwd == 0 && access("user_profiles_disabled", F_OK))
|
2013-03-21 09:49:12 +00:00
|
|
|
#endif
|
2014-07-28 06:42:28 +00:00
|
|
|
{
|
|
|
|
char *homedir;
|
|
|
|
int32_t asperr;
|
|
|
|
|
|
|
|
if ((homedir = Bgethomedir()))
|
|
|
|
{
|
|
|
|
Bsnprintf(cwd,sizeof(cwd),"%s/"
|
|
|
|
#if defined(_WIN32)
|
|
|
|
"EDuke32 Settings"
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
"Library/Application Support/EDuke32"
|
|
|
|
#elif defined(GEKKO)
|
|
|
|
"apps/eduke32"
|
|
|
|
#else
|
|
|
|
".eduke32"
|
|
|
|
#endif
|
|
|
|
,homedir);
|
|
|
|
asperr = addsearchpath(cwd);
|
|
|
|
if (asperr == -2)
|
|
|
|
{
|
|
|
|
if (Bmkdir(cwd,S_IRWXU) == 0) asperr = addsearchpath(cwd);
|
|
|
|
else asperr = -1;
|
|
|
|
}
|
|
|
|
if (asperr == 0)
|
|
|
|
chdir(cwd);
|
|
|
|
Bfree(homedir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// JBF 20031220: Because it's annoying renaming GRP files whenever I want to test different game data
|
|
|
|
if (g_grpNamePtr == NULL)
|
|
|
|
{
|
|
|
|
const char *cp = getenv("DUKE3DGRP");
|
|
|
|
if (cp)
|
|
|
|
{
|
|
|
|
clearGrpNamePtr();
|
|
|
|
g_grpNamePtr = dup_filename(cp);
|
|
|
|
initprintf("Using \"%s\" as main GRP file\n", g_grpNamePtr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void G_ExtPreStartupWindow(void)
|
|
|
|
{
|
|
|
|
ScanGroups();
|
|
|
|
{
|
|
|
|
// try and identify the 'defaultgamegrp' in the set of GRPs.
|
|
|
|
// if it is found, set up the environment accordingly for the game it represents.
|
|
|
|
// if it is not found, choose the first GRP from the list
|
|
|
|
struct grpfile *fg, *first = NULL;
|
|
|
|
|
|
|
|
for (fg = foundgrps; fg; fg=fg->next)
|
|
|
|
{
|
|
|
|
struct grpfile *grp;
|
|
|
|
for (grp = listgrps; grp; grp=grp->next)
|
|
|
|
if (fg->crcval == grp->crcval) break;
|
|
|
|
|
|
|
|
if (grp == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fg->game = grp->game;
|
|
|
|
if (!first) first = fg;
|
|
|
|
if (!Bstrcasecmp(fg->name, G_DefaultGrpFile()))
|
|
|
|
{
|
|
|
|
g_gameType = grp->game;
|
|
|
|
g_gameNamePtr = grp->name;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!fg && first)
|
|
|
|
{
|
|
|
|
if (g_grpNamePtr == NULL)
|
|
|
|
{
|
|
|
|
clearGrpNamePtr();
|
|
|
|
g_grpNamePtr = dup_filename(first->name);
|
|
|
|
}
|
|
|
|
g_gameType = first->game;
|
|
|
|
g_gameNamePtr = listgrps->name;
|
|
|
|
}
|
|
|
|
else if (!fg) g_gameNamePtr = NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-03-21 09:49:12 +00:00
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
void G_ExtPostStartupWindow(int32_t autoload)
|
2013-03-21 09:49:12 +00:00
|
|
|
{
|
2014-07-28 06:42:28 +00:00
|
|
|
if (g_modDir[0] != '/')
|
|
|
|
{
|
|
|
|
char cwd[BMAX_PATH];
|
|
|
|
|
|
|
|
Bstrcat(g_rootDir,g_modDir);
|
|
|
|
addsearchpath(g_rootDir);
|
|
|
|
// addsearchpath(mod_dir);
|
|
|
|
|
|
|
|
if (getcwd(cwd,BMAX_PATH))
|
|
|
|
{
|
|
|
|
Bsprintf(cwd,"%s/%s",cwd,g_modDir);
|
|
|
|
if (!Bstrcmp(g_rootDir, cwd))
|
|
|
|
{
|
|
|
|
if (addsearchpath(cwd) == -2)
|
|
|
|
if (Bmkdir(cwd,S_IRWXU) == 0) addsearchpath(cwd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_OPENGL
|
|
|
|
Bsprintf(cwd,"%s/%s",g_modDir,TEXCACHEFILE);
|
|
|
|
Bstrcpy(TEXCACHEFILE,cwd);
|
2013-03-21 09:49:12 +00:00
|
|
|
#endif
|
2014-07-28 06:42:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (g_usingAddon)
|
|
|
|
G_LoadAddon();
|
|
|
|
|
|
|
|
{
|
|
|
|
int32_t i;
|
|
|
|
const char *grpfile = G_GrpFile();
|
|
|
|
|
|
|
|
if (g_dependencyCRC)
|
|
|
|
{
|
|
|
|
struct grpfile * grp = FindGroup(g_dependencyCRC);
|
|
|
|
if (grp)
|
|
|
|
{
|
|
|
|
if ((i = initgroupfile(grp->name)) == -1)
|
|
|
|
initprintf("Warning: could not find main data file \"%s\"!\n",grp->name);
|
|
|
|
else
|
|
|
|
initprintf("Using \"%s\" as main game data file.\n", grp->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((i = initgroupfile(grpfile)) == -1)
|
|
|
|
initprintf("Warning: could not find main data file \"%s\"!\n",grpfile);
|
|
|
|
else
|
|
|
|
initprintf("Using \"%s\" as main game data file.\n", grpfile);
|
|
|
|
|
|
|
|
if (autoload)
|
|
|
|
{
|
|
|
|
G_LoadGroupsInDir("autoload");
|
|
|
|
|
|
|
|
if (i != -1)
|
|
|
|
G_DoAutoload(grpfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_modDir[0] != '/')
|
|
|
|
G_LoadGroupsInDir(g_modDir);
|
|
|
|
|
|
|
|
if (g_defNamePtr == NULL)
|
|
|
|
{
|
|
|
|
const char *tmpptr = getenv("DUKE3DDEF");
|
|
|
|
if (tmpptr)
|
|
|
|
{
|
|
|
|
clearDefNamePtr();
|
|
|
|
g_defNamePtr = dup_filename(tmpptr);
|
|
|
|
initprintf("Using \"%s\" as definitions file\n", g_defNamePtr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
loaddefinitions_game(G_DefFile(), TRUE);
|
|
|
|
|
|
|
|
{
|
|
|
|
struct strllist *s;
|
|
|
|
|
|
|
|
pathsearchmode = 1;
|
|
|
|
while (CommandGrps)
|
|
|
|
{
|
|
|
|
int32_t j;
|
|
|
|
|
|
|
|
s = CommandGrps->next;
|
|
|
|
|
|
|
|
if ((j = initgroupfile(CommandGrps->str)) == -1)
|
|
|
|
initprintf("Could not find file \"%s\".\n",CommandGrps->str);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_groupFileHandle = j;
|
|
|
|
initprintf("Using file \"%s\" as game data.\n",CommandGrps->str);
|
|
|
|
if (autoload)
|
|
|
|
G_DoAutoload(CommandGrps->str);
|
|
|
|
}
|
|
|
|
|
|
|
|
Bfree(CommandGrps->str);
|
|
|
|
Bfree(CommandGrps);
|
|
|
|
CommandGrps = s;
|
|
|
|
}
|
|
|
|
pathsearchmode = 0;
|
|
|
|
}
|
2013-03-21 09:49:12 +00:00
|
|
|
}
|
|
|
|
|
2013-03-28 23:35:52 +00:00
|
|
|
#ifdef _WIN32
|
2013-04-05 07:48:20 +00:00
|
|
|
const char * G_GetInstallPath(int32_t insttype)
|
2013-03-28 23:35:52 +00:00
|
|
|
{
|
2013-04-05 07:48:20 +00:00
|
|
|
static char spath[NUMINSTPATHS][BMAX_PATH];
|
|
|
|
static int32_t success[NUMINSTPATHS] = { -1, -1 };
|
2013-03-28 23:35:52 +00:00
|
|
|
int32_t siz = BMAX_PATH;
|
|
|
|
|
2013-04-05 07:48:20 +00:00
|
|
|
if (success[insttype] == -1)
|
|
|
|
{
|
2013-04-13 03:50:37 +00:00
|
|
|
HKEY HKLM32;
|
|
|
|
LONG keygood = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ | KEY_WOW64_32KEY, &HKLM32);
|
|
|
|
// KEY_WOW64_32KEY gets us around Wow6432Node on 64-bit builds
|
|
|
|
|
|
|
|
if (keygood == ERROR_SUCCESS)
|
2013-11-03 04:02:01 +00:00
|
|
|
{
|
2013-04-13 03:50:37 +00:00
|
|
|
switch (insttype)
|
|
|
|
{
|
|
|
|
case INSTPATH_STEAM:
|
|
|
|
success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App 225140", "InstallLocation", NULL, spath[insttype], (LPDWORD)&siz);
|
|
|
|
break;
|
|
|
|
case INSTPATH_GOG:
|
|
|
|
success[insttype] = SHGetValueA(HKLM32, "SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", NULL, spath[insttype], (LPDWORD)&siz);
|
|
|
|
break;
|
|
|
|
}
|
2013-11-03 04:02:01 +00:00
|
|
|
|
|
|
|
RegCloseKey(HKLM32);
|
|
|
|
}
|
2013-04-05 07:48:20 +00:00
|
|
|
}
|
2013-03-28 23:35:52 +00:00
|
|
|
|
2013-04-05 07:48:20 +00:00
|
|
|
if (success[insttype] == ERROR_SUCCESS)
|
|
|
|
return spath[insttype];
|
2013-03-28 23:35:52 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
static void G_LoadAddon(void)
|
|
|
|
{
|
|
|
|
struct grpfile * grp;
|
|
|
|
int32_t crc = 0; // compiler-happy
|
|
|
|
|
|
|
|
switch (g_usingAddon)
|
|
|
|
{
|
|
|
|
case ADDON_DUKEDC:
|
|
|
|
crc = DUKEDC_CRC;
|
|
|
|
break;
|
|
|
|
case ADDON_NWINTER:
|
|
|
|
crc = DUKENW_CRC;
|
|
|
|
break;
|
|
|
|
case ADDON_CARIBBEAN:
|
|
|
|
crc = DUKECB_CRC;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!crc) return;
|
|
|
|
|
|
|
|
grp = FindGroup(crc);
|
|
|
|
|
|
|
|
if (grp && FindGroup(DUKE15_CRC))
|
|
|
|
{
|
|
|
|
clearGrpNamePtr();
|
|
|
|
g_grpNamePtr = dup_filename(FindGroup(DUKE15_CRC)->name);
|
|
|
|
|
|
|
|
G_AddGroup(grp->name);
|
|
|
|
|
|
|
|
for (grp = listgrps; grp; grp=grp->next)
|
|
|
|
if (crc == grp->crcval) break;
|
|
|
|
|
|
|
|
if (grp != NULL && grp->scriptname)
|
|
|
|
{
|
|
|
|
clearScriptNamePtr();
|
|
|
|
g_scriptNamePtr = dup_filename(grp->scriptname);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (grp != NULL && grp->defname)
|
|
|
|
{
|
|
|
|
clearDefNamePtr();
|
|
|
|
g_defNamePtr = dup_filename(grp->defname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-21 09:48:21 +00:00
|
|
|
void G_AddSearchPaths(void)
|
|
|
|
{
|
|
|
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
|
|
|
addsearchpath("/usr/share/games/jfduke3d");
|
|
|
|
addsearchpath("/usr/local/share/games/jfduke3d");
|
|
|
|
addsearchpath("/usr/share/games/eduke32");
|
|
|
|
addsearchpath("/usr/local/share/games/eduke32");
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
addsearchpath("/Library/Application Support/JFDuke3D");
|
|
|
|
addsearchpath("/Library/Application Support/EDuke32");
|
|
|
|
#elif defined (_WIN32)
|
2013-03-27 01:39:18 +00:00
|
|
|
// detect Steam and GOG versions of Duke3D
|
|
|
|
char buf[BMAX_PATH];
|
2013-04-13 03:50:37 +00:00
|
|
|
const char* instpath;
|
2013-03-27 01:39:18 +00:00
|
|
|
|
2013-04-13 03:50:37 +00:00
|
|
|
if ((instpath = G_GetInstallPath(INSTPATH_STEAM)))
|
2013-03-27 01:39:18 +00:00
|
|
|
{
|
2014-07-28 06:42:28 +00:00
|
|
|
Bsnprintf(buf, sizeof(buf), "%s/gameroot", instpath);
|
2013-03-28 23:35:52 +00:00
|
|
|
addsearchpath(buf);
|
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons", instpath);
|
2013-03-28 23:35:52 +00:00
|
|
|
addsearchpath(buf);
|
2013-03-27 01:39:18 +00:00
|
|
|
}
|
|
|
|
|
2013-04-13 03:50:37 +00:00
|
|
|
if ((instpath = G_GetInstallPath(INSTPATH_GOG)))
|
|
|
|
addsearchpath(instpath);
|
2013-03-21 09:48:21 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-04-08 18:30:39 +00:00
|
|
|
void G_CleanupSearchPaths(void)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
char buf[BMAX_PATH];
|
2013-04-13 03:50:37 +00:00
|
|
|
const char* instpath;
|
2013-04-08 18:30:39 +00:00
|
|
|
|
2013-04-13 03:50:37 +00:00
|
|
|
if ((instpath = G_GetInstallPath(INSTPATH_STEAM)))
|
2013-04-08 18:30:39 +00:00
|
|
|
{
|
2014-07-28 06:42:28 +00:00
|
|
|
Bsnprintf(buf, sizeof(buf), "%s/gameroot", instpath);
|
2013-04-08 18:30:39 +00:00
|
|
|
removesearchpath(buf);
|
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
Bsnprintf(buf, sizeof(buf), "%s/gameroot/addons", instpath);
|
2013-04-08 18:30:39 +00:00
|
|
|
removesearchpath(buf);
|
|
|
|
}
|
|
|
|
|
2013-04-13 03:50:37 +00:00
|
|
|
if ((instpath = G_GetInstallPath(INSTPATH_GOG)))
|
|
|
|
removesearchpath(instpath);
|
2013-04-08 18:30:39 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-03-21 09:48:21 +00:00
|
|
|
//////////
|
|
|
|
|
2012-03-26 22:03:20 +00:00
|
|
|
struct strllist *CommandPaths, *CommandGrps;
|
|
|
|
|
2013-11-03 04:02:23 +00:00
|
|
|
char **g_scriptModules = NULL;
|
|
|
|
int32_t g_scriptModulesNum = 0;
|
|
|
|
char **g_defModules = NULL;
|
|
|
|
int32_t g_defModulesNum = 0;
|
|
|
|
|
|
|
|
#ifdef HAVE_CLIPSHAPE_FEATURE
|
|
|
|
char **g_clipMapFiles = NULL;
|
|
|
|
int32_t g_clipMapFilesNum = 0;
|
|
|
|
#endif
|
|
|
|
|
2012-03-26 22:03:20 +00:00
|
|
|
void G_AddGroup(const char *buffer)
|
|
|
|
{
|
|
|
|
char buf[BMAX_PATH];
|
|
|
|
|
2014-05-30 00:02:19 +00:00
|
|
|
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
|
2012-03-26 22:03:20 +00:00
|
|
|
|
|
|
|
Bstrcpy(buf, buffer);
|
|
|
|
|
|
|
|
if (Bstrchr(buf,'.') == 0)
|
|
|
|
Bstrcat(buf,".grp");
|
|
|
|
|
2014-05-30 00:02:19 +00:00
|
|
|
s->str = Xstrdup(buf);
|
2012-03-26 22:03:20 +00:00
|
|
|
|
|
|
|
if (CommandGrps)
|
|
|
|
{
|
|
|
|
struct strllist *t;
|
|
|
|
for (t = CommandGrps; t->next; t=t->next) ;
|
|
|
|
t->next = s;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
CommandGrps = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void G_AddPath(const char *buffer)
|
|
|
|
{
|
2014-05-30 00:02:19 +00:00
|
|
|
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
|
|
|
|
s->str = Xstrdup(buffer);
|
2012-03-26 22:03:20 +00:00
|
|
|
|
|
|
|
if (CommandPaths)
|
|
|
|
{
|
|
|
|
struct strllist *t;
|
|
|
|
for (t = CommandPaths; t->next; t=t->next) ;
|
|
|
|
t->next = s;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
CommandPaths = s;
|
|
|
|
}
|
2012-03-26 22:05:23 +00:00
|
|
|
|
2013-11-03 04:02:23 +00:00
|
|
|
void G_AddDef(const char *buffer)
|
|
|
|
{
|
|
|
|
clearDefNamePtr();
|
|
|
|
g_defNamePtr = dup_filename(buffer);
|
|
|
|
initprintf("Using DEF file \"%s\".\n",g_defNamePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void G_AddDefModule(const char *buffer)
|
|
|
|
{
|
2014-05-30 00:02:19 +00:00
|
|
|
g_defModules = (char **) Xrealloc (g_defModules, (g_defModulesNum+1) * sizeof(char *));
|
|
|
|
g_defModules[g_defModulesNum] = Xstrdup(buffer);
|
2013-11-03 04:02:23 +00:00
|
|
|
++g_defModulesNum;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_CLIPSHAPE_FEATURE
|
|
|
|
void G_AddClipMap(const char *buffer)
|
|
|
|
{
|
2014-05-30 00:02:19 +00:00
|
|
|
g_clipMapFiles = (char **) Xrealloc (g_clipMapFiles, (g_clipMapFilesNum+1) * sizeof(char *));
|
|
|
|
g_clipMapFiles[g_clipMapFilesNum] = Xstrdup(buffer);
|
2013-11-03 04:02:23 +00:00
|
|
|
++g_clipMapFilesNum;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void G_AddCon(const char *buffer)
|
|
|
|
{
|
|
|
|
clearScriptNamePtr();
|
|
|
|
g_scriptNamePtr = dup_filename(buffer);
|
|
|
|
initprintf("Using CON file \"%s\".\n",g_scriptNamePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void G_AddConModule(const char *buffer)
|
|
|
|
{
|
2014-05-30 00:02:19 +00:00
|
|
|
g_scriptModules = (char **) Xrealloc (g_scriptModules, (g_scriptModulesNum+1) * sizeof(char *));
|
|
|
|
g_scriptModules[g_scriptModulesNum] = Xstrdup(buffer);
|
2013-11-03 04:02:23 +00:00
|
|
|
++g_scriptModulesNum;
|
|
|
|
}
|
|
|
|
|
2012-03-26 22:05:23 +00:00
|
|
|
//////////
|
|
|
|
|
|
|
|
int32_t getatoken(scriptfile *sf, const tokenlist *tl, int32_t ntokens)
|
|
|
|
{
|
|
|
|
char *tok;
|
|
|
|
int32_t i;
|
|
|
|
|
|
|
|
if (!sf) return T_ERROR;
|
|
|
|
tok = scriptfile_gettoken(sf);
|
|
|
|
if (!tok) return T_EOF;
|
|
|
|
|
|
|
|
for (i=ntokens-1; i>=0; i--)
|
|
|
|
{
|
|
|
|
if (!Bstrcasecmp(tok, tl[i].text))
|
|
|
|
return tl[i].tokenid;
|
|
|
|
}
|
|
|
|
return T_ERROR;
|
|
|
|
}
|
2012-03-28 19:41:39 +00:00
|
|
|
|
|
|
|
//////////
|
|
|
|
|
2014-07-28 06:42:28 +00:00
|
|
|
int32_t G_CheckCmdSwitch(int32_t argc, const char **argv, const char *str)
|
|
|
|
{
|
|
|
|
int32_t i;
|
|
|
|
for (i=0; i<argc; i++)
|
|
|
|
{
|
|
|
|
if (str && !Bstrcasecmp(argv[i], str))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-11 20:35:47 +00:00
|
|
|
// returns: 1 if file could be opened, 0 else
|
|
|
|
int32_t testkopen(const char *filename, char searchfirst)
|
|
|
|
{
|
|
|
|
int32_t fd = kopen4load(filename, searchfirst);
|
|
|
|
if (fd >= 0)
|
|
|
|
kclose(fd);
|
|
|
|
return (fd >= 0);
|
|
|
|
}
|
|
|
|
|
2012-03-28 19:41:39 +00:00
|
|
|
// checks from path and in ZIPs, returns 1 if NOT found
|
|
|
|
int32_t check_file_exist(const char *fn)
|
|
|
|
{
|
|
|
|
int32_t opsm = pathsearchmode;
|
|
|
|
char *tfn;
|
|
|
|
|
|
|
|
pathsearchmode = 1;
|
|
|
|
if (findfrompath(fn,&tfn) < 0)
|
|
|
|
{
|
|
|
|
char buf[BMAX_PATH];
|
|
|
|
|
|
|
|
Bstrcpy(buf,fn);
|
|
|
|
kzfindfilestart(buf);
|
|
|
|
if (!kzfindfile(buf))
|
|
|
|
{
|
|
|
|
initprintf("Error: file \"%s\" does not exist\n",fn);
|
|
|
|
pathsearchmode = opsm;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else Bfree(tfn);
|
|
|
|
pathsearchmode = opsm;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-03-28 19:41:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
//// FILE NAME / DIRECTORY LISTS ////
|
|
|
|
void fnlist_clearnames(fnlist_t *fnl)
|
|
|
|
{
|
|
|
|
klistfree(fnl->finddirs);
|
|
|
|
klistfree(fnl->findfiles);
|
|
|
|
|
|
|
|
fnl->finddirs = fnl->findfiles = NULL;
|
|
|
|
fnl->numfiles = fnl->numdirs = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// dirflags, fileflags:
|
|
|
|
// -1 means "don't get dirs/files",
|
|
|
|
// otherwise ORed to flags for respective klistpath
|
|
|
|
int32_t fnlist_getnames(fnlist_t *fnl, const char *dirname, const char *pattern,
|
|
|
|
int32_t dirflags, int32_t fileflags)
|
|
|
|
{
|
|
|
|
CACHE1D_FIND_REC *r;
|
|
|
|
|
|
|
|
fnlist_clearnames(fnl);
|
|
|
|
|
|
|
|
if (dirflags != -1)
|
|
|
|
fnl->finddirs = klistpath(dirname, "*", CACHE1D_FIND_DIR|dirflags);
|
|
|
|
if (fileflags != -1)
|
|
|
|
fnl->findfiles = klistpath(dirname, pattern, CACHE1D_FIND_FILE|fileflags);
|
|
|
|
|
|
|
|
for (r=fnl->finddirs; r; r=r->next)
|
|
|
|
fnl->numdirs++;
|
|
|
|
for (r=fnl->findfiles; r; r=r->next)
|
|
|
|
fnl->numfiles++;
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-12 02:53:10 +00:00
|
|
|
// loads all group (grp, zip, pk3/4) files in the given directory
|
2012-03-28 19:41:57 +00:00
|
|
|
void G_LoadGroupsInDir(const char *dirname)
|
|
|
|
{
|
2012-12-12 02:53:10 +00:00
|
|
|
static const char *extensions[4] = { "*.grp", "*.zip", "*.pk3", "*.pk4" };
|
2012-03-28 19:41:57 +00:00
|
|
|
|
|
|
|
char buf[BMAX_PATH];
|
|
|
|
int32_t i;
|
|
|
|
|
|
|
|
fnlist_t fnlist = FNLIST_INITIALIZER;
|
|
|
|
|
2012-12-12 02:53:10 +00:00
|
|
|
for (i=0; i<4; i++)
|
2012-03-28 19:41:57 +00:00
|
|
|
{
|
|
|
|
CACHE1D_FIND_REC *rec;
|
|
|
|
|
|
|
|
fnlist_getnames(&fnlist, dirname, extensions[i], -1, 0);
|
|
|
|
|
|
|
|
for (rec=fnlist.findfiles; rec; rec=rec->next)
|
|
|
|
{
|
|
|
|
Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name);
|
|
|
|
initprintf("Using group file \"%s\".\n", buf);
|
|
|
|
initgroupfile(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
fnlist_clearnames(&fnlist);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void G_DoAutoload(const char *dirname)
|
|
|
|
{
|
|
|
|
char buf[BMAX_PATH];
|
|
|
|
|
|
|
|
Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname);
|
|
|
|
G_LoadGroupsInDir(buf);
|
|
|
|
}
|
2012-03-28 19:43:39 +00:00
|
|
|
|
|
|
|
////
|
|
|
|
|
|
|
|
// returns a buffer of size BMAX_PATH
|
|
|
|
char *dup_filename(const char *fn)
|
|
|
|
{
|
2014-05-30 00:02:19 +00:00
|
|
|
char *buf = (char *)Xmalloc(BMAX_PATH);
|
2012-03-28 19:43:39 +00:00
|
|
|
|
|
|
|
return Bstrncpyz(buf, fn, BMAX_PATH);
|
|
|
|
}
|
2012-09-08 22:18:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Copy FN to WBUF and append an extension if it's not there, which is checked
|
|
|
|
// case-insensitively.
|
|
|
|
// Returns: 1 if not all characters could be written to WBUF, 0 else.
|
|
|
|
int32_t maybe_append_ext(char *wbuf, int32_t wbufsiz, const char *fn, const char *ext)
|
|
|
|
{
|
|
|
|
const int32_t slen=Bstrlen(fn), extslen=Bstrlen(ext);
|
|
|
|
const int32_t haveext = (slen>=extslen && Bstrcasecmp(&fn[slen-extslen], ext)==0);
|
|
|
|
|
|
|
|
Bassert((intptr_t)wbuf != (intptr_t)fn); // no aliasing
|
|
|
|
|
|
|
|
// If 'fn' has no extension suffixed, append one.
|
|
|
|
return (Bsnprintf(wbuf, wbufsiz, "%s%s", fn, haveext ? "" : ext) >= wbufsiz);
|
|
|
|
}
|
2012-11-29 12:49:38 +00:00
|
|
|
|
|
|
|
|
2013-02-16 18:53:15 +00:00
|
|
|
// Approximations to 2D and 3D Euclidean distances. Initial EDuke32 SVN import says
|
2012-11-29 12:49:38 +00:00
|
|
|
// in jmact/mathutil.c: "Ken's reverse-engineering job".
|
|
|
|
// Note that jmact/mathutil.c contains practically the same code, but where the
|
|
|
|
// individual x/y(/z) distances are passed instead.
|
|
|
|
int32_t ldist(const spritetype *s1, const spritetype *s2)
|
|
|
|
{
|
|
|
|
int32_t x = klabs(s1->x-s2->x);
|
|
|
|
int32_t y = klabs(s1->y-s2->y);
|
|
|
|
|
|
|
|
if (x<y) swaplong(&x,&y);
|
|
|
|
|
|
|
|
{
|
|
|
|
int32_t t = y + (y>>1);
|
|
|
|
return (x - (x>>5) - (x>>7) + (t>>2) + (t>>6));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t dist(const spritetype *s1, const spritetype *s2)
|
|
|
|
{
|
|
|
|
int32_t x = klabs(s1->x-s2->x);
|
|
|
|
int32_t y = klabs(s1->y-s2->y);
|
|
|
|
int32_t z = klabs((s1->z-s2->z)>>4);
|
|
|
|
|
|
|
|
if (x<y) swaplong(&x,&y);
|
|
|
|
if (x<z) swaplong(&x,&z);
|
|
|
|
|
|
|
|
{
|
|
|
|
int32_t t = y + z;
|
|
|
|
return (x - (x>>4) + (t>>2) + (t>>3));
|
|
|
|
}
|
|
|
|
}
|
2012-12-25 16:13:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Clear OSD background
|
|
|
|
void COMMON_clearbackground(int32_t numcols, int32_t numrows)
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(numcols);
|
|
|
|
|
|
|
|
# ifdef USE_OPENGL
|
2013-05-17 03:44:09 +00:00
|
|
|
if (getrendermode() >= REND_POLYMOST && qsetmode==200)
|
2012-12-25 16:13:50 +00:00
|
|
|
{
|
2014-03-30 20:35:57 +00:00
|
|
|
bglPushAttrib(GL_FOG_BIT);
|
|
|
|
bglDisable(GL_FOG);
|
|
|
|
|
2012-12-25 16:13:50 +00:00
|
|
|
setpolymost2dview();
|
|
|
|
bglColor4f(0,0,0,0.67f);
|
|
|
|
bglEnable(GL_BLEND);
|
|
|
|
bglRectd(0,0, xdim,8*numrows+8);
|
|
|
|
bglColor4f(0,0,0,1);
|
|
|
|
bglRectd(0,8*numrows+4, xdim,8*numrows+8);
|
2014-03-30 20:35:57 +00:00
|
|
|
|
|
|
|
bglPopAttrib();
|
|
|
|
|
2012-12-25 16:13:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
|
|
|
CLEARLINES2D(0, min(ydim, numrows*8+8), editorcolors[16]);
|
|
|
|
}
|