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