1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-11 15:45:05 +02:00

move memory stream to stream.h, PHD loader (WIP)

This commit is contained in:
XProger
2022-04-30 04:06:49 +03:00
parent dba6a54739
commit 0e2c96be6b
6 changed files with 349 additions and 151 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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