22 #include <glm/gtc/matrix_transform.hpp>
70 for (
int i = 0; i < 256; i++) {
76 glm::vec4 c(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
87 for (
unsigned int i = 0; i < numTextures; i++) {
88 std::array<uint8_t, 256 * 256 * 2> arr;
94 unsigned char* img =
argb16to32(&arr[0], 256, 256);
110 for (
unsigned int o = 0; o < numObjectTextures; o++) {
134 for (
int i = 0; i < 4; i++) {
140 assert((xCoordinate == 1) || (xCoordinate == 255) || (xCoordinate == 0));
141 assert((yCoordinate == 1) || (yCoordinate == 255) || (yCoordinate == 0));
149 if (numObjectTextures > 0)
158 std::vector<uint16_t> animatedTextures;
159 for (
unsigned int a = 0; a < numWords; a++) {
164 for (
unsigned int a = 0; a < numAnimatedTextures; a++) {
165 int count = animatedTextures.at(pos) + 1;
166 if ((pos + count) >= numWords) {
168 << pos + count <<
" >= " << numWords <<
")!" <<
Log::endl;
172 for (
int i = 0; i < count; i++) {
179 if ((numAnimatedTextures > 0) || (numWords > 0))
180 Log::get(
LOG_INFO) <<
"LoaderTR2: Found " << numAnimatedTextures <<
" Animated Textures!" <<
197 for (
unsigned int l = 0; l < numLights; l++) {
215 for (
unsigned int s = 0; s < numStaticMeshes; s++) {
233 staticModels.push_back(
new StaticModel(glm::vec3(x, y, z),
234 glm::radians((rotation >> 14) * 90.0f),
244 if (flags & 0x0001) {
259 std::vector<IndexedRectangle>& triangles,
260 uint16_t& numRectangles, uint16_t& numTriangles) {
262 for (
unsigned int r = 0; r < numRectangles; r++) {
272 rectangles.emplace_back(texture, vertex1, vertex2, vertex3, vertex4);
276 for (
unsigned int t = 0; t < numTriangles; t++) {
285 triangles.emplace_back(texture, vertex1, vertex2, vertex3);
291 for (
unsigned int i = 0; i < numRooms; i++) {
298 glm::vec3 pos(xOffset, 0.0f, zOffset);
303 glm::vec3 bbox[2] = {
304 glm::vec3(0.0f, 0.0f, 0.0f),
305 glm::vec3(0.0f, 0.0f, 0.0f)
309 std::vector<RoomVertexTR2> vertices;
310 for (
unsigned int v = 0; v < numVertices; v++) {
313 vertices.push_back(vert);
317 for (
int i = 0; i < 2; i++) {
323 if (vert.
x < bbox[0].x)
325 if (vert.
x > bbox[1].x)
327 if (vert.
y < bbox[0].y)
329 if (vert.
y > bbox[1].y)
331 if (vert.
z < bbox[0].z)
333 if (vert.
z > bbox[1].z)
341 std::vector<IndexedRectangle> rectangles;
342 std::vector<IndexedRectangle> triangles;
343 uint16_t numRectangles, numTriangles;
344 loadRoomMesh(rectangles, triangles, numRectangles, numTriangles);
347 std::vector<RoomSprite*> roomSprites;
348 for (
unsigned int s = 0; s < numSprites; s++) {
352 auto& v = vertices.at(vertex);
353 roomSprites.push_back(
new RoomSprite(glm::vec3(v.x, v.y, v.z) + pos, sprite));
357 std::vector<Portal*> portals;
358 for (
unsigned int p = 0; p < numPortals; p++) {
386 portals.push_back(
new Portal(adjoiningRoom,
387 glm::vec3(xNormal, yNormal, zNormal),
388 glm::vec3(xCorner1, yCorner1, zCorner1),
389 glm::vec3(xCorner2, yCorner2, zCorner2),
390 glm::vec3(xCorner3, yCorner3, zCorner3),
391 glm::vec3(xCorner4, yCorner4, zCorner4)));
396 for (
unsigned int s = 0; s < (numZSectors * numXSectors); s++) {
418 if ((((uint8_t)floor) == 0x81) || (((uint8_t)ceiling) == 0x81)) {
428 std::vector<StaticModel*> staticModels;
431 int16_t alternateRoom = -1;
432 unsigned int roomFlags = 0;
437 Room* room =
new Room(pos, boundingbox, mesh, roomFlags, alternateRoom,
438 numXSectors, numZSectors, i);
440 for (
auto p : portals)
443 for (
auto m : staticModels)
446 for (
auto s : roomSprites)
452 if ((numPortals == 0) && (numVertices == 0)
453 && (numRectangles == 0) && (numTriangles == 0))
454 Log::get(
LOG_DEBUG) <<
"LoaderTR2: Room " << i <<
" seems invalid: " << numPortals <<
"p "
455 << numRectangles <<
"r " << numTriangles <<
"t " << numVertices
467 for (
unsigned int f = 0; f < numFloorData; f++) {
473 if (numFloorData > 0)
474 Log::get(
LOG_INFO) <<
"LoaderTR2: Found " << numFloorData <<
" words FloorData, unimplemented!" <<
482 for (
unsigned int s = 0; s < numSpriteTextures; s++) {
500 for (
unsigned int s = 0; s < numSpriteSequences; s++) {
513 if ((numSpriteTextures > 0) || (numSpriteSequences > 0))
514 Log::get(
LOG_INFO) <<
"LoaderTR2: Found " << numSpriteTextures <<
" Sprites in " <<
515 numSpriteSequences <<
524 return (index & 0xFF00) >> 8;
533 std::vector<uint16_t> buffer;
534 for (
unsigned int i = 0; i < numMeshData; i++) {
539 for (
unsigned int i = 0; i < numMeshPointers; i++) {
542 if (numMeshData < (meshPointer / 2)) {
544 << (meshPointer / 2) <<
" > " << numMeshData <<
Log::endl;
548 char* tmpPtr =
reinterpret_cast<char*
>(&buffer[meshPointer / 2]);
549 BinaryMemory mem(tmpPtr, (numMeshData * 2) - meshPointer);
551 int16_t mx = mem.
read16();
552 int16_t my = mem.
read16();
553 int16_t mz = mem.
read16();
554 int32_t collisionSize = mem.
read32();
557 uint16_t numVertices = mem.
readU16();
558 std::vector<glm::vec3> vertices;
559 for (
int v = 0; v < numVertices; v++) {
563 vertices.emplace_back(x, y, z);
566 int16_t numNormals = mem.
read16();
567 if (numNormals > 0) {
573 for (
int n = 0; n < numNormals; n++) {
580 }
else if (numNormals < 0) {
583 for (
int l = 0; l < (numNormals * -1); l++) {
584 int16_t light = mem.
read16();
589 int16_t numTexturedRectangles = mem.
read16();
590 std::vector<IndexedRectangle> texturedRectangles;
591 for (
int r = 0; r < numTexturedRectangles; r++) {
592 uint16_t vertex1 = mem.
readU16();
593 uint16_t vertex2 = mem.
readU16();
594 uint16_t vertex3 = mem.
readU16();
595 uint16_t vertex4 = mem.
readU16();
596 uint16_t texture = mem.
readU16();
598 texturedRectangles.emplace_back(texture, vertex1, vertex2, vertex3, vertex4);
601 int16_t numTexturedTriangles = mem.
read16();
602 std::vector<IndexedRectangle> texturedTriangles;
603 for (
int t = 0; t < numTexturedTriangles; t++) {
604 uint16_t vertex1 = mem.
readU16();
605 uint16_t vertex2 = mem.
readU16();
606 uint16_t vertex3 = mem.
readU16();
607 uint16_t texture = mem.
readU16();
609 texturedTriangles.emplace_back(texture, vertex1, vertex2, vertex3);
612 int16_t numColoredRectangles = mem.
read16();
613 std::vector<IndexedColoredRectangle> coloredRectangles;
614 for (
int r = 0; r < numColoredRectangles; r++) {
615 uint16_t vertex1 = mem.
readU16();
616 uint16_t vertex2 = mem.
readU16();
617 uint16_t vertex3 = mem.
readU16();
618 uint16_t vertex4 = mem.
readU16();
619 uint16_t texture = mem.
readU16();
622 coloredRectangles.emplace_back(index, vertex1, vertex2, vertex3, vertex4);
625 int16_t numColoredTriangles = mem.
read16();
626 std::vector<IndexedColoredRectangle> coloredTriangles;
627 for (
int t = 0; t < numColoredTriangles; t++) {
628 uint16_t vertex1 = mem.
readU16();
629 uint16_t vertex2 = mem.
readU16();
630 uint16_t vertex3 = mem.
readU16();
631 uint16_t texture = mem.
readU16();
634 coloredTriangles.emplace_back(index, vertex1, vertex2, vertex3);
637 Mesh* mesh =
new Mesh(vertices, texturedRectangles, texturedTriangles,
638 coloredRectangles, coloredTriangles);
642 if (numMeshPointers > 0)
650 for (
unsigned int s = 0; s < numStaticMeshes; s++) {
681 if (numStaticMeshes > 0)
690 uint32_t frameOffset;
691 uint8_t frameRate, frameSize;
692 uint16_t stateID, frameStart, frameEnd, nextAnimation;
693 uint16_t nextFrame, numStateChanges, stateChangeOffset;
694 uint16_t numAnimCommands, animCommandOffset;
696 Animation_t(uint32_t fo, uint8_t fr, uint8_t fs, uint16_t si,
697 uint16_t fst, uint16_t fe, uint16_t na, uint16_t nf,
698 uint16_t ns, uint16_t so, uint16_t nac, uint16_t ao)
699 : frameOffset(fo), frameRate(fr), frameSize(fs),
700 stateID(si), frameStart(fst), frameEnd(fe), nextAnimation(na),
701 nextFrame(nf), numStateChanges(ns), stateChangeOffset(so),
702 numAnimCommands(nac), animCommandOffset(ao) { }
705 struct StateChange_t {
706 uint16_t stateID, numAnimDispatches, animDispatchOffset;
708 StateChange_t(uint16_t s, uint16_t n, uint16_t a)
709 : stateID(s), numAnimDispatches(n), animDispatchOffset(a) { }
712 struct AnimDispatch_t {
713 int16_t low, high, nextAnimation, nextFrame;
715 AnimDispatch_t(int16_t l, int16_t h, int16_t na, int16_t nf)
716 : low(l), high(h), nextAnimation(na), nextFrame(nf) { }
720 uint16_t startingMesh, uint32_t meshTree,
721 uint32_t numMeshTrees, std::vector<int32_t> meshTrees) {
722 for (
int i = 0; i < numMeshes; i++) {
723 int mesh = startingMesh + i;
724 glm::vec3 offset(0.0f, 0.0f, 0.0f);
725 float rotation[3] = { 0.0f, 0.0f, 0.0f };
726 char flag = (i == 0) ? 2 : 0;
730 char* tmp =
reinterpret_cast<char*
>(&meshTrees[0]) + meshTree;
732 BinaryMemory tree(tmp, (numMeshTrees * 4) - meshTree - ((i - 1) * 16));
742 if ((a & 0x8000) && (a & 0x4000))
746 rotation[index] = ((float)(a & 0x03FF)) * 360.0f / 1024.0f;
750 rotation[0] = (a & 0x3FF0) >> 4;
751 rotation[1] = ((a & 0x000F) << 6) | ((b & 0xFC00) >> 10);
752 rotation[2] = b & 0x03FF;
753 for (
int i = 0; i < 3; i++)
754 rotation[i] = rotation[i] * 360.0f / 1024.0f;
758 glm::vec3 rot(rotation[0], rotation[1], rotation[2]);
765 uint16_t startingMesh, uint32_t meshTree,
766 uint32_t numMeshTrees, std::vector<int32_t> meshTrees) {
767 int16_t bb1x = frame.
read16();
768 int16_t bb1y = frame.
read16();
769 int16_t bb1z = frame.
read16();
770 int16_t bb2x = frame.
read16();
771 int16_t bb2y = frame.
read16();
772 int16_t bb2z = frame.
read16();
780 loadAngleSet(bf, frame, numMeshes, startingMesh, meshTree, numMeshTrees, meshTrees);
787 std::vector<Animation_t> animations;
788 for (
unsigned int a = 0; a < numAnimations; a++) {
813 animations.emplace_back(frameOffset, frameRate, frameSize,
814 stateID, frameStart, frameEnd, nextAnimation, nextFrame, numStateChanges,
815 stateChangeOffset, numAnimCommands, animCommandOffset);
818 if (numAnimations > 0)
824 std::vector<StateChange_t> stateChanges;
825 for (
unsigned int s = 0; s < numStateChanges; s++) {
830 stateChanges.emplace_back(stateID, numAnimDispatches, animDispatchOffset);
833 if (numStateChanges > 0)
839 std::vector<AnimDispatch_t> animDispatches;
840 for (
unsigned int a = 0; a < numAnimDispatches; a++) {
846 animDispatches.emplace_back(low, high, nextAnimation, nextFrame);
849 if (numAnimDispatches > 0)
850 Log::get(
LOG_INFO) <<
"LoaderTR2: Found " << numAnimDispatches <<
" AnimationDispatches!" <<
856 std::vector<int16_t> animCommands;
857 for (
unsigned int a = 0; a < numAnimCommands; a++) {
864 if (numAnimCommands > 0)
874 std::vector<int32_t> meshTrees;
875 for (
unsigned int m = 0; m < numMeshTrees; m++) {
891 if (numMeshTrees > 0)
897 std::vector<uint16_t> frames;
898 for (
unsigned int f = 0; f < numFrames; f++) {
918 for (
unsigned int m = 0; m < numMoveables; m++) {
935 char* tmp =
reinterpret_cast<char*
>(&frames[0]) + frameOffset;
938 if (((numFrames * 2) - frameOffset) <= 0)
941 BoneFrame* bf =
loadFrame(frame, numMeshes, startingMesh, meshTree, numMeshTrees, meshTrees);
970 if (numMoveables > 0)
978 for (
unsigned int i = 0; i < numItems; i++) {
996 static_cast<float>(x),
997 static_cast<float>(y),
998 static_cast<float>(z)
1003 glm::radians(((angle >> 14) & 0x03) * 90.0f),
1010 if (objectID == 0) {
1023 for (
unsigned int b = 0; b < numBoxes; b++) {
1040 std::vector<std::vector<uint16_t>> overlaps;
1041 overlaps.emplace_back();
1042 unsigned int list = 0;
1043 for (
unsigned int o = 0; o < numOverlaps; o++) {
1048 overlaps.at(list).push_back(e);
1050 overlaps.emplace_back();
1057 for (
unsigned int z = 0; z < numBoxes; z++) {
1075 if ((numBoxes > 0) || (numOverlaps > 0))
1077 <<
", " << numOverlaps <<
", " << list <<
"), unimplemented!" <<
Log::endl;
1086 for (
unsigned int s = 0; s < numSoundSources; s++) {
1101 if (numSoundSources > 0)
1108 for (
int i = 0; i < 370; i++) {
1115 for (
unsigned int s = 0; s < numSoundDetails; s++) {
1130 if (numSoundDetails > 0)
1138 for (
unsigned int i = 0; i < numSampleIndices; i++) {
1142 if (numSampleIndices > 0)
1149 size_t dir = f.find_last_of(
"/\\");
1150 if (dir != std::string::npos) {
1151 f.replace(dir + 1, std::string::npos,
"MAIN.SFX");
1157 if (sfx.
open(f) != 0) {
1167 else if (riffCount == 0)
1175 while (!sfx.
eof()) {
1176 if ((count > 0) && (riffCount >= count))
1181 for (
int i = 0; i < 4; i++)
1182 test[i] = sfx.
read8();
1184 if (std::string(
"RIFF") != std::string(test)) {
1186 <<
", \"" << test <<
"\" != \"RIFF\")" <<
Log::endl;
1191 uint32_t riffSize = sfx.
readU32();
1193 unsigned char* buff =
new unsigned char[riffSize + 8];
1195 for (
int i = 0; i < (riffSize + 8); i++)
1211 for (
unsigned int c = 0; c < numCameras; c++) {
1228 for (
unsigned int c = 0; c < numCinematicFrames; c++) {
1241 if (numCinematicFrames > 0)
1243 <<
" CinematicFrames, unimplemented!" <<
Log::endl;
1248 for (
unsigned int d = 0; d < numDemoData; d++)
1252 if (numDemoData > 0)
1253 Log::get(
LOG_INFO) <<
"LoaderTR2: Found " << numDemoData <<
" bytes DemoData, unimplemented!" <<
void addSkeletalModel(SkeletalModel *model)
virtual void loadPalette()
void addModel(StaticModel *s)
virtual void loadAngleSet(BoneFrame *bf, BinaryReader &frame, uint16_t numMeshes, uint16_t startingMesh, uint32_t meshTree, uint32_t numMeshTrees, std::vector< int32_t > meshTrees)
virtual void loadAnimatedTextures()
#define assertLessThanEqual(x, y)
void add(AnimationFrame *f)
static void addAnimatedTile(int index, int tile)
virtual void loadSoundSources()
static void addTile(TextureTile *t)
virtual void loadSoundMap()
virtual int getPaletteIndex(uint16_t index)
virtual int loadSoundFiles(BinaryReader &sfx, unsigned int count=0)
virtual void loadCinematicFrames()
virtual void seek(long long pos=0)
virtual void loadSampleIndices()
static LogLevel & get(int level)
virtual void loadTextiles()
virtual void loadMeshes()
virtual void loadStaticMeshes()
virtual BoneFrame * loadFrame(BinaryReader &frame, uint16_t numMeshes, uint16_t startingMesh, uint32_t meshTree, uint32_t numMeshTrees, std::vector< int32_t > meshTrees)
virtual void loadRoomVertex(RoomVertexTR2 &vert)
static int test(const char *name)
static void addSampleIndex(int index)
virtual void loadRoomLights()
static int loadBuffer(unsigned char *buffer, unsigned int length)
virtual void loadRoomMesh(std::vector< IndexedRectangle > &rectangles, std::vector< IndexedRectangle > &triangles, uint16_t &numRectangles, uint16_t &numTriangles)
static void addSoundSource(glm::vec3 p, int id, int flags)
virtual void loadSprites()
void addSprite(RoomSprite *s)
virtual void loadCameras()
void addSprite(Sprite *sprite)
virtual uint16_t readU16()
static void addSoundMapEntry(int id)
#define assertGreaterThanEqual(x, y)
virtual int load(std::string f)
virtual void loadRoomStaticMeshes(std::vector< StaticModel * > &staticModels)
virtual void loadRoomDataEnd(int16_t &alternateRoom, unsigned int &roomFlags)
virtual void loadTextures()
virtual void loadMoveables()
void addSpriteSequence(SpriteSequence *sprite)
virtual void loadSoundDetails()
virtual uint32_t readU32()
static void setLara(long lara)
void addPortal(Portal *p)
void add(TextureTileVertex t)
virtual void seek(long long pos=0)=0
virtual void loadDemoData()
virtual long long tell()=0
static void setPalette(int index, glm::vec4 color)
void addEntity(Entity *entity)
virtual void loadBoxesOverlapsZones()
#define assertLessThan(x, y)
virtual void loadFloorData()
static int loadBufferSlot(unsigned char *image=nullptr, unsigned int width=256, unsigned int height=256, ColorMode mode=ColorMode::RGBA, unsigned int bpp=32, TextureStorage s=TextureStorage::GAME, int slot=-1, bool filter=true)
Loads Buffer as texture.
unsigned char * argb16to32(unsigned char *image, unsigned int w, unsigned int h)
virtual void loadExternalSoundFile(std::string f)
int open(std::string f="")
void addStaticMesh(StaticMesh *model)
static void addSoundDetail(int sample, float volume)