formatting
[btb/d2x.git] / main / bm.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 /*
15  * $Source: /cvs/cvsroot/d2x/main/bm.c,v $
16  * $Revision: 1.6 $
17  * $Author: bradleyb $
18  * $Date: 2001-11-02 02:22:25 $
19  *
20  * Bitmap and palette loading functions.
21  *
22  * $Log: not supported by cvs2svn $
23  * Revision 1.5  2001/10/25 02:15:55  bradleyb
24  * conditionalize including multi.h and network.h, fix backslashes
25  *
26  * Revision 1.4  2001/10/19 08:06:20  bradleyb
27  * Partial application of linux/alpha patch.  Courtesy of Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
28  *
29  *
30  */
31
32 #ifdef HAVE_CONFIG_H
33 #include <conf.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #include "pstypes.h"
40 #include "inferno.h"
41 #include "gr.h"
42 #include "bm.h"
43 #include "u_mem.h"
44 #include "mono.h"
45 #include "error.h"
46 #include "object.h"
47 #include "vclip.h"
48 #include "effects.h"
49 #include "polyobj.h"
50 #include "wall.h"
51 #include "textures.h"
52 #include "game.h"
53 #ifdef NETWORK
54 #include "multi.h"
55 #endif
56 #include "iff.h"
57 #include "cfile.h"
58 #include "powerup.h"
59 #include "sounds.h"
60 #include "piggy.h"
61 #include "aistruct.h"
62 #include "robot.h"
63 #include "weapon.h"
64 #include "gauges.h"
65 #include "player.h"
66 #include "endlevel.h"
67 #include "cntrlcen.h"
68 #include "byteswap.h"
69
70 ubyte Sounds[MAX_SOUNDS];
71 ubyte AltSounds[MAX_SOUNDS];
72
73 #ifdef EDITOR
74 int Num_total_object_types;
75 byte    ObjType[MAX_OBJTYPE];
76 byte    ObjId[MAX_OBJTYPE];
77 fix     ObjStrength[MAX_OBJTYPE];
78 #endif
79
80 //for each model, a model number for dying & dead variants, or -1 if none
81 int Dying_modelnums[MAX_POLYGON_MODELS];
82 int Dead_modelnums[MAX_POLYGON_MODELS];
83
84 //the polygon model number to use for the marker
85 int     Marker_model_num = -1;
86
87 //right now there's only one player ship, but we can have another by 
88 //adding an array and setting the pointer to the active ship.
89 player_ship only_player_ship,*Player_ship=&only_player_ship;
90
91 //----------------- Miscellaneous bitmap pointers ---------------
92 int                                     Num_cockpits = 0;
93 bitmap_index            cockpit_bitmap[N_COCKPIT_BITMAPS];
94
95 //---------------- Variables for wall textures ------------------
96 int                                     Num_tmaps;
97 tmap_info                       TmapInfo[MAX_TEXTURES];
98
99 //---------------- Variables for object textures ----------------
100
101 int                                     First_multi_bitmap_num=-1;
102
103 bitmap_index            ObjBitmaps[MAX_OBJ_BITMAPS];
104 ushort                          ObjBitmapPtrs[MAX_OBJ_BITMAPS];         // These point back into ObjBitmaps, since some are used twice.
105
106 #ifdef PORTABLE_LOADER
107 void read_tmap_info(CFILE *fp, int inNumTexturesToRead, int inOffset)
108 {
109         int i;
110         
111         for (i = inOffset; i < (inNumTexturesToRead + inOffset); i++)
112         {
113                 TmapInfo[i].flags = cfile_read_byte(fp);
114                 TmapInfo[i].pad[0] = cfile_read_byte(fp);
115                 TmapInfo[i].pad[1] = cfile_read_byte(fp);
116                 TmapInfo[i].pad[2] = cfile_read_byte(fp);
117                 TmapInfo[i].lighting = cfile_read_fix(fp);
118                 TmapInfo[i].damage = cfile_read_fix(fp);
119                 TmapInfo[i].eclip_num = cfile_read_short(fp);
120                 TmapInfo[i].destroyed = cfile_read_short(fp);
121                 TmapInfo[i].slide_u = cfile_read_short(fp);
122                 TmapInfo[i].slide_v = cfile_read_short(fp);
123         }
124 }
125
126 void read_vclip_info(CFILE *fp, int inNumVClipsToRead, int inOffset)
127 {
128         int i, j;
129         
130         for (i = inOffset; i < (inNumVClipsToRead + inOffset); i++)
131         {
132                 Vclip[i].play_time = cfile_read_fix(fp);
133                 Vclip[i].num_frames = cfile_read_int(fp);
134                 Vclip[i].frame_time = cfile_read_fix(fp);
135                 Vclip[i].flags = cfile_read_int(fp);
136                 Vclip[i].sound_num = cfile_read_short(fp);
137                 for (j = 0; j < VCLIP_MAX_FRAMES; j++)
138                         Vclip[i].frames[j].index = cfile_read_short(fp);
139                 Vclip[i].light_value = cfile_read_fix(fp);
140         }
141 }
142
143 void read_effect_info(CFILE *fp, int inNumEffectsToRead, int inOffset)
144 {
145         int i, j;
146
147
148         for (i = inOffset; i < (inNumEffectsToRead + inOffset); i++)
149         {
150                 Effects[i].vc.play_time = cfile_read_fix(fp);
151                 Effects[i].vc.num_frames = cfile_read_int(fp);
152                 Effects[i].vc.frame_time = cfile_read_fix(fp);
153                 Effects[i].vc.flags = cfile_read_int(fp);
154                 Effects[i].vc.sound_num = cfile_read_short(fp);
155                 for (j = 0; j < VCLIP_MAX_FRAMES; j++)
156                         Effects[i].vc.frames[j].index = cfile_read_short(fp);
157                 Effects[i].vc.light_value = cfile_read_fix(fp);
158                 Effects[i].time_left = cfile_read_fix(fp);
159                 Effects[i].frame_count = cfile_read_int(fp);
160                 Effects[i].changing_wall_texture = cfile_read_short(fp);
161                 Effects[i].changing_object_texture = cfile_read_short(fp);
162                 Effects[i].flags = cfile_read_int(fp);
163                 Effects[i].crit_clip = cfile_read_int(fp);
164                 Effects[i].dest_bm_num = cfile_read_int(fp);
165                 Effects[i].dest_vclip = cfile_read_int(fp);
166                 Effects[i].dest_eclip = cfile_read_int(fp);
167                 Effects[i].dest_size = cfile_read_fix(fp);
168                 Effects[i].sound_num = cfile_read_int(fp);
169                 Effects[i].segnum = cfile_read_int(fp);
170                 Effects[i].sidenum = cfile_read_int(fp);
171         }
172 }
173
174 void read_wallanim_info(CFILE *fp, int inNumWallAnimsToRead, int inOffset)
175 {
176         int i, j;
177         
178         for (i = inOffset; i < (inNumWallAnimsToRead + inOffset); i++)
179         {
180                 WallAnims[i].play_time = cfile_read_fix(fp);;
181                 WallAnims[i].num_frames = cfile_read_short(fp);;
182                 for (j = 0; j < MAX_CLIP_FRAMES; j++)
183                         WallAnims[i].frames[j] = cfile_read_short(fp);
184                 WallAnims[i].open_sound = cfile_read_short(fp);
185                 WallAnims[i].close_sound = cfile_read_short(fp);
186                 WallAnims[i].flags = cfile_read_short(fp);
187                 cfread(WallAnims[i].filename, 13, 1, fp);
188                 WallAnims[i].pad = cfile_read_byte(fp);
189         }               
190 }
191
192 void read_robot_info(CFILE *fp, int inNumRobotsToRead, int inOffset)
193 {
194         int i, j, k;
195         
196         for (i = inOffset; i < (inNumRobotsToRead + inOffset); i++)
197         {
198                 Robot_info[i].model_num = cfile_read_int(fp);
199                 for (j = 0; j < MAX_GUNS; j++)
200                         cfile_read_vector(&(Robot_info[i].gun_points[j]), fp);
201                 for (j = 0; j < MAX_GUNS; j++)
202                         Robot_info[i].gun_submodels[j] = cfile_read_byte(fp);
203
204                 Robot_info[i].exp1_vclip_num = cfile_read_short(fp);
205                 Robot_info[i].exp1_sound_num = cfile_read_short(fp);
206
207                 Robot_info[i].exp2_vclip_num = cfile_read_short(fp);
208                 Robot_info[i].exp2_sound_num = cfile_read_short(fp);
209
210                 Robot_info[i].weapon_type = cfile_read_byte(fp);
211                 Robot_info[i].weapon_type2 = cfile_read_byte(fp);
212                 Robot_info[i].n_guns = cfile_read_byte(fp);
213                 Robot_info[i].contains_id = cfile_read_byte(fp);
214
215                 Robot_info[i].contains_count = cfile_read_byte(fp);
216                 Robot_info[i].contains_prob = cfile_read_byte(fp);
217                 Robot_info[i].contains_type = cfile_read_byte(fp);
218                 Robot_info[i].kamikaze = cfile_read_byte(fp);
219
220                 Robot_info[i].score_value = cfile_read_short(fp);
221                 Robot_info[i].badass = cfile_read_byte(fp);
222                 Robot_info[i].energy_drain = cfile_read_byte(fp);
223                 
224                 Robot_info[i].lighting = cfile_read_fix(fp);
225                 Robot_info[i].strength = cfile_read_fix(fp);
226
227                 Robot_info[i].mass = cfile_read_fix(fp);
228                 Robot_info[i].drag = cfile_read_fix(fp);
229
230                 for (j = 0; j < NDL; j++)
231                         Robot_info[i].field_of_view[j] = cfile_read_fix(fp);
232                 for (j = 0; j < NDL; j++)
233                         Robot_info[i].firing_wait[j] = cfile_read_fix(fp);
234                 for (j = 0; j < NDL; j++)
235                         Robot_info[i].firing_wait2[j] = cfile_read_fix(fp);
236                 for (j = 0; j < NDL; j++)
237                         Robot_info[i].turn_time[j] = cfile_read_fix(fp);
238                 for (j = 0; j < NDL; j++)
239                         Robot_info[i].max_speed[j] = cfile_read_fix(fp);
240                 for (j = 0; j < NDL; j++)
241                         Robot_info[i].circle_distance[j] = cfile_read_fix(fp);
242                 for (j = 0; j < NDL; j++)
243                         cfread(&(Robot_info[i].rapidfire_count[j]), sizeof(byte), 1, fp);
244                 for (j = 0; j < NDL; j++)
245                         cfread(&(Robot_info[i].evade_speed[j]), sizeof(byte), 1, fp);
246                 Robot_info[i].cloak_type = cfile_read_byte(fp);
247                 Robot_info[i].attack_type = cfile_read_byte(fp);
248
249                 Robot_info[i].see_sound = cfile_read_byte(fp);
250                 Robot_info[i].attack_sound = cfile_read_byte(fp);
251                 Robot_info[i].claw_sound = cfile_read_byte(fp);
252                 Robot_info[i].taunt_sound = cfile_read_byte(fp);
253
254                 Robot_info[i].boss_flag = cfile_read_byte(fp);
255                 Robot_info[i].companion = cfile_read_byte(fp);
256                 Robot_info[i].smart_blobs = cfile_read_byte(fp);
257                 Robot_info[i].energy_blobs = cfile_read_byte(fp);
258
259                 Robot_info[i].thief = cfile_read_byte(fp);
260                 Robot_info[i].pursuit = cfile_read_byte(fp);
261                 Robot_info[i].lightcast = cfile_read_byte(fp);
262                 Robot_info[i].death_roll = cfile_read_byte(fp);
263
264                 Robot_info[i].flags = cfile_read_byte(fp);
265                 Robot_info[i].pad[0] = cfile_read_byte(fp);
266                 Robot_info[i].pad[1] = cfile_read_byte(fp);
267                 Robot_info[i].pad[2] = cfile_read_byte(fp);
268
269                 Robot_info[i].deathroll_sound = cfile_read_byte(fp);
270                 Robot_info[i].glow = cfile_read_byte(fp);
271                 Robot_info[i].behavior = cfile_read_byte(fp);
272                 Robot_info[i].aim = cfile_read_byte(fp);
273
274                 for (j = 0; j < MAX_GUNS + 1; j++) {
275                         for (k = 0; k < N_ANIM_STATES; k++) {
276                                 Robot_info[i].anim_states[j][k].n_joints = cfile_read_short(fp);
277                                 Robot_info[i].anim_states[j][k].offset = cfile_read_short(fp);
278                         }
279                 }
280
281                 Robot_info[i].always_0xabcd = cfile_read_int(fp);
282         }
283 }
284
285 void read_robot_joint_info(CFILE *fp, int inNumRobotJointsToRead, int inOffset)
286 {
287         int i;
288
289         for (i = inOffset; i < (inNumRobotJointsToRead + inOffset); i++)
290         {
291                 Robot_joints[i].jointnum = cfile_read_short(fp);
292                 cfile_read_angvec(&(Robot_joints[i].angles), fp);
293         }
294 }
295
296 void read_weapon_info(CFILE *fp, int inNumWeaponsToRead, int inOffset)
297 {
298         int i, j;
299         
300         for (i = inOffset; i < (inNumWeaponsToRead + inOffset); i++)
301         {
302                 Weapon_info[i].render_type = cfile_read_byte(fp);
303                 Weapon_info[i].persistent = cfile_read_byte(fp);
304                 Weapon_info[i].model_num = cfile_read_short(fp);
305                 Weapon_info[i].model_num_inner = cfile_read_short(fp);
306
307                 Weapon_info[i].flash_vclip = cfile_read_byte(fp);
308                 Weapon_info[i].robot_hit_vclip = cfile_read_byte(fp);
309                 Weapon_info[i].flash_sound = cfile_read_short(fp);              
310
311                 Weapon_info[i].wall_hit_vclip = cfile_read_byte(fp);
312                 Weapon_info[i].fire_count = cfile_read_byte(fp);
313                 Weapon_info[i].robot_hit_sound = cfile_read_short(fp);
314                 
315                 Weapon_info[i].ammo_usage = cfile_read_byte(fp);
316                 Weapon_info[i].weapon_vclip = cfile_read_byte(fp);
317                 Weapon_info[i].wall_hit_sound = cfile_read_short(fp);           
318
319                 Weapon_info[i].destroyable = cfile_read_byte(fp);
320                 Weapon_info[i].matter = cfile_read_byte(fp);
321                 Weapon_info[i].bounce = cfile_read_byte(fp);
322                 Weapon_info[i].homing_flag = cfile_read_byte(fp);
323
324                 Weapon_info[i].speedvar = cfile_read_byte(fp);
325                 Weapon_info[i].flags = cfile_read_byte(fp);
326                 Weapon_info[i].flash = cfile_read_byte(fp);
327                 Weapon_info[i].afterburner_size = cfile_read_byte(fp);
328                 
329                 Weapon_info[i].children = cfile_read_byte(fp);
330
331                 Weapon_info[i].energy_usage = cfile_read_fix(fp);
332                 Weapon_info[i].fire_wait = cfile_read_fix(fp);
333                 
334                 Weapon_info[i].multi_damage_scale = cfile_read_fix(fp);
335                 
336                 Weapon_info[i].bitmap.index = cfile_read_short(fp);     // bitmap_index = short
337
338                 Weapon_info[i].blob_size = cfile_read_fix(fp);
339                 Weapon_info[i].flash_size = cfile_read_fix(fp);
340                 Weapon_info[i].impact_size = cfile_read_fix(fp);
341                 for (j = 0; j < NDL; j++)
342                         Weapon_info[i].strength[j] = cfile_read_fix(fp);
343                 for (j = 0; j < NDL; j++)
344                         Weapon_info[i].speed[j] = cfile_read_fix(fp);
345                 Weapon_info[i].mass = cfile_read_fix(fp);
346                 Weapon_info[i].drag = cfile_read_fix(fp);
347                 Weapon_info[i].thrust = cfile_read_fix(fp);
348                 Weapon_info[i].po_len_to_width_ratio = cfile_read_fix(fp);
349                 Weapon_info[i].light = cfile_read_fix(fp);
350                 Weapon_info[i].lifetime = cfile_read_fix(fp);
351                 Weapon_info[i].damage_radius = cfile_read_fix(fp);
352                 Weapon_info[i].picture.index = cfile_read_short(fp);            // bitmap_index is a short
353                 Weapon_info[i].hires_picture.index = cfile_read_short(fp);              // bitmap_index is a short
354         }
355 }
356
357 void read_powerup_info(CFILE *fp, int inNumPowerupsToRead, int inOffset)
358 {
359         int i;
360         
361         for (i = inOffset; i < (inNumPowerupsToRead + inOffset); i++)
362         {
363                 Powerup_info[i].vclip_num = cfile_read_int(fp);
364                 Powerup_info[i].hit_sound = cfile_read_int(fp);
365                 Powerup_info[i].size = cfile_read_fix(fp);
366                 Powerup_info[i].light = cfile_read_fix(fp);
367         }
368 }
369
370 void read_polygon_models(CFILE *fp, int inNumPolygonModelsToRead, int inOffset)
371 {
372         int i, j;
373
374         for (i = inOffset; i < (inNumPolygonModelsToRead + inOffset); i++)
375         {
376                 Polygon_models[i].n_models = cfile_read_int(fp);
377                 Polygon_models[i].model_data_size = cfile_read_int(fp);
378                 Polygon_models[i].model_data = (ubyte *) cfile_read_int(fp);
379                 for (j = 0; j < MAX_SUBMODELS; j++)
380                         Polygon_models[i].submodel_ptrs[j] = cfile_read_int(fp);
381                 for (j = 0; j < MAX_SUBMODELS; j++)
382                         cfile_read_vector(&(Polygon_models[i].submodel_offsets[j]), fp);
383                 for (j = 0; j < MAX_SUBMODELS; j++)
384                         cfile_read_vector(&(Polygon_models[i].submodel_norms[j]), fp);
385                 for (j = 0; j < MAX_SUBMODELS; j++)
386                         cfile_read_vector(&(Polygon_models[i].submodel_pnts[j]), fp);
387                 for (j = 0; j < MAX_SUBMODELS; j++)
388                         Polygon_models[i].submodel_rads[j] = cfile_read_fix(fp);
389                 for (j = 0; j < MAX_SUBMODELS; j++)
390                         Polygon_models[i].submodel_parents[j] = cfile_read_byte(fp);
391                 for (j = 0; j < MAX_SUBMODELS; j++)
392                         cfile_read_vector(&(Polygon_models[i].submodel_mins[j]), fp);
393                 for (j = 0; j < MAX_SUBMODELS; j++)
394                         cfile_read_vector(&(Polygon_models[i].submodel_maxs[j]), fp);
395                 cfile_read_vector(&(Polygon_models[i].mins), fp);
396                 cfile_read_vector(&(Polygon_models[i].maxs), fp);
397                 Polygon_models[i].rad = cfile_read_fix(fp);             
398                 Polygon_models[i].n_textures = cfile_read_byte(fp);
399                 Polygon_models[i].first_texture = cfile_read_short(fp);
400                 Polygon_models[i].simpler_model = cfile_read_byte(fp);
401         }
402 }
403
404 void read_player_ship(CFILE *fp)
405 {
406         int i;
407
408         only_player_ship.model_num = cfile_read_int(fp);
409         only_player_ship.expl_vclip_num = cfile_read_int(fp);
410         only_player_ship.mass = cfile_read_fix(fp);
411         only_player_ship.drag = cfile_read_fix(fp);
412         only_player_ship.max_thrust = cfile_read_fix(fp);
413         only_player_ship.reverse_thrust = cfile_read_fix(fp);
414         only_player_ship.brakes = cfile_read_fix(fp);
415         only_player_ship.wiggle = cfile_read_fix(fp);
416         only_player_ship.max_rotthrust = cfile_read_fix(fp);
417         for (i = 0; i < N_PLAYER_GUNS; i++)
418                 cfile_read_vector(&(only_player_ship.gun_points[i]), fp);
419 }
420
421 void read_reactor_info(CFILE *fp, int inNumReactorsToRead, int inOffset)
422 {
423         int i, j;
424         
425         for (i = inOffset; i < (inNumReactorsToRead + inOffset); i++)
426         {
427                 Reactors[i].model_num = cfile_read_int(fp);
428                 Reactors[i].n_guns = cfile_read_int(fp);
429                 for (j = 0; j < MAX_CONTROLCEN_GUNS; j++)
430                         cfile_read_vector(&(Reactors[i].gun_points[j]), fp);
431                 for (j = 0; j < MAX_CONTROLCEN_GUNS; j++)
432                         cfile_read_vector(&(Reactors[i].gun_dirs[j]), fp);
433         }
434 }
435
436 #ifdef SHAREWARE
437 extern int exit_modelnum,destroyed_exit_modelnum, Num_bitmap_files;
438 int N_ObjBitmaps, extra_bitmap_num;
439
440 bitmap_index exitmodel_bm_load_sub( char * filename )
441 {
442         bitmap_index bitmap_num;
443         grs_bitmap * new;
444         ubyte newpal[256*3];
445         int i, iff_error;               //reference parm to avoid warning message
446
447         bitmap_num.index = 0;
448
449         MALLOC( new, grs_bitmap, 1 );
450         iff_error = iff_read_bitmap(filename,new,BM_LINEAR,newpal);
451         new->bm_handle=0;
452         if (iff_error != IFF_NO_ERROR)          {
453                 Error("Error loading exit model bitmap <%s> - IFF error: %s",filename,iff_errormsg(iff_error));
454         }
455         
456         if ( iff_has_transparency )
457                 gr_remap_bitmap_good( new, newpal, iff_transparent_color, 254 );
458         else
459                 gr_remap_bitmap_good( new, newpal, -1, 254 );
460
461         new->avg_color = 0;     //compute_average_pixel(new);
462
463         bitmap_num.index = extra_bitmap_num;
464
465         GameBitmaps[extra_bitmap_num++] = *new;
466         
467         d_free( new );
468         return bitmap_num;
469 }
470
471 grs_bitmap *load_exit_model_bitmap(char *name)
472 {
473         Assert(N_ObjBitmaps < MAX_OBJ_BITMAPS);
474
475         {
476                 ObjBitmaps[N_ObjBitmaps] = exitmodel_bm_load_sub(name);
477                 if (GameBitmaps[ObjBitmaps[N_ObjBitmaps].index].bm_w!=64 || GameBitmaps[ObjBitmaps[N_ObjBitmaps].index].bm_h!=64)
478                         Error("Bitmap <%s> is not 64x64",name);
479                 ObjBitmapPtrs[N_ObjBitmaps] = N_ObjBitmaps;
480                 N_ObjBitmaps++;
481                 Assert(N_ObjBitmaps < MAX_OBJ_BITMAPS);
482                 return &GameBitmaps[ObjBitmaps[N_ObjBitmaps-1].index];
483         }
484 }
485
486 void load_exit_models()
487 {
488         CFILE *exit_hamfile;
489         int i, j;
490         ubyte pal[768];
491         int start_num;
492
493         start_num = N_ObjBitmaps;
494         extra_bitmap_num = Num_bitmap_files;
495         load_exit_model_bitmap("steel1.bbm");
496         load_exit_model_bitmap("rbot061.bbm");
497         load_exit_model_bitmap("rbot062.bbm");
498
499         load_exit_model_bitmap("steel1.bbm");
500         load_exit_model_bitmap("rbot061.bbm");
501         load_exit_model_bitmap("rbot063.bbm");
502
503         exit_hamfile = cfopen(":Data:exit.ham","rb");
504
505         exit_modelnum = N_polygon_models++;
506         destroyed_exit_modelnum = N_polygon_models++;
507
508 #ifndef PORTABLE_LOADER
509         cfread( &Polygon_models[exit_modelnum], sizeof(polymodel), 1, exit_hamfile );
510         cfread( &Polygon_models[destroyed_exit_modelnum], sizeof(polymodel), 1, exit_hamfile );
511 #else
512         for (i = exit_modelnum; i <= destroyed_exit_modelnum; i++) {
513                 Polygon_models[i].n_models = cfile_read_int(exit_hamfile);
514                 Polygon_models[i].model_data_size = cfile_read_int(exit_hamfile);
515                 Polygon_models[i].model_data = (ubyte *)read_int_swap(exit_hamfile);
516                 for (j = 0; j < MAX_SUBMODELS; j++)
517                         Polygon_models[i].submodel_ptrs[j] = cfile_read_int(exit_hamfile);
518                 for (j = 0; j < MAX_SUBMODELS; j++)
519                         cfile_read_vector(&(Polygon_models[i].submodel_offsets), exit_hamfile);
520                 for (j = 0; j < MAX_SUBMODELS; j++)
521                         cfile_read_vector(&(Polygon_models[i].submodel_norms), exit_hamfile);
522                 for (j = 0; j < MAX_SUBMODELS; j++)
523                         cfile_read_vector(&(Polygon_models[i].submodel_pnts), exit_hamfile);
524                 for (j = 0; j < MAX_SUBMODELS; j++)
525                         Polygon_models[i].submodel_rads[j] = cfile_read_fix(exit_hamfile);
526                 for (j = 0; j < MAX_SUBMODELS; j++)
527                         Polygon_models[i].submodel_parents[j] = cfile_read_byte(exit_hamfile);
528                 for (j = 0; j < MAX_SUBMODELS; j++)
529                         cfile_read_vector(&(Polygon_models[i].submodel_mins), exit_hamfile);
530                 for (j = 0; j < MAX_SUBMODELS; j++)
531                         cfile_read_vector(&(Polygon_models[i].submodel_maxs), exit_hamfile);
532                 cfile_read_vector(&(Polygon_models[i].mins), exit_hamfile);
533                 cfile_read_vector(&(Polygon_models[i].maxs), exit_hamfile);
534                 Polygon_models[i].rad = cfile_read_fix(exit_hamfile);           
535                 Polygon_models[i].n_textures = cfile_read_byte(exit_hamfile);
536                 Polygon_models[i].first_texture = cfile_read_short(exit_hamfile);
537                 Polygon_models[i].simpler_model = cfile_read_byte(exit_hamfile);
538         }
539         Polygon_models[exit_modelnum].first_texture = start_num;
540         Polygon_models[destroyed_exit_modelnum].first_texture = start_num+3;
541 #endif
542
543         Polygon_models[exit_modelnum].model_data = d_malloc(Polygon_models[exit_modelnum].model_data_size);
544         Assert( Polygon_models[exit_modelnum].model_data != NULL );
545         cfread( Polygon_models[exit_modelnum].model_data, sizeof(ubyte), Polygon_models[exit_modelnum].model_data_size, exit_hamfile );
546         #ifdef MACINTOSH
547         swap_polygon_model_data(Polygon_models[exit_modelnum].model_data);
548         #endif
549         g3_init_polygon_model(Polygon_models[exit_modelnum].model_data);
550
551         Polygon_models[destroyed_exit_modelnum].model_data = d_malloc(Polygon_models[destroyed_exit_modelnum].model_data_size);
552         Assert( Polygon_models[destroyed_exit_modelnum].model_data != NULL );
553         cfread( Polygon_models[destroyed_exit_modelnum].model_data, sizeof(ubyte), Polygon_models[destroyed_exit_modelnum].model_data_size, exit_hamfile );
554         #ifdef MACINTOSH
555         swap_polygon_model_data(Polygon_models[destroyed_exit_modelnum].model_data);
556         #endif
557         g3_init_polygon_model(Polygon_models[destroyed_exit_modelnum].model_data);
558
559         cfclose(exit_hamfile);
560
561 }
562 #endif          // SHAREWARE
563
564 #endif          // PORTABLE_LOADER
565
566 //-----------------------------------------------------------------
567 // Read data from piggy.
568 // This is called when the editor is OUT.  
569 // If editor is in, bm_init_use_table() is called.
570 int bm_init()
571 {
572         init_polygon_models();
573         if (! piggy_init())                             // This calls bm_read_all
574                 Error("Cannot open pig and/or ham file");
575
576         piggy_read_sounds();
577
578         #ifdef SHAREWARE
579         init_endlevel();                //this is in bm_init_use_tbl(), so I gues it goes here
580         #endif
581
582         return 0;
583 }
584
585 void bm_read_all(CFILE * fp)
586 {
587         int i,t;
588
589         NumTextures = cfile_read_int(fp);
590 #ifndef PORTABLE_LOADER
591         cfread( Textures, sizeof(bitmap_index), NumTextures, fp );
592         cfread( TmapInfo, sizeof(tmap_info), NumTextures, fp );
593 #else
594         for (i = 0; i < NumTextures; i++)
595                 Textures[i].index = cfile_read_short(fp);
596         read_tmap_info(fp, NumTextures, 0);
597 #endif
598
599         t = cfile_read_int(fp); 
600         cfread( Sounds, sizeof(ubyte), t, fp );
601         cfread( AltSounds, sizeof(ubyte), t, fp );
602
603         Num_vclips = cfile_read_int(fp);
604 #ifndef PORTABLE_LOADER
605         cfread( Vclip, sizeof(vclip), Num_vclips, fp );
606 #else
607         read_vclip_info(fp, Num_vclips, 0);
608 #endif
609
610         Num_effects = cfile_read_int(fp);
611 #ifndef PORTABLE_LOADER
612         cfread( Effects, sizeof(eclip), Num_effects, fp );
613 #else   
614         read_effect_info(fp, Num_effects, 0);
615 #endif
616
617         Num_wall_anims = cfile_read_int(fp);
618 #ifndef PORTABLE_LOADER
619         cfread( WallAnims, sizeof(wclip), Num_wall_anims, fp );
620 #else
621         read_wallanim_info(fp, Num_wall_anims, 0);
622 #endif
623
624         N_robot_types = cfile_read_int(fp);
625 #ifndef PORTABLE_LOADER
626         cfread( Robot_info, sizeof(robot_info), N_robot_types, fp );
627 #else
628         read_robot_info(fp, N_robot_types, 0);
629 #endif
630         N_robot_joints = cfile_read_int(fp);
631 #ifndef PORTABLE_LOADER
632         cfread( Robot_joints, sizeof(jointpos), N_robot_joints, fp );
633 #else
634         read_robot_joint_info(fp, N_robot_joints, 0);
635 #endif
636
637         N_weapon_types = cfile_read_int(fp);
638 #ifndef PORTABLE_LOADER
639         cfread( Weapon_info, sizeof(weapon_info), N_weapon_types, fp );
640 #else
641         read_weapon_info(fp, N_weapon_types, 0);
642 #endif
643
644         N_powerup_types = cfile_read_int(fp);
645 #ifndef PORTABLE_LOADER
646         cfread( Powerup_info, sizeof(powerup_type_info), N_powerup_types, fp );
647 #else
648         read_powerup_info(fp, N_powerup_types, 0);
649 #endif
650         
651         N_polygon_models = cfile_read_int(fp);
652 #ifndef PORTABLE_LOADER
653         cfread( Polygon_models, sizeof(polymodel), N_polygon_models, fp );
654 #else
655         read_polygon_models(fp, N_polygon_models, 0);
656 #endif
657
658         for (i=0; i<N_polygon_models; i++ )     {
659                 Polygon_models[i].model_data = d_malloc(Polygon_models[i].model_data_size);
660                 Assert( Polygon_models[i].model_data != NULL );
661                 cfread( Polygon_models[i].model_data, sizeof(ubyte), Polygon_models[i].model_data_size, fp );
662 #ifdef MACINTOSH
663                 swap_polygon_model_data(Polygon_models[i].model_data);
664 #endif
665                 g3_init_polygon_model(Polygon_models[i].model_data);
666         }
667
668         cfread( Dying_modelnums, sizeof(int), N_polygon_models, fp );
669         cfread( Dead_modelnums, sizeof(int), N_polygon_models, fp );
670 #ifdef MACINTOSH
671         for (i = 0; i < N_polygon_models; i++)
672                 Dying_modelnums[i]= SWAPINT(Dying_modelnums[i]);
673         for (i = 0; i < N_polygon_models; i++)
674                 Dead_modelnums[i]= SWAPINT(Dead_modelnums[i]);
675 #endif
676
677         t = cfile_read_int(fp);
678         cfread( Gauges, sizeof(bitmap_index), t, fp );
679         cfread( Gauges_hires, sizeof(bitmap_index), t, fp );
680 #ifdef MACINTOSH
681         for (i = 0; i < t; i++) {
682                 Gauges[i].index = SWAPSHORT(Gauges[i].index);
683                 Gauges_hires[i].index = SWAPSHORT(Gauges_hires[i].index);
684         }
685 #endif
686
687         t = cfile_read_int(fp);
688         cfread( ObjBitmaps, sizeof(bitmap_index), t, fp );
689         cfread( ObjBitmapPtrs, sizeof(ushort), t, fp );
690
691 #ifdef MACINTOSH
692 #ifdef SHAREWARE
693         N_ObjBitmaps = t;
694 #endif
695         for (i = 0; i < t; i++) {
696                 ObjBitmaps[i].index = SWAPSHORT(ObjBitmaps[i].index);
697                 ObjBitmapPtrs[i] = SWAPSHORT(ObjBitmapPtrs[i]);
698         }
699 #endif
700
701 #ifndef PORTABLE_LOADER
702         cfread( &only_player_ship, sizeof(player_ship), 1, fp );
703 #else
704         read_player_ship(fp);
705 #endif
706
707         Num_cockpits = cfile_read_int(fp);
708         cfread( cockpit_bitmap, sizeof(bitmap_index), Num_cockpits, fp );
709 #ifdef PORTABLE_LOADER
710         for (i = 0; i < Num_cockpits; i++)
711                 cockpit_bitmap[i].index = SWAPSHORT(cockpit_bitmap[i].index);
712 #endif
713
714 //@@    cfread( &Num_total_object_types, sizeof(int), 1, fp );
715 //@@    cfread( ObjType, sizeof(byte), Num_total_object_types, fp );
716 //@@    cfread( ObjId, sizeof(byte), Num_total_object_types, fp );
717 //@@    cfread( ObjStrength, sizeof(fix), Num_total_object_types, fp );
718
719         First_multi_bitmap_num = cfile_read_int(fp);
720
721         Num_reactors = cfile_read_int(fp);
722 #ifndef MACINTOSH
723         cfread( Reactors, sizeof(*Reactors), Num_reactors, fp);
724 #else
725         read_reactor_info(fp, Num_reactors, 0);
726 #endif
727
728         Marker_model_num = cfile_read_int(fp);
729
730         //@@cfread( &N_controlcen_guns, sizeof(int), 1, fp );
731         //@@cfread( controlcen_gun_points, sizeof(vms_vector), N_controlcen_guns, fp );
732         //@@cfread( controlcen_gun_dirs, sizeof(vms_vector), N_controlcen_guns, fp );
733
734         #ifdef SHAREWARE
735         exit_modelnum = cfile_read_int(fp);
736         destroyed_exit_modelnum = cfile_read_int(fp);
737         #endif
738
739 }
740
741
742 //these values are the number of each item in the release of d2
743 //extra items added after the release get written in an additional hamfile
744 #define N_D2_ROBOT_TYPES                66
745 #define N_D2_ROBOT_JOINTS               1145
746 #define N_D2_POLYGON_MODELS             166
747 #define N_D2_OBJBITMAPS                 422
748 #define N_D2_OBJBITMAPPTRS              502
749 #define N_D2_WEAPON_TYPES               62
750
751 //type==1 means 1.1, type==2 means 1.2 (with weaons)
752 void bm_read_extra_robots(char *fname,int type)
753 {
754         CFILE *fp;
755         int t,i;
756         int version;
757         
758         #ifdef MACINTOSH
759                 ulong varSave = 0;
760         #endif
761
762         fp = cfopen(fname,"rb");
763
764         if (type == 2) {
765                 int sig;
766
767                 sig = cfile_read_int(fp);
768                 if (sig != 0x5848414d) /* 'XHAM' */
769                         return;
770                 version = cfile_read_int(fp);
771         }
772         else
773                 version = 0;
774
775         //read extra weapons
776
777         t = cfile_read_int(fp);
778         N_weapon_types = N_D2_WEAPON_TYPES+t;
779         if (N_weapon_types >= MAX_WEAPON_TYPES)
780                 Error("Too many weapons (%d) in <%s>.  Max is %d.",t,fname,MAX_WEAPON_TYPES-N_D2_WEAPON_TYPES);
781         #ifdef MACINTOSH
782                 read_weapon_info(fp, t, N_D2_WEAPON_TYPES);
783         #else
784                 cfread( &Weapon_info[N_D2_WEAPON_TYPES], sizeof(weapon_info), t, fp );
785         #endif 
786         
787         //now read robot info
788
789         t = cfile_read_int(fp);
790         N_robot_types = N_D2_ROBOT_TYPES+t;
791         if (N_robot_types >= MAX_ROBOT_TYPES)
792                 Error("Too many robots (%d) in <%s>.  Max is %d.",t,fname,MAX_ROBOT_TYPES-N_D2_ROBOT_TYPES);
793         #ifdef MACINTOSH
794                 read_robot_info(fp, t, N_D2_ROBOT_TYPES);
795         #else
796                 cfread( &Robot_info[N_D2_ROBOT_TYPES], sizeof(robot_info), t, fp );
797         #endif
798         
799         t = cfile_read_int(fp);
800         N_robot_joints = N_D2_ROBOT_JOINTS+t;
801         if (N_robot_joints >= MAX_ROBOT_JOINTS)
802                 Error("Too many robot joints (%d) in <%s>.  Max is %d.",t,fname,MAX_ROBOT_JOINTS-N_D2_ROBOT_JOINTS);
803         #ifdef MACINTOSH
804                 read_robot_joint_info(fp, t, N_D2_ROBOT_JOINTS);
805         #else
806                 cfread( &Robot_joints[N_D2_ROBOT_JOINTS], sizeof(jointpos), t, fp );
807         #endif
808         
809         t = cfile_read_int(fp);
810         N_polygon_models = N_D2_POLYGON_MODELS+t;
811         if (N_polygon_models >= MAX_POLYGON_MODELS)
812                 Error("Too many polygon models (%d) in <%s>.  Max is %d.",t,fname,MAX_POLYGON_MODELS-N_D2_POLYGON_MODELS);
813         #ifdef MACINTOSH
814                 read_polygon_models(fp, t, N_D2_POLYGON_MODELS);
815         #else
816                 cfread( &Polygon_models[N_D2_POLYGON_MODELS], sizeof(polymodel), t, fp );
817         #endif
818         
819         for (i=N_D2_POLYGON_MODELS; i<N_polygon_models; i++ )
820         {
821                 Polygon_models[i].model_data = d_malloc(Polygon_models[i].model_data_size);
822                 Assert( Polygon_models[i].model_data != NULL );
823                 cfread( Polygon_models[i].model_data, sizeof(ubyte), Polygon_models[i].model_data_size, fp );
824                 
825                 #ifdef MACINTOSH
826                         swap_polygon_model_data(Polygon_models[i].model_data);
827                 #endif
828                 
829                 g3_init_polygon_model(Polygon_models[i].model_data);
830         }
831
832         cfread( &Dying_modelnums[N_D2_POLYGON_MODELS], sizeof(int), t, fp );
833         cfread( &Dead_modelnums[N_D2_POLYGON_MODELS], sizeof(int), t, fp );
834
835         #ifdef MACINTOSH
836                 for (i = N_D2_POLYGON_MODELS; i < N_polygon_models; i++)
837                 {
838                         Dying_modelnums[i]= SWAPINT(Dying_modelnums[i]);
839                         Dead_modelnums[i]= SWAPINT(Dead_modelnums[i]);
840                 }
841         #endif
842
843         t = cfile_read_int(fp);
844         if (N_D2_OBJBITMAPS+t >= MAX_OBJ_BITMAPS)
845                 Error("Too many object bitmaps (%d) in <%s>.  Max is %d.",t,fname,MAX_OBJ_BITMAPS-N_D2_OBJBITMAPS);
846         cfread( &ObjBitmaps[N_D2_OBJBITMAPS], sizeof(bitmap_index), t, fp );
847         #ifdef MACINTOSH
848                 for (i = N_D2_OBJBITMAPS; i < (N_D2_OBJBITMAPS + t); i++)
849                 {
850                         ObjBitmaps[i].index = SWAPSHORT(ObjBitmaps[i].index);
851                 }
852         #endif
853
854         t = cfile_read_int(fp);
855         if (N_D2_OBJBITMAPPTRS+t >= MAX_OBJ_BITMAPS)
856                 Error("Too many object bitmap pointers (%d) in <%s>.  Max is %d.",t,fname,MAX_OBJ_BITMAPS-N_D2_OBJBITMAPPTRS);
857         cfread( &ObjBitmapPtrs[N_D2_OBJBITMAPPTRS], sizeof(ushort), t, fp );
858         #ifdef MACINTOSH
859                 for (i = N_D2_OBJBITMAPPTRS; i < (N_D2_OBJBITMAPPTRS + t); i++)
860                 {
861                         ObjBitmapPtrs[i] = SWAPSHORT(ObjBitmapPtrs[i]);
862                 }
863         #endif
864
865         cfclose(fp);
866 }
867
868 extern void change_filename_extension( char *dest, char *src, char *new_ext );
869
870 int Robot_replacements_loaded = 0;
871
872 void load_robot_replacements(char *level_name)
873 {
874         CFILE *fp;
875         int t,i,j;
876         char ifile_name[FILENAME_LEN];
877
878         change_filename_extension(ifile_name, level_name, ".HXM" );
879         
880         fp = cfopen(ifile_name,"rb");
881
882         if (!fp)                //no robot replacement file
883                 return;
884
885         t = cfile_read_int(fp);                 //read id "HXM!"
886         if (t!= 0x21584d48) 
887                 Error("ID of HXM! file incorrect");
888
889         t = cfile_read_int(fp);                 //read version
890         if (t<1)
891                 Error("HXM! version too old (%d)",t); 
892
893         t = cfile_read_int(fp);                 //read number of robots
894         for (j=0;j<t;j++) {
895                 i = cfile_read_int(fp);         //read robot number
896            if (i<0 || i>=N_robot_types)
897                         Error("Robots number (%d) out of range in (%s).  Range = [0..%d].",i,level_name,N_robot_types-1);
898                 #ifdef MACINTOSH
899                         read_robot_info(fp, 1, i);
900                 #else
901                         cfread( &Robot_info[i], sizeof(robot_info), 1, fp );
902                 #endif
903         }
904
905         t = cfile_read_int(fp);                 //read number of joints
906         for (j=0;j<t;j++) {
907                 i = cfile_read_int(fp);         //read joint number
908                 if (i<0 || i>=N_robot_joints)
909                         Error("Robots joint (%d) out of range in (%s).  Range = [0..%d].",i,level_name,N_robot_joints-1);
910                 #ifdef MACINTOSH
911                         read_robot_joint_info(fp, 1, i);
912                 #else
913                         cfread( &Robot_joints[i], sizeof(jointpos), 1, fp );
914                 #endif
915         }
916
917         t = cfile_read_int(fp);                 //read number of polygon models
918         for (j=0;j<t;j++)
919         {
920                 i = cfile_read_int(fp);         //read model number
921                 if (i<0 || i>=N_polygon_models)
922                         Error("Polygon model (%d) out of range in (%s).  Range = [0..%d].",i,level_name,N_polygon_models-1);
923         
924                 #ifdef MACINTOSH
925                         read_polygon_models(fp, 1, i);
926                 #else
927                         cfread( &Polygon_models[i], sizeof(polymodel), 1, fp );
928                 #endif
929         
930                 d_free(Polygon_models[i].model_data);
931                 Polygon_models[i].model_data = d_malloc(Polygon_models[i].model_data_size);
932                 Assert( Polygon_models[i].model_data != NULL );
933
934                 cfread( Polygon_models[i].model_data, sizeof(ubyte), Polygon_models[i].model_data_size, fp );
935                 #ifdef MACINTOSH
936                         swap_polygon_model_data(Polygon_models[i].model_data);
937                 #endif
938                 g3_init_polygon_model(Polygon_models[i].model_data);
939
940                 Dying_modelnums[i] = cfile_read_int(fp);
941                 Dead_modelnums[i] = cfile_read_int(fp);
942         }
943
944         t = cfile_read_int(fp);                 //read number of objbitmaps
945         for (j=0;j<t;j++) {
946                 i = cfile_read_int(fp);         //read objbitmap number
947                 if (i<0 || i>=MAX_OBJ_BITMAPS)
948                         Error("Object bitmap number (%d) out of range in (%s).  Range = [0..%d].",i,level_name,MAX_OBJ_BITMAPS-1);
949                 ObjBitmaps[i].index = cfile_read_short(fp);
950         }
951
952         t = cfile_read_int(fp);                 //read number of objbitmapptrs
953         for (j=0;j<t;j++) {
954                 i = cfile_read_int(fp);         //read objbitmapptr number
955                 if (i<0 || i>=MAX_OBJ_BITMAPS)
956                         Error("Object bitmap pointer (%d) out of range in (%s).  Range = [0..%d].",i,level_name,MAX_OBJ_BITMAPS-1);
957                 ObjBitmapPtrs[i] = cfile_read_short(fp);
958         }
959
960         cfclose(fp);
961 }