/** \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; }
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) { 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; }
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; }