//===================================================================================== // CreateAreas //===================================================================================== geBoolean CreateAreas(GBSP_Node *RootNode) { GBSP_Model *pModel; int32 m; GHook.Printf(" --- Create Area Leafs --- \n"); // Clear all model area info for (pModel = BSPModels+1, m=1; m < NumBSPModels; m++, pModel++) // Skip world model { pModel->Areas[0] = pModel->Areas[1] = 0; pModel->IsAreaPortal = GE_FALSE; } if (GFXAreas) geRam_Free(GFXAreas); if (GFXAreaPortals) geRam_Free(GFXAreaPortals); GFXAreas = GE_RAM_ALLOCATE_ARRAY(GFX_Area, MAX_AREAS); if (!GFXAreas) return GE_FALSE; GFXAreaPortals = GE_RAM_ALLOCATE_ARRAY(GFX_AreaPortal, MAX_AREA_PORTALS); if (!GFXAreaPortals) return GE_FALSE; NumGFXAreas = 1; // 0 is invalid NumGFXAreaPortals = 0; if (!CreateAreas_r(RootNode)) { GHook.Error("Could not create model areas.\n"); return GE_FALSE; } if (!FinishAreaPortals_r(RootNode)) { GHook.Error("CreateAreas: FinishAreaPortals_r failed.\n"); return GE_FALSE; } if (!FinishAreas()) { GHook.Error("Could not finalize model areas.\n"); return GE_FALSE; } //GHook.Printf("Num Areas : %5i\n", NumGFXAreas-1); return GE_TRUE; }
//===================================================================================== // FinalizeFace //===================================================================================== geBoolean FinalizeFace(GBSP_Face *Face, int32 Base) { int32 i; TotalIndexVerts += NumTempIndexVerts; if (NumTempIndexVerts == Face->NumIndexVerts) return GE_TRUE; if (TexInfo[Face->TexInfo].Flags & TEXINFO_MIRROR) return GE_TRUE; if (TexInfo[Face->TexInfo].Flags & TEXINFO_SKY) return GE_TRUE; if (Face->IndexVerts) geRam_Free(Face->IndexVerts); Face->IndexVerts = GE_RAM_ALLOCATE_ARRAY(int32,NumTempIndexVerts); for (i=0; i< NumTempIndexVerts; i++) Face->IndexVerts[i] = TempIndexVerts[(i+Base)%NumTempIndexVerts]; Face->NumIndexVerts = NumTempIndexVerts; NumFixedFaces++; return GE_TRUE; }
//===================================================================================== // GetFaceVertIndexNumbers //===================================================================================== geBoolean GetFaceVertIndexNumbers(GBSP_Face *Face) { int32 i, Index; geVec3d *Verts; NumTempIndexVerts = 0; Verts = Face->Poly->Verts; for (i=0; i< Face->Poly->NumVerts; i++) { if (NumTempIndexVerts >= MAX_TEMP_INDEX_VERTS) { GHook.Error("GetFaceVertIndexNumbers: Max Temp Index Verts.\n"); return GE_FALSE; } Index = WeldVert(&Verts[i]); if (Index == -1) { GHook.Error("GetFaceVertIndexNumbers: Could not FindVert.\n"); return GE_FALSE; } TempIndexVerts[NumTempIndexVerts] = Index; NumTempIndexVerts++; TotalIndexVerts++; } Face->NumIndexVerts = NumTempIndexVerts; Face->IndexVerts = GE_RAM_ALLOCATE_ARRAY(int32,NumTempIndexVerts); if (!Face->IndexVerts) { GHook.Error("GetFaceVertIndexNumbers: Out of memory for index list.\n"); return GE_FALSE; } for (i=0; i < NumTempIndexVerts; i++) Face->IndexVerts[i] = TempIndexVerts[i]; return GE_TRUE; }
//======================================================================================== // ReadChunk //======================================================================================== static geBoolean ReadChunk(GBSP_BSPData *BSP, GBSP_Chunk *Chunk, geVFile *f) { int i; if (geVFile_Read(f, Chunk, sizeof(GBSP_Chunk)) == GE_FALSE) { return GE_FALSE; } switch(Chunk->Type) { case GBSP_CHUNK_HEADER: { // printf("GBSP_CHUNK_HEADER\n"); if (sizeof(GBSP_Header) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } if (!ReadChunkData(Chunk, (void*)&BSP->GBSPHeader, f)) return GE_FALSE; if (strcmp(BSP->GBSPHeader.TAG, "GBSP")) { geErrorLog_Add(GE_ERR_INVALID_BSP_TAG, NULL); return GE_FALSE; } if (BSP->GBSPHeader.Version != GBSP_VERSION) { geErrorLog_Add(GE_ERR_INVALID_BSP_VERSION, NULL); return GE_FALSE; } break; } case GBSP_CHUNK_MODELS: { // printf("GBSP_CHUNK_MODELS\n"); if (sizeof(GFX_Model) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXModels = Chunk->Elements; BSP->GFXModels = GE_RAM_ALLOCATE_ARRAY(GFX_Model, BSP->NumGFXModels); if (!ReadChunkData(Chunk, (void*)BSP->GFXModels, f)) return GE_FALSE; // Walk the models and zero out the motion pointers for (i = 0; i < BSP->NumGFXModels; i++) BSP->GFXModels[i].Motion = NULL; break; } case GBSP_CHUNK_NODES: { // printf("GBSP_CHUNK_NODES\n"); if (sizeof(GFX_Node) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXNodes = Chunk->Elements; BSP->GFXNodes = (GFX_Node*)geRam_Allocate(sizeof(GFX_Node)*BSP->NumGFXNodes); if (!ReadChunkData(Chunk, (void*)BSP->GFXNodes, f)) return GE_FALSE; break; } case GBSP_CHUNK_BNODES: { // printf("GBSP_CHUNK_BNODES\n"); if (sizeof(GFX_BNode) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXBNodes = Chunk->Elements; if (BSP->NumGFXBNodes) { BSP->GFXBNodes = (GFX_BNode*)geRam_Allocate(sizeof(GFX_BNode)*BSP->NumGFXBNodes); if (!ReadChunkData(Chunk, (void*)BSP->GFXBNodes, f)) return GE_FALSE; } break; } case GBSP_CHUNK_LEAFS: { // printf("GBSP_CHUNK_LEAFS\n"); if (sizeof(GFX_Leaf) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLeafs = Chunk->Elements; BSP->GFXLeafs = (GFX_Leaf*)geRam_Allocate(sizeof(GFX_Leaf)*BSP->NumGFXLeafs); if (!ReadChunkData(Chunk, (void*)BSP->GFXLeafs, f)) return GE_FALSE; break; } case GBSP_CHUNK_CLUSTERS: { // printf("GBSP_CHUNK_CLUSTERS\n"); if (sizeof(GFX_Cluster) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXClusters = Chunk->Elements; //BSP->GFXClusters = GE_RAM_ALLOCATE_ARRAY(GFX_Cluster, BSP->NumGFXClusters); BSP->GFXClusters = (GFX_Cluster*)geRam_Allocate(sizeof(GFX_Cluster)*BSP->NumGFXClusters); if (!ReadChunkData(Chunk, (void*)BSP->GFXClusters, f)) return GE_FALSE; break; } case GBSP_CHUNK_AREAS: { // printf("GBSP_CHUNK_AREAS\n"); if (sizeof(GFX_Area) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXAreas = Chunk->Elements; BSP->GFXAreas = GE_RAM_ALLOCATE_ARRAY(GFX_Area, BSP->NumGFXAreas); if (!ReadChunkData(Chunk, BSP->GFXAreas, f)) return GE_FALSE; break; } case GBSP_CHUNK_AREA_PORTALS: { // printf("GBSP_CHUNK_AREA_PORTALS\n"); if (sizeof(GFX_AreaPortal) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXAreaPortals = Chunk->Elements; BSP->GFXAreaPortals = GE_RAM_ALLOCATE_ARRAY(GFX_AreaPortal, BSP->NumGFXAreaPortals); if (!ReadChunkData(Chunk, BSP->GFXAreaPortals, f)) return GE_FALSE; break; } case GBSP_CHUNK_PORTALS: { // printf("GBSP_CHUNK_PORTALS\n"); if (sizeof(GFX_Portal) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXPortals = Chunk->Elements; BSP->GFXPortals = (GFX_Portal*)geRam_Allocate(sizeof(GFX_Portal)*BSP->NumGFXPortals); if (!ReadChunkData(Chunk, (void*)BSP->GFXPortals, f)) return GE_FALSE; break; } case GBSP_CHUNK_PLANES: { // printf("GBSP_CHUNK_PLANES\n"); if (sizeof(GFX_Plane) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXPlanes = Chunk->Elements; BSP->GFXPlanes = (GFX_Plane*)geRam_Allocate(sizeof(GFX_Plane)*BSP->NumGFXPlanes); if (!ReadChunkData(Chunk, (void*)BSP->GFXPlanes, f)) return GE_FALSE; break; } case GBSP_CHUNK_FACES: { // printf("GBSP_CHUNK_FACES\n"); if (sizeof(GFX_Face) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXFaces = Chunk->Elements; BSP->GFXFaces = (GFX_Face*)geRam_Allocate(sizeof(GFX_Face)*BSP->NumGFXFaces); if (!ReadChunkData(Chunk, (void*)BSP->GFXFaces, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAF_FACES: { // printf("GBSP_CHUNK_LEAF_FACES\n"); if (sizeof(int32) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLeafFaces = Chunk->Elements; BSP->GFXLeafFaces = (int32*)geRam_Allocate(sizeof(int32)*BSP->NumGFXLeafFaces); if (!ReadChunkData(Chunk, (void*)BSP->GFXLeafFaces, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAF_SIDES: { // printf("GBSP_CHUNK_LEAF_SIDES\n"); if (sizeof(GFX_LeafSide) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLeafSides = Chunk->Elements; BSP->GFXLeafSides = (GFX_LeafSide*)geRam_Allocate(sizeof(GFX_LeafSide)*BSP->NumGFXLeafSides); if (!ReadChunkData(Chunk, (void*)BSP->GFXLeafSides, f)) return GE_FALSE; break; } case GBSP_CHUNK_VERTS: { // printf("GBSP_CHUNK_VERTS\n"); if (sizeof(geVec3d) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXVerts = Chunk->Elements; BSP->GFXVerts = (geVec3d*)geRam_Allocate(sizeof(geVec3d)*BSP->NumGFXVerts); if (!ReadChunkData(Chunk, (void*)BSP->GFXVerts, f)) return GE_FALSE; break; } case GBSP_CHUNK_VERT_INDEX: { // printf("GBSP_CHUNK_VERT_INDEX\n"); if (sizeof(int32) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXVertIndexList = Chunk->Elements; BSP->GFXVertIndexList = (int32*)geRam_Allocate(sizeof(int32)*BSP->NumGFXVertIndexList); if (!ReadChunkData(Chunk, (void*)BSP->GFXVertIndexList, f)) return GE_FALSE; break; } case GBSP_CHUNK_RGB_VERTS: { // printf("GBSP_CHUNK_RGB_VERTS\n"); if (sizeof(geVec3d) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXRGBVerts = Chunk->Elements; BSP->GFXRGBVerts = (geVec3d*)geRam_Allocate(sizeof(geVec3d)*BSP->NumGFXRGBVerts); if (!ReadChunkData(Chunk, (void*)BSP->GFXRGBVerts, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXINFO: { // printf("GBSP_CHUNK_TEXINFO\n"); if (sizeof(GFX_TexInfo) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXTexInfo = Chunk->Elements; BSP->GFXTexInfo = (GFX_TexInfo*)geRam_Allocate(sizeof(GFX_TexInfo)*BSP->NumGFXTexInfo); if (!ReadChunkData(Chunk, (void*)BSP->GFXTexInfo, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXTURES: { // printf("GBSP_CHUNK_TEXTURES\n"); if (sizeof(GFX_Texture) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXTextures = Chunk->Elements; BSP->GFXTextures = (GFX_Texture*)geRam_Allocate(sizeof(GFX_Texture)*BSP->NumGFXTextures); if (!ReadChunkData(Chunk, (void*)BSP->GFXTextures, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXDATA: { // printf("GBSP_CHUNK_TEXDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXTexData = Chunk->Elements; BSP->GFXTexData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXTexData); if (!ReadChunkData(Chunk, (void*)BSP->GFXTexData, f)) return GE_FALSE; break; } case GBSP_CHUNK_ENTDATA: { // printf("GBSP_CHUNK_ENTDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXEntData = Chunk->Elements; BSP->GFXEntData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXEntData); if (!ReadChunkData(Chunk, (void*)BSP->GFXEntData, f)) return GE_FALSE; break; } case GBSP_CHUNK_LIGHTDATA: { // printf("GBSP_CHUNK_LIGHTDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXLightData = Chunk->Elements; BSP->GFXLightData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXLightData); if (!ReadChunkData(Chunk, (void*)BSP->GFXLightData, f)) return GE_FALSE; break; } case GBSP_CHUNK_VISDATA: { // printf("GBSP_CHUNK_VISDATA\n"); if (sizeof(uint8) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXVisData = Chunk->Elements; BSP->GFXVisData = (uint8*)geRam_Allocate(sizeof(uint8)*BSP->NumGFXVisData); if (!ReadChunkData(Chunk, (void*)BSP->GFXVisData, f)) return GE_FALSE; break; } case GBSP_CHUNK_SKYDATA: { // printf("GBSP_CHUNK_SKYDATA\n"); if (sizeof(GFX_SkyData) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } if (!ReadChunkData(Chunk, (void*)&BSP->GFXSkyData, f)) return GE_FALSE; break; } case GBSP_CHUNK_PALETTES: { // printf("GBSP_CHUNK_PALETTES\n"); if (sizeof(DRV_Palette) != Chunk->Size) { geErrorLog_Add(GE_ERR_BAD_BSP_FILE_CHUNK_SIZE, NULL); return GE_FALSE; } BSP->NumGFXPalettes = Chunk->Elements; BSP->GFXPalettes = (DRV_Palette*)geRam_Allocate(sizeof(DRV_Palette)*BSP->NumGFXPalettes); if (BSP->GFXPalettes == NULL) return GE_FALSE; if (!ReadChunkData(Chunk, (void*)BSP->GFXPalettes, f)) return GE_FALSE; break; } case GBSP_CHUNK_MOTIONS: { // printf("GBSP_CHUNK_MOTIONS\n"); return LoadMotions(BSP, f); } case GBSP_CHUNK_END: { // printf("GBSP_CHUNK_END\n"); break; } default: // printf("Don't know what this chunk is\n"); return GE_FALSE; } return TRUE; }
//===================================================================================== // Vis_WorldInit //===================================================================================== geBoolean Vis_WorldInit(geWorld *World) { World_BSP *BSP; int32 i; static int32 StartupParams[]={0x696C6345,0x21657370}; assert(World != NULL); BSP = World->CurrentBSP; assert(BSP != NULL); if (!BSP) return GE_FALSE; BSP->NodeVisFrame = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXNodes); if (!BSP->NodeVisFrame) goto Error; BSP->ClusterVisFrame = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXClusters); if (!BSP->ClusterVisFrame) goto Error; BSP->AreaVisFrame = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXAreas); if (!BSP->AreaVisFrame) goto Error; BSP->NodeParents = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXNodes); if (!BSP->NodeParents) goto Error; memset(BSP->NodeVisFrame, 0, sizeof(int32)*BSP->BSPData.NumGFXNodes); memset(BSP->ClusterVisFrame, 0, sizeof(int32)*BSP->BSPData.NumGFXClusters); memset(BSP->AreaVisFrame, 0, sizeof(int32)*BSP->BSPData.NumGFXAreas); memset(BSP->NodeParents, 0, sizeof(int32)*BSP->BSPData.NumGFXNodes); FindParents(World->CurrentBSP); // Set the identity on the AreaMatrix for (i=0; i<256; i++) World->CurrentBSP->AreaConnections[i][i] = 1; return GE_TRUE; Error: if (BSP->NodeVisFrame) geRam_Free(BSP->NodeVisFrame); if (BSP->ClusterVisFrame) geRam_Free(BSP->ClusterVisFrame); if (BSP->AreaVisFrame) geRam_Free(BSP->AreaVisFrame); if (BSP->NodeParents) geRam_Free(BSP->NodeParents); BSP->NodeVisFrame = NULL; BSP->ClusterVisFrame = NULL; BSP->AreaVisFrame = NULL; BSP->NodeParents = NULL; return GE_FALSE; }
//======================================================================================== // ReadChunk //======================================================================================== geBoolean ReadChunk(GBSP_Chunk *Chunk, geVFile *f) { if (geVFile_Read(f, Chunk, sizeof(GBSP_Chunk)) != GE_TRUE) { return GE_FALSE; } #ifdef DEBUGCHUNKS if (Chunk->Type != GBSP_CHUNK_END) { long Pos; geVFile_Tell(f, &Pos); GHook.Printf(" ReadChunk: @%08x '%s', %d elements of %d size\n", Pos, ChunkNames[Chunk->Type], Chunk->Elements, Chunk->Size); } else { long Pos; geVFile_Tell(f, &Pos); GHook.Printf(" ReadChunk: @%08x 'GBSP_CHUNK_END', %d elements of %d size\n", Pos, Chunk->Elements, Chunk->Size); } #endif switch(Chunk->Type) { case GBSP_CHUNK_HEADER: { if (!ReadChunkData(Chunk, (void*)&GBSPHeader, f)) return GE_FALSE; if (strcmp(GBSPHeader.TAG, "GBSP")) return GE_FALSE; if (GBSPHeader.Version != GBSP_VERSION) return GE_FALSE; break; } case GBSP_CHUNK_MODELS: { NumGFXModels = Chunk->Elements; GFXModels = GE_RAM_ALLOCATE_ARRAY(GFX_Model, NumGFXModels); if (!ReadChunkData(Chunk, GFXModels, f)) return GE_FALSE; break; } case GBSP_CHUNK_NODES: { NumGFXNodes = Chunk->Elements; GFXNodes = GE_RAM_ALLOCATE_ARRAY(GFX_Node,NumGFXNodes); if (!ReadChunkData(Chunk, GFXNodes, f)) return GE_FALSE; break; } case GBSP_CHUNK_BNODES: { NumGFXBNodes = Chunk->Elements; GFXBNodes = GE_RAM_ALLOCATE_ARRAY(GFX_BNode,NumGFXBNodes); if (!ReadChunkData(Chunk, GFXBNodes, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAFS: { NumGFXLeafs = Chunk->Elements; GFXLeafs = GE_RAM_ALLOCATE_ARRAY(GFX_Leaf,NumGFXLeafs); if (!ReadChunkData(Chunk, GFXLeafs, f)) return GE_FALSE; break; } case GBSP_CHUNK_CLUSTERS: { NumGFXClusters = Chunk->Elements; GFXClusters = GE_RAM_ALLOCATE_ARRAY(GFX_Cluster,NumGFXClusters); if (!ReadChunkData(Chunk, GFXClusters, f)) return GE_FALSE; break; } case GBSP_CHUNK_AREAS: { NumGFXAreas = Chunk->Elements; GFXAreas = GE_RAM_ALLOCATE_ARRAY(GFX_Area,NumGFXAreas); if (!ReadChunkData(Chunk, GFXAreas, f)) return GE_FALSE; break; } case GBSP_CHUNK_AREA_PORTALS: { NumGFXAreaPortals = Chunk->Elements; GFXAreaPortals = GE_RAM_ALLOCATE_ARRAY(GFX_AreaPortal,NumGFXAreaPortals); if (!ReadChunkData(Chunk, GFXAreaPortals, f)) return GE_FALSE; break; } case GBSP_CHUNK_PORTALS: { NumGFXPortals = Chunk->Elements; GFXPortals = GE_RAM_ALLOCATE_ARRAY(GFX_Portal,NumGFXPortals); if (!ReadChunkData(Chunk, GFXPortals, f)) return GE_FALSE; break; } case GBSP_CHUNK_PLANES: { NumGFXPlanes = Chunk->Elements; GFXPlanes = GE_RAM_ALLOCATE_ARRAY(GFX_Plane,NumGFXPlanes); if (!ReadChunkData(Chunk, GFXPlanes, f)) return GE_FALSE; break; } case GBSP_CHUNK_FACES: { NumGFXFaces = Chunk->Elements; GFXFaces = GE_RAM_ALLOCATE_ARRAY(GFX_Face,NumGFXFaces); if (!ReadChunkData(Chunk, GFXFaces, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAF_FACES: { NumGFXLeafFaces = Chunk->Elements; GFXLeafFaces = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXLeafFaces); if (!ReadChunkData(Chunk, GFXLeafFaces, f)) return GE_FALSE; break; } case GBSP_CHUNK_LEAF_SIDES: { NumGFXLeafSides = Chunk->Elements; GFXLeafSides = GE_RAM_ALLOCATE_ARRAY(GFX_LeafSide,NumGFXLeafSides); if (!ReadChunkData(Chunk, GFXLeafSides, f)) return GE_FALSE; break; } case GBSP_CHUNK_VERTS: { NumGFXVerts = Chunk->Elements; GFXVerts = GE_RAM_ALLOCATE_ARRAY(geVec3d,NumGFXVerts); if (!ReadChunkData(Chunk, GFXVerts, f)) return GE_FALSE; break; } case GBSP_CHUNK_VERT_INDEX: { NumGFXVertIndexList = Chunk->Elements; GFXVertIndexList = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXVertIndexList); if (!ReadChunkData(Chunk, GFXVertIndexList, f)) return GE_FALSE; break; } case GBSP_CHUNK_RGB_VERTS: { NumGFXRGBVerts = Chunk->Elements; GFXRGBVerts = GE_RAM_ALLOCATE_ARRAY(geVec3d,NumGFXRGBVerts); if (!ReadChunkData(Chunk, GFXRGBVerts, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXINFO: { NumGFXTexInfo = Chunk->Elements; GFXTexInfo = GE_RAM_ALLOCATE_ARRAY(GFX_TexInfo,NumGFXTexInfo); if (!ReadChunkData(Chunk, GFXTexInfo, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXTURES: { NumGFXTextures = Chunk->Elements; GFXTextures = GE_RAM_ALLOCATE_ARRAY(GFX_Texture,NumGFXTextures); if (!ReadChunkData(Chunk, GFXTextures, f)) return GE_FALSE; break; } case GBSP_CHUNK_TEXDATA: { // GHook.Printf(" Reading TEXDATA: %d bytes of %d size \n", Chunk->Elements, Chunk->Size); NumGFXTexData = Chunk->Elements; GFXTexData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXTexData); if (!ReadChunkData(Chunk, GFXTexData, f)) return GE_FALSE; break; } case GBSP_CHUNK_ENTDATA: { NumGFXEntData = Chunk->Elements; GFXEntData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXEntData); if (!ReadChunkData(Chunk, GFXEntData, f)) return GE_FALSE; break; } case GBSP_CHUNK_LIGHTDATA: { NumGFXLightData = Chunk->Elements; GFXLightData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXLightData); if (!ReadChunkData(Chunk, GFXLightData, f)) return GE_FALSE; break; } case GBSP_CHUNK_VISDATA: { NumGFXVisData = Chunk->Elements; GFXVisData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXVisData); if (!ReadChunkData(Chunk, GFXVisData, f)) return GE_FALSE; break; } case GBSP_CHUNK_SKYDATA: { if (!ReadChunkData(Chunk, &GFXSkyData, f)) return GE_FALSE; break; } case GBSP_CHUNK_PALETTES: { NumGFXPalettes = Chunk->Elements; GFXPalettes = GE_RAM_ALLOCATE_ARRAY(DRV_Palette,NumGFXPalettes); if (!GFXPalettes) return GE_FALSE; if (!ReadChunkData(Chunk, GFXPalettes, f)) return GE_FALSE; break; } case GBSP_CHUNK_MOTIONS: { // GHook.Printf(" Reading motions: %d Elements of %d size\n", Chunk->Elements, Chunk->Size); NumGFXMotionBytes = Chunk->Elements; GFXMotionData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXMotionBytes); if (!ReadChunkData(Chunk, GFXMotionData, f)) return GE_FALSE; break; } case GBSP_CHUNK_END: { break; } default: return GE_FALSE; } return GE_TRUE; }
//======================================================================================= // LoadPortalFile //======================================================================================= geBoolean LoadPortalFile(char *FileName) { int32 LeafFrom, LeafTo; VIS_Portal *pPortal; VIS_Leaf *pLeaf; GBSP_Poly *pPoly; int32 i, NumVerts; char TAG[13]; geVFile *f; pPoly = NULL; // open the file f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_READONLY); if (!f) // opps { GHook.Error("LoadPortalFile: Could not open %s for reading.\n", FileName); goto ExitWithError; } // // Check the TAG // if (geVFile_Read(f, TAG, sizeof(char) * 12) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading portal file TAG.\n"); goto ExitWithError; } if (strncmp(TAG, "GBSP_PRTFILE", 12)) { GHook.Error("LoadPortalFile: %s is not a GBSP Portal file.\n", FileName); goto ExitWithError; } // // Get the number of portals // if (geVFile_Read(f, &NumVisPortals, sizeof(int32)) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading NumVisPortals.\n"); goto ExitWithError; } if (NumVisPortals >= MAX_TEMP_PORTALS) { GHook.Error("LoadPortalFile: Max portals for temp buffers.\n"); goto ExitWithError; } VisPortals = GE_RAM_ALLOCATE_ARRAY(VIS_Portal,NumVisPortals); if (!VisPortals) { GHook.Error("LoadPortalFile: Out of memory for VisPortals.\n"); goto ExitWithError; } memset(VisPortals, 0, sizeof(VIS_Portal)*NumVisPortals); VisSortedPortals = GE_RAM_ALLOCATE_ARRAY(pVIS_Portal,NumVisPortals); if (!VisSortedPortals) { GHook.Error("LoadPortalFile: Out of memory for VisSortedPortals.\n"); goto ExitWithError; } // // Get the number of leafs // if (geVFile_Read(f, &NumVisLeafs, sizeof(int32)) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading NumVisLeafs.\n"); goto ExitWithError; } if (NumVisLeafs > NumGFXLeafs) goto ExitWithError; VisLeafs = GE_RAM_ALLOCATE_ARRAY(VIS_Leaf,NumVisLeafs); if (!VisLeafs) { GHook.Error("LoadPortalFile: Out of memory for VisLeafs.\n"); goto ExitWithError; } memset(VisLeafs, 0, sizeof(VIS_Leaf)*NumVisLeafs); // // Load in the portals // for (i=0; i< NumVisPortals; i++) { if (geVFile_Read(f, &NumVerts, sizeof(int32)) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading NumVerts.\n"); goto ExitWithError; } pPoly = AllocPoly(NumVerts); if (!pPoly) goto ExitWithError; if (geVFile_Read(f, pPoly->Verts, sizeof(geVec3d) * NumVerts) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading portal vertices.\n"); goto ExitWithError; } if (geVFile_Read(f, &LeafFrom, sizeof(int32)) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading portal LeafFrom.\n"); goto ExitWithError; } if (geVFile_Read(f, &LeafTo, sizeof(int32)) != GE_TRUE) { GHook.Error("LoadPortalFile: Error reading portal LeafTo.\n"); goto ExitWithError; } if (LeafFrom >= NumVisLeafs || LeafFrom < 0) { GHook.Error("LoadPortalFile: Invalid LeafFrom: %i.\n", LeafFrom); goto ExitWithError; } if (LeafTo >= NumVisLeafs || LeafTo < 0) { GHook.Error("LoadPortalFile: Invalid LeafTo: %i.\n", LeafTo); goto ExitWithError; } pLeaf = &VisLeafs[LeafFrom]; pPortal = &VisPortals[i]; pPortal->Poly = pPoly; pPortal->Leaf = LeafTo; PlaneFromVerts(pPoly->Verts, &pPortal->Plane); pPortal->Next = pLeaf->Portals; pLeaf->Portals = pPortal; CalcPortalInfo(pPortal); } NumVisLeafBytes = ((NumVisLeafs+63)&~63) >> 3; NumVisPortalBytes = ((NumVisPortals+63)&~63) >> 3; NumVisPortalLongs = NumVisPortalBytes/sizeof(uint32); NumVisLeafLongs = NumVisLeafBytes/sizeof(uint32); geVFile_Close(f); return GE_TRUE; // ==== ERROR === ExitWithError: { if (f) geVFile_Close(f); if (VisPortals) geRam_Free(VisPortals); if (VisSortedPortals) geRam_Free(VisSortedPortals); if (VisLeafs) geRam_Free(VisLeafs); if (pPoly) FreePoly(pPoly); VisPortals = NULL; VisSortedPortals = NULL; VisLeafs = NULL; pPoly = NULL; return GE_FALSE; } }
//======================================================================================= // VisAllLeafs //======================================================================================= geBoolean VisAllLeafs(void) { int32 i; // Create PortalSeen array. This is used by Vis flooding routines // This is deleted below... PortalSeen = GE_RAM_ALLOCATE_ARRAY(uint8,NumVisPortals); if (!PortalSeen) goto ExitWithError; // Flood all the leafs with the fast method first... for (i=0; i< NumVisLeafs; i++) FloodLeafPortalsFast(i); // Check for cancel request if (CancelRequest) { GHook.Printf("Cancel requested...\n"); goto ExitWithError; } // Sort the portals with MightSee SortPortals(); if (FullVis) if (!FloodPortalsSlow()) return GE_FALSE; // Don't need this anymore... geRam_Free(PortalSeen); PortalSeen = NULL; LeafVisBits = GE_RAM_ALLOCATE_ARRAY(uint8,NumVisLeafs*NumVisLeafBytes); if (!LeafVisBits) { GHook.Error("VisAllLeafs: Out of memory for LeafVisBits.\n"); goto ExitWithError; } memset(LeafVisBits, 0, NumVisLeafs*NumVisLeafBytes); TotalVisibleLeafs = 0; PortalBits = GE_RAM_ALLOCATE_ARRAY(uint8,NumVisPortalBytes); if (!PortalBits) goto ExitWithError; for (i=0; i< NumVisLeafs; i++) { LeafSee = 0; if (!CollectLeafVisBits(i)) goto ExitWithError; TotalVisibleLeafs += LeafSee; } geRam_Free(PortalBits); GHook.Printf("Total visible areas : %5i\n", TotalVisibleLeafs); GHook.Printf("Average visible from each area: %5i\n", TotalVisibleLeafs / NumVisLeafs); return GE_TRUE; // ==== ERROR ==== ExitWithError: { // Free all the global vis data FreeAllVisData(); return GE_FALSE; } }