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