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)
{
ShatterObject(0, mesh, 128, to.roomNumber, 0);
mesh->Flags &= ~1;
mesh->flags &= ~1;
SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS*)mesh, 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++)
{
room = &Rooms[roomList[i]];
mesh = room->mesh;
for (int j = room->numMeshes; j > 0; j--, mesh++)
for (int j = room->mesh.size(); j > 0; j--, mesh++)
{
mesh = &room->mesh[j];
StaticInfo* sInfo = &StaticObjects[mesh->staticNumber];
if ((sInfo->flags & 1)) // No collision
continue;
@ -136,12 +136,12 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
{
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];
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)
{
@ -1384,16 +1384,11 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
short* door, numDoors;
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;
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
roomsList.push_back(room.doors[i].room);
}
for (int i = 0; i < roomsList.size(); i++)
@ -1420,12 +1415,11 @@ void LaraBaddieCollision(ITEM_INFO* l, COLL_INFO* coll)
if (coll->enableSpaz)
{
MESH_INFO* mesh = Rooms[roomsList[i]].mesh;
int numMeshes = Rooms[roomsList[i]].numMeshes;
for (int j = 0; j < numMeshes; j++)
for (int j = 0; j < Rooms[roomsList[i]].mesh.size(); 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 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;
SmashedMesh[SmashedMeshCount] = mesh;
++SmashedMeshCount;
mesh->Flags &= ~0x1;
mesh->flags &= ~0x1;
SoundEffect(ShatterSounds[CurrentLevel - 5][mesh->staticNumber], (PHD_3DPOS *)mesh, 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]];
for (m = 0; m < room->numMeshes; m++)
for (m = 0; m < room->mesh.size(); m++)
{
meshp = &room->mesh[m];
if (meshp->Flags & 1)
if (meshp->flags & 1)
{
pos.xPos = meshp->x;
pos.yPos = meshp->y;
@ -2896,7 +2896,7 @@ void DoFlipMap(short group)
{
ROOM_INFO temp;
for (int i = 0; i < NumberRooms; i++)
for (int i = 0; i < Rooms.size(); i++)
{
ROOM_INFO *r = &Rooms[i];

View file

@ -896,22 +896,17 @@ 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)
{
*dptr = NULL;
if (room->door)
{
if (room->door > 0)
{
int numDoors = *(room->door);
short* door = &room->door[1];
/**dptr = NULL;
int halfX = x >> 1;
int halfZ = z >> 1;
for (int i = 0; i < numDoors; i++)
for (int i = 0; i < room->doors.size(); i++)
{
int x1 = halfX + room->x + (door[4] + 128) & 0xFFFFFF00;
int x2 = halfX + room->x + (door[10] + 128) & 0xFFFFFF00;
ROOM_DOOR door = room->doors[i];
int x1 = halfX + room->x + ((int)door.vertices[0].x + 128) & 0xFFFFFF00;
int x2 = halfX + room->x + ((int)door.vertices[2].x + 128) & 0xFFFFFF00;
if (x1 > x2)
{
@ -920,8 +915,8 @@ void GetClosedDoorNormal(ROOM_INFO* room, short** dptr, byte* n, int z, int x, i
x2 = temp;
}
int z1 = halfZ + room->z + (door[6] + 128) & 0xFFFFFF00;
int z2 = halfZ + room->z + (door[12] + 128) & 0xFFFFFF00;
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)
{
@ -947,16 +942,12 @@ void GetClosedDoorNormal(ROOM_INFO* room, short** dptr, byte* n, int z, int x, i
*n = (byte)door[3] & 0x84 | 4;
}
}
door += 16;
}
}
}
}*/
}
void ProcessClosedDoors()
{
for (int i = 0; i < 32; i++)
/*for (int i = 0; i < 32; i++)
{
ITEM_INFO* item = ClosedDoors[i];
@ -982,7 +973,7 @@ void ProcessClosedDoors()
ItemNewRoom(item - Items, roomNumber);
item->inDrawRoom = false;
}
}
}*/
}
void AssignClosedDoor(ITEM_INFO* item)

View file

@ -13,7 +13,7 @@ void ClearItem(short itemNum)
item->collidable = true;
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->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 changed = 0;
for (int i = 0; i < NumberRooms; i++)
for (int i = 0; i < Rooms.size(); i++)
{
ROOM_INFO* room = &Rooms[i];
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;
SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++;
currentMesh->Flags &= ~1;
currentMesh->flags &= ~1;
}
k++;
@ -1214,7 +1214,7 @@ void ControlCrossbowBolt(short itemNumber)
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++;
currentMesh->Flags &= ~1;
currentMesh->flags &= ~1;
}
k++;

View file

@ -55,15 +55,11 @@ void GetRoomList(short roomNumber, short* roomArray, short* numRooms)
bool adjoiningRoomFound;
roomArray[0] = roomNumber;
door = Rooms[roomNumber].door;
if (door)
{
numDoors = *door;
door++;
ROOM_INFO* room = &Rooms[roomNumber];
for (i = 0; i < numDoors; i++)
for (i = 0; i < room->doors.size(); i++)
{
adjoiningRoom = *door;
adjoiningRoom = room->doors[i].room;
adjoiningRoomFound = false;
for (j = 0; j < *numRooms; j++)
@ -77,29 +73,22 @@ void GetRoomList(short roomNumber, short* roomArray, short* numRooms)
if (!adjoiningRoomFound)
roomArray[*(numRooms++)] = adjoiningRoom;
door += 16;
}
}
}
void GetRoomList(short roomNumber, vector<short>* destRoomList)
{
vector<short> roomList;
short numDoors, *door, adjoiningRoom;
short adjoiningRoom;
int i, j;
bool adjoiningRoomFound;
roomList.push_back(roomNumber);
door = Rooms[roomNumber].door;
if (door)
{
numDoors = *door;
door++;
ROOM_INFO* room = &Rooms[roomNumber];
for (i = 0; i < numDoors; i++)
for (i = 0; i < room->doors.size(); i++)
{
adjoiningRoom = *door;
adjoiningRoom = room->doors[i].room;
adjoiningRoomFound = false;
for (j = 0; j < roomList.size(); j++)
@ -114,8 +103,6 @@ void GetRoomList(short roomNumber, vector<short>* destRoomList)
if (!adjoiningRoomFound)
roomList.push_back(adjoiningRoom);
door += 16;
}
}
*destRoomList = roomList;

View file

@ -1394,13 +1394,12 @@ void PickupControl(short itemNum)
short* FindPlinth(ITEM_INFO* item)
{
ROOM_INFO* room = &Rooms[item->roomNumber];
MESH_INFO* mesh = room->mesh;
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];
if (mesh->Flags & 1)
if (mesh->flags & 1)
{
if (item->pos.xPos == mesh->x && item->pos.zPos == mesh->z)
{

View file

@ -1,4 +1,5 @@
#pragma once
#include <framework.h>
typedef struct tr5_room_layer
{
@ -36,6 +37,13 @@ typedef struct tr5_room_vertex
DWORD Colour; // 32-bit colour
};
struct ROOM_DOOR
{
short room;
Vector3 normal;
Vector3 vertices[4];
};
typedef struct tr4_mesh_face3 // 10 bytes
{
short Vertices[3];
@ -50,7 +58,7 @@ typedef struct tr4_mesh_face4 // 12 bytes
short Effects;
};
typedef struct tr_room_portal // 32 bytes
typedef struct tr_ROOM_DOOR // 32 bytes
{
short AdjoiningRoom; // Which room this portal leads to
TR_VERTEX Normal;
@ -67,21 +75,17 @@ typedef struct tr_room_sector // 8 bytes
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 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 Out; // Cosine of the OUT value for light / size of OUT value
float RadIn; // (IN radians) * 2
float RadOut; // (OUT radians) * 2
float Range; // Range of light
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 radIn; // (IN radians) * 2
float radOut; // (OUT radians) * 2
float range; // Range of light
float dx, dy, dz; // Direction - used only by sun and spot lights
int x2, y2, z2; // Same as position, only in integer.
int dx2, dy2, dz2; // Same as direction, only in integer.
byte LightType;
byte Filler[3]; // Dummy values = 3 x 0xCD
byte type;
};
typedef struct MESH_INFO
@ -91,7 +95,7 @@ typedef struct MESH_INFO
int z;
short yRot;
short shade;
short Flags;
short flags;
short staticNumber;
};
@ -115,16 +119,46 @@ typedef struct LIGHTINFO
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
{
unsigned short index;
unsigned short fx : 4;
unsigned short box : 11;
unsigned short stopper : 1;
unsigned char pitRoom;
signed char floor;
unsigned char skyRoom;
signed char ceiling;
int index;
int box;
int fx;
int stopper;
int pitRoom;
int floor;
int skyRoom;
int ceiling;
SECTOR_COLLISION_INFO floorCollision;
SECTOR_COLLISION_INFO ceilingCollision;
};
typedef enum RoomEnumFlag
@ -143,64 +177,29 @@ typedef enum RoomEnumFlag
typedef struct ROOM_INFO
{
short* data;
short* door;
FLOOR_INFO* floor;
void* something;
MESH_INFO* mesh;
int x;
int y;
int z;
int minfloor;
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 ySize;
std::vector<FLOOR_INFO> floor;
CVECTOR ambient;
short numLights;
short numMeshes;
std::vector<ROOM_LIGHT> lights;
std::vector<MESH_INFO> mesh;
short flippedRoom;
unsigned short flags;
byte meshEffect;
unsigned char reverbType;
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 fxNumber;
short flippedRoom;
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
bool boundActive;
};
typedef struct ANIM_STRUCT

View file

@ -185,12 +185,9 @@ void SaveGame::saveGameStatus(int arg1, int arg2)
LEB128::Write(m_stream, CurrentSequence);
// Now the sub-chunks
if (NumberRooms > 0)
{
for (int i = 0; i < NumberRooms; i++)
for (int j = 0; j < Rooms[i].numMeshes; j++)
for (int i = 0; i < Rooms.size(); i++)
for (int j = 0; j < Rooms[i].mesh.size(); j++)
m_writer->WriteChunk(m_chunkStaticFlags, &saveStaticFlag, i, j);
}
for (int i = 0; i < 6; 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, 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)
@ -851,7 +848,7 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
short roomIndex = LEB128::ReadInt16(m_stream);
short staticIndex = LEB128::ReadInt16(m_stream);
short flags = LEB128::ReadInt16(m_stream);
Rooms[roomIndex].mesh[staticIndex].Flags = flags;
Rooms[roomIndex].mesh[staticIndex].flags = flags;
if (!flags)
{

View file

@ -93,16 +93,10 @@ static void SkidooBaddieCollision(short itemNum, ITEM_INFO* skidoo)
vector<short> roomsList;
roomsList.push_back(skidoo->roomNumber);
short* door = Rooms[skidoo->roomNumber].door;
if (door)
ROOM_INFO* room = &Rooms[skidoo->roomNumber];
for (int i = 0; i < room->doors.size(); i++)
{
short numDoors = *door;
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
roomsList.push_back(room->doors[i].room);
}
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);
/* -------- get nearby rooms */
door = Rooms[kayak->roomNumber].door;
if (door)
ROOM_INFO* room = &Rooms[kayak->roomNumber];
for (int i = 0; i < room->doors.size(); i++)
{
numDoors = *door;
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
roomsList.push_back(room->doors[i].room);
}
/* -------- collide with all baddies in these rooms */

View file

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

View file

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

View file

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

View file

@ -44,7 +44,7 @@ void SphinxControl(short itemNumber)
{
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];
@ -53,7 +53,7 @@ void SphinxControl(short itemNumber)
ShatterObject(NULL, mesh, -64, item->roomNumber, 0);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);
mesh->Flags &= ~0x100;
mesh->flags &= ~0x100;
floor->stopper = false;
TestTriggers(TriggerIndex, 1, 0);

View file

@ -512,16 +512,10 @@ static void JeepBaddieCollision(ITEM_INFO* jeep)
roomsList.push_back(jeep->roomNumber);
door = Rooms[jeep->roomNumber].door;
if (door)
ROOM_INFO* room = &Rooms[jeep->roomNumber];
for (int i = 0; i < room->doors.size(); i++)
{
numDoors = *door;
door++;
for (int i = 0; i < numDoors; i++)
{
roomsList.push_back(*door);
door += 16;
}
roomsList.push_back(room->doors[i].room);
}
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);
if (floor->stopper)
{
for (i = 0; i < r->numMeshes; i++)
for (i = 0; i < r->mesh.size(); i++)
{
mesh = &r->mesh[i];
@ -329,7 +329,7 @@ void ControlGladiator(short itemNumber)
{
ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0);
//SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0);
mesh->Flags &= 0xFEu;
mesh->flags &= 0xFEu;
GetFloorHeight(floor, pos.x, pos.y, pos.z);
TestTriggers(TriggerIndex, 1, 0);
}

View file

@ -110,7 +110,7 @@ void ControlGunShip(short itemNumber)
if (hitMesh->staticNumber >= 50 && hitMesh->staticNumber < 59)
{
ShatterObject(0, hitMesh, 64, end.roomNumber, 0);
hitMesh->Flags &= 0xFFFE;
hitMesh->flags &= 0xFFFE;
TestTriggersAtXYZ(hitMesh->x, hitMesh->y, hitMesh->z, end.roomNumber, 1, 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->stopper)
{
for (i = 0; i < room->numMeshes; i++)
for (i = 0; i < room->mesh.size(); i++)
{
mesh = &room->mesh[i];
@ -619,7 +619,7 @@ void RomanStatueControl(short itemNumber)
(PHD_3DPOS*)mesh,
0);
mesh->Flags &= ~1;
mesh->flags &= ~1;
floor->stopper = false;
GetFloorHeight(floor, pos.x, pos.y, pos.z);
TestTriggers(TriggerIndex, 1, 0);

View file

@ -77,7 +77,7 @@ void Renderer11::createBillboardMatrix(Matrix* out, Vector3* particlePos, Vector
void Renderer11::updateAnimatedTextures()
{
// 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;
RendererRoom & const room = m_rooms[i];
@ -888,16 +888,11 @@ void Renderer11::getVisibleRooms(int from, int to, Vector4* viewPort, bool water
Vector4 clipPort;
if (room->door != NULL)
for (int i = 0; i < room->doors.size(); i++)
{
short numDoors = *(room->door);
if (numDoors)
{
short* door = room->door + 1;
for (int i = 0; i < numDoors; i++) {
short adjoiningRoom = *(door);
short adjoiningRoom = room->doors[i].room;
if (node->From != adjoiningRoom && checkPortal(node->To, door, viewPort, &node->ClipPort))
if (node->From != adjoiningRoom && checkPortal(node->To, &room->doors[i], viewPort, &node->ClipPort))
{
RendererRoomNode* childNode = &nodes[nextNode++];
childNode->From = node->To;
@ -906,25 +901,19 @@ void Renderer11::getVisibleRooms(int from, int to, Vector4* viewPort, bool water
// 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];
portal++;
Vector3 n = Vector3(portal[0], portal[1], portal[2]);
Vector3 n = portal->normal;
Vector3 v = Vector3(
Camera.pos.x - (room->x + portal[3]),
Camera.pos.y - (room->y + portal[4]),
Camera.pos.z - (room->z + portal[5]));
Camera.pos.x - (room->x + portal->vertices[0].x),
Camera.pos.y - (room->y + portal->vertices[0].y),
Camera.pos.z - (room->z + portal->vertices[0].z));
// Test camera and normal positions and decide if process door or not
if (n.Dot(v) <= 0.0f)
@ -938,12 +927,10 @@ bool Renderer11::checkPortal(short roomIndex, short* portal, Vector4* viewPort,
clipPort->z = FLT_MIN;
clipPort->w = FLT_MIN;
portal += 3;
// 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
Vector4::Transform(tmp, ViewProjection, p[i]);

View file

@ -624,7 +624,7 @@ private:
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);
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 collectRooms();
void collectItems(short roomNumber);

View file

@ -152,7 +152,7 @@ bool Renderer11::PrepareDataForTheRenderer()
int baseRoomVertex = 0;
int baseRoomIndex = 0;
for (int i = 0; i < NumberRooms; i++)
for (int i = 0; i < Rooms.size(); i++)
{
ROOM_INFO* room = &Rooms[i];
@ -163,30 +163,16 @@ bool Renderer11::PrepareDataForTheRenderer()
r.Room = room;
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.Statics.resize(room->numMeshes);
r.Statics.resize(room->mesh.size());
if (room->NumVertices == 0)
if (room->vertices.size() == 0)
continue;
int lastRectangle = 0;
int lastTriangle = 0;
tr5_room_vertex * vertices = room->vertices.data();
tr5_room_layer * layers = (tr5_room_layer*)room->LayerOffset;
for (int l = 0; l < room->NumLayers; l++)
for (int n = 0; n < room->quads.size(); n++)
{
tr5_room_layer* layer = &layers[l];
if (layer->NumLayerVertices == 0)
continue;
byte * polygons = (byte*)layer->PolyOffset;
tr5_room_vertex * vertices = (tr5_room_vertex*)layer->VerticesOffset;
if (layer->NumLayerRectangles > 0)
{
for (int n = 0; n < layer->NumLayerRectangles; n++)
{
tr4_mesh_face4* poly = (tr4_mesh_face4*)polygons;
tr4_mesh_face4* poly = &room->quads[n];
// Get the real texture index and if double sided
short textureIndex = poly->Texture & 0x3FFF;
@ -285,16 +271,11 @@ bool Renderer11::PrepareDataForTheRenderer()
newPolygon.Indices[2] = baseVertices + 2;
newPolygon.Indices[3] = baseVertices + 3;
bucket->Polygons.push_back(newPolygon);
polygons += sizeof(tr4_mesh_face4);
}
}
if (layer->NumLayerTriangles > 0)
for (int n = 0; n < room->triangles.size(); n++)
{
for (int n = 0; n < layer->NumLayerTriangles; n++)
{
tr4_mesh_face3* poly = (tr4_mesh_face3*)polygons;
tr4_mesh_face3* poly = &room->triangles[n];
// Get the real texture index and if double sided
short textureIndex = poly->Texture & 0x3FFF;
@ -389,21 +370,16 @@ bool Renderer11::PrepareDataForTheRenderer()
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
bucket->Polygons.push_back(newPolygon);
polygons += sizeof(tr4_mesh_face3);
}
}
}
if (room->numLights != 0)
if (room->lights.size() != 0)
{
tr5_room_light* oldLight = room->light;
for (int l = 0; l < room->numLights; l++)
for (int l = 0; l < room->lights.size(); l++)
{
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.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
@ -412,38 +388,38 @@ bool Renderer11::PrepareDataForTheRenderer()
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.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Intensity = 1.0f;
light.In = oldLight->In;
light.Out = oldLight->Out;
light.In = oldLight->in;
light.Out = oldLight->out;
light.Type = LIGHT_TYPE_POINT;
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.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.In = oldLight->In;
light.Out = oldLight->Out;
light.In = oldLight->in;
light.Out = oldLight->out;
light.Type = LIGHT_TYPE_SHADOW;
light.Intensity = 1.0f;
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.Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light.Direction = Vector4(oldLight->dx, oldLight->dy, oldLight->dz, 1.0f);
light.Intensity = 1.0f;
light.In = oldLight->In;
light.Out = oldLight->Out;
light.Range = oldLight->Range;
light.In = oldLight->in;
light.Out = oldLight->out;
light.Range = oldLight->range;
light.Type = LIGHT_TYPE_SPOT;
r.Lights.push_back(light);

View file

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

View file

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

View file

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

View file

@ -50,8 +50,7 @@ char* LevelDataPtr;
vector<OBJECT_TEXTURE> ObjectTextures;
ITEM_INFO* Items;
int LevelItems;
int NumberRooms;
ROOM_INFO* Rooms;
std::vector<ROOM_INFO> Rooms;
ANIM_STRUCT* Anims;
CHANGE_STRUCT* Changes;
RANGE_STRUCT* Ranges;
@ -91,6 +90,13 @@ short ReadInt16()
return value;
}
unsigned short ReadUInt16()
{
unsigned short value = *(unsigned short*)LevelDataPtr;
LevelDataPtr += 2;
return value;
}
int ReadInt32()
{
int value = *(int*)LevelDataPtr;
@ -144,11 +150,11 @@ int LoadItems()
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)];
@ -396,109 +402,178 @@ void LoadTextures()
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()
{
ReadInt32();
int numRooms = ReadInt32();
NumberRooms = numRooms;
Rooms = (ROOM_INFO*)game_malloc(NumberRooms * sizeof(ROOM_INFO));
//NumberRooms = numRooms;
//Rooms = (ROOM_INFO*)game_malloc(NumberRooms * sizeof(ROOM_INFO));
Rooms.clear();
printf("NumRooms: %d\n", numRooms);
for (int i = 0; i < NumberRooms; i++)
for (int i = 0; i < numRooms; i++)
{
// Ignore XELA
int xela = ReadInt32();
ROOM_INFO room;
// Read room data
int roomDataSize = ReadInt32();
byte* roomData = (byte*)game_malloc(roomDataSize);
ReadBytes(roomData, roomDataSize);
room.x = ReadInt32();
room.y = 0;
room.z = ReadInt32();
room.minfloor = ReadInt32();
room.maxceiling = ReadInt32();
// Put the room data in the struct
FixUpRoom(&Rooms[i], (ROOM_INFO*)roomData);
int numDataWords = ReadInt32();
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 ITEM_INFO* Items;
extern int LevelItems;
extern int NumberRooms;
extern ROOM_INFO* Rooms;
extern std::vector<ROOM_INFO> Rooms;
extern ANIM_STRUCT* Anims;
extern CHANGE_STRUCT* Changes;
extern RANGE_STRUCT* Ranges;
@ -159,7 +158,6 @@ void LoadTextureInfos();
void LoadAIObjects();
FILE* FileOpen(const char* fileName);
void FileClose(FILE* ptr);
void FixUpRoom(ROOM_INFO* room, ROOM_INFO* roomData);
void Decompress(byte* dest, byte* src, unsigned long compressedSize, unsigned long uncompressedSize);
unsigned CALLBACK LoadLevel(void* data);