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.h>
23 
24 #include "l_main.h"
25 #include "../core/system.h"
26 
27 #define RCSID "$Id: l_tr1.cpp,v 1.16 2002/09/20 15:59:02 crow Exp $"
28 
29 /** \brief reads rgb colour.
30   *
31   * Reads three rgb colour components. The read 6-bit values get shifted, so they are 8-bit.
32   * The alpha value of tr2_colour_t gets set to 0.
33   */
read_tr_colour(SDL_RWops * const src,tr2_colour_t & colour)34 void TR_Level::read_tr_colour(SDL_RWops * const src, tr2_colour_t & colour)
35 {
36     // read 6 bit color and change to 8 bit
37     colour.r = read_bitu8(src) << 2;
38     colour.g = read_bitu8(src) << 2;
39     colour.b = read_bitu8(src) << 2;
40     colour.a = 0;
41 }
42 
43 /** \brief reads three 16-bit vertex components.
44   *
45   * The values get converted from bit16 to float. y and z are negated to fit OpenGLs coordinate system.
46   */
read_tr_vertex16(SDL_RWops * const src,tr5_vertex_t & vertex)47 void TR_Level::read_tr_vertex16(SDL_RWops * const src, tr5_vertex_t & vertex)
48 {
49     // read vertex and change coordinate system
50     vertex.x = (float)read_bit16(src);
51     vertex.y = (float)-read_bit16(src);
52     vertex.z = (float)-read_bit16(src);
53 }
54 
55 /** \brief reads three 32-bit vertex components.
56   *
57   * The values get converted from bit32 to float. y and z are negated to fit OpenGLs coordinate system.
58   */
read_tr_vertex32(SDL_RWops * const src,tr5_vertex_t & vertex)59 void TR_Level::read_tr_vertex32(SDL_RWops * const src, tr5_vertex_t & vertex)
60 {
61     // read vertex and change coordinate system
62     vertex.x = (float)read_bit32(src);
63     vertex.y = (float)-read_bit32(src);
64     vertex.z = (float)-read_bit32(src);
65 }
66 
67 /** \brief reads a triangle definition.
68   *
69   * The lighting value is set to 0, as it is only in TR4-5.
70   */
read_tr_face3(SDL_RWops * const src,tr4_face3_t & meshface)71 void TR_Level::read_tr_face3(SDL_RWops * const src, tr4_face3_t & meshface)
72 {
73     meshface.vertices[0] = read_bitu16(src);
74     meshface.vertices[1] = read_bitu16(src);
75     meshface.vertices[2] = read_bitu16(src);
76     meshface.texture = read_bitu16(src);
77     // lighting only in TR4-5
78     meshface.lighting = 0;
79 }
80 
81 /** \brief reads a triangle definition.
82   *
83   * The lighting value is set to 0, as it is only in TR4-5.
84   */
read_tr_face4(SDL_RWops * const src,tr4_face4_t & meshface)85 void TR_Level::read_tr_face4(SDL_RWops * const src, tr4_face4_t & meshface)
86 {
87     meshface.vertices[0] = read_bitu16(src);
88     meshface.vertices[1] = read_bitu16(src);
89     meshface.vertices[2] = read_bitu16(src);
90     meshface.vertices[3] = read_bitu16(src);
91     meshface.texture = read_bitu16(src);
92     // only in TR4-TR5
93     meshface.lighting = 0;
94 }
95 
96 /// \brief reads a 8-bit 256x256 textile.
read_tr_textile8(SDL_RWops * const src,tr_textile8_t & textile)97 void TR_Level::read_tr_textile8(SDL_RWops * const src, tr_textile8_t & textile)
98 {
99     for (int i = 0; i < 256; i++)
100         if (SDL_RWread(src, textile.pixels[i], 1, 256) < 256)
101                         Sys_extError("read_tr_textile8");
102 }
103 
104 /// \brief reads the lightmap.
read_tr_lightmap(SDL_RWops * const src,tr_lightmap_t & lightmap)105 void TR_Level::read_tr_lightmap(SDL_RWops * const src, tr_lightmap_t & lightmap)
106 {
107     for (int i = 0; i < (32 * 256); i++)
108         lightmap.map[i] = read_bitu8(src);
109 }
110 
111 /// \brief reads the 256 colour palette values.
read_tr_palette(SDL_RWops * const src,tr2_palette_t & palette)112 void TR_Level::read_tr_palette(SDL_RWops * const src, tr2_palette_t & palette)
113 {
114     for (int i = 0; i < 256; i++)
115         read_tr_colour(src, palette.colour[i]);
116 }
117 
read_tr_box(SDL_RWops * const src,tr_box_t & box)118 void TR_Level::read_tr_box(SDL_RWops * const src, tr_box_t & box)
119 {
120     box.zmax =-read_bit32(src);
121     box.zmin =-read_bit32(src);
122     box.xmin = read_bit32(src);
123     box.xmax = read_bit32(src);
124     box.true_floor =-read_bit16(src);
125     box.overlap_index = read_bitu16(src);
126 }
127 
read_tr_zone(SDL_RWops * const src,tr2_zone_t & zone)128 void TR_Level::read_tr_zone(SDL_RWops * const src, tr2_zone_t & zone)
129 {
130     zone.GroundZone1_Normal = read_bit16(src);
131     zone.GroundZone2_Normal = read_bit16(src);
132     zone.GroundZone3_Normal = -1;
133     zone.GroundZone4_Normal = -1;
134     zone.FlyZone_Normal = read_bit16(src);
135     zone.GroundZone1_Alternate = read_bit16(src);
136     zone.GroundZone2_Alternate = read_bit16(src);
137     zone.GroundZone3_Alternate = -1;
138     zone.GroundZone4_Alternate = -1;
139     zone.FlyZone_Alternate = read_bit16(src);
140 }
141 
142 /// \brief reads a room sprite definition.
read_tr_room_sprite(SDL_RWops * const src,tr_room_sprite_t & room_sprite)143 void TR_Level::read_tr_room_sprite(SDL_RWops * const src, tr_room_sprite_t & room_sprite)
144 {
145     room_sprite.vertex = read_bit16(src);
146     room_sprite.texture = read_bit16(src);
147 }
148 
149 /** \brief reads a room portal definition.
150   *
151   * A check is preformed to see wether the normal lies on a coordinate axis, if not an exception gets thrown.
152   */
read_tr_room_portal(SDL_RWops * const src,tr_room_portal_t & portal)153 void TR_Level::read_tr_room_portal(SDL_RWops * const src, tr_room_portal_t & portal)
154 {
155     portal.adjoining_room = read_bitu16(src);
156     read_tr_vertex16(src, portal.normal);
157     read_tr_vertex16(src, portal.vertices[0]);
158     read_tr_vertex16(src, portal.vertices[1]);
159     read_tr_vertex16(src, portal.vertices[2]);
160     read_tr_vertex16(src, portal.vertices[3]);
161     if ((portal.normal.x == 1.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == 0.0f))
162         return;
163     if ((portal.normal.x == -1.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == 0.0f))
164         return;
165     if ((portal.normal.x == 0.0f) && (portal.normal.y == 1.0f) && (portal.normal.z == 0.0f))
166         return;
167     if ((portal.normal.x == 0.0f) && (portal.normal.y == -1.0f) && (portal.normal.z == 0.0f))
168         return;
169     if ((portal.normal.x == 0.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == 1.0f))
170         return;
171     if ((portal.normal.x == 0.0f) && (portal.normal.y == 0.0f) && (portal.normal.z == -1.0f))
172         return;
173         Sys_extWarn("read_tr_room_portal: normal not on world axis");
174 }
175 
176 /// \brief reads a room sector definition.
read_tr_room_sector(SDL_RWops * const src,tr_room_sector_t & sector)177 void TR_Level::read_tr_room_sector(SDL_RWops * const src, tr_room_sector_t & sector)
178 {
179     sector.fd_index = read_bitu16(src);
180     sector.box_index = read_bitu16(src);
181     sector.room_below = read_bitu8(src);
182     sector.floor = read_bit8(src);
183     sector.room_above = read_bitu8(src);
184     sector.ceiling = read_bit8(src);
185 }
186 
187 /** \brief reads a room light definition.
188   *
189   * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
190   * intensity2 and fade2 are introduced in TR2 and are set to intensity1 and fade1 for TR1.
191   */
read_tr_room_light(SDL_RWops * const src,tr5_room_light_t & light)192 void TR_Level::read_tr_room_light(SDL_RWops * const src, tr5_room_light_t & light)
193 {
194     read_tr_vertex32(src, light.pos);
195     // read and make consistent
196     float data = read_bitu16(src);
197     data = data < 0.0f || data > 8191.0f ? 0.0f : data;
198 
199     light.intensity1 = (8191 - data);
200 
201     light.fade1 = read_bitu32(src);
202     // only in TR2
203     light.intensity2 = light.intensity1;
204 
205     light.intensity = light.intensity1 / 8191.0f;
206 
207     if(light.intensity == 0.0f || light.intensity > 1.0f)
208         light.intensity = 1.0f;
209 
210     light.fade2 = light.fade1;
211 
212     light.r_outer = light.fade1;
213     light.r_inner = light.fade1 / 2;
214 
215     light.light_type = 0x01; // Point light
216 
217     // all white
218     light.color.r = 0xff;
219     light.color.g = 0xff;
220     light.color.b = 0xff;
221 }
222 
223 /** \brief reads a room vertex definition.
224   *
225   * lighting1 gets converted, so it matches the 0-32768 range introduced in TR3.
226   * lighting2 is introduced in TR2 and is set to lighting1 for TR1.
227   * attributes is introduced in TR2 and is set 0 for TR1.
228   * All other values are introduced in TR5 and get set to appropiate values.
229   */
read_tr_room_vertex(SDL_RWops * const src,tr5_room_vertex_t & room_vertex)230 void TR_Level::read_tr_room_vertex(SDL_RWops * const src, tr5_room_vertex_t & room_vertex)
231 {
232     read_tr_vertex16(src, room_vertex.vertex);
233     // read and make consistent
234     float data = read_bitu16(src);
235     data = data < 0.0f || data > 8191.0f ? 0.0f : data;
236 
237     room_vertex.lighting1 = (8191 - data);
238 
239 
240     // only in TR2
241     room_vertex.lighting2 = room_vertex.lighting1;
242     room_vertex.attributes = 0;
243     // only in TR5
244     room_vertex.normal.x = 0;
245     room_vertex.normal.y = 0;
246     room_vertex.normal.z = 0;
247     room_vertex.colour.r = room_vertex.lighting1 / 8191.0f;
248     room_vertex.colour.g = room_vertex.lighting1 / 8191.0f;
249     room_vertex.colour.b = room_vertex.lighting1 / 8191.0f;
250     room_vertex.colour.a = 1.0f;
251 }
252 
253 /** \brief reads a room staticmesh definition.
254   *
255   * rotation gets converted to float and scaled appropiatly.
256   * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
257   * intensity2 is introduced in TR2 and is set to intensity1 for TR1.
258   */
read_tr_room_staticmesh(SDL_RWops * const src,tr2_room_staticmesh_t & room_static_mesh)259 void TR_Level::read_tr_room_staticmesh(SDL_RWops * const src, tr2_room_staticmesh_t & room_static_mesh)
260 {
261     read_tr_vertex32(src, room_static_mesh.pos);
262     room_static_mesh.rotation = (float)read_bitu16(src) / 16384.0f * -90;
263     room_static_mesh.intensity1 = read_bit16(src);
264     room_static_mesh.object_id = read_bitu16(src);
265     // make consistent
266     if (room_static_mesh.intensity1 >= 0)
267         room_static_mesh.intensity1 = (8191 - room_static_mesh.intensity1) << 2;
268     // only in TR2
269     room_static_mesh.intensity2 = room_static_mesh.intensity1;
270 
271     room_static_mesh.tint.b = room_static_mesh.tint.g = room_static_mesh.tint.r = (room_static_mesh.intensity2 / 16384.0f);
272     room_static_mesh.tint.a = 1.0f;
273 }
274 
275 /** \brief reads a room definition.
276   *
277   * intensity1 gets converted, so it matches the 0-32768 range introduced in TR3.
278   * intensity2 is introduced in TR2 and is set to intensity1 for TR1.
279   * light_mode is only in TR2 and is set 0 for TR1.
280   * light_colour is only in TR3-4 and gets set appropiatly.
281   */
read_tr_room(SDL_RWops * const src,tr5_room_t & room)282 void TR_Level::read_tr_room(SDL_RWops * const src, tr5_room_t & room)
283 {
284     uint32_t num_data_words;
285     uint32_t i;
286     int64_t pos;
287 
288     // read and change coordinate system
289     room.offset.x = (float)read_bit32(src);
290     room.offset.y = 0;
291     room.offset.z = (float)-read_bit32(src);
292     room.y_bottom = (float)-read_bit32(src);
293     room.y_top = (float)-read_bit32(src);
294 
295     num_data_words = read_bitu32(src);
296 
297     pos = SDL_RWseek(src, 0, RW_SEEK_CUR);
298 
299     room.num_layers = 0;
300 
301     room.num_vertices = read_bitu16(src);
302     room.vertices = (tr5_room_vertex_t*)calloc(room.num_vertices, sizeof(tr5_room_vertex_t));
303     for (i = 0; i < room.num_vertices; i++)
304         read_tr_room_vertex(src, room.vertices[i]);
305 
306     room.num_rectangles = read_bitu16(src);
307         room.rectangles = (tr4_face4_t*)malloc(room.num_rectangles * sizeof(tr4_face4_t));
308     for (i = 0; i < room.num_rectangles; i++)
309         read_tr_face4(src, room.rectangles[i]);
310 
311     room.num_triangles = read_bitu16(src);
312     room.triangles = (tr4_face3_t*)malloc(room.num_triangles * sizeof(tr4_face3_t));
313     for (i = 0; i < room.num_triangles; i++)
314         read_tr_face3(src, room.triangles[i]);
315 
316     room.num_sprites = read_bitu16(src);
317     room.sprites = (tr_room_sprite_t*)malloc(room.num_sprites * sizeof(tr_room_sprite_t));
318     for (i = 0; i < room.num_sprites; i++)
319         read_tr_room_sprite(src, room.sprites[i]);
320 
321     // set to the right position in case that there is some unused data
322     SDL_RWseek(src, pos + (num_data_words * 2), RW_SEEK_SET);
323 
324     room.num_portals = read_bitu16(src);
325     room.portals = (tr_room_portal_t*)malloc(room.num_portals * sizeof(tr_room_portal_t));
326     for (i = 0; i < room.num_portals; i++)
327         read_tr_room_portal(src, room.portals[i]);
328 
329     room.num_zsectors = read_bitu16(src);
330     room.num_xsectors = read_bitu16(src);
331     room.sector_list = (tr_room_sector_t*)malloc(room.num_zsectors * room.num_xsectors * sizeof(tr_room_sector_t));
332     for (i = 0; i < (uint32_t)(room.num_zsectors * room.num_xsectors); i++)
333         read_tr_room_sector(src, room.sector_list[i]);
334 
335     // read and make consistent
336     float roomIntensity = read_bit16(src);
337     roomIntensity = (roomIntensity < 0.0f || roomIntensity > 8191.0f) ? 0.0f : roomIntensity;
338 
339     room.intensity1 = roomIntensity;
340     // only in TR2-TR4
341     room.intensity2 = room.intensity1;
342     // only in TR2
343     room.light_mode = 0;
344 
345     roomIntensity /= 16384.0f;
346 
347     room.num_lights = read_bitu16(src);
348     room.lights = (tr5_room_light_t*)malloc(room.num_lights * sizeof(tr5_room_light_t));
349     for (i = 0; i < room.num_lights; i++)
350         read_tr_room_light(src, room.lights[i]);
351 
352     room.num_static_meshes = read_bitu16(src);
353     room.static_meshes = (tr2_room_staticmesh_t*)malloc(room.num_static_meshes * sizeof(tr2_room_staticmesh_t));
354     for (i = 0; i < room.num_static_meshes; i++)
355         read_tr_room_staticmesh(src, room.static_meshes[i]);
356 
357     room.alternate_room  = read_bit16(src);
358     room.alternate_group = 0;   // Doesn't exist in TR1-3
359 
360     room.flags = read_bitu16(src);
361         room.reverb_info = 2;
362 
363     room.light_colour.r = roomIntensity;
364     room.light_colour.g = roomIntensity;
365     room.light_colour.b = roomIntensity;
366 
367     room.light_colour.a = 1.0f;
368 }
369 
370 /// \brief reads object texture vertex definition.
read_tr_object_texture_vert(SDL_RWops * const src,tr4_object_texture_vert_t & vert)371 void TR_Level::read_tr_object_texture_vert(SDL_RWops * const src, tr4_object_texture_vert_t & vert)
372 {
373     vert.xcoordinate = read_bit8(src);
374     vert.xpixel = read_bitu8(src);
375     vert.ycoordinate = read_bit8(src);
376     vert.ypixel = read_bitu8(src);
377 }
378 
379 /** \brief reads object texture definition.
380   *
381   * some sanity checks get done and if they fail an exception gets thrown.
382   * all values introduced in TR4 get set appropiatly.
383   */
read_tr_object_texture(SDL_RWops * const src,tr4_object_texture_t & object_texture)384 void TR_Level::read_tr_object_texture(SDL_RWops * const src, tr4_object_texture_t & object_texture)
385 {
386     object_texture.transparency_flags = read_bitu16(src);
387     object_texture.tile_and_flag = read_bitu16(src);
388     if (object_texture.tile_and_flag > 64)
389         Sys_extWarn("object_texture.tile_and_flags > 64");
390 
391     if ((object_texture.tile_and_flag & (1 << 15)) != 0)
392         Sys_extWarn("object_texture.tile_and_flags has top bit set!");
393 
394     // only in TR4
395     object_texture.flags = 0;
396     read_tr_object_texture_vert(src, object_texture.vertices[0]);
397     read_tr_object_texture_vert(src, object_texture.vertices[1]);
398     read_tr_object_texture_vert(src, object_texture.vertices[2]);
399     read_tr_object_texture_vert(src, object_texture.vertices[3]);
400     // only in TR4
401     object_texture.unknown1 = 0;
402     object_texture.unknown2 = 0;
403     object_texture.x_size = 0;
404     object_texture.y_size = 0;
405 }
406 
407 /** \brief reads sprite texture definition.
408   *
409   * some sanity checks get done and if they fail an exception gets thrown.
410   */
read_tr_sprite_texture(SDL_RWops * const src,tr_sprite_texture_t & sprite_texture)411 void TR_Level::read_tr_sprite_texture(SDL_RWops * const src, tr_sprite_texture_t & sprite_texture)
412 {
413     int tx, ty, tw, th, tleft, tright, ttop, tbottom;
414     float w, h;
415 
416     sprite_texture.tile = read_bitu16(src);
417     if (sprite_texture.tile > 64)
418         Sys_extWarn("sprite_texture.tile > 64");
419 
420     tx = read_bitu8(src);
421     ty = read_bitu8(src);
422     tw = read_bitu16(src);
423     th = read_bitu16(src);
424     tleft = read_bit16(src);
425     ttop = read_bit16(src);
426     tright = read_bit16(src);
427     tbottom = read_bit16(src);
428 
429     w = tw / 256.0;
430     h = th / 256.0;
431     sprite_texture.x0 = tx;
432     sprite_texture.y0 = ty;
433     sprite_texture.x1 = sprite_texture.x0 + w;
434     sprite_texture.y1 = sprite_texture.y0 + h;
435 
436     sprite_texture.left_side = tleft;
437     sprite_texture.right_side = tright;
438     sprite_texture.top_side =-tbottom;
439     sprite_texture.bottom_side =-ttop;
440 }
441 
442 /** \brief reads sprite sequence definition.
443   *
444   * length is negative when read and thus gets negated.
445   */
read_tr_sprite_sequence(SDL_RWops * const src,tr_sprite_sequence_t & sprite_sequence)446 void TR_Level::read_tr_sprite_sequence(SDL_RWops * const src, tr_sprite_sequence_t & sprite_sequence)
447 {
448     sprite_sequence.object_id = read_bit32(src);
449     sprite_sequence.length = -read_bit16(src);
450     sprite_sequence.offset = read_bit16(src);
451 }
452 
453 /** \brief reads mesh definition.
454   *
455   * The read num_normals value is positive when normals are available and negative when light
456   * values are available. The values get set appropiatly.
457   */
read_tr_mesh(SDL_RWops * const src,tr4_mesh_t & mesh)458 void TR_Level::read_tr_mesh(SDL_RWops * const src, tr4_mesh_t & mesh)
459 {
460     int i;
461 
462     read_tr_vertex16(src, mesh.centre);
463     mesh.collision_size = read_bit16(src);
464     mesh.flags = read_bitu8(src);
465     mesh.dummy = read_bitu8(src);
466 
467     mesh.num_vertices = read_bit16(src);
468     mesh.vertices = (tr5_vertex_t*)malloc(mesh.num_vertices * sizeof(tr5_vertex_t));
469     for (i = 0; i < mesh.num_vertices; i++)
470         read_tr_vertex16(src, mesh.vertices[i]);
471 
472     mesh.num_normals = read_bit16(src);
473     if (mesh.num_normals >= 0) {
474         mesh.num_lights = 0;
475         mesh.normals = (tr5_vertex_t*)malloc(mesh.num_normals * sizeof(tr5_vertex_t));
476         for (i = 0; i < mesh.num_normals; i++)
477             read_tr_vertex16(src, mesh.normals[i]);
478     } else {
479         mesh.num_lights = -mesh.num_normals;
480         mesh.num_normals = 0;
481         mesh.lights = (int16_t*)malloc(mesh.num_lights * sizeof(int16_t));
482         for (i = 0; i < mesh.num_lights; i++)
483             mesh.lights[i] = read_bit16(src);
484     }
485 
486     mesh.num_textured_rectangles = read_bit16(src);
487     mesh.textured_rectangles = (tr4_face4_t*)malloc(mesh.num_textured_rectangles * sizeof(tr4_face4_t));
488     for (i = 0; i < mesh.num_textured_rectangles; i++)
489         read_tr_face4(src, mesh.textured_rectangles[i]);
490 
491     mesh.num_textured_triangles = read_bit16(src);
492     mesh.textured_triangles = (tr4_face3_t*)malloc(mesh.num_textured_triangles * sizeof(tr4_face3_t));
493     for (i = 0; i < mesh.num_textured_triangles; i++)
494         read_tr_face3(src, mesh.textured_triangles[i]);
495 
496     mesh.num_coloured_rectangles = read_bit16(src);
497     mesh.coloured_rectangles = (tr4_face4_t*)malloc(mesh.num_coloured_rectangles * sizeof(tr4_face4_t));
498     for (i = 0; i < mesh.num_coloured_rectangles; i++)
499         read_tr_face4(src, mesh.coloured_rectangles[i]);
500 
501     mesh.num_coloured_triangles = read_bit16(src);
502     mesh.coloured_triangles = (tr4_face3_t*)malloc(mesh.num_coloured_triangles * sizeof(tr4_face3_t));
503     for (i = 0; i < mesh.num_coloured_triangles; i++)
504         read_tr_face3(src, mesh.coloured_triangles[i]);
505 }
506 
507 /// \brief reads an animation state change.
read_tr_state_changes(SDL_RWops * const src,tr_state_change_t & state_change)508 void TR_Level::read_tr_state_changes(SDL_RWops * const src, tr_state_change_t & state_change)
509 {
510     state_change.state_id = read_bitu16(src);
511     state_change.num_anim_dispatches = read_bitu16(src);
512     state_change.anim_dispatch = read_bitu16(src);
513 }
514 
515 /// \brief reads an animation dispatch.
read_tr_anim_dispatches(SDL_RWops * const src,tr_anim_dispatch_t & anim_dispatch)516 void TR_Level::read_tr_anim_dispatches(SDL_RWops * const src, tr_anim_dispatch_t & anim_dispatch)
517 {
518     anim_dispatch.low = read_bit16(src);
519     anim_dispatch.high = read_bit16(src);
520     anim_dispatch.next_animation = read_bit16(src);
521     anim_dispatch.next_frame = read_bit16(src);
522 }
523 
524 /// \brief reads an animation definition.
read_tr_animation(SDL_RWops * const src,tr_animation_t & animation)525 void TR_Level::read_tr_animation(SDL_RWops * const src, tr_animation_t & animation)
526 {
527     animation.frame_offset = read_bitu32(src);
528     animation.frame_rate = read_bitu8(src);
529     animation.frame_size = read_bitu8(src);
530     animation.state_id = read_bitu16(src);
531 
532     animation.speed = read_mixfloat(src);
533     animation.accel = read_mixfloat(src);
534 
535     animation.frame_start = read_bitu16(src);
536     animation.frame_end = read_bitu16(src);
537     animation.next_animation = read_bitu16(src);
538     animation.next_frame = read_bitu16(src);
539 
540     animation.num_state_changes = read_bitu16(src);
541     animation.state_change_offset = read_bitu16(src);
542     animation.num_anim_commands = read_bitu16(src);
543     animation.anim_command = read_bitu16(src);
544 }
545 
546 /** \brief reads a moveable definition.
547   *
548   * some sanity checks get done which throw a exception on failure.
549   * frame_offset needs to be corrected later in TR_Level::read_tr_level.
550   */
read_tr_moveable(SDL_RWops * const src,tr_moveable_t & moveable)551 void TR_Level::read_tr_moveable(SDL_RWops * const src, tr_moveable_t & moveable)
552 {
553     moveable.object_id = read_bitu32(src);
554     moveable.num_meshes = read_bitu16(src);
555     moveable.starting_mesh = read_bitu16(src);
556     moveable.mesh_tree_index = read_bitu32(src);
557     moveable.frame_offset = read_bitu32(src);
558     moveable.animation_index = read_bitu16(src);
559 
560     // Disable unused skybox polygons.
561     if((this->game_version == TR_III) && (moveable.object_id == 355))
562     {
563         this->meshes[(this->mesh_indices[moveable.starting_mesh])].num_coloured_triangles = 16;
564     }
565 }
566 
567 /// \brief reads an item definition.
read_tr_item(SDL_RWops * const src,tr2_item_t & item)568 void TR_Level::read_tr_item(SDL_RWops * const src, tr2_item_t & item)
569 {
570     item.object_id = read_bit16(src);
571     item.room = read_bit16(src);
572     read_tr_vertex32(src, item.pos);
573     item.rotation = (float)read_bitu16(src) / 16384.0f * -90;
574     item.intensity1 = read_bitu16(src);
575     if (item.intensity1 >= 0)
576         item.intensity1 = (8191 - item.intensity1) << 2;
577     item.intensity2 = item.intensity1;
578     item.ocb = 0;   // Not present in TR1!
579     item.flags = read_bitu16(src);
580 }
581 
582 /// \brief reads a cinematic frame
read_tr_cinematic_frame(SDL_RWops * const src,tr_cinematic_frame_t & cf)583 void TR_Level::read_tr_cinematic_frame(SDL_RWops * const src, tr_cinematic_frame_t & cf)
584 {
585     //Camera look at position
586     cf.targetx = read_bit16(src);
587     cf.targety = read_bit16(src);
588     cf.targetz = read_bit16(src);
589     //Camera position
590     cf.posx = read_bit16(src);
591     cf.posy = read_bit16(src);
592     cf.posz = read_bit16(src);
593     cf.fov = read_bit16(src);
594     cf.roll = read_bit16(src);
595 }
596 
597 /// \brief reads a static mesh definition.
read_tr_staticmesh(SDL_RWops * const src,tr_staticmesh_t & mesh)598 void TR_Level::read_tr_staticmesh(SDL_RWops * const src, tr_staticmesh_t & mesh)
599 {
600     mesh.object_id = read_bitu32(src);
601     mesh.mesh = read_bitu16(src);
602 
603     mesh.visibility_box[0].x = (float)read_bit16(src);
604     mesh.visibility_box[1].x = (float)read_bit16(src);
605     mesh.visibility_box[0].y = (float)-read_bit16(src);
606     mesh.visibility_box[1].y = (float)-read_bit16(src);
607     mesh.visibility_box[0].z = (float)-read_bit16(src);
608     mesh.visibility_box[1].z = (float)-read_bit16(src);
609 
610     mesh.collision_box[0].x = (float)read_bit16(src);
611     mesh.collision_box[1].x = (float)read_bit16(src);
612     mesh.collision_box[0].y = (float)-read_bit16(src);
613     mesh.collision_box[1].y = (float)-read_bit16(src);
614     mesh.collision_box[0].z = (float)-read_bit16(src);
615     mesh.collision_box[1].z = (float)-read_bit16(src);
616 
617     mesh.flags = read_bitu16(src);
618 }
619 
read_tr_level(SDL_RWops * const src,bool demo_or_ub)620 void TR_Level::read_tr_level(SDL_RWops * const src, bool demo_or_ub)
621 {
622     uint32_t i;
623 
624     // Version
625     uint32_t file_version = read_bitu32(src);
626 
627     if (file_version != 0x00000020)
628         Sys_extError("Wrong level version");
629 
630     this->num_textiles = 0;
631     this->num_room_textiles = 0;
632     this->num_obj_textiles = 0;
633     this->num_bump_textiles = 0;
634     this->num_misc_textiles = 0;
635     this->read_32bit_textiles = false;
636 
637     this->textile8_count = this->num_textiles = read_bitu32(src);
638     this->textile8 = (tr_textile8_t*)malloc(this->textile8_count * sizeof(tr_textile8_t));
639     for (i = 0; i < this->textile8_count; i++)
640         read_tr_textile8(src, this->textile8[i]);
641 
642     // Unused
643     if (read_bitu32(src) != 0)
644         Sys_extWarn("Bad value for 'unused'");
645 
646     this->rooms_count = read_bitu16(src);
647     this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t));
648     for (i = 0; i < this->rooms_count; i++)
649         read_tr_room(src, this->rooms[i]);
650 
651     this->floor_data_size = read_bitu32(src);
652     this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t));
653     for(i = 0; i < this->floor_data_size; i++)
654         this->floor_data[i] = read_bitu16(src);
655 
656     read_mesh_data(src);
657 
658     this->animations_count = read_bitu32(src);
659     this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t));
660     for (i = 0; i < this->animations_count; i++)
661         read_tr_animation(src, this->animations[i]);
662 
663     this->state_changes_count = read_bitu32(src);
664     this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t));
665     for (i = 0; i < this->state_changes_count; i++)
666         read_tr_state_changes(src, this->state_changes[i]);
667 
668     this->anim_dispatches_count = read_bitu32(src);
669     this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t));
670     for (i = 0; i < this->anim_dispatches_count; i++)
671         read_tr_anim_dispatches(src, this->anim_dispatches[i]);
672 
673     this->anim_commands_count = read_bitu32(src);
674     this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t));
675     for (i = 0; i < this->anim_commands_count; i++)
676         this->anim_commands[i] = read_bit16(src);
677 
678     this->mesh_tree_data_size = read_bitu32(src);
679     this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t));
680     for (i = 0; i < this->mesh_tree_data_size; i++)
681         this->mesh_tree_data[i] = read_bitu32(src);
682 
683     read_frame_moveable_data(src);
684 
685     // try to fix ugly hack
686     for (i = 0; i < this->animations_count; i++)
687     {
688         uint32_t frame_offset = this->animations[i].frame_offset / 2;
689         this->animations[i].frame_size = this->frame_data[frame_offset + 9] * 2 + 10;
690     }
691 
692     this->static_meshes_count = read_bitu32(src);
693     this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t));
694     for (i = 0; i < this->static_meshes_count; i++)
695         read_tr_staticmesh(src, this->static_meshes[i]);
696 
697     this->object_textures_count = read_bitu32(src);
698     this->object_textures = (tr4_object_texture_t*)malloc(this->object_textures_count * sizeof(tr4_object_texture_t));
699     for (i = 0; i < this->object_textures_count; i++)
700         read_tr_object_texture(src, this->object_textures[i]);
701 
702     this->sprite_textures_count = read_bitu32(src);
703     this->sprite_textures = (tr_sprite_texture_t*)malloc(this->sprite_textures_count * sizeof(tr_sprite_texture_t));
704     for (i = 0; i < this->sprite_textures_count; i++)
705         read_tr_sprite_texture(src, this->sprite_textures[i]);
706 
707     this->sprite_sequences_count = read_bitu32(src);
708     this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t));
709     for (i = 0; i < this->sprite_sequences_count; i++)
710         read_tr_sprite_sequence(src, this->sprite_sequences[i]);
711 
712     if (demo_or_ub)
713         read_tr_palette(src, this->palette);
714 
715     this->cameras_count = read_bitu32(src);
716     this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t));
717     for (i = 0; i < this->cameras_count; i++)
718     {
719         this->cameras[i].x = read_bit32(src);
720         this->cameras[i].y = read_bit32(src);
721         this->cameras[i].z = read_bit32(src);
722 
723         this->cameras[i].room = read_bit16(src);
724         this->cameras[i].unknown1 = read_bitu16(src);
725     }
726 
727     this->sound_sources_count = read_bitu32(src);
728     this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t));
729     for(i = 0; i < this->sound_sources_count; i++)
730     {
731         this->sound_sources[i].x = read_bit32(src);
732         this->sound_sources[i].y = read_bit32(src);
733         this->sound_sources[i].z = read_bit32(src);
734 
735         this->sound_sources[i].sound_id = read_bitu16(src);
736         this->sound_sources[i].flags = read_bitu16(src);
737     }
738 
739     this->boxes_count = read_bitu32(src);
740     this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t));
741     this->zones = (tr2_zone_t*)malloc(this->boxes_count * sizeof(tr2_zone_t));
742     for (i = 0; i < this->boxes_count; i++)
743         read_tr_box(src, this->boxes[i]);
744 
745     this->overlaps_count = read_bitu32(src);
746     this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t));
747     for (i = 0; i < this->overlaps_count; i++)
748         this->overlaps[i] = read_bitu16(src);
749 
750     // Zones
751     for (i = 0; i < this->boxes_count; i++)
752         read_tr_zone(src, this->zones[i]);
753 
754     this->animated_textures_count = read_bitu32(src);
755     this->animated_textures_uv_count = 0; // No UVRotate in TR1
756     this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t));
757     for (i = 0; i < this->animated_textures_count; i++)
758     {
759         this->animated_textures[i] = read_bitu16(src);
760     }
761 
762     this->items_count = read_bitu32(src);
763     this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t));
764     for (i = 0; i < this->items_count; i++)
765         read_tr_item(src, this->items[i]);
766 
767     read_tr_lightmap(src, this->lightmap);
768 
769     if (!demo_or_ub)
770         read_tr_palette(src, this->palette);
771 
772     this->cinematic_frames_count = read_bitu16(src);
773     this->cinematic_frames = (tr_cinematic_frame_t*)malloc(this->cinematic_frames_count * sizeof(tr_cinematic_frame_t));
774     for (i = 0; i < this->cinematic_frames_count; i++)
775     {
776         read_tr_cinematic_frame(src, this->cinematic_frames[i]);
777     }
778 
779     this->demo_data_count = read_bitu16(src);
780     this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t));
781     for(i=0; i < this->demo_data_count; i++)
782         this->demo_data[i] = read_bitu8(src);
783 
784     // Soundmap
785     this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR1 * sizeof(int16_t));
786     for(i=0; i < TR_AUDIO_MAP_SIZE_TR1; i++)
787         this->soundmap[i] = read_bit16(src);
788 
789     this->sound_details_count = read_bitu32(src);
790     this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t));
791 
792     for(i = 0; i < this->sound_details_count; i++)
793     {
794         this->sound_details[i].sample = read_bitu16(src);
795         this->sound_details[i].volume = read_bitu16(src);
796         this->sound_details[i].chance = read_bitu16(src);
797         this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src);
798         this->sound_details[i].flags_2 = read_bitu8(src);
799         this->sound_details[i].sound_range = TR_AUDIO_DEFAULT_RANGE;
800         this->sound_details[i].pitch = (int16_t)TR_AUDIO_DEFAULT_PITCH;
801     }
802 
803     // LOAD SAMPLES
804 
805     // In TR1, samples are embedded into level file as solid block, preceded by
806     // block size in bytes. Sample block is followed by sample indices array.
807 
808     this->samples_count = 0;
809     this->samples_data_size = read_bitu32(src);
810     this->samples_data = (uint8_t*)malloc(this->samples_data_size * sizeof(uint8_t));
811     for(i=0; i < this->samples_data_size; i++)
812     {
813         this->samples_data[i] = read_bitu8(src);
814         if((i >= 4) && (*((uint32_t*)(this->samples_data+i-4)) == 0x46464952))   /// RIFF
815         {
816             this->samples_count++;
817         }
818     }
819 
820     this->sample_indices_count = read_bitu32(src);
821     this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t));
822     for(i=0; i < this->sample_indices_count; i++)
823         this->sample_indices[i] = read_bitu32(src);
824 }
825