diff --git a/src/p_setup.c b/src/p_setup.c index c4b4a35b3..3e327a549 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3419,13 +3419,13 @@ typedef enum { } nodetype_t; // Find out the BSP format. -static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) +static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata, char signature[4 + 1]) { boolean supported[NUMNODETYPES] = {0}; nodetype_t nodetype = NT_UNSUPPORTED; - char signature[4 + 1]; *nodedata = NULL; + signature[0] = signature[4] = '\0'; if (udmf) { @@ -3434,7 +3434,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) if (virtznodes && virtznodes->size) { *nodedata = virtznodes->data; - supported[NT_XGLN] = supported[NT_XGL3] = true; + supported[NT_XGLN] = supported[NT_XGL2] = supported[NT_XGL3] = true; } } else @@ -3456,9 +3456,9 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) virtssectors = vres_Find(virt, "SSECTORS"); if (virtssectors && virtssectors->size) - { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. + { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump (it is confusing, yeah), and has a signature. *nodedata = virtssectors->data; - supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true; + supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL2] = supported[NT_XGL3] = true; } else { // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. @@ -3478,19 +3478,42 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) } M_Memcpy(signature, *nodedata, 4); - signature[4] = '\0'; (*nodedata) += 4; - if (!strcmp(signature, "XNOD")) - nodetype = NT_XNOD; - else if (!strcmp(signature, "ZNOD")) - nodetype = NT_ZNOD; - else if (!strcmp(signature, "XGLN")) - nodetype = NT_XGLN; - else if (!strcmp(signature, "ZGLN")) - nodetype = NT_ZGLN; - else if (!strcmp(signature, "XGL3")) - nodetype = NT_XGL3; + // Identify node format from its starting signature. + if (memcmp(&signature[1], "NOD", 3) == 0) // ZDoom extended nodes + { + if (signature[0] == 'X') + { + nodetype = NT_XNOD; // Uncompressed + } + else if (signature[0] == 'Z') + { + nodetype = NT_ZNOD; // Compressed + } + } + else if (memcmp(&signature[1], "GL", 2) == 0) // GL nodes + { + switch (signature[0]) + { + case 'X': // Uncompressed + switch (signature[3]) + { + case 'N': nodetype = NT_XGLN; break; // GL nodes + case '2': nodetype = NT_XGL2; break; // Version 2 GL nodes + case '3': nodetype = NT_XGL3; break; // Version 3 GL nodes + } + break; + case 'Z': // Compressed + switch (signature[3]) + { + case 'N': nodetype = NT_ZGLN; break; // GL nodes (compressed) + case '2': nodetype = NT_ZGL2; break; // Version 2 GL nodes (compressed) + case '3': nodetype = NT_ZGL3; break; // Version 3 GL nodes (compressed) + } + break; + } + } return supported[nodetype] ? nodetype : NT_UNSUPPORTED; } @@ -3560,6 +3583,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype switch (nodetype) { case NT_XGLN: + case NT_XGL2: case NT_XGL3: for (m = 0; m < (size_t)subsectors[i].numlines; m++, k++) { @@ -3571,7 +3595,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype READUINT32((*data)); // partner, can be ignored by software renderer - if (nodetype == NT_XGL3) + if (nodetype != NT_XGLN) { UINT32 linenum = READUINT32((*data)); if (linenum != 0xFFFFFFFF && linenum >= numlines) @@ -3682,8 +3706,9 @@ static void P_LoadExtendedNodes(UINT8 **data, nodetype_t nodetype) static void P_LoadMapBSP(const virtres_t *virt) { + char signature[4 + 1]; UINT8 *nodedata = NULL; - nodetype_t nodetype = P_GetNodetype(virt, &nodedata); + nodetype_t nodetype = P_GetNodetype(virt, &nodedata, signature); switch (nodetype) { @@ -3715,6 +3740,7 @@ static void P_LoadMapBSP(const virtres_t *virt) } case NT_XNOD: case NT_XGLN: + case NT_XGL2: case NT_XGL3: if (!P_LoadExtraVertices(&nodedata)) return; @@ -3723,10 +3749,13 @@ static void P_LoadMapBSP(const virtres_t *virt) P_LoadExtendedNodes(&nodedata, nodetype); break; default: - CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); - return; + if (isprint(signature[0]) && isprint(signature[1]) && isprint(signature[2]) && isprint(signature[3])) + { + I_Error("Unsupported BSP format '%s' detected!\n", signature); + return; + } + I_Error("Unknown BSP format detected!\n"); } - return; } // Split from P_LoadBlockMap for convenience