/** \brief reads sprite texture definition. * * some sanity checks get done and if they fail an exception gets thrown. */ void TR_Level::read_tr_sprite_texture(SDL_RWops * const src, tr_sprite_texture_t & sprite_texture) { int tx, ty, tw, th, tleft, tright, ttop, tbottom; float w, h; sprite_texture.tile = read_bitu16(src); if (sprite_texture.tile > 64) Sys_extWarn("sprite_texture.tile > 64"); tx = read_bitu8(src); ty = read_bitu8(src); tw = read_bitu16(src); th = read_bitu16(src); tleft = read_bit16(src); ttop = read_bit16(src); tright = read_bit16(src); tbottom = read_bit16(src); w = tw / 256.0; h = th / 256.0; sprite_texture.x0 = tx; sprite_texture.y0 = ty; sprite_texture.x1 = sprite_texture.x0 + w; sprite_texture.y1 = sprite_texture.y0 + h; sprite_texture.left_side = tleft; sprite_texture.right_side = tright; sprite_texture.top_side =-tbottom; sprite_texture.bottom_side =-ttop; }
/// \brief reads object texture vertex definition. void TR_Level::read_tr_object_texture_vert(SDL_RWops * const src, tr4_object_texture_vert_t & vert) { vert.xcoordinate = read_bit8(src); vert.xpixel = read_bitu8(src); vert.ycoordinate = read_bit8(src); vert.ypixel = read_bitu8(src); }
/** \brief reads rgb colour. * * Reads three rgb colour components. The read 6-bit values get shifted, so they are 8-bit. * The alpha value of tr2_colour_t gets set to 0. */ void TR_Level::read_tr_colour(SDL_RWops * const src, tr2_colour_t & colour) { // read 6 bit color and change to 8 bit colour.r = read_bitu8(src) << 2; colour.g = read_bitu8(src) << 2; colour.b = read_bitu8(src) << 2; colour.a = 0; }
void TR_Level::read_tr5_room_vertex(SDL_RWops * const src, tr5_room_vertex_t & vert) { read_tr4_vertex_float(src, vert.vertex); read_tr4_vertex_float(src, vert.normal); vert.colour.b = read_bitu8(src) / 255.0f; vert.colour.g = read_bitu8(src) / 255.0f; vert.colour.r = read_bitu8(src) / 255.0f; vert.colour.a = read_bitu8(src) / 255.0f; }
/// \brief reads a room sector definition. void TR_Level::read_tr_room_sector(SDL_RWops * const src, tr_room_sector_t & sector) { sector.fd_index = read_bitu16(src); sector.box_index = read_bitu16(src); sector.room_below = read_bitu8(src); sector.floor = read_bit8(src); sector.room_above = read_bitu8(src); sector.ceiling = read_bit8(src); }
void TR_Level::read_tr2_box(SDL_RWops * const src, tr_box_t & box) { box.zmax =-1024 * read_bitu8(src); box.zmin =-1024 * read_bitu8(src); box.xmin = 1024 * read_bitu8(src); box.xmax = 1024 * read_bitu8(src); box.true_floor =-read_bit16(src); box.overlap_index = read_bit16(src); }
/** \brief reads mesh definition. * * The read num_normals value is positive when normals are available and negative when light * values are available. The values get set appropiatly. */ void TR_Level::read_tr_mesh(SDL_RWops * const src, tr4_mesh_t & mesh) { int i; read_tr_vertex16(src, mesh.centre); mesh.collision_size = read_bit16(src); mesh.flags = read_bitu8(src); mesh.dummy = read_bitu8(src); mesh.num_vertices = read_bit16(src); mesh.vertices = (tr5_vertex_t*)malloc(mesh.num_vertices * sizeof(tr5_vertex_t)); for (i = 0; i < mesh.num_vertices; i++) read_tr_vertex16(src, mesh.vertices[i]); mesh.num_normals = read_bit16(src); if (mesh.num_normals >= 0) { mesh.num_lights = 0; mesh.normals = (tr5_vertex_t*)malloc(mesh.num_normals * sizeof(tr5_vertex_t)); for (i = 0; i < mesh.num_normals; i++) read_tr_vertex16(src, mesh.normals[i]); } else { mesh.num_lights = -mesh.num_normals; mesh.num_normals = 0; mesh.lights = (int16_t*)malloc(mesh.num_lights * sizeof(int16_t)); for (i = 0; i < mesh.num_lights; i++) mesh.lights[i] = read_bit16(src); } mesh.num_textured_rectangles = read_bit16(src); mesh.textured_rectangles = (tr4_face4_t*)malloc(mesh.num_textured_rectangles * sizeof(tr4_face4_t)); for (i = 0; i < mesh.num_textured_rectangles; i++) read_tr_face4(src, mesh.textured_rectangles[i]); mesh.num_textured_triangles = read_bit16(src); mesh.textured_triangles = (tr4_face3_t*)malloc(mesh.num_textured_triangles * sizeof(tr4_face3_t)); for (i = 0; i < mesh.num_textured_triangles; i++) read_tr_face3(src, mesh.textured_triangles[i]); mesh.num_coloured_rectangles = read_bit16(src); mesh.coloured_rectangles = (tr4_face4_t*)malloc(mesh.num_coloured_rectangles * sizeof(tr4_face4_t)); for (i = 0; i < mesh.num_coloured_rectangles; i++) read_tr_face4(src, mesh.coloured_rectangles[i]); mesh.num_coloured_triangles = read_bit16(src); mesh.coloured_triangles = (tr4_face3_t*)malloc(mesh.num_coloured_triangles * sizeof(tr4_face3_t)); for (i = 0; i < mesh.num_coloured_triangles; i++) read_tr_face3(src, mesh.coloured_triangles[i]); }
void TR_Level::read_tr3_room_light(SDL_RWops * const src, tr5_room_light_t & light) { read_tr_vertex32(src, light.pos); light.color.r = read_bitu8(src); light.color.g = read_bitu8(src); light.color.b = read_bitu8(src); light.color.a = read_bitu8(src); light.fade1 = read_bitu32(src); light.fade2 = read_bitu32(src); light.intensity = 1.0f; light.r_outer = (float)light.fade1; light.r_inner = (float)light.fade1 / 2.0; light.light_type = 0x01; // Point light }
/// \brief reads an animation definition. void TR_Level::read_tr_animation(SDL_RWops * const src, tr_animation_t & animation) { animation.frame_offset = read_bitu32(src); animation.frame_rate = read_bitu8(src); animation.frame_size = read_bitu8(src); animation.state_id = read_bitu16(src); animation.speed = read_mixfloat(src); animation.accel = read_mixfloat(src); animation.frame_start = read_bitu16(src); animation.frame_end = read_bitu16(src); animation.next_animation = read_bitu16(src); animation.next_frame = read_bitu16(src); animation.num_state_changes = read_bitu16(src); animation.state_change_offset = read_bitu16(src); animation.num_anim_commands = read_bitu16(src); animation.anim_command = read_bitu16(src); }
void TR_Level::read_tr5_room_light(SDL_RWops * const src, tr5_room_light_t & light) { uint32_t temp; read_tr4_vertex_float(src, light.pos); //read_tr_colour(src, light.color); light.color.r = read_float(src) * 255.0; // r light.color.g = read_float(src) * 255.0; // g light.color.b = read_float(src) * 255.0; // b light.color.a = read_float(src) * 255.0; // a light.color.a = 1.0f; /* if ((temp != 0) && (temp != 0xCDCDCDCD)) throw TR_ReadError("read_tr5_room_light: seperator1 has wrong value"); */ light.r_inner = read_float(src); light.r_outer = read_float(src); read_float(src); // rad_input read_float(src); // rad_output read_float(src); // range read_tr4_vertex_float(src, light.dir); read_tr_vertex32(src, light.pos2); read_tr_vertex32(src, light.dir2); light.light_type = read_bitu8(src); temp = read_bitu8(src); if (temp != 0xCD) Sys_extWarn("read_tr5_room_light: seperator2 has wrong value"); temp = read_bitu8(src); if (temp != 0xCD) Sys_extWarn("read_tr5_room_light: seperator3 has wrong value"); temp = read_bitu8(src); if (temp != 0xCD) Sys_extWarn("read_tr5_room_light: seperator4 has wrong value"); }
void TR_Level::read_tr_level(SDL_RWops * const src, bool demo_or_ub) { uint32_t i; // Version uint32_t file_version = read_bitu32(src); if (file_version != 0x00000020) Sys_extError("Wrong level version"); this->num_textiles = 0; this->num_room_textiles = 0; this->num_obj_textiles = 0; this->num_bump_textiles = 0; this->num_misc_textiles = 0; this->read_32bit_textiles = false; this->textile8_count = this->num_textiles = read_bitu32(src); this->textile8 = (tr_textile8_t*)malloc(this->textile8_count * sizeof(tr_textile8_t)); for (i = 0; i < this->textile8_count; i++) read_tr_textile8(src, this->textile8[i]); // Unused if (read_bitu32(src) != 0) Sys_extWarn("Bad value for 'unused'"); this->rooms_count = read_bitu16(src); this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t)); for (i = 0; i < this->rooms_count; i++) read_tr_room(src, this->rooms[i]); this->floor_data_size = read_bitu32(src); this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t)); for(i = 0; i < this->floor_data_size; i++) this->floor_data[i] = read_bitu16(src); read_mesh_data(src); this->animations_count = read_bitu32(src); this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t)); for (i = 0; i < this->animations_count; i++) read_tr_animation(src, this->animations[i]); this->state_changes_count = read_bitu32(src); this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t)); for (i = 0; i < this->state_changes_count; i++) read_tr_state_changes(src, this->state_changes[i]); this->anim_dispatches_count = read_bitu32(src); this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t)); for (i = 0; i < this->anim_dispatches_count; i++) read_tr_anim_dispatches(src, this->anim_dispatches[i]); this->anim_commands_count = read_bitu32(src); this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t)); for (i = 0; i < this->anim_commands_count; i++) this->anim_commands[i] = read_bit16(src); this->mesh_tree_data_size = read_bitu32(src); this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t)); for (i = 0; i < this->mesh_tree_data_size; i++) this->mesh_tree_data[i] = read_bitu32(src); // 4 bytes read_frame_moveable_data(src); // try to fix ugly stick for (i = 0; i < this->animations_count; i++) { uint32_t frame_offset = this->animations[i].frame_offset / 2; this->animations[i].frame_size = this->frame_data[frame_offset + 9] * 2 + 10; } this->static_meshes_count = read_bitu32(src); this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t)); for (i = 0; i < this->static_meshes_count; i++) read_tr_staticmesh(src, this->static_meshes[i]); this->object_textures_count = read_bitu32(src); this->object_textures = (tr4_object_texture_t*)malloc(this->object_textures_count * sizeof(tr4_object_texture_t)); for (i = 0; i < this->object_textures_count; i++) read_tr_object_texture(src, this->object_textures[i]); this->sprite_textures_count = read_bitu32(src); this->sprite_textures = (tr_sprite_texture_t*)malloc(this->sprite_textures_count * sizeof(tr_sprite_texture_t)); for (i = 0; i < this->sprite_textures_count; i++) read_tr_sprite_texture(src, this->sprite_textures[i]); this->sprite_sequences_count = read_bitu32(src); this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t)); for (i = 0; i < this->sprite_sequences_count; i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); if (demo_or_ub) read_tr_palette(src, this->palette); this->cameras_count = read_bitu32(src); this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t)); for (i = 0; i < this->cameras_count; i++) { this->cameras[i].x = read_bit32(src); this->cameras[i].y = read_bit32(src); this->cameras[i].z = read_bit32(src); this->cameras[i].room = read_bit16(src); this->cameras[i].unknown1 = read_bitu16(src); } this->sound_sources_count = read_bitu32(src); this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t)); for(i = 0; i < this->sound_sources_count; i++) { this->sound_sources[i].x = read_bit32(src); this->sound_sources[i].y = read_bit32(src); this->sound_sources[i].z = read_bit32(src); this->sound_sources[i].sound_id = read_bitu16(src); this->sound_sources[i].flags = read_bitu16(src); } this->boxes_count = read_bitu32(src); this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t)); for (i = 0; i < this->boxes_count; i++) read_tr_box(src, this->boxes[i]); this->overlaps_count = read_bitu32(src); this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t)); for (i = 0; i < this->overlaps_count; i++) this->overlaps[i] = read_bitu16(src); // Zones SDL_RWseek(src, this->boxes_count * 12, RW_SEEK_CUR); this->animated_textures_count = read_bitu32(src); this->animated_textures_uv_count = 0; // No UVRotate in TR1 this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t)); for (i = 0; i < this->animated_textures_count; i++) { this->animated_textures[i] = read_bitu16(src); } this->items_count = read_bitu32(src); this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t)); for (i = 0; i < this->items_count; i++) read_tr_item(src, this->items[i]); read_tr_lightmap(src, this->lightmap); if (!demo_or_ub) read_tr_palette(src, this->palette); this->cinematic_frames_count = read_bitu16(src); this->cinematic_frames = (tr_cinematic_frame_t*)malloc(this->cinematic_frames_count * sizeof(tr_cinematic_frame_t)); for (i = 0; i < this->cinematic_frames_count; i++) { read_tr_cinematic_frame(src, this->cinematic_frames[i]); } this->demo_data_count = read_bitu16(src); this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t)); for(i=0; i < this->demo_data_count; i++) this->demo_data[i] = read_bitu8(src); // Soundmap this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR1 * sizeof(int16_t)); for(i=0; i < TR_AUDIO_MAP_SIZE_TR1; i++) this->soundmap[i] = read_bit16(src); this->sound_details_count = read_bitu32(src); this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t)); for(i = 0; i < this->sound_details_count; i++) { this->sound_details[i].sample = read_bitu16(src); this->sound_details[i].volume = read_bitu16(src); this->sound_details[i].chance = read_bitu16(src); this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src); this->sound_details[i].flags_2 = read_bitu8(src); this->sound_details[i].sound_range = TR_AUDIO_DEFAULT_RANGE; this->sound_details[i].pitch = (int16_t)TR_AUDIO_DEFAULT_PITCH; } // LOAD SAMPLES // In TR1, samples are embedded into level file as solid block, preceded by // block size in bytes. Sample block is followed by sample indices array. this->samples_count = 0; this->samples_data_size = read_bitu32(src); this->samples_data = (uint8_t*)malloc(this->samples_data_size * sizeof(uint8_t)); for(i=0; i < this->samples_data_size; i++) { this->samples_data[i] = read_bitu8(src); if((i >= 4) && (*((uint32_t*)(this->samples_data+i-4)) == 0x46464952)) /// RIFF { this->samples_count++; } } this->sample_indices_count = read_bitu32(src); this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t)); for(i=0; i < this->sample_indices_count; i++) this->sample_indices[i] = read_bitu32(src); }
/// \brief reads the lightmap. void TR_Level::read_tr_lightmap(SDL_RWops * const src, tr_lightmap_t & lightmap) { for (int i = 0; i < (32 * 256); i++) lightmap.map[i] = read_bitu8(src); }
void TR_Level::read_tr2_level(SDL_RWops * const src, bool demo) { uint32_t i; // Version uint32_t file_version = read_bitu32(src); if (file_version != 0x0000002d) Sys_extError("Wrong level version"); read_tr_palette(src, this->palette); read_tr2_palette16(src, this->palette16); this->num_textiles = 0; this->num_room_textiles = 0; this->num_obj_textiles = 0; this->num_bump_textiles = 0; this->num_misc_textiles = 0; this->read_32bit_textiles = false; this->textile8_count = this->num_textiles = read_bitu32(src); this->textile8 = (tr_textile8_t*)malloc(this->textile8_count * sizeof(tr_textile8_t)); for (i = 0; i < this->textile8_count; i++) read_tr_textile8(src, this->textile8[i]); this->textile16_count = this->textile8_count; this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t)); for (i = 0; i < this->textile16_count; i++) read_tr2_textile16(src, this->textile16[i]); // Unused if (read_bitu32(src) != 0) Sys_extWarn("Bad value for 'unused'"); this->rooms_count = read_bitu16(src); this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t)); for (i = 0; i < this->rooms_count; i++) read_tr2_room(src, this->rooms[i]); this->floor_data_size = read_bitu32(src); this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t)); for(i = 0; i < this->floor_data_size; i++) this->floor_data[i] = read_bitu16(src); read_mesh_data(src); this->animations_count = read_bitu32(src); this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t)); for (i = 0; i < this->animations_count; i++) read_tr_animation(src, this->animations[i]); this->state_changes_count = read_bitu32(src); this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t)); for (i = 0; i < this->state_changes_count; i++) read_tr_state_changes(src, this->state_changes[i]); this->anim_dispatches_count = read_bitu32(src); this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t)); for (i = 0; i < this->anim_dispatches_count; i++) read_tr_anim_dispatches(src, this->anim_dispatches[i]); this->anim_commands_count = read_bitu32(src); this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t)); for (i = 0; i < this->anim_commands_count; i++) this->anim_commands[i] = read_bit16(src); this->mesh_tree_data_size = read_bitu32(src); this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t)); for (i = 0; i < this->mesh_tree_data_size; i++) this->mesh_tree_data[i] = read_bitu32(src); // 4 bytes read_frame_moveable_data(src); this->static_meshes_count = read_bitu32(src); this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t)); for (i = 0; i < this->static_meshes_count; i++) read_tr_staticmesh(src, this->static_meshes[i]); this->object_textures.resize( read_bitu32(src) ); for (i = 0; i < this->object_textures.size(); i++) read_tr_object_texture(src, this->object_textures[i]); this->sprite_textures.resize( read_bitu32(src) ); for (i = 0; i < this->sprite_textures.size(); i++) read_tr_sprite_texture(src, this->sprite_textures[i]); this->sprite_sequences_count = read_bitu32(src); this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t)); for (i = 0; i < this->sprite_sequences_count; i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); if (demo) read_tr_lightmap(src, this->lightmap); this->cameras_count = read_bitu32(src); this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t)); for (i = 0; i < this->cameras_count; i++) { this->cameras[i].x = read_bit32(src); this->cameras[i].y = read_bit32(src); this->cameras[i].z = read_bit32(src); this->cameras[i].room = read_bit16(src); this->cameras[i].unknown1 = read_bitu16(src); } this->sound_sources_count = read_bitu32(src); this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t)); for(i = 0; i < this->sound_sources_count; i++) { this->sound_sources[i].x = read_bit32(src); this->sound_sources[i].y = read_bit32(src); this->sound_sources[i].z = read_bit32(src); this->sound_sources[i].sound_id = read_bitu16(src); this->sound_sources[i].flags = read_bitu16(src); } this->boxes_count = read_bitu32(src); this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t)); for (i = 0; i < this->boxes_count; i++) read_tr2_box(src, this->boxes[i]); this->overlaps_count = read_bitu32(src); this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t)); for (i = 0; i < this->overlaps_count; i++) this->overlaps[i] = read_bitu16(src); // Zones SDL_RWseek(src, this->boxes_count * 20, RW_SEEK_CUR); this->animated_textures_count = read_bitu32(src); this->animated_textures_uv_count = 0; // No UVRotate in TR2 this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t)); for (i = 0; i < this->animated_textures_count; i++) { this->animated_textures[i] = read_bitu16(src); } this->items_count = read_bitu32(src); this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t)); for (i = 0; i < this->items_count; i++) read_tr2_item(src, this->items[i]); if (!demo) read_tr_lightmap(src, this->lightmap); this->cinematic_frames_count = read_bitu16(src); this->cinematic_frames = (tr_cinematic_frame_t*)malloc(this->cinematic_frames_count * sizeof(tr_cinematic_frame_t)); for (i = 0; i < this->cinematic_frames_count; i++) { read_tr_cinematic_frame(src, this->cinematic_frames[i]); } this->demo_data_count = read_bitu16(src); this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t)); for(i=0; i < this->demo_data_count; i++) this->demo_data[i] = read_bitu8(src); // Soundmap this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR2 * sizeof(int16_t)); for(i=0; i < TR_AUDIO_MAP_SIZE_TR2; i++) this->soundmap[i] = read_bit16(src); this->sound_details_count = read_bitu32(src); this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t)); for(i = 0; i < this->sound_details_count; i++) { this->sound_details[i].sample = read_bitu16(src); this->sound_details[i].volume = read_bitu16(src); this->sound_details[i].chance = read_bitu16(src); this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src); this->sound_details[i].flags_2 = read_bitu8(src); this->sound_details[i].sound_range = TR_AUDIO_DEFAULT_RANGE; this->sound_details[i].pitch = (int16_t)TR_AUDIO_DEFAULT_PITCH; } this->sample_indices_count = read_bitu32(src); this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t)); for(i=0; i < this->sample_indices_count; i++) this->sample_indices[i] = read_bitu32(src); // remap all sample indices here for(i = 0; i < this->sound_details_count; i++) { if(this->sound_details[i].sample < this->sample_indices_count) { this->sound_details[i].sample = this->sample_indices[this->sound_details[i].sample]; } } // LOAD SAMPLES // In TR2, samples are stored in separate file called MAIN.SFX. // If there is no such files, no samples are loaded. SDL_RWops *newsrc = SDL_RWFromFile(this->sfx_path, "rb"); if (newsrc == NULL) { Sys_extWarn("read_tr2_level: failed to open \"%s\"! No samples loaded.", this->sfx_path); } else { this->samples_data.resize( SDL_RWsize(newsrc) ); this->samples_count = 0; for(i = 0; i < this->samples_data.size(); i++) { this->samples_data[i] = read_bitu8(newsrc); if((i >= 4) && (*((uint32_t*)(this->samples_data.data()+i-4)) == 0x46464952)) /// RIFF { this->samples_count++; } } SDL_RWclose(newsrc); newsrc = NULL; } }
void TR_Level::read_tr5_level(SDL_RWops * const src) { uint32_t i; uint8_t *comp_buffer = NULL; uint8_t *uncomp_buffer = NULL; SDL_RWops *newsrc = NULL; // Version uint32_t file_version = read_bitu32(src); if (file_version != 0x00345254) Sys_extError("Wrong level version"); this->num_textiles = 0; this->num_room_textiles = 0; this->num_obj_textiles = 0; this->num_bump_textiles = 0; this->num_misc_textiles = 0; this->read_32bit_textiles = false; uint32_t uncomp_size; uint32_t comp_size; unsigned long size; this->num_room_textiles = read_bitu16(src); this->num_obj_textiles = read_bitu16(src); this->num_bump_textiles = read_bitu16(src); this->num_misc_textiles = 3; this->num_textiles = this->num_room_textiles + this->num_obj_textiles + this->num_bump_textiles + this->num_misc_textiles; uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles32 uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { uncomp_buffer = new uint8_t[uncomp_size]; this->textile32.resize( this->num_textiles ); comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: textiles32"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++) read_tr4_textile32(newsrc, this->textile32[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; this->read_32bit_textiles = true; } uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles16 uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { if (this->textile32.empty()) { uncomp_buffer = new uint8_t[uncomp_size]; this->textile16_count = this->num_textiles; this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t)); comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: textiles16"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++) read_tr2_textile16(newsrc, this->textile16[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; } else { SDL_RWseek(src, comp_size, SEEK_CUR); } } uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles32d uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { uncomp_buffer = new uint8_t[uncomp_size]; if ((uncomp_size / (256 * 256 * 4)) > 3) Sys_extWarn("read_tr5_level: num_misc_textiles > 3"); if (this->textile32.empty()) { this->textile32.resize( this->num_misc_textiles ); } comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: misc_textiles"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = (this->num_textiles - this->num_misc_textiles); i < this->num_textiles; i++) read_tr4_textile32(newsrc, this->textile32[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; } // flags? /* I found 2 flags in the TR5 file format. Directly after the sprite textures are 2 ints as a flag. The first one is the lara type: 0 Normal 3 Catsuit 4 Divesuit 6 Invisible The second one is the weather type (effects all outside rooms): 0 No weather 1 Rain 2 Snow (in title.trc these are red triangles falling from the sky). */ i = read_bitu16(src); i = read_bitu16(src); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[1]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[2]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[3]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[4]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[5]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[6]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[7]"); // LevelDataSize1 read_bitu32(src); // LevelDataSize2 read_bitu32(src); // Unused if (read_bitu32(src) != 0) Sys_extWarn("Bad value for 'unused'"); this->rooms_count = read_bitu32(src); this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t)); for (i = 0; i < this->rooms_count; i++) read_tr5_room(src, this->rooms[i]); this->floor_data_size = read_bitu32(src); this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t)); for(i = 0; i < this->floor_data_size; i++) this->floor_data[i] = read_bitu16(src); read_mesh_data(src); this->animations_count = read_bitu32(src); this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t)); for (i = 0; i < this->animations_count; i++) { read_tr4_animation(src, this->animations[i]); } this->state_changes_count = read_bitu32(src); this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t)); for (i = 0; i < this->state_changes_count; i++) read_tr_state_changes(src, this->state_changes[i]); this->anim_dispatches_count = read_bitu32(src); this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t)); for (i = 0; i < this->anim_dispatches_count; i++) read_tr_anim_dispatches(src, this->anim_dispatches[i]); this->anim_commands_count = read_bitu32(src); this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t)); for (i = 0; i < this->anim_commands_count; i++) this->anim_commands[i] = read_bit16(src); this->mesh_tree_data_size = read_bitu32(src); this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t)); for (i = 0; i < this->mesh_tree_data_size; i++) this->mesh_tree_data[i] = read_bitu32(src); // 4 bytes read_frame_moveable_data(src); this->static_meshes_count = read_bitu32(src); this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t)); for (i = 0; i < this->static_meshes_count; i++) read_tr_staticmesh(src, this->static_meshes[i]); if (read_bit8(src) != 'S') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 'P') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 'R') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 0) Sys_extError("read_tr5_level: 'SPR' not found"); this->sprite_textures.resize( read_bitu32(src) ); for (i = 0; i < this->sprite_textures.size(); i++) read_tr4_sprite_texture(src, this->sprite_textures[i]); this->sprite_sequences_count = read_bitu32(src); this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t)); for (i = 0; i < this->sprite_sequences_count; i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); this->cameras_count = read_bitu32(src); this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t)); for (i = 0; i < this->cameras_count; i++) { this->cameras[i].x = read_bit32(src); this->cameras[i].y = read_bit32(src); this->cameras[i].z = read_bit32(src); this->cameras[i].room = read_bit16(src); this->cameras[i].unknown1 = read_bitu16(src); } this->flyby_cameras_count = read_bitu32(src); this->flyby_cameras = (tr4_flyby_camera_t*)malloc(this->flyby_cameras_count * sizeof(tr4_flyby_camera_t)); for (i = 0; i < this->flyby_cameras_count; i++) { this->flyby_cameras[i].cam_x = read_bit32(src); this->flyby_cameras[i].cam_y = read_bit32(src); this->flyby_cameras[i].cam_z = read_bit32(src); this->flyby_cameras[i].target_x = read_bit32(src); this->flyby_cameras[i].target_y = read_bit32(src); this->flyby_cameras[i].target_z = read_bit32(src); this->flyby_cameras[i].sequence = read_bit8(src); this->flyby_cameras[i].index = read_bit8(src); this->flyby_cameras[i].fov = read_bitu16(src); this->flyby_cameras[i].roll = read_bitu16(src); this->flyby_cameras[i].timer = read_bitu16(src); this->flyby_cameras[i].speed = read_bitu16(src); this->flyby_cameras[i].flags = read_bitu16(src); this->flyby_cameras[i].room_id = read_bitu32(src); } this->sound_sources_count = read_bitu32(src); this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t)); for(i = 0; i < this->sound_sources_count; i++) { this->sound_sources[i].x = read_bit32(src); this->sound_sources[i].y = read_bit32(src); this->sound_sources[i].z = read_bit32(src); this->sound_sources[i].sound_id = read_bitu16(src); this->sound_sources[i].flags = read_bitu16(src); } this->boxes_count = read_bitu32(src); this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t)); for (i = 0; i < this->boxes_count; i++) read_tr2_box(src, this->boxes[i]); this->overlaps_count = read_bitu32(src); this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t)); for (i = 0; i < this->overlaps_count; i++) this->overlaps[i] = read_bitu16(src); // Zones SDL_RWseek(src, this->boxes_count * 20, SEEK_CUR); this->animated_textures_count = read_bitu32(src); this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t)); for (i = 0; i < this->animated_textures_count; i++) { this->animated_textures[i] = read_bitu16(src); } this->animated_textures_uv_count = read_bitu8(src); if (read_bit8(src) != 'T') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 'E') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 'X') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 0) Sys_extError("read_tr5_level: '\\0TEX' not found"); this->object_textures.resize( read_bitu32(src) ); for (i = 0; i < this->object_textures.size(); i++) { read_tr4_object_texture(src, this->object_textures[i]); if (read_bitu16(src) != 0) Sys_extWarn("read_tr5_level: obj_tex trailing bitu16 != 0"); } this->items_count = read_bitu32(src); this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t)); for (i = 0; i < this->items_count; i++) read_tr4_item(src, this->items[i]); this->ai_objects_count = read_bitu32(src); this->ai_objects = (tr4_ai_object_t*)malloc(this->ai_objects_count * sizeof(tr4_ai_object_t)); for(i=0; i < this->ai_objects_count; i++) { this->ai_objects[i].object_id = read_bitu16(src); this->ai_objects[i].room = read_bitu16(src); this->ai_objects[i].x = read_bit32(src); this->ai_objects[i].y = read_bit32(src); this->ai_objects[i].z = read_bit32(src); // 16 this->ai_objects[i].ocb = read_bitu16(src); this->ai_objects[i].flags = read_bitu16(src); // 20 this->ai_objects[i].angle = read_bit32(src); // 24 } this->demo_data_count = read_bitu16(src); this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t)); for(i=0; i < this->demo_data_count; i++) this->demo_data[i] = read_bitu8(src); // Soundmap this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR5 * sizeof(int16_t)); for(i=0; i < TR_AUDIO_MAP_SIZE_TR5; i++) this->soundmap[i] = read_bit16(src); this->sound_details_count = read_bitu32(src); this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t)); for(i=0; i < this->sound_details_count; i++) { this->sound_details[i].sample = read_bitu16(src); this->sound_details[i].volume = (uint16_t)read_bitu8(src); // n x 2.6 this->sound_details[i].sound_range = (uint16_t)read_bitu8(src); // n as is this->sound_details[i].chance = (uint16_t)read_bitu8(src); // If n = 99, n = 0 (max. chance) this->sound_details[i].pitch = (int16_t)read_bit8(src); // n as is this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src); this->sound_details[i].flags_2 = read_bitu8(src); } this->sample_indices_count = read_bitu32(src); this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t)); for(i=0; i < this->sample_indices_count; i++) this->sample_indices[i] = read_bitu32(src); SDL_RWseek(src, 6, SEEK_CUR); // In TR5, sample indices are followed by 6 0xCD bytes. - correct - really 0xCDCDCDCDCDCD // LOAD SAMPLES i = read_bitu32(src); // Read num samples if(i) { this->samples_count = i; // Since sample data is the last part, we simply load whole last // block of file as single array. this->samples_data.resize( SDL_RWsize(src) - SDL_RWtell(src) ); for(i = 0; i < this->samples_data.size(); i++) this->samples_data[i] = read_bitu8(src); } }
void TR_Level::read_tr5_room(SDL_RWops * const src, tr5_room_t & room) { uint32_t room_data_size; //uint32_t portal_offset; uint32_t sector_data_offset; uint32_t static_meshes_offset; uint32_t layer_offset; uint32_t vertices_offset; uint32_t poly_offset; uint32_t poly_offset2; uint32_t vertices_size; //uint32_t light_size; SDL_RWops *newsrc = NULL; uint32_t temp; uint32_t i; uint8_t *buffer; if (read_bitu32(src) != 0x414C4558) Sys_extError("read_tr5_room: 'XELA' not found"); room_data_size = read_bitu32(src); buffer = new uint8_t[room_data_size]; if (SDL_RWread(src, buffer, 1, room_data_size) < room_data_size) Sys_extError("read_tr5_room: room_data"); if ((newsrc = SDL_RWFromMem(buffer, room_data_size)) == NULL) Sys_extError("read_tr5_room: SDL_RWFromMem"); room.intensity1 = 32767; room.intensity2 = 32767; room.light_mode = 0; if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator1 has wrong value"); /*portal_offset = */read_bit32(newsrc); // StartPortalOffset? // endSDOffset sector_data_offset = read_bitu32(newsrc); // StartSDOffset temp = read_bitu32(newsrc); if ((temp != 0) && (temp != 0xCDCDCDCD)) Sys_extWarn("read_tr5_room: seperator2 has wrong value"); static_meshes_offset = read_bitu32(newsrc); // endPortalOffset // static_meshes_offset or room_layer_offset // read and change coordinate system room.offset.x = (float)read_bit32(newsrc); room.offset.y = read_bitu32(newsrc); room.offset.z = (float)-read_bit32(newsrc); room.y_bottom = (float)-read_bit32(newsrc); room.y_top = (float)-read_bit32(newsrc); room.num_zsectors = read_bitu16(newsrc); room.num_xsectors = read_bitu16(newsrc); room.light_colour.b = read_bitu8(newsrc) / 255.0f; room.light_colour.g = read_bitu8(newsrc) / 255.0f; room.light_colour.r = read_bitu8(newsrc) / 255.0f; room.light_colour.a = read_bitu8(newsrc) / 255.0f; room.num_lights = read_bitu16(newsrc); if (room.num_lights > 512) Sys_extWarn("read_tr5_room: num_lights > 512"); room.num_static_meshes = read_bitu16(newsrc); if (room.num_static_meshes > 512) Sys_extWarn("read_tr5_room: num_static_meshes > 512"); room.reverb_info = read_bitu8(newsrc); room.alternate_group = read_bitu8(newsrc); room.water_scheme = read_bitu16(newsrc); if (read_bitu32(newsrc) != 0x00007FFF) Sys_extWarn("read_tr5_room: filler1 has wrong value"); if (read_bitu32(newsrc) != 0x00007FFF) Sys_extWarn("read_tr5_room: filler2 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator4 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator5 has wrong value"); if (read_bitu32(newsrc) != 0xFFFFFFFF) Sys_extWarn("read_tr5_room: seperator6 has wrong value"); room.alternate_room = read_bit16(newsrc); room.flags = read_bitu16(newsrc); room.unknown_r1 = read_bitu32(newsrc); room.unknown_r2 = read_bitu32(newsrc); room.unknown_r3 = read_bitu32(newsrc); temp = read_bitu32(newsrc); if ((temp != 0) && (temp != 0xCDCDCDCD)) Sys_extWarn("read_tr5_room: seperator7 has wrong value"); room.unknown_r4a = read_bitu16(newsrc); room.unknown_r4b = read_bitu16(newsrc); room.room_x = read_float(newsrc); room.unknown_r5 = read_bitu32(newsrc); room.room_z = -read_float(newsrc); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator8 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator9 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator10 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator11 has wrong value"); temp = read_bitu32(newsrc); if ((temp != 0) && (temp != 0xCDCDCDCD)) Sys_extWarn("read_tr5_room: seperator12 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator13 has wrong value"); room.num_triangles = read_bitu32(newsrc); if (room.num_triangles == 0xCDCDCDCD) room.num_triangles = 0; if (room.num_triangles > 512) Sys_extWarn("read_tr5_room: num_triangles > 512"); room.num_rectangles = read_bitu32(newsrc); if (room.num_rectangles == 0xCDCDCDCD) room.num_rectangles = 0; if (room.num_rectangles > 1024) Sys_extWarn("read_tr5_room: num_rectangles > 1024"); if (read_bitu32(newsrc) != 0) Sys_extWarn("read_tr5_room: seperator14 has wrong value"); /*light_size = */read_bitu32(newsrc); if (read_bitu32(newsrc) != room.num_lights) Sys_extError("read_tr5_room: room.num_lights2 != room.num_lights"); room.unknown_r6 = read_bitu32(newsrc); room.room_y_top = -read_float(newsrc); room.room_y_bottom = -read_float(newsrc); room.num_layers = read_bitu32(newsrc); /* if (room.num_layers != 0) { if (room.x != room.room_x) throw TR_ReadError("read_tr5_room: x != room_x"); if (room.z != room.room_z) throw TR_ReadError("read_tr5_room: z != room_z"); if (room.y_top != room.room_y_top) throw TR_ReadError("read_tr5_room: y_top != room_y_top"); if (room.y_bottom != room.room_y_bottom) throw TR_ReadError("read_tr5_room: y_bottom != room_y_bottom"); } */ layer_offset = read_bitu32(newsrc); vertices_offset = read_bitu32(newsrc); poly_offset = read_bitu32(newsrc); poly_offset2 = read_bitu32(newsrc); if (poly_offset != poly_offset2) Sys_extError("read_tr5_room: poly_offset != poly_offset2"); vertices_size = read_bitu32(newsrc); if ((vertices_size % 28) != 0) Sys_extError("read_tr5_room: vertices_size has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator15 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator16 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator17 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator18 has wrong value"); room.lights = (tr5_room_light_t*)malloc(room.num_lights * sizeof(tr5_room_light_t)); for (i = 0; i < room.num_lights; i++) read_tr5_room_light(newsrc, room.lights[i]); SDL_RWseek(newsrc, 208 + sector_data_offset, SEEK_SET); room.sector_list = (tr_room_sector_t*)malloc(room.num_zsectors * room.num_xsectors * sizeof(tr_room_sector_t)); for (i = 0; i < (uint32_t)(room.num_zsectors * room.num_xsectors); i++) read_tr_room_sector(newsrc, room.sector_list[i]); /* if (room.portal_offset != 0xFFFFFFFF) { if (room.portal_offset != (room.sector_data_offset + (room.num_zsectors * room.num_xsectors * 8))) throw TR_ReadError("read_tr5_room: portal_offset has wrong value"); SDL_RWseek(newsrc, 208 + room.portal_offset, SEEK_SET); } */ room.num_portals = read_bit16(newsrc); room.portals = (tr_room_portal_t*)malloc(room.num_portals * sizeof(tr_room_portal_t)); for (i = 0; i < room.num_portals; i++) read_tr_room_portal(newsrc, room.portals[i]); SDL_RWseek(newsrc, 208 + static_meshes_offset, SEEK_SET); room.static_meshes = (tr2_room_staticmesh_t*)malloc(room.num_static_meshes * sizeof(tr2_room_staticmesh_t)); for (i = 0; i < room.num_static_meshes; i++) read_tr4_room_staticmesh(newsrc, room.static_meshes[i]); SDL_RWseek(newsrc, 208 + layer_offset, SEEK_SET); room.layers = (tr5_room_layer_t*)malloc(room.num_layers * sizeof(tr5_room_layer_t)); for (i = 0; i < room.num_layers; i++) read_tr5_room_layer(newsrc, room.layers[i]); SDL_RWseek(newsrc, 208 + poly_offset, SEEK_SET); { uint32_t vertex_index = 0; uint32_t rectangle_index = 0; uint32_t triangle_index = 0; room.rectangles = (tr4_face4_t*)malloc(room.num_rectangles * sizeof(tr4_face4_t)); room.triangles = (tr4_face3_t*)malloc(room.num_triangles * sizeof(tr4_face3_t)); for (i = 0; i < room.num_layers; i++) { uint32_t j; for (j = 0; j < room.layers[i].num_rectangles; j++) { read_tr4_face4(newsrc, room.rectangles[rectangle_index]); room.rectangles[rectangle_index].vertices[0] += vertex_index; room.rectangles[rectangle_index].vertices[1] += vertex_index; room.rectangles[rectangle_index].vertices[2] += vertex_index; room.rectangles[rectangle_index].vertices[3] += vertex_index; rectangle_index++; } for (j = 0; j < room.layers[i].num_triangles; j++) { read_tr4_face3(newsrc, room.triangles[triangle_index]); room.triangles[triangle_index].vertices[0] += vertex_index; room.triangles[triangle_index].vertices[1] += vertex_index; room.triangles[triangle_index].vertices[2] += vertex_index; triangle_index++; } vertex_index += room.layers[i].num_vertices; } } SDL_RWseek(newsrc, 208 + vertices_offset, SEEK_SET); { uint32_t vertex_index = 0; room.num_vertices = vertices_size / 28; //int temp1 = room_data_size - (208 + vertices_offset + vertices_size); room.vertices = (tr5_room_vertex_t*)calloc(room.num_vertices, sizeof(tr5_room_vertex_t)); for (i = 0; i < room.num_layers; i++) { uint32_t j; for (j = 0; j < room.layers[i].num_vertices; j++) read_tr5_room_vertex(newsrc, room.vertices[vertex_index++]); } } SDL_RWseek(newsrc, room_data_size, SEEK_SET); SDL_RWclose(newsrc); newsrc = NULL; delete [] buffer; }
void TR_Level::read_tr3_room(SDL_RWops * const src, tr5_room_t & room) { uint32_t num_data_words; uint32_t i; int64_t pos; // read and change coordinate system room.offset.x = (float)read_bit32(src); room.offset.y = 0; room.offset.z = (float)-read_bit32(src); room.y_bottom = (float)-read_bit32(src); room.y_top = (float)-read_bit32(src); num_data_words = read_bitu32(src); pos = SDL_RWseek(src, 0, RW_SEEK_CUR); room.num_layers = 0; room.num_vertices = read_bitu16(src); room.vertices = (tr5_room_vertex_t*)calloc(room.num_vertices, sizeof(tr5_room_vertex_t)); for (i = 0; i < room.num_vertices; i++) read_tr3_room_vertex(src, room.vertices[i]); room.num_rectangles = read_bitu16(src); room.rectangles = (tr4_face4_t*)malloc(room.num_rectangles * sizeof(tr4_face4_t)); for (i = 0; i < room.num_rectangles; i++) read_tr_face4(src, room.rectangles[i]); room.num_triangles = read_bitu16(src); room.triangles = (tr4_face3_t*)malloc(room.num_triangles * sizeof(tr4_face3_t)); for (i = 0; i < room.num_triangles; i++) read_tr_face3(src, room.triangles[i]); room.num_sprites = read_bitu16(src); room.sprites = (tr_room_Sprite*)malloc(room.num_sprites * sizeof(tr_room_Sprite)); for (i = 0; i < room.num_sprites; i++) read_tr_room_sprite(src, room.sprites[i]); // set to the right position in case that there is some unused data SDL_RWseek(src, pos + (num_data_words * 2), RW_SEEK_SET); room.num_portals = read_bitu16(src); room.portals = (tr_room_portal_t*)malloc(room.num_portals * sizeof(tr_room_portal_t)); for (i = 0; i < room.num_portals; i++) read_tr_room_portal(src, room.portals[i]); room.num_zsectors = read_bitu16(src); room.num_xsectors = read_bitu16(src); room.sector_list = (tr_room_sector_t*)malloc(room.num_zsectors * room.num_xsectors * sizeof(tr_room_sector_t)); for (i = 0; i < (uint32_t)(room.num_zsectors * room.num_xsectors); i++) read_tr_room_sector(src, room.sector_list[i]); room.intensity1 = read_bit16(src); room.intensity2 = read_bit16(src); // only in TR2 room.light_mode = 0; room.num_lights = read_bitu16(src); room.lights = (tr5_room_light_t*)malloc(room.num_lights * sizeof(tr5_room_light_t)); for (i = 0; i < room.num_lights; i++) read_tr2_room_light(src, room.lights[i]); room.num_static_meshes = read_bitu16(src); room.static_meshes = (tr2_room_staticmesh_t*)malloc(room.num_static_meshes * sizeof(tr2_room_staticmesh_t)); for (i = 0; i < room.num_static_meshes; i++) read_tr3_room_staticmesh(src, room.static_meshes[i]); room.alternate_room = read_bit16(src); room.alternate_group = 0; // Doesn't exist in TR1-3 room.flags = read_bitu16(src); if(room.flags & 0x0080) { room.flags |= 0x0002; // Move quicksand flag to another bit to avoid confusion with NL flag. room.flags ^= 0x0080; } // Only in TR3-5 room.water_scheme = read_bitu8(src); room.reverb_info = read_bitu8(src); SDL_RWseek(src, 1, SEEK_CUR); // Alternate_group override? room.light_colour.r = room.intensity1 / 65534.0f; room.light_colour.g = room.intensity1 / 65534.0f; room.light_colour.b = room.intensity1 / 65534.0f; room.light_colour.a = 1.0f; }