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.
* *
*/ */
#pragma once
#ifndef _FIREBALL_H
#define _FIREBALL_H
#include <physfs.h> #include <physfs.h>
#ifdef __cplusplus #ifdef __cplusplus
#include "maths.h" #include "maths.h"
#include "fwd-partial_range.h"
struct vms_vector; struct vms_vector;
struct objptridx_t; struct objptridx_t;
@ -44,17 +43,24 @@ struct vobjptridx_t;
#define ET_MULTI_START 1 //first part of multi-part explosion #define ET_MULTI_START 1 //first part of multi-part explosion
#define ET_MULTI_SECOND 2 //second 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; segnum_t segnum;
int sidenum; uint8_t sidenum;
fix time; 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) // data for exploding walls (such as hostage door)
#define MAX_EXPLODING_WALLS 10 #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); 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); 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 * 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; extern fix Flash_effect;
#endif #endif
int pick_connected_segment(vobjptr_t objp, int max_depth); int pick_connected_segment(vobjptr_t objp, int max_depth);
#endif #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 "compiler-range_for.h"
#include "highest_valid.h" #include "highest_valid.h"
#include "partial_range.h"
#include "segiter.h" #include "segiter.h"
using std::min; 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 #define EXPL_WALL_FIREBALL_SIZE (0x48000*6/10) //smallest size
#endif #endif
expl_wall expl_wall_list[MAX_EXPLODING_WALLS]; array<expl_wall, MAX_EXPLODING_WALLS> expl_wall_list;
void init_exploding_walls() void init_exploding_walls()
{ {
int i; range_for (auto &i, expl_wall_list)
i.segnum = segment_none;
for (i=0;i<MAX_EXPLODING_WALLS;i++)
expl_wall_list[i].segnum = segment_none;
} }
//explode the given wall //explode the given wall
void explode_wall(const vsegptridx_t segnum,int sidenum) void explode_wall(const vsegptridx_t segnum,int sidenum)
{ {
int i;
//find a free slot //find a free slot
const auto e = end(expl_wall_list);
for (i=0;i<MAX_EXPLODING_WALLS && expl_wall_list[i].segnum != segment_none;i++); const auto predicate = [](expl_wall &e) {
return e.segnum == segment_none;
if (i==MAX_EXPLODING_WALLS) { //didn't find slot. };
const auto i = std::find_if(begin(expl_wall_list), e, predicate);
if (i == e)
{ //didn't find slot.
Int3(); Int3();
return; return;
} }
expl_wall_list[i].segnum = segnum; auto &w = *i;
expl_wall_list[i].sidenum = sidenum; w.segnum = segnum;
expl_wall_list[i].time = 0; w.sidenum = sidenum;
w.time = 0;
//play one long sound for whole door wall explosion //play one long sound for whole door wall explosion
const auto pos = compute_center_point_on_side(segnum,sidenum); 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 //note: this wall code assumes the wall is not triangulated
void do_exploding_wall_frame() void do_exploding_wall_frame()
{ {
int i; range_for (auto &i, expl_wall_list)
{
for (i=0;i<MAX_EXPLODING_WALLS;i++) { auto segnum = i.segnum;
auto segnum = expl_wall_list[i].segnum;
if (segnum != segment_none) { if (segnum != segment_none) {
int sidenum = expl_wall_list[i].sidenum; int sidenum = i.sidenum;
fix oldfrac,newfrac; fix oldfrac,newfrac;
int old_count,new_count,e; //n, 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; i.time += FrameTime;
if (expl_wall_list[i].time > EXPL_WALL_TIME) if (i.time > EXPL_WALL_TIME)
expl_wall_list[i].time = EXPL_WALL_TIME; i.time = EXPL_WALL_TIME;
const auto seg = vsegptridx(segnum); 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; int a,n;
a = Walls[seg->sides[sidenum].wall_num].clip_num; a = Walls[seg->sides[sidenum].wall_num].clip_num;
n = WallAnims[a].num_frames; 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)); old_count = f2i(EXPL_WALL_TOTAL_FIREBALLS * fixmul(oldfrac,oldfrac));
new_count = f2i(EXPL_WALL_TOTAL_FIREBALLS * fixmul(newfrac,newfrac)); 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); 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 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 else
object_create_badass_explosion( object_none, expl_wall_list[i].segnum, pos, object_create_badass_explosion( object_none, i.segnum, pos,
size, size,
VCLIP_SMALL_EXPLOSION, VCLIP_SMALL_EXPLOSION,
i2f(4), // damage strength i2f(4), // damage strength
@ -1338,13 +1339,9 @@ void do_exploding_wall_frame()
i2f(50), // damage force i2f(50), // damage force
object_none // parent id object_none // parent id
); );
} }
if (i.time >= EXPL_WALL_TIME)
if (expl_wall_list[i].time >= EXPL_WALL_TIME) i.segnum = segment_none; //flag this slot as free
expl_wall_list[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 * 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; range_for (auto &e, r)
{
PHYSFS_read(fp, ew, sizeof(expl_wall), n); disk_expl_wall d;
PHYSFS_read(fp, &d, sizeof(d), 1);
if (swap) if (swap)
for (i = 0; i < n; i++) {
expl_wall_swap(&ew[i], 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 #endif

View file

@ -1037,9 +1037,16 @@ int state_save_all_sub(const char *filename, const char *desc)
#if defined(DXX_BUILD_DESCENT_II) #if defined(DXX_BUILD_DESCENT_II)
//Save exploding wall info //Save exploding wall info
i = MAX_EXPLODING_WALLS; i = expl_wall_list.size();
PHYSFS_write(fp, &i, sizeof(int), 1); 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 #endif
//Save door info //Save door info
@ -1511,8 +1518,8 @@ int state_restore_all_sub(const char *filename, int secret_restore)
//Restore exploding wall info //Restore exploding wall info
if (version >= 10) { if (version >= 10) {
i = PHYSFSX_readSXE32(fp, swap); unsigned i = PHYSFSX_readSXE32(fp, swap);
expl_wall_read_n_swap(expl_wall_list, i, swap, fp); expl_wall_read_n_swap(fp, swap, partial_range(expl_wall_list, i));
} }
#endif #endif