mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-13 16:44:50 +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;
|
||||
break;
|
||||
|
||||
case TR::FloorData::FLOOR : // floor & ceiling
|
||||
case TR::FloorData::CEILING : {
|
||||
TR::FloorData::Slant slant = (*fd++).slant;
|
||||
int sx = (int)slant.x;
|
||||
int sz = (int)slant.z;
|
||||
case TR::FloorData::FLOOR :
|
||||
case TR::FloorData::FLOOR_NW_SE_SOLID :
|
||||
case TR::FloorData::FLOOR_NE_SW_SOLID :
|
||||
case TR::FloorData::FLOOR_NW_SE_PORTAL_SE :
|
||||
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) {
|
||||
info.slantX = sx;
|
||||
info.slantZ = sz;
|
||||
info.floor -= sx * (sx > 0 ? (dx - 1024) : dx) >> 2;
|
||||
info.floor -= sz * (sz > 0 ? (dz - 1024) : dz) >> 2;
|
||||
sx = fd->slantX;
|
||||
sz = fd->slantZ;
|
||||
} else {
|
||||
info.ceiling -= sx * (sx < 0 ? (dx - 1024) : dx) >> 2;
|
||||
info.ceiling += sz * (sz > 0 ? (dz - 1024) : dz) >> 2;
|
||||
if (cmd.func == TR::FloorData::FLOOR_NW_SE_SOLID ||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -457,23 +530,9 @@ struct Controller {
|
||||
info.climb = cmd.sub; // climb mask
|
||||
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
|
||||
case TR::FloorData::MONKEY : break;
|
||||
case TR::FloorData::MINECART_LEFT :
|
||||
case TR::FloorData::MINECART_RIGHT : break;
|
||||
|
||||
default : LOG("unknown func: %d\n", cmd.func);
|
||||
}
|
||||
|
137
src/format.h
137
src/format.h
@@ -1440,12 +1440,20 @@ namespace TR {
|
||||
|
||||
union FloorData {
|
||||
uint16 value;
|
||||
struct Command {
|
||||
uint16 func:5, tri:3, sub:7, end:1;
|
||||
union Command {
|
||||
struct {
|
||||
uint16 func:5, tri:3, sub:7, end:1;
|
||||
};
|
||||
struct {
|
||||
int16 :5, a:5, b:5, :1;
|
||||
} triangle;
|
||||
} cmd;
|
||||
struct Slant {
|
||||
int8 x:8, z:8;
|
||||
} slant;
|
||||
struct {
|
||||
int16 slantX:8, slantZ:8;
|
||||
};
|
||||
struct {
|
||||
uint16 a:4, b:4, c:4, d:4;
|
||||
};
|
||||
struct TriggerInfo {
|
||||
uint16 timer:8, once:1, mask:5, :2;
|
||||
} triggerInfo;
|
||||
@@ -1459,13 +1467,28 @@ namespace TR {
|
||||
} triggerCmd;
|
||||
|
||||
enum {
|
||||
NONE ,
|
||||
PORTAL ,
|
||||
FLOOR ,
|
||||
CEILING ,
|
||||
TRIGGER ,
|
||||
LAVA ,
|
||||
CLIMB ,
|
||||
NONE
|
||||
, PORTAL
|
||||
, FLOOR
|
||||
, CEILING
|
||||
, TRIGGER
|
||||
, LAVA
|
||||
, 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++;
|
||||
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 :
|
||||
fd++;
|
||||
do {} while (!(*fd++).triggerCmd.end);
|
||||
@@ -5502,26 +5540,11 @@ namespace TR {
|
||||
|
||||
case FloorData::LAVA :
|
||||
case FloorData::CLIMB :
|
||||
case FloorData::MONKEY :
|
||||
case FloorData::MINECART_LEFT :
|
||||
case FloorData::MINECART_RIGHT :
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -5531,9 +5554,33 @@ namespace TR {
|
||||
if (!sector->floorIndex) return NO_ROOM;
|
||||
FloorData *fd = &floors[sector->floorIndex];
|
||||
// floor data always in this order
|
||||
if (!fd->cmd.end && fd->cmd.func == FloorData::FLOOR) fd += 2; // skip floor slant info
|
||||
if (!fd->cmd.end && fd->cmd.func == FloorData::CEILING) fd += 2; // skip ceiling slant info
|
||||
if (fd->cmd.func == FloorData::PORTAL) return (++fd)->value;
|
||||
if ( fd->cmd.func == FloorData::FLOOR
|
||||
|| fd->cmd.func == FloorData::FLOOR_NW_SE_SOLID
|
||||
|| 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;
|
||||
}
|
||||
|
||||
@@ -5630,12 +5677,12 @@ namespace TR {
|
||||
cmd = (*fd++).cmd;
|
||||
|
||||
switch (cmd.func) {
|
||||
case FloorData::FLOOR : {
|
||||
FloorData::Slant slant = (*fd++).slant;
|
||||
int sx = (int)slant.x;
|
||||
int sz = (int)slant.z;
|
||||
int dx = x % 1024;
|
||||
int dz = z % 1024;
|
||||
case FloorData::FLOOR : { // TODO: triangulation
|
||||
int sx = fd->slantX;
|
||||
int sz = fd->slantZ;
|
||||
fd++;
|
||||
int dx = x & 1023;
|
||||
int dz = z & 1023;
|
||||
floor -= sx * (sx > 0 ? (dx - 1023) : dx) >> 2;
|
||||
floor -= sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
||||
break;
|
||||
@@ -5682,12 +5729,12 @@ namespace TR {
|
||||
fd += 2; // skip floor slant
|
||||
}
|
||||
|
||||
if (fd->cmd.func == FloorData::CEILING) {
|
||||
FloorData::Slant slant = (++fd)->slant;
|
||||
int sx = (int)slant.x;
|
||||
int sz = (int)slant.z;
|
||||
int dx = x % 1024;
|
||||
int dz = z % 1024;
|
||||
if (fd->cmd.func == FloorData::CEILING) { // TODO: triangulation
|
||||
int sx = fd->slantX;
|
||||
int sz = fd->slantZ;
|
||||
fd++;
|
||||
int dx = x & 1023;
|
||||
int dz = z & 1023;
|
||||
ceiling -= sx * (sx < 0 ? (dx - 1023) : dx) >> 2;
|
||||
ceiling += sz * (sz > 0 ? (dz - 1023) : dz) >> 2;
|
||||
}
|
||||
|
Reference in New Issue
Block a user