diff --git a/src/doomdef.h b/src/doomdef.h index 51a15bd64..0d673a426 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -461,6 +461,8 @@ extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); void M_UnGetToken(void); +UINT32 M_GetTokenPos(void); +void M_SetTokenPos(UINT32 newPos); char *sizeu1(size_t num); char *sizeu2(size_t num); char *sizeu3(size_t num); diff --git a/src/m_misc.c b/src/m_misc.c index b0a1fb8c5..edb24ab1e 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1908,6 +1908,20 @@ void M_UnGetToken(void) endPos = oldendPos; } +/** Returns the current token's position. + */ +UINT32 M_GetTokenPos(void) +{ + return endPos; +} + +/** Sets the current token's position. + */ +void M_SetTokenPos(UINT32 newPos) +{ + endPos = newPos; +} + /** Count bits in a number. */ UINT8 M_CountBits(UINT32 num, UINT8 size) diff --git a/src/p_setup.c b/src/p_setup.c index 99da5ccee..c7eb50382 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -83,6 +83,8 @@ #include "p_slopes.h" #endif +#include "fastcmp.h" // textmap parsing + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -1236,10 +1238,367 @@ static void P_LoadThings(UINT8 *data) } } +// Stores positions for relevant map data spread through a TEXTMAP. +UINT32 mapthingsPos[UINT16_MAX]; +UINT32 linesPos[UINT16_MAX]; +UINT32 sidesPos[UINT16_MAX]; +UINT32 vertexesPos[UINT16_MAX]; +UINT32 sectorsPos[UINT16_MAX]; + +static boolean TextmapCount (UINT8 *data, size_t size) +{ + char *nsp1 = M_GetToken((char *)data); + boolean ret = true; + + // Determine total amount of map data in TEXTMAP. + // Look for namespace at the beginning. + if (fastcmp(nsp1, "namespace")) + { + char *nsp2 = M_GetToken(NULL); + char *tkn = M_GetToken(NULL); + + // Check if namespace is valid. + if (!fastcmp(nsp2, "srb2")) + CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", nsp2); + Z_Free(nsp2); + + while (tkn != NULL && M_GetTokenPos() < size) + { + // Avoid anything inside bracketed stuff, only look for external keywords. + // Assuming there's only one level of bracket nesting. + if (fastcmp(tkn, "{")) + { + Z_Free(tkn); + while (!fastcmp(tkn, "}")) + { + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + } + // Check for valid fields. + else if (fastcmp(tkn, "thing")) + mapthingsPos[nummapthings++] = M_GetTokenPos(); + else if (fastcmp(tkn, "linedef")) + linesPos[numlines++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sidedef")) + sidesPos[numsides++] = M_GetTokenPos(); + else if (fastcmp(tkn, "vertex")) + vertexesPos[numvertexes++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sector")) + sectorsPos[numsectors++] = M_GetTokenPos(); + else + CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); + + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + } + else + { + CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + ret = false; + } + + Z_Free(nsp1); + return ret; +} + +static char* dat; + +/** Auxiliary function for TextmapParse. + * + * \param Vertex number. + * \param Parameter string. + */ +static void TextmapVertex(UINT32 i, char *param) +{ + if (fastcmp(param, "x")) + vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "y")) + vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); +} + +/** Auxiliary function for TextmapParse. + * + * \param Sector number. + * \param Parameter string. + */ +static void TextmapSector(UINT32 i, char *param) +{ + if (fastcmp(param, "heightfloor")) + sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + else if (fastcmp(param, "heightceiling")) + sectors[i].ceilingheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + if (fastcmp(param, "texturefloor")) + sectors[i].floorpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + else if (fastcmp(param, "textureceiling")) + sectors[i].ceilingpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + else if (fastcmp(param, "lightlevel")) + sectors[i].lightlevel = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "special")) + sectors[i].special = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "id")) + sectors[i].tag = atol(dat = M_GetToken(NULL)); +} + +/** Auxiliary function for TextmapParse. + * + * \param Side number. + * \param Parameter string. + */ +static void TextmapSide(UINT32 i, char *param) +{ + if (fastcmp(param, "offsetx")) + sides[i].textureoffset = atol(dat = M_GetToken(NULL))<z = 0; + + TextmapParse(vertexesPos[i], i, TextmapVertex); + } + + for (i = 0, sc = sectors; i < numsectors; i++, sc++) + { + // Defaults. + sc->floorheight = 0; + sc->ceilingheight = 0; + + sc->floorpic = 0; + sc->ceilingpic = 0; + + sc->lightlevel = 255; + + sc->special = 0; + sc->tag = 0; + + sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; + sc->floorpic_angle = sc->ceilingpic_angle = 0; + + TextmapParse(sectorsPos[i], i, TextmapSector); + + P_InitializeSector(sc); + } + + for (i = 0, ld = lines; i < numlines; i++, ld++) + { + // Defaults. + ld->tag = 0; + ld->special = 0; + ld->sidenum[1] = 0xffff; + + TextmapParse(linesPos[i], i, TextmapLine); + + P_InitializeLinedef(ld); + } + + for (i = 0, sd = sides; i < numsides; i++, sd++) + { + // Defaults. + sd->rowoffset = 0; + sd->textureoffset = 0; + + sd->toptexture = R_TextureNumForName("-"); + sd->midtexture = R_TextureNumForName("-"); + sd->bottomtexture = R_TextureNumForName("-"); + sd->repeatcnt = 0; + + TextmapParse(sidesPos[i], i, TextmapSide); + } + + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) + { + // Defaults. + mt->z = 0; + mt->angle = 0; + + TextmapParse(mapthingsPos[i], i, TextmapThing); + } +} + +/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. + */ +static void TextmapFixFlatOffsets (void) +{ + fixed_t pc, ps; + fixed_t xoffs, yoffs; + size_t i; + sector_t* sec = sectors; + for (i = 0; i < numsectors; i++, sec++) + { + if (sec->floorpic_angle) + { + pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + xoffs = sec->floor_xoffs; + yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + + if (sec->ceilingpic_angle) + { + pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + xoffs = sec->ceiling_xoffs; + yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + } +} + static void P_LoadMapData(const virtres_t *virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; -#ifdef UDMF virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); // Count map data. @@ -1252,10 +1611,9 @@ static void P_LoadMapData(const virtres_t *virt) numsectors = 0; // Count how many entries for each type we got in textmap. - //TextmapCount(vtextmap->data, vtextmap->size); + TextmapCount(textmap->data, textmap->size); } else -#endif { virtthings = vres_Find(virt, "THINGS"); virtvertexes = vres_Find(virt, "VERTEXES"); @@ -1305,15 +1663,14 @@ static void P_LoadMapData(const virtres_t *virt) numlevelflats = 0; -#ifdef UDMF + // Load map data. if (textmap) { - + P_LoadTextmap(); + TextmapFixFlatOffsets(); } else -#endif { - // Strict map data P_LoadVertices(virtvertexes->data); P_LoadSectors(virtsectors->data); P_LoadLinedefs(virtlinedefs->data); diff --git a/src/w_wad.c b/src/w_wad.c index 62992441a..47c3f42d0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1942,6 +1942,8 @@ void vres_Free(virtres_t* vres) Z_Free(vres->vlumps[vres->numlumps].data); Z_Free(vres->vlumps); Z_Free(vres); + + CONS_Printf("A A A\n"); } /** (Debug) Prints lumps from a virtual resource into console.