Decompiled wraiths; Added outside rooms table;

This commit is contained in:
Montagna Marco 2020-08-02 19:39:55 +02:00
parent 45e1754c91
commit 325b5841d0
8 changed files with 145 additions and 196 deletions

View file

@ -1009,7 +1009,7 @@ int UpdateLOT(LOT_INFO* LOT, int depth)
{ {
BOX_NODE* node; BOX_NODE* node;
printf("LOT->head: %d, LOT->tail: %d\n", LOT->head, LOT->tail); //printf("LOT->head: %d, LOT->tail: %d\n", LOT->head, LOT->tail);
if (LOT->requiredBox != NO_BOX && LOT->requiredBox != LOT->targetBox) if (LOT->requiredBox != NO_BOX && LOT->requiredBox != LOT->targetBox)
{ {

View file

@ -43,11 +43,13 @@
#include "spark.h" #include "spark.h"
#include "explosion.h" #include "explosion.h"
#include "drip.h" #include "drip.h"
using std::vector; using std::vector;
using namespace T5M::Effects::Explosion; using namespace T5M::Effects::Explosion;
using namespace T5M::Effects::Spark; using namespace T5M::Effects::Spark;
using namespace T5M::Effects::Smoke; using namespace T5M::Effects::Smoke;
using T5M::Renderer::g_Renderer; using T5M::Renderer::g_Renderer;
short ShatterSounds[18][10] = short ShatterSounds[18][10] =
{ {
{SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS}, {SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS, SFX_SMASH_GLASS},
@ -147,12 +149,14 @@ short FlashFadeR;
short FlashFadeG; short FlashFadeG;
short FlashFadeB; short FlashFadeB;
short FlashFader; short FlashFader;
short IsRoomOutsideNo;
int TiltXOffset; int TiltXOffset;
int TiltYOffset; int TiltYOffset;
int FramesCount; int FramesCount;
std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
short IsRoomOutsideNo;
extern GameFlow *g_GameFlow; extern GameFlow *g_GameFlow;
extern GameScript *g_GameScript; extern GameScript *g_GameScript;
extern Inventory g_Inventory; extern Inventory g_Inventory;
@ -3239,21 +3243,18 @@ void InterpolateAngle(short angle, short *rotation, short *outAngle, int shift)
int IsRoomOutside(int x, int y, int z) int IsRoomOutside(int x, int y, int z)
{ {
return 0; int xTable = x / 4 / 1024;
/* int zTable = z / 4 / 1024;
short offset = OutsideRoomOffsets[((x >> 12) * 27) + (z >> 12)];
if (offset == -1)
return -2;
if (offset < 0) for (int i = 0; i < OutsideRoomTable[xTable][zTable].size(); i++)
{ {
ROOM_INFO* r = &g_Level.Rooms[(offset & 0x7FFF)]; short roomNumber = OutsideRoomTable[xTable][zTable][i];
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
if ((y > r->maxceiling) && (y < r->minfloor) if ((y > r->maxceiling) && (y < r->minfloor)
&& ((z > (r->z + 1024)) && (z < (r->z + ((r->xSize - 1) * 1024)))) && ((z > (r->z + 1024)) && (z < (r->z + ((r->xSize - 1) * 1024))))
&& ((x > (r->x + 1024)) && (x < (r->x + ((r->ySize - 1) * 1024))))) && ((x > (r->x + 1024)) && (x < (r->x + ((r->ySize - 1) * 1024)))))
{ {
short roomNumber = offset & 0x7fff;
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber); FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
int height = GetFloorHeight(floor, x, y, z); int height = GetFloorHeight(floor, x, y, z);
if (height == NO_HEIGHT || y > height) if (height == NO_HEIGHT || y > height)
@ -3265,41 +3266,10 @@ int IsRoomOutside(int x, int y, int z)
if (!(r->flags & (ENV_FLAG_WIND | ENV_FLAG_WATER))) if (!(r->flags & (ENV_FLAG_WIND | ENV_FLAG_WATER)))
return -3; return -3;
IsRoomOutsideNo = offset & 0x7FFF; IsRoomOutsideNo = roomNumber;
return 1; return 1;
} }
else
return -2;
} }
else
{
unsigned char* s = &OutsideRoomTable[offset];
while (*s != 0xFF) return -2;
{
ROOM_INFO* r = &g_Level.Rooms[*s];
if ((y > r->maxceiling && y < r->minfloor)
&& ((z > (r->z + 1024)) && (z < (r->z + ((r->xSize - 1) * 1024))))
&& ((x > (r->x + 1024)) && (x < (r->x + ((r->ySize - 1) * 1024)))))
{
short roomNumber = *s;
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
int height = GetFloorHeight(floor, x, y, z);
if (height == NO_HEIGHT || y > height)
return -2;
height = GetCeiling(floor, x, y, z);
if (y < height)
return -2;
if (!(r->flags & (ENV_FLAG_WIND | ENV_FLAG_WATER)))
return -3;
IsRoomOutsideNo = *s;
return 1;
}
s++;
}
return -2;
}*/
} }

View file

@ -58,6 +58,9 @@ enum COMMAND_TYPES
#define TRIG_BITS(T) ((T & 0x3FFF) >> 10) #define TRIG_BITS(T) ((T & 0x3FFF) >> 10)
#define OUTSIDE_Z 64
#define OUTSIDE_SIZE 108
extern int KeyTriggerActive; extern int KeyTriggerActive;
extern byte IsAtmospherePlaying; extern byte IsAtmospherePlaying;
extern byte FlipStatus; extern byte FlipStatus;
@ -130,9 +133,10 @@ extern short FlashFadeR;
extern short FlashFadeG; extern short FlashFadeG;
extern short FlashFadeB; extern short FlashFadeB;
extern short FlashFader; extern short FlashFader;
extern short IsRoomOutsideNo;
extern int TiltXOffset; extern int TiltXOffset;
extern int TiltYOffset; extern int TiltYOffset;
extern std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
extern short IsRoomOutsideNo;
GAME_STATUS DoTitle(int index); GAME_STATUS DoTitle(int index);
GAME_STATUS DoLevel(int index, int ambient, bool loadFromSavegame); GAME_STATUS DoLevel(int index, int ambient, bool loadFromSavegame);

View file

@ -49,6 +49,7 @@ void WraithControl(short itemNumber)
SoundEffect(SFX_TR4_WRAITH_WHISPERS, &item->pos, 0); SoundEffect(SFX_TR4_WRAITH_WHISPERS, &item->pos, 0);
// hitPoints stores the target of wraith
ITEM_INFO* target; ITEM_INFO* target;
if (item->hitPoints) if (item->hitPoints)
target = &g_Level.Items[item->hitPoints]; target = &g_Level.Items[item->hitPoints];
@ -57,7 +58,7 @@ void WraithControl(short itemNumber)
int x, y, z, distance, dx, dy, dz, oldX, oldY, oldZ; int x, y, z, distance, dx, dy, dz, oldX, oldY, oldZ;
if (target == LaraItem || target->objectNumber == 445) if (target == LaraItem || target->objectNumber == ID_ANIMATING10)
{ {
x = target->pos.xPos - item->pos.xPos; x = target->pos.xPos - item->pos.xPos;
y = target->pos.yPos; y = target->pos.yPos;
@ -165,6 +166,7 @@ void WraithControl(short itemNumber)
item->pos.zPos += item->speed * phd_cos(item->pos.yRot) >> W2V_SHIFT; item->pos.zPos += item->speed * phd_cos(item->pos.yRot) >> W2V_SHIFT;
IsRoomOutsideNo = NO_ROOM; IsRoomOutsideNo = NO_ROOM;
IsRoomOutside(item->pos.xPos, item->pos.yPos, item->pos.zPos);
if (item->roomNumber != IsRoomOutsideNo && IsRoomOutsideNo != NO_ROOM) if (item->roomNumber != IsRoomOutsideNo && IsRoomOutsideNo != NO_ROOM)
{ {
ItemNewRoom(itemNumber, IsRoomOutsideNo); ItemNewRoom(itemNumber, IsRoomOutsideNo);
@ -243,9 +245,9 @@ void WraithControl(short itemNumber)
} }
if (item->hitPoints) if (item->hitPoints)
{ {
if (item->TOSSPAD & 0x3E00) if (item->TOSSPAD /*& 0x3E00*/)
{ {
item->TOSSPAD = ((item->TOSSPAD & 0xFE00) - 1) & 0x3E00; item->TOSSPAD--; // = ((item->TOSSPAD & 0xFE00) - 1) & 0x3E00;
} }
} }
} }
@ -273,8 +275,8 @@ void WraithControl(short itemNumber)
else if (target->objectNumber == ID_ANIMATING10) else if (target->objectNumber == ID_ANIMATING10)
{ {
// ANIMATING10 is the sacred pedistal that can kill WRAITH // ANIMATING10 is the sacred pedistal that can kill WRAITH
item->TOSSPAD = ((item->TOSSPAD & 0xFE00) + 512) & 0x3E00; // HACK: maybe create new var for this item->TOSSPAD++; // ((item->TOSSPAD & 0xFE00) + 512) & 0x3E00; // HACK: maybe create new var for this
if (item->TOSSPAD & 0x3E00 > 12800) if (item->TOSSPAD > 25 /* (item->TOSSPAD & 0x3E00) > 12800*/)
{ {
item->pos.xPos = target->pos.xPos; item->pos.xPos = target->pos.xPos;
item->pos.yPos = target->pos.yPos - 384; item->pos.yPos = target->pos.yPos - 384;
@ -293,8 +295,8 @@ void WraithControl(short itemNumber)
else else
{ {
// Target is another WRAITH (fire vs ice), they kill both themselves // Target is another WRAITH (fire vs ice), they kill both themselves
item->TOSSPAD = item->TOSSPAD & 0xD5FF | 0x1400; item->TOSSPAD = item->TOSSPAD & 0xD5 | 0x14;
if (item->TOSSPAD & 0x3E00) if (item->TOSSPAD /*& 0x3E00*/)
{ {
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos, item->pos.zPos, 2, -2, 1, item->roomNumber); TriggerExplosionSparks(item->pos.xPos, item->pos.yPos, item->pos.zPos, 2, -2, 1, item->roomNumber);
target->hitPoints = 0; target->hitPoints = 0;
@ -325,13 +327,13 @@ void WraithControl(short itemNumber)
int j = 0; int j = 0;
for (int i = WRAITH_COUNT - 1; i > 0; i--) for (int i = WRAITH_COUNT - 1; i > 0; i--)
{ {
creature[i - 1].xPos += (creature[i - 1].xRot / 16); creature[i - 1].xPos += (creature[i - 1].xRot >> 4);
creature[i - 1].yPos += (creature[i - 1].yRot / 16); creature[i - 1].yPos += (creature[i - 1].yRot >> 4);
creature[i - 1].zPos += (creature[i - 1].zRot / 16); creature[i - 1].zPos += (creature[i - 1].zRot >> 4);
creature[i - 1].xRot -= (creature[i - 1].xRot / 16); creature[i - 1].xRot -= (creature[i - 1].xRot >> 4);
creature[i - 1].yRot -= (creature[i - 1].yRot / 16); creature[i - 1].yRot -= (creature[i - 1].yRot >> 4);
creature[i - 1].zRot -= (creature[i - 1].zRot / 16); creature[i - 1].zRot -= (creature[i - 1].zRot >> 4);
creature[i].xPos = creature[i - 1].xPos; creature[i].xPos = creature[i - 1].xPos;
creature[i].yPos = creature[i - 1].yPos; creature[i].yPos = creature[i - 1].yPos;
@ -367,9 +369,9 @@ void WraithControl(short itemNumber)
creature[0].yPos = item->pos.yPos; creature[0].yPos = item->pos.yPos;
creature[0].zPos = item->pos.zPos; creature[0].zPos = item->pos.zPos;
creature[0].xRot = (item->pos.xPos - oldX); creature[0].xRot = 4 * (item->pos.xPos - oldX);
creature[0].yRot = (item->pos.yPos - oldY); creature[0].yRot = 4 * (item->pos.yPos - oldY);
creature[0].zRot = (item->pos.zPos - oldZ); creature[0].zRot = 4 * (item->pos.zPos - oldZ);
// Standard WRAITH drawing code // Standard WRAITH drawing code
DrawWraith( DrawWraith(

View file

@ -566,6 +566,7 @@ namespace T5M::Renderer
bool drawScaledSpikes(RendererItem* item, bool transparent, bool animated); bool drawScaledSpikes(RendererItem* item, bool transparent, bool animated);
bool drawStatics(bool transparent, RenderView& view); bool drawStatics(bool transparent, RenderView& view);
bool drawWaterfalls(); bool drawWaterfalls();
bool drawWraithExtra(RendererItem* item, bool transparent, bool animated);
bool drawShadowMap(); bool drawShadowMap();
bool drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ); bool drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ);
bool drawLara(bool transparent, bool shadowMap); bool drawLara(bool transparent, bool shadowMap);

View file

@ -19,6 +19,7 @@
#include "tr5_bats_emitter.h" #include "tr5_bats_emitter.h"
#include "tr5_spider_emitter.h" #include "tr5_spider_emitter.h"
#include "ConstantBuffers/CameraMatrixBuffer.h" #include "ConstantBuffers/CameraMatrixBuffer.h"
#include <Objects\TR4\Entity\tr4_wraith.h>
#include "RenderView/RenderView.h" #include "RenderView/RenderView.h"
extern T5M::Renderer::RendererHUDBar *g_DashBar; extern T5M::Renderer::RendererHUDBar *g_DashBar;
extern T5M::Renderer::RendererHUDBar *g_SFXVolumeBar; extern T5M::Renderer::RendererHUDBar *g_SFXVolumeBar;
@ -2181,6 +2182,12 @@ namespace T5M::Renderer
// We'll draw waterfalls later // We'll draw waterfalls later
continue; continue;
} }
else if (objectNumber >= ID_WRAITH1 && objectNumber <= ID_WRAITH3)
{
// Wraiths have some additional special effects
drawAnimatingItem(item, transparent, animated);
drawWraithExtra(item, transparent, animated);
}
else else
{ {
drawAnimatingItem(item, transparent, animated); drawAnimatingItem(item, transparent, animated);
@ -2267,6 +2274,62 @@ namespace T5M::Renderer
} }
} }
bool Renderer11::drawWraithExtra(RendererItem* item, bool transparent, bool animated)
{
ITEM_INFO* nativeItem = item->Item;
WRAITH_INFO* info = (WRAITH_INFO*)nativeItem->data;
if (transparent || animated)
return true;
for (int j = 0; j <= 4; j++)
{
Matrix rotation;
switch (j)
{
case 0:
rotation = Matrix::CreateRotationY(TO_RAD(-1092));
break;
case 1:
rotation = Matrix::CreateRotationY(TO_RAD(1092));
break;
case 2:
rotation = Matrix::CreateRotationZ(TO_RAD(-1092));
break;
case 3:
rotation = Matrix::CreateRotationZ(TO_RAD(1092));
break;
default:
rotation = Matrix::Identity;
break;
}
Matrix world = rotation * item->World;
/*for (int i = 0; i < 7; i++)
{
Vector3 p1 = Vector3(info[i].xPos - nativeItem->pos.xPos, info[i].yPos - nativeItem->pos.yPos, info[i].zPos - nativeItem->pos.zPos);
Vector3 p2 = Vector3(info[i+1].xPos - info[i ].xPos, info[i + 1].yPos - info[i ].yPos, info[i + 1].zPos - info[i ].zPos);
p1 = Vector3::Transform(p1, world);
p2 = Vector3::Transform(p2, world);
AddLine3D(p1, p2, Vector4(info[i].r / 255.0f, info[i].g / 255.0f, info[i].b / 255.0f, 1.0f));
}*/
for (int i = 0; i < 7; i++)
{
Vector3 p1 = Vector3(info[i].xPos, info[i].yPos, info[i].zPos);
Vector3 p2 = Vector3(info[i + 1].xPos , info[i + 1].yPos, info[i + 1].zPos);
AddLine3D(p1, p2, Vector4(info[i].r / 255.0f, info[i].g / 255.0f, info[i].b / 255.0f, 1.0f));
}
}
return true;
}
bool Renderer11::drawStatics(bool transparent, RenderView &view) bool Renderer11::drawStatics(bool transparent, RenderView &view)
{ {
//return true; //return true;

View file

@ -647,141 +647,6 @@ void ReadRooms()
} }
} }
void BuildOutsideRoomsTable()
{
/*long max_slots = 0;
AllocT(OutsideRoomOffsets, short, 27 * 27);
AllocT(OutsideRoomTable, char, 27 * 27 * OUTSIDE_Z);
memset(OutsideRoomTable, -1, 27 * 27 * OUTSIDE_Z);
char flipped[256];
memset(flipped, 0, 255);
for (int i = 0; i < number_rooms; i++)
{
if (room[i].flipped_room != -1)
flipped[i] = true;
}
for (int y = 0; y < 108; y += 4)
{
for (int x = 0; x < 108; x += 4)
{
for (int i = 0; i < number_rooms; i++)
{
const auto r = &room[i];
if (!flipped[i])
{
const int rx = (r->z >> SECTOR(1)) + 1;
const int ry = (r->x >> SECTOR(1)) + 1;
int j = 0;
for (int yl = 0; yl < 4; yl++)
{
for (int xl = 0; xl < 4; xl++)
{
if ((x + xl) >= rx && (x + xl) < (rx + r->x_size - 2) &&
(y + yl) >= ry && (y + yl) < (ry + r->y_size - 2))
{
j = 1;
break;
}
}
}
if (!j)
continue;
if (i == 255)
{
S_Warn("ERROR : Room 255 fuckeroony - go tell Chris\n");
}
char* d = &OutsideRoomTable[OUTSIDE_Z * (x >> 2) + OUTSIDE_Z * (y >> 2) * 27];
for (int j = 0; j < OUTSIDE_Z; j++)
{
if (d[j] == -1)
{
d[j] = i;
if (j > max_slots)
max_slots = j;
break;
}
}
if (j == OUTSIDE_Z)
{
S_Warn("ERROR : Buffer shittage - go tell Chris\n");
}
}
}
}
}
// todo it's a bit incorrect
char* s = OutsideRoomTable;
for (int y = 0; y < 27; y++)
{
for (int x = 0; x < 27; x++)
{
int z = 0;
char* d = &OutsideRoomTable[OUTSIDE_Z * x + OUTSIDE_Z * y * 27];
const int i = 27 * y + x;
while (d[z] != -1)
z++;
if (z == 0)
{
OutsideRoomOffsets[i] = -1;
}
else if (z == 1)
{
OutsideRoomOffsets[i] = *d | 0x8000;
}
else
{
char* p = OutsideRoomTable;
while (p < s)
{
if (memcmp(p, d, z) == 0)
{
OutsideRoomOffsets[i] = p - OutsideRoomTable;
break;
}
else
{
int z2 = 0;
while (p[z2] != -1)
z2++;
p += z2 + 1;
}
}
if (p >= s)
{
OutsideRoomOffsets[i] = s - OutsideRoomTable;
while (z-- > 0)
* s++ = *d++;
*s++ = -1;
}
}
}
}*/
}
void LoadRooms() void LoadRooms()
{ {
printf("LoadRooms\n"); printf("LoadRooms\n");
@ -1244,4 +1109,47 @@ void GetAIPickups()
item->TOSSPAD |= item->aiBits << 8 | (char) item->itemFlags[3]; item->TOSSPAD |= item->aiBits << 8 | (char) item->itemFlags[3];
} }
} }
} }
void BuildOutsideRoomsTable()
{
int maxSlots = 0;
// Clear the tabel
for (int x = 0; x < OUTSIDE_SIZE; x++)
for (int z = 0; z < OUTSIDE_SIZE; z++)
OutsideRoomTable[x][z].clear();
for (int x = 0; x < OUTSIDE_SIZE * 4; x += 4)
{
for (int z = 0; z < OUTSIDE_SIZE * 4; z += 4)
{
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
ROOM_INFO* r = &g_Level.Rooms[i];
int rx = (r->x / 1024) + 1;
int rz = (r->z / 1024) + 1;
bool found = false;
for (int xl = 0; xl < 4; xl++)
{
for (int zl = 0; zl < 4; zl++)
{
if ((x + xl) >= rx && (x + xl) < (rx + r->ySize - 2) &&
(z + zl) >= rz && (z + zl) < (rz + r->xSize - 2))
{
found = true;
break;
}
}
}
if (!found)
continue;
OutsideRoomTable[x][z].push_back(i);
}
}
}
}

View file

@ -166,5 +166,6 @@ void LoadAIObjects();
FILE* FileOpen(const char* fileName); FILE* FileOpen(const char* fileName);
void FileClose(FILE* ptr); void FileClose(FILE* ptr);
bool Decompress(byte* dest, byte* src, unsigned long compressedSize, unsigned long uncompressedSize); bool Decompress(byte* dest, byte* src, unsigned long compressedSize, unsigned long uncompressedSize);
void BuildOutsideRoomsTable();
unsigned CALLBACK LoadLevel(void* data); unsigned CALLBACK LoadLevel(void* data);