mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
TERRAIN lump mockup
This commit is contained in:
parent
4ff50fe438
commit
12acd6977b
2 changed files with 436 additions and 0 deletions
366
src/k_terrain.c
Normal file
366
src/k_terrain.c
Normal file
|
|
@ -0,0 +1,366 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2021 by ZDoom + GZDoom teams, and contributors
|
||||||
|
// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour
|
||||||
|
// Copyright (C) 2021 by Kart Krew
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file k_terrain.c
|
||||||
|
/// \brief Implementation of TERRAIN lump from GZDoom codebase for DRRR.
|
||||||
|
|
||||||
|
#include "k_terrain.h"
|
||||||
|
|
||||||
|
#include "z_zone.h"
|
||||||
|
|
||||||
|
t_splash_t *splashDefs = NULL;
|
||||||
|
UINT16 numSplashDefs = 0;
|
||||||
|
|
||||||
|
t_footstep_t *footstepDefs = NULL;
|
||||||
|
UINT16 numFootstepDefs = 0;
|
||||||
|
|
||||||
|
terrain_t *terrainDefs = NULL;
|
||||||
|
UINT16 numTerrainDefs = 0;
|
||||||
|
|
||||||
|
UINT16 defaultTerrain = UINT16_MAX;
|
||||||
|
|
||||||
|
terrain_t *K_GetTerrainByIndex(UINT16 checkIndex)
|
||||||
|
{
|
||||||
|
if (checkIndex >= numTerrainDefs)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return terrainDefs[checkIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
terrain_t *K_GetTerrainByName(const char *checkName)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
if (numTerrainDefs == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search backwards through all terrain definitions.
|
||||||
|
// The latest one will have priority over the older one.
|
||||||
|
for (i = numTerrainDefs-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
terrain_t t = terrainDefs[i];
|
||||||
|
|
||||||
|
if (stricmp(checkName, t->name) == 0)
|
||||||
|
{
|
||||||
|
// Name matches.
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
terrain_t *K_GetDefaultTerrain(void)
|
||||||
|
{
|
||||||
|
return K_GetTerrainByIndex(defaultTerrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
terrain_t *K_GetTerrainForTextureNum(INT32 textureNum)
|
||||||
|
{
|
||||||
|
INT32 i, j;
|
||||||
|
|
||||||
|
if (textureNum == -1)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numTerrainDefs == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search backwards through all terrain definitions.
|
||||||
|
// The latest one will have priority over the older one.
|
||||||
|
|
||||||
|
for (i = numTerrainDefs-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
terrain_t t = terrainDefs[i];
|
||||||
|
|
||||||
|
if (t->numTextureIDs == 0)
|
||||||
|
{
|
||||||
|
// No textures are applied to this terrain type.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < numTextureIDs; j++)
|
||||||
|
{
|
||||||
|
if (textureNum == t->textureIDs[j])
|
||||||
|
{
|
||||||
|
// Texture matches.
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This texture doesn't have a terrain directly applied to it,
|
||||||
|
// so we fallback to the default terrain.
|
||||||
|
return K_GetDefaultTerrain();
|
||||||
|
}
|
||||||
|
|
||||||
|
terrain_t *K_GetTerrainForTextureName(const char *checkName)
|
||||||
|
{
|
||||||
|
return K_GetTerrainForTextureNum( R_CheckTextureNumForName(checkName) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_GrowSplashDefs(void)
|
||||||
|
{
|
||||||
|
numSplashDefs++;
|
||||||
|
splashDefs = (t_splash_t *)Z_Realloc(splashDefs, sizeof(t_splash_t) * (numSplashDefs + 1), PU_STATIC, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_GrowFootstepDefs(void)
|
||||||
|
{
|
||||||
|
numFootstepDefs++;
|
||||||
|
footstepDefs = (t_footstep_t *)Z_Realloc(footstepDefs, sizeof(t_footstep_t) * (numFootstepDefs + 1), PU_STATIC, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_ParseNextLine(char *p, char *token)
|
||||||
|
{
|
||||||
|
// parse next line
|
||||||
|
while (*p != '\0' && *p != '\n')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '\n')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = M_GetToken(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_GrowTerrainDefs(void)
|
||||||
|
{
|
||||||
|
numTerrainDefs++;
|
||||||
|
terrainDefs = (terrain_t *)Z_Realloc(terrainDefs, sizeof(terrain_t) * (numTerrainDefs + 1), PU_STATIC, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_ParseTerrainDefintion(void)
|
||||||
|
{
|
||||||
|
char *token;
|
||||||
|
size_t tokenLength;
|
||||||
|
char *endPos;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
// Startname
|
||||||
|
token = M_GetToken(NULL);
|
||||||
|
|
||||||
|
if (token == NULL)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing TERRAIN lump: Expected terrain definition, got end of file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stricmp(token, "{") != 0)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing TERRAIN lump: No starting bracket");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (token != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
tokenLength = strlen(token);
|
||||||
|
|
||||||
|
if (stricmp(animdefsToken, "OPTIONAL") == 0)
|
||||||
|
{
|
||||||
|
// This is meaningful to ZDoom - it tells the program NOT to bomb out
|
||||||
|
// if the textures can't be found - but it's useless in SRB2, so we'll
|
||||||
|
// just smile, nod, and carry on
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
animdefsToken = M_GetToken(NULL);
|
||||||
|
|
||||||
|
if (animdefsToken == NULL)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where start texture/flat name should be");
|
||||||
|
}
|
||||||
|
else if (stricmp(animdefsToken, "RANGE") == 0)
|
||||||
|
{
|
||||||
|
// Oh. Um. Apparently "OPTIONAL" is a texture name. Naughty.
|
||||||
|
// I should probably handle this more gracefully, but right now
|
||||||
|
// I can't be bothered; especially since ZDoom doesn't handle this
|
||||||
|
// condition at all.
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: \"OPTIONAL\" is a keyword; you cannot use it as the startname of an animation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
animdefsTokenLength = strlen(animdefsToken);
|
||||||
|
if (animdefsTokenLength>8)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for existing animdef
|
||||||
|
for (i = 0; i < maxanims; i++)
|
||||||
|
if (animdefs[i].istexture == istexture // Check if it's the same type!
|
||||||
|
&& stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||||
|
{
|
||||||
|
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
||||||
|
|
||||||
|
// If we weren't parsing in reverse order, we would `break` here and parse the new data into the existing slot we found.
|
||||||
|
// Instead, we're just going to skip parsing the rest of this line entirely.
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found
|
||||||
|
if (i == maxanims)
|
||||||
|
{
|
||||||
|
// Increase the size to make room for the new animation definition
|
||||||
|
GrowAnimDefs();
|
||||||
|
strncpy(animdefs[i].startname, animdefsToken, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// animdefs[i].startname is now set to animdefsToken either way.
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
|
||||||
|
// set texture type
|
||||||
|
animdefs[i].istexture = istexture;
|
||||||
|
|
||||||
|
// "RANGE"
|
||||||
|
animdefsToken = M_GetToken(NULL);
|
||||||
|
if (animdefsToken == NULL)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"RANGE\" after \"%s\"'s startname should be", animdefs[i].startname);
|
||||||
|
}
|
||||||
|
if (stricmp(animdefsToken, "ALLOWDECALS") == 0)
|
||||||
|
{
|
||||||
|
// Another ZDoom keyword, ho-hum. Skip it, move on to the next token.
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
animdefsToken = M_GetToken(NULL);
|
||||||
|
}
|
||||||
|
if (stricmp(animdefsToken, "PIC") == 0)
|
||||||
|
{
|
||||||
|
// This is technically legitimate ANIMDEFS syntax, but SRB2 doesn't support it.
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Animation definitions utilizing \"PIC\" (specific frames instead of a consecutive range) are not supported by SRB2");
|
||||||
|
}
|
||||||
|
if (stricmp(animdefsToken, "RANGE") != 0)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Expected \"RANGE\" after \"%s\"'s startname, got \"%s\"", animdefs[i].startname, animdefsToken);
|
||||||
|
}
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
|
||||||
|
// Endname
|
||||||
|
animdefsToken = M_GetToken(NULL);
|
||||||
|
if (animdefsToken == NULL)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s end texture/flat name should be", animdefs[i].startname);
|
||||||
|
}
|
||||||
|
animdefsTokenLength = strlen(animdefsToken);
|
||||||
|
if (animdefsTokenLength>8)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: lump name \"%s\" exceeds 8 characters", animdefsToken);
|
||||||
|
}
|
||||||
|
strncpy(animdefs[i].endname, animdefsToken, 9);
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
|
||||||
|
// "TICS"
|
||||||
|
animdefsToken = M_GetToken(NULL);
|
||||||
|
if (animdefsToken == NULL)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s \"TICS\" should be", animdefs[i].startname);
|
||||||
|
}
|
||||||
|
if (stricmp(animdefsToken, "RAND") == 0)
|
||||||
|
{
|
||||||
|
// This is technically legitimate ANIMDEFS syntax, but SRB2 doesn't support it.
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Animation definitions utilizing \"RAND\" (random duration per frame) are not supported by SRB2");
|
||||||
|
}
|
||||||
|
if (stricmp(animdefsToken, "TICS") != 0)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Expected \"TICS\" in animation definition for \"%s\", got \"%s\"", animdefs[i].startname, animdefsToken);
|
||||||
|
}
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
|
||||||
|
// Speed
|
||||||
|
animdefsToken = M_GetToken(NULL);
|
||||||
|
if (animdefsToken == NULL)
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Unexpected end of file where \"%s\"'s animation speed should be", animdefs[i].startname);
|
||||||
|
}
|
||||||
|
endPos = NULL;
|
||||||
|
#ifndef AVOID_ERRNO
|
||||||
|
errno = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
animSpeed = strtol(animdefsToken,&endPos,10);
|
||||||
|
|
||||||
|
if (endPos == animdefsToken // Empty string
|
||||||
|
|| *endPos != '\0' // Not end of string
|
||||||
|
#ifndef AVOID_ERRNO
|
||||||
|
|| errno == ERANGE // Number out-of-range
|
||||||
|
#endif
|
||||||
|
|| animSpeed < 0) // Number is not positive
|
||||||
|
{
|
||||||
|
I_Error("Error parsing ANIMDEFS lump: Expected a positive integer for \"%s\"'s animation speed, got \"%s\"", animdefs[i].startname, animdefsToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
animdefs[i].speed = animSpeed;
|
||||||
|
|
||||||
|
Z_Free(animdefsToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_ParseTERRAINLump(INT32 wadNum, UINT16 lumpnum)
|
||||||
|
{
|
||||||
|
char *lump;
|
||||||
|
size_t lumpLength;
|
||||||
|
char *fullText;
|
||||||
|
char *token;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
||||||
|
// need to make a space of memory where I can ensure that it will terminate
|
||||||
|
// correctly. Start by loading the relevant data from the WAD.
|
||||||
|
lump = (char *)W_CacheLumpNumPwad(wadNum, lumpnum, PU_STATIC);
|
||||||
|
|
||||||
|
// If that didn't exist, we have nothing to do here.
|
||||||
|
if (lump == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
||||||
|
lumpLength = W_LumpLengthPwad(wadNum, lumpnum);
|
||||||
|
fullText = (char *)Z_Malloc((lumpLength + 1) * sizeof(char), PU_STATIC, NULL);
|
||||||
|
|
||||||
|
// Now move the contents of the lump into this new location.
|
||||||
|
memmove(fullText, lump, lumpLength);
|
||||||
|
|
||||||
|
// Make damn well sure the last character in our new memory location is \0.
|
||||||
|
fullText[lumpLength] = '\0';
|
||||||
|
|
||||||
|
// Finally, free up the memory from the first data load, because we really
|
||||||
|
// don't need it.
|
||||||
|
Z_Free(lump);
|
||||||
|
|
||||||
|
// Now, let's start parsing this thing
|
||||||
|
p = fullText;
|
||||||
|
token = M_GetToken(p);
|
||||||
|
|
||||||
|
while (token != NULL)
|
||||||
|
{
|
||||||
|
if (stricmp(token, "TERRAIN") == 0)
|
||||||
|
{
|
||||||
|
Z_Free(token);
|
||||||
|
K_ParseTerrainDefintion(&p, &token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_Error("Error parsing TERRAIN lump: Expected \"SPLASH\", \"FOOTSTEP\", \"TERRAIN\", \"FLOOR\"; got \"%s\"", token);
|
||||||
|
}
|
||||||
|
|
||||||
|
K_ParseNextLine(&p, &token);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(token);
|
||||||
|
Z_Free((void *)fullText);
|
||||||
|
}
|
||||||
70
src/k_terrain.h
Normal file
70
src/k_terrain.h
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1998-2021 by ZDoom + GZDoom teams, and contributors
|
||||||
|
// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour
|
||||||
|
// Copyright (C) 2021 by Kart Krew
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file k_terrain.h
|
||||||
|
/// \brief Implementation of a TERRAIN-style lump for DRRR, ala GZDoom's codebase.
|
||||||
|
|
||||||
|
#ifndef __K_TERRAIN_H__
|
||||||
|
#define __K_TERRAIN_H__
|
||||||
|
|
||||||
|
typedef struct t_splash_s
|
||||||
|
{
|
||||||
|
// Splash definition.
|
||||||
|
// These are particles spawned when hitting the floor.
|
||||||
|
|
||||||
|
const char *name; // Lookup name.
|
||||||
|
|
||||||
|
UINT16 objType; // Thing type. MT_NULL to not spawn anything.
|
||||||
|
UINT16 sound; // Sound to play.
|
||||||
|
} t_splash_t;
|
||||||
|
|
||||||
|
typedef struct t_footstep_s
|
||||||
|
{
|
||||||
|
// Footstep definition.
|
||||||
|
// These are particles spawned when moving fast enough on a floor.
|
||||||
|
|
||||||
|
const char *name; // Lookup name.
|
||||||
|
|
||||||
|
UINT16 objType; // Thing type. MT_NULL to not spawn anything.
|
||||||
|
UINT16 sound; // Sound to play.
|
||||||
|
} t_footstep_t;
|
||||||
|
|
||||||
|
typedef struct terrain_s
|
||||||
|
{
|
||||||
|
// Terrain definition.
|
||||||
|
// These are all of the properties that the floor gets.
|
||||||
|
|
||||||
|
const char *name; // Lookup name.
|
||||||
|
|
||||||
|
INT32 *textureIDs; // Texture nums this terrain applies to. (Doesn't support flats, stop using them already.)
|
||||||
|
UINT32 numTextureIDs; // Length of the above table.
|
||||||
|
|
||||||
|
UINT16 splashID; // Splash defintion ID.
|
||||||
|
UINT16 footstepID; // Footstep defintion ID.
|
||||||
|
|
||||||
|
fixed_t friction; // The default friction of this texture.
|
||||||
|
UINT8 offroad; // The default offroad level of this texture.
|
||||||
|
INT16 damageType; // The default damage type of this texture. (Negative means no damage).
|
||||||
|
} terrain_t;
|
||||||
|
|
||||||
|
// Arrays for all terrain definitions.
|
||||||
|
extern t_splash_t *splashDefs;
|
||||||
|
extern UINT16 numSplashDefs;
|
||||||
|
|
||||||
|
extern t_footstep_t *footstepDefs;
|
||||||
|
extern UINT16 numFootstepDefs;
|
||||||
|
|
||||||
|
extern terrain_t *terrainDefs;
|
||||||
|
extern UINT16 numTerrainDefs;
|
||||||
|
|
||||||
|
// Default terrain definition ID.
|
||||||
|
extern UINT16 defaultTerrain;
|
||||||
|
|
||||||
|
#endif // __K_TERRAIN_H__
|
||||||
Loading…
Add table
Reference in a new issue