// DR. ROBOTNIK'S RING RACERS //----------------------------------------------------------------------------- // 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_brightmap.c /// \brief Brightmap texture loading. #include "k_brightmap.h" #include "doomdata.h" #include "doomdef.h" #include "doomtype.h" #include "fastcmp.h" #include "r_textures.h" #include "w_wad.h" #include "z_zone.h" static brightmapStorage_t *brightmapStorage = NULL; static size_t maxBrightmapStorage = 0; /*-------------------------------------------------- static brightmapStorage_t *K_NewBrightmap(void) Increases the size of maxBrightmapStorage by 1. Input Arguments:- None Return:- The new brightmap storage struct. --------------------------------------------------*/ static brightmapStorage_t *K_NewBrightmap(void) { maxBrightmapStorage++; brightmapStorage = (brightmapStorage_t *)Z_Realloc(brightmapStorage, sizeof(brightmapStorage_t) * (maxBrightmapStorage + 1), PU_STATIC, NULL); return &brightmapStorage[ maxBrightmapStorage - 1 ]; } /*-------------------------------------------------- static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex) See header file for description. --------------------------------------------------*/ static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex) { if (checkIndex >= maxBrightmapStorage) { return NULL; } return &brightmapStorage[checkIndex]; } /*-------------------------------------------------- static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName) See header file for description. --------------------------------------------------*/ static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName) { size_t i; if (maxBrightmapStorage == 0) { return NULL; } for (i = 0; i < maxBrightmapStorage; i++) { brightmapStorage_t *bms = &brightmapStorage[i]; if (stricmp(checkName, bms->textureName) == 0) { // Name matches. return bms; } } return NULL; } /*-------------------------------------------------- static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) Parses inputted lump data as a BRIGHT lump. Input Arguments:- data - Pointer to lump data. size - The length of the lump data. Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) { char *tkn = M_GetToken((char *)data); size_t pos = 0; while (tkn && (pos = M_GetTokenPos()) < size) { boolean valid = true; if (stricmp(tkn, "texture") == 0) { Z_Free(tkn); tkn = M_GetToken(NULL); pos = M_GetTokenPos(); if (tkn && pos < size) { brightmapStorage_t *bms = K_GetBrightmapStorageByTextureName(tkn); if (bms == NULL) { bms = K_NewBrightmap(); strncpy(bms->textureName, tkn, 9); } Z_Free(tkn); tkn = M_GetToken(NULL); pos = M_GetTokenPos(); if (tkn && pos < size) { strncpy(bms->brightmapName, tkn, 9); } else { CONS_Alert(CONS_ERROR, "No brightmap for brightmap definition.\n"); valid = false; } } else { CONS_Alert(CONS_ERROR, "No texture for brightmap definition.\n"); valid = false; } } // todo: SPRITE brightmaps?! else { CONS_Alert(CONS_ERROR, "Unknown keyword '%s' found in BRIGHT lump.\n", tkn); valid = false; } Z_Free(tkn); if (valid == false) { return false; } tkn = M_GetToken(NULL); } Z_Free(tkn); return true; } /*-------------------------------------------------- void K_InitBrightmaps(void) See header file for description. --------------------------------------------------*/ void K_InitBrightmaps(void) { INT32 wadNum; size_t i; I_Assert(brightmapStorage == NULL); maxBrightmapStorage = 0; for (wadNum = 0; wadNum < numwadfiles; wadNum++) { UINT16 lumpNum; // Find BRIGHT lump in the WAD lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0); while (lumpNum != INT16_MAX) { UINT8 *data; data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); // If that didn't exist, we have nothing to do here. if (data == NULL) { lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); continue; } else { lumpinfo_t *lump_p = &wadfiles[wadNum]->lumpinfo[lumpNum]; size_t size = W_LumpLengthPwad(wadNum, lumpNum); size_t nameLength = strlen(wadfiles[wadNum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name char *name = malloc(nameLength + 1); sprintf(name, "%s|%s", wadfiles[wadNum]->filename, lump_p->fullname); name[nameLength] = '\0'; size = W_LumpLengthPwad(wadNum, lumpNum); CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name); K_BRIGHTLumpParser(data, size); free(name); } lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); } } if (maxBrightmapStorage == 0) { // No brightmaps were defined. return; } for (i = 0; i < maxBrightmapStorage; i++) { brightmapStorage_t *bms = K_GetBrightmapStorageByIndex(i); INT32 texNum, bmNum; if (bms == NULL) { // Shouldn't happen. break; } texNum = R_CheckTextureNumForName(bms->textureName); if (texNum != -1) { bmNum = R_CheckTextureNumForName(bms->brightmapName); if (bmNum == -1) { texturebrightmaps[texNum] = 0; } else { texturebrightmaps[texNum] = bmNum; } } } R_ClearTextureNumCache(false); // Clear brightmapStorage now that we're done with it. Z_Free(brightmapStorage); brightmapStorage = NULL; }