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