whitespace
[btb/d2x.git] / main / paging.c
1 //#define PSX_BUILD_TOOLS
2
3 /*
4 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
5 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
6 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
7 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
8 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
9 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
10 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
11 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
12 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
13 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
14 */
15
16 #ifdef HAVE_CONFIG_H
17 #include <conf.h>
18 #endif
19
20 #ifdef RCS
21 static char rcsid[] = "$Id: paging.c,v 1.2 2001-01-31 15:17:57 bradleyb Exp $";
22 #endif
23
24 #ifdef WINDOWS
25 #include "desw.h"
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <math.h>
31 #include <string.h>
32
33 #include "pstypes.h"
34 #include "mono.h"
35 #include "inferno.h"
36 #include "segment.h"
37 #include "textures.h"
38 #include "wall.h"
39 #include "object.h"
40 #include "gamemine.h"
41 #include "error.h"
42 #include "gameseg.h"
43 #include "game.h"
44 #include "piggy.h"
45 #include "texmerge.h"
46 #include "polyobj.h"
47 #include "vclip.h"
48 #include "effects.h"
49 #include "fireball.h"
50 #include "weapon.h"
51 #include "palette.h"
52 #include "timer.h"
53 #include "text.h"
54 #include "cntrlcen.h"
55 #include "gauges.h"
56 #include "powerup.h"
57 #include "fuelcen.h"
58 #include "mission.h"
59
60
61 #ifdef WINDOWS
62 void paging_touch_vclip_w( vclip * vc )
63 {
64         int i;
65
66         for (i=0; i<vc->num_frames; i++ )       {
67                 if ( GameBitmaps[(vc->frames[i]).index].bm_flags & BM_FLAG_PAGED_OUT) 
68                         piggy_bitmap_page_in_w( vc->frames[i],1 );
69         }
70 }
71 #endif
72
73
74 void paging_touch_vclip( vclip * vc )
75 {
76         int i;
77
78         for (i=0; i<vc->num_frames; i++ )       {
79                 PIGGY_PAGE_IN( vc->frames[i] );
80         }
81 }
82
83
84 void paging_touch_wall_effects( int tmap_num )
85 {
86         int i;
87
88         for (i=0;i<Num_effects;i++)     {
89                 if ( Effects[i].changing_wall_texture == tmap_num )     {
90                         paging_touch_vclip( &Effects[i].vc );
91
92                         if (Effects[i].dest_bm_num > -1)
93                                 PIGGY_PAGE_IN( Textures[Effects[i].dest_bm_num] );      //use this bitmap when monitor destroyed
94                         if ( Effects[i].dest_vclip > -1 )
95                                 paging_touch_vclip( &Vclip[Effects[i].dest_vclip] );              //what vclip to play when exploding
96
97                         if ( Effects[i].dest_eclip > -1 )
98                                 paging_touch_vclip( &Effects[Effects[i].dest_eclip].vc ); //what eclip to play when exploding
99
100                         if ( Effects[i].crit_clip > -1 )
101                                 paging_touch_vclip( &Effects[Effects[i].crit_clip].vc ); //what eclip to play when mine critical
102                 }
103
104         }
105 }
106
107 void paging_touch_object_effects( int tmap_num )
108 {
109         int i;
110
111         for (i=0;i<Num_effects;i++)     {
112                 if ( Effects[i].changing_object_texture == tmap_num )   {
113                         paging_touch_vclip( &Effects[i].vc );
114                 }
115         }
116 }
117
118
119 void paging_touch_model( int modelnum )
120 {
121         int i;
122         polymodel *pm = &Polygon_models[modelnum];
123
124         for (i=0;i<pm->n_textures;i++)  {
125                 PIGGY_PAGE_IN( ObjBitmaps[ObjBitmapPtrs[pm->first_texture+i]] );
126                 paging_touch_object_effects( ObjBitmapPtrs[pm->first_texture+i] );
127                 #ifdef PSX_BUILD_TOOLS
128                 // cmp added
129                 paging_touch_object_effects( pm->first_texture+i );
130                 #endif
131         }
132 }
133
134 void paging_touch_weapon( int weapon_type )
135 {
136         // Page in the robot's weapons.
137         
138         if ( (weapon_type < 0) || (weapon_type > N_weapon_types) ) return;
139
140         if ( Weapon_info[weapon_type].picture.index )   {
141                 PIGGY_PAGE_IN( Weapon_info[weapon_type].picture );
142         }               
143         
144         if ( Weapon_info[weapon_type].flash_vclip > -1 )
145                 paging_touch_vclip(&Vclip[Weapon_info[weapon_type].flash_vclip]);
146         if ( Weapon_info[weapon_type].wall_hit_vclip > -1 )
147                 paging_touch_vclip(&Vclip[Weapon_info[weapon_type].wall_hit_vclip]);
148         if ( Weapon_info[weapon_type].damage_radius )   {
149                 // Robot_hit_vclips are actually badass_vclips
150                 if ( Weapon_info[weapon_type].robot_hit_vclip > -1 )
151                         paging_touch_vclip(&Vclip[Weapon_info[weapon_type].robot_hit_vclip]);
152         }
153
154         switch( Weapon_info[weapon_type].render_type )  {
155         case WEAPON_RENDER_VCLIP:
156                 if ( Weapon_info[weapon_type].weapon_vclip > -1 )
157                         paging_touch_vclip( &Vclip[Weapon_info[weapon_type].weapon_vclip] );
158                 break;
159         case WEAPON_RENDER_NONE:
160                 break;
161         case WEAPON_RENDER_POLYMODEL:
162                 paging_touch_model( Weapon_info[weapon_type].model_num );
163                 break;
164         case WEAPON_RENDER_BLOB:
165                 PIGGY_PAGE_IN( Weapon_info[weapon_type].bitmap );
166                 break;
167         }
168 }
169
170
171
172 byte super_boss_gate_type_list[13] = {0, 1, 8, 9, 10, 11, 12, 15, 16, 18, 19, 20, 22 };
173
174 void paging_touch_robot( int robot_index )
175 {
176         int i;
177
178         //mprintf((0, "Robot %d loading...", robot_index));
179
180         // Page in robot_index
181         paging_touch_model(Robot_info[robot_index].model_num);
182         if ( Robot_info[robot_index].exp1_vclip_num>-1 )
183                 paging_touch_vclip(&Vclip[Robot_info[robot_index].exp1_vclip_num]);
184         if ( Robot_info[robot_index].exp2_vclip_num>-1 )
185                 paging_touch_vclip(&Vclip[Robot_info[robot_index].exp2_vclip_num]);
186
187         // Page in his weapons
188         paging_touch_weapon( Robot_info[robot_index].weapon_type );
189
190         // A super-boss can gate in robots...
191         if ( Robot_info[robot_index].boss_flag==2 )     {
192                 for (i=0; i<13; i++ )
193                         paging_touch_robot(super_boss_gate_type_list[i]);
194
195                 paging_touch_vclip( &Vclip[VCLIP_MORPHING_ROBOT] );
196         }
197 }
198
199
200 void paging_touch_object( object * obj )
201 {
202         int v;
203
204         switch (obj->render_type) {
205
206                 case RT_NONE:   break;          //doesn't render, like the player
207
208                 case RT_POLYOBJ:
209                         if ( obj->rtype.pobj_info.tmap_override != -1 )
210                                 PIGGY_PAGE_IN( Textures[obj->rtype.pobj_info.tmap_override] );
211                         else
212                                 paging_touch_model(obj->rtype.pobj_info.model_num);
213                         break;
214
215                 case RT_POWERUP: 
216                         if ( obj->rtype.vclip_info.vclip_num > -1 ) {
217                 //@@    #ifdef WINDOWS
218                 //@@            paging_touch_vclip_w(&Vclip[obj->rtype.vclip_info.vclip_num]);
219                 //@@    #else
220                                 paging_touch_vclip(&Vclip[obj->rtype.vclip_info.vclip_num]);
221                 //@@    #endif
222                         }
223                         break;
224
225                 case RT_MORPH:  break;
226
227                 case RT_FIREBALL: break;
228
229                 case RT_WEAPON_VCLIP: break;
230
231                 case RT_HOSTAGE: 
232                         paging_touch_vclip(&Vclip[obj->rtype.vclip_info.vclip_num]);
233                         break;
234
235                 case RT_LASER: break;
236         }
237
238         switch (obj->type) {    
239         case OBJ_PLAYER:        
240                 v = get_explosion_vclip(obj, 0);
241                 if ( v > -1 )
242                         paging_touch_vclip(&Vclip[v]);
243                 break;
244         case OBJ_ROBOT:
245                 paging_touch_robot( obj->id );
246                 break;
247         case OBJ_CNTRLCEN:
248                 paging_touch_weapon( CONTROLCEN_WEAPON_NUM );
249                 if (Dead_modelnums[obj->rtype.pobj_info.model_num] != -1)       {
250                         paging_touch_model( Dead_modelnums[obj->rtype.pobj_info.model_num] );
251                 }
252                 break;
253         }
254 }
255
256         
257
258 void paging_touch_side( segment * segp, int sidenum )
259 {
260         int tmap1, tmap2;
261
262         if (!(WALL_IS_DOORWAY(segp,sidenum) & WID_RENDER_FLAG))
263                 return;
264         
265         tmap1 = segp->sides[sidenum].tmap_num;
266         paging_touch_wall_effects(tmap1);
267         tmap2 = segp->sides[sidenum].tmap_num2;
268         if (tmap2 != 0) {
269                 texmerge_get_cached_bitmap( tmap1, tmap2 );
270                 paging_touch_wall_effects( tmap2 & 0x3FFF );
271         } else  {
272                 PIGGY_PAGE_IN( Textures[tmap1] );
273         }
274
275         // PSX STUFF
276         #ifdef PSX_BUILD_TOOLS
277                 // If there is water on the level, then force the water splash into memory
278                 if(!(TmapInfo[tmap1].flags & TMI_VOLATILE) && (TmapInfo[tmap1].flags & TMI_WATER)) {
279                         bitmap_index Splash;
280                         Splash.index = 1098;
281                         PIGGY_PAGE_IN(Splash);
282                         Splash.index = 1099;
283                         PIGGY_PAGE_IN(Splash);
284                         Splash.index = 1100;
285                         PIGGY_PAGE_IN(Splash);
286                         Splash.index = 1101;
287                         PIGGY_PAGE_IN(Splash);
288                         Splash.index = 1102;
289                         PIGGY_PAGE_IN(Splash);
290                 }
291         #endif
292
293 }
294
295 void paging_touch_robot_maker( segment * segp )
296 {
297         segment2        *seg2p = &Segment2s[segp-Segments];
298
299         if ( seg2p->special == SEGMENT_IS_ROBOTMAKER )  {
300                 paging_touch_vclip(&Vclip[VCLIP_MORPHING_ROBOT]);
301                 if (RobotCenters[seg2p->matcen_num].robot_flags != 0) {
302                         int     i;
303                         uint    flags;
304                         int     robot_index;
305
306                         for (i=0;i<2;i++) {
307                                 robot_index = i*32;
308                                 flags = RobotCenters[seg2p->matcen_num].robot_flags[i];
309                                 while (flags) {
310                                         if (flags & 1)  {
311                                                 // Page in robot_index
312                                                 paging_touch_robot( robot_index );
313                                         }
314                                         flags >>= 1;
315                                         robot_index++;
316                                 }
317                         }
318                 }
319         }
320 }
321
322
323 void paging_touch_segment(segment * segp)
324 {
325         int sn;
326         int objnum;
327         segment2        *seg2p = &Segment2s[segp-Segments];
328
329         if ( seg2p->special == SEGMENT_IS_ROBOTMAKER )  
330                 paging_touch_robot_maker(segp);
331
332 //      paging_draw_orb();
333         for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) {
334 //              paging_draw_orb();
335                 paging_touch_side( segp, sn );
336         }
337
338         for (objnum=segp->objects;objnum!=-1;objnum=Objects[objnum].next)       {
339 //              paging_draw_orb();
340                 paging_touch_object( &Objects[objnum] );
341         }
342 }
343
344
345
346 void paging_touch_walls()
347 {
348         int i,j;
349         wclip *anim;
350
351         for (i=0;i<Num_walls;i++) {
352 //              paging_draw_orb();
353                 if ( Walls[i].clip_num > -1 )   {
354                         anim = &WallAnims[Walls[i].clip_num];
355                         for (j=0; j < anim->num_frames; j++ )   {
356                                 PIGGY_PAGE_IN( Textures[anim->frames[j]] );
357                         }
358                 }
359         }
360 }
361
362 void paging_touch_all()
363 {
364         int black_screen;
365         int s;
366         
367         stop_time();
368
369         black_screen = gr_palette_faded_out;
370
371         if ( gr_palette_faded_out )     {
372                 gr_clear_canvas( BM_XRGB(0,0,0) );
373                 gr_palette_load( gr_palette );
374         }
375         
376 //@@    show_boxed_message(TXT_LOADING);
377
378         mprintf(( 0, "Loading all textures in mine..." ));
379         for (s=0; s<=Highest_segment_index; s++)        {
380                 paging_touch_segment( &Segments[s] );
381         }       
382         paging_touch_walls();
383
384         for ( s=0; s < N_powerup_types; s++ )   {
385                 if ( Powerup_info[s].vclip_num > -1 )   
386                         paging_touch_vclip(&Vclip[Powerup_info[s].vclip_num]);
387         }
388
389         for ( s=0; s<N_weapon_types; s++ )      {
390                 paging_touch_weapon(s);
391         }
392
393         for ( s=0; s < N_powerup_types; s++ )   {
394                 if ( Powerup_info[s].vclip_num > -1 )   
395                         paging_touch_vclip(&Vclip[Powerup_info[s].vclip_num]);
396         }
397
398
399         for (s=0; s<MAX_GAUGE_BMS; s++ )        {
400                 if ( Gauges[s].index )  {
401                         PIGGY_PAGE_IN( Gauges[s] );
402                 }
403         }
404         paging_touch_vclip( &Vclip[VCLIP_PLAYER_APPEARANCE] );
405         paging_touch_vclip( &Vclip[VCLIP_POWERUP_DISAPPEARANCE] );
406
407
408 #ifdef PSX_BUILD_TOOLS
409
410         //PSX STUFF 
411         paging_touch_walls();
412         for(s=0; s<=Highest_object_index; s++) {
413                 paging_touch_object(&Objects[s]);
414         }
415
416
417         {
418                 char * p;
419                 extern int Current_level_num;
420                 extern ushort GameBitmapXlat[MAX_BITMAP_FILES];
421                 short Used[MAX_BITMAP_FILES];
422                 FILE * fp;
423                 char fname[128];
424                 int i;
425
426                 if (Current_level_num<0)                //secret level
427                         strcpy( fname, Secret_level_names[-Current_level_num-1] );
428                 else                                    //normal level
429                         strcpy( fname, Level_names[Current_level_num-1] );
430                 p = strchr( fname, '.' );
431                 if ( p ) *p = 0;
432                 strcat( fname, ".pag" );
433
434                 fp = fopen( fname, "wt" );
435                 for (i=0; i<MAX_BITMAP_FILES;i++ )      {
436                         Used[i] = 0;
437                 }
438                 for (i=0; i<MAX_BITMAP_FILES;i++ )      {
439                         Used[GameBitmapXlat[i]]++;
440                 }
441
442                 //cmp added so that .damage bitmaps are included for paged-in lights of the current level
443                 for (i=0; i<MAX_TEXTURES;i++) {
444                         if(Textures[i].index > 0 && Textures[i].index < MAX_BITMAP_FILES && 
445                                 Used[Textures[i].index] > 0 &&
446                                 TmapInfo[i].destroyed > 0 && TmapInfo[i].destroyed < MAX_BITMAP_FILES) {
447                                 Used[Textures[TmapInfo[i].destroyed].index] += 1;
448                                 mprintf((0, "HERE %d ", Textures[TmapInfo[i].destroyed].index));
449
450                                 PIGGY_PAGE_IN(Textures[TmapInfo[i].destroyed]);
451
452                         }
453                 }
454
455                 //      Force cockpit to be paged in.
456                 {
457                         bitmap_index bonk;
458                         bonk.index = 109;
459                         PIGGY_PAGE_IN(bonk);
460                 }
461
462                 // Force in the frames for markers
463                 {
464                         bitmap_index bonk2;
465                         bonk2.index = 2014;
466                         PIGGY_PAGE_IN(bonk2);
467                         bonk2.index = 2015;
468                         PIGGY_PAGE_IN(bonk2);
469                         bonk2.index = 2016;
470                         PIGGY_PAGE_IN(bonk2);
471                         bonk2.index = 2017;
472                         PIGGY_PAGE_IN(bonk2);
473                         bonk2.index = 2018;
474                         PIGGY_PAGE_IN(bonk2);
475                 }
476
477                 for (i=0; i<MAX_BITMAP_FILES;i++ )      {
478                         int paged_in = 1;
479                         // cmp debug
480                         //piggy_get_bitmap_name(i,fname);
481
482                         if (GameBitmaps[i].bm_flags & BM_FLAG_PAGED_OUT ) 
483                                 paged_in = 0;
484
485 //                      if (GameBitmapXlat[i]!=i)
486 //                              paged_in = 0;
487
488                         if ( !Used[i] )
489                                 paged_in = 0;
490                         if ( (i==47) || (i==48) )               // Mark red mplayer ship textures as paged in.
491                                 paged_in = 1;
492         
493                         if ( !paged_in )
494                                 fprintf( fp, "0,\t// Bitmap %d (%s)\n", i, "test\0"); // cmp debug fname );
495                         else
496                                 fprintf( fp, "1,\t// Bitmap %d (%s)\n", i, "test\0"); // cmp debug fname );
497                 }
498
499                 fclose(fp);
500         }
501 #endif
502
503         mprintf(( 0, "done\n" ));
504
505 //@@    clear_boxed_message();
506
507         if ( black_screen )     {
508                 gr_palette_clear();
509                 gr_clear_canvas( BM_XRGB(0,0,0) );
510         }
511         start_time();
512         reset_cockpit();                //force cockpit redraw next time
513
514 }
515