Пример #1
0
/** \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;
}
Пример #2
0
void TR_Level::read_tr3_room_staticmesh(SDL_RWops * const src, tr2_room_staticmesh_t & room_static_mesh)
{
	read_tr_vertex32(src, room_static_mesh.pos);
	room_static_mesh.rotation = (float)read_bitu16(src) / 16384.0f * -90;
	room_static_mesh.intensity1 = read_bit16(src);
	room_static_mesh.intensity2 = read_bit16(src);
	room_static_mesh.object_id = read_bitu16(src);
}
Пример #3
0
/// \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);
}
Пример #4
0
/** \brief reads a triangle definition.
  *
  * The lighting value is set to 0, as it is only in TR4-5.
  */
void TR_Level::read_tr_face3(SDL_RWops * const src, tr4_face3_t & meshface)
{
    meshface.vertices[0] = read_bitu16(src);
    meshface.vertices[1] = read_bitu16(src);
    meshface.vertices[2] = read_bitu16(src);
    meshface.texture = read_bitu16(src);
    // lighting only in TR4-5
    meshface.lighting = 0;
}
Пример #5
0
void TR_Level::read_tr3_item(SDL_RWops * const src, tr2_item_t & item)
{
	item.object_id = read_bit16(src);
	item.room = read_bit16(src);
	read_tr_vertex32(src, item.pos);
	item.rotation = (float)read_bitu16(src) / 16384.0f * -90;
	item.intensity1 = read_bitu16(src);
	item.intensity2 = read_bitu16(src);
	item.flags = read_bitu16(src);
}
Пример #6
0
/// \brief reads an item definition.
void TR_Level::read_tr_item(SDL_RWops * const src, tr2_item_t & item)
{
    item.object_id = read_bit16(src);
    item.room = read_bit16(src);
    read_tr_vertex32(src, item.pos);
    item.rotation = (float)read_bitu16(src) / 16384.0f * -90;
    item.intensity1 = read_bitu16(src);
    if (item.intensity1 >= 0)
        item.intensity1 = (8191 - item.intensity1) << 2;
    item.intensity2 = item.intensity1;
    item.ocb = 0;   // Not present in TR1!
    item.flags = read_bitu16(src);
}
Пример #7
0
void TR_Level::read_tr3_room_staticmesh(SDL_RWops *const src, tr2_room_staticmesh_t & room_static_mesh)
{
    read_tr_vertex32(src, room_static_mesh.pos);
    room_static_mesh.rotation = (float)read_bitu16(src) / 16384.0f * -90;
    room_static_mesh.intensity1 = read_bit16(src);
    room_static_mesh.intensity2 = read_bit16(src);
    room_static_mesh.object_id = read_bitu16(src);

    room_static_mesh.tint.r = ((room_static_mesh.intensity1 & 0x001F)        ) / 62.0f;

    room_static_mesh.tint.g = ((room_static_mesh.intensity1 & 0x03E0) >> 5   ) / 62.0f;

    room_static_mesh.tint.b = ((room_static_mesh.intensity1 & 0x7C00) >> 10  ) / 62.0f;
    room_static_mesh.tint.a = 1.0f;
}
Пример #8
0
/** \brief reads a room staticmesh definition.
  *
  * rotation gets converted to float and scaled appropiatly.
  * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
  * intensity2 is introduced in TR2 and is set to intensity1 for TR1.
  */
void TR_Level::read_tr_room_staticmesh(SDL_RWops * const src, tr2_room_staticmesh_t & room_static_mesh)
{
    read_tr_vertex32(src, room_static_mesh.pos);
    room_static_mesh.rotation = (float)read_bitu16(src) / 16384.0f * -90;
    room_static_mesh.intensity1 = read_bit16(src);
    room_static_mesh.object_id = read_bitu16(src);
    // make consistent
    if (room_static_mesh.intensity1 >= 0)
        room_static_mesh.intensity1 = (8191 - room_static_mesh.intensity1) << 2;
    // only in TR2
    room_static_mesh.intensity2 = room_static_mesh.intensity1;

    room_static_mesh.tint.b = room_static_mesh.tint.g = room_static_mesh.tint.r = (room_static_mesh.intensity2 / 16384.0f);
    room_static_mesh.tint.a = 1.0f;
}
Пример #9
0
/** \brief reads a moveable definition.
  *
  * some sanity checks get done which throw a exception on failure.
  * frame_offset needs to be corrected later in TR_Level::read_tr_level.
  */
void TR_Level::read_tr_moveable(SDL_RWops * const src, tr_moveable_t & moveable)
{
    moveable.object_id = read_bitu32(src);
    moveable.num_meshes = read_bitu16(src);
    moveable.starting_mesh = read_bitu16(src);
    moveable.mesh_tree_index = read_bitu32(src);
    moveable.frame_offset = read_bitu32(src);
    moveable.animation_index = read_bitu16(src);

    // Disable unused skybox polygons.
    if((this->game_version == TR_III) && (moveable.object_id == 355))
    {
        this->meshes[(this->mesh_indices[moveable.starting_mesh])].num_coloured_triangles = 16;
    }
}
Пример #10
0
/** \brief reads a room light definition.
  *
  * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
  * intensity2 and fade2 are introduced in TR2 and are set to intensity1 and fade1 for TR1.
  */
void TR_Level::read_tr_room_light(SDL_RWops * const src, tr5_room_light_t & light)
{
    read_tr_vertex32(src, light.pos);
    // read and make consistent
    light.intensity1 = (8191 - read_bitu16(src)) << 2;
    light.fade1 = read_bitu32(src);
    // only in TR2
    light.intensity2 = light.intensity1;

    light.intensity = light.intensity1;
    light.intensity /= 4096.0f;

    if(light.intensity > 1.0f)
        light.intensity = 1.0f;

    light.fade2 = light.fade1;

    light.r_outer = light.fade1;
    light.r_inner = light.fade1 / 2;

    light.light_type = 0x01; // Point light

    // all white
    light.color.r = 0xff;
    light.color.g = 0xff;
    light.color.b = 0xff;
}
Пример #11
0
/** \brief reads a room light definition.
  *
  * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
  * intensity2 and fade2 are introduced in TR2 and are set to intensity1 and fade1 for TR1.
  */
void TR_Level::read_tr_room_light(SDL_RWops * const src, tr5_room_light_t & light)
{
    read_tr_vertex32(src, light.pos);
    // read and make consistent
    float data = read_bitu16(src);
    data = data < 0.0f || data > 8191.0f ? 0.0f : data;
    
    light.intensity1 = (8191 - data);
    
    light.fade1 = read_bitu32(src);
    // only in TR2
    light.intensity2 = light.intensity1;

    light.intensity = light.intensity1 / 8191.0f;

    if(light.intensity == 0.0f || light.intensity > 1.0f)
        light.intensity = 1.0f;

    light.fade2 = light.fade1;

    light.r_outer = light.fade1;
    light.r_inner = light.fade1 / 2;

    light.light_type = 0x01; // Point light

    // all white
    light.color.r = 0xff;
    light.color.g = 0xff;
    light.color.b = 0xff;
}
Пример #12
0
void TR_Level::read_tr_box(SDL_RWops * const src, tr_box_t & box)
{
    box.zmax =-read_bit32(src);
    box.zmin =-read_bit32(src);
    box.xmin = read_bit32(src);
    box.xmax = read_bit32(src);
    box.true_floor =-read_bit16(src);
    box.overlap_index = read_bitu16(src);
}
Пример #13
0
/// \brief reads a static mesh definition.
void TR_Level::read_tr_staticmesh(SDL_RWops * const src, tr_staticmesh_t & mesh)
{
    mesh.object_id = read_bitu32(src);
    mesh.mesh = read_bitu16(src);

    mesh.visibility_box[0].x = (float)read_bit16(src);
    mesh.visibility_box[1].x = (float)read_bit16(src);
    mesh.visibility_box[0].y = (float)-read_bit16(src);
    mesh.visibility_box[1].y = (float)-read_bit16(src);
    mesh.visibility_box[0].z = (float)-read_bit16(src);
    mesh.visibility_box[1].z = (float)-read_bit16(src);

    mesh.collision_box[0].x = (float)read_bit16(src);
    mesh.collision_box[1].x = (float)read_bit16(src);
    mesh.collision_box[0].y = (float)-read_bit16(src);
    mesh.collision_box[1].y = (float)-read_bit16(src);
    mesh.collision_box[0].z = (float)-read_bit16(src);
    mesh.collision_box[1].z = (float)-read_bit16(src);

    mesh.flags = read_bitu16(src);
}
Пример #14
0
/** \brief reads object texture definition.
  *
  * some sanity checks get done and if they fail an exception gets thrown.
  * all values introduced in TR4 get set appropiatly.
  */
void TR_Level::read_tr_object_texture(SDL_RWops * const src, tr4_object_texture_t & object_texture)
{
    object_texture.transparency_flags = read_bitu16(src);
    object_texture.tile_and_flag = read_bitu16(src);
    if (object_texture.tile_and_flag > 64)
        Sys_extWarn("object_texture.tile_and_flags > 64");

    if ((object_texture.tile_and_flag & (1 << 15)) != 0)
        Sys_extWarn("object_texture.tile_and_flags has top bit set!");

    // only in TR4
    object_texture.flags = 0;
    read_tr_object_texture_vert(src, object_texture.vertices[0]);
    read_tr_object_texture_vert(src, object_texture.vertices[1]);
    read_tr_object_texture_vert(src, object_texture.vertices[2]);
    read_tr_object_texture_vert(src, object_texture.vertices[3]);
    // only in TR4
    object_texture.unknown1 = 0;
    object_texture.unknown2 = 0;
    object_texture.x_size = 0;
    object_texture.y_size = 0;
}
Пример #15
0
/// \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);
}
Пример #16
0
void TR_Level::read_tr3_room_vertex(SDL_RWops * const src, tr5_room_vertex_t & room_vertex)
{
	read_tr_vertex16(src, room_vertex.vertex);
	// read and make consistent
	room_vertex.lighting1 = read_bit16(src);
	room_vertex.attributes = read_bitu16(src);
	room_vertex.lighting2 = read_bit16(src);
	// only in TR5
	room_vertex.normal.x = 0;
	room_vertex.normal.y = 0;
	room_vertex.normal.z = 0;
	room_vertex.colour.r = room_vertex.lighting1 / 32767.0f;
	room_vertex.colour.g = room_vertex.lighting1 / 32767.0f;
	room_vertex.colour.b = room_vertex.lighting1 / 32767.0f;
	room_vertex.colour.a = 255;
}
Пример #17
0
void TR_Level::read_tr3_room_vertex(SDL_RWops *const src, tr5_room_vertex_t & room_vertex)
{
    read_tr_vertex16(src, room_vertex.vertex);
    // read and make consistent
    room_vertex.lighting1 = read_bit16(src);
    room_vertex.attributes = read_bitu16(src);
    room_vertex.lighting2 = read_bit16(src);
    // only in TR5
    room_vertex.normal.x = 0;
    room_vertex.normal.y = 0;
    room_vertex.normal.z = 0;

    room_vertex.colour.r = ((room_vertex.lighting2 & 0x7C00) >> 10  ) / 62.0f;
    room_vertex.colour.g = ((room_vertex.lighting2 & 0x03E0) >> 5   ) / 62.0f;
    room_vertex.colour.b = ((room_vertex.lighting2 & 0x001F)        ) / 62.0f;
    room_vertex.colour.a = 1.0f;
}
Пример #18
0
/** \brief reads a room vertex definition.
  *
  * lighting1 gets converted, so it matches the 0-32768 range introduced in TR3.
  * lighting2 is introduced in TR2 and is set to lighting1 for TR1.
  * attributes is introduced in TR2 and is set 0 for TR1.
  * All other values are introduced in TR5 and get set to appropiate values.
  */
void TR_Level::read_tr_room_vertex(SDL_RWops * const src, tr5_room_vertex_t & room_vertex)
{
    read_tr_vertex16(src, room_vertex.vertex);
    // read and make consistent
    float data = read_bitu16(src);
    data = data < 0.0f || data > 8191.0f ? 0.0f : data;
    
    room_vertex.lighting1 = (8191 - data);
    
    
    // only in TR2
    room_vertex.lighting2 = room_vertex.lighting1;
    room_vertex.attributes = 0;
    // only in TR5
    room_vertex.normal.x = 0;
    room_vertex.normal.y = 0;
    room_vertex.normal.z = 0;
    room_vertex.colour.r = room_vertex.lighting1 / 8191.0f;
    room_vertex.colour.g = room_vertex.lighting1 / 8191.0f;
    room_vertex.colour.b = room_vertex.lighting1 / 8191.0f;
    room_vertex.colour.a = 1.0f;
}
Пример #19
0
/** \brief reads a room portal definition.
  *
  * A check is preformed to see wether the normal lies on a coordinate axis, if not an exception gets thrown.
  */
void TR_Level::read_tr_room_portal(SDL_RWops * const src, tr_room_portal_t & portal)
{
    portal.adjoining_room = read_bitu16(src);
    read_tr_vertex16(src, portal.normal);
    read_tr_vertex16(src, portal.vertices[0]);
    read_tr_vertex16(src, portal.vertices[1]);
    read_tr_vertex16(src, portal.vertices[2]);
    read_tr_vertex16(src, portal.vertices[3]);
    if ((portal.normal.x == 1.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == 0.0f))
        return;
    if ((portal.normal.x == -1.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == 0.0f))
        return;
    if ((portal.normal.x == 0.0f) && (portal.normal.y == 1.0f) && (portal.normal.z == 0.0f))
        return;
    if ((portal.normal.x == 0.0f) && (portal.normal.y == -1.0f) && (portal.normal.z == 0.0f))
        return;
    if ((portal.normal.x == 0.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == 1.0f))
        return;
    if ((portal.normal.x == 0.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == -1.0f))
        return;
        Sys_extWarn("read_tr_room_portal: normal not on world axis");
}
Пример #20
0
void TR_Level::read_tr5_room_layer(SDL_RWops * const src, tr5_room_layer_t & layer)
{
    layer.num_vertices = read_bitu16(src);
    layer.unknown_l1 = read_bitu16(src);
    if (layer.unknown_l1 != 0)
        layer.unknown_l1 = layer.unknown_l1;
    layer.unknown_l2 = read_bitu16(src);
    if (layer.unknown_l2 != 0)
        layer.unknown_l2 = layer.unknown_l2;
    layer.num_rectangles = read_bitu16(src);
    layer.num_triangles = read_bitu16(src);
    layer.unknown_l3 = read_bitu16(src);
    if (layer.unknown_l3 != 0)
        layer.unknown_l3 = layer.unknown_l3;
    layer.unknown_l4 = read_bitu16(src);
    if (layer.unknown_l4 != 0)
        layer.unknown_l4 = layer.unknown_l4;
    if (read_bitu16(src) != 0)
        Sys_extWarn("read_tr5_room_layer: filler2 has wrong value");

    layer.bounding_box_x1 = read_float(src);
    layer.bounding_box_y1 = -read_float(src);
    layer.bounding_box_z1 = -read_float(src);
    layer.bounding_box_x2 = read_float(src);
    layer.bounding_box_y2 = -read_float(src);
    layer.bounding_box_z2 = -read_float(src);
    if (read_bitu32(src) != 0)
        Sys_extWarn("read_tr5_room_layer: filler3 has wrong value");

    layer.unknown_l6a = read_bit16(src);
    layer.unknown_l6b = read_bit16(src);
    layer.unknown_l7a = read_bit16(src);
    layer.unknown_l7b = read_bit16(src);
    layer.unknown_l8a = read_bit16(src);
    layer.unknown_l8b = read_bit16(src);
}
Пример #21
0
void TR_Level::read_tr3_room(SDL_RWops * const src, tr5_room_t & room)
{
	bitu32 num_data_words;
	bitu32 i;
	int 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, SEEK_CUR);

	room.num_layers = 0;

	room.num_vertices = read_bitu16(src);
	room.vertices.resize(room.num_vertices);
	for (i = 0; i < room.num_vertices; i++)
		read_tr3_room_vertex(src, room.vertices[i]);

	room.num_rectangles = read_bitu16(src);
	room.rectangles.resize(room.num_rectangles);
	for (i = 0; i < room.num_rectangles; i++)
		read_tr_face4(src, room.rectangles[i]);

	room.num_triangles = read_bitu16(src);
	room.triangles.resize(room.num_triangles);
	for (i = 0; i < room.num_triangles; i++)
		read_tr_face3(src, room.triangles[i]);

	room.num_sprites = read_bitu16(src);
	room.sprites.resize(room.num_sprites);
	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), SEEK_SET);

	room.num_portals = read_bitu16(src);
	room.portals.resize(room.num_portals);
	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.resize(room.num_zsectors * room.num_xsectors);
	for (i = 0; i < (bitu32)(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.resize(room.num_lights);
	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.resize(room.num_static_meshes);
	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.flags = read_bitu16(src);

	// only in TR3-TR4
	read_tr_colour(src, room.fog_colour);
	room.light_colour.r = room.intensity1 / 32767.0f;
	room.light_colour.g = room.intensity1 / 32767.0f;
	room.light_colour.b = room.intensity1 / 32767.0f;
	room.light_colour.a = 1.0f;
}
Пример #22
0
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);
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
void TR_Level::read_tr5_moveable(SDL_RWops * const src, tr_moveable_t & moveable)
{
    read_tr_moveable(src, moveable);
    if (read_bitu16(src) != 0xFFEF)
        Sys_extWarn("read_tr5_moveable: filler has wrong value");
}
Пример #26
0
/// \brief reads an animation state change.
void TR_Level::read_tr_state_changes(SDL_RWops * const src, tr_state_change_t & state_change)
{
    state_change.state_id = read_bitu16(src);
    state_change.num_anim_dispatches = read_bitu16(src);
    state_change.anim_dispatch = read_bitu16(src);
}
Пример #27
0
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);
    }
}
Пример #28
0
/** \brief reads a room definition.
  *
  * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
  * intensity2 is introduced in TR2 and is set to intensity1 for TR1.
  * light_mode is only in TR2 and is set 0 for TR1.
  * light_colour is only in TR3-4 and gets set appropiatly.
  */
void TR_Level::read_tr_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_tr_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_t*)malloc(room.num_sprites * sizeof(tr_room_sprite_t));
    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]);

    // read and make consistent
    room.intensity1 = (8191 - read_bit16(src)) << 2;
    // only in TR2-TR4
    room.intensity2 = room.intensity1;
    // 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_tr_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_tr_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);
        room.reverb_info = 2;

    room.light_colour.r = room.intensity1 / 32767.0f;
    room.light_colour.g = room.intensity1 / 32767.0f;
    room.light_colour.b = room.intensity1 / 32767.0f;
    room.light_colour.a = 1.0f;
}
Пример #29
0
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;
    }
}
Пример #30
0
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);
}