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