]> icculus.org git repositories - btb/d2x.git/blob - main/paging.c
implement repair centers
[btb/d2x.git] / main / paging.c
1 /* $Id: paging.c,v 1.3 2003-10-04 03:14:47 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Routines for paging in/out textures.
18  *
19  * Old Log:
20  * Revision 1.5  1995/10/30  11:06:58  allender
21  * added change to paging code ala John -- check tmap_override
22  * when paging in robots
23  *
24  * Revision 1.4  1995/09/13  08:48:28  allender
25  * John's new paging code
26  *
27  * Revision 1.3  1995/08/18  10:20:31  allender
28  * changed hard coded black pixel value to use BM_XRGB
29  *
30  * Revision 1.2  1995/07/26  17:02:10  allender
31  * small fix to page in effect bitmaps correctly
32  *
33  * Revision 1.1  1995/05/16  15:29:35  allender
34  * Initial revision
35  *
36  * Revision 2.5  1995/10/07  13:18:21  john
37  * Added PSX debugging stuff that builds .PAG files.
38  *
39  * Revision 2.4  1995/08/24  13:40:03  john
40  * Added code to page in vclip for powerup disapperance and to
41  * fix bug that made robot makers not page in the correct bot
42  * textures.
43  *
44  * Revision 2.3  1995/07/26  12:09:19  john
45  * Made code that pages in weapon_info->robot_hit_vclip not
46  * page in unless it is a badass weapon.  Took out old functionallity
47  * of using this if no robot exp1_vclip, since all robots have these.
48  *
49  * Revision 2.2  1995/07/24  13:22:11  john
50  * Made sure everything gets paged in at the
51  * level start.  Fixed bug with robot effects not
52  * getting paged in correctly.
53  *
54  * Revision 2.1  1995/05/12  15:50:16  allender
55  * fix to check effects dest_bm_num > -1 before paging in
56  *
57  * Revision 2.0  1995/02/27  11:27:39  john
58  * New version 2.0, which has no anonymous unions, builds with
59  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
60  *
61  * Revision 1.18  1995/02/22  14:12:28  allender
62  * remove anonyous union from object structure
63  *
64  * Revision 1.17  1995/02/11  22:54:15  john
65  * Made loading for pig not show up for demos.
66  *
67  * Revision 1.16  1995/02/11  22:37:04  john
68  * Made cockpit redraw.
69  *
70  * Revision 1.15  1995/01/28  16:29:35  john
71  * *** empty log message ***
72  *
73  * Revision 1.14  1995/01/27  17:16:18  john
74  * Added code to page in all the weapons.
75  *
76  * Revision 1.13  1995/01/24  21:51:22  matt
77  * Clear the boxed message to fix a mem leakage
78  *
79  * Revision 1.12  1995/01/23  13:00:46  john
80  * Added hostage vclip paging.
81  *
82  * Revision 1.11  1995/01/23  12:29:52  john
83  * Added code to page in eclip on robots, dead control center,
84  * gauges bitmaps, and weapon pictures.
85  *
86  * Revision 1.10  1995/01/21  12:54:15  adam
87  * *** empty log message ***
88  *
89  * Revision 1.9  1995/01/21  12:41:29  adam
90  * changed orb to loading box
91  *
92  * Revision 1.8  1995/01/18  15:09:02  john
93  * Added start/stop time around paging.
94  * Made paging clear screen around globe.
95  *
96  * Revision 1.7  1995/01/18  10:37:00  john
97  * Added code to page in exploding monitors.
98  *
99  * Revision 1.6  1995/01/17  19:03:35  john
100  * Added cool spinning orb during loading.
101  *
102  * Revision 1.5  1995/01/17  14:49:26  john
103  * Paged in weapons.
104  *
105  * Revision 1.4  1995/01/17  12:14:07  john
106  * Made walls, object explosion vclips load at level start.
107  *
108  * Revision 1.3  1995/01/15  13:23:24  john
109  * First working version
110  *
111  * Revision 1.2  1995/01/15  11:56:45  john
112  * Working version of paging.
113  *
114  * Revision 1.1  1995/01/15  11:33:37  john
115  * Initial revision
116  *
117  *
118  */
119
120 #ifdef HAVE_CONFIG_H
121 #include <conf.h>
122 #endif
123
124 //#define PSX_BUILD_TOOLS
125
126 #ifdef RCS
127 static char rcsid[] = "$Id: paging.c,v 1.3 2003-10-04 03:14:47 btb Exp $";
128 #endif
129
130 #ifdef WINDOWS
131 #include "desw.h"
132 #endif
133
134 #include <stdio.h>
135 #include <stdlib.h>
136 #include <math.h>
137 #include <string.h>
138
139 #include "pstypes.h"
140 #include "mono.h"
141 #include "inferno.h"
142 #include "segment.h"
143 #include "textures.h"
144 #include "wall.h"
145 #include "object.h"
146 #include "gamemine.h"
147 #include "error.h"
148 #include "gameseg.h"
149 #include "game.h"
150 #include "piggy.h"
151 #include "texmerge.h"
152 #include "polyobj.h"
153 #include "vclip.h"
154 #include "effects.h"
155 #include "fireball.h"
156 #include "weapon.h"
157 #include "palette.h"
158 #include "timer.h"
159 #include "text.h"
160 #include "cntrlcen.h"
161 #include "gauges.h"
162 #include "powerup.h"
163 #include "fuelcen.h"
164 #include "mission.h"
165
166
167 #ifdef WINDOWS
168 void paging_touch_vclip_w( vclip * vc )
169 {
170         int i;
171
172         for (i=0; i<vc->num_frames; i++ )       {
173                 if ( GameBitmaps[(vc->frames[i]).index].bm_flags & BM_FLAG_PAGED_OUT)
174                         piggy_bitmap_page_in_w( vc->frames[i],1 );
175         }
176 }
177 #endif
178
179
180 void paging_touch_vclip( vclip * vc )
181 {
182         int i;
183
184         for (i=0; i<vc->num_frames; i++ )       {
185                 PIGGY_PAGE_IN( vc->frames[i] );
186         }
187 }
188
189
190 void paging_touch_wall_effects( int tmap_num )
191 {
192         int i;
193
194         for (i=0;i<Num_effects;i++)     {
195                 if ( Effects[i].changing_wall_texture == tmap_num )     {
196                         paging_touch_vclip( &Effects[i].vc );
197
198                         if (Effects[i].dest_bm_num > -1)
199                                 PIGGY_PAGE_IN( Textures[Effects[i].dest_bm_num] );      //use this bitmap when monitor destroyed
200                         if ( Effects[i].dest_vclip > -1 )
201                                 paging_touch_vclip( &Vclip[Effects[i].dest_vclip] );              //what vclip to play when exploding
202
203                         if ( Effects[i].dest_eclip > -1 )
204                                 paging_touch_vclip( &Effects[Effects[i].dest_eclip].vc ); //what eclip to play when exploding
205
206                         if ( Effects[i].crit_clip > -1 )
207                                 paging_touch_vclip( &Effects[Effects[i].crit_clip].vc ); //what eclip to play when mine critical
208                 }
209
210         }
211 }
212
213 void paging_touch_object_effects( int tmap_num )
214 {
215         int i;
216
217         for (i=0;i<Num_effects;i++)     {
218                 if ( Effects[i].changing_object_texture == tmap_num )   {
219                         paging_touch_vclip( &Effects[i].vc );
220                 }
221         }
222 }
223
224
225 void paging_touch_model( int modelnum )
226 {
227         int i;
228         polymodel *pm = &Polygon_models[modelnum];
229
230         for (i=0;i<pm->n_textures;i++)  {
231                 PIGGY_PAGE_IN( ObjBitmaps[ObjBitmapPtrs[pm->first_texture+i]] );
232                 paging_touch_object_effects( ObjBitmapPtrs[pm->first_texture+i] );
233                 #ifdef PSX_BUILD_TOOLS
234                 // cmp added
235                 paging_touch_object_effects( pm->first_texture+i );
236                 #endif
237         }
238 }
239
240 void paging_touch_weapon( int weapon_type )
241 {
242         // Page in the robot's weapons.
243         
244         if ( (weapon_type < 0) || (weapon_type > N_weapon_types) ) return;
245
246         if ( Weapon_info[weapon_type].picture.index )   {
247                 PIGGY_PAGE_IN( Weapon_info[weapon_type].picture );
248         }               
249         
250         if ( Weapon_info[weapon_type].flash_vclip > -1 )
251                 paging_touch_vclip(&Vclip[Weapon_info[weapon_type].flash_vclip]);
252         if ( Weapon_info[weapon_type].wall_hit_vclip > -1 )
253                 paging_touch_vclip(&Vclip[Weapon_info[weapon_type].wall_hit_vclip]);
254         if ( Weapon_info[weapon_type].damage_radius )   {
255                 // Robot_hit_vclips are actually badass_vclips
256                 if ( Weapon_info[weapon_type].robot_hit_vclip > -1 )
257                         paging_touch_vclip(&Vclip[Weapon_info[weapon_type].robot_hit_vclip]);
258         }
259
260         switch( Weapon_info[weapon_type].render_type )  {
261         case WEAPON_RENDER_VCLIP:
262                 if ( Weapon_info[weapon_type].weapon_vclip > -1 )
263                         paging_touch_vclip( &Vclip[Weapon_info[weapon_type].weapon_vclip] );
264                 break;
265         case WEAPON_RENDER_NONE:
266                 break;
267         case WEAPON_RENDER_POLYMODEL:
268                 paging_touch_model( Weapon_info[weapon_type].model_num );
269                 break;
270         case WEAPON_RENDER_BLOB:
271                 PIGGY_PAGE_IN( Weapon_info[weapon_type].bitmap );
272                 break;
273         }
274 }
275
276
277
278 sbyte super_boss_gate_type_list[13] = {0, 1, 8, 9, 10, 11, 12, 15, 16, 18, 19, 20, 22 };
279
280 void paging_touch_robot( int robot_index )
281 {
282         int i;
283
284         //mprintf((0, "Robot %d loading...", robot_index));
285
286         // Page in robot_index
287         paging_touch_model(Robot_info[robot_index].model_num);
288         if ( Robot_info[robot_index].exp1_vclip_num>-1 )
289                 paging_touch_vclip(&Vclip[Robot_info[robot_index].exp1_vclip_num]);
290         if ( Robot_info[robot_index].exp2_vclip_num>-1 )
291                 paging_touch_vclip(&Vclip[Robot_info[robot_index].exp2_vclip_num]);
292
293         // Page in his weapons
294         paging_touch_weapon( Robot_info[robot_index].weapon_type );
295
296         // A super-boss can gate in robots...
297         if ( Robot_info[robot_index].boss_flag==2 )     {
298                 for (i=0; i<13; i++ )
299                         paging_touch_robot(super_boss_gate_type_list[i]);
300
301                 paging_touch_vclip( &Vclip[VCLIP_MORPHING_ROBOT] );
302         }
303 }
304
305
306 void paging_touch_object( object * obj )
307 {
308         int v;
309
310         switch (obj->render_type) {
311
312                 case RT_NONE:   break;          //doesn't render, like the player
313
314                 case RT_POLYOBJ:
315                         if ( obj->rtype.pobj_info.tmap_override != -1 )
316                                 PIGGY_PAGE_IN( Textures[obj->rtype.pobj_info.tmap_override] );
317                         else
318                                 paging_touch_model(obj->rtype.pobj_info.model_num);
319                         break;
320
321                 case RT_POWERUP:
322                         if ( obj->rtype.vclip_info.vclip_num > -1 ) {
323                 //@@    #ifdef WINDOWS
324                 //@@            paging_touch_vclip_w(&Vclip[obj->rtype.vclip_info.vclip_num]);
325                 //@@    #else
326                                 paging_touch_vclip(&Vclip[obj->rtype.vclip_info.vclip_num]);
327                 //@@    #endif
328                         }
329                         break;
330
331                 case RT_MORPH:  break;
332
333                 case RT_FIREBALL: break;
334
335                 case RT_WEAPON_VCLIP: break;
336
337                 case RT_HOSTAGE:
338                         paging_touch_vclip(&Vclip[obj->rtype.vclip_info.vclip_num]);
339                         break;
340
341                 case RT_LASER: break;
342         }
343
344         switch (obj->type) {    
345         case OBJ_PLAYER:        
346                 v = get_explosion_vclip(obj, 0);
347                 if ( v > -1 )
348                         paging_touch_vclip(&Vclip[v]);
349                 break;
350         case OBJ_ROBOT:
351                 paging_touch_robot( obj->id );
352                 break;
353         case OBJ_CNTRLCEN:
354                 paging_touch_weapon( CONTROLCEN_WEAPON_NUM );
355                 if (Dead_modelnums[obj->rtype.pobj_info.model_num] != -1)       {
356                         paging_touch_model( Dead_modelnums[obj->rtype.pobj_info.model_num] );
357                 }
358                 break;
359         }
360 }
361
362         
363
364 void paging_touch_side( segment * segp, int sidenum )
365 {
366         int tmap1, tmap2;
367
368         if (!(WALL_IS_DOORWAY(segp,sidenum) & WID_RENDER_FLAG))
369                 return;
370         
371         tmap1 = segp->sides[sidenum].tmap_num;
372         paging_touch_wall_effects(tmap1);
373         tmap2 = segp->sides[sidenum].tmap_num2;
374         if (tmap2 != 0) {
375                 texmerge_get_cached_bitmap( tmap1, tmap2 );
376                 paging_touch_wall_effects( tmap2 & 0x3FFF );
377         } else  {
378                 PIGGY_PAGE_IN( Textures[tmap1] );
379         }
380
381         // PSX STUFF
382         #ifdef PSX_BUILD_TOOLS
383                 // If there is water on the level, then force the water splash into memory
384                 if(!(TmapInfo[tmap1].flags & TMI_VOLATILE) && (TmapInfo[tmap1].flags & TMI_WATER)) {
385                         bitmap_index Splash;
386                         Splash.index = 1098;
387                         PIGGY_PAGE_IN(Splash);
388                         Splash.index = 1099;
389                         PIGGY_PAGE_IN(Splash);
390                         Splash.index = 1100;
391                         PIGGY_PAGE_IN(Splash);
392                         Splash.index = 1101;
393                         PIGGY_PAGE_IN(Splash);
394                         Splash.index = 1102;
395                         PIGGY_PAGE_IN(Splash);
396                 }
397         #endif
398
399 }
400
401 void paging_touch_robot_maker( segment * segp )
402 {
403         segment2        *seg2p = &Segment2s[segp-Segments];
404
405         if ( seg2p->special == SEGMENT_IS_ROBOTMAKER )  {
406                 paging_touch_vclip(&Vclip[VCLIP_MORPHING_ROBOT]);
407                 if (RobotCenters[seg2p->matcen_num].robot_flags != 0) {
408                         int     i;
409                         uint    flags;
410                         int     robot_index;
411
412                         for (i=0;i<2;i++) {
413                                 robot_index = i*32;
414                                 flags = RobotCenters[seg2p->matcen_num].robot_flags[i];
415                                 while (flags) {
416                                         if (flags & 1)  {
417                                                 // Page in robot_index
418                                                 paging_touch_robot( robot_index );
419                                         }
420                                         flags >>= 1;
421                                         robot_index++;
422                                 }
423                         }
424                 }
425         }
426 }
427
428
429 void paging_touch_segment(segment * segp)
430 {
431         int sn;
432         int objnum;
433         segment2        *seg2p = &Segment2s[segp-Segments];
434
435         if ( seg2p->special == SEGMENT_IS_ROBOTMAKER )  
436                 paging_touch_robot_maker(segp);
437
438 //      paging_draw_orb();
439         for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) {
440 //              paging_draw_orb();
441                 paging_touch_side( segp, sn );
442         }
443
444         for (objnum=segp->objects;objnum!=-1;objnum=Objects[objnum].next)       {
445 //              paging_draw_orb();
446                 paging_touch_object( &Objects[objnum] );
447         }
448 }
449
450
451
452 void paging_touch_walls()
453 {
454         int i,j;
455         wclip *anim;
456
457         for (i=0;i<Num_walls;i++) {
458 //              paging_draw_orb();
459                 if ( Walls[i].clip_num > -1 )   {
460                         anim = &WallAnims[Walls[i].clip_num];
461                         for (j=0; j < anim->num_frames; j++ )   {
462                                 PIGGY_PAGE_IN( Textures[anim->frames[j]] );
463                         }
464                 }
465         }
466 }
467
468 void paging_touch_all()
469 {
470         int black_screen;
471         int s;
472         
473         stop_time();
474
475         black_screen = gr_palette_faded_out;
476
477         if ( gr_palette_faded_out )     {
478                 gr_clear_canvas( BM_XRGB(0,0,0) );
479                 gr_palette_load( gr_palette );
480         }
481         
482 //@@    show_boxed_message(TXT_LOADING);
483
484         mprintf(( 0, "Loading all textures in mine..." ));
485         for (s=0; s<=Highest_segment_index; s++)        {
486                 paging_touch_segment( &Segments[s] );
487         }       
488         paging_touch_walls();
489
490         for ( s=0; s < N_powerup_types; s++ )   {
491                 if ( Powerup_info[s].vclip_num > -1 )   
492                         paging_touch_vclip(&Vclip[Powerup_info[s].vclip_num]);
493         }
494
495         for ( s=0; s<N_weapon_types; s++ )      {
496                 paging_touch_weapon(s);
497         }
498
499         for ( s=0; s < N_powerup_types; s++ )   {
500                 if ( Powerup_info[s].vclip_num > -1 )   
501                         paging_touch_vclip(&Vclip[Powerup_info[s].vclip_num]);
502         }
503
504
505         for (s=0; s<MAX_GAUGE_BMS; s++ )        {
506                 if ( Gauges[s].index )  {
507                         PIGGY_PAGE_IN( Gauges[s] );
508                 }
509         }
510         paging_touch_vclip( &Vclip[VCLIP_PLAYER_APPEARANCE] );
511         paging_touch_vclip( &Vclip[VCLIP_POWERUP_DISAPPEARANCE] );
512
513
514 #ifdef PSX_BUILD_TOOLS
515
516         //PSX STUFF
517         paging_touch_walls();
518         for(s=0; s<=Highest_object_index; s++) {
519                 paging_touch_object(&Objects[s]);
520         }
521
522
523         {
524                 char * p;
525                 extern int Current_level_num;
526                 extern ushort GameBitmapXlat[MAX_BITMAP_FILES];
527                 short Used[MAX_BITMAP_FILES];
528                 FILE * fp;
529                 char fname[128];
530                 int i;
531
532                 if (Current_level_num<0)                //secret level
533                         strcpy( fname, Secret_level_names[-Current_level_num-1] );
534                 else                                    //normal level
535                         strcpy( fname, Level_names[Current_level_num-1] );
536                 p = strchr( fname, '.' );
537                 if ( p ) *p = 0;
538                 strcat( fname, ".pag" );
539
540                 fp = fopen( fname, "wt" );
541                 for (i=0; i<MAX_BITMAP_FILES;i++ )      {
542                         Used[i] = 0;
543                 }
544                 for (i=0; i<MAX_BITMAP_FILES;i++ )      {
545                         Used[GameBitmapXlat[i]]++;
546                 }
547
548                 //cmp added so that .damage bitmaps are included for paged-in lights of the current level
549                 for (i=0; i<MAX_TEXTURES;i++) {
550                         if(Textures[i].index > 0 && Textures[i].index < MAX_BITMAP_FILES &&
551                                 Used[Textures[i].index] > 0 &&
552                                 TmapInfo[i].destroyed > 0 && TmapInfo[i].destroyed < MAX_BITMAP_FILES) {
553                                 Used[Textures[TmapInfo[i].destroyed].index] += 1;
554                                 mprintf((0, "HERE %d ", Textures[TmapInfo[i].destroyed].index));
555
556                                 PIGGY_PAGE_IN(Textures[TmapInfo[i].destroyed]);
557
558                         }
559                 }
560
561                 //      Force cockpit to be paged in.
562                 {
563                         bitmap_index bonk;
564                         bonk.index = 109;
565                         PIGGY_PAGE_IN(bonk);
566                 }
567
568                 // Force in the frames for markers
569                 {
570                         bitmap_index bonk2;
571                         bonk2.index = 2014;
572                         PIGGY_PAGE_IN(bonk2);
573                         bonk2.index = 2015;
574                         PIGGY_PAGE_IN(bonk2);
575                         bonk2.index = 2016;
576                         PIGGY_PAGE_IN(bonk2);
577                         bonk2.index = 2017;
578                         PIGGY_PAGE_IN(bonk2);
579                         bonk2.index = 2018;
580                         PIGGY_PAGE_IN(bonk2);
581                 }
582
583                 for (i=0; i<MAX_BITMAP_FILES;i++ )      {
584                         int paged_in = 1;
585                         // cmp debug
586                         //piggy_get_bitmap_name(i,fname);
587
588                         if (GameBitmaps[i].bm_flags & BM_FLAG_PAGED_OUT )
589                                 paged_in = 0;
590
591 //                      if (GameBitmapXlat[i]!=i)
592 //                              paged_in = 0;
593
594                         if ( !Used[i] )
595                                 paged_in = 0;
596                         if ( (i==47) || (i==48) )               // Mark red mplayer ship textures as paged in.
597                                 paged_in = 1;
598         
599                         if ( !paged_in )
600                                 fprintf( fp, "0,\t// Bitmap %d (%s)\n", i, "test\0"); // cmp debug fname );
601                         else
602                                 fprintf( fp, "1,\t// Bitmap %d (%s)\n", i, "test\0"); // cmp debug fname );
603                 }
604
605                 fclose(fp);
606         }
607 #endif
608
609         mprintf(( 0, "done\n" ));
610
611 //@@    clear_boxed_message();
612
613         if ( black_screen )     {
614                 gr_palette_clear();
615                 gr_clear_canvas( BM_XRGB(0,0,0) );
616         }
617         start_time();
618         reset_cockpit();                //force cockpit redraw next time
619
620 }
621