mirror of
https://github.com/XProger/OpenLara.git
synced 2025-01-17 21:09:00 +01:00
TR4 level parser (WIP), remove audio and level folders
This commit is contained in:
parent
3923325031
commit
f78075f3f8
@ -1 +0,0 @@
|
|||||||
- track_XX.ogg, track_XX.mp3, track_XX.wav for *_EN, *_DE, *_FR, *_IT, *_JA, *_RU
|
|
@ -1,2 +0,0 @@
|
|||||||
- track_XX.ogg, track_XX.mp3, track_XX.wav for *_EN, *_DE, *_FR, *_IT, *_JA, *_RU
|
|
||||||
- MAIN.SFX
|
|
@ -1,2 +0,0 @@
|
|||||||
- cdaudio.wad
|
|
||||||
- MAIN.SFX
|
|
@ -1,2 +0,0 @@
|
|||||||
- *.PHD, *.PSX
|
|
||||||
- *.PCX
|
|
@ -1,2 +0,0 @@
|
|||||||
- *.TR2, *.PSX
|
|
||||||
- *.PCX
|
|
@ -1,2 +0,0 @@
|
|||||||
- *.TR2
|
|
||||||
- *.BMP
|
|
427
src/format.h
427
src/format.h
@ -1171,6 +1171,7 @@ namespace TR {
|
|||||||
|
|
||||||
short3 normal;
|
short3 normal;
|
||||||
uint16 vertices[4];
|
uint16 vertices[4];
|
||||||
|
uint16 effects;
|
||||||
uint8 triangle:1, colored:1, water:1, flip:5;
|
uint8 triangle:1, colored:1, water:1, flip:5;
|
||||||
|
|
||||||
static int cmp(const Face &a, const Face &b) {
|
static int cmp(const Face &a, const Face &b) {
|
||||||
@ -1309,8 +1310,8 @@ namespace TR {
|
|||||||
};
|
};
|
||||||
uint16 value;
|
uint16 value;
|
||||||
} flags;
|
} flags;
|
||||||
uint16 reverbType;
|
|
||||||
uint8 waterScheme;
|
uint8 waterScheme;
|
||||||
|
uint8 reverbType;
|
||||||
uint8 filter;
|
uint8 filter;
|
||||||
uint8 align;
|
uint8 align;
|
||||||
int32 waterLevel[2]; // water level for normal and flipped level state
|
int32 waterLevel[2]; // water level for normal and flipped level state
|
||||||
@ -1353,10 +1354,19 @@ namespace TR {
|
|||||||
} *sectors;
|
} *sectors;
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
DIRECT, POINT, SPOT, SHADOW, FOG
|
||||||
|
};
|
||||||
|
|
||||||
int32 x, y, z;
|
int32 x, y, z;
|
||||||
uint32 radius;
|
uint32 radius;
|
||||||
int32 intensity;
|
int32 intensity;
|
||||||
Color32 color;
|
Color32 color;
|
||||||
|
float in, out;
|
||||||
|
float length, cutoff;
|
||||||
|
vec3 dir;
|
||||||
|
uint8 type;
|
||||||
} *lights;
|
} *lights;
|
||||||
|
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
@ -1559,7 +1569,10 @@ namespace TR {
|
|||||||
int32 x, y, z;
|
int32 x, y, z;
|
||||||
angle rotation;
|
angle rotation;
|
||||||
int16 intensity;
|
int16 intensity;
|
||||||
|
union {
|
||||||
int16 intensity2;
|
int16 intensity2;
|
||||||
|
int16 OCB;
|
||||||
|
};
|
||||||
union Flags {
|
union Flags {
|
||||||
struct {
|
struct {
|
||||||
uint16 state:2, unused:3, smooth:1, :1, invisible:1, once:1, active:5, reverse:1, rendered:1;
|
uint16 state:2, unused:3, smooth:1, :1, invisible:1, once:1, active:5, reverse:1, rendered:1;
|
||||||
@ -2057,6 +2070,9 @@ namespace TR {
|
|||||||
fixed speed;
|
fixed speed;
|
||||||
fixed accel;
|
fixed accel;
|
||||||
|
|
||||||
|
fixed speedLateral;
|
||||||
|
fixed accelLateral;
|
||||||
|
|
||||||
uint16 frameStart;
|
uint16 frameStart;
|
||||||
uint16 frameEnd;
|
uint16 frameEnd;
|
||||||
uint16 nextAnimation;
|
uint16 nextAnimation;
|
||||||
@ -2199,6 +2215,19 @@ namespace TR {
|
|||||||
} flags;
|
} flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FlybyCamera {
|
||||||
|
int32 x, y, z;
|
||||||
|
int32 dx, dy, dz;
|
||||||
|
uint8 sequence;
|
||||||
|
uint8 index;
|
||||||
|
uint16 fov;
|
||||||
|
int16 roll;
|
||||||
|
uint16 timer;
|
||||||
|
uint16 speed;
|
||||||
|
uint16 flags;
|
||||||
|
uint32 room;
|
||||||
|
};
|
||||||
|
|
||||||
struct CameraFrame {
|
struct CameraFrame {
|
||||||
short3 target;
|
short3 target;
|
||||||
short3 pos;
|
short3 pos;
|
||||||
@ -2206,6 +2235,15 @@ namespace TR {
|
|||||||
int16 roll;
|
int16 roll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AIObject {
|
||||||
|
uint16 type;
|
||||||
|
uint16 room;
|
||||||
|
int32 x, y, z;
|
||||||
|
uint16 OCB;
|
||||||
|
uint16 flags;
|
||||||
|
int32 angle;
|
||||||
|
};
|
||||||
|
|
||||||
struct SoundSource {
|
struct SoundSource {
|
||||||
int32 x, y, z; // absolute position of sound source (world coordinates)
|
int32 x, y, z; // absolute position of sound source (world coordinates)
|
||||||
uint16 id; // internal sample index
|
uint16 id; // internal sample index
|
||||||
@ -2351,6 +2389,9 @@ namespace TR {
|
|||||||
int32 camerasCount;
|
int32 camerasCount;
|
||||||
Camera *cameras;
|
Camera *cameras;
|
||||||
|
|
||||||
|
int32 flybyCamerasCount;
|
||||||
|
FlybyCamera *flybyCameras;
|
||||||
|
|
||||||
int32 soundSourcesCount;
|
int32 soundSourcesCount;
|
||||||
SoundSource *soundSources;
|
SoundSource *soundSources;
|
||||||
|
|
||||||
@ -2377,10 +2418,15 @@ namespace TR {
|
|||||||
Tile4 *tiles4;
|
Tile4 *tiles4;
|
||||||
Tile8 *tiles8;
|
Tile8 *tiles8;
|
||||||
Tile16 *tiles16;
|
Tile16 *tiles16;
|
||||||
|
Tile32 *tiles32;
|
||||||
|
Tile32 *tilesMisc;
|
||||||
|
|
||||||
uint16 cameraFramesCount;
|
uint16 cameraFramesCount;
|
||||||
CameraFrame *cameraFrames;
|
CameraFrame *cameraFrames;
|
||||||
|
|
||||||
|
AIObject *AIObjects;
|
||||||
|
uint32 AIObjectsCount;
|
||||||
|
|
||||||
uint16 demoDataSize;
|
uint16 demoDataSize;
|
||||||
uint8 *demoData;
|
uint8 *demoData;
|
||||||
|
|
||||||
@ -2587,7 +2633,7 @@ namespace TR {
|
|||||||
case MAGIC_TR3_PC2 :
|
case MAGIC_TR3_PC2 :
|
||||||
case MAGIC_TR3_PC3 : version = VER_TR3_PC; break;
|
case MAGIC_TR3_PC3 : version = VER_TR3_PC; break;
|
||||||
case MAGIC_TR3_PSX : version = VER_TR3_PSX; break;
|
case MAGIC_TR3_PSX : version = VER_TR3_PSX; break;
|
||||||
//case MAGIC_TR4_PC : version = VER_TR4_PC; break;
|
case MAGIC_TR4_PC : version = VER_TR4_PC; break;
|
||||||
default : ;
|
default : ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2650,6 +2696,7 @@ namespace TR {
|
|||||||
delete[] spriteSequences;
|
delete[] spriteSequences;
|
||||||
delete[] spriteTexturesData;
|
delete[] spriteTexturesData;
|
||||||
delete[] cameras;
|
delete[] cameras;
|
||||||
|
delete[] flybyCameras;
|
||||||
delete[] soundSources;
|
delete[] soundSources;
|
||||||
delete[] boxes;
|
delete[] boxes;
|
||||||
delete[] overlaps;
|
delete[] overlaps;
|
||||||
@ -2670,7 +2717,10 @@ namespace TR {
|
|||||||
delete[] tiles4;
|
delete[] tiles4;
|
||||||
delete[] tiles8;
|
delete[] tiles8;
|
||||||
delete[] tiles16;
|
delete[] tiles16;
|
||||||
|
delete[] tiles32;
|
||||||
|
delete[] tilesMisc;
|
||||||
delete[] cameraFrames;
|
delete[] cameraFrames;
|
||||||
|
delete[] AIObjects;
|
||||||
delete[] demoData;
|
delete[] demoData;
|
||||||
delete[] soundsMap;
|
delete[] soundsMap;
|
||||||
delete[] soundsInfo;
|
delete[] soundsInfo;
|
||||||
@ -2978,7 +3028,65 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadTR4_PC (Stream &stream) {
|
void loadTR4_PC (Stream &stream) {
|
||||||
|
uint16 roomTilesCount, objTilesCount, bumpTilesCount;
|
||||||
|
uint32 sizeD, sizeC, sizeR;
|
||||||
|
uint8 *dataC, *dataD;
|
||||||
|
|
||||||
|
stream.read(roomTilesCount);
|
||||||
|
stream.read(objTilesCount);
|
||||||
|
stream.read(bumpTilesCount);
|
||||||
|
|
||||||
|
// tiles32
|
||||||
|
stream.read(sizeD);
|
||||||
|
stream.read(dataC, stream.read(sizeC));
|
||||||
|
ASSERT(sizeD == sizeof(Tile32) * (roomTilesCount + objTilesCount + bumpTilesCount));
|
||||||
|
tiles32 = new Tile32[roomTilesCount + objTilesCount + bumpTilesCount];
|
||||||
|
tinf_uncompress(tiles32, &sizeR, dataC + 2, 0);
|
||||||
|
ASSERT(sizeD == sizeR);
|
||||||
|
delete[] dataC;
|
||||||
|
|
||||||
|
// tiles16
|
||||||
|
stream.read(sizeD);
|
||||||
|
stream.read(sizeC);
|
||||||
|
stream.seek(sizeC); // skip compressed 16-bit tiles
|
||||||
|
|
||||||
|
// tiles16
|
||||||
|
stream.read(sizeD);
|
||||||
|
stream.read(dataC, stream.read(sizeC));
|
||||||
|
ASSERT(sizeD == sizeof(Tile32) * 2);
|
||||||
|
tilesMisc = new Tile32[2];
|
||||||
|
tinf_uncompress(tilesMisc, &sizeR, dataC + 2, 0);
|
||||||
|
ASSERT(sizeD == sizeR);
|
||||||
|
delete[] dataC;
|
||||||
|
|
||||||
|
stream.read(sizeD);
|
||||||
|
stream.read(dataC, stream.read(sizeC));
|
||||||
|
dataD = new uint8[sizeD];
|
||||||
|
tinf_uncompress(dataD, &sizeR, dataC + 2, 0);
|
||||||
|
ASSERT(sizeD == sizeR);
|
||||||
|
delete[] dataC;
|
||||||
|
|
||||||
|
{
|
||||||
|
Stream stream(NULL, dataD, sizeD);
|
||||||
|
readDataArrays(stream);
|
||||||
|
stream.seek(3); // SPR
|
||||||
|
readSpriteTex(stream);
|
||||||
|
readCameras(stream);
|
||||||
|
readFlybyCameras(stream);
|
||||||
|
readSoundSources(stream);
|
||||||
|
readBoxes(stream);
|
||||||
|
readOverlaps(stream);
|
||||||
|
readZones(stream);
|
||||||
|
readAnimTex(stream);
|
||||||
|
stream.seek(3); // TEX
|
||||||
|
readObjectTex(stream);
|
||||||
|
readEntities(stream);
|
||||||
|
readAIObjects(stream);
|
||||||
|
readDemoData(stream);
|
||||||
|
readSoundMap(stream);
|
||||||
|
readSoundOffsets(stream);
|
||||||
|
}
|
||||||
|
delete[] dataD;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadTR4_PSX (Stream &stream) {
|
void loadTR4_PSX (Stream &stream) {
|
||||||
@ -3027,7 +3135,9 @@ namespace TR {
|
|||||||
|
|
||||||
stream.read(meshData, stream.read(meshDataSize));
|
stream.read(meshData, stream.read(meshDataSize));
|
||||||
stream.read(meshOffsets, stream.read(meshOffsetsCount));
|
stream.read(meshOffsets, stream.read(meshOffsetsCount));
|
||||||
stream.read(anims, stream.read(animsCount));
|
|
||||||
|
readAnims(stream);
|
||||||
|
|
||||||
stream.read(states, stream.read(statesCount));
|
stream.read(states, stream.read(statesCount));
|
||||||
stream.read(ranges, stream.read(rangesCount));
|
stream.read(ranges, stream.read(rangesCount));
|
||||||
stream.read(commands, stream.read(commandsCount));
|
stream.read(commands, stream.read(commandsCount));
|
||||||
@ -3039,6 +3149,36 @@ namespace TR {
|
|||||||
stream.read(staticMeshes, stream.read(staticMeshesCount));
|
stream.read(staticMeshes, stream.read(staticMeshesCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void readAnims(Stream &stream) {
|
||||||
|
stream.read(animsCount);
|
||||||
|
anims = animsCount ? new Animation[animsCount] : NULL;
|
||||||
|
for (int i = 0; i < animsCount; i++) {
|
||||||
|
Animation &anim = anims[i];
|
||||||
|
stream.read(anim.frameOffset);
|
||||||
|
stream.read(anim.frameRate);
|
||||||
|
stream.read(anim.frameSize);
|
||||||
|
stream.read(anim.state);
|
||||||
|
stream.read(anim.speed);
|
||||||
|
stream.read(anim.accel);
|
||||||
|
if (version & (VER_TR4 | VER_TR5)) {
|
||||||
|
stream.read(anim.speedLateral);
|
||||||
|
stream.read(anim.accelLateral);
|
||||||
|
} else {
|
||||||
|
anim.speedLateral.value = 0;
|
||||||
|
anim.accelLateral.value = 0;
|
||||||
|
}
|
||||||
|
stream.read(anim.frameStart);
|
||||||
|
stream.read(anim.frameEnd);
|
||||||
|
stream.read(anim.nextAnimation);
|
||||||
|
stream.read(anim.nextFrame);
|
||||||
|
stream.read(anim.scCount);
|
||||||
|
stream.read(anim.scOffset);
|
||||||
|
stream.read(anim.acCount);
|
||||||
|
stream.read(anim.animCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void readModels(Stream &stream) {
|
void readModels(Stream &stream) {
|
||||||
models = stream.read(modelsCount) ? new Model[modelsCount] : NULL;
|
models = stream.read(modelsCount) ? new Model[modelsCount] : NULL;
|
||||||
for (int i = 0; i < modelsCount; i++) {
|
for (int i = 0; i < modelsCount; i++) {
|
||||||
@ -3062,6 +3202,10 @@ namespace TR {
|
|||||||
stream.read(cameras, stream.read(camerasCount));
|
stream.read(cameras, stream.read(camerasCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void readFlybyCameras(Stream &stream) {
|
||||||
|
stream.read(flybyCameras, stream.read(flybyCamerasCount));
|
||||||
|
}
|
||||||
|
|
||||||
void readSoundSources(Stream &stream) {
|
void readSoundSources(Stream &stream) {
|
||||||
stream.read(soundSources, stream.read(soundSourcesCount));
|
stream.read(soundSources, stream.read(soundSourcesCount));
|
||||||
}
|
}
|
||||||
@ -3077,7 +3221,7 @@ namespace TR {
|
|||||||
stream.read(b.maxX);
|
stream.read(b.maxX);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version & (VER_TR2 | VER_TR3)) {
|
if (version & (VER_TR2 | VER_TR3 | VER_TR4 | VER_TR5)) {
|
||||||
uint8 value;
|
uint8 value;
|
||||||
b.minZ = stream.read(value) * 1024;
|
b.minZ = stream.read(value) * 1024;
|
||||||
b.maxZ = stream.read(value) * 1024;
|
b.maxZ = stream.read(value) * 1024;
|
||||||
@ -3117,6 +3261,10 @@ namespace TR {
|
|||||||
stream.read(cameraFrames, stream.read(cameraFramesCount));
|
stream.read(cameraFrames, stream.read(cameraFramesCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void readAIObjects(Stream &stream) {
|
||||||
|
stream.read(AIObjects, stream.read(AIObjectsCount));
|
||||||
|
}
|
||||||
|
|
||||||
void readDemoData(Stream &stream) {
|
void readDemoData(Stream &stream) {
|
||||||
stream.read(demoData, stream.read(demoDataSize));
|
stream.read(demoData, stream.read(demoDataSize));
|
||||||
}
|
}
|
||||||
@ -3128,7 +3276,7 @@ namespace TR {
|
|||||||
SoundInfo &s = soundsInfo[i];
|
SoundInfo &s = soundsInfo[i];
|
||||||
|
|
||||||
stream.read(s.index);
|
stream.read(s.index);
|
||||||
if (version & (VER_TR1 | VER_TR2)) {
|
if (version & (VER_TR1 | VER_TR2 | VER_TR4 | VER_TR5)) {
|
||||||
uint16 v;
|
uint16 v;
|
||||||
stream.read(v); s.volume = float(v) / 0x7FFF;
|
stream.read(v); s.volume = float(v) / 0x7FFF;
|
||||||
stream.read(v); s.chance = float(v) / 0xFFFF;
|
stream.read(v); s.chance = float(v) / 0xFFFF;
|
||||||
@ -3909,12 +4057,14 @@ namespace TR {
|
|||||||
Model &model = models[i];
|
Model &model = models[i];
|
||||||
model.type = Entity::remap(version, model.type);
|
model.type = Entity::remap(version, model.type);
|
||||||
|
|
||||||
for (int j = 0; j < model.mCount; j++)
|
for (int j = 0; j < model.mCount; j++) {
|
||||||
initMesh(model.mStart + j, model.type);
|
initMesh(model.mStart + j, model.type);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < staticMeshesCount; i++)
|
for (int i = 0; i < staticMeshesCount; i++) {
|
||||||
initMesh(staticMeshes[i].mesh);
|
initMesh(staticMeshes[i].mesh);
|
||||||
|
}
|
||||||
|
|
||||||
remapMeshOffsetsToIndices();
|
remapMeshOffsetsToIndices();
|
||||||
|
|
||||||
@ -4274,17 +4424,23 @@ namespace TR {
|
|||||||
return TR::isCutsceneLevel(id);
|
return TR::isCutsceneLevel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void readFace(Stream &stream, Face &f, bool colored, bool triangle) {
|
void readFace(Stream &stream, Face &f, bool colored, bool triangle, bool isRoomMesh) {
|
||||||
f.triangle = triangle;
|
f.triangle = triangle;
|
||||||
|
|
||||||
for (int i = 0; i < (triangle ? 3 : 4); i++)
|
for (int i = 0; i < (triangle ? 3 : 4); i++) {
|
||||||
stream.read(f.vertices[i]);
|
stream.read(f.vertices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (triangle)
|
if (triangle) {
|
||||||
f.vertices[3] = 0;
|
f.vertices[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
stream.read(f.flags.value);
|
stream.read(f.flags.value);
|
||||||
|
|
||||||
|
if (!isRoomMesh && (version & (VER_TR4 | VER_TR5))) {
|
||||||
|
stream.read(f.effects);
|
||||||
|
}
|
||||||
|
|
||||||
f.colored = colored;
|
f.colored = colored;
|
||||||
f.water = false;
|
f.water = false;
|
||||||
f.flip = false;
|
f.flip = false;
|
||||||
@ -4298,7 +4454,9 @@ namespace TR {
|
|||||||
// room data
|
// room data
|
||||||
stream.read(d.size);
|
stream.read(d.size);
|
||||||
int startOffset = stream.pos;
|
int startOffset = stream.pos;
|
||||||
if (version == VER_TR1_PSX) stream.seek(2);
|
if (version == VER_TR1_PSX) {
|
||||||
|
stream.seek(2);
|
||||||
|
}
|
||||||
|
|
||||||
// only for TR3 PSX
|
// only for TR3 PSX
|
||||||
int32 partsCount;
|
int32 partsCount;
|
||||||
@ -4344,8 +4502,9 @@ namespace TR {
|
|||||||
d.vertices = d.vCount ? new Room::Data::Vertex[d.vCount] : NULL;
|
d.vertices = d.vCount ? new Room::Data::Vertex[d.vCount] : NULL;
|
||||||
|
|
||||||
d.vCount = d.fCount = 0;
|
d.vCount = d.fCount = 0;
|
||||||
} else
|
} else {
|
||||||
d.vertices = stream.read(d.vCount) ? new Room::Data::Vertex[d.vCount] : NULL;
|
d.vertices = stream.read(d.vCount) ? new Room::Data::Vertex[d.vCount] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (version == VER_TR3_PSX) {
|
if (version == VER_TR3_PSX) {
|
||||||
for (int pIndex = 0; pIndex < partsCount; pIndex++) {
|
for (int pIndex = 0; pIndex < partsCount; pIndex++) {
|
||||||
@ -4472,21 +4631,24 @@ namespace TR {
|
|||||||
stream.read(v.pos.z);
|
stream.read(v.pos.z);
|
||||||
stream.read(lighting);
|
stream.read(lighting);
|
||||||
|
|
||||||
if (version == VER_TR2_PC || version == VER_TR3_PC)
|
if (version == VER_TR2_PC || version == VER_TR3_PC || version == VER_TR4_PC) {
|
||||||
stream.read(v.attributes);
|
stream.read(v.attributes);
|
||||||
|
}
|
||||||
|
|
||||||
if (version == VER_TR2_PC)
|
if (version == VER_TR2_PC) {
|
||||||
stream.read(lighting); // real lighting value
|
stream.read(lighting); // real lighting value
|
||||||
|
}
|
||||||
|
|
||||||
if (version == VER_TR3_PC) {
|
if (version == VER_TR3_PC || version == VER_TR4_PC) {
|
||||||
Color16 color;
|
Color16 color;
|
||||||
stream.read(color.value);
|
stream.read(color.value);
|
||||||
v.color = color.getBGR();
|
v.color = color.getBGR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version == VER_TR1_PSX || version == VER_TR3_PSX)
|
if (version == VER_TR1_PSX || version == VER_TR3_PSX) {
|
||||||
lighting = 0x1FFF - (lighting << 5); // convert vertex luminance from PSX to PC format
|
lighting = 0x1FFF - (lighting << 5); // convert vertex luminance from PSX to PC format
|
||||||
|
}
|
||||||
|
|
||||||
if ((version & VER_VERSION) < VER_TR3) { // lighting to color conversion
|
if ((version & VER_VERSION) < VER_TR3) { // lighting to color conversion
|
||||||
int value = clamp((lighting > 0x1FFF) ? 255 : (255 - (lighting >> 5)), 0, 255);
|
int value = clamp((lighting > 0x1FFF) ? 255 : (255 - (lighting >> 5)), 0, 255);
|
||||||
@ -4495,8 +4657,9 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version == VER_TR2_PSX)
|
if (version == VER_TR2_PSX) {
|
||||||
stream.seek(2);
|
stream.seek(2);
|
||||||
|
}
|
||||||
|
|
||||||
int tmp = stream.pos;
|
int tmp = stream.pos;
|
||||||
if (version == VER_TR2_PSX) {
|
if (version == VER_TR2_PSX) {
|
||||||
@ -4504,8 +4667,9 @@ namespace TR {
|
|||||||
stream.seek(sizeof(uint16) * d.rCount);
|
stream.seek(sizeof(uint16) * d.rCount);
|
||||||
if ((stream.pos - startOffset) % 4) stream.seek(2);
|
if ((stream.pos - startOffset) % 4) stream.seek(2);
|
||||||
stream.seek(sizeof(uint16) * 4 * d.rCount);
|
stream.seek(sizeof(uint16) * 4 * d.rCount);
|
||||||
} else
|
} else {
|
||||||
stream.seek(stream.read(d.rCount) * FACE4_SIZE); // uint32 colored (not existing in file)
|
stream.seek(stream.read(d.rCount) * FACE4_SIZE); // uint32 colored (not existing in file)
|
||||||
|
}
|
||||||
stream.read(d.tCount);
|
stream.read(d.tCount);
|
||||||
stream.setPos(tmp);
|
stream.setPos(tmp);
|
||||||
|
|
||||||
@ -4521,7 +4685,11 @@ namespace TR {
|
|||||||
if (version == VER_TR2_PSX) {
|
if (version == VER_TR2_PSX) {
|
||||||
for (int i = 0; i < d.rCount; i++)
|
for (int i = 0; i < d.rCount; i++)
|
||||||
stream.raw(&d.faces[i].flags.value, sizeof(uint16));
|
stream.raw(&d.faces[i].flags.value, sizeof(uint16));
|
||||||
if ((stream.pos - startOffset) % 4) stream.seek(2);
|
|
||||||
|
if ((stream.pos - startOffset) % 4) {
|
||||||
|
stream.seek(2);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < d.rCount; i++) {
|
for (int i = 0; i < d.rCount; i++) {
|
||||||
Face &f = d.faces[i];
|
Face &f = d.faces[i];
|
||||||
stream.raw(f.vertices, sizeof(uint16) * 4);
|
stream.raw(f.vertices, sizeof(uint16) * 4);
|
||||||
@ -4534,8 +4702,11 @@ namespace TR {
|
|||||||
f.water = false;
|
f.water = false;
|
||||||
f.flip = false;
|
f.flip = false;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
for (int i = 0; i < d.rCount; i++) readFace(stream, d.faces[idx++], false, false);
|
for (int i = 0; i < d.rCount; i++) {
|
||||||
|
readFace(stream, d.faces[idx++], false, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stream.read(tmpCount);
|
stream.read(tmpCount);
|
||||||
ASSERT(tmpCount == d.tCount);
|
ASSERT(tmpCount == d.tCount);
|
||||||
@ -4556,27 +4727,31 @@ namespace TR {
|
|||||||
f.flip = false;
|
f.flip = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < d.tCount; i++)
|
for (int i = 0; i < d.tCount; i++) {
|
||||||
readFace(stream, d.faces[idx++], false, true);
|
readFace(stream, d.faces[idx++], false, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version & VER_PSX) { // swap indices (quad strip -> quad list) only for PSX version
|
if (version & VER_PSX) { // swap indices (quad strip -> quad list) only for PSX version
|
||||||
for (int j = 0; j < d.fCount; j++)
|
for (int j = 0; j < d.fCount; j++) {
|
||||||
if (!d.faces[j].triangle)
|
if (!d.faces[j].triangle) {
|
||||||
swap(d.faces[j].vertices[2], d.faces[j].vertices[3]);
|
swap(d.faces[j].vertices[2], d.faces[j].vertices[3]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// room sprites
|
// room sprites
|
||||||
if (version == VER_TR2_PSX || version == VER_TR3_PSX) { // there is no room sprites
|
if (version == VER_TR2_PSX || version == VER_TR3_PSX) { // there is no room sprites
|
||||||
d.sprites = NULL;
|
d.sprites = NULL;
|
||||||
d.sCount = 0;
|
d.sCount = 0;
|
||||||
} else
|
} else {
|
||||||
stream.read(d.sprites, stream.read(d.sCount));
|
stream.read(d.sprites, stream.read(d.sCount));
|
||||||
|
}
|
||||||
|
|
||||||
if (version == VER_TR3_PSX)
|
if (version == VER_TR3_PSX && partsCount != 0) {
|
||||||
if (partsCount != 0)
|
|
||||||
stream.seek(4); // skip unknown shit
|
stream.seek(4); // skip unknown shit
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(int(d.size * 2) >= stream.pos - startOffset);
|
ASSERT(int(d.size * 2) >= stream.pos - startOffset);
|
||||||
stream.setPos(startOffset + d.size * 2);
|
stream.setPos(startOffset + d.size * 2);
|
||||||
@ -4613,15 +4788,17 @@ namespace TR {
|
|||||||
} else {
|
} else {
|
||||||
s.material = s.boxIndex & 0x0F;
|
s.material = s.boxIndex & 0x0F;
|
||||||
s.boxIndex = s.boxIndex >> 4;
|
s.boxIndex = s.boxIndex >> 4;
|
||||||
if (s.boxIndex == 2047)
|
if (s.boxIndex == 2047) {
|
||||||
s.boxIndex = 0; // TODO TR3 slide box indices
|
s.boxIndex = 0; // TODO TR3 slide box indices
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ambient light luminance
|
// ambient light luminance
|
||||||
stream.read(r.ambient);
|
stream.read(r.ambient);
|
||||||
|
|
||||||
if (version != VER_TR3_PSX) {
|
if (version != VER_TR3_PSX) {
|
||||||
if (version & (VER_TR2 | VER_TR3))
|
if (version & (VER_TR2 | VER_TR3 | VER_TR4))
|
||||||
stream.read(r.ambient2);
|
stream.read(r.ambient2);
|
||||||
|
|
||||||
if (version & VER_TR2)
|
if (version & VER_TR2)
|
||||||
@ -4641,21 +4818,39 @@ namespace TR {
|
|||||||
|
|
||||||
uint16 intensity;
|
uint16 intensity;
|
||||||
|
|
||||||
if (version & VER_TR3)
|
if (version & (VER_TR3 | VER_TR4)) {
|
||||||
stream.read(light.color);
|
stream.read(light.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version & VER_TR4) {
|
||||||
|
stream.read(light.type);
|
||||||
|
uint8 byteIntensity;
|
||||||
|
intensity = stream.read(byteIntensity);
|
||||||
|
stream.read(light.in);
|
||||||
|
stream.read(light.out);
|
||||||
|
stream.read(light.length);
|
||||||
|
stream.read(light.cutoff);
|
||||||
|
stream.read(light.dir);
|
||||||
|
light.radius = uint32(light.length);
|
||||||
|
} else {
|
||||||
stream.read(intensity);
|
stream.read(intensity);
|
||||||
|
}
|
||||||
|
|
||||||
if (version == VER_TR1_PSX)
|
if (version == VER_TR1_PSX) {
|
||||||
stream.seek(2);
|
stream.seek(2);
|
||||||
|
}
|
||||||
|
|
||||||
if (version & (VER_TR2 | VER_TR3))
|
if (version & (VER_TR2 | VER_TR3)) {
|
||||||
stream.seek(2); // intensity2
|
stream.seek(2); // intensity2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != VER_TR4_PC) {
|
||||||
stream.read(light.radius);
|
stream.read(light.radius);
|
||||||
|
}
|
||||||
|
|
||||||
if (version & VER_TR2)
|
if (version & VER_TR2) {
|
||||||
stream.seek(4); // radius2
|
stream.seek(4); // radius2
|
||||||
|
}
|
||||||
|
|
||||||
if ((version & VER_VERSION) < VER_TR3) {
|
if ((version & VER_VERSION) < VER_TR3) {
|
||||||
int value = clamp((intensity > 0x1FFF) ? 0 : (intensity >> 5), 0, 255);
|
int value = clamp((intensity > 0x1FFF) ? 0 : (intensity >> 5), 0, 255);
|
||||||
@ -4665,8 +4860,9 @@ namespace TR {
|
|||||||
|
|
||||||
light.intensity = intensity;
|
light.intensity = intensity;
|
||||||
|
|
||||||
if (version == VER_TR3_PSX)
|
if (version == VER_TR3_PSX) {
|
||||||
light.radius >>= 2;
|
light.radius >>= 2;
|
||||||
|
}
|
||||||
|
|
||||||
light.radius *= 2;
|
light.radius *= 2;
|
||||||
}
|
}
|
||||||
@ -4678,15 +4874,16 @@ namespace TR {
|
|||||||
stream.read(m.x);
|
stream.read(m.x);
|
||||||
stream.read(m.y);
|
stream.read(m.y);
|
||||||
stream.read(m.z);
|
stream.read(m.z);
|
||||||
stream.read(m.rotation);
|
stream.read(m.rotation.value);
|
||||||
if (version & VER_TR3) {
|
if (version & (VER_TR3 | VER_TR4)) {
|
||||||
Color16 color;
|
Color16 color;
|
||||||
stream.read(color.value);
|
stream.read(color.value);
|
||||||
m.color = color;
|
m.color = color;
|
||||||
stream.seek(2);
|
stream.seek(2);
|
||||||
} else {
|
} else {
|
||||||
if (version & VER_TR2)
|
if (version & VER_TR2) {
|
||||||
stream.seek(2);
|
stream.seek(2);
|
||||||
|
}
|
||||||
|
|
||||||
uint16 intensity;
|
uint16 intensity;
|
||||||
stream.read(intensity);
|
stream.read(intensity);
|
||||||
@ -4698,16 +4895,18 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream.read(m.meshID);
|
stream.read(m.meshID);
|
||||||
if (version == VER_TR1_PSX)
|
if (version == VER_TR1_PSX) {
|
||||||
stream.seek(2); // skip padding
|
stream.seek(2); // skip padding
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// misc flags
|
// misc flags
|
||||||
stream.read(r.alternateRoom);
|
stream.read(r.alternateRoom);
|
||||||
stream.read(r.flags.value);
|
stream.read(r.flags.value);
|
||||||
if (version & VER_TR3) {
|
if (version & (VER_TR3 | VER_TR4)) {
|
||||||
stream.read(r.waterScheme);
|
stream.read(r.waterScheme);
|
||||||
stream.read(r.reverbType);
|
stream.read(r.reverbType);
|
||||||
|
stream.read(r.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
r.dynLightsCount = 0;
|
r.dynLightsCount = 0;
|
||||||
@ -4715,9 +4914,11 @@ namespace TR {
|
|||||||
|
|
||||||
void initMesh(int mIndex, Entity::Type type = Entity::NONE) {
|
void initMesh(int mIndex, Entity::Type type = Entity::NONE) {
|
||||||
int offset = meshOffsets[mIndex];
|
int offset = meshOffsets[mIndex];
|
||||||
for (int i = 0; i < meshesCount; i++)
|
for (int i = 0; i < meshesCount; i++) {
|
||||||
if (meshes[i].offset == offset)
|
if (meshes[i].offset == offset) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Stream stream(NULL, &meshData[offset / 2], 1024 * 1024);
|
Stream stream(NULL, &meshData[offset / 2], 1024 * 1024);
|
||||||
|
|
||||||
@ -4920,24 +5121,9 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
case VER_TR1_PC :
|
case VER_TR1_PC :
|
||||||
case VER_TR2_PC :
|
case VER_TR2_PC :
|
||||||
case VER_TR3_PC : {
|
case VER_TR3_PC :
|
||||||
/* struct {
|
case VER_TR4_PC :
|
||||||
short3 center;
|
case VER_TR5_PC : {
|
||||||
short2 collider;
|
|
||||||
short vCount;
|
|
||||||
short3 vertices[vCount];
|
|
||||||
short nCount;
|
|
||||||
short3 normals[max(0, nCount)];
|
|
||||||
ushort luminance[-min(0, nCount)];
|
|
||||||
short rCount;
|
|
||||||
Rectangle rectangles[rCount];
|
|
||||||
short tCount;
|
|
||||||
Triangle triangles[tCount];
|
|
||||||
short crCount;
|
|
||||||
Rectangle crectangles[crCount];
|
|
||||||
short ctCount;
|
|
||||||
Triangle ctriangles[ctCount];
|
|
||||||
}; */
|
|
||||||
mesh.vertices = new Mesh::Vertex[mesh.vCount];
|
mesh.vertices = new Mesh::Vertex[mesh.vCount];
|
||||||
for (int i = 0; i < mesh.vCount; i++) {
|
for (int i = 0; i < mesh.vCount; i++) {
|
||||||
short4 &c = mesh.vertices[i].coord;
|
short4 &c = mesh.vertices[i].coord;
|
||||||
@ -4963,13 +5149,22 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 rCount, tCount, crCount, ctCount;
|
uint16 rCount, tCount, crCount = 0, ctCount = 0;
|
||||||
|
|
||||||
|
int faceSize4 = FACE4_SIZE;
|
||||||
|
int faceSize3 = FACE3_SIZE;
|
||||||
|
if (version & (VER_TR4 | VER_TR5)) {
|
||||||
|
faceSize4 += 2;
|
||||||
|
faceSize3 += 2;
|
||||||
|
}
|
||||||
|
|
||||||
int tmp = stream.pos;
|
int tmp = stream.pos;
|
||||||
stream.seek(stream.read(rCount) * FACE4_SIZE); // uint32 colored (not existing in file)
|
stream.seek(stream.read(rCount) * faceSize4); // uint32 colored (not existing in file)
|
||||||
stream.seek(stream.read(tCount) * FACE3_SIZE);
|
stream.seek(stream.read(tCount) * faceSize3);
|
||||||
stream.seek(stream.read(crCount) * FACE4_SIZE);
|
if (!(version & (VER_TR4 | VER_TR5))) {
|
||||||
stream.seek(stream.read(ctCount) * FACE3_SIZE);
|
stream.seek(stream.read(crCount) * faceSize4);
|
||||||
|
stream.seek(stream.read(ctCount) * faceSize3);
|
||||||
|
}
|
||||||
stream.setPos(tmp);
|
stream.setPos(tmp);
|
||||||
|
|
||||||
mesh.rCount = rCount + crCount;
|
mesh.rCount = rCount + crCount;
|
||||||
@ -4978,26 +5173,26 @@ namespace TR {
|
|||||||
mesh.faces = mesh.fCount ? new Face[mesh.fCount] : NULL;
|
mesh.faces = mesh.fCount ? new Face[mesh.fCount] : NULL;
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
stream.seek(sizeof(rCount)); for (int i = 0; i < rCount; i++) readFace(stream, mesh.faces[idx++], false, false);
|
stream.seek(sizeof(rCount)); for (int i = 0; i < rCount; i++) readFace(stream, mesh.faces[idx++], false, false, false);
|
||||||
stream.seek(sizeof(tCount)); for (int i = 0; i < tCount; i++) readFace(stream, mesh.faces[idx++], false, true);
|
stream.seek(sizeof(tCount)); for (int i = 0; i < tCount; i++) readFace(stream, mesh.faces[idx++], false, true, false);
|
||||||
stream.seek(sizeof(crCount)); for (int i = 0; i < crCount; i++) readFace(stream, mesh.faces[idx++], true, false);
|
if (!(version & (VER_TR4 | VER_TR5))) {
|
||||||
stream.seek(sizeof(ctCount)); for (int i = 0; i < ctCount; i++) readFace(stream, mesh.faces[idx++], true, true);
|
stream.seek(sizeof(crCount)); for (int i = 0; i < crCount; i++) readFace(stream, mesh.faces[idx++], true, false, false);
|
||||||
|
stream.seek(sizeof(ctCount)); for (int i = 0; i < ctCount; i++) readFace(stream, mesh.faces[idx++], true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (int i = 0; i < mesh.fCount; i++) {
|
||||||
|
Face &f = mesh.faces[i];
|
||||||
|
for (int j = 0; j < (f.triangle ? 3 : 4); j++) {
|
||||||
|
ASSERT(f.vertices[j] < mesh.vCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VER_TR1_PSX :
|
case VER_TR1_PSX :
|
||||||
case VER_TR2_PSX : {
|
case VER_TR2_PSX : {
|
||||||
/* struct {
|
|
||||||
short3 center;
|
|
||||||
short2 collider;
|
|
||||||
short vCount;
|
|
||||||
short4 vertices[abs(vCount)];
|
|
||||||
short4 normals[max(0, vCount)];
|
|
||||||
ushort luminance[-min(0, vCount)];
|
|
||||||
short rCount;
|
|
||||||
Rectangle rectangles[rCount];
|
|
||||||
short tCount;
|
|
||||||
Triangle triangles[tCount];
|
|
||||||
}; */
|
|
||||||
int nCount = mesh.vCount;
|
int nCount = mesh.vCount;
|
||||||
mesh.vCount = abs(mesh.vCount);
|
mesh.vCount = abs(mesh.vCount);
|
||||||
mesh.vertices = new Mesh::Vertex[mesh.vCount];
|
mesh.vertices = new Mesh::Vertex[mesh.vCount];
|
||||||
@ -5035,8 +5230,8 @@ namespace TR {
|
|||||||
mesh.faces = mesh.fCount ? new Face[mesh.fCount] : NULL;
|
mesh.faces = mesh.fCount ? new Face[mesh.fCount] : NULL;
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
stream.seek(sizeof(mesh.rCount)); for (int i = 0; i < mesh.rCount; i++) readFace(stream, mesh.faces[idx++], false, false);
|
stream.seek(sizeof(mesh.rCount)); for (int i = 0; i < mesh.rCount; i++) readFace(stream, mesh.faces[idx++], false, false, false);
|
||||||
stream.seek(sizeof(mesh.tCount)); for (int i = 0; i < mesh.tCount; i++) readFace(stream, mesh.faces[idx++], false, true);
|
stream.seek(sizeof(mesh.tCount)); for (int i = 0; i < mesh.tCount; i++) readFace(stream, mesh.faces[idx++], false, true, false);
|
||||||
|
|
||||||
if (!mesh.fCount)
|
if (!mesh.fCount)
|
||||||
LOG("! warning: mesh %d has no geometry with %d vertices\n", meshesCount - 1, mesh.vCount);
|
LOG("! warning: mesh %d has no geometry with %d vertices\n", meshesCount - 1, mesh.vCount);
|
||||||
@ -5264,10 +5459,32 @@ namespace TR {
|
|||||||
uint8 xh2, x2, yh2, y2;
|
uint8 xh2, x2, yh2, y2;
|
||||||
uint8 xh3, x3, yh3, y3;
|
uint8 xh3, x3, yh3, y3;
|
||||||
} d;
|
} d;
|
||||||
|
|
||||||
stream.raw(&d, sizeof(d));
|
stream.raw(&d, sizeof(d));
|
||||||
SET_PARAMS(t, d, 0);
|
SET_PARAMS(t, d, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VER_TR4_PC :
|
||||||
|
case VER_TR5_PC : {
|
||||||
|
struct {
|
||||||
|
uint16 attribute;
|
||||||
|
uint16 tile:14, :2;
|
||||||
|
uint16 flags;
|
||||||
|
uint8 xh0, x0, yh0, y0;
|
||||||
|
uint8 xh1, x1, yh1, y1;
|
||||||
|
uint8 xh2, x2, yh2, y2;
|
||||||
|
uint8 xh3, x3, yh3, y3;
|
||||||
|
} d;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32 U, V, W, H;
|
||||||
|
} duv;
|
||||||
|
|
||||||
|
stream.raw(&d, sizeof(d));
|
||||||
|
stream.raw(&duv, sizeof(duv));
|
||||||
|
SET_PARAMS(t, d, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case VER_TR1_PSX :
|
case VER_TR1_PSX :
|
||||||
case VER_TR2_PSX :
|
case VER_TR2_PSX :
|
||||||
case VER_TR3_PSX : {
|
case VER_TR3_PSX : {
|
||||||
@ -5305,9 +5522,10 @@ namespace TR {
|
|||||||
|
|
||||||
void readObjectTex(Stream &stream) {
|
void readObjectTex(Stream &stream) {
|
||||||
objectTextures = stream.read(objectTexturesCount) ? new TextureInfo[objectTexturesCount] : NULL;
|
objectTextures = stream.read(objectTexturesCount) ? new TextureInfo[objectTexturesCount] : NULL;
|
||||||
for (int i = 0; i < objectTexturesCount; i++)
|
for (int i = 0; i < objectTexturesCount; i++) {
|
||||||
readObjectTex(stream, objectTextures[i]);
|
readObjectTex(stream, objectTextures[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void readSpriteTex(Stream &stream, TextureInfo &t) {
|
void readSpriteTex(Stream &stream, TextureInfo &t) {
|
||||||
#define SET_PARAMS(t, d, c) {\
|
#define SET_PARAMS(t, d, c) {\
|
||||||
@ -5347,7 +5565,9 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
case VER_TR1_PC :
|
case VER_TR1_PC :
|
||||||
case VER_TR2_PC :
|
case VER_TR2_PC :
|
||||||
case VER_TR3_PC : {
|
case VER_TR3_PC :
|
||||||
|
case VER_TR4_PC :
|
||||||
|
case VER_TR5_PC : {
|
||||||
struct {
|
struct {
|
||||||
uint16 tile;
|
uint16 tile;
|
||||||
uint8 u, v;
|
uint8 u, v;
|
||||||
@ -5423,9 +5643,9 @@ namespace TR {
|
|||||||
void readAnimTex(Stream &stream) {
|
void readAnimTex(Stream &stream) {
|
||||||
uint32 size;
|
uint32 size;
|
||||||
stream.read(size);
|
stream.read(size);
|
||||||
|
stream.seek(size * 2);
|
||||||
if (!size) return;
|
size = 0;
|
||||||
|
if (size) {
|
||||||
stream.read(animTexturesCount);
|
stream.read(animTexturesCount);
|
||||||
animTextures = animTexturesCount ? new AnimTexture[animTexturesCount] : NULL;
|
animTextures = animTexturesCount ? new AnimTexture[animTexturesCount] : NULL;
|
||||||
|
|
||||||
@ -5438,6 +5658,12 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version & (VER_TR4 | VER_TR5)) {
|
||||||
|
uint8 animTexUVs;
|
||||||
|
stream.read(animTexUVs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void readEntities(Stream &stream) {
|
void readEntities(Stream &stream) {
|
||||||
entitiesCount = stream.read(entitiesBaseCount) + MAX_RESERVED_ENTITIES;
|
entitiesCount = stream.read(entitiesBaseCount) + MAX_RESERVED_ENTITIES;
|
||||||
entities = new Entity[entitiesCount];
|
entities = new Entity[entitiesCount];
|
||||||
@ -5449,10 +5675,14 @@ namespace TR {
|
|||||||
stream.read(e.x);
|
stream.read(e.x);
|
||||||
stream.read(e.y);
|
stream.read(e.y);
|
||||||
stream.read(e.z);
|
stream.read(e.z);
|
||||||
stream.read(e.rotation);
|
stream.read(e.rotation.value);
|
||||||
stream.read(e.intensity);
|
stream.read(e.intensity);
|
||||||
if (version & (VER_TR2 | VER_TR3))
|
if (version & (VER_TR2 | VER_TR3)) {
|
||||||
stream.read(e.intensity2);
|
stream.read(e.intensity2);
|
||||||
|
}
|
||||||
|
if (version & (VER_TR4 | VER_TR5)) {
|
||||||
|
stream.read(e.OCB);
|
||||||
|
}
|
||||||
stream.read(e.flags.value);
|
stream.read(e.flags.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5600,6 +5830,23 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VER_TR4_PC :
|
||||||
|
case VER_TR5_PC : {
|
||||||
|
ASSERT(tiles32);
|
||||||
|
|
||||||
|
Color32 *ptr = &dst->color[uv.y * 256];
|
||||||
|
for (int y = uv.y; y < uv.w; y++) {
|
||||||
|
for (int x = uv.x; x < uv.z; x++) {
|
||||||
|
Color32 c = tiles32[t->tile].color[y * 256 + x];
|
||||||
|
ptr[x].r = c.b;
|
||||||
|
ptr[x].g = c.g;
|
||||||
|
ptr[x].b = c.r;
|
||||||
|
ptr[x].a = c.a;
|
||||||
|
}
|
||||||
|
ptr += 256;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case VER_TR1_PSX :
|
case VER_TR1_PSX :
|
||||||
case VER_TR2_PSX :
|
case VER_TR2_PSX :
|
||||||
case VER_TR3_PSX : {
|
case VER_TR3_PSX : {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user