mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-15 09:34:18 +02:00
refactoring of level loader
This commit is contained in:
862
src/format.h
862
src/format.h
@@ -2280,8 +2280,6 @@ namespace TR {
|
||||
|
||||
int32 tilesCount;
|
||||
|
||||
uint32 unused;
|
||||
|
||||
uint16 roomsCount;
|
||||
Room *rooms;
|
||||
|
||||
@@ -2548,10 +2546,10 @@ namespace TR {
|
||||
|
||||
Level(Stream &stream) {
|
||||
memset(this, 0, sizeof(*this));
|
||||
version = VER_UNKNOWN;
|
||||
cutEntity = -1;
|
||||
version = VER_UNKNOWN;
|
||||
cutEntity = -1;
|
||||
meshesCount = 0;
|
||||
|
||||
int startPos = stream.pos;
|
||||
uint32 magic;
|
||||
|
||||
#define MAGIC_TR1_PC 0x00000020
|
||||
@@ -2562,87 +2560,34 @@ namespace TR {
|
||||
#define MAGIC_TR3_PC2 0xFF180038
|
||||
#define MAGIC_TR3_PC3 0xFF180034
|
||||
#define MAGIC_TR3_PSX 0xFFFFFFC8
|
||||
#define MAGIC_TR4_PC 0x00345254
|
||||
|
||||
id = TR::getLevelID(stream.size, stream.name, version, isDemoLevel);
|
||||
|
||||
if (version == VER_UNKNOWN || version == VER_TR1_PSX) {
|
||||
stream.read(magic);
|
||||
if (magic == MAGIC_TR1_SAT) {
|
||||
version = VER_TR1_SAT;
|
||||
|
||||
stream.seek(-4);
|
||||
// get file name without extension
|
||||
size_t len = strlen(stream.name);
|
||||
char *name = new char[len + 1];
|
||||
memcpy(name, stream.name, len);
|
||||
for (int i = int(len) - 1; i >= 0; i--) {
|
||||
if (name[i] == '/' || name[i] == '\\')
|
||||
break;
|
||||
if (name[i] == '.') {
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
name[len] = 0;
|
||||
LOG("load Sega Saturn level: %s\n", name);
|
||||
|
||||
strcat(name, ".SAD");
|
||||
Stream sad(name);
|
||||
name[len] = '\0';
|
||||
strcat(name, ".SPR");
|
||||
Stream spr(name);
|
||||
name[len] = '\0';
|
||||
strcat(name, ".SND");
|
||||
Stream snd(name);
|
||||
name[len] = '\0';
|
||||
strcat(name, ".CIN");
|
||||
|
||||
Stream *cin = NULL;
|
||||
if (Stream::existsContent(name)) {
|
||||
cin = new Stream(name);
|
||||
} else {
|
||||
len = strlen(name);
|
||||
for (int i = int(len) - 1; i >= 0; i--)
|
||||
if (name[i] == '/' || name[i] == '\\') {
|
||||
char *newName = new char[len + 11 + 1];
|
||||
name[i] = 0;
|
||||
strcpy(newName, name);
|
||||
strcat(newName, "/../CINDATA/");
|
||||
strcat(newName, name + i + 1);
|
||||
delete[] name;
|
||||
name = newName;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Stream::existsContent(name))
|
||||
cin = new Stream(name);
|
||||
}
|
||||
|
||||
delete[] name;
|
||||
|
||||
readSAT(sad);
|
||||
readSAT(spr);
|
||||
readSAT(snd);
|
||||
if (cin) {
|
||||
readCIN(*cin);
|
||||
delete cin;
|
||||
}
|
||||
readSAT(stream); // sat
|
||||
return;
|
||||
}
|
||||
|
||||
if (magic != MAGIC_TR1_PC && magic != MAGIC_TR2_PC && magic != MAGIC_TR3_PC1 && magic != MAGIC_TR3_PC2 && magic != MAGIC_TR3_PC3 && magic != MAGIC_TR3_PSX) {
|
||||
if (magic != MAGIC_TR1_PC &&
|
||||
magic != MAGIC_TR1_SAT &&
|
||||
magic != MAGIC_TR2_PC &&
|
||||
magic != MAGIC_TR3_PC1 &&
|
||||
magic != MAGIC_TR3_PC2 &&
|
||||
magic != MAGIC_TR3_PC3 &&
|
||||
magic != MAGIC_TR3_PSX &&
|
||||
magic != MAGIC_TR4_PC) {
|
||||
stream.read(magic);
|
||||
}
|
||||
|
||||
switch (magic) {
|
||||
case MAGIC_TR1_PC : version = VER_TR1_PC; break;
|
||||
case MAGIC_TR1_PSX : version = VER_TR1_PSX; break;
|
||||
case MAGIC_TR1_SAT : version = VER_TR1_SAT; break;
|
||||
case MAGIC_TR2_PC : version = VER_TR2_PC; break;
|
||||
case MAGIC_TR3_PC1 :
|
||||
case MAGIC_TR3_PC2 :
|
||||
case MAGIC_TR3_PC3 : version = VER_TR3_PC; break;
|
||||
case MAGIC_TR3_PSX : version = VER_TR3_PSX; break;
|
||||
//case MAGIC_TR4_PC : version = VER_TR4_PC; break;
|
||||
default : ;
|
||||
}
|
||||
}
|
||||
@@ -2653,291 +2598,20 @@ namespace TR {
|
||||
return;
|
||||
}
|
||||
|
||||
if (version == VER_TR2_PSX) {
|
||||
stream.read(soundOffsets, stream.read(soundOffsetsCount) + 1);
|
||||
soundSize = new uint32[soundOffsetsCount];
|
||||
soundDataSize = 0;
|
||||
for (int i = 0; i < soundOffsetsCount; i++) {
|
||||
ASSERT(soundOffsets[i] < soundOffsets[i + 1]);
|
||||
soundSize[i] = soundOffsets[i + 1] - soundOffsets[i];
|
||||
soundOffsets[i] = soundDataSize;
|
||||
soundDataSize += soundSize[i];
|
||||
}
|
||||
stream.read(soundData, soundDataSize);
|
||||
}
|
||||
|
||||
if (version == VER_TR3_PSX) {
|
||||
stream.read(soundOffsets, stream.read(soundOffsetsCount));
|
||||
if (soundOffsetsCount) {
|
||||
stream.read(soundDataSize);
|
||||
stream.read(soundData, soundDataSize);
|
||||
soundSize = new uint32[soundOffsetsCount];
|
||||
int size = 0;
|
||||
for (int i = 0; i < soundOffsetsCount - 1; i++) {
|
||||
ASSERT(soundOffsets[i] < soundOffsets[i + 1]);
|
||||
size += soundSize[i] = soundOffsets[i + 1] - soundOffsets[i];
|
||||
}
|
||||
|
||||
if (soundOffsetsCount) {
|
||||
soundSize[soundOffsetsCount - 1] = soundDataSize;
|
||||
if (soundOffsetsCount > 1)
|
||||
soundSize[soundOffsetsCount - 1] -= soundSize[soundOffsetsCount - 2];
|
||||
}
|
||||
}
|
||||
|
||||
// skip code modules
|
||||
int size;
|
||||
for (int i = 0; i < 13; i++) {
|
||||
stream.read(size);
|
||||
if (size) {
|
||||
stream.seek(size);
|
||||
stream.read(size);
|
||||
stream.seek(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version == VER_TR2_PC || version == VER_TR3_PC) {
|
||||
stream.read(palette, 256);
|
||||
stream.read(palette32, 256);
|
||||
}
|
||||
|
||||
if (version == VER_TR1_PSX && !isCutsceneLevel()) {
|
||||
uint32 offsetTexTiles;
|
||||
stream.seek(8);
|
||||
stream.read(offsetTexTiles);
|
||||
// sound offsets
|
||||
uint16 numSounds;
|
||||
stream.setPos(startPos + 22);
|
||||
stream.read(numSounds);
|
||||
stream.setPos(startPos + 2086 + numSounds * 512);
|
||||
soundOffsetsCount = numSounds;
|
||||
soundOffsets = new uint32[soundOffsetsCount];
|
||||
soundSize = new uint32[soundOffsetsCount];
|
||||
soundDataSize = 0;
|
||||
for (int i = 0; i < soundOffsetsCount; i++) {
|
||||
soundOffsets[i] = soundDataSize;
|
||||
uint16 size;
|
||||
stream.read(size);
|
||||
soundDataSize += soundSize[i] = size * 8;
|
||||
}
|
||||
// sound data
|
||||
stream.setPos(startPos + 2600 + numSounds * 512);
|
||||
stream.read(soundData, soundDataSize);
|
||||
stream.setPos(startPos + offsetTexTiles + 8);
|
||||
}
|
||||
|
||||
// tiles
|
||||
if (version & VER_PC) {
|
||||
stream.read(tiles8, stream.read(tilesCount));
|
||||
}
|
||||
|
||||
if (version == VER_TR2_PC || version == VER_TR3_PC)
|
||||
stream.read(tiles16, tilesCount);
|
||||
|
||||
if (version == VER_TR1_PSX) {
|
||||
stream.read(tiles4, tilesCount = 13);
|
||||
stream.read(cluts, clutsCount = 1024);
|
||||
}
|
||||
|
||||
if (version != VER_TR3_PSX)
|
||||
stream.read(unused);
|
||||
|
||||
// rooms
|
||||
rooms = stream.read(roomsCount) ? new Room[roomsCount] : NULL;
|
||||
for (int i = 0; i < roomsCount; i++)
|
||||
readRoom(stream, i);
|
||||
|
||||
// floors
|
||||
stream.read(floors, stream.read(floorsCount));
|
||||
|
||||
if (version == VER_TR3_PSX) {
|
||||
// outside room offsets
|
||||
stream.seek(27 * 27 * 2);
|
||||
// outside rooms table
|
||||
int size;
|
||||
stream.read(size);
|
||||
stream.seek(size);
|
||||
// room mesh bbox
|
||||
stream.read(size);
|
||||
stream.seek(8 * size);
|
||||
}
|
||||
|
||||
// meshes
|
||||
meshesCount = 0;
|
||||
stream.read(meshData, stream.read(meshDataSize));
|
||||
stream.read(meshOffsets, stream.read(meshOffsetsCount));
|
||||
// animations
|
||||
|
||||
stream.read(anims, stream.read(animsCount));
|
||||
stream.read(states, stream.read(statesCount));
|
||||
stream.read(ranges, stream.read(rangesCount));
|
||||
stream.read(commands, stream.read(commandsCount));
|
||||
stream.read(nodesData, stream.read(nodesDataSize));
|
||||
stream.read(frameData, stream.read(frameDataSize));
|
||||
// models
|
||||
models = stream.read(modelsCount) ? new Model[modelsCount] : NULL;
|
||||
for (int i = 0; i < modelsCount; i++) {
|
||||
Model &m = models[i];
|
||||
uint16 type;
|
||||
m.type = Entity::Type(stream.read(type));
|
||||
stream.seek(sizeof(m.index));
|
||||
m.index = i;
|
||||
stream.read(m.mCount);
|
||||
stream.read(m.mStart);
|
||||
stream.read(m.node);
|
||||
stream.read(m.frame);
|
||||
stream.read(m.animation);
|
||||
if (version & VER_PSX)
|
||||
stream.seek(2);
|
||||
}
|
||||
stream.read(staticMeshes, stream.read(staticMeshesCount));
|
||||
|
||||
if (version == VER_TR2_PSX || version == VER_TR3_PSX) {
|
||||
stream.read(tiles4, stream.read(tilesCount));
|
||||
stream.read(clutsCount);
|
||||
if (clutsCount > 1024) { // check for japanese version (read kanji CLUT index)
|
||||
kanjiSprite = clutsCount & 0xFFFF;
|
||||
stream.seek(-2);
|
||||
stream.read(clutsCount);
|
||||
}
|
||||
if (version == VER_TR3_PSX)
|
||||
clutsCount *= 2; // read underwater cluts too
|
||||
stream.read(cluts, clutsCount);
|
||||
if (version != VER_TR3_PSX)
|
||||
stream.seek(4);
|
||||
}
|
||||
|
||||
// textures & UV
|
||||
if (version != VER_TR3_PC)
|
||||
readObjectTex(stream);
|
||||
readSpriteTex(stream);
|
||||
// palette for demo levels
|
||||
if (version == VER_TR1_PC && isDemoLevel) stream.read(palette, 256);
|
||||
// cameras
|
||||
stream.read(cameras, stream.read(camerasCount));
|
||||
// sound sources
|
||||
stream.read(soundSources, stream.read(soundSourcesCount));
|
||||
// AI
|
||||
boxes = stream.read(boxesCount) ? new Box[boxesCount] : NULL;
|
||||
for (int i = 0; i < boxesCount; i++) {
|
||||
Box &b = boxes[i];
|
||||
if (version & VER_TR1) {
|
||||
stream.read(b.minZ);
|
||||
stream.read(b.maxZ);
|
||||
stream.read(b.minX);
|
||||
stream.read(b.maxX);
|
||||
}
|
||||
|
||||
if (version & (VER_TR2 | VER_TR3)) {
|
||||
uint8 value;
|
||||
b.minZ = stream.read(value) * 1024;
|
||||
b.maxZ = stream.read(value) * 1024;
|
||||
b.minX = stream.read(value) * 1024;
|
||||
b.maxX = stream.read(value) * 1024;
|
||||
}
|
||||
|
||||
stream.read(b.floor);
|
||||
stream.read(b.overlap.value);
|
||||
}
|
||||
|
||||
stream.read(overlaps, stream.read(overlapsCount));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
stream.read(zones[i].ground1, boxesCount);
|
||||
stream.read(zones[i].ground2, boxesCount);
|
||||
if (!(version & VER_TR1)) {
|
||||
stream.read(zones[i].ground3, boxesCount);
|
||||
stream.read(zones[i].ground4, boxesCount);
|
||||
} else {
|
||||
zones[i].ground3 = NULL;
|
||||
zones[i].ground4 = NULL;
|
||||
}
|
||||
stream.read(zones[i].fly, boxesCount);
|
||||
}
|
||||
|
||||
// animated textures
|
||||
readAnimTex(stream);
|
||||
|
||||
if (version == VER_TR3_PC)
|
||||
readObjectTex(stream);
|
||||
|
||||
// entities (enemies, items, lara etc.)
|
||||
readEntities(stream);
|
||||
|
||||
if (version & VER_PC) {
|
||||
stream.seek(32 * 256);
|
||||
// palette for release levels
|
||||
if ((version == VER_TR1_PC) && !isDemoLevel)
|
||||
stream.read(palette, 256);
|
||||
// cinematic frames for cameras (PC)
|
||||
stream.read(cameraFrames, stream.read(cameraFramesCount));
|
||||
// demo data
|
||||
stream.read(demoData, stream.read(demoDataSize));
|
||||
}
|
||||
|
||||
if (version == VER_TR2_PSX)
|
||||
stream.seek(4);
|
||||
|
||||
if (version == VER_TR3_PSX) {
|
||||
stream.read(skyColor);
|
||||
|
||||
roomTexturesCount = stream.readLE32();
|
||||
|
||||
if (roomTexturesCount) {
|
||||
roomTextures = new TextureInfo[roomTexturesCount];
|
||||
|
||||
// load room textures
|
||||
for (int i = 0; i < roomTexturesCount; i++) {
|
||||
readObjectTex(stream, roomTextures[i], TEX_TYPE_ROOM);
|
||||
stream.seek(2 * 16); // skip 2 mipmap levels
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sounds
|
||||
stream.read(soundsMap, (version & VER_TR1) ? 256 : 370);
|
||||
soundsInfo = stream.read(soundsInfoCount) ? new SoundInfo[soundsInfoCount] : NULL;
|
||||
for (int i = 0; i < soundsInfoCount; i++) {
|
||||
SoundInfo &s = soundsInfo[i];
|
||||
|
||||
stream.read(s.index);
|
||||
if (version & (VER_TR1 | VER_TR2)) {
|
||||
uint16 v;
|
||||
stream.read(v); s.volume = float(v) / 0x7FFF;
|
||||
stream.read(v); s.chance = float(v) / 0xFFFF;
|
||||
s.range = 8 * 1024;
|
||||
s.pitch = 0.2f;
|
||||
} else {
|
||||
uint8 v;
|
||||
stream.read(v); s.volume = float(v) / 0xFF;
|
||||
stream.read(v); s.range = float(v) * 1024;
|
||||
stream.read(v); s.chance = float(v) / 0xFF;
|
||||
stream.read(v); s.pitch = float(v) / 0xFF;
|
||||
}
|
||||
|
||||
stream.read(s.flags.value);
|
||||
|
||||
ASSERT(s.volume <= 1.0f);
|
||||
}
|
||||
|
||||
if (version == VER_TR3_PSX)
|
||||
stream.seek(4);
|
||||
|
||||
if (version == VER_TR1_PC) {
|
||||
stream.read(soundData, stream.read(soundDataSize));
|
||||
stream.read(soundOffsets, stream.read(soundOffsetsCount));
|
||||
}
|
||||
|
||||
if (version == VER_TR2_PC || version == VER_TR3_PC) {
|
||||
stream.read(soundOffsets, stream.read(soundOffsetsCount));
|
||||
new Stream(getGameSoundsFile(version), sfxLoadAsync, this);
|
||||
}
|
||||
|
||||
// cinematic frames for cameras (PSX)
|
||||
if (version & VER_PSX) {
|
||||
if (version != VER_TR3_PSX)
|
||||
stream.seek(4);
|
||||
stream.read(cameraFrames, stream.read(cameraFramesCount));
|
||||
switch (version) {
|
||||
case VER_TR1_PC : loadTR1_PC (stream); break;
|
||||
case VER_TR1_PSX : loadTR1_PSX (stream); break;
|
||||
case VER_TR1_SAT : loadTR1_SAT (stream); break;
|
||||
case VER_TR2_PC : loadTR2_PC (stream); break;
|
||||
case VER_TR2_PSX : loadTR2_PSX (stream); break;
|
||||
case VER_TR3_PC : loadTR3_PC (stream); break;
|
||||
case VER_TR3_PSX : loadTR3_PSX (stream); break;
|
||||
case VER_TR4_PC : loadTR4_PC (stream); break;
|
||||
case VER_TR4_PSX : loadTR4_PSX (stream); break;
|
||||
case VER_TR4_SDC : loadTR4_SDC (stream); break;
|
||||
case VER_TR5_PC : loadTR5_PC (stream); break;
|
||||
case VER_TR5_PSX : loadTR5_PSX (stream); break;
|
||||
case VER_TR5_SDC : loadTR5_SDC (stream); break;
|
||||
}
|
||||
|
||||
prepare();
|
||||
@@ -3007,6 +2681,481 @@ namespace TR {
|
||||
delete[] tsub;
|
||||
}
|
||||
|
||||
void loadTR1_PC (Stream &stream) {
|
||||
stream.read(tiles8, stream.read(tilesCount));
|
||||
|
||||
readDataArrays(stream);
|
||||
readObjectTex(stream);
|
||||
readSpriteTex(stream);
|
||||
|
||||
if (isDemoLevel) {
|
||||
stream.read(palette, 256);
|
||||
}
|
||||
|
||||
readCameras(stream);
|
||||
readSoundSources(stream);
|
||||
readBoxes(stream);
|
||||
readOverlaps(stream);
|
||||
readZones(stream);
|
||||
readAnimTex(stream);
|
||||
readEntities(stream);
|
||||
readLightMap(stream);
|
||||
|
||||
if (!isDemoLevel) {
|
||||
stream.read(palette, 256);
|
||||
}
|
||||
|
||||
readCameraFrames(stream);
|
||||
readDemoData(stream);
|
||||
readSoundMap(stream);
|
||||
readSoundData(stream);
|
||||
readSoundOffsets(stream);
|
||||
}
|
||||
|
||||
void loadTR1_PSX (Stream &stream) {
|
||||
if (!isCutsceneLevel()) {
|
||||
uint32 offsetTexTiles;
|
||||
stream.seek(8);
|
||||
stream.read(offsetTexTiles);
|
||||
// sound offsets
|
||||
uint16 numSounds;
|
||||
stream.setPos(22);
|
||||
stream.read(numSounds);
|
||||
stream.setPos(2086 + numSounds * 512);
|
||||
soundOffsetsCount = numSounds;
|
||||
soundOffsets = new uint32[soundOffsetsCount];
|
||||
soundSize = new uint32[soundOffsetsCount];
|
||||
soundDataSize = 0;
|
||||
for (int i = 0; i < soundOffsetsCount; i++) {
|
||||
soundOffsets[i] = soundDataSize;
|
||||
uint16 size;
|
||||
stream.read(size);
|
||||
soundDataSize += soundSize[i] = size * 8;
|
||||
}
|
||||
// sound data
|
||||
stream.setPos(2600 + numSounds * 512);
|
||||
stream.read(soundData, soundDataSize);
|
||||
stream.setPos(offsetTexTiles + 8);
|
||||
}
|
||||
|
||||
stream.read(tiles4, tilesCount = 13);
|
||||
stream.read(cluts, clutsCount = 1024);
|
||||
|
||||
readDataArrays(stream);
|
||||
readObjectTex(stream);
|
||||
readSpriteTex(stream);
|
||||
readCameras(stream);
|
||||
readSoundSources(stream);
|
||||
readBoxes(stream);
|
||||
readOverlaps(stream);
|
||||
readZones(stream);
|
||||
readAnimTex(stream);
|
||||
readEntities(stream);
|
||||
readSoundMap(stream);
|
||||
stream.seek(4);
|
||||
readCameraFrames(stream);
|
||||
}
|
||||
|
||||
void loadTR1_SAT (Stream &stream) {
|
||||
stream.seek(-4); // no magic header
|
||||
|
||||
// get file name without extension
|
||||
size_t len = strlen(stream.name);
|
||||
char *name = new char[len + 1];
|
||||
memcpy(name, stream.name, len);
|
||||
for (int i = int(len) - 1; i >= 0; i--) {
|
||||
if (name[i] == '/' || name[i] == '\\')
|
||||
break;
|
||||
if (name[i] == '.') {
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
name[len] = 0;
|
||||
|
||||
LOG("load Sega Saturn level: %s\n", name);
|
||||
|
||||
strcat(name, ".SAD");
|
||||
Stream sad(name);
|
||||
name[len] = '\0';
|
||||
strcat(name, ".SPR");
|
||||
Stream spr(name);
|
||||
name[len] = '\0';
|
||||
strcat(name, ".SND");
|
||||
Stream snd(name);
|
||||
name[len] = '\0';
|
||||
strcat(name, ".CIN");
|
||||
|
||||
Stream *cin = NULL;
|
||||
if (Stream::existsContent(name)) {
|
||||
cin = new Stream(name);
|
||||
} else {
|
||||
len = strlen(name);
|
||||
for (int i = int(len) - 1; i >= 0; i--)
|
||||
if (name[i] == '/' || name[i] == '\\') {
|
||||
char *newName = new char[len + 11 + 1];
|
||||
name[i] = 0;
|
||||
strcpy(newName, name);
|
||||
strcat(newName, "/../CINDATA/");
|
||||
strcat(newName, name + i + 1);
|
||||
delete[] name;
|
||||
name = newName;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Stream::existsContent(name))
|
||||
cin = new Stream(name);
|
||||
}
|
||||
|
||||
delete[] name;
|
||||
|
||||
readSAT(sad);
|
||||
readSAT(spr);
|
||||
readSAT(snd);
|
||||
if (cin) {
|
||||
readCIN(*cin);
|
||||
delete cin;
|
||||
}
|
||||
readSAT(stream); // sat
|
||||
}
|
||||
|
||||
void loadTR2_PC (Stream &stream) {
|
||||
stream.read(palette, 256);
|
||||
stream.read(palette32, 256);
|
||||
stream.read(tiles8, stream.read(tilesCount));
|
||||
stream.read(tiles16, tilesCount);
|
||||
|
||||
readDataArrays(stream);
|
||||
readObjectTex(stream);
|
||||
readSpriteTex(stream);
|
||||
readCameras(stream);
|
||||
readSoundSources(stream);
|
||||
readBoxes(stream);
|
||||
readOverlaps(stream);
|
||||
readZones(stream);
|
||||
readAnimTex(stream);
|
||||
readEntities(stream);
|
||||
readLightMap(stream);
|
||||
readCameraFrames(stream);
|
||||
readDemoData(stream);
|
||||
readSoundMap(stream);
|
||||
readSoundOffsets(stream);
|
||||
|
||||
new Stream(getGameSoundsFile(version), sfxLoadAsync, this);
|
||||
}
|
||||
|
||||
void loadTR2_PSX (Stream &stream) {
|
||||
stream.read(soundOffsets, stream.read(soundOffsetsCount) + 1);
|
||||
soundSize = new uint32[soundOffsetsCount];
|
||||
soundDataSize = 0;
|
||||
for (int i = 0; i < soundOffsetsCount; i++) {
|
||||
ASSERT(soundOffsets[i] < soundOffsets[i + 1]);
|
||||
soundSize[i] = soundOffsets[i + 1] - soundOffsets[i];
|
||||
soundOffsets[i] = soundDataSize;
|
||||
soundDataSize += soundSize[i];
|
||||
}
|
||||
stream.read(soundData, soundDataSize);
|
||||
|
||||
readDataArrays(stream);
|
||||
|
||||
stream.read(tiles4, stream.read(tilesCount));
|
||||
stream.read(clutsCount);
|
||||
if (clutsCount > 1024) { // check for japanese version (read kanji CLUT index)
|
||||
kanjiSprite = clutsCount & 0xFFFF;
|
||||
stream.seek(-2);
|
||||
stream.read(clutsCount);
|
||||
}
|
||||
stream.read(cluts, clutsCount);
|
||||
stream.seek(4);
|
||||
readObjectTex(stream);
|
||||
readSpriteTex(stream);
|
||||
readCameras(stream);
|
||||
readSoundSources(stream);
|
||||
readBoxes(stream);
|
||||
readOverlaps(stream);
|
||||
readZones(stream);
|
||||
readAnimTex(stream);
|
||||
readEntities(stream);
|
||||
stream.seek(4);
|
||||
readSoundMap(stream);
|
||||
stream.seek(4);
|
||||
readCameraFrames(stream);
|
||||
}
|
||||
|
||||
void loadTR3_PC (Stream &stream) {
|
||||
stream.read(palette, 256);
|
||||
stream.read(palette32, 256);
|
||||
stream.read(tiles8, stream.read(tilesCount));
|
||||
stream.read(tiles16, tilesCount);
|
||||
|
||||
readDataArrays(stream);
|
||||
readSpriteTex(stream);
|
||||
readCameras(stream);
|
||||
readSoundSources(stream);
|
||||
readBoxes(stream);
|
||||
readOverlaps(stream);
|
||||
readZones(stream);
|
||||
readAnimTex(stream);
|
||||
readObjectTex(stream);
|
||||
readEntities(stream);
|
||||
readLightMap(stream);
|
||||
readCameraFrames(stream);
|
||||
readDemoData(stream);
|
||||
readSoundMap(stream);
|
||||
readSoundOffsets(stream);
|
||||
new Stream(getGameSoundsFile(version), sfxLoadAsync, this);
|
||||
}
|
||||
|
||||
void loadTR3_PSX (Stream &stream) {
|
||||
readSoundOffsets(stream);
|
||||
if (soundOffsetsCount) {
|
||||
readSoundData(stream);
|
||||
soundSize = new uint32[soundOffsetsCount];
|
||||
int size = 0;
|
||||
for (int i = 0; i < soundOffsetsCount - 1; i++) {
|
||||
ASSERT(soundOffsets[i] < soundOffsets[i + 1]);
|
||||
size += soundSize[i] = soundOffsets[i + 1] - soundOffsets[i];
|
||||
}
|
||||
|
||||
if (soundOffsetsCount) {
|
||||
soundSize[soundOffsetsCount - 1] = soundDataSize;
|
||||
if (soundOffsetsCount > 1) {
|
||||
soundSize[soundOffsetsCount - 1] -= soundSize[soundOffsetsCount - 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// skip code modules
|
||||
int size;
|
||||
for (int i = 0; i < 13; i++) {
|
||||
stream.read(size);
|
||||
if (size) {
|
||||
stream.seek(size);
|
||||
stream.read(size);
|
||||
stream.seek(size);
|
||||
}
|
||||
}
|
||||
|
||||
readDataArrays(stream);
|
||||
|
||||
stream.read(tiles4, stream.read(tilesCount));
|
||||
stream.read(clutsCount);
|
||||
if (clutsCount > 1024) { // check for japanese version (read kanji CLUT index)
|
||||
kanjiSprite = clutsCount & 0xFFFF;
|
||||
stream.seek(-2);
|
||||
stream.read(clutsCount);
|
||||
}
|
||||
clutsCount *= 2; // read underwater cluts too
|
||||
stream.read(cluts, clutsCount);
|
||||
|
||||
readObjectTex(stream);
|
||||
readSpriteTex(stream);
|
||||
readCameras(stream);
|
||||
readSoundSources(stream);
|
||||
readBoxes(stream);
|
||||
readOverlaps(stream);
|
||||
readZones(stream);
|
||||
readAnimTex(stream);
|
||||
readEntities(stream);
|
||||
|
||||
stream.read(skyColor);
|
||||
|
||||
roomTexturesCount = stream.readLE32();
|
||||
|
||||
if (roomTexturesCount) {
|
||||
roomTextures = new TextureInfo[roomTexturesCount];
|
||||
|
||||
// load room textures
|
||||
for (int i = 0; i < roomTexturesCount; i++) {
|
||||
readObjectTex(stream, roomTextures[i], TEX_TYPE_ROOM);
|
||||
stream.seek(2 * 16); // skip 2 mipmap levels
|
||||
}
|
||||
}
|
||||
|
||||
readSoundMap(stream);
|
||||
stream.seek(4);
|
||||
readCameraFrames(stream);
|
||||
}
|
||||
|
||||
void loadTR4_PC (Stream &stream) {
|
||||
|
||||
}
|
||||
|
||||
void loadTR4_PSX (Stream &stream) {
|
||||
|
||||
}
|
||||
|
||||
void loadTR4_SDC (Stream &stream) {
|
||||
|
||||
}
|
||||
|
||||
void loadTR5_PC (Stream &stream) {
|
||||
|
||||
}
|
||||
|
||||
void loadTR5_PSX (Stream &stream) {
|
||||
|
||||
}
|
||||
|
||||
void loadTR5_SDC (Stream &stream) {
|
||||
|
||||
}
|
||||
|
||||
void readDataArrays(Stream &stream) {
|
||||
if (version != VER_TR3_PSX) {
|
||||
stream.seek(4);
|
||||
}
|
||||
|
||||
rooms = stream.read(roomsCount) ? new Room[roomsCount] : NULL;
|
||||
for (int i = 0; i < roomsCount; i++) {
|
||||
readRoom(stream, i);
|
||||
}
|
||||
|
||||
stream.read(floors, stream.read(floorsCount));
|
||||
|
||||
if (version == VER_TR3_PSX) {
|
||||
// outside room offsets
|
||||
stream.seek(27 * 27 * 2);
|
||||
// outside rooms table
|
||||
int size;
|
||||
stream.read(size);
|
||||
stream.seek(size);
|
||||
// room mesh bbox
|
||||
stream.read(size);
|
||||
stream.seek(8 * size);
|
||||
}
|
||||
|
||||
stream.read(meshData, stream.read(meshDataSize));
|
||||
stream.read(meshOffsets, stream.read(meshOffsetsCount));
|
||||
stream.read(anims, stream.read(animsCount));
|
||||
stream.read(states, stream.read(statesCount));
|
||||
stream.read(ranges, stream.read(rangesCount));
|
||||
stream.read(commands, stream.read(commandsCount));
|
||||
stream.read(nodesData, stream.read(nodesDataSize));
|
||||
stream.read(frameData, stream.read(frameDataSize));
|
||||
|
||||
readModels(stream);
|
||||
|
||||
stream.read(staticMeshes, stream.read(staticMeshesCount));
|
||||
}
|
||||
|
||||
void readModels(Stream &stream) {
|
||||
models = stream.read(modelsCount) ? new Model[modelsCount] : NULL;
|
||||
for (int i = 0; i < modelsCount; i++) {
|
||||
Model &m = models[i];
|
||||
uint16 type;
|
||||
m.type = Entity::Type(stream.read(type));
|
||||
stream.seek(sizeof(m.index));
|
||||
m.index = i;
|
||||
stream.read(m.mCount);
|
||||
stream.read(m.mStart);
|
||||
stream.read(m.node);
|
||||
stream.read(m.frame);
|
||||
stream.read(m.animation);
|
||||
if (version & VER_PSX) {
|
||||
stream.seek(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readCameras(Stream &stream) {
|
||||
stream.read(cameras, stream.read(camerasCount));
|
||||
}
|
||||
|
||||
void readSoundSources(Stream &stream) {
|
||||
stream.read(soundSources, stream.read(soundSourcesCount));
|
||||
}
|
||||
|
||||
void readBoxes(Stream &stream) {
|
||||
boxes = stream.read(boxesCount) ? new Box[boxesCount] : NULL;
|
||||
for (int i = 0; i < boxesCount; i++) {
|
||||
Box &b = boxes[i];
|
||||
if (version & VER_TR1) {
|
||||
stream.read(b.minZ);
|
||||
stream.read(b.maxZ);
|
||||
stream.read(b.minX);
|
||||
stream.read(b.maxX);
|
||||
}
|
||||
|
||||
if (version & (VER_TR2 | VER_TR3)) {
|
||||
uint8 value;
|
||||
b.minZ = stream.read(value) * 1024;
|
||||
b.maxZ = stream.read(value) * 1024;
|
||||
b.minX = stream.read(value) * 1024;
|
||||
b.maxX = stream.read(value) * 1024;
|
||||
}
|
||||
|
||||
stream.read(b.floor);
|
||||
stream.read(b.overlap.value);
|
||||
}
|
||||
}
|
||||
|
||||
void readOverlaps(Stream &stream) {
|
||||
stream.read(overlaps, stream.read(overlapsCount));
|
||||
}
|
||||
|
||||
void readZones(Stream &stream) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
stream.read(zones[i].ground1, boxesCount);
|
||||
stream.read(zones[i].ground2, boxesCount);
|
||||
if (!(version & VER_TR1)) {
|
||||
stream.read(zones[i].ground3, boxesCount);
|
||||
stream.read(zones[i].ground4, boxesCount);
|
||||
} else {
|
||||
zones[i].ground3 = NULL;
|
||||
zones[i].ground4 = NULL;
|
||||
}
|
||||
stream.read(zones[i].fly, boxesCount);
|
||||
}
|
||||
}
|
||||
|
||||
void readLightMap(Stream &stream) {
|
||||
stream.seek(32 * 256); // unused
|
||||
}
|
||||
|
||||
void readCameraFrames(Stream &stream) {
|
||||
stream.read(cameraFrames, stream.read(cameraFramesCount));
|
||||
}
|
||||
|
||||
void readDemoData(Stream &stream) {
|
||||
stream.read(demoData, stream.read(demoDataSize));
|
||||
}
|
||||
|
||||
void readSoundMap(Stream &stream) {
|
||||
stream.read(soundsMap, (version & VER_TR1) ? 256 : 370);
|
||||
soundsInfo = stream.read(soundsInfoCount) ? new SoundInfo[soundsInfoCount] : NULL;
|
||||
for (int i = 0; i < soundsInfoCount; i++) {
|
||||
SoundInfo &s = soundsInfo[i];
|
||||
|
||||
stream.read(s.index);
|
||||
if (version & (VER_TR1 | VER_TR2)) {
|
||||
uint16 v;
|
||||
stream.read(v); s.volume = float(v) / 0x7FFF;
|
||||
stream.read(v); s.chance = float(v) / 0xFFFF;
|
||||
s.range = 8 * 1024;
|
||||
s.pitch = 0.2f;
|
||||
} else {
|
||||
uint8 v;
|
||||
stream.read(v); s.volume = float(v) / 0xFF;
|
||||
stream.read(v); s.range = float(v) * 1024;
|
||||
stream.read(v); s.chance = float(v) / 0xFF;
|
||||
stream.read(v); s.pitch = float(v) / 0xFF;
|
||||
}
|
||||
|
||||
stream.read(s.flags.value);
|
||||
|
||||
ASSERT(s.volume <= 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void readSoundData(Stream &stream) {
|
||||
stream.read(soundData, stream.read(soundDataSize));
|
||||
}
|
||||
|
||||
void readSoundOffsets(Stream &stream) {
|
||||
stream.read(soundOffsets, stream.read(soundOffsetsCount));
|
||||
}
|
||||
|
||||
#define CHUNK(str) ((uint64)((const char*)(str))[0] | ((uint64)((const char*)(str))[1] << 8) | ((uint64)((const char*)(str))[2] << 16) | ((uint64)((const char*)(str))[3] << 24) | \
|
||||
((uint64)((const char*)(str))[4] << 32) | ((uint64)((const char*)(str))[5] << 40) | ((uint64)((const char*)(str))[6] << 48) | ((uint64)((const char*)(str))[7] << 56))
|
||||
|
||||
@@ -3439,7 +3588,6 @@ namespace TR {
|
||||
case CHUNK("ROOMEND ") :
|
||||
ASSERTV(stream.readBE32() == 0x00000000);
|
||||
ASSERTV(stream.readBE32() == 0x00000000);
|
||||
prepare();
|
||||
break;
|
||||
// SAD
|
||||
case CHUNK("OBJFILE ") :
|
||||
@@ -4044,7 +4192,7 @@ namespace TR {
|
||||
TextureInfo &t = objectTextures[f.flags.texture];
|
||||
if (t.type != TEX_TYPE_OBJECT) {
|
||||
if (!dupObjTex) {
|
||||
dupObjTex = new TextureInfo[128];
|
||||
dupObjTex = new TextureInfo[256];
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
@@ -4056,7 +4204,7 @@ namespace TR {
|
||||
}
|
||||
|
||||
if (index == dupObjTexCount) {
|
||||
ASSERT(index <= 128);
|
||||
ASSERT(index <= 256);
|
||||
dupObjTex[dupObjTexCount] = t;
|
||||
dupObjTex[dupObjTexCount].type = TEX_TYPE_OBJECT;
|
||||
dupObjTexCount++;
|
||||
|
@@ -18,15 +18,16 @@ namespace TR {
|
||||
enum Version {
|
||||
VER_UNKNOWN = 0,
|
||||
|
||||
VER_PC = 256,
|
||||
VER_PSX = 512,
|
||||
VER_SAT = 1024,
|
||||
VER_PC = 0x1000,
|
||||
VER_PSX = 0x2000,
|
||||
VER_SAT = 0x4000,
|
||||
VER_SDC = 0x8000,
|
||||
|
||||
VER_TR1 = 1,
|
||||
VER_TR2 = 2,
|
||||
VER_TR3 = 4,
|
||||
VER_TR4 = 8,
|
||||
VER_TR5 = 16,
|
||||
VER_TR1 = 0x01,
|
||||
VER_TR2 = 0x02,
|
||||
VER_TR3 = 0x04,
|
||||
VER_TR4 = 0x08,
|
||||
VER_TR5 = 0x10,
|
||||
|
||||
VER_VERSION = VER_TR1 | VER_TR2 | VER_TR3 | VER_TR4 | VER_TR5,
|
||||
VER_PLATFORM = VER_PC | VER_PSX | VER_SAT,
|
||||
@@ -41,6 +42,14 @@ namespace TR {
|
||||
VER_TR3_PC = VER_TR3 | VER_PC,
|
||||
VER_TR3_PSX = VER_TR3 | VER_PSX,
|
||||
|
||||
VER_TR4_PC = VER_TR4 | VER_PC,
|
||||
VER_TR4_PSX = VER_TR4 | VER_PSX,
|
||||
VER_TR4_SDC = VER_TR4 | VER_SDC,
|
||||
|
||||
VER_TR5_PC = VER_TR5 | VER_PC,
|
||||
VER_TR5_PSX = VER_TR5 | VER_PSX,
|
||||
VER_TR5_SDC = VER_TR5 | VER_SDC,
|
||||
|
||||
VER_MAX = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
|
@@ -466,13 +466,13 @@ namespace GAPI {
|
||||
C3D_AttrInfo vertexAttribs;
|
||||
|
||||
void init() {
|
||||
gfxInitDefault();
|
||||
consoleInit(GFX_BOTTOM, NULL);
|
||||
|
||||
LOG("Vendor : %s\n", "Nintendo");
|
||||
LOG("Renderer : %s\n", "PICA200 citro3D");
|
||||
LOG("Version : %s\n", "1.0");
|
||||
|
||||
gfxInitDefault();
|
||||
consoleInit(GFX_BOTTOM, NULL);
|
||||
|
||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||
defTarget[0] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
defTarget[1] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
|
Reference in New Issue
Block a user