diff --git a/common/main/bm.h b/common/main/bm.h index 5488952a7..58ddd038b 100644 --- a/common/main/bm.h +++ b/common/main/bm.h @@ -28,6 +28,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include #include "maths.h" #include "fwd-vclip.h" +#include "d_array.h" struct bitmap_index; @@ -153,8 +154,12 @@ constexpr std::integral_constant MAX_OBJ_BITMAPS{}; extern unsigned N_ObjBitmaps; #endif -extern std::array ObjBitmaps; -extern std::array ObjBitmapPtrs; +enum class object_bitmap_index : uint16_t +{ + None = UINT16_MAX +}; +extern enumerated_array ObjBitmaps; +extern std::array ObjBitmapPtrs; } diff --git a/common/main/effects.h b/common/main/effects.h index c51d797b1..7279d8383 100644 --- a/common/main/effects.h +++ b/common/main/effects.h @@ -28,6 +28,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "vclip.h" #include "dxxsconf.h" #include "pack.h" +#include "bm.h" #include #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) @@ -60,7 +61,7 @@ struct eclip : public prohibit_void_ptr fix time_left; //for sequencing uint32_t frame_count; //for sequencing short changing_wall_texture; //Which element of Textures array to replace. - short changing_object_texture; //Which element of ObjBitmapPtrs array to replace. + object_bitmap_index changing_object_texture; //Which element of ObjBitmapPtrs array to replace. int flags; //see above int crit_clip; //use this clip instead of above one when mine critical unsigned dest_bm_num; //use this bitmap when monitor destroyed diff --git a/d1x-rebirth/main/custom.cpp b/d1x-rebirth/main/custom.cpp index 8ec8d1a7e..484b02c1e 100644 --- a/d1x-rebirth/main/custom.cpp +++ b/d1x-rebirth/main/custom.cpp @@ -571,10 +571,10 @@ static void load_hxm(const d_fname &hxmname) { for (i = 0; i < n_items; i++) { - repl_num = PHYSFSX_readInt(f); + const auto oi = static_cast(PHYSFSX_readInt(f)); auto v = PHYSFSX_readShort(f); - if (repl_num < ObjBitmaps.size()) - ObjBitmaps[repl_num].index = v; + if (ObjBitmaps.valid_index(oi)) + ObjBitmaps[oi].index = v; } } } diff --git a/similar/arch/ogl/ogl.cpp b/similar/arch/ogl/ogl.cpp index 7aaa3c6c8..61287014f 100644 --- a/similar/arch/ogl/ogl.cpp +++ b/similar/arch/ogl/ogl.cpp @@ -434,7 +434,7 @@ void ogl_cache_level_textures(void) range_for (auto &ec, partial_const_range(Effects, Num_effects)) { ogl_cache_vclipn_textures(Vclip, ec.dest_vclip); - if ((ec.changing_wall_texture == -1) && (ec.changing_object_texture==-1) ) + if (ec.changing_wall_texture == -1 && ec.changing_object_texture == object_bitmap_index::None) continue; if (ec.vc.num_frames>max_efx) max_efx=ec.vc.num_frames; @@ -443,7 +443,7 @@ void ogl_cache_level_textures(void) for (ef=0;ef ObjBitmaps; -std::array ObjBitmapPtrs; // These point back into ObjBitmaps, since some are used twice. +enumerated_array ObjBitmaps; +std::array ObjBitmapPtrs; // These point back into ObjBitmaps, since some are used twice. void gamedata_close() { @@ -225,7 +225,13 @@ void properties_read_cmp(d_vclip_array &Vclip, PHYSFS_File * fp) bitmap_index_read_n(fp, ObjBitmaps); range_for (auto &i, ObjBitmapPtrs) - i = PHYSFSX_readShort(fp); + { + const auto oi = static_cast(PHYSFSX_readShort(fp)); + if (ObjBitmaps.valid_index(oi)) + i = oi; + else + i = {}; + } player_ship_read(&only_player_ship, fp); @@ -360,7 +366,13 @@ void bm_read_all(d_vclip_array &Vclip, PHYSFS_File * fp) N_ObjBitmaps = PHYSFSX_readInt(fp); bitmap_index_read_n(fp, partial_range(ObjBitmaps, N_ObjBitmaps)); range_for (auto &i, partial_range(ObjBitmapPtrs, N_ObjBitmaps)) - i = PHYSFSX_readShort(fp); + { + const auto oi = static_cast(PHYSFSX_readShort(fp)); + if (ObjBitmaps.valid_index(oi)) + i = oi; + else + i = {}; + } player_ship_read(&only_player_ship, fp); @@ -503,7 +515,13 @@ void bm_read_extra_robots(const char *fname, Mission::descent_version_type type) if (N_D2_OBJBITMAPPTRS+t >= ObjBitmapPtrs.size()) Error("Too many object bitmap pointers (%d) in <%s>. Max is %" DXX_PRI_size_type ".", t, fname, ObjBitmapPtrs.size() - N_D2_OBJBITMAPPTRS); range_for (auto &i, partial_range(ObjBitmapPtrs, N_D2_OBJBITMAPPTRS.value, N_D2_OBJBITMAPPTRS + t)) - i = PHYSFSX_readShort(fp); + { + const auto oi = static_cast(PHYSFSX_readShort(fp)); + if (ObjBitmaps.valid_index(oi)) + i = oi; + else + i = {}; + } } int Robot_replacements_loaded = 0; @@ -566,10 +584,10 @@ void load_robot_replacements(const d_fname &level_name) t = PHYSFSX_readInt(fp); //read number of objbitmaps for (j=0;j= ObjBitmaps.size()) - Error("Object bitmap number (%u) out of range in (%s). Range = [0..%" DXX_PRI_size_type "].", i, static_cast(level_name), ObjBitmaps.size() - 1); - bitmap_index_read(fp, ObjBitmaps[i]); + const auto oi = static_cast(PHYSFSX_readInt(fp)); //read objbitmap number + if (!ObjBitmaps.valid_index(oi)) + Error("Object bitmap number (%u) out of range in (%s). Range = [0..%" DXX_PRI_size_type "].", static_cast(oi), static_cast(level_name), ObjBitmaps.size() - 1); + bitmap_index_read(fp, ObjBitmaps[oi]); } t = PHYSFSX_readInt(fp); //read number of objbitmapptrs @@ -577,7 +595,10 @@ void load_robot_replacements(const d_fname &level_name) const unsigned i = PHYSFSX_readInt(fp); //read objbitmapptr number if (i >= ObjBitmapPtrs.size()) Error("Object bitmap pointer (%u) out of range in (%s). Range = [0..%" DXX_PRI_size_type "].", i, static_cast(level_name), ObjBitmapPtrs.size() - 1); - ObjBitmapPtrs[i] = PHYSFSX_readShort(fp); + const auto oi = static_cast(PHYSFSX_readShort(fp)); + if (!ObjBitmaps.valid_index(oi)) + Error("Object bitmap number (%u) out of range in (%s). Range = [0..%" DXX_PRI_size_type "].", static_cast(oi), static_cast(level_name), ObjBitmaps.size() - 1); + ObjBitmapPtrs[i] = oi; } Robot_replacements_loaded = 1; } @@ -616,9 +637,11 @@ static grs_bitmap *read_extra_bitmap_iff(const char * filename, grs_bitmap &n) // formerly load_exit_model_bitmap static grs_bitmap *bm_load_extra_objbitmap(const char *name) { - assert(N_ObjBitmaps < ObjBitmaps.size()); + const auto oi = static_cast(N_ObjBitmaps); + if (!ObjBitmaps.valid_index(oi)) + return nullptr; { - auto &bitmap_idx = ObjBitmaps[N_ObjBitmaps]; + auto &bitmap_idx = ObjBitmaps[oi]; const auto bitmap_store_index = bitmap_index{static_cast(extra_bitmap_num)}; grs_bitmap &n = GameBitmaps[bitmap_store_index.index]; if (!read_extra_bitmap_iff(name, n)) @@ -633,7 +656,7 @@ static grs_bitmap *bm_load_extra_objbitmap(const char *name) if (n.bm_w != 64 || n.bm_h != 64) Error("Bitmap <%s> is not 64x64",name); - ObjBitmapPtrs[N_ObjBitmaps] = N_ObjBitmaps; + ObjBitmapPtrs[N_ObjBitmaps] = oi; N_ObjBitmaps++; assert(N_ObjBitmaps < ObjBitmaps.size()); return &n; diff --git a/similar/main/bmread.cpp b/similar/main/bmread.cpp index 7823fec5e..b26f1cf7c 100644 --- a/similar/main/bmread.cpp +++ b/similar/main/bmread.cpp @@ -524,7 +524,7 @@ int gamedata_read_tbl(d_vclip_array &Vclip, int pc_shareware) { //Effects[i].bm_ptr = (grs_bitmap **) -1; ec.changing_wall_texture = -1; - ec.changing_object_texture = -1; + ec.changing_object_texture = object_bitmap_index::None; ec.segnum = segment_none; ec.vc.num_frames = -1; //another mark of being unused } @@ -801,7 +801,7 @@ int gamedata_read_tbl(d_vclip_array &Vclip, int pc_shareware) range_for (auto &&en, enumerate(Effects)) { auto &e = en.value; - if ((e.changing_wall_texture != -1 || e.changing_object_texture != -1) && e.vc.num_frames == ~0u) + if ((e.changing_wall_texture != -1 || e.changing_object_texture != object_bitmap_index::None) && e.vc.num_frames == ~0u) Error("EClip %" PRIuFAST32 " referenced (by polygon object?), but not defined", en.idx); } @@ -846,9 +846,12 @@ void verify_textures() #if defined(DXX_BUILD_DESCENT_II) for (uint_fast32_t i = 0; i < Num_effects; ++i) - if (Effects[i].changing_object_texture != -1) - if (GameBitmaps[ObjBitmaps[Effects[i].changing_object_texture].index].bm_w!=64 || GameBitmaps[ObjBitmaps[Effects[i].changing_object_texture].index].bm_h!=64) + if (const auto changing_object_texture = Effects[i].changing_object_texture; changing_object_texture != object_bitmap_index::None) + { + const auto &o = ObjBitmaps[changing_object_texture].index; + if (GameBitmaps[o].bm_w != 64 || GameBitmaps[o].bm_h != 64) Error("Effect %" PRIuFAST32 " is used on object, but is not 64x64",i); + } #endif } @@ -981,8 +984,9 @@ static void bm_read_eclip(int skip) if (obj_eclip) { - if (Effects[clip_num].changing_object_texture == -1) { //first time referenced - Effects[clip_num].changing_object_texture = N_ObjBitmaps; // XChange ObjectBitmaps + if (Effects[clip_num].changing_object_texture == object_bitmap_index::None) + { //first time referenced + Effects[clip_num].changing_object_texture = static_cast(N_ObjBitmaps); // XChange ObjectBitmaps N_ObjBitmaps++; } @@ -1389,13 +1393,12 @@ static grs_bitmap *load_polymodel_bitmap(int skip, const char *name) if (name[0] == '%') { //an animating bitmap! const unsigned eclip_num = atoi(name+1); - if (Effects[eclip_num].changing_object_texture == -1) { //first time referenced - Effects[eclip_num].changing_object_texture = N_ObjBitmaps; - ObjBitmapPtrs[N_ObjBitmapPtrs++] = N_ObjBitmaps; - N_ObjBitmaps++; - } else { - ObjBitmapPtrs[N_ObjBitmapPtrs++] = Effects[eclip_num].changing_object_texture; - } + auto &changing_object_texture = Effects[eclip_num].changing_object_texture; + // On first reference, changing_object_texture will be None. + // Assign it a value. + if (changing_object_texture == object_bitmap_index::None) + changing_object_texture = static_cast(N_ObjBitmaps++); + ObjBitmapPtrs[N_ObjBitmapPtrs++] = changing_object_texture; #if defined(DXX_BUILD_DESCENT_II) assert(N_ObjBitmaps < ObjBitmaps.size()); assert(N_ObjBitmapPtrs < ObjBitmapPtrs.size()); @@ -1403,18 +1406,21 @@ static grs_bitmap *load_polymodel_bitmap(int skip, const char *name) return NULL; } else { - ObjBitmaps[N_ObjBitmaps] = bm_load_sub(skip, name); + const auto loaded_value = bm_load_sub(skip, name); + const auto oi = static_cast(N_ObjBitmaps); + auto &ob = ObjBitmaps[oi]; + ob = loaded_value; #if defined(DXX_BUILD_DESCENT_II) - if (GameBitmaps[ObjBitmaps[N_ObjBitmaps].index].bm_w!=64 || GameBitmaps[ObjBitmaps[N_ObjBitmaps].index].bm_h!=64) + if (GameBitmaps[ob.index].bm_w != 64 || GameBitmaps[ob.index].bm_h != 64) Error("Bitmap <%s> is not 64x64",name); #endif - ObjBitmapPtrs[N_ObjBitmapPtrs++] = N_ObjBitmaps; + ObjBitmapPtrs[N_ObjBitmapPtrs++] = oi; N_ObjBitmaps++; #if defined(DXX_BUILD_DESCENT_II) assert(N_ObjBitmaps < ObjBitmaps.size()); assert(N_ObjBitmapPtrs < ObjBitmapPtrs.size()); #endif - return &GameBitmaps[ObjBitmaps[N_ObjBitmaps-1].index]; + return &GameBitmaps[ob.index]; } } diff --git a/similar/main/effects.cpp b/similar/main/effects.cpp index 19a148c5f..e6f923aa5 100644 --- a/similar/main/effects.cpp +++ b/similar/main/effects.cpp @@ -68,8 +68,8 @@ void reset_special_effects() if (ec.changing_wall_texture != -1) Textures[ec.changing_wall_texture] = ec.vc.frames[ec.frame_count]; - if (ec.changing_object_texture != -1) - ObjBitmaps[ec.changing_object_texture] = ec.vc.frames[ec.frame_count]; + if (const auto changing_object_texture = ec.changing_object_texture; changing_object_texture != object_bitmap_index::None) + ObjBitmaps[changing_object_texture] = ec.vc.frames[ec.frame_count]; } } @@ -83,7 +83,7 @@ void do_special_effects() const auto vc_frame_time = ec.vc.frame_time; if (!vc_frame_time) continue; - if ((ec.changing_wall_texture == -1) && (ec.changing_object_texture==-1) ) + if (ec.changing_wall_texture == -1 && ec.changing_object_texture == object_bitmap_index::None) continue; if (ec.flags & EF_STOPPED) @@ -121,16 +121,16 @@ void do_special_effects() if (ec.changing_wall_texture != -1) Textures[ec.changing_wall_texture] = Effects[n].vc.frames[Effects[n].frame_count]; - if (ec.changing_object_texture != -1) - ObjBitmaps[ec.changing_object_texture] = Effects[n].vc.frames[Effects[n].frame_count]; + if (const auto changing_object_texture = ec.changing_object_texture; changing_object_texture != object_bitmap_index::None) + ObjBitmaps[changing_object_texture] = Effects[n].vc.frames[Effects[n].frame_count]; } else { if (ec.changing_wall_texture != -1) Textures[ec.changing_wall_texture] = ec.vc.frames[ec.frame_count]; - if (ec.changing_object_texture != -1) - ObjBitmaps[ec.changing_object_texture] = ec.vc.frames[ec.frame_count]; + if (const auto changing_object_texture = ec.changing_object_texture; changing_object_texture != object_bitmap_index::None) + ObjBitmaps[changing_object_texture] = ec.vc.frames[ec.frame_count]; } } @@ -145,8 +145,8 @@ void restore_effect_bitmap_icons() if (ec.changing_wall_texture != -1) Textures[ec.changing_wall_texture] = ec.vc.frames[0]; - if (ec.changing_object_texture != -1) - ObjBitmaps[ec.changing_object_texture] = ec.vc.frames[0]; + if (const auto changing_object_texture = ec.changing_object_texture; changing_object_texture != object_bitmap_index::None) + ObjBitmaps[changing_object_texture] = ec.vc.frames[0]; } } } @@ -167,9 +167,8 @@ void stop_effect(int effect_num) if (ec->changing_wall_texture != -1) Textures[ec->changing_wall_texture] = ec->vc.frames[0]; - if (ec->changing_object_texture != -1) - ObjBitmaps[ec->changing_object_texture] = ec->vc.frames[0]; - + if (const auto changing_object_texture = ec->changing_object_texture; changing_object_texture != object_bitmap_index::None) + ObjBitmaps[changing_object_texture] = ec->vc.frames[0]; } //restart a stopped effect diff --git a/similar/main/paging.cpp b/similar/main/paging.cpp index d532e0c46..596ff9dde 100644 --- a/similar/main/paging.cpp +++ b/similar/main/paging.cpp @@ -109,7 +109,7 @@ static void paging_touch_wall_effects(const d_eclip_array &Effects, const Textur } } -static void paging_touch_object_effects(const d_eclip_array &Effects, const unsigned tmap_num) +static void paging_touch_object_effects(const d_eclip_array &Effects, const object_bitmap_index tmap_num) { range_for (auto &i, partial_const_range(Effects, Num_effects)) {