New FLOOR_INFO struct; Refactoring rooms part I

This commit is contained in:
Montagna Marco 2020-06-26 07:06:18 +02:00
parent a0279655c5
commit 235dab2f13
29 changed files with 610 additions and 642 deletions

View file

@ -841,7 +841,7 @@ void FixedCamera(ITEM_INFO* item)
if (mesh->staticNumber >= 50 && mesh->staticNumber < 58) if (mesh->staticNumber >= 50 && mesh->staticNumber < 58)
{ {
ShatterObject(0, mesh, 128, to.roomNumber, 0); ShatterObject(0, mesh, 128, to.roomNumber, 0);
mesh->Flags &= ~1; mesh->flags &= ~1;
SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS*)mesh, 0); SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS*)mesh, 0);
} }
TriggerRicochetSpark(&to, 2 * GetRandomControl(), 3, 0); TriggerRicochetSpark(&to, 2 * GetRandomControl(), 3, 0);

View file

@ -60,11 +60,11 @@ int CollideStaticObjects(COLL_INFO* coll, int x, int y, int z, short roomNumber,
for (int i = 0; i < numRooms; i++) for (int i = 0; i < numRooms; i++)
{ {
room = &Rooms[roomList[i]]; room = &Rooms[roomList[i]];
mesh = room->mesh; for (int j = room->mesh.size(); j > 0; j--, mesh++)
for (int j = room->numMeshes; j > 0; j--, mesh++)
{ {
mesh = &room->mesh[j];
StaticInfo* sInfo = &StaticObjects[mesh->staticNumber]; StaticInfo* sInfo = &StaticObjects[mesh->staticNumber];
if ((sInfo->flags & 1)) // No collision if ((sInfo->flags & 1)) // No collision
continue; continue;
@ -136,12 +136,12 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
{ {
room = &Rooms[roomsArray[i]]; room = &Rooms[roomsArray[i]];
for (int j = 0; j < room->numMeshes; j++) for (int j = 0; j < room->mesh.size(); j++)
{ {
MESH_INFO* mesh = &room->mesh[j]; MESH_INFO* mesh = &room->mesh[j];
StaticInfo* staticMesh = &StaticObjects[mesh->staticNumber]; StaticInfo* staticMesh = &StaticObjects[mesh->staticNumber];
if (mesh->Flags & 1) if (mesh->flags & 1)
{ {
if (collidingItem->pos.yPos + radius + STEP_SIZE/2 >= mesh->y + staticMesh->yMinc) if (collidingItem->pos.yPos + radius + STEP_SIZE/2 >= mesh->y + staticMesh->yMinc)
{ {
@ -1384,16 +1384,11 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
short* door, numDoors; short* door, numDoors;
roomsList.push_back(l->roomNumber); roomsList.push_back(l->roomNumber);
door = Rooms[l->roomNumber].door;
if (door) ROOM_INFO room = Rooms[l->roomNumber];
for (int i = 0; i < room.doors.size(); i++)
{ {
numDoors = *door; roomsList.push_back(room.doors[i].room);
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
} }
for (int i = 0; i < roomsList.size(); i++) for (int i = 0; i < roomsList.size(); i++)
@ -1420,12 +1415,11 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
if (coll->enableSpaz) if (coll->enableSpaz)
{ {
MESH_INFO* mesh = Rooms[roomsList[i]].mesh; for (int j = 0; j < Rooms[roomsList[i]].mesh.size(); j++)
int numMeshes = Rooms[roomsList[i]].numMeshes;
for (int j = 0; j < numMeshes; j++)
{ {
if (mesh->Flags & 1) MESH_INFO* mesh = &Rooms[roomsList[i]].mesh[j];
if (mesh->flags & 1)
{ {
int x = l->pos.xPos - mesh->x; int x = l->pos.xPos - mesh->x;
int y = l->pos.yPos - mesh->y; int y = l->pos.yPos - mesh->y;

View file

@ -2145,7 +2145,7 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
SmashedMeshRoom[SmashedMeshCount] = target.roomNumber; SmashedMeshRoom[SmashedMeshCount] = target.roomNumber;
SmashedMesh[SmashedMeshCount] = mesh; SmashedMesh[SmashedMeshCount] = mesh;
++SmashedMeshCount; ++SmashedMeshCount;
mesh->Flags &= ~0x1; mesh->flags &= ~0x1;
SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS *)mesh, 0); SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS *)mesh, 0);
} }
TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0); TriggerRicochetSpark(&target, LaraItem->pos.yRot, 3, 0);
@ -2343,11 +2343,11 @@ int ObjectOnLOS2(GAME_VECTOR *start, GAME_VECTOR *end, PHD_VECTOR *vec, MESH_INF
{ {
room = &Rooms[los_rooms[r]]; room = &Rooms[los_rooms[r]];
for (m = 0; m < room->numMeshes; m++) for (m = 0; m < room->mesh.size(); m++)
{ {
meshp = &room->mesh[m]; meshp = &room->mesh[m];
if (meshp->Flags & 1) if (meshp->flags & 1)
{ {
pos.xPos = meshp->x; pos.xPos = meshp->x;
pos.yPos = meshp->y; pos.yPos = meshp->y;
@ -2896,7 +2896,7 @@ void DoFlipMap(short group)
{ {
ROOM_INFO temp; ROOM_INFO temp;
for (int i = 0; i < NumberRooms; i++) for (int i = 0; i < Rooms.size(); i++)
{ {
ROOM_INFO *r = &Rooms[i]; ROOM_INFO *r = &Rooms[i];

View file

@ -896,67 +896,58 @@ void FillDoorPointers(DOOR_DATA* doorData, ITEM_INFO* item, short roomNumber, in
void GetClosedDoorNormal(ROOM_INFO* room, short** dptr, byte* n, int z, int x, int absX, int absZ) void GetClosedDoorNormal(ROOM_INFO* room, short** dptr, byte* n, int z, int x, int absX, int absZ)
{ {
*dptr = NULL; /**dptr = NULL;
if (room->door) int halfX = x >> 1;
{ int halfZ = z >> 1;
if (room->door > 0)
for (int i = 0; i < room->doors.size(); i++)
{ {
int numDoors = *(room->door); ROOM_DOOR door = room->doors[i];
short* door = &room->door[1];
int halfX = x >> 1; int x1 = halfX + room->x + ((int)door.vertices[0].x + 128) & 0xFFFFFF00;
int halfZ = z >> 1; int x2 = halfX + room->x + ((int)door.vertices[2].x + 128) & 0xFFFFFF00;
for (int i = 0; i < numDoors; i++) if (x1 > x2)
{ {
int x1 = halfX + room->x + (door[4] + 128) & 0xFFFFFF00; int temp = x1;
int x2 = halfX + room->x + (door[10] + 128) & 0xFFFFFF00; x1 = x2;
x2 = temp;
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
}
int z1 = halfZ + room->z + (door[6] + 128) & 0xFFFFFF00;
int z2 = halfZ + room->z + (door[12] + 128) & 0xFFFFFF00;
if (z1 > z2)
{
int temp = z1;
z1 = z2;
z2 = temp;
}
if (absX >= x1 && absX <= x2 && absZ >= z1 && absZ <= z2)
{
*dptr = &door[1];
if (door[1])
{
*n = (byte)door[1] & 0x81 | 1;
}
else if (door[2])
{
*n = (byte)door[2] & 0x82 | 2;
}
else
{
*n = (byte)door[3] & 0x84 | 4;
}
}
door += 16;
} }
}
} int z1 = halfZ + room->z + ((int)door.vertices[0].z + 128) & 0xFFFFFF00;
int z2 = halfZ + room->z + ((int)door.vertices[2].z + 128) & 0xFFFFFF00;
if (z1 > z2)
{
int temp = z1;
z1 = z2;
z2 = temp;
}
if (absX >= x1 && absX <= x2 && absZ >= z1 && absZ <= z2)
{
*dptr = &door[1];
if (door[1])
{
*n = (byte)door[1] & 0x81 | 1;
}
else if (door[2])
{
*n = (byte)door[2] & 0x82 | 2;
}
else
{
*n = (byte)door[3] & 0x84 | 4;
}
}
}*/
} }
void ProcessClosedDoors() void ProcessClosedDoors()
{ {
for (int i = 0; i < 32; i++) /*for (int i = 0; i < 32; i++)
{ {
ITEM_INFO* item = ClosedDoors[i]; ITEM_INFO* item = ClosedDoors[i];
@ -982,7 +973,7 @@ void ProcessClosedDoors()
ItemNewRoom(item - Items, roomNumber); ItemNewRoom(item - Items, roomNumber);
item->inDrawRoom = false; item->inDrawRoom = false;
} }
} }*/
} }
void AssignClosedDoor(ITEM_INFO* item) void AssignClosedDoor(ITEM_INFO* item)

View file

@ -13,7 +13,7 @@ void ClearItem(short itemNum)
item->collidable = true; item->collidable = true;
item->data = NULL; item->data = NULL;
item->drawRoom = (((item->pos.zPos - room->z) >> WALL_SHIFT) & 0xFF) | ((((item->pos.xPos - room->mesh->x) >> WALL_SHIFT) & 0xFF) << 8); item->drawRoom = (((item->pos.zPos - room->z) >> WALL_SHIFT) & 0xFF) | ((((item->pos.xPos - room->x) >> WALL_SHIFT) & 0xFF) << 8);
item->TOSSPAD = item->pos.yRot & 0xE000; item->TOSSPAD = item->pos.yRot & 0xE000;
item->itemFlags[2] = item->roomNumber | ((item->pos.yPos - room->minfloor) & 0xFF00); item->itemFlags[2] = item->roomNumber | ((item->pos.yPos - room->minfloor) & 0xFF00);
} }
@ -475,7 +475,7 @@ short SpawnItem(ITEM_INFO* item, short objectNumber)
int GlobalItemReplace(short search, short replace) int GlobalItemReplace(short search, short replace)
{ {
int changed = 0; int changed = 0;
for (int i = 0; i < NumberRooms; i++) for (int i = 0; i < Rooms.size(); i++)
{ {
ROOM_INFO* room = &Rooms[i]; ROOM_INFO* room = &Rooms[i];
for (short itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = Items[itemNumber].nextItem) for (short itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = Items[itemNumber].nextItem)

View file

@ -708,7 +708,7 @@ void ControlGrenade(short itemNumber)
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber; SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh; SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++; SmashedMeshCount++;
currentMesh->Flags &= ~1; currentMesh->flags &= ~1;
} }
k++; k++;
@ -1214,7 +1214,7 @@ void ControlCrossbowBolt(short itemNumber)
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber; SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh; SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++; SmashedMeshCount++;
currentMesh->Flags &= ~1; currentMesh->flags &= ~1;
} }
k++; k++;

View file

@ -50,72 +50,59 @@ void TargetNearestEntity(ITEM_INFO* item, CREATURE_INFO* creature)
void GetRoomList(short roomNumber, short* roomArray, short* numRooms) void GetRoomList(short roomNumber, short* roomArray, short* numRooms)
{ {
short numDoors, *door, adjoiningRoom; short numDoors, * door, adjoiningRoom;
int i, j; int i, j;
bool adjoiningRoomFound; bool adjoiningRoomFound;
roomArray[0] = roomNumber; roomArray[0] = roomNumber;
door = Rooms[roomNumber].door; ROOM_INFO* room = &Rooms[roomNumber];
if (door)
for (i = 0; i < room->doors.size(); i++)
{ {
numDoors = *door; adjoiningRoom = room->doors[i].room;
door++; adjoiningRoomFound = false;
for (i = 0; i < numDoors; i++) for (j = 0; j < *numRooms; j++)
{ {
adjoiningRoom = *door; if (roomArray[i] == adjoiningRoom)
adjoiningRoomFound = false;
for (j = 0; j < *numRooms; j++)
{ {
if (roomArray[i] == adjoiningRoom) adjoiningRoomFound = true;
{ break;
adjoiningRoomFound = true;
break;
}
} }
if (!adjoiningRoomFound)
roomArray[*(numRooms++)] = adjoiningRoom;
door += 16;
} }
if (!adjoiningRoomFound)
roomArray[*(numRooms++)] = adjoiningRoom;
} }
} }
void GetRoomList(short roomNumber, vector<short>* destRoomList) void GetRoomList(short roomNumber, vector<short>* destRoomList)
{ {
vector<short> roomList; vector<short> roomList;
short numDoors, *door, adjoiningRoom; short adjoiningRoom;
int i, j; int i, j;
bool adjoiningRoomFound; bool adjoiningRoomFound;
roomList.push_back(roomNumber); roomList.push_back(roomNumber);
door = Rooms[roomNumber].door; ROOM_INFO* room = &Rooms[roomNumber];
if (door)
for (i = 0; i < room->doors.size(); i++)
{ {
numDoors = *door; adjoiningRoom = room->doors[i].room;
door++; adjoiningRoomFound = false;
for (i = 0; i < numDoors; i++) for (j = 0; j < roomList.size(); j++)
{ {
adjoiningRoom = *door; if (roomList[i] == adjoiningRoom)
adjoiningRoomFound = false;
for (j = 0; j < roomList.size(); j++)
{ {
if (roomList[i] == adjoiningRoom) adjoiningRoomFound = true;
{ break;
adjoiningRoomFound = true;
break;
}
} }
if (!adjoiningRoomFound)
roomList.push_back(adjoiningRoom);
door += 16;
} }
if (!adjoiningRoomFound)
roomList.push_back(adjoiningRoom);
} }
*destRoomList = roomList; *destRoomList = roomList;

View file

@ -1394,13 +1394,12 @@ void PickupControl(short itemNum)
short* FindPlinth(ITEM_INFO* item) short* FindPlinth(ITEM_INFO* item)
{ {
ROOM_INFO* room = &Rooms[item->roomNumber]; ROOM_INFO* room = &Rooms[item->roomNumber];
MESH_INFO* mesh = room->mesh;
int found = -1; int found = -1;
for (int i = 0; i < room->numMeshes; i++) for (int i = 0; i < room->mesh.size(); i++)
{ {
MESH_INFO* mesh = &room->mesh[i]; MESH_INFO* mesh = &room->mesh[i];
if (mesh->Flags & 1) if (mesh->flags & 1)
{ {
if (item->pos.xPos == mesh->x && item->pos.zPos == mesh->z) if (item->pos.xPos == mesh->x && item->pos.zPos == mesh->z)
{ {

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <framework.h>
typedef struct tr5_room_layer typedef struct tr5_room_layer
{ {
@ -36,6 +37,13 @@ typedef struct tr5_room_vertex
DWORD Colour; // 32-bit colour DWORD Colour; // 32-bit colour
}; };
struct ROOM_DOOR
{
short room;
Vector3 normal;
Vector3 vertices[4];
};
typedef struct tr4_mesh_face3 // 10 bytes typedef struct tr4_mesh_face3 // 10 bytes
{ {
short Vertices[3]; short Vertices[3];
@ -50,7 +58,7 @@ typedef struct tr4_mesh_face4 // 12 bytes
short Effects; short Effects;
}; };
typedef struct tr_room_portal // 32 bytes typedef struct tr_ROOM_DOOR // 32 bytes
{ {
short AdjoiningRoom; // Which room this portal leads to short AdjoiningRoom; // Which room this portal leads to
TR_VERTEX Normal; TR_VERTEX Normal;
@ -67,21 +75,17 @@ typedef struct tr_room_sector // 8 bytes
signed char Ceiling; // Absolute height of ceiling signed char Ceiling; // Absolute height of ceiling
}; };
typedef struct tr5_room_light typedef struct ROOM_LIGHT
{ {
float x, y, z; // Position of light, in world coordinates float x, y, z; // Position of light, in world coordinates
float r, g, b; // Colour of the light float r, g, b; // Colour of the light
int Separator; // Dummy value = 0xCDCDCDCD float in; // Cosine of the IN value for light / size of IN value
float In; // Cosine of the IN value for light / size of IN value float out; // Cosine of the OUT value for light / size of OUT value
float Out; // Cosine of the OUT value for light / size of OUT value float radIn; // (IN radians) * 2
float RadIn; // (IN radians) * 2 float radOut; // (OUT radians) * 2
float RadOut; // (OUT radians) * 2 float range; // Range of light
float Range; // Range of light
float dx, dy, dz; // Direction - used only by sun and spot lights float dx, dy, dz; // Direction - used only by sun and spot lights
int x2, y2, z2; // Same as position, only in integer. byte type;
int dx2, dy2, dz2; // Same as direction, only in integer.
byte LightType;
byte Filler[3]; // Dummy values = 3 x 0xCD
}; };
typedef struct MESH_INFO typedef struct MESH_INFO
@ -91,7 +95,7 @@ typedef struct MESH_INFO
int z; int z;
short yRot; short yRot;
short shade; short shade;
short Flags; short flags;
short staticNumber; short staticNumber;
}; };
@ -115,16 +119,46 @@ typedef struct LIGHTINFO
short Cutoff; // size=0, offset=30 short Cutoff; // size=0, offset=30
}; };
enum SECTOR_SPLIT_TYPE
{
ST_NONE = 0,
ST_SPLIT1 = 1,
ST_SPLIT2 = 2
};
enum SECTOR_NOCOLLISION_TYPE
{
NC_NONE = 0,
NC_TRIANGLE1 = 1,
NC_TRIANGLE2 = 2
};
struct SECTOR_PLANE
{
float a;
float b;
float c;
};
struct SECTOR_COLLISION_INFO
{
int split;
int noCollision;
SECTOR_PLANE planes[2];
};
typedef struct FLOOR_INFO typedef struct FLOOR_INFO
{ {
unsigned short index; int index;
unsigned short fx : 4; int box;
unsigned short box : 11; int fx;
unsigned short stopper : 1; int stopper;
unsigned char pitRoom; int pitRoom;
signed char floor; int floor;
unsigned char skyRoom; int skyRoom;
signed char ceiling; int ceiling;
SECTOR_COLLISION_INFO floorCollision;
SECTOR_COLLISION_INFO ceilingCollision;
}; };
typedef enum RoomEnumFlag typedef enum RoomEnumFlag
@ -143,64 +177,29 @@ typedef enum RoomEnumFlag
typedef struct ROOM_INFO typedef struct ROOM_INFO
{ {
short* data;
short* door;
FLOOR_INFO* floor;
void* something;
MESH_INFO* mesh;
int x; int x;
int y; int y;
int z; int z;
int minfloor; int minfloor;
int maxceiling; int maxceiling;
std::vector<tr5_room_vertex> vertices;
std::vector<tr4_mesh_face4> quads;
std::vector<tr4_mesh_face3> triangles;
std::vector<ROOM_DOOR> doors;
short xSize; short xSize;
short ySize; short ySize;
std::vector<FLOOR_INFO> floor;
CVECTOR ambient; CVECTOR ambient;
short numLights; std::vector<ROOM_LIGHT> lights;
short numMeshes; std::vector<MESH_INFO> mesh;
short flippedRoom;
unsigned short flags;
byte meshEffect;
unsigned char reverbType; unsigned char reverbType;
unsigned char flipNumber; unsigned char flipNumber;
byte meshEffect;
byte boundActive;
short left;
short right;
short top;
short bottom;
short testLeft;
short testRight;
short testTop;
short testBottom;
short itemNumber; short itemNumber;
short fxNumber; short fxNumber;
short flippedRoom; bool boundActive;
unsigned short flags; // ENV_FLAG_enum
unsigned int Unknown1;
unsigned int Unknown2; // Always 0
unsigned int Unknown3; // Always 0
unsigned int Separator; // 0xCDCDCDCD
unsigned short Unknown4;
unsigned short Unknown5;
float RoomX;
float RoomY;
float RoomZ;
unsigned int Separator1[4]; // Always 0xCDCDCDCD
unsigned int Separator2; // 0 for normal rooms and 0xCDCDCDCD for null rooms
unsigned int Separator3; // Always 0xCDCDCDCD
unsigned int NumRoomTriangles;
unsigned int NumRoomRectangles;
tr5_room_light* light; // Always 0
unsigned int LightDataSize;
unsigned int NumLights2; // Always same as NumLights
unsigned int Unknown6;
int RoomYTop;
int RoomYBottom;
unsigned int NumLayers;
tr5_room_layer* LayerOffset;
tr5_room_vertex* VerticesOffset;
void* PolyOffset;
void* PolyOffset2; // Same as PolyOffset
int NumVertices;
int Separator5[4]; // Always 0xCDCDCDCD
}; };
typedef struct ANIM_STRUCT typedef struct ANIM_STRUCT

View file

@ -183,14 +183,11 @@ void SaveGame::saveGameStatus(int arg1, int arg2)
LEB128::Write(m_stream, FlipTimer); LEB128::Write(m_stream, FlipTimer);
LEB128::Write(m_stream, CurrentAtmosphere); LEB128::Write(m_stream, CurrentAtmosphere);
LEB128::Write(m_stream, CurrentSequence); LEB128::Write(m_stream, CurrentSequence);
// Now the sub-chunks // Now the sub-chunks
if (NumberRooms > 0) for (int i = 0; i < Rooms.size(); i++)
{ for (int j = 0; j < Rooms[i].mesh.size(); j++)
for (int i = 0; i < NumberRooms; i++) m_writer->WriteChunk(m_chunkStaticFlags, &saveStaticFlag, i, j);
for (int j = 0; j < Rooms[i].numMeshes; j++)
m_writer->WriteChunk(m_chunkStaticFlags, &saveStaticFlag, i, j);
}
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
m_writer->WriteChunk(m_chunkSequenceSwitch, &saveSequenceSwitch, i, SequenceUsed[i]); m_writer->WriteChunk(m_chunkSequenceSwitch, &saveSequenceSwitch, i, SequenceUsed[i]);
@ -741,7 +738,7 @@ void SaveGame::saveStaticFlag(int arg1, int arg2)
{ {
LEB128::Write(m_stream, arg1); LEB128::Write(m_stream, arg1);
LEB128::Write(m_stream, arg2); LEB128::Write(m_stream, arg2);
LEB128::Write(m_stream, Rooms[arg1].mesh[arg2].Flags); LEB128::Write(m_stream, Rooms[arg1].mesh[arg2].flags);
} }
bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg) bool SaveGame::readLaraChunks(ChunkId* chunkId, int maxSize, int arg)
@ -851,7 +848,7 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
short roomIndex = LEB128::ReadInt16(m_stream); short roomIndex = LEB128::ReadInt16(m_stream);
short staticIndex = LEB128::ReadInt16(m_stream); short staticIndex = LEB128::ReadInt16(m_stream);
short flags = LEB128::ReadInt16(m_stream); short flags = LEB128::ReadInt16(m_stream);
Rooms[roomIndex].mesh[staticIndex].Flags = flags; Rooms[roomIndex].mesh[staticIndex].flags = flags;
if (!flags) if (!flags)
{ {

View file

@ -93,16 +93,10 @@ static void SkidooBaddieCollision(short itemNum, ITEM_INFO* skidoo)
vector<short> roomsList; vector<short> roomsList;
roomsList.push_back(skidoo->roomNumber); roomsList.push_back(skidoo->roomNumber);
short* door = Rooms[skidoo->roomNumber].door; ROOM_INFO* room = &Rooms[skidoo->roomNumber];
if (door) for (int i = 0; i < room->doors.size(); i++)
{ {
short numDoors = *door; roomsList.push_back(room->doors[i].room);
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
} }
for (int i = 0; i < roomsList.size(); i++) for (int i = 0; i < roomsList.size(); i++)

View file

@ -1073,17 +1073,10 @@ static void KayakToBaddieCollision(ITEM_INFO* kayak)
roomsList.push_back(kayak->roomNumber); roomsList.push_back(kayak->roomNumber);
/* -------- get nearby rooms */ ROOM_INFO* room = &Rooms[kayak->roomNumber];
door = Rooms[kayak->roomNumber].door; for (int i = 0; i < room->doors.size(); i++)
if (door)
{ {
numDoors = *door; roomsList.push_back(room->doors[i].room);
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
} }
/* -------- collide with all baddies in these rooms */ /* -------- collide with all baddies in these rooms */

View file

@ -184,16 +184,10 @@ static void CartToBaddieCollision(ITEM_INFO* v)
roomsList.push_back(v->roomNumber); roomsList.push_back(v->roomNumber);
door = Rooms[v->roomNumber].door; ROOM_INFO* room = &Rooms[v->roomNumber];
if (door) for (int i = 0; i < room->doors.size(); i++)
{ {
numDoors = *door; roomsList.push_back(room->doors[i].room);
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
} }
for (int i = 0; i < roomsList.size(); i++) for (int i = 0; i < roomsList.size(); i++)

View file

@ -308,16 +308,10 @@ static void QuadBaddieCollision(ITEM_INFO* quad)
roomsList.push_back(quad->roomNumber); roomsList.push_back(quad->roomNumber);
short* door = Rooms[quad->roomNumber].door; ROOM_INFO* room = &Rooms[quad->roomNumber];
if (door) for (int i = 0; i < room->doors.size(); i++)
{ {
short numDoors = *door; roomsList.push_back(room->doors[i].room);
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
} }
for (int i = 0; i < roomsList.size(); i++) for (int i = 0; i < roomsList.size(); i++)

View file

@ -171,10 +171,10 @@ void KnightTemplarControl(short itemNumber)
if (currentFloor->stopper) if (currentFloor->stopper)
{ {
MESH_INFO* mesh = room->mesh; for (int i = 0; i < room->mesh.size(); i++)
for (int i = 0; i < room->numMeshes; i++)
{ {
MESH_INFO* mesh = &room->mesh[i];
if (floor(pos.x) == floor(mesh->x) && if (floor(pos.x) == floor(mesh->x) &&
floor(pos.z) == floor(mesh->z) && floor(pos.z) == floor(mesh->z) &&
mesh->staticNumber >= 50) mesh->staticNumber >= 50)
@ -182,7 +182,7 @@ void KnightTemplarControl(short itemNumber)
ShatterObject(NULL, mesh, -64, LaraItem->roomNumber, 0); ShatterObject(NULL, mesh, -64, LaraItem->roomNumber, 0);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0); SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);
mesh->Flags &= ~1; mesh->flags &= ~1;
currentFloor->stopper = false; currentFloor->stopper = false;
int height = GetFloorHeight(currentFloor, pos.x, pos.y, pos.z); int height = GetFloorHeight(currentFloor, pos.x, pos.y, pos.z);
TestTriggers(TriggerIndex, 1, 0); TestTriggers(TriggerIndex, 1, 0);

View file

@ -629,21 +629,17 @@ void SkeletonControl(short itemNumber)
FLOOR_INFO* floor = &room->floor[((z - room->z) >> 10) + room->ySize * ((x - room->x) >> 10)]; FLOOR_INFO* floor = &room->floor[((z - room->z) >> 10) + room->ySize * ((x - room->x) >> 10)];
if (floor->stopper) if (floor->stopper)
{ {
MESH_INFO* staticMesh = room->mesh; for (int i = 0; i < room->mesh.size(); i++)
if (room->numMeshes > 0)
{ {
for (int i = 0; i < room->numMeshes; i++) MESH_INFO* staticMesh = &room->mesh[i];
if (abs(pos.x - staticMesh->x) < 1024 && abs(pos.z - staticMesh->z) < 1024 && staticMesh->staticNumber >= 50)
{ {
staticMesh = &room->mesh[i]; ShatterObject(0, staticMesh, -128, LaraItem->roomNumber, 0);
if (abs(pos.x - staticMesh->x) < 1024 && abs(pos.z - staticMesh->z) < 1024 && staticMesh->staticNumber >= 50) SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);
{ staticMesh->flags &= ~1;
ShatterObject(0, staticMesh, -128, LaraItem->roomNumber, 0); floor->stopper = 0;
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0); GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
staticMesh->Flags &= ~1; TestTriggers(TriggerIndex, 1, 0);
floor->stopper = 0;
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
TestTriggers(TriggerIndex, 1, 0);
}
} }
} }
} }

View file

@ -44,7 +44,7 @@ void SphinxControl(short itemNumber)
{ {
ROOM_INFO* room = &Rooms[item->roomNumber]; ROOM_INFO* room = &Rooms[item->roomNumber];
for (int i = 0; i < room->numMeshes; i++) for (int i = 0; i < room->mesh.size(); i++)
{ {
MESH_INFO* mesh = &room->mesh[i]; MESH_INFO* mesh = &room->mesh[i];
@ -53,7 +53,7 @@ void SphinxControl(short itemNumber)
ShatterObject(NULL, mesh, -64, item->roomNumber, 0); ShatterObject(NULL, mesh, -64, item->roomNumber, 0);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0); SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);
mesh->Flags &= ~0x100; mesh->flags &= ~0x100;
floor->stopper = false; floor->stopper = false;
TestTriggers(TriggerIndex, 1, 0); TestTriggers(TriggerIndex, 1, 0);

View file

@ -512,16 +512,10 @@ static void JeepBaddieCollision(ITEM_INFO* jeep)
roomsList.push_back(jeep->roomNumber); roomsList.push_back(jeep->roomNumber);
door = Rooms[jeep->roomNumber].door; ROOM_INFO* room = &Rooms[jeep->roomNumber];
if (door) for (int i = 0; i < room->doors.size(); i++)
{ {
numDoors = *door; roomsList.push_back(room->doors[i].room);
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
} }
for (int i = 0; i < roomsList.size(); i++) for (int i = 0; i < roomsList.size(); i++)

View file

@ -317,7 +317,7 @@ void ControlGladiator(short itemNumber)
floor = &XZ_GET_SECTOR(r, pos.x - r->x, pos.z - r->z); floor = &XZ_GET_SECTOR(r, pos.x - r->x, pos.z - r->z);
if (floor->stopper) if (floor->stopper)
{ {
for (i = 0; i < r->numMeshes; i++) for (i = 0; i < r->mesh.size(); i++)
{ {
mesh = &r->mesh[i]; mesh = &r->mesh[i];
@ -329,7 +329,7 @@ void ControlGladiator(short itemNumber)
{ {
ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0); ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0);
//SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0); //SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0);
mesh->Flags &= 0xFEu; mesh->flags &= 0xFEu;
GetFloorHeight(floor, pos.x, pos.y, pos.z); GetFloorHeight(floor, pos.x, pos.y, pos.z);
TestTriggers(TriggerIndex, 1, 0); TestTriggers(TriggerIndex, 1, 0);
} }

View file

@ -110,7 +110,7 @@ void ControlGunShip(short itemNumber)
if (hitMesh->staticNumber >= 50 && hitMesh->staticNumber < 59) if (hitMesh->staticNumber >= 50 && hitMesh->staticNumber < 59)
{ {
ShatterObject(0, hitMesh, 64, end.roomNumber, 0); ShatterObject(0, hitMesh, 64, end.roomNumber, 0);
hitMesh->Flags &= 0xFFFE; hitMesh->flags &= 0xFFFE;
TestTriggersAtXYZ(hitMesh->x, hitMesh->y, hitMesh->z, end.roomNumber, 1, 0); TestTriggersAtXYZ(hitMesh->x, hitMesh->y, hitMesh->z, end.roomNumber, 1, 0);
SoundEffect(ShatterSounds[CurrentLevel - 5][hitMesh->staticNumber], (PHD_3DPOS*)hitMesh, 0); SoundEffect(ShatterSounds[CurrentLevel - 5][hitMesh->staticNumber], (PHD_3DPOS*)hitMesh, 0);
} }

View file

@ -605,7 +605,7 @@ void RomanStatueControl(short itemNumber)
// If floor is stopped, then try to find static meshes and shatter them, activating heavy triggers below // If floor is stopped, then try to find static meshes and shatter them, activating heavy triggers below
if (floor->stopper) if (floor->stopper)
{ {
for (i = 0; i < room->numMeshes; i++) for (i = 0; i < room->mesh.size(); i++)
{ {
mesh = &room->mesh[i]; mesh = &room->mesh[i];
@ -619,7 +619,7 @@ void RomanStatueControl(short itemNumber)
(PHD_3DPOS*)mesh, (PHD_3DPOS*)mesh,
0); 0);
mesh->Flags &= ~1; mesh->flags &= ~1;
floor->stopper = false; floor->stopper = false;
GetFloorHeight(floor, pos.x, pos.y, pos.z); GetFloorHeight(floor, pos.x, pos.y, pos.z);
TestTriggers(TriggerIndex, 1, 0); TestTriggers(TriggerIndex, 1, 0);

View file

@ -77,7 +77,7 @@ void Renderer11::createBillboardMatrix(Matrix* out, Vector3* particlePos, Vector
void Renderer11::updateAnimatedTextures() void Renderer11::updateAnimatedTextures()
{ {
// Update room's animated textures // Update room's animated textures
for (int i = 0; i < NumberRooms; i++) for (int i = 0; i < Rooms.size(); i++)
{ {
if (m_rooms.size() <= i) continue; if (m_rooms.size() <= i) continue;
RendererRoom & const room = m_rooms[i]; RendererRoom & const room = m_rooms[i];
@ -888,43 +888,32 @@ void Renderer11::getVisibleRooms(int from, int to, Vector4* viewPort, bool water
Vector4 clipPort; Vector4 clipPort;
if (room->door != NULL) for (int i = 0; i < room->doors.size(); i++)
{ {
short numDoors = *(room->door); short adjoiningRoom = room->doors[i].room;
if (numDoors)
if (node->From != adjoiningRoom && checkPortal(node->To, &room->doors[i], viewPort, &node->ClipPort))
{ {
short* door = room->door + 1; RendererRoomNode* childNode = &nodes[nextNode++];
for (int i = 0; i < numDoors; i++) { childNode->From = node->To;
short adjoiningRoom = *(door); childNode->To = adjoiningRoom;
if (node->From != adjoiningRoom && checkPortal(node->To, door, viewPort, &node->ClipPort)) // Push
{ stack[stackDepth++] = childNode;
RendererRoomNode* childNode = &nodes[nextNode++];
childNode->From = node->To;
childNode->To = adjoiningRoom;
// Push
stack[stackDepth++] = childNode;
}
door += 16;
}
} }
} }
} }
} }
bool Renderer11::checkPortal(short roomIndex, short* portal, Vector4* viewPort, Vector4* clipPort) bool Renderer11::checkPortal(short roomIndex, ROOM_DOOR* portal, Vector4* viewPort, Vector4* clipPort)
{ {
ROOM_INFO* room = &Rooms[roomIndex]; ROOM_INFO* room = &Rooms[roomIndex];
portal++; Vector3 n = portal->normal;
Vector3 n = Vector3(portal[0], portal[1], portal[2]);
Vector3 v = Vector3( Vector3 v = Vector3(
Camera.pos.x - (room->x + portal[3]), Camera.pos.x - (room->x + portal->vertices[0].x),
Camera.pos.y - (room->y + portal[4]), Camera.pos.y - (room->y + portal->vertices[0].y),
Camera.pos.z - (room->z + portal[5])); Camera.pos.z - (room->z + portal->vertices[0].z));
// Test camera and normal positions and decide if process door or not // Test camera and normal positions and decide if process door or not
if (n.Dot(v) <= 0.0f) if (n.Dot(v) <= 0.0f)
@ -938,12 +927,10 @@ bool Renderer11::checkPortal(short roomIndex, short* portal, Vector4* viewPort,
clipPort->z = FLT_MIN; clipPort->z = FLT_MIN;
clipPort->w = FLT_MIN; clipPort->w = FLT_MIN;
portal += 3;
// Project all portal's corners in screen space // Project all portal's corners in screen space
for (int i = 0; i < 4; i++, portal += 3) for (int i = 0; i < 4; i++)
{ {
Vector4 tmp = Vector4(portal[0] + room->x, portal[1] + room->y, portal[2] + room->z, 1.0f); Vector4 tmp = Vector4(portal->vertices[i].x + room->x, portal->vertices[i].y + room->y, portal->vertices[i].z + room->z, 1.0f);
// Project corner on screen // Project corner on screen
Vector4::Transform(tmp, ViewProjection, p[i]); Vector4::Transform(tmp, ViewProjection, p[i]);

View file

@ -624,7 +624,7 @@ private:
void buildHierarchyRecursive(RendererObject* obj, RendererBone* node, RendererBone* parentNode); void buildHierarchyRecursive(RendererObject* obj, RendererBone* node, RendererBone* parentNode);
void updateAnimation(RendererItem* item, RendererObject* obj, short** frmptr, short frac, short rate, int mask,bool useObjectWorldRotation = false); void updateAnimation(RendererItem* item, RendererObject* obj, short** frmptr, short frac, short rate, int mask,bool useObjectWorldRotation = false);
bool printDebugMessage(int x, int y, int alpha, byte r, byte g, byte b, LPCSTR Message); bool printDebugMessage(int x, int y, int alpha, byte r, byte g, byte b, LPCSTR Message);
bool checkPortal(short roomIndex, short* portal, DirectX::SimpleMath::Vector4* viewPort, DirectX::SimpleMath::Vector4* clipPort); bool checkPortal(short roomIndex, ROOM_DOOR* portal, DirectX::SimpleMath::Vector4* viewPort, DirectX::SimpleMath::Vector4* clipPort);
void getVisibleRooms(int from, int to, DirectX::SimpleMath::Vector4* viewPort, bool water, int count); void getVisibleRooms(int from, int to, DirectX::SimpleMath::Vector4* viewPort, bool water, int count);
void collectRooms(); void collectRooms();
void collectItems(short roomNumber); void collectItems(short roomNumber);

View file

@ -152,7 +152,7 @@ bool Renderer11::PrepareDataForTheRenderer()
int baseRoomVertex = 0; int baseRoomVertex = 0;
int baseRoomIndex = 0; int baseRoomIndex = 0;
for (int i = 0; i < NumberRooms; i++) for (int i = 0; i < Rooms.size(); i++)
{ {
ROOM_INFO* room = &Rooms[i]; ROOM_INFO* room = &Rooms[i];
@ -163,247 +163,223 @@ bool Renderer11::PrepareDataForTheRenderer()
r.Room = room; r.Room = room;
r.AmbientLight = Vector4(room->ambient.b / 255.0f, room->ambient.g / 255.0f, room->ambient.r / 255.0f, 1.0f); r.AmbientLight = Vector4(room->ambient.b / 255.0f, room->ambient.g / 255.0f, room->ambient.r / 255.0f, 1.0f);
r.LightsToDraw = vector<RendererLight*>(MAX_LIGHTS); r.LightsToDraw = vector<RendererLight*>(MAX_LIGHTS);
r.Statics.resize(room->numMeshes); r.Statics.resize(room->mesh.size());
if (room->NumVertices == 0) if (room->vertices.size() == 0)
continue; continue;
int lastRectangle = 0; tr5_room_vertex * vertices = room->vertices.data();
int lastTriangle = 0;
tr5_room_layer * layers = (tr5_room_layer*)room->LayerOffset; for (int n = 0; n < room->quads.size(); n++)
for (int l = 0; l < room->NumLayers; l++)
{ {
tr5_room_layer* layer = &layers[l]; tr4_mesh_face4* poly = &room->quads[n];
if (layer->NumLayerVertices == 0)
continue;
byte * polygons = (byte*)layer->PolyOffset; // Get the real texture index and if double sided
tr5_room_vertex * vertices = (tr5_room_vertex*)layer->VerticesOffset; short textureIndex = poly->Texture & 0x3FFF;
bool doubleSided = (poly->Texture & 0x8000) >> 15;
if (layer->NumLayerRectangles > 0) // Get the object texture
OBJECT_TEXTURE* texture = &ObjectTextures[textureIndex];
int tile = texture->tileAndFlag & 0x7FFF;
// Create vertices
RendererBucket* bucket;
int animatedSetIndex = getAnimatedTextureInfo(textureIndex);
int bucketIndex = RENDERER_BUCKET_SOLID;
if (!doubleSided)
{ {
for (int n = 0; n < layer->NumLayerRectangles; n++) if (texture->attribute == 2)
{ bucketIndex = RENDERER_BUCKET_TRANSPARENT;
tr4_mesh_face4* poly = (tr4_mesh_face4*)polygons; else
bucketIndex = RENDERER_BUCKET_SOLID;
// Get the real texture index and if double sided }
short textureIndex = poly->Texture & 0x3FFF; else
bool doubleSided = (poly->Texture & 0x8000) >> 15; {
if (texture->attribute == 2)
// Get the object texture bucketIndex = RENDERER_BUCKET_TRANSPARENT_DS;
OBJECT_TEXTURE* texture = &ObjectTextures[textureIndex]; else
int tile = texture->tileAndFlag & 0x7FFF; bucketIndex = RENDERER_BUCKET_SOLID_DS;
// Create vertices
RendererBucket* bucket;
int animatedSetIndex = getAnimatedTextureInfo(textureIndex);
int bucketIndex = RENDERER_BUCKET_SOLID;
if (!doubleSided)
{
if (texture->attribute == 2)
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
}
else
{
if (texture->attribute == 2)
bucketIndex = RENDERER_BUCKET_TRANSPARENT_DS;
else
bucketIndex = RENDERER_BUCKET_SOLID_DS;
}
if (animatedSetIndex == -1)
{
bucket = &r.Buckets[bucketIndex];
}
else
{
bucket = &r.AnimatedBuckets[bucketIndex];
}
// Calculate face normal
Vector3 p0 = Vector3(vertices[poly->Vertices[0]].Vertex.x,
vertices[poly->Vertices[0]].Vertex.y,
vertices[poly->Vertices[0]].Vertex.z);
Vector3 p1 = Vector3(vertices[poly->Vertices[1]].Vertex.x,
vertices[poly->Vertices[1]].Vertex.y,
vertices[poly->Vertices[1]].Vertex.z);
Vector3 p2 = Vector3(vertices[poly->Vertices[2]].Vertex.x,
vertices[poly->Vertices[2]].Vertex.y,
vertices[poly->Vertices[2]].Vertex.z);
Vector3 e1 = p1 - p0;
Vector3 e2 = p1 - p2;
Vector3 normal = e1.Cross(e2);
normal.Normalize();
int baseVertices = bucket->NumVertices;
for (int v = 0; v < 4; v++)
{
RendererVertex vertex;
vertex.Position.x = room->x + vertices[poly->Vertices[v]].Vertex.x;
vertex.Position.y = room->y + vertices[poly->Vertices[v]].Vertex.y;
vertex.Position.z = room->z + vertices[poly->Vertices[v]].Vertex.z;
vertex.Normal.x = vertices[poly->Vertices[v]].Normal.x;
vertex.Normal.y = vertices[poly->Vertices[v]].Normal.y;
vertex.Normal.z = vertices[poly->Vertices[v]].Normal.z;
vertex.UV.x = texture->vertices[v].x;
vertex.UV.y = texture->vertices[v].y;
vertex.Color.x = ((vertices[poly->Vertices[v]].Colour >> 16) & 0xFF) / 255.0f;
vertex.Color.y = ((vertices[poly->Vertices[v]].Colour >> 8) & 0xFF) / 255.0f;
vertex.Color.z = ((vertices[poly->Vertices[v]].Colour >> 0) & 0xFF) / 255.0f;
vertex.Color.w = 1.0f;
vertex.Bone = 0;
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 2);
bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 1);
bucket->NumIndices += 6;
RendererPolygon newPolygon;
newPolygon.Shape = SHAPE_RECTANGLE;
newPolygon.AnimatedSet = animatedSetIndex;
newPolygon.TextureId = textureIndex;
newPolygon.Indices[0] = baseVertices;
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
newPolygon.Indices[3] = baseVertices + 3;
bucket->Polygons.push_back(newPolygon);
polygons += sizeof(tr4_mesh_face4);
}
} }
if (layer->NumLayerTriangles > 0) if (animatedSetIndex == -1)
{ {
for (int n = 0; n < layer->NumLayerTriangles; n++) bucket = &r.Buckets[bucketIndex];
{
tr4_mesh_face3* poly = (tr4_mesh_face3*)polygons;
// Get the real texture index and if double sided
short textureIndex = poly->Texture & 0x3FFF;
bool doubleSided = (poly->Texture & 0x8000) >> 15;
// Get the object texture
OBJECT_TEXTURE* texture = &ObjectTextures[textureIndex];
int tile = texture->tileAndFlag & 0x7FFF;
// Create vertices
RendererBucket* bucket;
int animatedSetIndex = getAnimatedTextureInfo(textureIndex);
int bucketIndex = RENDERER_BUCKET_SOLID;
if (!doubleSided)
{
if (texture->attribute == 2)
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
}
else
{
if (texture->attribute == 2)
bucketIndex = RENDERER_BUCKET_TRANSPARENT_DS;
else
bucketIndex = RENDERER_BUCKET_SOLID_DS;
}
if (animatedSetIndex == -1)
{
bucket = &r.Buckets[bucketIndex];
}
else
{
bucket = &r.AnimatedBuckets[bucketIndex];
}
// Calculate face normal
Vector3 p0 = Vector3(vertices[poly->Vertices[0]].Vertex.x,
vertices[poly->Vertices[0]].Vertex.y,
vertices[poly->Vertices[0]].Vertex.z);
Vector3 p1 = Vector3(vertices[poly->Vertices[1]].Vertex.x,
vertices[poly->Vertices[1]].Vertex.y,
vertices[poly->Vertices[1]].Vertex.z);
Vector3 p2 = Vector3(vertices[poly->Vertices[2]].Vertex.x,
vertices[poly->Vertices[2]].Vertex.y,
vertices[poly->Vertices[2]].Vertex.z);
Vector3 e1 = p1 - p0;
Vector3 e2 = p1 - p2;
Vector3 normal = e1.Cross(e2);
normal.Normalize();
int baseVertices = bucket->NumVertices;
for (int v = 0; v < 3; v++)
{
RendererVertex vertex;
vertex.Position.x = room->x + vertices[poly->Vertices[v]].Vertex.x;
vertex.Position.y = room->y + vertices[poly->Vertices[v]].Vertex.y;
vertex.Position.z = room->z + vertices[poly->Vertices[v]].Vertex.z;
vertex.Normal.x = vertices[poly->Vertices[v]].Normal.x;
vertex.Normal.y = vertices[poly->Vertices[v]].Normal.y;
vertex.Normal.z = vertices[poly->Vertices[v]].Normal.z;
vertex.UV.x = texture->vertices[v].x;
vertex.UV.y = texture->vertices[v].y;
vertex.Color.x = ((vertices[poly->Vertices[v]].Colour >> 16) & 0xFF) / 255.0f;
vertex.Color.y = ((vertices[poly->Vertices[v]].Colour >> 8) & 0xFF) / 255.0f;
vertex.Color.z = ((vertices[poly->Vertices[v]].Colour >> 0) & 0xFF) / 255.0f;
vertex.Color.w = 1.0f;
vertex.Bone = 0;
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 2);
bucket->NumIndices += 3;
RendererPolygon newPolygon;
newPolygon.Shape = SHAPE_TRIANGLE;
newPolygon.AnimatedSet = animatedSetIndex;
newPolygon.TextureId = textureIndex;
newPolygon.Indices[0] = baseVertices;
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
bucket->Polygons.push_back(newPolygon);
polygons += sizeof(tr4_mesh_face3);
}
} }
else
{
bucket = &r.AnimatedBuckets[bucketIndex];
}
// Calculate face normal
Vector3 p0 = Vector3(vertices[poly->Vertices[0]].Vertex.x,
vertices[poly->Vertices[0]].Vertex.y,
vertices[poly->Vertices[0]].Vertex.z);
Vector3 p1 = Vector3(vertices[poly->Vertices[1]].Vertex.x,
vertices[poly->Vertices[1]].Vertex.y,
vertices[poly->Vertices[1]].Vertex.z);
Vector3 p2 = Vector3(vertices[poly->Vertices[2]].Vertex.x,
vertices[poly->Vertices[2]].Vertex.y,
vertices[poly->Vertices[2]].Vertex.z);
Vector3 e1 = p1 - p0;
Vector3 e2 = p1 - p2;
Vector3 normal = e1.Cross(e2);
normal.Normalize();
int baseVertices = bucket->NumVertices;
for (int v = 0; v < 4; v++)
{
RendererVertex vertex;
vertex.Position.x = room->x + vertices[poly->Vertices[v]].Vertex.x;
vertex.Position.y = room->y + vertices[poly->Vertices[v]].Vertex.y;
vertex.Position.z = room->z + vertices[poly->Vertices[v]].Vertex.z;
vertex.Normal.x = vertices[poly->Vertices[v]].Normal.x;
vertex.Normal.y = vertices[poly->Vertices[v]].Normal.y;
vertex.Normal.z = vertices[poly->Vertices[v]].Normal.z;
vertex.UV.x = texture->vertices[v].x;
vertex.UV.y = texture->vertices[v].y;
vertex.Color.x = ((vertices[poly->Vertices[v]].Colour >> 16) & 0xFF) / 255.0f;
vertex.Color.y = ((vertices[poly->Vertices[v]].Colour >> 8) & 0xFF) / 255.0f;
vertex.Color.z = ((vertices[poly->Vertices[v]].Colour >> 0) & 0xFF) / 255.0f;
vertex.Color.w = 1.0f;
vertex.Bone = 0;
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 2);
bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 1);
bucket->NumIndices += 6;
RendererPolygon newPolygon;
newPolygon.Shape = SHAPE_RECTANGLE;
newPolygon.AnimatedSet = animatedSetIndex;
newPolygon.TextureId = textureIndex;
newPolygon.Indices[0] = baseVertices;
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
newPolygon.Indices[3] = baseVertices + 3;
bucket->Polygons.push_back(newPolygon);
} }
if (room->numLights != 0) for (int n = 0; n < room->triangles.size(); n++)
{ {
tr5_room_light* oldLight = room->light; tr4_mesh_face3* poly = &room->triangles[n];
for (int l = 0; l < room->numLights; l++) // Get the real texture index and if double sided
short textureIndex = poly->Texture & 0x3FFF;
bool doubleSided = (poly->Texture & 0x8000) >> 15;
// Get the object texture
OBJECT_TEXTURE* texture = &ObjectTextures[textureIndex];
int tile = texture->tileAndFlag & 0x7FFF;
// Create vertices
RendererBucket* bucket;
int animatedSetIndex = getAnimatedTextureInfo(textureIndex);
int bucketIndex = RENDERER_BUCKET_SOLID;
if (!doubleSided)
{
if (texture->attribute == 2)
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
}
else
{
if (texture->attribute == 2)
bucketIndex = RENDERER_BUCKET_TRANSPARENT_DS;
else
bucketIndex = RENDERER_BUCKET_SOLID_DS;
}
if (animatedSetIndex == -1)
{
bucket = &r.Buckets[bucketIndex];
}
else
{
bucket = &r.AnimatedBuckets[bucketIndex];
}
// Calculate face normal
Vector3 p0 = Vector3(vertices[poly->Vertices[0]].Vertex.x,
vertices[poly->Vertices[0]].Vertex.y,
vertices[poly->Vertices[0]].Vertex.z);
Vector3 p1 = Vector3(vertices[poly->Vertices[1]].Vertex.x,
vertices[poly->Vertices[1]].Vertex.y,
vertices[poly->Vertices[1]].Vertex.z);
Vector3 p2 = Vector3(vertices[poly->Vertices[2]].Vertex.x,
vertices[poly->Vertices[2]].Vertex.y,
vertices[poly->Vertices[2]].Vertex.z);
Vector3 e1 = p1 - p0;
Vector3 e2 = p1 - p2;
Vector3 normal = e1.Cross(e2);
normal.Normalize();
int baseVertices = bucket->NumVertices;
for (int v = 0; v < 3; v++)
{
RendererVertex vertex;
vertex.Position.x = room->x + vertices[poly->Vertices[v]].Vertex.x;
vertex.Position.y = room->y + vertices[poly->Vertices[v]].Vertex.y;
vertex.Position.z = room->z + vertices[poly->Vertices[v]].Vertex.z;
vertex.Normal.x = vertices[poly->Vertices[v]].Normal.x;
vertex.Normal.y = vertices[poly->Vertices[v]].Normal.y;
vertex.Normal.z = vertices[poly->Vertices[v]].Normal.z;
vertex.UV.x = texture->vertices[v].x;
vertex.UV.y = texture->vertices[v].y;
vertex.Color.x = ((vertices[poly->Vertices[v]].Colour >> 16) & 0xFF) / 255.0f;
vertex.Color.y = ((vertices[poly->Vertices[v]].Colour >> 8) & 0xFF) / 255.0f;
vertex.Color.z = ((vertices[poly->Vertices[v]].Colour >> 0) & 0xFF) / 255.0f;
vertex.Color.w = 1.0f;
vertex.Bone = 0;
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 2);
bucket->NumIndices += 3;
RendererPolygon newPolygon;
newPolygon.Shape = SHAPE_TRIANGLE;
newPolygon.AnimatedSet = animatedSetIndex;
newPolygon.TextureId = textureIndex;
newPolygon.Indices[0] = baseVertices;
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
bucket->Polygons.push_back(newPolygon);
}
if (room->lights.size() != 0)
{
for (int l = 0; l < room->lights.size(); l++)
{ {
RendererLight light; RendererLight light;
ROOM_LIGHT* oldLight = &room->lights[l];
if (oldLight->LightType == LIGHT_TYPES::LIGHT_TYPE_SUN) if (oldLight->type == LIGHT_TYPES::LIGHT_TYPE_SUN)
{ {
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f); light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
@ -412,38 +388,38 @@ bool Renderer11::PrepareDataForTheRenderer()
r.Lights.push_back(light); r.Lights.push_back(light);
} }
else if (oldLight->LightType == LIGHT_TYPE_POINT) else if (oldLight->type == LIGHT_TYPE_POINT)
{ {
light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f); light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Intensity = 1.0f; light.Intensity = 1.0f;
light.In = oldLight->In; light.In = oldLight->in;
light.Out = oldLight->Out; light.Out = oldLight->out;
light.Type = LIGHT_TYPE_POINT; light.Type = LIGHT_TYPE_POINT;
r.Lights.push_back(light); r.Lights.push_back(light);
} }
else if (oldLight->LightType == LIGHT_TYPE_SHADOW) else if (oldLight->type == LIGHT_TYPE_SHADOW)
{ {
light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.In = oldLight->In; light.In = oldLight->in;
light.Out = oldLight->Out; light.Out = oldLight->out;
light.Type = LIGHT_TYPE_SHADOW; light.Type = LIGHT_TYPE_SHADOW;
light.Intensity = 1.0f; light.Intensity = 1.0f;
r.Lights.push_back(light); r.Lights.push_back(light);
} }
else if (oldLight->LightType == LIGHT_TYPE_SPOT) else if (oldLight->type == LIGHT_TYPE_SPOT)
{ {
light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light.Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f); light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Intensity = 1.0f; light.Intensity = 1.0f;
light.In = oldLight->In; light.In = oldLight->in;
light.Out = oldLight->Out; light.Out = oldLight->out;
light.Range = oldLight->Range; light.Range = oldLight->range;
light.Type = LIGHT_TYPE_SPOT; light.Type = LIGHT_TYPE_SPOT;
r.Lights.push_back(light); r.Lights.push_back(light);

View file

@ -2282,7 +2282,7 @@ bool Renderer11::drawStatics(bool transparent)
{ {
MESH_INFO* msh = m_staticsToDraw[i]->Mesh; MESH_INFO* msh = m_staticsToDraw[i]->Mesh;
if (!(msh->Flags & 1)) if (!(msh->flags & 1))
continue; continue;
RendererRoom& const room = m_rooms[m_staticsToDraw[i]->RoomIndex]; RendererRoom& const room = m_rooms[m_staticsToDraw[i]->RoomIndex];

View file

@ -12,7 +12,7 @@ void Renderer11::collectRooms()
{ {
short baseRoomIndex = Camera.pos.roomNumber; short baseRoomIndex = Camera.pos.roomNumber;
for (int i = 0; i < NumberRooms; i++) for (int i = 0; i < Rooms.size(); i++)
{ {
m_rooms[i].Visited = false; m_rooms[i].Visited = false;
m_rooms[i].LightsToDraw.clear(); m_rooms[i].LightsToDraw.clear();
@ -77,9 +77,9 @@ void Renderer11::collectStatics(short roomNumber)
} }
RendererRoom& const room = m_rooms[roomNumber]; RendererRoom& const room = m_rooms[roomNumber];
ROOM_INFO* r = room.Room; ROOM_INFO* r = room.Room;
if (r->numMeshes <= 0) if (r->mesh.size() <= 0)
return; return;
int numStatics = r->numMeshes; int numStatics = r->mesh.size();
for (int i = 0; i < numStatics; i++) for (int i = 0; i < numStatics; i++)
{ {
MESH_INFO* mesh = &r->mesh[i]; MESH_INFO* mesh = &r->mesh[i];
@ -110,7 +110,7 @@ void Renderer11::collectLightsForEffect(short roomNumber, RendererEffect * effec
ROOM_INFO* r = room.Room; ROOM_INFO* r = room.Room;
if (r->numLights <= 0) if (r->lights.size() <= 0)
return; return;
m_tempItemLights.clear(); m_tempItemLights.clear();
@ -212,7 +212,7 @@ void Renderer11::collectLightsForItem(short roomNumber, RendererItem * item)
ROOM_INFO* r = room.Room; ROOM_INFO* r = room.Room;
if (r->numLights <= 0) if (r->lights.size() <= 0)
return; return;
m_tempItemLights.clear(); m_tempItemLights.clear();

View file

@ -1485,7 +1485,7 @@ short GameScriptItem::GetRoom()
void GameScriptItem::SetRoom(short room) void GameScriptItem::SetRoom(short room)
{ {
if (room < 0 || room >= NumberRooms) if (room < 0 || room >= Rooms.size())
{ {
if (WarningsAsErrors) if (WarningsAsErrors)
throw runtime_error("invalid room number"); throw runtime_error("invalid room number");

View file

@ -50,8 +50,7 @@ char* LevelDataPtr;
vector<OBJECT_TEXTURE> ObjectTextures; vector<OBJECT_TEXTURE> ObjectTextures;
ITEM_INFO* Items; ITEM_INFO* Items;
int LevelItems; int LevelItems;
int NumberRooms; std::vector<ROOM_INFO> Rooms;
ROOM_INFO* Rooms;
ANIM_STRUCT* Anims; ANIM_STRUCT* Anims;
CHANGE_STRUCT* Changes; CHANGE_STRUCT* Changes;
RANGE_STRUCT* Ranges; RANGE_STRUCT* Ranges;
@ -91,6 +90,13 @@ short ReadInt16()
return value; return value;
} }
unsigned short ReadUInt16()
{
unsigned short value = *(unsigned short*)LevelDataPtr;
LevelDataPtr += 2;
return value;
}
int ReadInt32() int ReadInt32()
{ {
int value = *(int*)LevelDataPtr; int value = *(int*)LevelDataPtr;
@ -144,11 +150,11 @@ int LoadItems()
InitialiseItem(i); InitialiseItem(i);
} }
for (int r = 0; r < NumberRooms; r++) for (int r = 0; r < Rooms.size(); r++)
{ {
MESH_INFO* mesh = Rooms[r].mesh; MESH_INFO* mesh = Rooms[r].mesh.data();
for (int m = 0; m < Rooms[r].numMeshes; m++) for (int m = 0; m < Rooms[r].mesh.size(); m++)
{ {
FLOOR_INFO* floor = &Rooms[r].floor[((mesh->z - Rooms[r].z) >> 10) + Rooms[r].xSize * ((mesh->x - Rooms[r].x) >> 10)]; FLOOR_INFO* floor = &Rooms[r].floor[((mesh->z - Rooms[r].z) >> 10) + Rooms[r].xSize * ((mesh->x - Rooms[r].x) >> 10)];
@ -396,109 +402,178 @@ void LoadTextures()
free(buffer); free(buffer);
} }
void ReadRoom(ROOM_INFO* room, ROOM_INFO* roomData)
{
/*ADD_PTR(roomData->door, short, roomData + 1);
ADD_PTR(roomData->floor, FLOOR_INFO, roomData + 1);
ADD_PTR(roomData->light, LIGHTINFO, roomData + 1);
ADD_PTR(roomData->mesh, MESH_INFO, roomData + 1);
ADD_PTR(roomData->Separator4, void, roomData + 1);
ADD_PTR(roomData->LayerOffset, tr5_room_layer, roomData + 1);
ADD_PTR(roomData->PolyOffset, void, roomData + 1);
ADD_PTR(roomData->PolyOffset2, void, roomData + 1);
ADD_PTR(roomData->VerticesOffset, tr5_room_vertex, roomData + 1);
roomData->LightDataSize += (int)(roomData + 1);
if ((byte)roomData->door & 1)
{
////DB_Log(0, "%X", roomData->door);
roomData->door = 0;
}
byte* polyOff = (byte*)roomData->PolyOffset;
byte* polyOff2 = (byte*)roomData->PolyOffset2;
byte* vertOff = (byte*)roomData->VerticesOffset;
for (int i = 0; i < roomData->NumLayers; i++)
{
roomData->LayerOffset[i].PolyOffset = polyOff;
roomData->LayerOffset[i].PolyOffset2 = polyOff2;
roomData->LayerOffset[i].VerticesOffset = vertOff;
polyOff += sizeof(tr4_mesh_face3) * roomData->LayerOffset[i].NumLayerTriangles +
sizeof(tr4_mesh_face4) * roomData->LayerOffset[i].NumLayerRectangles;
polyOff2 += 4 * roomData->LayerOffset[i].NumLayerVertices; // todo find what struct this is
vertOff += sizeof(tr5_room_vertex) * roomData->LayerOffset[i].NumLayerVertices;
}
memcpy(room, roomData, sizeof(ROOM_INFO));*/
}
void FixUpRoom(ROOM_INFO* room, ROOM_INFO* roomData)
{
AddPtr(roomData->door, short, roomData + 1);
AddPtr(roomData->floor, FLOOR_INFO, roomData + 1);
AddPtr(roomData->light, tr5_room_light, roomData + 1);
AddPtr(roomData->mesh, MESH_INFO, roomData + 1);
//AddPtr(roomData->RoomLights, tr5_room_light, roomData + 1);
AddPtr(roomData->LayerOffset, tr5_room_layer, roomData + 1);
AddPtr(roomData->PolyOffset, void, roomData + 1);
AddPtr(roomData->PolyOffset2, void, roomData + 1);
AddPtr(roomData->VerticesOffset, tr5_room_vertex, roomData + 1);
roomData->LightDataSize += (uint32_t)(roomData + 1);
if ((uint8_t)roomData->door & 1)
{
roomData->door = nullptr;
}
auto* polyOff = (char*)roomData->PolyOffset;
auto* polyOff2 = (char*)roomData->PolyOffset2;
auto* vertOff = (char*)roomData->VerticesOffset;
for (int i = 0; i < roomData->NumLayers; i++)
{
roomData->LayerOffset[i].PolyOffset = polyOff;
roomData->LayerOffset[i].PolyOffset2 = polyOff2;
roomData->LayerOffset[i].VerticesOffset = vertOff;
polyOff += sizeof(struct tr4_mesh_face3) * roomData->LayerOffset[i].NumLayerTriangles +
sizeof(struct tr4_mesh_face4) * roomData->LayerOffset[i].NumLayerRectangles;
polyOff2 += 4 * roomData->LayerOffset[i].NumLayerVertices; // todo find what struct this is
vertOff += sizeof(tr5_room_vertex) * roomData->LayerOffset[i].NumLayerVertices;
}
memcpy(room, roomData, sizeof(ROOM_INFO));
}
void ReadRooms() void ReadRooms()
{ {
ReadInt32(); ReadInt32();
int numRooms = ReadInt32(); int numRooms = ReadInt32();
NumberRooms = numRooms; //NumberRooms = numRooms;
Rooms = (ROOM_INFO*)game_malloc(NumberRooms * sizeof(ROOM_INFO)); //Rooms = (ROOM_INFO*)game_malloc(NumberRooms * sizeof(ROOM_INFO));
Rooms.clear();
printf("NumRooms: %d\n", numRooms); printf("NumRooms: %d\n", numRooms);
for (int i = 0; i < NumberRooms; i++) for (int i = 0; i < numRooms; i++)
{ {
// Ignore XELA ROOM_INFO room;
int xela = ReadInt32();
// Read room data room.x = ReadInt32();
int roomDataSize = ReadInt32(); room.y = 0;
byte* roomData = (byte*)game_malloc(roomDataSize); room.z = ReadInt32();
ReadBytes(roomData, roomDataSize); room.minfloor = ReadInt32();
room.maxceiling = ReadInt32();
// Put the room data in the struct int numDataWords = ReadInt32();
FixUpRoom(&Rooms[i], (ROOM_INFO*)roomData);
short numVertices = ReadInt16();
room.vertices.reserve(numVertices);
for (int j = 0; j < numVertices; j++)
{
tr5_room_vertex vertex;
vertex.Vertex.x = ReadInt16();
vertex.Vertex.y = ReadInt16();
vertex.Vertex.z = ReadInt16();
vertex.Colour = ReadInt32();
ReadInt16();
room.vertices.push_back(vertex);
}
short numQuads = ReadInt16();
room.quads.reserve(numQuads);
for (int j = 0; j < numQuads; j++)
{
tr4_mesh_face4 poly;
poly.Vertices[0] = ReadInt16();
poly.Vertices[1] = ReadInt16();
poly.Vertices[2] = ReadInt16();
poly.Vertices[3] = ReadInt16();
poly.Texture = ReadInt16();
room.quads.push_back(poly);
}
short numTriangles = ReadInt16();
room.triangles.reserve(numTriangles);
for (int j = 0; j < numTriangles; j++)
{
tr4_mesh_face3 poly;
poly.Vertices[0] = ReadInt16();
poly.Vertices[1] = ReadInt16();
poly.Vertices[2] = ReadInt16();
poly.Texture = ReadInt16();
room.triangles.push_back(poly);
}
short numPortals = ReadInt16();
for (int j = 0; j < numPortals; j++)
{
ROOM_DOOR door;
door.room = ReadInt16();
door.normal.x = ReadInt16();
door.normal.y = ReadInt16();
door.normal.z = ReadInt16();
for (int k = 0; k < 4; k++)
{
door.vertices[k].x = ReadInt16();
door.vertices[k].y = ReadInt16();
door.vertices[k].z = ReadInt16();
}
room.doors.push_back(door);
}
room.xSize = ReadInt16();
room.ySize = ReadInt16();
room.floor.reserve(room.xSize * room.ySize);
for (int j = 0; j < room.xSize * room.ySize; j++)
{
FLOOR_INFO floor;
floor.index = ReadInt32();
floor.box = ReadInt32();
floor.fx = ReadInt32();
floor.stopper = ReadInt32();
floor.pitRoom = ReadInt32();
floor.floor = ReadInt32();
floor.skyRoom = ReadInt32();
floor.ceiling = ReadInt32();
floor.floorCollision.split = ReadInt32();
floor.floorCollision.noCollision = ReadInt32();
floor.floorCollision.planes[0].a = ReadFloat();
floor.floorCollision.planes[0].b = ReadFloat();
floor.floorCollision.planes[0].c = ReadFloat();
floor.floorCollision.planes[1].a = ReadFloat();
floor.floorCollision.planes[1].b = ReadFloat();
floor.floorCollision.planes[1].c = ReadFloat();
floor.ceilingCollision.split = ReadInt32();
floor.ceilingCollision.noCollision = ReadInt32();
floor.ceilingCollision.planes[0].a = ReadFloat();
floor.ceilingCollision.planes[0].b = ReadFloat();
floor.ceilingCollision.planes[0].c = ReadFloat();
floor.ceilingCollision.planes[1].a = ReadFloat();
floor.ceilingCollision.planes[1].b = ReadFloat();
floor.ceilingCollision.planes[1].c = ReadFloat();
room.floor.push_back(floor);
}
room.ambient.r = ReadInt8();
room.ambient.g = ReadInt8();
room.ambient.b = ReadInt8();
ReadInt8();
short numLights = ReadInt16();
room.lights.reserve(numLights);
for (int j = 0; j < numLights; j++)
{
ROOM_LIGHT light;
light.x = ReadFloat();
light.y = ReadFloat();
light.z = ReadFloat();
light.r = ReadFloat();
light.g = ReadFloat();
light.b = ReadFloat();
light.in = ReadFloat();
light.out = ReadFloat();
light.radIn = ReadFloat();
light.radOut = ReadFloat();
light.range = ReadFloat();
light.dx = ReadFloat();
light.dy = ReadFloat();
light.dz = ReadFloat();
light.type = ReadInt8();
room.lights.push_back(light);
}
short numStatics = ReadInt16();
room.mesh.reserve(numStatics);
for (int j = 0; j < numStatics; j++)
{
MESH_INFO mesh;
mesh.x = ReadInt32();
mesh.y = ReadInt32();
mesh.z = ReadInt32();
mesh.yRot = ReadUInt16();
mesh.shade = ReadUInt16();
mesh.flags = ReadUInt16();
mesh.staticNumber = ReadUInt16();
room.mesh.push_back(mesh);
}
room.flippedRoom = ReadInt16();
room.flags = ReadInt16();
room.meshEffect = ReadInt8();
room.reverbType = ReadInt8();
room.flipNumber = ReadInt8();
room.itemNumber = NO_ITEM;
room.fxNumber = NO_ITEM;
Rooms.push_back(room);
} }
} }

View file

@ -116,8 +116,7 @@ extern int NumItems;
extern vector<OBJECT_TEXTURE> ObjectTextures; extern vector<OBJECT_TEXTURE> ObjectTextures;
extern ITEM_INFO* Items; extern ITEM_INFO* Items;
extern int LevelItems; extern int LevelItems;
extern int NumberRooms; extern std::vector<ROOM_INFO> Rooms;
extern ROOM_INFO* Rooms;
extern ANIM_STRUCT* Anims; extern ANIM_STRUCT* Anims;
extern CHANGE_STRUCT* Changes; extern CHANGE_STRUCT* Changes;
extern RANGE_STRUCT* Ranges; extern RANGE_STRUCT* Ranges;
@ -159,7 +158,6 @@ void LoadTextureInfos();
void LoadAIObjects(); void LoadAIObjects();
FILE* FileOpen(const char* fileName); FILE* FileOpen(const char* fileName);
void FileClose(FILE* ptr); void FileClose(FILE* ptr);
void FixUpRoom(ROOM_INFO* room, ROOM_INFO* roomData);
void Decompress(byte* dest, byte* src, unsigned long compressedSize, unsigned long uncompressedSize); void Decompress(byte* dest, byte* src, unsigned long compressedSize, unsigned long uncompressedSize);
unsigned CALLBACK LoadLevel(void* data); unsigned CALLBACK LoadLevel(void* data);