1 /*
2 * Copyright 2002 - Florian Schulze <crow@icculus.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 * This file is part of vt.
19 *
20 */
21
22 #include <SDL2/SDL_endian.h>
23
24 #include <zlib.h>
25 #include "l_main.h"
26 #include "tr_versions.h"
27 #include "../core/system.h"
28
29 #define RCSID "$Id: l_tr4.cpp,v 1.14 2002/09/20 15:59:02 crow Exp $"
30
read_tr4_vertex_float(SDL_RWops * const src,tr5_vertex_t & vertex)31 void TR_Level::read_tr4_vertex_float(SDL_RWops * const src, tr5_vertex_t & vertex)
32 {
33 vertex.x = read_float(src);
34 vertex.y = -read_float(src);
35 vertex.z = -read_float(src);
36 }
37
read_tr4_textile32(SDL_RWops * const src,tr4_textile32_t & textile)38 void TR_Level::read_tr4_textile32(SDL_RWops * const src, tr4_textile32_t & textile)
39 {
40 for (int i = 0; i < 256; i++) {
41 if (SDL_RWread(src, textile.pixels[i], 4, 256) < 256)
42 Sys_extError("read_tr4_textile32");
43
44 for (int j = 0; j < 256; j++)
45 textile.pixels[i][j] = SDL_SwapLE32((textile.pixels[i][j] & 0xff00ff00) | ((textile.pixels[i][j] & 0x00ff0000) >> 16) | ((textile.pixels[i][j] & 0x000000ff) << 16));
46 }
47 }
48
read_tr4_face3(SDL_RWops * const src,tr4_face3_t & meshface)49 void TR_Level::read_tr4_face3(SDL_RWops * const src, tr4_face3_t & meshface)
50 {
51 meshface.vertices[0] = read_bitu16(src);
52 meshface.vertices[1] = read_bitu16(src);
53 meshface.vertices[2] = read_bitu16(src);
54 meshface.texture = read_bitu16(src);
55 meshface.lighting = read_bitu16(src);
56 }
57
read_tr4_face4(SDL_RWops * const src,tr4_face4_t & meshface)58 void TR_Level::read_tr4_face4(SDL_RWops * const src, tr4_face4_t & meshface)
59 {
60 meshface.vertices[0] = read_bitu16(src);
61 meshface.vertices[1] = read_bitu16(src);
62 meshface.vertices[2] = read_bitu16(src);
63 meshface.vertices[3] = read_bitu16(src);
64 meshface.texture = read_bitu16(src);
65 meshface.lighting = read_bitu16(src);
66 }
67
read_tr4_room_light(SDL_RWops * const src,tr5_room_light_t & light)68 void TR_Level::read_tr4_room_light(SDL_RWops * const src, tr5_room_light_t & light)
69 {
70 read_tr_vertex32(src, light.pos);
71 read_tr_colour(src, light.color);
72 light.light_type = read_bitu8(src);
73 light.unknown = read_bitu8(src);
74 light.intensity1 = read_bitu8(src);
75 light.intensity = light.intensity1;
76 light.intensity /= 32;
77 light.r_inner = read_float(src);
78 light.r_outer = read_float(src);
79 light.length = read_float(src);
80 light.cutoff = read_float(src);
81 read_tr4_vertex_float(src, light.dir);
82 }
83
read_tr4_room_vertex(SDL_RWops * const src,tr5_room_vertex_t & room_vertex)84 void TR_Level::read_tr4_room_vertex(SDL_RWops * const src, tr5_room_vertex_t & room_vertex)
85 {
86 read_tr_vertex16(src, room_vertex.vertex);
87 // read and make consistent
88 room_vertex.lighting1 = read_bit16(src);
89 room_vertex.attributes = read_bitu16(src);
90 room_vertex.lighting2 = read_bit16(src);
91 // only in TR5
92 room_vertex.normal.x = 0;
93 room_vertex.normal.y = 0;
94 room_vertex.normal.z = 0;
95
96 room_vertex.colour.r = ((room_vertex.lighting2 & 0x7C00) >> 10 ) / 31.0f;
97 room_vertex.colour.g = ((room_vertex.lighting2 & 0x03E0) >> 5 ) / 31.0f;
98 room_vertex.colour.b = ((room_vertex.lighting2 & 0x001F) ) / 31.0f;
99 room_vertex.colour.a = 1.0f;
100 }
101
read_tr4_room_staticmesh(SDL_RWops * const src,tr2_room_staticmesh_t & room_static_mesh)102 void TR_Level::read_tr4_room_staticmesh(SDL_RWops * const src, tr2_room_staticmesh_t & room_static_mesh)
103 {
104 read_tr_vertex32(src, room_static_mesh.pos);
105 room_static_mesh.rotation = (float)read_bitu16(src) / 16384.0f * -90;
106 room_static_mesh.intensity1 = read_bit16(src);
107 room_static_mesh.intensity2 = read_bit16(src);
108 room_static_mesh.object_id = read_bitu16(src);
109
110 room_static_mesh.tint.r = ((room_static_mesh.intensity1 & 0x001F) ) / 31.0f;
111
112 room_static_mesh.tint.g = ((room_static_mesh.intensity1 & 0x03E0) >> 5 ) / 31.0f;
113
114 room_static_mesh.tint.b = ((room_static_mesh.intensity1 & 0x7C00) >> 10 ) / 31.0f;
115 room_static_mesh.tint.a = 1.0f;
116 }
117
read_tr4_room(SDL_RWops * const src,tr5_room_t & room)118 void TR_Level::read_tr4_room(SDL_RWops * const src, tr5_room_t & room)
119 {
120 uint32_t num_data_words;
121 uint32_t i;
122 int64_t pos;
123
124 // read and change coordinate system
125 room.offset.x = (float)read_bit32(src);
126 room.offset.y = 0;
127 room.offset.z = (float)-read_bit32(src);
128 room.y_bottom = (float)-read_bit32(src);
129 room.y_top = (float)-read_bit32(src);
130
131 num_data_words = read_bitu32(src);
132
133 pos = SDL_RWseek(src, 0, SEEK_CUR);
134
135 room.num_layers = 0;
136
137 room.num_vertices = read_bitu16(src);
138 room.vertices = (tr5_room_vertex_t*)calloc(room.num_vertices, sizeof(tr5_room_vertex_t));
139 for (i = 0; i < room.num_vertices; i++)
140 read_tr4_room_vertex(src, room.vertices[i]);
141
142 room.num_rectangles = read_bitu16(src);
143 room.rectangles = (tr4_face4_t*)malloc(room.num_rectangles * sizeof(tr4_face4_t));
144 for (i = 0; i < room.num_rectangles; i++)
145 read_tr_face4(src, room.rectangles[i]);
146
147 room.num_triangles = read_bitu16(src);
148 room.triangles = (tr4_face3_t*)malloc(room.num_triangles * sizeof(tr4_face3_t));
149 for (i = 0; i < room.num_triangles; i++)
150 read_tr_face3(src, room.triangles[i]);
151
152 room.num_sprites = read_bitu16(src);
153 room.sprites = (tr_room_sprite_t*)malloc(room.num_sprites * sizeof(tr_room_sprite_t));
154 for (i = 0; i < room.num_sprites; i++)
155 read_tr_room_sprite(src, room.sprites[i]);
156
157 // set to the right position in case that there is some unused data
158 SDL_RWseek(src, pos + (num_data_words * 2), SEEK_SET);
159
160 room.num_portals = read_bitu16(src);
161 room.portals = (tr_room_portal_t*)malloc(room.num_portals * sizeof(tr_room_portal_t));
162 for (i = 0; i < room.num_portals; i++)
163 read_tr_room_portal(src, room.portals[i]);
164
165 room.num_zsectors = read_bitu16(src);
166 room.num_xsectors = read_bitu16(src);
167 room.sector_list = (tr_room_sector_t*)malloc(room.num_zsectors * room.num_xsectors * sizeof(tr_room_sector_t));
168 for (i = 0; i < (uint32_t)(room.num_zsectors * room.num_xsectors); i++)
169 read_tr_room_sector(src, room.sector_list[i]);
170
171 room.light_colour.b = read_bitu8(src) / 255.0f;
172 room.light_colour.g = read_bitu8(src) / 255.0f;
173 room.light_colour.r = read_bitu8(src) / 255.0f;
174 room.light_colour.a = read_bitu8(src) / 255.0f;
175
176 // only in TR2
177 room.light_mode = 0;
178
179 room.num_lights = read_bitu16(src);
180 room.lights = (tr5_room_light_t*)malloc(room.num_lights * sizeof(tr5_room_light_t));
181 for (i = 0; i < room.num_lights; i++)
182 read_tr4_room_light(src, room.lights[i]);
183
184 room.num_static_meshes = read_bitu16(src);
185 room.static_meshes = (tr2_room_staticmesh_t*)malloc(room.num_static_meshes * sizeof(tr2_room_staticmesh_t));
186 for (i = 0; i < room.num_static_meshes; i++)
187 read_tr4_room_staticmesh(src, room.static_meshes[i]);
188
189 room.alternate_room = read_bit16(src);
190 room.flags = read_bitu16(src);
191
192 // Only in TR3-5
193
194 room.water_scheme = read_bitu8(src);
195 room.reverb_info = read_bitu8(src);
196
197 // Only in TR4-5
198
199 room.alternate_group = read_bitu8(src);
200 }
201
read_tr4_item(SDL_RWops * const src,tr2_item_t & item)202 void TR_Level::read_tr4_item(SDL_RWops * const src, tr2_item_t & item)
203 {
204 item.object_id = read_bit16(src);
205 item.room = read_bit16(src);
206 read_tr_vertex32(src, item.pos);
207 item.rotation = (float)read_bitu16(src) / 16384.0f * -90;
208 item.intensity1 = read_bitu16(src);
209 item.intensity2 = item.intensity1;
210 item.ocb = read_bitu16(src);
211 item.flags = read_bitu16(src);
212 }
213
read_tr4_object_texture_vert(SDL_RWops * const src,tr4_object_texture_vert_t & vert)214 void TR_Level::read_tr4_object_texture_vert(SDL_RWops * const src, tr4_object_texture_vert_t & vert)
215 {
216 vert.xcoordinate = read_bit8(src);
217 vert.xpixel = read_bitu8(src);
218 vert.ycoordinate = read_bit8(src);
219 vert.ypixel = read_bitu8(src);
220 if (vert.xcoordinate == 0)
221 vert.xcoordinate = 1;
222 if (vert.ycoordinate == 0)
223 vert.ycoordinate = 1;
224 }
225
read_tr4_object_texture(SDL_RWops * const src,tr4_object_texture_t & object_texture)226 void TR_Level::read_tr4_object_texture(SDL_RWops * const src, tr4_object_texture_t & object_texture)
227 {
228 object_texture.transparency_flags = read_bitu16(src);
229 object_texture.tile_and_flag = read_bitu16(src);
230 if ((object_texture.tile_and_flag & 0x7FFF) > 128)
231 Sys_extWarn("object_texture.tile > 128");
232
233 object_texture.flags = read_bitu16(src);
234 read_tr4_object_texture_vert(src, object_texture.vertices[0]);
235 read_tr4_object_texture_vert(src, object_texture.vertices[1]);
236 read_tr4_object_texture_vert(src, object_texture.vertices[2]);
237 read_tr4_object_texture_vert(src, object_texture.vertices[3]);
238 object_texture.unknown1 = read_bitu32(src);
239 object_texture.unknown2 = read_bitu32(src);
240 object_texture.x_size = read_bitu32(src);
241 object_texture.y_size = read_bitu32(src);
242 }
243
244 /*
245 * tr4 + sprite loading
246 */
read_tr4_sprite_texture(SDL_RWops * const src,tr_sprite_texture_t & sprite_texture)247 void TR_Level::read_tr4_sprite_texture(SDL_RWops * const src, tr_sprite_texture_t & sprite_texture)
248 {
249 int tx, ty, tw, th, tleft, tright, ttop, tbottom;
250
251 sprite_texture.tile = read_bitu16(src);
252 if (sprite_texture.tile > 128)
253 Sys_extWarn("sprite_texture.tile > 128");
254
255 tx = read_bitu8(src);
256 ty = read_bitu8(src);
257 tw = read_bitu16(src);
258 th = read_bitu16(src);
259 tleft = read_bit16(src);
260 ttop = read_bit16(src);
261 tright = read_bit16(src);
262 tbottom = read_bit16(src);
263
264 sprite_texture.x0 = tleft;
265 sprite_texture.x1 = tright;
266 sprite_texture.y0 = tbottom;
267 sprite_texture.y1 = ttop;
268
269 sprite_texture.left_side = tx;
270 sprite_texture.right_side = tx + tw / (256);
271 sprite_texture.bottom_side = ty;
272 sprite_texture.top_side = ty + th / (256);
273 }
274
read_tr4_mesh(SDL_RWops * const src,tr4_mesh_t & mesh)275 void TR_Level::read_tr4_mesh(SDL_RWops * const src, tr4_mesh_t & mesh)
276 {
277 int i;
278
279 read_tr_vertex16(src, mesh.centre);
280 mesh.collision_size = read_bit16(src);
281 mesh.flags = read_bitu8(src);
282 mesh.dummy = read_bitu8(src);
283
284 mesh.num_vertices = read_bit16(src);
285 mesh.vertices = (tr5_vertex_t*)malloc(mesh.num_vertices * sizeof(tr5_vertex_t));
286 for (i = 0; i < mesh.num_vertices; i++)
287 read_tr_vertex16(src, mesh.vertices[i]);
288
289 mesh.num_normals = read_bit16(src);
290 if (mesh.num_normals >= 0)
291 {
292 mesh.num_lights = 0;
293 mesh.normals = (tr5_vertex_t*)malloc(mesh.num_normals * sizeof(tr5_vertex_t));
294 for (i = 0; i < mesh.num_normals; i++)
295 read_tr_vertex16(src, mesh.normals[i]);
296 }
297 else
298 {
299 mesh.num_lights = -mesh.num_normals;
300 mesh.num_normals = 0;
301 mesh.lights = (int16_t*)malloc(mesh.num_lights * sizeof(int16_t));
302 for (i = 0; i < mesh.num_lights; i++)
303 mesh.lights[i] = read_bit16(src);
304 }
305
306 mesh.num_textured_rectangles = read_bit16(src);
307 mesh.textured_rectangles = (tr4_face4_t*)malloc(mesh.num_textured_rectangles * sizeof(tr4_face4_t));
308 for (i = 0; i < mesh.num_textured_rectangles; i++)
309 read_tr4_face4(src, mesh.textured_rectangles[i]);
310
311 mesh.num_textured_triangles = read_bit16(src);
312 mesh.textured_triangles = (tr4_face3_t*)malloc(mesh.num_textured_triangles * sizeof(tr4_face3_t));
313 for (i = 0; i < mesh.num_textured_triangles; i++)
314 read_tr4_face3(src, mesh.textured_triangles[i]);
315
316 mesh.num_coloured_rectangles = 0;
317 mesh.num_coloured_triangles = 0;
318 }
319
320 /// \brief reads an animation definition.
read_tr4_animation(SDL_RWops * const src,tr_animation_t & animation)321 void TR_Level::read_tr4_animation(SDL_RWops * const src, tr_animation_t & animation)
322 {
323 animation.frame_offset = read_bitu32(src);
324 animation.frame_rate = read_bitu8(src);
325 animation.frame_size = read_bitu8(src);
326 animation.state_id = read_bitu16(src);
327
328 animation.speed = read_mixfloat(src);
329 animation.accel = read_mixfloat(src);
330 animation.speed_lateral = read_mixfloat(src);
331 animation.accel_lateral = read_mixfloat(src);
332
333 animation.frame_start = read_bitu16(src);
334 animation.frame_end = read_bitu16(src);
335 animation.next_animation = read_bitu16(src);
336 animation.next_frame = read_bitu16(src);
337
338 animation.num_state_changes = read_bitu16(src);
339 animation.state_change_offset = read_bitu16(src);
340 animation.num_anim_commands = read_bitu16(src);
341 animation.anim_command = read_bitu16(src);
342 }
343
read_tr4_level(SDL_RWops * const _src)344 void TR_Level::read_tr4_level(SDL_RWops * const _src)
345 {
346 SDL_RWops *src = _src;
347 uint32_t i;
348 uint8_t *uncomp_buffer = NULL;
349 uint8_t *comp_buffer = NULL;
350 SDL_RWops *newsrc = NULL;
351
352 // Version
353 uint32_t file_version = read_bitu32(src);
354
355 if (file_version != 0x00345254 /*&& file_version != 0x63345254*/) // +TRLE
356 Sys_extError("Wrong level version");
357
358 this->num_textiles = 0;
359 this->num_room_textiles = 0;
360 this->num_obj_textiles = 0;
361 this->num_bump_textiles = 0;
362 this->num_misc_textiles = 0;
363 this->read_32bit_textiles = false;
364
365 {
366 uint32_t uncomp_size;
367 uint32_t comp_size;
368 unsigned long size;
369
370 this->num_room_textiles = read_bitu16(src);
371 this->num_obj_textiles = read_bitu16(src);
372 this->num_bump_textiles = read_bitu16(src);
373 this->num_misc_textiles = 2;
374 this->num_textiles = this->num_room_textiles + this->num_obj_textiles + this->num_bump_textiles + this->num_misc_textiles;
375
376 uncomp_size = read_bitu32(src);
377 if (uncomp_size == 0)
378 Sys_extError("read_tr4_level: textiles32 uncomp_size == 0");
379
380 comp_size = read_bitu32(src);
381 if (comp_size > 0)
382 {
383 uncomp_buffer = new uint8_t[uncomp_size];
384
385 this->textile32_count = this->num_textiles;
386 this->textile32 = (tr4_textile32_t*)malloc(this->textile32_count * sizeof(tr4_textile32_t));
387 comp_buffer = new uint8_t[comp_size];
388
389 if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
390 Sys_extError("read_tr4_level: textiles32");
391
392 size = uncomp_size;
393 if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
394 Sys_extError("read_tr4_level: uncompress");
395
396 if (size != uncomp_size)
397 Sys_extError("read_tr4_level: uncompress size mismatch");
398 delete [] comp_buffer;
399
400 comp_buffer = NULL;
401 if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
402 Sys_extError("read_tr4_level: SDL_RWFromMem");
403
404 for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++)
405 read_tr4_textile32(newsrc, this->textile32[i]);
406 SDL_RWclose(newsrc);
407 newsrc = NULL;
408 delete [] uncomp_buffer;
409
410 uncomp_buffer = NULL;
411 this->read_32bit_textiles = true;
412 }
413
414 uncomp_size = read_bitu32(src);
415 if (uncomp_size == 0)
416 Sys_extError("read_tr4_level: textiles16 uncomp_size == 0");
417
418 comp_size = read_bitu32(src);
419 if (comp_size > 0)
420 {
421 if (this->textile32_count == 0)
422 {
423 uncomp_buffer = new uint8_t[uncomp_size];
424
425 this->textile16_count = this->num_textiles;
426 this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t));
427 comp_buffer = new uint8_t[comp_size];
428
429 if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
430 {
431 delete [] comp_buffer;
432 delete [] uncomp_buffer;
433 Sys_extError("read_tr4_level: textiles16");
434 }
435
436 size = uncomp_size;
437 if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
438 {
439 delete [] comp_buffer;
440 delete [] uncomp_buffer;
441 Sys_extError("read_tr4_level: uncompress");
442 }
443
444 delete [] comp_buffer;
445 comp_buffer = NULL;
446
447 if (size != uncomp_size)
448 {
449 delete [] uncomp_buffer;
450 Sys_extError("read_tr4_level: uncompress size mismatch");
451 }
452
453 if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
454 {
455 delete [] uncomp_buffer;
456 Sys_extError("read_tr4_level: SDL_RWFromMem");
457 }
458
459 for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++)
460 read_tr2_textile16(newsrc, this->textile16[i]);
461
462 SDL_RWclose(newsrc);
463 newsrc = NULL;
464 delete [] uncomp_buffer;
465 uncomp_buffer = NULL;
466 }
467 else
468 {
469 SDL_RWseek(src, comp_size, SEEK_CUR);
470 }
471 }
472
473 uncomp_size = read_bitu32(src);
474 if (uncomp_size == 0)
475 Sys_extError("read_tr4_level: textiles32d uncomp_size == 0");
476
477 comp_size = read_bitu32(src);
478 if (comp_size > 0)
479 {
480 uncomp_buffer = new uint8_t[uncomp_size];
481
482 if ((uncomp_size / (256 * 256 * 4)) > 2)
483 Sys_extWarn("read_tr4_level: num_misc_textiles > 2");
484
485 if (this->textile32_count == 0)
486 {
487 this->textile32_count = this->num_textiles;
488 this->textile32 = (tr4_textile32_t*)malloc(this->textile32_count * sizeof(tr4_textile32_t));
489 }
490 comp_buffer = new uint8_t[comp_size];
491
492 if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
493 {
494 delete [] uncomp_buffer;
495 delete [] comp_buffer;
496 Sys_extError("read_tr4_level: misc_textiles");
497 }
498
499 size = uncomp_size;
500 if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
501 {
502 delete [] uncomp_buffer;
503 delete [] comp_buffer;
504 Sys_extError("read_tr4_level: uncompress");
505 }
506
507 delete [] comp_buffer;
508 comp_buffer = NULL;
509 if (size != uncomp_size)
510 {
511 delete [] uncomp_buffer;
512 Sys_extError("read_tr4_level: uncompress size mismatch");
513 }
514
515 if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
516 {
517 delete [] uncomp_buffer;
518 Sys_extError("read_tr4_level: SDL_RWFromMem");
519 }
520
521 for (i = (this->num_textiles - this->num_misc_textiles); i < this->num_textiles; i++)
522 read_tr4_textile32(newsrc, this->textile32[i]);
523
524 SDL_RWclose(newsrc);
525 newsrc = NULL;
526 delete [] uncomp_buffer;
527 uncomp_buffer = NULL;
528 }
529
530 uncomp_size = read_bitu32(src);
531 if (uncomp_size == 0)
532 Sys_extError("read_tr4_level: packed geometry uncomp_size == 0");
533
534 comp_size = read_bitu32(src);
535
536 if (!comp_size)
537 Sys_extError("read_tr4_level: packed geometry");
538
539 uncomp_buffer = new uint8_t[uncomp_size];
540 comp_buffer = new uint8_t[comp_size];
541
542 if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size)
543 {
544 delete [] uncomp_buffer;
545 delete [] comp_buffer;
546 Sys_extError("read_tr4_level: packed geometry");
547 }
548
549 size = uncomp_size;
550 if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK)
551 {
552 delete [] uncomp_buffer;
553 delete [] comp_buffer;
554 Sys_extError("read_tr4_level: uncompress");
555 }
556
557 delete [] comp_buffer;
558 comp_buffer = NULL;
559 if (size != uncomp_size)
560 {
561 delete [] uncomp_buffer;
562 Sys_extError("read_tr4_level: uncompress size mismatch");
563 }
564
565 if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL)
566 {
567 delete [] uncomp_buffer;
568 Sys_extError("read_tr4_level: SDL_RWFromMem");
569 }
570 }
571
572 // Unused
573 if (read_bitu32(newsrc) != 0)
574 Sys_extWarn("Bad value for 'unused'");
575
576 this->rooms_count = read_bitu16(newsrc);
577 this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t));
578 for (i = 0; i < this->rooms_count; i++)
579 read_tr4_room(newsrc, this->rooms[i]);
580
581 this->floor_data_size = read_bitu32(newsrc);
582 this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t));
583 for(i = 0; i < this->floor_data_size; i++)
584 this->floor_data[i] = read_bitu16(newsrc);
585
586 read_mesh_data(newsrc);
587
588 this->animations_count = read_bitu32(newsrc);
589 this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t));
590 for (i = 0; i < this->animations_count; i++)
591 read_tr4_animation(newsrc, this->animations[i]);
592
593 this->state_changes_count = read_bitu32(newsrc);
594 this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t));
595 for (i = 0; i < this->state_changes_count; i++)
596 read_tr_state_changes(newsrc, this->state_changes[i]);
597
598 this->anim_dispatches_count = read_bitu32(newsrc);
599 this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t));
600 for (i = 0; i < this->anim_dispatches_count; i++)
601 read_tr_anim_dispatches(newsrc, this->anim_dispatches[i]);
602
603 this->anim_commands_count = read_bitu32(newsrc);
604 this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t));
605 for (i = 0; i < this->anim_commands_count; i++)
606 this->anim_commands[i] = read_bit16(newsrc);
607
608 this->mesh_tree_data_size = read_bitu32(newsrc);
609 this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t));
610 for (i = 0; i < this->mesh_tree_data_size; i++)
611 this->mesh_tree_data[i] = read_bitu32(newsrc); // 4 bytes
612
613 read_frame_moveable_data(newsrc);
614
615 this->static_meshes_count = read_bitu32(newsrc);
616 this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t));
617 for (i = 0; i < this->static_meshes_count; i++)
618 read_tr_staticmesh(newsrc, this->static_meshes[i]);
619
620 if (read_bit8(newsrc) != 'S')
621 Sys_extError("read_tr4_level: 'SPR' not found");
622
623 if (read_bit8(newsrc) != 'P')
624 Sys_extError("read_tr4_level: 'SPR' not found");
625
626 if (read_bit8(newsrc) != 'R')
627 Sys_extError("read_tr4_level: 'SPR' not found");
628
629 this->sprite_textures_count = read_bitu32(newsrc);
630 this->sprite_textures = (tr_sprite_texture_t*)malloc(this->sprite_textures_count * sizeof(tr_sprite_texture_t));
631 for (i = 0; i < this->sprite_textures_count; i++)
632 read_tr4_sprite_texture(newsrc, this->sprite_textures[i]);
633
634 this->sprite_sequences_count = read_bitu32(newsrc);
635 this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t));
636 for (i = 0; i < this->sprite_sequences_count; i++)
637 read_tr_sprite_sequence(newsrc, this->sprite_sequences[i]);
638
639 this->cameras_count = read_bitu32(newsrc);
640 this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t));
641 for (i = 0; i < this->cameras_count; i++)
642 {
643 this->cameras[i].x = read_bit32(newsrc);
644 this->cameras[i].y = read_bit32(newsrc);
645 this->cameras[i].z = read_bit32(newsrc);
646
647 this->cameras[i].room = read_bit16(newsrc);
648 this->cameras[i].unknown1 = read_bitu16(newsrc);
649 }
650 //SDL_RWseek(newsrc, this->cameras.size() * 16, SEEK_CUR);
651
652 this->flyby_cameras_count = read_bitu32(newsrc);
653 this->flyby_cameras = (tr4_flyby_camera_t*)malloc(this->flyby_cameras_count * sizeof(tr4_flyby_camera_t));
654 for (i = 0; i < this->flyby_cameras_count; i++)
655 {
656 this->flyby_cameras[i].pos_x = read_bit32(newsrc);
657 this->flyby_cameras[i].pos_y = read_bit32(newsrc);
658 this->flyby_cameras[i].pos_z = read_bit32(newsrc);
659 this->flyby_cameras[i].target_x = read_bit32(newsrc);
660 this->flyby_cameras[i].target_y = read_bit32(newsrc);
661 this->flyby_cameras[i].target_z = read_bit32(newsrc);
662
663 this->flyby_cameras[i].sequence = read_bit8(newsrc);
664 this->flyby_cameras[i].index = read_bit8(newsrc);
665
666 this->flyby_cameras[i].fov = read_bitu16(newsrc);
667 this->flyby_cameras[i].roll = read_bitu16(newsrc);
668 this->flyby_cameras[i].timer = read_bitu16(newsrc);
669 this->flyby_cameras[i].speed = read_bitu16(newsrc);
670 this->flyby_cameras[i].flags = read_bitu16(newsrc);
671
672 this->flyby_cameras[i].room_id = read_bit32(newsrc);
673 }
674
675 this->sound_sources_count = read_bitu32(newsrc);
676 this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t));
677 for(i = 0; i < this->sound_sources_count; i++)
678 {
679 this->sound_sources[i].x = read_bit32(newsrc);
680 this->sound_sources[i].y = read_bit32(newsrc);
681 this->sound_sources[i].z = read_bit32(newsrc);
682
683 this->sound_sources[i].sound_id = read_bitu16(newsrc);
684 this->sound_sources[i].flags = read_bitu16(newsrc);
685 }
686
687 this->boxes_count = read_bitu32(newsrc);
688 this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t));
689 this->zones = (tr2_zone_t*)malloc(this->boxes_count * sizeof(tr2_zone_t));
690 for (i = 0; i < this->boxes_count; i++)
691 read_tr2_box(newsrc, this->boxes[i]);
692
693 this->overlaps_count = read_bitu32(newsrc);
694 this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t));
695 for (i = 0; i < this->overlaps_count; i++)
696 this->overlaps[i] = read_bitu16(newsrc);
697
698 // Zones
699 for (i = 0; i < this->boxes_count; i++)
700 read_tr2_zone(newsrc, this->zones[i]);
701
702 this->animated_textures_count = read_bitu32(newsrc);
703 this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t));
704 for (i = 0; i < this->animated_textures_count; i++)
705 {
706 this->animated_textures[i] = read_bitu16(newsrc);
707 }
708
709 this->animated_textures_uv_count = read_bitu8(newsrc);
710
711 if (read_bit8(newsrc) != 'T')
712 Sys_extError("read_tr4_level: '\\0TEX' not found");
713
714 if (read_bit8(newsrc) != 'E')
715 Sys_extError("read_tr4_level: '\\0TEX' not found");
716
717 if (read_bit8(newsrc) != 'X')
718 Sys_extError("read_tr4_level: '\\0TEX' not found");
719
720 this->object_textures_count = read_bitu32(newsrc);
721 this->object_textures = (tr4_object_texture_t*)malloc(this->object_textures_count * sizeof(tr4_object_texture_t));
722 for (i = 0; i < this->object_textures_count; i++)
723 read_tr4_object_texture(newsrc, this->object_textures[i]);
724
725 this->items_count = read_bitu32(newsrc);
726 this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t));
727 for (i = 0; i < this->items_count; i++)
728 read_tr4_item(newsrc, this->items[i]);
729
730 this->ai_objects_count = read_bitu32(newsrc);
731 this->ai_objects = (tr4_ai_object_t*)malloc(this->ai_objects_count * sizeof(tr4_ai_object_t));
732 for(i=0; i < this->ai_objects_count; i++)
733 {
734 this->ai_objects[i].object_id = read_bitu16(newsrc);
735 this->ai_objects[i].room = read_bitu16(newsrc); // 4
736
737 this->ai_objects[i].x = read_bit32(newsrc);
738 this->ai_objects[i].y = read_bit32(newsrc);
739 this->ai_objects[i].z = read_bit32(newsrc); // 16
740
741 this->ai_objects[i].ocb = read_bitu16(newsrc);
742 this->ai_objects[i].flags = read_bitu16(newsrc); // 20
743 this->ai_objects[i].angle = read_bit32(newsrc); // 24
744 }
745
746 this->demo_data_count = read_bitu16(newsrc);
747 this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t));
748 for(i=0; i < this->demo_data_count; i++)
749 this->demo_data[i] = read_bitu8(newsrc);
750
751 // Soundmap
752 this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR4 * sizeof(int16_t));
753 for(i=0; i < TR_AUDIO_MAP_SIZE_TR4; i++)
754 this->soundmap[i] = read_bit16(newsrc);
755
756 this->sound_details_count = 0;
757 i = read_bitu32(newsrc);
758 if(i)
759 {
760 this->sound_details_count = i;
761
762 this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t));
763 for(i=0; i < this->sound_details_count; i++)
764 {
765 this->sound_details[i].sample = read_bitu16(newsrc);
766 this->sound_details[i].volume = (uint16_t)read_bitu8(newsrc); // n x 2.6
767 this->sound_details[i].sound_range = (uint16_t)read_bitu8(newsrc); // n as is
768 this->sound_details[i].chance = (uint16_t)read_bitu8(newsrc); // If n = 99, n = 0 (max. chance)
769 this->sound_details[i].pitch = (int16_t)read_bit8(newsrc); // n as is
770 this->sound_details[i].num_samples_and_flags_1 = read_bitu8(newsrc);
771 this->sound_details[i].flags_2 = read_bitu8(newsrc);
772 }
773 }
774
775 // IMPORTANT NOTE: Sample indices ARE NOT USED in TR4 engine, but are parsed anyway.
776 i = read_bitu32(newsrc);
777 if(i)
778 {
779 this->sample_indices_count = i;
780
781 this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t));
782 for(i=0; i < this->sample_indices_count; i++)
783 this->sample_indices[i] = read_bitu32(newsrc);
784 }
785 else
786 {
787 this->sample_indices_count = 0;
788 this->sample_indices = NULL;
789 }
790
791 SDL_RWclose(newsrc);
792 newsrc = NULL;
793 delete [] uncomp_buffer;
794 uncomp_buffer = NULL;
795
796 // LOAD SAMPLES
797
798 this->samples_count = read_bitu32(src); // Read num samples
799 if(this->samples_count)
800 {
801 // Since sample data is the last part, we simply load whole last
802 // block of file as single array.
803 this->samples_data_size = (uint32_t) (SDL_RWsize(src) - SDL_RWtell(src));
804 this->samples_data = (uint8_t*)malloc(this->samples_data_size * sizeof(uint8_t));
805 for(i = 0; i < this->samples_data_size; i++)
806 this->samples_data[i] = read_bitu8(src);
807 }
808 }
809