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_tr3_level(SDL_RWops * const src) { bitu32 i; // Version bitu32 file_version = read_bitu32(src); if ((file_version != 0xFF080038) && (file_version != 0xFF180038) /*&& (file_version != 0xFF180034) */ ) throw TR_ReadError ("Wrong level version", __FILE__, __LINE__, RCSID); 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->num_textiles = read_bitu32(src); this->textile8.resize(this->num_textiles); for (i = 0; i < this->num_textiles; i++) read_tr_textile8(src, this->textile8[i]); this->textile16.resize(this->num_textiles); for (i = 0; i < this->num_textiles; i++) read_tr2_textile16(src, this->textile16[i]); // Unused if (read_bitu32(src) != 0) throw TR_ReadError ("Bad value for 'unused'", __FILE__, __LINE__, RCSID); this->rooms.resize(read_bitu16(src)); for (i = 0; i < this->rooms.size(); i++) read_tr3_room(src, this->rooms[i]); this->floor_data.resize(read_bitu32(src)); SDL_RWseek(src, this->floor_data.size() * 2, SEEK_CUR); read_mesh_data(src); this->animations.resize(read_bitu32(src)); for (i = 0; i < this->animations.size(); i++) read_tr_animation(src, this->animations[i]); this->state_changes.resize(read_bitu32(src)); SDL_RWseek(src, this->state_changes.size() * 6, SEEK_CUR); this->anim_dispatches.resize(read_bitu32(src)); SDL_RWseek(src, this->anim_dispatches.size() * 8, SEEK_CUR); this->anim_commands.resize(read_bitu32(src)); SDL_RWseek(src, this->anim_commands.size() * 2, SEEK_CUR); bitu32 num_mesh_trees = read_bitu32(src); if ((num_mesh_trees % 4) != 0) throw TR_ReadError ("read_tr3_level: num_mesh_trees % 4 != 0", __FILE__, __LINE__, RCSID); num_mesh_trees /= 4; this->mesh_trees.resize(num_mesh_trees); for (i = 0; i < this->mesh_trees.size(); i++) read_tr_meshtree(src, this->mesh_trees[i]); read_frame_moveable_data(src); this->static_meshes.resize(read_bitu32(src)); for (i = 0; i < this->static_meshes.size(); i++) read_tr_staticmesh(src, this->static_meshes[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.resize(read_bitu32(src)); for (i = 0; i < this->sprite_sequences.size(); i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); this->cameras.resize(read_bitu32(src)); SDL_RWseek(src, this->cameras.size() * 16, SEEK_CUR); this->sound_sources.resize(read_bitu32(src)); SDL_RWseek(src, this->sound_sources.size() * 16, SEEK_CUR); this->boxes.resize(read_bitu32(src)); SDL_RWseek(src, this->boxes.size() * 8, SEEK_CUR); this->overlaps.resize(read_bitu32(src)); SDL_RWseek(src, this->overlaps.size() * 2, SEEK_CUR); // Zones SDL_RWseek(src, this->boxes.size() * 20, SEEK_CUR); this->animated_textures.resize(read_bitu32(src)); SDL_RWseek(src, this->animated_textures.size() * 2, SEEK_CUR); 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->items.resize(read_bitu32(src)); for (i = 0; i < this->items.size(); i++) read_tr3_item(src, this->items[i]); read_tr_lightmap(src, this->lightmap); this->cinematic_frames.resize(read_bitu16(src)); SDL_RWseek(src, this->cinematic_frames.size() * 16, SEEK_CUR); this->demo_data.resize(read_bitu16(src)); SDL_RWseek(src, this->demo_data.size(), SEEK_CUR); // Soundmap SDL_RWseek(src, 2 * 370, SEEK_CUR); this->sound_details.resize(read_bitu32(src)); SDL_RWseek(src, this->sound_details.size() * 8, SEEK_CUR); this->sample_indices.resize(read_bitu32(src)); SDL_RWseek(src, this->sample_indices.size() * 4, SEEK_CUR); }
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); read_frame_moveable_data(src); // try to fix ugly hack 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)); this->zones = (tr2_zone_t*)malloc(this->boxes_count * sizeof(tr2_zone_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 for (i = 0; i < this->boxes_count; i++) read_tr_zone(src, this->zones[i]); 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); }