mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-10 20:46:47 +03:00
New FLOOR_INFO struct; Refactoring rooms part I
This commit is contained in:
parent
a0279655c5
commit
235dab2f13
29 changed files with 610 additions and 642 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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++;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue