diff --git a/TR5Main/Game/box.cpp b/TR5Main/Game/box.cpp index 121df5d00..b4e3c8516 100644 --- a/TR5Main/Game/box.cpp +++ b/TR5Main/Game/box.cpp @@ -1009,7 +1009,7 @@ int UpdateLOT(LOT_INFO* LOT, int depth) { 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) { diff --git a/TR5Main/Game/control.cpp b/TR5Main/Game/control.cpp index 444db6365..8348a3d46 100644 --- a/TR5Main/Game/control.cpp +++ b/TR5Main/Game/control.cpp @@ -43,11 +43,13 @@ #include "spark.h" #include "explosion.h" #include "drip.h" + using std::vector; using namespace T5M::Effects::Explosion; using namespace T5M::Effects::Spark; using namespace T5M::Effects::Smoke; using T5M::Renderer::g_Renderer; + 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}, @@ -147,12 +149,14 @@ short FlashFadeR; short FlashFadeG; short FlashFadeB; short FlashFader; -short IsRoomOutsideNo; int TiltXOffset; int TiltYOffset; int FramesCount; +std::vector OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE]; +short IsRoomOutsideNo; + extern GameFlow *g_GameFlow; extern GameScript *g_GameScript; 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) { - return 0; - /* - short offset = OutsideRoomOffsets[((x >> 12) * 27) + (z >> 12)]; - if (offset == -1) - return -2; + int xTable = x / 4 / 1024; + int zTable = z / 4 / 1024; - 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) && ((z > (r->z + 1024)) && (z < (r->z + ((r->xSize - 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); int height = GetFloorHeight(floor, x, y, z); 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))) return -3; - IsRoomOutsideNo = offset & 0x7FFF; + IsRoomOutsideNo = roomNumber; return 1; } - else - return -2; } - else - { - unsigned char* s = &OutsideRoomTable[offset]; - while (*s != 0xFF) - { - 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; - }*/ + return -2; } diff --git a/TR5Main/Game/control.h b/TR5Main/Game/control.h index 26e16f131..f37729fe1 100644 --- a/TR5Main/Game/control.h +++ b/TR5Main/Game/control.h @@ -58,6 +58,9 @@ enum COMMAND_TYPES #define TRIG_BITS(T) ((T & 0x3FFF) >> 10) +#define OUTSIDE_Z 64 +#define OUTSIDE_SIZE 108 + extern int KeyTriggerActive; extern byte IsAtmospherePlaying; extern byte FlipStatus; @@ -130,9 +133,10 @@ extern short FlashFadeR; extern short FlashFadeG; extern short FlashFadeB; extern short FlashFader; -extern short IsRoomOutsideNo; extern int TiltXOffset; extern int TiltYOffset; +extern std::vector OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE]; +extern short IsRoomOutsideNo; GAME_STATUS DoTitle(int index); GAME_STATUS DoLevel(int index, int ambient, bool loadFromSavegame); diff --git a/TR5Main/Objects/TR4/Entity/tr4_wraith.cpp b/TR5Main/Objects/TR4/Entity/tr4_wraith.cpp index 37a45936f..8708eb3e6 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_wraith.cpp +++ b/TR5Main/Objects/TR4/Entity/tr4_wraith.cpp @@ -49,6 +49,7 @@ void WraithControl(short itemNumber) SoundEffect(SFX_TR4_WRAITH_WHISPERS, &item->pos, 0); + // hitPoints stores the target of wraith ITEM_INFO* target; if (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; - if (target == LaraItem || target->objectNumber == 445) + if (target == LaraItem || target->objectNumber == ID_ANIMATING10) { x = target->pos.xPos - item->pos.xPos; y = target->pos.yPos; @@ -165,6 +166,7 @@ void WraithControl(short itemNumber) item->pos.zPos += item->speed * phd_cos(item->pos.yRot) >> W2V_SHIFT; IsRoomOutsideNo = NO_ROOM; + IsRoomOutside(item->pos.xPos, item->pos.yPos, item->pos.zPos); if (item->roomNumber != IsRoomOutsideNo && IsRoomOutsideNo != NO_ROOM) { ItemNewRoom(itemNumber, IsRoomOutsideNo); @@ -243,9 +245,9 @@ void WraithControl(short itemNumber) } 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) { // ANIMATING10 is the sacred pedistal that can kill WRAITH - item->TOSSPAD = ((item->TOSSPAD & 0xFE00) + 512) & 0x3E00; // HACK: maybe create new var for this - if (item->TOSSPAD & 0x3E00 > 12800) + item->TOSSPAD++; // ((item->TOSSPAD & 0xFE00) + 512) & 0x3E00; // HACK: maybe create new var for this + if (item->TOSSPAD > 25 /* (item->TOSSPAD & 0x3E00) > 12800*/) { item->pos.xPos = target->pos.xPos; item->pos.yPos = target->pos.yPos - 384; @@ -293,8 +295,8 @@ void WraithControl(short itemNumber) else { // Target is another WRAITH (fire vs ice), they kill both themselves - item->TOSSPAD = item->TOSSPAD & 0xD5FF | 0x1400; - if (item->TOSSPAD & 0x3E00) + item->TOSSPAD = item->TOSSPAD & 0xD5 | 0x14; + if (item->TOSSPAD /*& 0x3E00*/) { TriggerExplosionSparks(item->pos.xPos, item->pos.yPos, item->pos.zPos, 2, -2, 1, item->roomNumber); target->hitPoints = 0; @@ -325,13 +327,13 @@ void WraithControl(short itemNumber) int j = 0; for (int i = WRAITH_COUNT - 1; i > 0; i--) { - creature[i - 1].xPos += (creature[i - 1].xRot / 16); - creature[i - 1].yPos += (creature[i - 1].yRot / 16); - creature[i - 1].zPos += (creature[i - 1].zRot / 16); + creature[i - 1].xPos += (creature[i - 1].xRot >> 4); + creature[i - 1].yPos += (creature[i - 1].yRot >> 4); + creature[i - 1].zPos += (creature[i - 1].zRot >> 4); - creature[i - 1].xRot -= (creature[i - 1].xRot / 16); - creature[i - 1].yRot -= (creature[i - 1].yRot / 16); - creature[i - 1].zRot -= (creature[i - 1].zRot / 16); + creature[i - 1].xRot -= (creature[i - 1].xRot >> 4); + creature[i - 1].yRot -= (creature[i - 1].yRot >> 4); + creature[i - 1].zRot -= (creature[i - 1].zRot >> 4); creature[i].xPos = creature[i - 1].xPos; creature[i].yPos = creature[i - 1].yPos; @@ -367,9 +369,9 @@ void WraithControl(short itemNumber) creature[0].yPos = item->pos.yPos; creature[0].zPos = item->pos.zPos; - creature[0].xRot = (item->pos.xPos - oldX); - creature[0].yRot = (item->pos.yPos - oldY); - creature[0].zRot = (item->pos.zPos - oldZ); + creature[0].xRot = 4 * (item->pos.xPos - oldX); + creature[0].yRot = 4 * (item->pos.yPos - oldY); + creature[0].zRot = 4 * (item->pos.zPos - oldZ); // Standard WRAITH drawing code DrawWraith( diff --git a/TR5Main/Renderer/Renderer11.h b/TR5Main/Renderer/Renderer11.h index cea52b2ad..640c2a70d 100644 --- a/TR5Main/Renderer/Renderer11.h +++ b/TR5Main/Renderer/Renderer11.h @@ -566,6 +566,7 @@ namespace T5M::Renderer bool drawScaledSpikes(RendererItem* item, bool transparent, bool animated); bool drawStatics(bool transparent, RenderView& view); bool drawWaterfalls(); + bool drawWraithExtra(RendererItem* item, bool transparent, bool animated); bool drawShadowMap(); bool drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ); bool drawLara(bool transparent, bool shadowMap); diff --git a/TR5Main/Renderer/Renderer11Draw.cpp b/TR5Main/Renderer/Renderer11Draw.cpp index 2f36835c1..35d2fca9e 100644 --- a/TR5Main/Renderer/Renderer11Draw.cpp +++ b/TR5Main/Renderer/Renderer11Draw.cpp @@ -19,6 +19,7 @@ #include "tr5_bats_emitter.h" #include "tr5_spider_emitter.h" #include "ConstantBuffers/CameraMatrixBuffer.h" +#include #include "RenderView/RenderView.h" extern T5M::Renderer::RendererHUDBar *g_DashBar; extern T5M::Renderer::RendererHUDBar *g_SFXVolumeBar; @@ -2181,6 +2182,12 @@ namespace T5M::Renderer // We'll draw waterfalls later continue; } + else if (objectNumber >= ID_WRAITH1 && objectNumber <= ID_WRAITH3) + { + // Wraiths have some additional special effects + drawAnimatingItem(item, transparent, animated); + drawWraithExtra(item, transparent, animated); + } else { 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) { //return true; diff --git a/TR5Main/Specific/level.cpp b/TR5Main/Specific/level.cpp index 2ba0dd3b1..8fa7fa905 100644 --- a/TR5Main/Specific/level.cpp +++ b/TR5Main/Specific/level.cpp @@ -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() { printf("LoadRooms\n"); @@ -1244,4 +1109,47 @@ void GetAIPickups() item->TOSSPAD |= item->aiBits << 8 | (char) item->itemFlags[3]; } } -} \ No newline at end of file +} + +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); + } + } + } +} diff --git a/TR5Main/Specific/level.h b/TR5Main/Specific/level.h index 07023b7ec..93e0f0b21 100644 --- a/TR5Main/Specific/level.h +++ b/TR5Main/Specific/level.h @@ -166,5 +166,6 @@ void LoadAIObjects(); FILE* FileOpen(const char* fileName); void FileClose(FILE* ptr); bool Decompress(byte* dest, byte* src, unsigned long compressedSize, unsigned long uncompressedSize); +void BuildOutsideRoomsTable(); unsigned CALLBACK LoadLevel(void* data);