dxx-rebirth/similar/main/paging.cpp

358 lines
8.5 KiB
C++
Raw Normal View History

2006-03-20 16:43:15 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING.txt.
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below.
* See COPYING.txt for license details.
2006-03-20 16:43:15 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
2006-03-20 16:43:15 +00:00
*/
2006-03-20 16:43:15 +00:00
/*
*
* Routines for paging in/out textures.
2006-03-20 16:43:15 +00:00
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "pstypes.h"
2006-03-20 16:43:15 +00:00
#include "inferno.h"
#include "segment.h"
#include "textures.h"
#include "wall.h"
#include "object.h"
#include "gamemine.h"
#include "dxxerror.h"
2006-03-20 16:43:15 +00:00
#include "gameseg.h"
#include "game.h"
#include "piggy.h"
#include "texmerge.h"
#include "paging.h"
#include "laser.h"
#include "robot.h"
2006-03-20 16:43:15 +00:00
#include "vclip.h"
#include "effects.h"
#include "fireball.h"
#include "weapon.h"
#include "palette.h"
#include "timer.h"
#include "text.h"
#include "cntrlcen.h"
#include "gauges.h"
#include "powerup.h"
#include "fuelcen.h"
#include "mission.h"
#include "ai.h"
2014-04-27 23:12:34 +00:00
#include "compiler-range_for.h"
2014-10-12 23:10:05 +00:00
#include "highest_valid.h"
2014-04-27 23:12:34 +00:00
#include "partial_range.h"
#include "segiter.h"
2006-03-20 16:43:15 +00:00
2015-08-22 20:43:03 +00:00
static void paging_touch_vclip(const vclip &vc)
2006-03-20 16:43:15 +00:00
{
2015-08-22 20:43:03 +00:00
range_for (const auto &i, partial_range(vc.frames, vc.num_frames))
2014-09-20 23:47:27 +00:00
{
PIGGY_PAGE_IN(i);
2006-03-20 16:43:15 +00:00
}
}
2013-10-27 22:00:14 +00:00
static void paging_touch_wall_effects( int tmap_num )
2006-03-20 16:43:15 +00:00
{
2014-09-20 23:47:27 +00:00
range_for (auto &i, partial_range(Effects, Num_effects))
{
if ( i.changing_wall_texture == tmap_num ) {
2015-08-22 20:43:03 +00:00
paging_touch_vclip(i.vc);
2006-03-20 16:43:15 +00:00
2014-09-20 23:47:27 +00:00
if (i.dest_bm_num > -1)
PIGGY_PAGE_IN( Textures[i.dest_bm_num] ); //use this bitmap when monitor destroyed
if ( i.dest_vclip > -1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[i.dest_vclip]); //what vclip to play when exploding
2006-03-20 16:43:15 +00:00
2014-09-20 23:47:27 +00:00
if ( i.dest_eclip > -1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Effects[i.dest_eclip].vc); //what eclip to play when exploding
2006-03-20 16:43:15 +00:00
2014-09-20 23:47:27 +00:00
if ( i.crit_clip > -1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Effects[i.crit_clip].vc); //what eclip to play when mine critical
break;
2006-03-20 16:43:15 +00:00
}
}
}
2013-10-27 22:00:14 +00:00
static void paging_touch_object_effects( int tmap_num )
2006-03-20 16:43:15 +00:00
{
2014-09-20 23:47:27 +00:00
range_for (auto &i, partial_range(Effects, Num_effects))
{
if ( i.changing_object_texture == tmap_num ) {
2015-08-22 20:43:03 +00:00
paging_touch_vclip(i.vc);
break;
2006-03-20 16:43:15 +00:00
}
}
}
2013-10-27 22:00:14 +00:00
static void paging_touch_model( int modelnum )
2006-03-20 16:43:15 +00:00
{
2015-08-22 20:43:03 +00:00
const auto &pm = Polygon_models[modelnum];
uint_fast32_t i = pm.first_texture;
for (const uint_fast32_t e = i + pm.n_textures; i != e; ++i)
{
const auto p = ObjBitmapPtrs[i];
PIGGY_PAGE_IN(ObjBitmaps[p]);
paging_touch_object_effects(p);
2006-03-20 16:43:15 +00:00
}
}
2015-08-22 20:43:03 +00:00
static void paging_touch_weapon(const weapon_info &weapon)
2006-03-20 16:43:15 +00:00
{
// Page in the robot's weapons.
2015-08-22 20:43:03 +00:00
if(weapon.picture.index)
{
PIGGY_PAGE_IN(weapon.picture);
2006-03-20 16:43:15 +00:00
}
2015-08-22 20:43:03 +00:00
if (weapon.flash_vclip > -1)
paging_touch_vclip(Vclip[weapon.flash_vclip]);
if (weapon.wall_hit_vclip > -1)
paging_touch_vclip(Vclip[weapon.wall_hit_vclip]);
if (weapon.damage_radius)
{
2006-03-20 16:43:15 +00:00
// Robot_hit_vclips are actually badass_vclips
2015-08-22 20:43:03 +00:00
if (weapon.robot_hit_vclip > -1)
paging_touch_vclip(Vclip[weapon.robot_hit_vclip]);
2006-03-20 16:43:15 +00:00
}
2015-08-22 20:43:03 +00:00
switch(weapon.render_type)
{
2006-03-20 16:43:15 +00:00
case WEAPON_RENDER_VCLIP:
2015-08-22 20:43:03 +00:00
if (weapon.weapon_vclip > -1)
paging_touch_vclip(Vclip[weapon.weapon_vclip]);
2006-03-20 16:43:15 +00:00
break;
case WEAPON_RENDER_NONE:
break;
case WEAPON_RENDER_POLYMODEL:
2015-08-22 20:43:03 +00:00
paging_touch_model(weapon.model_num);
2006-03-20 16:43:15 +00:00
break;
case WEAPON_RENDER_BLOB:
2015-08-22 20:43:03 +00:00
PIGGY_PAGE_IN(weapon.bitmap);
2006-03-20 16:43:15 +00:00
break;
}
}
2015-08-22 20:43:03 +00:00
static void paging_touch_weapon(uint_fast32_t weapon_type)
{
if (weapon_type < N_weapon_types)
paging_touch_weapon(Weapon_info[weapon_type]);
}
2015-04-02 02:36:52 +00:00
const array<sbyte, 13> super_boss_gate_type_list{{0, 1, 8, 9, 10, 11, 12, 15, 16, 18, 19, 20, 22}};
2006-03-20 16:43:15 +00:00
2013-10-27 22:00:14 +00:00
static void paging_touch_robot( int robot_index )
2006-03-20 16:43:15 +00:00
{
// Page in robot_index
paging_touch_model(Robot_info[robot_index].model_num);
if ( Robot_info[robot_index].exp1_vclip_num>-1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[Robot_info[robot_index].exp1_vclip_num]);
2006-03-20 16:43:15 +00:00
if ( Robot_info[robot_index].exp2_vclip_num>-1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[Robot_info[robot_index].exp2_vclip_num]);
2006-03-20 16:43:15 +00:00
// Page in his weapons
paging_touch_weapon( Robot_info[robot_index].weapon_type );
// A super-boss can gate in robots...
if (Robot_info[robot_index].boss_flag == BOSS_SUPER)
{
2015-02-14 22:48:27 +00:00
range_for (const auto i, super_boss_gate_type_list)
paging_touch_robot(i);
2006-03-20 16:43:15 +00:00
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[VCLIP_MORPHING_ROBOT]);
2006-03-20 16:43:15 +00:00
}
}
2014-10-02 03:02:34 +00:00
static void paging_touch_object(const vcobjptr_t obj)
2006-03-20 16:43:15 +00:00
{
int v;
switch (obj->render_type) {
case RT_NONE: break; //doesn't render, like the player
case RT_POLYOBJ:
if ( obj->rtype.pobj_info.tmap_override != -1 )
PIGGY_PAGE_IN( Textures[obj->rtype.pobj_info.tmap_override] );
else
paging_touch_model(obj->rtype.pobj_info.model_num);
2006-03-20 16:43:15 +00:00
break;
case RT_POWERUP:
if ( obj->rtype.vclip_info.vclip_num > -1 ) {
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[obj->rtype.vclip_info.vclip_num]);
}
2006-03-20 16:43:15 +00:00
break;
case RT_MORPH: break;
case RT_FIREBALL: break;
case RT_WEAPON_VCLIP: break;
case RT_HOSTAGE:
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[obj->rtype.vclip_info.vclip_num]);
2006-03-20 16:43:15 +00:00
break;
case RT_LASER: break;
}
switch (obj->type) {
case OBJ_PLAYER:
v = get_explosion_vclip(obj, 0);
if ( v > -1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[v]);
2006-03-20 16:43:15 +00:00
break;
case OBJ_ROBOT:
paging_touch_robot( get_robot_id(obj) );
2006-03-20 16:43:15 +00:00
break;
case OBJ_CNTRLCEN:
paging_touch_weapon( CONTROLCEN_WEAPON_NUM );
if (Dead_modelnums[obj->rtype.pobj_info.model_num] != -1) {
paging_touch_model( Dead_modelnums[obj->rtype.pobj_info.model_num] );
}
break;
}
}
2014-10-02 03:02:34 +00:00
static void paging_touch_side(const vcsegptr_t segp, int sidenum )
2006-03-20 16:43:15 +00:00
{
int tmap1, tmap2;
if (!(WALL_IS_DOORWAY(segp,sidenum) & WID_RENDER_FLAG))
return;
tmap1 = segp->sides[sidenum].tmap_num;
paging_touch_wall_effects(tmap1);
tmap2 = segp->sides[sidenum].tmap_num2;
if (tmap2 != 0) {
texmerge_get_cached_bitmap( tmap1, tmap2 );
paging_touch_wall_effects( tmap2 & 0x3FFF );
} else {
PIGGY_PAGE_IN( Textures[tmap1] );
}
}
2014-10-02 03:02:34 +00:00
static void paging_touch_robot_maker(const vcsegptr_t segp )
2006-03-20 16:43:15 +00:00
{
if ( segp->special == SEGMENT_IS_ROBOTMAKER ) {
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[VCLIP_MORPHING_ROBOT]);
2006-03-20 16:43:15 +00:00
uint flags;
int robot_index;
for (unsigned i=0;i<sizeof(RobotCenters[0].robot_flags)/sizeof(RobotCenters[0].robot_flags[0]);i++) {
robot_index = i*32;
flags = RobotCenters[segp->matcen_num].robot_flags[i];
while (flags) {
if (flags & 1) {
// Page in robot_index
paging_touch_robot( robot_index );
}
flags >>= 1;
robot_index++;
2006-03-20 16:43:15 +00:00
}
}
2006-03-20 16:43:15 +00:00
}
}
2014-10-02 03:02:34 +00:00
static void paging_touch_segment(const vcsegptr_t segp)
2006-03-20 16:43:15 +00:00
{
if ( segp->special == SEGMENT_IS_ROBOTMAKER )
2006-03-20 16:43:15 +00:00
paging_touch_robot_maker(segp);
// paging_draw_orb();
for (int sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) {
2006-03-20 16:43:15 +00:00
// paging_draw_orb();
paging_touch_side( segp, sn );
}
range_for (const auto objp, objects_in(*segp))
paging_touch_object(objp);
2006-03-20 16:43:15 +00:00
}
2013-10-27 22:00:14 +00:00
static void paging_touch_walls()
2006-03-20 16:43:15 +00:00
{
wclip *anim;
2014-04-27 23:12:34 +00:00
range_for (auto &w, partial_range(Walls, Num_walls))
{
2006-03-20 16:43:15 +00:00
// paging_draw_orb();
2014-04-27 23:12:34 +00:00
if ( w.clip_num > -1 ) {
anim = &WallAnims[w.clip_num];
for (int j=0; j < anim->num_frames; j++ ) {
2006-03-20 16:43:15 +00:00
PIGGY_PAGE_IN( Textures[anim->frames[j]] );
}
}
}
}
void paging_touch_all()
{
stop_time();
#if defined(DXX_BUILD_DESCENT_I)
show_boxed_message(TXT_LOADING, 0);
#endif
range_for (const auto s, highest_valid(Segments))
2014-10-12 23:10:05 +00:00
{
2015-06-13 22:42:18 +00:00
const auto &&segp = vcsegptr(static_cast<segnum_t>(s));
paging_touch_segment(segp);
2006-03-20 16:43:15 +00:00
}
paging_touch_walls();
2014-09-20 23:47:27 +00:00
range_for (auto &s, partial_range(Powerup_info, N_powerup_types))
{
if ( s.vclip_num > -1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[s.vclip_num]);
2006-03-20 16:43:15 +00:00
}
2015-08-22 20:43:03 +00:00
range_for (const auto &w, partial_range(Weapon_info, N_weapon_types))
{
paging_touch_weapon(w);
2006-03-20 16:43:15 +00:00
}
2014-09-20 23:47:27 +00:00
range_for (auto &s, partial_range(Powerup_info, N_powerup_types))
{
if ( s.vclip_num > -1 )
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[s.vclip_num]);
2006-03-20 16:43:15 +00:00
}
2014-09-20 23:47:27 +00:00
range_for (auto &s, Gauges)
{
if ( s.index ) {
PIGGY_PAGE_IN( s );
2006-03-20 16:43:15 +00:00
}
}
2015-08-22 20:43:03 +00:00
paging_touch_vclip(Vclip[VCLIP_PLAYER_APPEARANCE]);
paging_touch_vclip(Vclip[VCLIP_POWERUP_DISAPPEARANCE]);
2006-03-20 16:43:15 +00:00
start_time();
reset_cockpit(); //force cockpit redraw next time
}