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