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
paging_touch_vclip_w(vclip * vc)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 
paging_touch_vclip(vclip * vc)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 
paging_touch_wall_effects(int tmap_num)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 
paging_touch_object_effects(int tmap_num)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 
paging_touch_model(int modelnum)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 
paging_touch_weapon(int weapon_type)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 
paging_touch_robot(int robot_index)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 
paging_touch_object(object * obj)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 
paging_touch_side(segment * segp,int sidenum)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 
paging_touch_robot_maker(segment * segp)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 
paging_touch_segment(segment * segp)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 
paging_touch_walls()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 
paging_touch_all()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 
516