/*! * \file include/TombRaider.h * \brief Loads maps, meshes, textures... * * \todo WARNING: No endian routines as of yet * \author Mongoose */ #ifndef _TOMBRAIDER_H_ #define _TOMBRAIDER_H_ #include #include #include "TombRaiderData.h" /*! * \brief Loads maps, meshes, textures... */ class TombRaider { public: /*! * \brief Constructs an object of TombRaider */ TombRaider(); /*! * \brief Deconstructs an object of TombRaider */ ~TombRaider(); //////////////////////////////////////// // Wash me -- not part of cleaned API // //////////////////////////////////////// int NumRooms(); int NumMoveables(); int NumTextures(); /*! * \brief Get number of _special_ textures/images * \returns number of special textures/images */ int NumSpecialTextures(); int NumAnimations(); unsigned int NumFrames(); int NumStaticMeshes(); int NumSpriteSequences(); int NumItems(); tr2_version_type Engine(); unsigned short* Frame(); tr2_animation_t* Animation(); tr2_item_t* Item(); tr2_box_t* Box(); tr2_mesh_t* Mesh(); /*! * \brief Get number of animations for a moveable * \param moveable_index valid moveable id * \returns number of animations for specified moveable */ int getNumAnimsForMoveable(int moveable_index); tr2_staticmesh_t* StaticMesh(); tr2_moveable_t* Moveable(); tr2_meshtree_t* MeshTree(); /*! * \brief Get the sprites * \returns the sprite array */ tr2_sprite_texture_t* Sprite(); tr2_sprite_sequence_t* SpriteSequence(); /*! * \brief Get copies of texture and it's bumpmap * \param texture valid textile index * \param image will be set to texture if found, or NULL * \param bumpmap will be set to bumpmap if found, or NULL */ void Texture(int texture, unsigned char** image, unsigned char** bumpmap); //unsigned int* Palette16(); //unsigned char* Palette8(); tr2_room_t* Room(); /*! * \brief Loads TombRaider 1-5 pak into memory * and does some processing. * \param filename points to valid TombRaider pak * \returns 0 on success, < 0 on error * \sa TombRaider::loadTR5() */ int Load(const char* filename); /*! * \brief Compute rotation angles from moveable animation data * \param frame moveable animation data * \param frame_offset moveable animation data * \param angle_offset moveable animation data * \param x will be set to computed angle * \param y will be set to computed angle * \param z will be set to computed angle */ void computeRotationAngles(unsigned short** frame, unsigned int* frame_offset, unsigned int* angle_offset, float* x, float* y, float* z); /*! * \brief Returns computed UV in u and v * \param st object texture vert, its coordinates are added to the pixels and divided by 255.0 * \param u will contain calculated x value * \param v will contain calculated y value */ void computeUV(tr2_object_texture_vert_t* st, float* u, float* v); void getColor(int index, float color[4]); tr2_version_type getEngine(); /*! * \brief Get the collision sphere for a mesh * \param meshIndex mesh index * \param center will be filled with center coordinates, not NULL * \param radius will be filled with radius, not NULL */ void getMeshCollisionInfo(unsigned int meshIndex, float center[3], float* radius); /*! * \brief Get SIGNED mesh count (TR encoded < 0 errors) * \returns signed mesh count */ int getMeshCount(); /*! * \brief This method is made to let you fill arrays or * create single faces. There may be an allocatin version that * passes back arrays later. * Returns Quads/Rects as 2 triangles, * because returning quads would be too trivial :) * \param meshIndex mesh index * \param faceIndex face index * \param index allocated RGBA * \param color allocated RGBA * \fixme This method interface may change later */ void getMeshColoredRectangle(unsigned int meshIndex, unsigned int faceIndex, int index[6], float color[4]); /*! * \brief This method is made to let you fill arrays or * create single faces. There may be an allocating version that * passes back arrays later. * \param meshIndex mesh index * \param faceIndex face index * \param index allocated RGBA * \param color allocated RGBA * \fixme This method interface may change later */ void getMeshColoredTriangle(unsigned int meshIndex, unsigned int faceIndex, int index[3], float color[4]); /*! * \brief This method is made to let you fill arrays or * create single faces. There may be an allocatin version that * passes back arrays later. * Returns Quads/Rects as 2 triangles, * because returning quads would be too trivial :) * \param meshIndex mesh index * \param faceIndex face index * \param index allocated * \param st allocated * \param texture allocated * \param transparency allocated * \fixme This method interface may change later */ void getMeshTexturedRectangle(unsigned int meshIndex, unsigned int faceIndex, int index[6], float st[12], int* texture, unsigned short* transparency); /*! * \brief This method is made to let you fill arrays or * create single faces. There may be an allocatin version that * passes back arrays later. * \param meshIndex mesh index * \param faceIndex face index * \param index allocated * \param st allocated * \param texture allocated * \param transparency allocated * \fixme This method interface may change later */ void getMeshTexturedTriangle(unsigned int meshIndex, unsigned int faceIndex, int index[3], float st[6], int* texture, unsigned short* transparency); /*! * \brief Get face counts for a given mesh. * * \todo This method interface may change later... * \param meshIndex mesh index * \returns number of textured triangles in mesh */ int getMeshTexturedTriangleCount(unsigned int meshIndex); /*! * \brief Get face counts for a given mesh. * \param meshIndex mesh index * \returns number of colored triangles in mesh */ int getMeshColoredTriangleCount(unsigned int meshIndex); /*! * \brief Get face counts for a given mesh. * \param meshIndex mesh index * \returns number of textured rectangles in mesh */ int getMeshTexturedRectangleCount(unsigned int meshIndex); /*! * \brief Get face counts for a given mesh. * \returns number if colored rectangles in mesh */ int getMeshColoredRectangleCount(unsigned int meshIndex); /*! * \brief Get vertex, normal and color arrays for a mesh * \param meshIndex mesh index * \param vertexCount will be set to length of vertex array * \param verts will be set to allocated vertex array (XYX) * \param normalCount will be set to length of normal array * \param norms will be set to allocated normal array (IJK) * \param colorCount will be set to length of color array * \param colors will be set to allocated color array (I) */ void getMeshVertexArrays(unsigned int meshIndex, unsigned int* vertexCount, float** verts, unsigned int* normalCount, float** norms, unsigned int* colorCount, float** colors); /*! * \brief Get a single collision box from room (unified) * \param roomIndex room index * \param index index of box in room * \param xyzA will contain first corner of box * \param xyzB will contain second corner of box * \param xyzC will contain third corner of box * \param xyzD will contain fourth corner of box * \returns 0 on success, < 0 on error */ int getRoomBox(unsigned int roomIndex, unsigned int index, float* xyzA, float* xyzB, float* xyzC, float* xyzD); /*! * \brief Get number of collision boxes in room (unified) * \param roomIndex room index * \returns number of collision boxes in room */ unsigned int getRoomBoxCount(unsigned int roomIndex); void getRoomInfo(unsigned int index, unsigned int* flags, float pos[3], float bboxMin[3], float bboxMax[3]); /*! * \brief Get a single light from a room (unified) * \param roomIndex valid room index * \param index valid light index in room * \param pos allocated, will contain position * \param color allocated, will contain color * \param dir allocated, will contain direction * \param attenuation will contain attenuation * \param cutoffAngle will contain cutoff angle * \param type will contain type * \param flags will contain flags * \returns 0 on success, < 0 on error */ int getRoomLight(unsigned int roomIndex, unsigned int index, float pos[4], float color[4], float dir[3], float* attenuation, float* cutoffAngle, unsigned int* type, unsigned int* flags); /*! * \brief Get number of lights in room (unified) * \param roomIndex room index * \returns number of lights in room */ unsigned int getRoomLightCount(unsigned int roomIndex); /*! * \brief Get a single model info from a room * \param roomIndex valid room index * \param index valid model index in room * \param modelIndex will contain starting mesh * \param pos will contain pos * \param yaw will contain yaw angle * \returns 0 on success, < 0 on error */ int getRoomModel(unsigned int roomIndex, unsigned int index, int* modelIndex, float pos[3], float* yaw); /*! * \brief Get number of room models in room (unified) * \param roomIndex room index * \returns number of room models in room */ unsigned int getRoomModelCount(unsigned int roomIndex); /*! * \brief Get a single portal from room (unified) * \param roomIndex valid room index * \param index valid portal index in room * \param adjoiningRoom will contain adjoining room index * \param normal allocated, will contain normal vector * \param vertices allocated, will contain vertices * \returns 0 on success, < 0 on error */ int getRoomPortal(unsigned int roomIndex, unsigned int index, int* adjoiningRoom, float normal[3], float vertices[12]); /*! * \brief Get number of portals from room (unified) * \param roomIndex room index * \returns number of portals from room */ unsigned int getRoomPortalCount(unsigned int roomIndex); /*! * \brief Get rectangle data with texCoords for non-matching * vertex/uv for each vertex in TombRaider room (unified) * \param roomIndex valid room index * \param rectangleIndex rectangle index in room * \param indices will contain indices * \param texCoords will contain texCoords * \param texture will contain texture * \param flags will contain flags */ void getRoomRectangle(unsigned int roomIndex, unsigned int rectangleIndex, unsigned int* indices, float* texCoords, int* texture, unsigned int* flags); /*! * \brief Get number of rectangles from room (unified) * \param roomIndex room index * \returns number of rectangles from room */ unsigned int getRoomRectangleCount(unsigned int roomIndex); /*! * \brief Get a single sector from room (unified) * \param roomIndex room index * \param index sector index * \param flags will contain flags * \param ceiling will contain ceiling * \param floor will contain floor * \param floorDataIndex will contain floor data index * \param boxIndex will contain boxIndex * \param roomBelow will contain roomBelow * \param roomAbove will contain roomAbove * \return 0 on success, < 0 on error */ int getRoomSector(unsigned int roomIndex, unsigned int index, unsigned int* flags, float* ceiling, float* floor, int* floorDataIndex, int* boxIndex, int* roomBelow, int* roomAbove); /*! * \brief Get number of sectors in room (unified) * \param roomIndex room index * \param zSectorsCount will contain width of sector list * \param xSectorsCount will contain height of sector list * \returns number of sectors in room */ unsigned int getRoomSectorCount(unsigned int roomIndex, unsigned int* zSectorsCount, unsigned int* xSectorsCount); void getRoomSprite(unsigned int roomIndex, unsigned int index, float scale, int* texture, float* pos, float* vertices, float* texcoords); /*! * \brief Get number of sprites in room (unified) * \param roomIndex room index * \returns number of sprites in room */ unsigned int getRoomSpriteCount(unsigned int roomIndex); /*! * \brief Gets triangle data with texCoords for non-matching * vertex/uv for each vertex in TombRaider room (unified) * \param roomIndex room index * \param triangleIndex triangle index * \param indices will contain indices * \param texCoords will contain texCoords * \param texture will contain texture * \param flags will contain flags */ void getRoomTriangle(unsigned int roomIndex, unsigned int triangleIndex, unsigned int* indices, float* texCoords, int* texture, unsigned int* flags); /*! * \brief Gets triangle data with texCoords for non-matching * vertex/uv for each vertex in TombRaider room. * * This is used with vertices, colors, etc. to do partial array * rendering, since the texcoords will never match vertives * (Tomb Raider is textile based). * \param index room index * \param textureOffset texture offset * \param count will contain count * \param indices will contain indices * \param texCoords will contain texCoords * \param textures will contain textures * \param flags will contain flags */ void getRoomTriangles(unsigned int index, int textureOffset, unsigned int* count, unsigned int** indices, float** texCoords, int** textures, unsigned int** flags); /*! * \brief Gets triangle data with duplicated vertex/color/normal * data for each face vertex to match the textile based texcoords. * * This uses more memory, but lets you do direct array rendering * with OpenGL, D3D, etc. * \param roomIndex room index * \param textureOffset texture offset * \param count will contain count * \param indices will contain indices * \param vertices will contain vertices * \param texCoords will contain texCoords * \param colors will contain colors * \param textures will contain textures * \param flags will contain flags */ void getRoomTriangles(unsigned int roomIndex, int textureOffset, unsigned int* count, unsigned int** indices, float** vertices, float** texCoords, float** colors, int** textures, unsigned int** flags); /*! * \brief Get number of triangles from room (unified) * \param roomIndex room index * \returns number of triangles from room */ unsigned int getRoomTriangleCount(unsigned int roomIndex); /*! * \brief Gets vertex position and color * \param roomIndex room index * \param vertexIndex vertex index * \param xyz will contain vertex position, has to be allocated * \param rgba will contain vertex color, has to be allocated */ void getRoomVertex(unsigned int roomIndex, unsigned int vertexIndex, float* xyz, float* rgba); /*! * \brief Get allocated vertex and color arrays and their element counts (unified) * \param roomIndex valid room index * \param vertexCount will contain vertex array length * \param vertices will contain vertex array * \param normalCount will contain normal array length * \param normals will contain normal array * \param colorCount will contain color array length * \param colors will contain color array */ void getRoomVertexArrays(unsigned int roomIndex, unsigned int* vertexCount, float** vertices, unsigned int* normalCount, float** normals, unsigned int* colorCount, float** colors); /*! * \brief Get number of lights in room (unified) * \param roomIndex room index * \returns number of lights in room */ unsigned int getRoomVertexCount(unsigned int roomIndex); /*! * \brief Get sky mesh ID * \returns moveable id of sky mesh or -1 if none */ int getSkyModelId(); /*! * \brief Get a copy of a sound sample and its byte size * \param index sound sample index * \param bytes will contain byte size of sound sample * \param data will contain sound sample */ void getSoundSample(unsigned int index, unsigned int* bytes, unsigned char** data); /*! * \brief Get number of loaded sound samples * \returns number of sound samples loaded */ unsigned int getSoundSamplesCount(); /*! * \brief Check if a mesh is valid * \param index mesh index (?) * \returns true if mesh is valid */ bool isMeshValid(int index); /*! * \brief Check if a room is valid (TRC support) * \param index room index * \returns true if room is valid */ bool isRoomValid(int index); /*! * \brief Load an external sound pak for TR2 and TR3 * \param filename pak to load * \returns < 0 on error */ int loadSFX(const char* filename); void reset(); private: void extractMeshes(unsigned char* mesh_data, unsigned int num_mesh_pointers, unsigned int* mesh_pointers); int Fread(void* buffer, size_t size, size_t count, FILE* f); /*! * \brief Get a copy of the sound samples * \param bytes will contain size of sound samples * \param data will contain sound samples themselves */ void getRiffData(unsigned int* bytes, unsigned char** data); /*! * \brief Get a copy of a TR4 sound sample * \param index sound sample index * \param bytes will contain length of sound sample * \param data will contain sound sample itself */ void getRiffDataTR4(unsigned int index, unsigned int* bytes, unsigned char** data); /*! * \brief Get an array of offsets for a contiguous RIFF data stream in chunks. * * Offsets will be allocated with enough space to hold expected * number of offsets. (Should be known number, otherwise not all RIFFs * will be parsed.) * \param riffData riff data * \param riffDataBytes length of riff data * \param offsets will contain offsets * \param numOffsets known number * \returns number of RIFFs found */ int getRiffOffsets(unsigned char* riffData, unsigned int riffDataBytes, unsigned int** offsets, unsigned int numOffsets); /*! * \brief Makes a 32bit RGBA image from a textile. * * This handles all selection and conversion, including * alpha layering flags, now. * \param texture valid index into textile list * \returns 32bit RGBA image or NULL on error */ unsigned char* getTexTile(int texture); /*! * \brief Loads a TR5 pak into memory. * \param f valid FILE * \returns 0 on success, < 0 on error */ int loadTR5(FILE* f); static void print(const char* methodName, const char* s, ...) __attribute__((format(printf, 2, 3))); void printDebug(const char* methodName, const char* s, ...) __attribute__((format(printf, 3, 4))); bool mDebug; //!< Debug output toggle unsigned int mPakVersion; //!< TombRaider pak file header version tr2_version_type mEngineVersion; //!< TombRaider engine version tr2_colour_t _palette8[256]; //!< 8-bit palette unsigned int _palette16[256]; //!< 16-bit palette unsigned int _num_textiles; //!< Total number of texture tiles unsigned short _num_room_textures; //!< Num textures only for room use? unsigned short _num_misc_textures; //!< Num of textures for misc use? unsigned short _num_bump_map_textures; //!< Num of textures that are bump map, texture pairs tr2_textile8_t* _textile8; //!< 8-bit (palettised) textiles tr2_textile16_t* _textile16; //!< 16-bit (ARGB) textiles tr2_textile32_t* _textile32; //!< 32-bit (BGRA) textiles unsigned int _num_tex_special; //!< Special textures and bump maps count unsigned char* _tex_special; //!< Special textures and bump maps unsigned int _unknown_t; //!< 32-bit unknown (always 0 in real TR2 levels) unsigned short _num_rooms; //!< Number of rooms in this level tr2_room_t* _rooms; //!< List of rooms (TR1,TR2,TR3,TR4) tr5_room_t* mRoomsTR5; //!< Rooms ( TR5 / TRC ) Only unsigned int _num_floor_data; //!< Num of words of floor data this level unsigned short* _floor_data; //!< Floor data int mMeshCount; //!< Number of meshes this level tr2_mesh_t* mMeshes; //!< list of meshes unsigned int _num_animations; //!< number of animations this level tr2_animation_t* _animations; //!< list of animations unsigned int _num_state_changes; //!< number of structures(?) this level tr2_state_change_t* _state_changes; //!< list of structures unsigned int _num_anim_dispatches; //!< number of ranges(?) this level tr2_anim_dispatch_t* _anim_dispatches; //!< list of ranges unsigned int _num_anim_commands; //!< number of Bone1s this level tr2_anim_command_t* _anim_commands; //!< list of Bone1s unsigned int _num_mesh_trees; //!< number of Bone2s this level tr2_meshtree_t* _mesh_trees; //!< list of Bone2s unsigned int _num_frames; //!< num of words of frame data this level unsigned short* _frames; //!< frame data unsigned int _num_moveables; //!< number of moveables this level tr2_moveable_t* _moveables; //!< list of moveables uint32_t numMoveablesTR5; tr5_moveable_t* moveablesTR5; uint32_t numAnimationsTR5; tr5_animation_t* animationsTR5; uint32_t numObjectTexturesTR5; tr5_object_texture_t* objectTexturesTR5; uint32_t numCinematicFramesTR5; tr5_cinematic_frame_t* cinematicFramesTR5; uint32_t numFlyByCamerasTR5; tr5_flyby_camera_t* flyByCamerasTR5; unsigned int _num_static_meshes; //!< number of static meshes this level tr2_staticmesh_t* _static_meshes; //!< static meshes unsigned int _num_object_textures; //!< number of object textures this level tr2_object_texture_t* _object_textures; //!< list of object textures unsigned int _num_sprite_textures; //!< num of sprite textures this level tr2_sprite_texture_t* _sprite_textures; //!< list of sprite textures unsigned int _num_sprite_sequences; //!< num of sprite sequences this level tr2_sprite_sequence_t* _sprite_sequences; //!< sprite sequence data int _num_cameras; //!< Number of Cameras tr2_camera_t* _cameras; //!< cameras int _num_sound_sources; //!< Number of Sounds tr2_sound_source_t* _sound_sources; //!< sounds int _num_boxes; //!< Number of Boxes tr2_box_t* _boxes; /*!< boxes - looks like * struct { unsigned short value[4]; } * - value[0..2] might be a vector; * value[3] seems to be index into * Overlaps[] */ int _num_overlaps; //!< Number of Overlaps short* _overlaps; /*!< Overlaps - * looks like ushort; 0x8000 is flag * of some sort appears to be an * offset into Boxes[] and/or * Boxes2[] */ short* _zones; //!< Boxes2 int _num_animated_textures; //!< Number of AnimTextures short* _animated_textures; //!< Animtextures int _num_items; //!< Number of Items tr2_item_t* _items; //!< Items unsigned char* _light_map; //!< Colour-light maps unsigned int _num_cinematic_frames; //!< Number of cut-scene frames tr2_cinematic_frame_t* _cinematic_frames; //!< Cut-scene frames short _num_demo_data; //!< Number of Demo Data unsigned char* _demo_data; //!< Demo data float mRoomVertexLightingFactor; float mTexelScale; // Sound data short* mSoundMap; //!< Sound map int mNumSoundDetails; //!< Number of SampleModifiers tr2_sound_details_t* mSoundDetails; //!< Sample modifiers int mNumSampleIndices; //!< Number of Sample Indices int* mSampleIndices; //!< Sample indices unsigned int* mSampleIndicesTR5; bool mRiffAlternateLoaded; //!< Is a TR2,TR3 SFX loaded? unsigned int* mRiffAlternateOffsets; //!< After parsing this will //!< hold byte offsets for TR2,TR3 //!< RIFFs in the buffered SFX int mRiffDataSz; //!< Byte size of a loaded SFX unsigned char* mRiffData; //!< SFX RIFF data in chunks unsigned int mNumTR4Samples; unsigned char** mTR4Samples; unsigned int* mTR4SamplesSz; // For packed Fread emu/wrapper unsigned char* mCompressedLevelData; //!< Buffer used to emulate fread with uncompressed libz data unsigned int mCompressedLevelDataOffset; //!< Offset into buffer unsigned int mCompressedLevelSize; //!< Size of buffer tr_fread_mode_t mFreadMode; //!< Fread mode file|buffer }; #endif