Use array<> for expl_wall_list

Fixes: 125d9257be ("Use special type names for segment/object numbers")
This commit is contained in:
Kp 2015-02-28 19:36:01 +00:00
parent b940ca0510
commit a9a330bf3f
3 changed files with 68 additions and 63 deletions

View file

@ -23,14 +23,13 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
*
*/
#ifndef _FIREBALL_H
#define _FIREBALL_H
#pragma once
#include <physfs.h>
#ifdef __cplusplus
#include "maths.h"
#include "fwd-partial_range.h"
struct vms_vector;
struct objptridx_t;
@ -44,17 +43,24 @@ struct vobjptridx_t;
#define ET_MULTI_START 1 //first part of multi-part explosion
#define ET_MULTI_SECOND 2 //second part of multi-part explosion
struct expl_wall
struct expl_wall : prohibit_void_ptr<expl_wall>
{
segnum_t segnum;
int sidenum;
uint8_t sidenum;
fix time;
};
struct disk_expl_wall
{
int segnum, sidenum;
fix time;
};
static_assert(sizeof(disk_expl_wall) == 12, "sizeof(disk_expl_wall) wrong");
// data for exploding walls (such as hostage door)
#define MAX_EXPLODING_WALLS 10
extern expl_wall expl_wall_list[MAX_EXPLODING_WALLS];
extern array<expl_wall, MAX_EXPLODING_WALLS> expl_wall_list;
objptridx_t object_create_explosion(vsegptridx_t segnum, const vms_vector &position, fix size, int vclip_type);
void object_create_muzzle_flash(vsegptridx_t segnum, const vms_vector &position, fix size, int vclip_type);
@ -92,12 +98,10 @@ void drop_afterburner_blobs(vobjptr_t obj, int count, fix size_scale, fix lifeti
/*
* reads n expl_wall structs from a PHYSFS_file and swaps if specified
*/
extern void expl_wall_read_n_swap(expl_wall *ew, int n, int swap, PHYSFS_file *fp);
void expl_wall_read_n_swap(PHYSFS_file *fp, int swap, partial_range_t<expl_wall *>);
extern fix Flash_effect;
#endif
int pick_connected_segment(vobjptr_t objp, int max_depth);
#endif
#endif /* _FIREBALL_H */

View file

@ -65,6 +65,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "compiler-range_for.h"
#include "highest_valid.h"
#include "partial_range.h"
#include "segiter.h"
using std::min;
@ -1227,32 +1228,33 @@ void do_explosion_sequence(const vobjptr_t obj)
#define EXPL_WALL_FIREBALL_SIZE (0x48000*6/10) //smallest size
#endif
expl_wall expl_wall_list[MAX_EXPLODING_WALLS];
array<expl_wall, MAX_EXPLODING_WALLS> expl_wall_list;
void init_exploding_walls()
{
int i;
for (i=0;i<MAX_EXPLODING_WALLS;i++)
expl_wall_list[i].segnum = segment_none;
range_for (auto &i, expl_wall_list)
i.segnum = segment_none;
}
//explode the given wall
void explode_wall(const vsegptridx_t segnum,int sidenum)
{
int i;
//find a free slot
for (i=0;i<MAX_EXPLODING_WALLS && expl_wall_list[i].segnum != segment_none;i++);
if (i==MAX_EXPLODING_WALLS) { //didn't find slot.
const auto e = end(expl_wall_list);
const auto predicate = [](expl_wall &e) {
return e.segnum == segment_none;
};
const auto i = std::find_if(begin(expl_wall_list), e, predicate);
if (i == e)
{ //didn't find slot.
Int3();
return;
}
expl_wall_list[i].segnum = segnum;
expl_wall_list[i].sidenum = sidenum;
expl_wall_list[i].time = 0;
auto &w = *i;
w.segnum = segnum;
w.sidenum = sidenum;
w.time = 0;
//play one long sound for whole door wall explosion
const auto pos = compute_center_point_on_side(segnum,sidenum);
@ -1264,24 +1266,23 @@ void explode_wall(const vsegptridx_t segnum,int sidenum)
//note: this wall code assumes the wall is not triangulated
void do_exploding_wall_frame()
{
int i;
for (i=0;i<MAX_EXPLODING_WALLS;i++) {
auto segnum = expl_wall_list[i].segnum;
range_for (auto &i, expl_wall_list)
{
auto segnum = i.segnum;
if (segnum != segment_none) {
int sidenum = expl_wall_list[i].sidenum;
int sidenum = i.sidenum;
fix oldfrac,newfrac;
int old_count,new_count,e; //n,
oldfrac = fixdiv(expl_wall_list[i].time,EXPL_WALL_TIME);
oldfrac = fixdiv(i.time,EXPL_WALL_TIME);
expl_wall_list[i].time += FrameTime;
if (expl_wall_list[i].time > EXPL_WALL_TIME)
expl_wall_list[i].time = EXPL_WALL_TIME;
i.time += FrameTime;
if (i.time > EXPL_WALL_TIME)
i.time = EXPL_WALL_TIME;
const auto seg = vsegptridx(segnum);
if (expl_wall_list[i].time>(EXPL_WALL_TIME*3)/4) {
if (i.time>(EXPL_WALL_TIME*3)/4) {
int a,n;
a = Walls[seg->sides[sidenum].wall_num].clip_num;
n = WallAnims[a].num_frames;
@ -1296,7 +1297,7 @@ void do_exploding_wall_frame()
}
newfrac = fixdiv(expl_wall_list[i].time,EXPL_WALL_TIME);
newfrac = fixdiv(i.time,EXPL_WALL_TIME);
old_count = f2i(EXPL_WALL_TOTAL_FIREBALLS * fixmul(oldfrac,oldfrac));
new_count = f2i(EXPL_WALL_TOTAL_FIREBALLS * fixmul(newfrac,newfrac));
@ -1328,9 +1329,9 @@ void do_exploding_wall_frame()
vm_vec_scale_add2(pos,Segments[segnum].sides[sidenum].normals[0],size*(EXPL_WALL_TOTAL_FIREBALLS-e)/EXPL_WALL_TOTAL_FIREBALLS);
if (e & 3) //3 of 4 are normal
object_create_explosion(expl_wall_list[i].segnum,pos,size,VCLIP_SMALL_EXPLOSION);
object_create_explosion(i.segnum,pos,size,VCLIP_SMALL_EXPLOSION);
else
object_create_badass_explosion( object_none, expl_wall_list[i].segnum, pos,
object_create_badass_explosion( object_none, i.segnum, pos,
size,
VCLIP_SMALL_EXPLOSION,
i2f(4), // damage strength
@ -1338,13 +1339,9 @@ void do_exploding_wall_frame()
i2f(50), // damage force
object_none // parent id
);
}
if (expl_wall_list[i].time >= EXPL_WALL_TIME)
expl_wall_list[i].segnum = segment_none; //flag this slot as free
if (i.time >= EXPL_WALL_TIME)
i.segnum = segment_none; //flag this slot as free
}
}
@ -1375,27 +1372,24 @@ void drop_afterburner_blobs(const vobjptr_t obj, int count, fix size_scale, fix
}
}
static void expl_wall_swap(expl_wall *ew, int swap)
{
if (!swap)
return;
ew->segnum = SWAPINT(ew->segnum);
ew->sidenum = SWAPINT(ew->sidenum);
ew->time = SWAPINT(ew->time);
}
/*
* reads n expl_wall structs from a PHYSFS_file and swaps if specified
*/
void expl_wall_read_n_swap(expl_wall *ew, int n, int swap, PHYSFS_file *fp)
void expl_wall_read_n_swap(PHYSFS_file *fp, int swap, partial_range_t<expl_wall *> r)
{
int i;
PHYSFS_read(fp, ew, sizeof(expl_wall), n);
if (swap)
for (i = 0; i < n; i++)
expl_wall_swap(&ew[i], swap);
range_for (auto &e, r)
{
disk_expl_wall d;
PHYSFS_read(fp, &d, sizeof(d), 1);
if (swap)
{
d.segnum = SWAPINT(d.segnum);
d.sidenum = SWAPINT(d.sidenum);
d.time = SWAPINT(d.time);
}
e.segnum = d.segnum;
e.sidenum = d.sidenum;
e.time = d.time;
}
}
#endif

View file

@ -1037,9 +1037,16 @@ int state_save_all_sub(const char *filename, const char *desc)
#if defined(DXX_BUILD_DESCENT_II)
//Save exploding wall info
i = MAX_EXPLODING_WALLS;
i = expl_wall_list.size();
PHYSFS_write(fp, &i, sizeof(int), 1);
PHYSFS_write(fp, expl_wall_list, sizeof(*expl_wall_list), i);
range_for (auto &e, expl_wall_list)
{
disk_expl_wall d;
d.segnum = e.segnum;
d.sidenum = e.sidenum;
d.time = e.time;
PHYSFS_write(fp, &d, sizeof(d), 1);
}
#endif
//Save door info
@ -1511,8 +1518,8 @@ int state_restore_all_sub(const char *filename, int secret_restore)
//Restore exploding wall info
if (version >= 10) {
i = PHYSFSX_readSXE32(fp, swap);
expl_wall_read_n_swap(expl_wall_list, i, swap, fp);
unsigned i = PHYSFSX_readSXE32(fp, swap);
expl_wall_read_n_swap(fp, swap, partial_range(expl_wall_list, i));
}
#endif