mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-14 00:54:05 +02:00
floor & ceiling triangulation for TR3 (WIP)
This commit is contained in:
115
src/controller.h
115
src/controller.h
@@ -411,20 +411,93 @@ struct Controller {
|
|||||||
info.roomNext = (*fd++).value;
|
info.roomNext = (*fd++).value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TR::FloorData::FLOOR : // floor & ceiling
|
case TR::FloorData::FLOOR :
|
||||||
case TR::FloorData::CEILING : {
|
case TR::FloorData::FLOOR_NW_SE_SOLID :
|
||||||
TR::FloorData::Slant slant = (*fd++).slant;
|
case TR::FloorData::FLOOR_NE_SW_SOLID :
|
||||||
int sx = (int)slant.x;
|
case TR::FloorData::FLOOR_NW_SE_PORTAL_SE :
|
||||||
int sz = (int)slant.z;
|
case TR::FloorData::FLOOR_NW_SE_PORTAL_NW :
|
||||||
|
case TR::FloorData::FLOOR_NE_SW_PORTAL_SW :
|
||||||
|
case TR::FloorData::FLOOR_NE_SW_PORTAL_NE : {
|
||||||
|
int sx, sz;
|
||||||
|
|
||||||
if (cmd.func == TR::FloorData::FLOOR) {
|
if (cmd.func == TR::FloorData::FLOOR) {
|
||||||
info.slantX = sx;
|
sx = fd->slantX;
|
||||||
info.slantZ = sz;
|
sz = fd->slantZ;
|
||||||
info.floor -= sx * (sx > 0 ? (dx - 1024) : dx) >> 2;
|
|
||||||
info.floor -= sz * (sz > 0 ? (dz - 1024) : dz) >> 2;
|
|
||||||
} else {
|
} else {
|
||||||
info.ceiling -= sx * (sx < 0 ? (dx - 1024) : dx) >> 2;
|
if (cmd.func == TR::FloorData::FLOOR_NW_SE_SOLID ||
|
||||||
info.ceiling += sz * (sz > 0 ? (dz - 1024) : dz) >> 2;
|
cmd.func == TR::FloorData::FLOOR_NW_SE_PORTAL_SE ||
|
||||||
|
cmd.func == TR::FloorData::FLOOR_NW_SE_PORTAL_NW) {
|
||||||
|
if (dx <= 1024 - dz) {
|
||||||
|
info.floor += cmd.triangle.b * 256;
|
||||||
|
sx = fd->a - fd->b;
|
||||||
|
sz = fd->c - fd->b;
|
||||||
|
} else {
|
||||||
|
info.floor += cmd.triangle.a * 256;
|
||||||
|
sx = fd->d - fd->c;
|
||||||
|
sz = fd->d - fd->a;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dx <= dz) {
|
||||||
|
info.floor += cmd.triangle.b * 256;
|
||||||
|
sx = fd->d - fd->c;
|
||||||
|
sz = fd->c - fd->b;
|
||||||
|
} else {
|
||||||
|
info.floor += cmd.triangle.a * 256;
|
||||||
|
sx = fd->a - fd->b;
|
||||||
|
sz = fd->d - fd->a;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fd++;
|
||||||
|
|
||||||
|
info.slantX = sx;
|
||||||
|
info.slantZ = sz;
|
||||||
|
info.floor -= sx * (sx > 0 ? (dx - 1023) : dx) >> 2;
|
||||||
|
info.floor -= sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TR::FloorData::CEILING :
|
||||||
|
case TR::FloorData::CEILING_NE_SW_SOLID :
|
||||||
|
case TR::FloorData::CEILING_NW_SE_SOLID :
|
||||||
|
case TR::FloorData::CEILING_NE_SW_PORTAL_SW :
|
||||||
|
case TR::FloorData::CEILING_NE_SW_PORTAL_NE :
|
||||||
|
case TR::FloorData::CEILING_NW_SE_PORTAL_SE :
|
||||||
|
case TR::FloorData::CEILING_NW_SE_PORTAL_NW : {
|
||||||
|
int sx, sz;
|
||||||
|
|
||||||
|
if (cmd.func == TR::FloorData::CEILING) {
|
||||||
|
sx = fd->slantX;
|
||||||
|
sz = fd->slantZ;
|
||||||
|
} else {
|
||||||
|
if (cmd.func == TR::FloorData::CEILING_NW_SE_SOLID ||
|
||||||
|
cmd.func == TR::FloorData::CEILING_NW_SE_PORTAL_SE ||
|
||||||
|
cmd.func == TR::FloorData::CEILING_NW_SE_PORTAL_NW) {
|
||||||
|
if (dx <= 1024 - dz) {
|
||||||
|
info.ceiling += cmd.triangle.b * 256;
|
||||||
|
sx = fd->c - fd->d;
|
||||||
|
sz = fd->b - fd->c;
|
||||||
|
} else {
|
||||||
|
info.ceiling += cmd.triangle.a * 256;
|
||||||
|
sx = fd->b - fd->a;
|
||||||
|
sz = fd->a - fd->d;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dx <= dz) {
|
||||||
|
info.ceiling += cmd.triangle.b * 256;
|
||||||
|
sx = fd->b - fd->a;
|
||||||
|
sz = fd->b - fd->c;
|
||||||
|
} else {
|
||||||
|
info.ceiling += cmd.triangle.a * 256;
|
||||||
|
sx = fd->c - fd->d;
|
||||||
|
sz = fd->a - fd->d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fd++;
|
||||||
|
|
||||||
|
info.ceiling -= sx * (sx < 0 ? (dx - 1023) : dx) >> 2;
|
||||||
|
info.ceiling += sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,23 +530,9 @@ struct Controller {
|
|||||||
info.climb = cmd.sub; // climb mask
|
info.climb = cmd.sub; // climb mask
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07 :
|
case TR::FloorData::MONKEY : break;
|
||||||
case 0x08 :
|
case TR::FloorData::MINECART_LEFT :
|
||||||
case 0x09 :
|
case TR::FloorData::MINECART_RIGHT : break;
|
||||||
case 0x0A :
|
|
||||||
case 0x0B :
|
|
||||||
case 0x0C :
|
|
||||||
case 0x0D :
|
|
||||||
case 0x0E :
|
|
||||||
case 0x0F :
|
|
||||||
case 0x10 :
|
|
||||||
case 0x11 :
|
|
||||||
case 0x12 : fd++; break; // TODO TR3 triangulation
|
|
||||||
|
|
||||||
case 0x13 : break; // TODO TR3 monkeyswing
|
|
||||||
|
|
||||||
case 0x14 :
|
|
||||||
case 0x15 : break; // TODO TR3 minecart
|
|
||||||
|
|
||||||
default : LOG("unknown func: %d\n", cmd.func);
|
default : LOG("unknown func: %d\n", cmd.func);
|
||||||
}
|
}
|
||||||
|
137
src/format.h
137
src/format.h
@@ -1440,12 +1440,20 @@ namespace TR {
|
|||||||
|
|
||||||
union FloorData {
|
union FloorData {
|
||||||
uint16 value;
|
uint16 value;
|
||||||
struct Command {
|
union Command {
|
||||||
uint16 func:5, tri:3, sub:7, end:1;
|
struct {
|
||||||
|
uint16 func:5, tri:3, sub:7, end:1;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
int16 :5, a:5, b:5, :1;
|
||||||
|
} triangle;
|
||||||
} cmd;
|
} cmd;
|
||||||
struct Slant {
|
struct {
|
||||||
int8 x:8, z:8;
|
int16 slantX:8, slantZ:8;
|
||||||
} slant;
|
};
|
||||||
|
struct {
|
||||||
|
uint16 a:4, b:4, c:4, d:4;
|
||||||
|
};
|
||||||
struct TriggerInfo {
|
struct TriggerInfo {
|
||||||
uint16 timer:8, once:1, mask:5, :2;
|
uint16 timer:8, once:1, mask:5, :2;
|
||||||
} triggerInfo;
|
} triggerInfo;
|
||||||
@@ -1459,13 +1467,28 @@ namespace TR {
|
|||||||
} triggerCmd;
|
} triggerCmd;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NONE ,
|
NONE
|
||||||
PORTAL ,
|
, PORTAL
|
||||||
FLOOR ,
|
, FLOOR
|
||||||
CEILING ,
|
, CEILING
|
||||||
TRIGGER ,
|
, TRIGGER
|
||||||
LAVA ,
|
, LAVA
|
||||||
CLIMB ,
|
, CLIMB
|
||||||
|
, FLOOR_NW_SE_SOLID
|
||||||
|
, FLOOR_NE_SW_SOLID
|
||||||
|
, CEILING_NW_SE_SOLID
|
||||||
|
, CEILING_NE_SW_SOLID
|
||||||
|
, FLOOR_NW_SE_PORTAL_SE
|
||||||
|
, FLOOR_NW_SE_PORTAL_NW
|
||||||
|
, FLOOR_NE_SW_PORTAL_SW
|
||||||
|
, FLOOR_NE_SW_PORTAL_NE
|
||||||
|
, CEILING_NW_SE_PORTAL_SE
|
||||||
|
, CEILING_NW_SE_PORTAL_NW
|
||||||
|
, CEILING_NE_SW_PORTAL_SW
|
||||||
|
, CEILING_NE_SW_PORTAL_NE
|
||||||
|
, MONKEY
|
||||||
|
, MINECART_LEFT
|
||||||
|
, MINECART_RIGHT
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5495,6 +5518,21 @@ namespace TR {
|
|||||||
fd++;
|
fd++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FloorData::FLOOR_NW_SE_SOLID :
|
||||||
|
case FloorData::FLOOR_NE_SW_SOLID :
|
||||||
|
case FloorData::CEILING_NW_SE_SOLID :
|
||||||
|
case FloorData::CEILING_NE_SW_SOLID :
|
||||||
|
case FloorData::FLOOR_NW_SE_PORTAL_NW :
|
||||||
|
case FloorData::FLOOR_NW_SE_PORTAL_SE :
|
||||||
|
case FloorData::FLOOR_NE_SW_PORTAL_NE :
|
||||||
|
case FloorData::FLOOR_NE_SW_PORTAL_SW :
|
||||||
|
case FloorData::CEILING_NW_SE_PORTAL_NW :
|
||||||
|
case FloorData::CEILING_NW_SE_PORTAL_SE :
|
||||||
|
case FloorData::CEILING_NE_SW_PORTAL_NE :
|
||||||
|
case FloorData::CEILING_NE_SW_PORTAL_SW :
|
||||||
|
fd++;
|
||||||
|
break;
|
||||||
|
|
||||||
case FloorData::TRIGGER :
|
case FloorData::TRIGGER :
|
||||||
fd++;
|
fd++;
|
||||||
do {} while (!(*fd++).triggerCmd.end);
|
do {} while (!(*fd++).triggerCmd.end);
|
||||||
@@ -5502,26 +5540,11 @@ namespace TR {
|
|||||||
|
|
||||||
case FloorData::LAVA :
|
case FloorData::LAVA :
|
||||||
case FloorData::CLIMB :
|
case FloorData::CLIMB :
|
||||||
|
case FloorData::MONKEY :
|
||||||
|
case FloorData::MINECART_LEFT :
|
||||||
|
case FloorData::MINECART_RIGHT :
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07 :
|
|
||||||
case 0x08 :
|
|
||||||
case 0x09 :
|
|
||||||
case 0x0A :
|
|
||||||
case 0x0B :
|
|
||||||
case 0x0C :
|
|
||||||
case 0x0D :
|
|
||||||
case 0x0E :
|
|
||||||
case 0x0F :
|
|
||||||
case 0x10 :
|
|
||||||
case 0x11 :
|
|
||||||
case 0x12 : fd++; break; // TODO TR3 triangulation
|
|
||||||
|
|
||||||
case 0x13 : break; // TODO TR3 monkeyswing
|
|
||||||
|
|
||||||
case 0x14 :
|
|
||||||
case 0x15 : break; // TODO TR3 minecart
|
|
||||||
|
|
||||||
default : LOG("unknown func to skip: %d\n", func);
|
default : LOG("unknown func to skip: %d\n", func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5531,9 +5554,33 @@ namespace TR {
|
|||||||
if (!sector->floorIndex) return NO_ROOM;
|
if (!sector->floorIndex) return NO_ROOM;
|
||||||
FloorData *fd = &floors[sector->floorIndex];
|
FloorData *fd = &floors[sector->floorIndex];
|
||||||
// floor data always in this order
|
// floor data always in this order
|
||||||
if (!fd->cmd.end && fd->cmd.func == FloorData::FLOOR) fd += 2; // skip floor slant info
|
if ( fd->cmd.func == FloorData::FLOOR
|
||||||
if (!fd->cmd.end && fd->cmd.func == FloorData::CEILING) fd += 2; // skip ceiling slant info
|
|| fd->cmd.func == FloorData::FLOOR_NW_SE_SOLID
|
||||||
if (fd->cmd.func == FloorData::PORTAL) return (++fd)->value;
|
|| fd->cmd.func == FloorData::FLOOR_NE_SW_SOLID
|
||||||
|
|| fd->cmd.func == FloorData::FLOOR_NW_SE_PORTAL_SE
|
||||||
|
|| fd->cmd.func == FloorData::FLOOR_NW_SE_PORTAL_NW
|
||||||
|
|| fd->cmd.func == FloorData::FLOOR_NE_SW_PORTAL_SW
|
||||||
|
|| fd->cmd.func == FloorData::FLOOR_NE_SW_PORTAL_NE) {
|
||||||
|
|
||||||
|
if (fd->cmd.end) return NO_ROOM;
|
||||||
|
fd += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fd->cmd.func == FloorData::CEILING
|
||||||
|
|| fd->cmd.func == FloorData::CEILING_NE_SW_SOLID
|
||||||
|
|| fd->cmd.func == FloorData::CEILING_NW_SE_SOLID
|
||||||
|
|| fd->cmd.func == FloorData::CEILING_NE_SW_PORTAL_SW
|
||||||
|
|| fd->cmd.func == FloorData::CEILING_NE_SW_PORTAL_NE
|
||||||
|
|| fd->cmd.func == FloorData::CEILING_NW_SE_PORTAL_SE
|
||||||
|
|| fd->cmd.func == FloorData::CEILING_NW_SE_PORTAL_NW) {
|
||||||
|
|
||||||
|
if (fd->cmd.end) return NO_ROOM;
|
||||||
|
fd += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd->cmd.func == FloorData::PORTAL)
|
||||||
|
return (++fd)->value;
|
||||||
|
|
||||||
return NO_ROOM;
|
return NO_ROOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5630,12 +5677,12 @@ namespace TR {
|
|||||||
cmd = (*fd++).cmd;
|
cmd = (*fd++).cmd;
|
||||||
|
|
||||||
switch (cmd.func) {
|
switch (cmd.func) {
|
||||||
case FloorData::FLOOR : {
|
case FloorData::FLOOR : { // TODO: triangulation
|
||||||
FloorData::Slant slant = (*fd++).slant;
|
int sx = fd->slantX;
|
||||||
int sx = (int)slant.x;
|
int sz = fd->slantZ;
|
||||||
int sz = (int)slant.z;
|
fd++;
|
||||||
int dx = x % 1024;
|
int dx = x & 1023;
|
||||||
int dz = z % 1024;
|
int dz = z & 1023;
|
||||||
floor -= sx * (sx > 0 ? (dx - 1023) : dx) >> 2;
|
floor -= sx * (sx > 0 ? (dx - 1023) : dx) >> 2;
|
||||||
floor -= sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
floor -= sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
||||||
break;
|
break;
|
||||||
@@ -5682,12 +5729,12 @@ namespace TR {
|
|||||||
fd += 2; // skip floor slant
|
fd += 2; // skip floor slant
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd->cmd.func == FloorData::CEILING) {
|
if (fd->cmd.func == FloorData::CEILING) { // TODO: triangulation
|
||||||
FloorData::Slant slant = (++fd)->slant;
|
int sx = fd->slantX;
|
||||||
int sx = (int)slant.x;
|
int sz = fd->slantZ;
|
||||||
int sz = (int)slant.z;
|
fd++;
|
||||||
int dx = x % 1024;
|
int dx = x & 1023;
|
||||||
int dz = z % 1024;
|
int dz = z & 1023;
|
||||||
ceiling -= sx * (sx < 0 ? (dx - 1023) : dx) >> 2;
|
ceiling -= sx * (sx < 0 ? (dx - 1023) : dx) >> 2;
|
||||||
ceiling += sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
ceiling += sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user