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
d05e781467
commit
7c0088b752
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