mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 07:34:33 +02:00
move memory stream to stream.h, PHD loader (WIP)
This commit is contained in:
@@ -1594,60 +1594,4 @@ void dmaCopy(const void* src, void* dst, uint32 size)
|
||||
#endif
|
||||
}
|
||||
|
||||
Stream::Stream(const uint8* data, int32 size) : data(data), size(size), pos(0)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
const void* Stream::getPtr()
|
||||
{
|
||||
return data + pos;
|
||||
}
|
||||
|
||||
uint8 Stream::read8u()
|
||||
{
|
||||
return data[pos++];
|
||||
}
|
||||
|
||||
uint16 Stream::read16u()
|
||||
{
|
||||
uint32 a = data[pos++];
|
||||
uint32 b = data[pos++];
|
||||
|
||||
if (bigEndian) {
|
||||
return b | (a << 8);
|
||||
} else {
|
||||
return a | (b << 8);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Stream::read32u()
|
||||
{
|
||||
uint32 a = data[pos++];
|
||||
uint32 b = data[pos++];
|
||||
uint32 c = data[pos++];
|
||||
uint32 d = data[pos++];
|
||||
|
||||
if (bigEndian) {
|
||||
return d | (c << 8) | (b << 16) | (a << 24);
|
||||
} else {
|
||||
return a | (b << 8) | (c << 16) | (d << 24);
|
||||
}
|
||||
}
|
||||
|
||||
int8 Stream::read8s()
|
||||
{
|
||||
return (int8)read8u();
|
||||
}
|
||||
|
||||
int16 Stream::read16s()
|
||||
{
|
||||
return (int16)read16u();
|
||||
}
|
||||
|
||||
int32 Stream::read32s()
|
||||
{
|
||||
return (int32)read32u();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2928,24 +2928,4 @@ void updateFading(int32 frames);
|
||||
void dmaFill(void* dst, uint8 value, uint32 count);
|
||||
void dmaCopy(const void* src, void* dst, uint32 size);
|
||||
|
||||
struct Stream
|
||||
{
|
||||
const uint8* data;
|
||||
int32 size;
|
||||
int32 pos;
|
||||
bool bigEndian;
|
||||
|
||||
Stream(const uint8* data, int32 size);
|
||||
|
||||
const void* getPtr();
|
||||
|
||||
uint8 read8u();
|
||||
uint16 read16u();
|
||||
uint32 read32u();
|
||||
|
||||
int8 read8s();
|
||||
int16 read16s();
|
||||
int32 read32s();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -2,94 +2,269 @@
|
||||
#define H_PHD
|
||||
|
||||
#include "common.h"
|
||||
#include "stream.h"
|
||||
|
||||
struct PHD
|
||||
bool read_PHD(Stream &f)
|
||||
{
|
||||
struct RoomVertex
|
||||
{
|
||||
int16 x, y, z;
|
||||
uint16 lighting;
|
||||
};
|
||||
uint8* ptr = gLevelData;
|
||||
|
||||
struct RoomQuad
|
||||
{
|
||||
uint16 indices[4];
|
||||
uint16 flags;
|
||||
};
|
||||
|
||||
struct RoomTriangle
|
||||
{
|
||||
uint16 indices[3];
|
||||
uint16 flags;
|
||||
};
|
||||
|
||||
struct RoomSprite
|
||||
{
|
||||
uint16 index;
|
||||
uint16 texture;
|
||||
};
|
||||
|
||||
struct RoomPortal
|
||||
{
|
||||
int16 roomIndex;
|
||||
vec3s normal;
|
||||
vec3s vertices[4];
|
||||
};
|
||||
};
|
||||
|
||||
RoomInfo roomsInfo_phd[MAX_ROOMS];
|
||||
|
||||
bool read_PHD(const uint8* data)
|
||||
{
|
||||
/* TODO
|
||||
Stream stream(data, 0);
|
||||
|
||||
uint32 magic = stream.read32u();
|
||||
uint32 magic = f.read32u();
|
||||
if (magic != 0x00000020)
|
||||
{
|
||||
LOG("Unsupported level format\n");
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
|
||||
level.version = VER_TR1_PC;
|
||||
|
||||
level.tilesCount = stream.read32u();
|
||||
level.tiles = (uint8*)stream.getPtr();
|
||||
stream.pos += 4;
|
||||
level.tilesCount = f.read32u();
|
||||
level.tiles = (uint8*)f.getPtr();
|
||||
|
||||
level.roomsCount = stream.read16u();
|
||||
level.roomsInfo = phd_roomsInfo;
|
||||
f.seek(level.tilesCount * 256 * 256 + 4);
|
||||
|
||||
level.roomsCount = f.read16u();
|
||||
level.roomsInfo = (RoomInfo*)ptr;
|
||||
ptr += level.roomsCount * sizeof(RoomInfo);
|
||||
|
||||
for (uint32 i = 0; i < level.roomsCount; i++)
|
||||
{
|
||||
RoomInfo* info = phd_roomsInfo + i;
|
||||
RoomInfo* info = (RoomInfo*)level.roomsInfo + i;
|
||||
|
||||
info->x = stream.read32s();
|
||||
info->z = stream.read32s();
|
||||
info->yBottom = stream.read32s();
|
||||
info->yTop = stream.read32s();
|
||||
info->x = f.read32s() >> 8;
|
||||
info->z = f.read32s() >> 8;
|
||||
f.seek(4 + 4 + 4);
|
||||
|
||||
info->verticesCount = stream.read16u();
|
||||
info->data.vertices = (RoomVertex*)stream.getPtr();
|
||||
stream.pos += sizeof(PHD::RoomVertex) * info->verticesCount;
|
||||
info->verticesCount = f.read16u();
|
||||
info->data.vertices = (RoomVertex*)ptr;
|
||||
|
||||
info->quadsCount = stream.read16u();
|
||||
info->data.quads = (RoomQuad*)stream.getPtr();
|
||||
stream.pos += sizeof(PHD::RoomQuad) * info->quadsCount;
|
||||
int32 vertDataPos = f.getPos();
|
||||
|
||||
info->trianglesCount = stream.read16u();
|
||||
info->data.triangles = (RoomTriangle*)stream.getPtr();
|
||||
stream.pos += sizeof(PHD::RoomTriangle) * info->trianglesCount;
|
||||
int32 yb = -32768;
|
||||
int32 yt = 32767;
|
||||
|
||||
info->spritesCount = stream.read16u();
|
||||
info->data.sprites = (RoomSprite*)stream.getPtr();
|
||||
stream.pos += sizeof(PHD::RoomSprite) * info->spritesCount;
|
||||
f.seek(2); // skip x
|
||||
for (uint32 j = 0; j < info->verticesCount; j++)
|
||||
{
|
||||
int32 y = f.read16s(); // read y
|
||||
|
||||
info->portalsCount = stream.read16u();
|
||||
info->data.portals = (RoomPortal*)stream.getPtr();
|
||||
stream.pos += sizeof(PHD::RoomPortal) * info->portalsCount;
|
||||
if (y < yt) {
|
||||
yt = y;
|
||||
}
|
||||
if (y > yb) {
|
||||
yb = y;
|
||||
}
|
||||
|
||||
f.seek(2 + 2 + 2); // skip z, g, x
|
||||
}
|
||||
|
||||
info->yBottom = yb;
|
||||
info->yTop = yt;
|
||||
|
||||
f.setPos(vertDataPos);
|
||||
|
||||
for (uint32 j = 0; j < info->verticesCount; j++)
|
||||
{
|
||||
RoomVertex *v = (RoomVertex*)ADDR_ALIGN4(ptr);
|
||||
ptr += sizeof(RoomVertex);
|
||||
|
||||
v->x = f.read16s() >> 8;
|
||||
v->y = (f.read16s() - yt) >> 8;
|
||||
v->z = f.read16s() >> 8;
|
||||
v->g = f.read16u() >> 3;
|
||||
}
|
||||
|
||||
info->quadsCount = f.read16u();
|
||||
info->data.quads = (RoomQuad*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < info->quadsCount; j++)
|
||||
{
|
||||
RoomQuad *q = (RoomQuad*)ptr;
|
||||
ptr += sizeof(RoomQuad);
|
||||
|
||||
q->indices[0] = f.read16u();
|
||||
q->indices[1] = f.read16u();
|
||||
q->indices[2] = f.read16u();
|
||||
q->indices[3] = f.read16u();
|
||||
q->flags = f.read16u();
|
||||
}
|
||||
|
||||
info->trianglesCount = f.read16u();
|
||||
info->data.triangles = (RoomTriangle*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < info->trianglesCount; j++)
|
||||
{
|
||||
RoomTriangle *t = (RoomTriangle*)ptr;
|
||||
ptr += sizeof(RoomTriangle);
|
||||
|
||||
t->indices[0] = f.read16u();
|
||||
t->indices[1] = f.read16u();
|
||||
t->indices[2] = f.read16u();
|
||||
t->flags = f.read16u();
|
||||
}
|
||||
|
||||
info->spritesCount = f.read16u();
|
||||
info->data.sprites = (RoomSprite*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < info->spritesCount; j++)
|
||||
{
|
||||
RoomSprite *s = (RoomSprite*)ptr;
|
||||
ptr += sizeof(RoomSprite);
|
||||
|
||||
int32 idx = f.read16u();
|
||||
s->index = f.read16u() * 0xFF;
|
||||
|
||||
int32 pos = f.getPos();
|
||||
f.setPos(vertDataPos + 8 * idx);
|
||||
|
||||
s->pos.x = f.read16u();
|
||||
s->pos.y = f.read16u();
|
||||
s->pos.z = f.read16u();
|
||||
s->g = f.read16u() >> 3;
|
||||
|
||||
f.setPos(pos);
|
||||
}
|
||||
|
||||
info->portalsCount = uint8(f.read16u());
|
||||
info->data.portals = (Portal*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < info->portalsCount; j++)
|
||||
{
|
||||
Portal *p = (Portal*)ptr;
|
||||
ptr += sizeof(Portal);
|
||||
|
||||
p->roomIndex = f.read16s();
|
||||
p->n.x = f.read16s();
|
||||
p->n.y = f.read16s();
|
||||
p->n.z = f.read16s();
|
||||
for (int32 k = 0; k < 4; k++)
|
||||
{
|
||||
p->v[k].x = f.read16s();
|
||||
p->v[k].y = f.read16s();
|
||||
p->v[k].z = f.read16s();
|
||||
}
|
||||
}
|
||||
|
||||
info->zSectors = uint8(f.read16u());
|
||||
info->xSectors = uint8(f.read16u());
|
||||
info->data.sectors = (Sector*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < uint32(info->zSectors) * uint32(info->xSectors); j++)
|
||||
{
|
||||
Sector *s = (Sector*)ptr;
|
||||
ptr += sizeof(Sector);
|
||||
|
||||
s->floorIndex = f.read16u();
|
||||
s->boxIndex = f.read16u();
|
||||
s->roomBelow = f.read8u();
|
||||
s->floor = f.read8s();
|
||||
s->roomAbove = f.read8u();
|
||||
s->ceiling = f.read8s();
|
||||
}
|
||||
|
||||
info->ambient = f.read16u() >> 5; // TODO 3?
|
||||
|
||||
info->lightsCount = uint8(f.read16u());
|
||||
info->data.lights = (Light*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < info->lightsCount; j++)
|
||||
{
|
||||
Light *l = (Light*)ptr;
|
||||
ptr += sizeof(Light);
|
||||
|
||||
l->pos.x = f.read32s() - (info->x << 8);
|
||||
l->pos.y = f.read32s();
|
||||
l->pos.z = f.read32s() - (info->z << 8);
|
||||
l->intensity = f.read16s() >> 5; // TODO 3?
|
||||
l->radius = f.read32s() >> 8;
|
||||
}
|
||||
|
||||
info->meshesCount = uint8(f.read16u());
|
||||
info->data.meshes = (RoomMesh*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 j = 0; j < info->meshesCount; j++)
|
||||
{
|
||||
RoomMesh *m = (RoomMesh*)ptr;
|
||||
ptr += sizeof(RoomMesh);
|
||||
|
||||
vec3s pos;
|
||||
uint8 intensity;
|
||||
uint8 flags;
|
||||
|
||||
pos.x = f.read32s() - (info->x << 8);
|
||||
pos.y = f.read32s();
|
||||
pos.z = f.read32s() - (info->z << 8);
|
||||
flags = ((f.read16s() / 0x4000 + 2) << 6);
|
||||
intensity = f.read16u() >> 5; // TODO 3?
|
||||
flags |= f.read16u();
|
||||
|
||||
m->xy = (pos.x << 16) | uint16(pos.y);
|
||||
m->zf = (pos.z << 16) | (intensity << 8) | flags;
|
||||
}
|
||||
|
||||
info->alternateRoom = uint8(f.read16s());
|
||||
uint16 flags = f.read16u();
|
||||
|
||||
info->flags = 0;
|
||||
if (flags & 1) info->flags |= 1; // TODO 1?
|
||||
if (flags & 256) info->flags |= 2; // TODO 2?
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
|
||||
{ // floors data
|
||||
uint32 floorsCount = f.read32u();
|
||||
level.floors = (FloorData*)ADDR_ALIGN4(ptr);
|
||||
FloorData *fd = (FloorData*)ptr;
|
||||
for (uint32 i = 0; i < floorsCount; i++)
|
||||
{
|
||||
fd[i] = f.read16u();
|
||||
}
|
||||
ptr += sizeof(FloorData) * floorsCount;
|
||||
}
|
||||
|
||||
{ // mesh data
|
||||
uint32 meshDataSize = f.read32u();
|
||||
level.meshes = (const Mesh**)ADDR_ALIGN4(ptr);
|
||||
|
||||
int32 meshDataPos = f.getPos();
|
||||
f.seek(meshDataSize * sizeof(uint16));
|
||||
|
||||
level.meshesCount = f.read32u();
|
||||
f.seek(level.meshesCount * sizeof(uint32));
|
||||
|
||||
// TODO
|
||||
ptr += meshDataSize * sizeof(uint32);
|
||||
}
|
||||
|
||||
{ // anims
|
||||
uint32 animsCount = f.read32u();
|
||||
level.anims = (Anim*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 i = 0; i < animsCount; i++)
|
||||
{
|
||||
Anim* anim = (Anim*)ptr;
|
||||
ptr += sizeof(Anim);
|
||||
|
||||
anim->frameOffset = f.read32u();
|
||||
anim->frameRate = f.read8u();
|
||||
anim->frameSize = f.read8u();
|
||||
anim->state = f.read16u();
|
||||
anim->speed = f.read32u();
|
||||
anim->accel = f.read32u();
|
||||
anim->frameBegin = f.read16u();
|
||||
anim->frameEnd = f.read16u();
|
||||
anim->nextAnimIndex = f.read16u();
|
||||
anim->nextFrameIndex = f.read16u();
|
||||
anim->statesCount = f.read16u();
|
||||
anim->statesStart = f.read16u();
|
||||
anim->commandsCount = f.read16u();
|
||||
anim->commandsStart = f.read16u();
|
||||
}
|
||||
}
|
||||
|
||||
{ // states
|
||||
uint32 animStatesCount = f.read32u();
|
||||
level.animStates = (AnimState*)ADDR_ALIGN4(ptr);
|
||||
for (uint32 i = 0; i < animStatesCount; i++)
|
||||
{
|
||||
AnimState* animState = (AnimState*)ptr;
|
||||
ptr += sizeof(AnimState);
|
||||
|
||||
animState->state = uint8(f.read16u());
|
||||
animState->rangesCount = uint8(f.read16u());
|
||||
animState->rangesStart = f.read16u();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@@ -2,9 +2,12 @@
|
||||
#define H_PKD
|
||||
|
||||
#include "common.h"
|
||||
#include "stream.h"
|
||||
|
||||
bool read_PKD(const uint8* data)
|
||||
bool read_PKD(Stream &f)
|
||||
{
|
||||
const uint8* data = f.getPtr();
|
||||
|
||||
memcpy(&level, data, sizeof(level));
|
||||
|
||||
{ // fix level data offsets
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define H_LEVEL
|
||||
|
||||
#include "common.h"
|
||||
#include "stream.h"
|
||||
|
||||
Level level;
|
||||
|
||||
@@ -58,18 +59,24 @@ void readLevel(const uint8* data)
|
||||
|
||||
gAnimTexFrame = 0;
|
||||
|
||||
Stream f(data, 0);
|
||||
|
||||
#ifdef CPU_BIG_ENDIAN
|
||||
f.bigEndian = true;
|
||||
#endif
|
||||
|
||||
#if (USE_FMT & LVL_FMT_PKD)
|
||||
if (read_PKD(data))
|
||||
if (read_PKD(f))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if (USE_FMT & LVL_FMT_PHD)
|
||||
if (read_PHD(data))
|
||||
if (read_PHD(f))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if (USE_FMT & LVL_FMT_PSX)
|
||||
if (read_PSX(data))
|
||||
if (read_PSX(f))
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
89
src/fixed/stream.h
Normal file
89
src/fixed/stream.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef H_STREAM
|
||||
#define H_STREAM
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct Stream
|
||||
{
|
||||
const uint8* data;
|
||||
int32 size;
|
||||
int32 pos;
|
||||
bool bigEndian;
|
||||
|
||||
Stream(const uint8* data, int32 size) : data(data), size(size), pos(0), bigEndian(false)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
const uint8* getPtr()
|
||||
{
|
||||
return data + pos;
|
||||
}
|
||||
|
||||
int32 getPos()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
void setPos(int32 newPos)
|
||||
{
|
||||
pos = newPos;
|
||||
}
|
||||
|
||||
void seek(int32 offset)
|
||||
{
|
||||
pos += offset;
|
||||
}
|
||||
|
||||
X_INLINE uint8 read8u()
|
||||
{
|
||||
return data[pos++];
|
||||
}
|
||||
|
||||
X_INLINE int8 read8s()
|
||||
{
|
||||
return (int8)read8u();
|
||||
}
|
||||
|
||||
uint16 read16u()
|
||||
{
|
||||
const uint8* ptr = data + pos;
|
||||
pos += 2;
|
||||
|
||||
uint16 n;
|
||||
if (intptr_t(ptr) & 1) {
|
||||
n = ptr[0] | (ptr[1] << 8);
|
||||
} else {
|
||||
n = *(uint16*)ptr;
|
||||
}
|
||||
|
||||
return bigEndian ? swap16(n) : n;
|
||||
}
|
||||
|
||||
X_INLINE int16 read16s()
|
||||
{
|
||||
return (int16)read16u();
|
||||
}
|
||||
|
||||
uint32 read32u()
|
||||
{
|
||||
const uint8* ptr = data + pos;
|
||||
pos += 4;
|
||||
|
||||
uint32 n;
|
||||
if (intptr_t(ptr) & 3) {
|
||||
n = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
|
||||
} else {
|
||||
n = *(uint32*)ptr;
|
||||
}
|
||||
|
||||
return bigEndian ? swap32(n) : n;
|
||||
}
|
||||
|
||||
X_INLINE int32 read32s()
|
||||
{
|
||||
return (int32)read32u();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user