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