diff --git a/common/include/ogl_init.h b/common/include/ogl_init.h index 2f41e4479..2dc59ebf7 100644 --- a/common/include/ogl_init.h +++ b/common/include/ogl_init.h @@ -21,6 +21,7 @@ #include "d_gl.h" #include "dsx-ns.h" #include "fwd-gr.h" +#include "fwd-segment.h" #include "palette.h" #include "pstypes.h" #include "3d.h" @@ -102,11 +103,10 @@ void ogl_cache_level_textures(); } #endif -#include "3d.h" -void _g3_draw_tmap_2(grs_canvas &, unsigned nv, const g3s_point *const *const pointlist, const g3s_uvl *uvl_list, const g3s_lrgb *light_rgb, grs_bitmap &bmbot, grs_bitmap &bm, unsigned orient); +void _g3_draw_tmap_2(grs_canvas &, unsigned nv, const g3s_point *const *const pointlist, const g3s_uvl *uvl_list, const g3s_lrgb *light_rgb, grs_bitmap &bmbot, grs_bitmap &bm, texture2_rotation_low orient); template -static inline void g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const std::array &pointlist, const std::array &uvl_list, const std::array &light_rgb, grs_bitmap &bmbot, grs_bitmap &bm, const unsigned orient) +static inline void g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const std::array &pointlist, const std::array &uvl_list, const std::array &light_rgb, grs_bitmap &bmbot, grs_bitmap &bm, const texture2_rotation_low orient) { static_assert(N <= MAX_POINTS_PER_POLY, "too many points in tmap"); #ifdef DXX_CONSTANT_TRUE diff --git a/common/main/fwd-segment.h b/common/main/fwd-segment.h index 5453d9e21..a27ecfdbe 100644 --- a/common/main/fwd-segment.h +++ b/common/main/fwd-segment.h @@ -74,6 +74,10 @@ enum sidenum_t : uint8_t WFRONT = 5 }; +enum class texture2_value : uint16_t; +enum class texture2_rotation_low : uint8_t; +enum class texture2_rotation_high : uint16_t; + //normal everyday vertices constexpr std::integral_constant DEFAULT_LIGHTING{}; // (F1_0/2) diff --git a/common/main/gamemine.h b/common/main/gamemine.h index 4c7ba5311..a5a65854c 100644 --- a/common/main/gamemine.h +++ b/common/main/gamemine.h @@ -148,6 +148,6 @@ namespace dsx { extern int d1_pig_present; /* stuff for loading descent.pig of descent 1 */ -extern short convert_d1_tmap_num(short d1_tmap_num); +uint16_t convert_d1_tmap_num(uint16_t d1_tmap_num); } #endif diff --git a/common/main/newdemo.h b/common/main/newdemo.h index 9f36cec7c..7dcf3db47 100644 --- a/common/main/newdemo.h +++ b/common/main/newdemo.h @@ -110,7 +110,7 @@ extern void newdemo_record_rearview(void); extern void newdemo_record_restore_cockpit(void); #ifdef dsx void newdemo_record_wall_set_tmap_num1(vcsegidx_t seg, unsigned side, vcsegidx_t cseg, unsigned cside, int16_t tmap); -void newdemo_record_wall_set_tmap_num2(vcsegidx_t seg, unsigned side, vcsegidx_t cseg, unsigned cside, int16_t tmap); +void newdemo_record_wall_set_tmap_num2(vcsegidx_t seg, unsigned side, vcsegidx_t cseg, unsigned cside, texture2_value tmap); #endif extern void newdemo_record_multi_cloak(int pnum); extern void newdemo_record_multi_decloak(int pnum); diff --git a/common/main/segment.h b/common/main/segment.h index 5df2dc8d3..99b7ad0dc 100644 --- a/common/main/segment.h +++ b/common/main/segment.h @@ -148,10 +148,75 @@ struct shared_side std::array normals; // 2 normals, if quadrilateral, both the same. }; +/* texture2_value uses the low 14 bits for the array index and the high + * 2 bits for texture2_rotation_high + */ +enum class texture2_value : uint16_t +{ + None, +}; + +enum class texture2_rotation_low : uint8_t +{ + Normal = 0, + _1 = 1, + _2 = 2, + _3 = 3, +}; + +#define TEXTURE2_ROTATION_SHIFT 14u +#define TEXTURE2_ROTATION_INDEX_MASK ((1u << TEXTURE2_ROTATION_SHIFT) - 1u) + +enum class texture2_rotation_high : uint16_t +{ + Normal = 0, + _1 = static_cast(texture2_rotation_low::_1) << TEXTURE2_ROTATION_SHIFT, + _2 = static_cast(texture2_rotation_low::_2) << TEXTURE2_ROTATION_SHIFT, + _3 = static_cast(texture2_rotation_low::_3) << TEXTURE2_ROTATION_SHIFT, +}; + +static constexpr texture2_rotation_high &operator++(texture2_rotation_high &t) +{ + /* Cast to uint32, step to the next value, cast back. The cast back + * will truncate to the low 16 bits, causing + * texture2_rotation_high::_3 to roll over to + * texture2_rotation_high::Normal. + */ + return (t = static_cast(static_cast(t) + (1u << TEXTURE2_ROTATION_SHIFT))); +} + +static constexpr uint16_t get_texture_index(const texture2_value t) +{ + return static_cast(t) & TEXTURE2_ROTATION_INDEX_MASK; +} + +static constexpr texture2_rotation_high get_texture_rotation_high(const texture2_value t) +{ + return static_cast(static_cast(t) & ~TEXTURE2_ROTATION_INDEX_MASK); +} + +static constexpr texture2_rotation_low get_texture_rotation_low(const texture2_rotation_high t) +{ + return static_cast(static_cast(t) >> TEXTURE2_ROTATION_SHIFT); +} + +static constexpr texture2_rotation_low get_texture_rotation_low(const texture2_value t) +{ + return get_texture_rotation_low(get_texture_rotation_high(t)); +} + +static constexpr texture2_value build_texture2_value(const unsigned t, const texture2_rotation_high rotation) +{ + return static_cast(t | static_cast(rotation)); +} + +#undef TEXTURE2_ROTATION_SHIFT +#undef TEXTURE2_ROTATION_INDEX_MASK + struct unique_side { int16_t tmap_num; - int16_t tmap_num2; + texture2_value tmap_num2; std::array uvls; }; diff --git a/common/main/texmerge.h b/common/main/texmerge.h index 851744073..80edadce7 100644 --- a/common/main/texmerge.h +++ b/common/main/texmerge.h @@ -27,15 +27,13 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifndef _TEXMERGE_H #define _TEXMERGE_H -#ifdef __cplusplus +#include "fwd-segment.h" struct grs_bitmap; int texmerge_init(); -grs_bitmap &texmerge_get_cached_bitmap(unsigned tmap_bottom, unsigned tmap_top); +grs_bitmap &texmerge_get_cached_bitmap(unsigned tmap_bottom, texture2_value tmap_top); void texmerge_close(); void texmerge_flush(); -#endif - #endif /* _TEXMERGE_H */ diff --git a/common/main/wall.h b/common/main/wall.h index 6825c486f..963fcaa66 100644 --- a/common/main/wall.h +++ b/common/main/wall.h @@ -222,8 +222,8 @@ struct wclip : public prohibit_void_ptr fix play_time; uint16_t num_frames; union { - std::array frames; - std::array d1_frames; + std::array frames; + std::array d1_frames; }; short open_sound; short close_sound; diff --git a/similar/arch/ogl/ogl.cpp b/similar/arch/ogl/ogl.cpp index d21de29e4..c3d7f8b5e 100644 --- a/similar/arch/ogl/ogl.cpp +++ b/similar/arch/ogl/ogl.cpp @@ -462,9 +462,11 @@ void ogl_cache_level_textures(void) } PIGGY_PAGE_IN(Textures[tmap1]); grs_bitmap *bm = &GameBitmaps[Textures[tmap1].index]; - if (tmap2 != 0){ - PIGGY_PAGE_IN(Textures[tmap2&0x3FFF]); - auto &bm2 = GameBitmaps[Textures[tmap2&0x3FFF].index]; + if (tmap2 != texture2_value::None) + { + const auto texture2 = Textures[get_texture_index(tmap2)]; + PIGGY_PAGE_IN(texture2); + auto &bm2 = GameBitmaps[texture2.index]; if (CGameArg.DbgUseOldTextureMerge || bm2.get_flag_mask(BM_FLAG_SUPER_TRANSPARENT)) bm = &texmerge_get_cached_bitmap( tmap1, tmap2 ); else { @@ -981,7 +983,7 @@ void _g3_draw_tmap(grs_canvas &canvas, const unsigned nv, cg3s_point *const *con /* * Everything texturemapped with secondary texture (walls with secondary texture) */ -void _g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const g3s_point *const *const pointlist, const g3s_uvl *uvl_list, const g3s_lrgb *light_rgb, grs_bitmap &bmbot, grs_bitmap &bm, const unsigned orient) +void _g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const g3s_point *const *const pointlist, const g3s_uvl *uvl_list, const g3s_lrgb *light_rgb, grs_bitmap &bmbot, grs_bitmap &bm, const texture2_rotation_low orient) { _g3_draw_tmap(canvas, nv, pointlist, uvl_list, light_rgb, bmbot);//draw the bottom texture first.. could be optimized with multitexturing.. ogl_client_states cs; @@ -1034,15 +1036,15 @@ void _g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const g3s_point *con { const GLfloat uf = f2glf(uvl.u), vf = f2glf(uvl.v); switch(orient){ - case 1: + case texture2_rotation_low::_1: texcoord[0] = 1.0 - vf; texcoord[1] = uf; break; - case 2: + case texture2_rotation_low::_2: texcoord[0] = 1.0 - uf; texcoord[1] = 1.0 - vf; break; - case 3: + case texture2_rotation_low::_3: texcoord[0] = vf; texcoord[1] = 1.0 - uf; break; diff --git a/similar/editor/elight.cpp b/similar/editor/elight.cpp index ef851fb4e..ee700462e 100644 --- a/similar/editor/elight.cpp +++ b/similar/editor/elight.cpp @@ -143,8 +143,7 @@ static void propagate_light_intensity(const csmusegment segp, const unsigned sid auto &TmapInfo = LevelUniqueTmapInfoState.TmapInfo; texmap = us.tmap_num; intensity += TmapInfo[texmap].lighting; - texmap = us.tmap_num2 & 0x3fff; - intensity += TmapInfo[texmap].lighting; + intensity += TmapInfo[get_texture_index(us.tmap_num2)].lighting; if (intensity > 0) { add_light_intensity_all_verts(us, intensity); diff --git a/similar/editor/eswitch.cpp b/similar/editor/eswitch.cpp index eeac30184..336949d76 100644 --- a/similar/editor/eswitch.cpp +++ b/similar/editor/eswitch.cpp @@ -497,7 +497,7 @@ window_event_result trigger_dialog_handler(UI_DIALOG *dlg,const d_event &event, gr_clear_canvas(canvas, CBLACK); else { auto &us = markedseg.u.sides[Markedside]; - if (us.tmap_num2 > 0) + if (us.tmap_num2 != texture2_value::None) { gr_ubitmap(canvas, texmerge_get_cached_bitmap(us.tmap_num, us.tmap_num2)); } else { diff --git a/similar/editor/group.cpp b/similar/editor/group.cpp index 7c91f088f..c58bf5b6c 100644 --- a/similar/editor/group.cpp +++ b/similar/editor/group.cpp @@ -1132,7 +1132,6 @@ static int med_load_group( const char *filename, group::vertex_array_type_t &ver { int vertnum; char ErrorMessage[200]; - short tmap_xlate; int translate=0; char *temptr; segment tseg; @@ -1293,12 +1292,11 @@ static int med_load_group( const char *filename, group::vertex_array_type_t &ver //Translate textures. if (translate == 1) { int temp; - tmap_xlate = useg.sides[j].tmap_num; - useg.sides[j].tmap_num = tmap_xlate_table[tmap_xlate]; + useg.sides[j].tmap_num = tmap_xlate_table[useg.sides[j].tmap_num]; temp = useg.sides[j].tmap_num2; - tmap_xlate = temp & 0x3fff; // strip off orientation bits - if (tmap_xlate != 0) - useg.sides[j].tmap_num2 = (temp & (~0x3fff)) | tmap_xlate_table[tmap_xlate]; // mask on original orientation bits + // strip off orientation bits + if (const auto tmap_xlate = get_texture_index(temp); tmap_xlate != 0) + useg.sides[j].tmap_num2 = build_texture2_value(tmap_xlate_table[tmap_xlate], get_texture_rotation_high(temp)); // mask on original orientation bits } } } diff --git a/similar/editor/info.cpp b/similar/editor/info.cpp index e9d86f295..c7e50bd12 100644 --- a/similar/editor/info.cpp +++ b/similar/editor/info.cpp @@ -264,7 +264,7 @@ static void info_display_default(grs_canvas &canvas, int show_all) gr_uprintf(canvas, *canvas.cv_font, 0, 48, "Cursegp/side: %3hu/%1d", static_cast(Cursegp), Curside); unique_segment &useg = *Cursegp; auto &uside = useg.sides[Curside]; - gr_uprintf(canvas, *canvas.cv_font, 0, 128, " tmap1,2,o: %3d/%3dx%1d", uside.tmap_num, uside.tmap_num2 & 0x3FFF, (uside.tmap_num2 >> 14) & 3); + gr_uprintf(canvas, *canvas.cv_font, 0, 128, " tmap1,2,o: %3d/%3dx%1u", uside.tmap_num, get_texture_index(uside.tmap_num2), static_cast(get_texture_rotation_low(uside.tmap_num2))); } //--------------- Current_vertex_numbers ------------- diff --git a/similar/editor/ktmap.cpp b/similar/editor/ktmap.cpp index 39770c9d2..0357c23bf 100644 --- a/similar/editor/ktmap.cpp +++ b/similar/editor/ktmap.cpp @@ -50,26 +50,23 @@ int AssignTexture(void) // Assign CurrentTexture to Curside in *Cursegp int AssignTexture2(void) { - int texnum, orient, ctexnum, newtexnum; - autosave_mine( mine_filename ); undo_status[Autosave_count] = "Assign Texture 2 UNDONE."; - { const unique_segment &useg = *Cursegp; auto &uside = useg.sides[Curside]; const auto tmap_num2 = uside.tmap_num2; - texnum = tmap_num2 & 0x3FFF; - orient = ((tmap_num2 & 0xC000) >> 14) & 3; - } - ctexnum = CurrentTexture; - - if ( ctexnum == texnum ) { - orient = (orient+1) & 3; - newtexnum = (orient<<14) | texnum; + const auto ctexnum = CurrentTexture; + texture2_value newtexnum; + texture2_rotation_high orient; + if (ctexnum == get_texture_index(tmap_num2)) + { + orient = get_texture_rotation_high(tmap_num2); + ++ orient; } else { - newtexnum = ctexnum; + orient = texture2_rotation_high::Normal; } + newtexnum = build_texture2_value(ctexnum, orient); Cursegp->unique_segment::sides[Curside].tmap_num2 = newtexnum; New_segment.unique_segment::sides[Curside].tmap_num2 = newtexnum; @@ -84,9 +81,8 @@ int ClearTexture2(void) autosave_mine( mine_filename ); undo_status[Autosave_count] = "Clear Texture 2 UNDONE."; - Cursegp->unique_segment::sides[Curside].tmap_num2 = 0; - - New_segment.unique_segment::sides[Curside].tmap_num2 = 0; + Cursegp->unique_segment::sides[Curside].tmap_num2 = texture2_value::None; + New_segment.unique_segment::sides[Curside].tmap_num2 = texture2_value::None; Update_flags |= UF_WORLD_CHANGED; diff --git a/similar/editor/medwall.cpp b/similar/editor/medwall.cpp index 7178e49c7..5c76b21bb 100644 --- a/similar/editor/medwall.cpp +++ b/similar/editor/medwall.cpp @@ -171,12 +171,12 @@ static int wall_assign_door(int door_type) if (wa.flags & WCF_TMAP1) { useg.sides[Curside].tmap_num = wa.frames[0]; ucseg.sides[Connectside].tmap_num = wa.frames[0]; - useg.sides[Curside].tmap_num2 = 0; - ucseg.sides[Connectside].tmap_num2 = 0; + useg.sides[Curside].tmap_num2 = texture2_value::None; + ucseg.sides[Connectside].tmap_num2 = texture2_value::None; } else { - useg.sides[Curside].tmap_num2 = wa.frames[0]; - ucseg.sides[Connectside].tmap_num2 = wa.frames[0]; + useg.sides[Curside].tmap_num2 = texture2_value{wa.frames[0]}; + ucseg.sides[Connectside].tmap_num2 = texture2_value{wa.frames[0]}; } Update_flags |= UF_WORLD_CHANGED; @@ -613,7 +613,7 @@ window_event_result wall_dialog_handler(UI_DIALOG *dlg,const d_event &event, wal else { auto &curside = Cursegp->unique_segment::sides[Curside]; const auto tmap_num = curside.tmap_num; - if (curside.tmap_num2 > 0) + if (curside.tmap_num2 != texture2_value::None) gr_ubitmap(*grd_curcanv, texmerge_get_cached_bitmap(tmap_num, curside.tmap_num2)); else { PIGGY_PAGE_IN(Textures[tmap_num]); @@ -705,15 +705,15 @@ int wall_restore_all() range_for (auto &&i, ActiveDoors.vmptr) wall_close_door_ref(Segments.vmptridx, Walls, WallAnims, i); - range_for (auto &&i, vmsegptr) - for (auto &&[us, ss] : zip(i->unique_segment::sides, i->shared_segment::sides)) + for (csmusegment &&i : vmsegptr) + for (auto &&[ss, us] : zip(i.s.sides, i.u.sides)) { const auto wall_num = ss.wall_num; if (wall_num != wall_none) { auto &w = *vcwallptr(wall_num); if (w.type == WALL_BLASTABLE || w.type == WALL_DOOR) - us.tmap_num2 = WallAnims[w.clip_num].frames[0]; + us.tmap_num2 = texture2_value{WallAnims[w.clip_num].frames[0]}; } } @@ -857,8 +857,8 @@ static int wall_add_to_side(fvcvertptr &vcvertptr, wall_array &Walls, const vmse } if (type != WALL_DOOR) { - segp->unique_segment::sides[side].tmap_num2 = 0; - csegp->unique_segment::sides[connectside].tmap_num2 = 0; + segp->unique_segment::sides[side].tmap_num2 = texture2_value::None; + csegp->unique_segment::sides[connectside].tmap_num2 = texture2_value::None; } if (type == WALL_DOOR) { @@ -926,8 +926,8 @@ int wall_add_to_markedside(fvcvertptr &vcvertptr, wall_array &Walls, const int8_ } if (type != WALL_DOOR) { - Markedsegp->unique_segment::sides[Markedside].tmap_num2 = 0; - csegp->unique_segment::sides[Connectside].tmap_num2 = 0; + Markedsegp->unique_segment::sides[Markedside].tmap_num2 = texture2_value::None; + csegp->unique_segment::sides[Connectside].tmap_num2 = texture2_value::None; } Update_flags |= UF_WORLD_CHANGED; diff --git a/similar/editor/mine.cpp b/similar/editor/mine.cpp index 5625d294e..5f445a1a6 100644 --- a/similar/editor/mine.cpp +++ b/similar/editor/mine.cpp @@ -645,29 +645,26 @@ int save_mine_data_compiled(PHYSFS_File *SaveFile) { if (seg.s.children[sidenum] == segment_none || seg.s.sides[sidenum].wall_num != wall_none) { - ushort tmap_num, tmap_num2; - - tmap_num = seg.u.sides[sidenum].tmap_num; - tmap_num2 = seg.u.sides[sidenum].tmap_num2; + auto tmap_num = seg.u.sides[sidenum].tmap_num; + auto tmap_num2 = seg.u.sides[sidenum].tmap_num2; #if defined(DXX_BUILD_DESCENT_II) if (Gamesave_current_version <= 3) // convert texture numbers back to d1 { tmap_num = convert_to_d1_tmap_num(tmap_num); - if (tmap_num2) + if (tmap_num2 != texture2_value::None) { - const auto orient = tmap_num2 & ~TMAP_NUM_MASK; - tmap_num2 = orient | convert_to_d1_tmap_num(tmap_num2 & TMAP_NUM_MASK); + tmap_num2 = build_texture2_value(convert_to_d1_tmap_num(get_texture_index(tmap_num2)), get_texture_rotation_high(tmap_num2)); } } #endif - if (tmap_num2 != 0 && New_file_format_save) + if (tmap_num2 != texture2_value::None && New_file_format_save) tmap_num |= 0x8000; PHYSFS_writeSLE16(SaveFile, tmap_num); - if (tmap_num2 != 0 || !New_file_format_save) - PHYSFS_writeSLE16(SaveFile, tmap_num2); + if (tmap_num2 != texture2_value::None || !New_file_format_save) + PHYSFS_writeSLE16(SaveFile, static_cast(tmap_num2)); range_for (auto &i, seg.u.sides[sidenum].uvls) { diff --git a/similar/editor/segment.cpp b/similar/editor/segment.cpp index 7c92678cb..d4f7212f1 100644 --- a/similar/editor/segment.cpp +++ b/similar/editor/segment.cpp @@ -621,7 +621,7 @@ static void copy_tmap_ids(unique_segment &dseg, const unique_segment &sseg) for (auto &&[ss, ds] : zip(sseg.sides, dseg.sides)) { ds.tmap_num = ss.tmap_num; - ds.tmap_num2 = 0; + ds.tmap_num2 = texture2_value::None; } } @@ -1365,7 +1365,7 @@ void med_create_new_segment(const vms_vector &scale) ss.wall_num = wall_none; create_walls_on_side(vcvertptr, sp, s); us.tmap_num = s + 1; // assign some stupid old tmap to this side. - us.tmap_num2 = 0; + us.tmap_num2 = texture2_value::None; } Seg_orientation = {}; diff --git a/similar/editor/seguvs.cpp b/similar/editor/seguvs.cpp index bfcbe72df..dfa866130 100644 --- a/similar/editor/seguvs.cpp +++ b/similar/editor/seguvs.cpp @@ -1167,7 +1167,7 @@ static void calim_process_all_lights(int quick_light) const auto sidep = &es.value; fix light_intensity; - light_intensity = TmapInfo[sidep->tmap_num].lighting + TmapInfo[sidep->tmap_num2 & 0x3fff].lighting; + light_intensity = TmapInfo[sidep->tmap_num].lighting + TmapInfo[get_texture_index(sidep->tmap_num2)].lighting; // if (segp->sides[sidenum].wall_num != -1) { // int wall_num, bitmap_num, effect_num; diff --git a/similar/editor/texpage.cpp b/similar/editor/texpage.cpp index a600d7dcc..a18d6a303 100644 --- a/similar/editor/texpage.cpp +++ b/similar/editor/texpage.cpp @@ -284,12 +284,13 @@ void do_replacements(void) if (sidep.tmap_num == old_tmap_num) { sidep.tmap_num = new_tmap_num; } - if ((sidep.tmap_num2 != 0) && ((sidep.tmap_num2 & 0x3fff) == old_tmap_num)) { + if (sidep.tmap_num2 != texture2_value::None && get_texture_index(sidep.tmap_num2) == old_tmap_num) + { if (new_tmap_num == 0) { Int3(); // Error. You have tried to replace a tmap_num2 with // the 0th tmap_num2 which is ILLEGAL! } else { - sidep.tmap_num2 = new_tmap_num | (sidep.tmap_num2 & 0xc000); + sidep.tmap_num2 = build_texture2_value(new_tmap_num, get_texture_rotation_high(sidep.tmap_num2)); } } } diff --git a/similar/main/collide.cpp b/similar/main/collide.cpp index e14069440..d89386aaa 100644 --- a/similar/main/collide.cpp +++ b/similar/main/collide.cpp @@ -395,7 +395,8 @@ static void collide_player_and_wall(const vmobjptridx_t playerobj, const fix hit const auto tmap_num2 = hitseg->unique_segment::sides[hitwall].tmap_num2; //don't do wall damage and sound if hit lava or water - if ((TmapInfo[tmap_num].flags & (TMI_WATER|TMI_VOLATILE)) || (tmap_num2 && (TmapInfo[tmap_num2&0x3fff].flags & (TMI_WATER|TMI_VOLATILE)))) + constexpr auto tmi_no_damage = (TMI_WATER | TMI_VOLATILE); + if ((TmapInfo[tmap_num].flags & tmi_no_damage) || (tmap_num2 != texture2_value::None && (TmapInfo[get_texture_index(tmap_num2)].flags & tmi_no_damage))) damage = 0; #endif @@ -556,8 +557,6 @@ int check_effect_blowup(const d_level_shared_destructible_light_state &LevelShar { auto &Effects = LevelUniqueEffectsClipState.Effects; auto &TmapInfo = LevelUniqueTmapInfoState.TmapInfo; - int tm; - #if defined(DXX_BUILD_DESCENT_I) static constexpr std::integral_constant force_blowup_flag{}; #elif defined(DXX_BUILD_DESCENT_II) @@ -581,23 +580,25 @@ int check_effect_blowup(const d_level_shared_destructible_light_state &LevelShar } #endif - if ((tm=seg->unique_segment::sides[side].tmap_num2) != 0) { - int tmf = tm&0xc000; //tm flags - tm &= 0x3fff; //tm without flags - - const auto ec = TmapInfo[tm].eclip_num; + if (const auto tmap2 = seg->unique_segment::sides[side].tmap_num2; tmap2 != texture2_value::None) + { + const auto tm = get_texture_index(tmap2); //tm without flags + auto &tmi2 = TmapInfo[tm]; + const auto ec = tmi2.eclip_num; unsigned db = 0; #if defined(DXX_BUILD_DESCENT_I) if (ec != eclip_none && (db = Effects[ec].dest_bm_num) != ~0u && !(Effects[ec].flags & EF_ONE_SHOT)) #elif defined(DXX_BUILD_DESCENT_II) //check if it's an animation (monitor) or casts light - if ((ec != eclip_none && ((db = Effects[ec].dest_bm_num) != ~0u && !(Effects[ec].flags & EF_ONE_SHOT))) || (ec == eclip_none && (TmapInfo[tm].destroyed != -1))) + if ((ec != eclip_none && ((db = Effects[ec].dest_bm_num) != ~0u && !(Effects[ec].flags & EF_ONE_SHOT))) || (ec == eclip_none && (tmi2.destroyed != -1))) #endif { - const grs_bitmap *bm = &GameBitmaps[Textures[tm].index]; + const auto tmf = get_texture_rotation_high(tmap2); //tm flags + auto &texture2 = Textures[tm]; + const grs_bitmap *bm = &GameBitmaps[texture2.index]; int x=0,y=0,t; - PIGGY_PAGE_IN(Textures[tm]); + PIGGY_PAGE_IN(texture2); //this can be blown up...did we hit it? @@ -610,10 +611,22 @@ int check_effect_blowup(const d_level_shared_destructible_light_state &LevelShar y = static_cast(f2i(v*bm->bm_h)) % bm->bm_h; switch (tmf) { //adjust for orientation of paste-on - case 0x0000: break; - case 0x4000: t=y; y=x; x=bm->bm_w-t-1; break; - case 0x8000: y=bm->bm_h-y-1; x=bm->bm_w-x-1; break; - case 0xc000: t=x; x=y; y=bm->bm_h-t-1; break; + case texture2_rotation_high::Normal: + break; + case texture2_rotation_high::_1: + t = y; + y = x; + x = bm->bm_w - t - 1; + break; + case texture2_rotation_high::_2: + y = bm->bm_h - y - 1; + x = bm->bm_w - x - 1; + break; + case texture2_rotation_high::_3: + t = x; + x = y; + y = bm->bm_h - t - 1; + break; } bm = rle_expand_texture(*bm); } @@ -685,20 +698,18 @@ int check_effect_blowup(const d_level_shared_destructible_light_state &LevelShar assert(bm_num != 0); auto &tmap_num2 = seg->unique_segment::sides[side].tmap_num2; - assert(tmap_num2 != 0); - tmap_num2 = bm_num | tmf; //replace with destroyed + tmap_num2 = build_texture2_value(bm_num, tmf); //replace with destroyed } else { assert(db != 0); auto &tmap_num2 = seg->unique_segment::sides[side].tmap_num2; - assert(tmap_num2 != 0); - tmap_num2 = db | tmf; //replace with destroyed + tmap_num2 = build_texture2_value(db, tmf); //replace with destroyed } } #if defined(DXX_BUILD_DESCENT_II) else { - seg->unique_segment::sides[side].tmap_num2 = TmapInfo[tm].destroyed | tmf; + seg->unique_segment::sides[side].tmap_num2 = build_texture2_value(tmi2.destroyed, tmf); //assume this is a light, and play light sound digi_link_sound_to_pos( SOUND_LIGHT_BLOWNUP, seg, 0, pnt, 0, F1_0 ); @@ -830,7 +841,7 @@ static window_event_result collide_weapon_and_wall( const auto Difficulty_level = GameUniqueState.Difficulty_level; // Wall is volatile if either tmap 1 or 2 is volatile if ((TmapInfo[uhitside.tmap_num].flags & TMI_VOLATILE) || - (uhitside.tmap_num2 && (TmapInfo[uhitside.tmap_num2 & 0x3fff].flags & TMI_VOLATILE)) + (uhitside.tmap_num2 != texture2_value::None && (TmapInfo[get_texture_index(uhitside.tmap_num2)].flags & TMI_VOLATILE)) ) { weapon_info *wi = &Weapon_info[get_weapon_id(weapon)]; @@ -860,7 +871,7 @@ static window_event_result collide_weapon_and_wall( } #if defined(DXX_BUILD_DESCENT_II) else if ((TmapInfo[uhitside.tmap_num].flags & TMI_WATER) || - (uhitside.tmap_num2 && (TmapInfo[uhitside.tmap_num2 & 0x3fff].flags & TMI_WATER)) + (uhitside.tmap_num2 != texture2_value::None && (TmapInfo[get_texture_index(uhitside.tmap_num2)].flags & TMI_WATER)) ) { weapon_info *wi = &Weapon_info[get_weapon_id(weapon)]; diff --git a/similar/main/dumpmine.cpp b/similar/main/dumpmine.cpp index fa110de5e..4c8412feb 100644 --- a/similar/main/dumpmine.cpp +++ b/similar/main/dumpmine.cpp @@ -819,7 +819,7 @@ static void determine_used_textures_level(d_level_shared_destructible_light_stat } } - if (const auto tmap_num2 = uside.tmap_num2 & 0x3fff) + if (const auto tmap_num2 = get_texture_index(uside.tmap_num2)) { if (tmap_num2 < max_tmap) { ++tmap_buf[tmap_num2]; @@ -904,7 +904,7 @@ static void determine_used_textures_level(d_level_shared_destructible_light_stat Int3(); // Error, bogus texture map. Should not be greater than max_tmap. } - if (const auto masked_tmap_num2 = (uside.tmap_num2 & 0x3fff)) + if (const auto masked_tmap_num2 = get_texture_index(uside.tmap_num2)) { if (masked_tmap_num2 < Textures.size()) { @@ -917,7 +917,7 @@ static void determine_used_textures_level(d_level_shared_destructible_light_stat if (!Ignore_tmap_num2_error) Int3(); // Error, bogus texture map. Should not be greater than max_tmap. Ignore_tmap_num2_error = 1; - uside.tmap_num2 = 0; + uside.tmap_num2 = texture2_value::None; } } } diff --git a/similar/main/effects.cpp b/similar/main/effects.cpp index b433e4aab..19a148c5f 100644 --- a/similar/main/effects.cpp +++ b/similar/main/effects.cpp @@ -103,8 +103,8 @@ void do_special_effects() ec.segnum = segment_none; //done with this assert(ec.sidenum < 6); auto &side = seg.sides[ec.sidenum]; - assert(ec.dest_bm_num != 0 && side.tmap_num2 != 0); - side.tmap_num2 = ec.dest_bm_num | (side.tmap_num2 & 0xc000); //replace with destoyed + assert(ec.dest_bm_num != 0 && side.tmap_num2 != texture2_value::None); + side.tmap_num2 = build_texture2_value(ec.dest_bm_num, get_texture_rotation_high(side.tmap_num2)); //replace with destroyed } ec.frame_count = 0; diff --git a/similar/main/fvi.cpp b/similar/main/fvi.cpp index a8617cf41..03eeae60a 100644 --- a/similar/main/fvi.cpp +++ b/similar/main/fvi.cpp @@ -1204,8 +1204,9 @@ int check_trans_wall(const vms_vector &pnt,const vcsegptridx_t seg,int sidenum,i auto &v = hitpoint.v; const auto tmap_num = side.tmap_num; - const grs_bitmap &rbm = (side.tmap_num2 != 0) ? texmerge_get_cached_bitmap(tmap_num, side.tmap_num2 ) : - GameBitmaps[Textures[PIGGY_PAGE_IN(Textures[tmap_num]), tmap_num].index]; + const grs_bitmap &rbm = (side.tmap_num2 != texture2_value::None) + ? texmerge_get_cached_bitmap(tmap_num, side.tmap_num2) + : GameBitmaps[Textures[PIGGY_PAGE_IN(Textures[tmap_num]), tmap_num].index]; const auto bm = rle_expand_texture(rbm); bmx = static_cast(f2i(u*bm->bm_w)) % bm->bm_w; diff --git a/similar/main/game.cpp b/similar/main/game.cpp index e2880edc6..8cdad94c1 100644 --- a/similar/main/game.cpp +++ b/similar/main/game.cpp @@ -2023,7 +2023,7 @@ static void flicker_lights(const d_level_shared_destructible_light_state &LevelS const auto sidenum = f.sidenum; { auto &side = segp->unique_segment::sides[sidenum]; - if (!(TmapInfo[side.tmap_num].lighting || TmapInfo[side.tmap_num2 & 0x3fff].lighting)) + if (!(TmapInfo[side.tmap_num].lighting || TmapInfo[get_texture_index(side.tmap_num2)].lighting)) continue; } diff --git a/similar/main/gamemine.cpp b/similar/main/gamemine.cpp index d5355e6b9..d949f1e9a 100644 --- a/similar/main/gamemine.cpp +++ b/similar/main/gamemine.cpp @@ -94,7 +94,8 @@ int d1_pig_present = 0; // can descent.pig from descent 1 be loaded? * If we can load the original d1 pig, we make sure this function is bijective. * This function was updated using the file config/convtabl.ini from devil 2.2. */ -short convert_d1_tmap_num(short d1_tmap_num) { +uint16_t convert_d1_tmap_num(const uint16_t d1_tmap_num) +{ switch (d1_tmap_num) { case 0: case 2: case 4: case 5: // all refer to grey rock001 (exception to bijectivity rule) @@ -946,13 +947,11 @@ int load_mine_data_compiled(PHYSFS_File *LoadFile, const char *const Gamesave_cu uside.tmap_num = convert_tmap(temp_ushort & 0x7fff); if (New_file_format_load && !(temp_ushort & 0x8000)) - uside.tmap_num2 = 0; + uside.tmap_num2 = texture2_value::None; else { // Read short Segments[segnum].sides[sidenum].tmap_num2; - uside.tmap_num2 = PHYSFSX_readShort(LoadFile); - uside.tmap_num2 = - (convert_tmap(uside.tmap_num2 & 0x3fff)) | - (uside.tmap_num2 & 0xc000); + const auto tmap_num2 = texture2_value{static_cast(PHYSFSX_readShort(LoadFile))}; + uside.tmap_num2 = build_texture2_value(convert_tmap(get_texture_index(tmap_num2)), get_texture_rotation_high(tmap_num2)); } #elif defined(DXX_BUILD_DESCENT_II) if (New_file_format_load) { @@ -964,12 +963,13 @@ int load_mine_data_compiled(PHYSFS_File *LoadFile, const char *const Gamesave_cu uside.tmap_num = convert_d1_tmap_num(uside.tmap_num); if (New_file_format_load && !(temp_ushort & 0x8000)) - uside.tmap_num2 = 0; + uside.tmap_num2 = texture2_value::None; else { // Read short Segments[segnum].sides[sidenum].tmap_num2; - uside.tmap_num2 = PHYSFSX_readShort(LoadFile); - if (Gamesave_current_version <= 1 && uside.tmap_num2 != 0) - uside.tmap_num2 = convert_d1_tmap_num(uside.tmap_num2); + const auto tmap_num2 = static_cast(PHYSFSX_readShort(LoadFile)); + uside.tmap_num2 = (Gamesave_current_version <= 1 && uside.tmap_num2 != texture2_value::None) + ? build_texture2_value(convert_d1_tmap_num(get_texture_index(uside.tmap_num2)), get_texture_rotation_high(tmap_num2)) + : tmap_num2; } #endif @@ -985,7 +985,7 @@ int load_mine_data_compiled(PHYSFS_File *LoadFile, const char *const Gamesave_cu } } else { uside.tmap_num = 0; - uside.tmap_num2 = 0; + uside.tmap_num2 = texture2_value::None; uside.uvls = {}; } } diff --git a/similar/main/gamesave.cpp b/similar/main/gamesave.cpp index e3918656f..7030aedf4 100644 --- a/similar/main/gamesave.cpp +++ b/similar/main/gamesave.cpp @@ -1171,7 +1171,7 @@ static int load_game_data( if (wa.flags & WCF_TMAP1) { uside.tmap_num = wa.frames[0]; - uside.tmap_num2 = 0; + uside.tmap_num2 = texture2_value(); } } validate_segment_wall(i, sside, side_idx); diff --git a/similar/main/gameseg.cpp b/similar/main/gameseg.cpp index 4f3d5fdb8..420577163 100644 --- a/similar/main/gameseg.cpp +++ b/similar/main/gameseg.cpp @@ -1714,7 +1714,7 @@ static void change_segment_light(const vmsegptridx_t segp, const unsigned sidenu auto &sidep = segp->unique_segment::sides[sidenum]; fix light_intensity; - light_intensity = TmapInfo[sidep.tmap_num].lighting + TmapInfo[sidep.tmap_num2 & 0x3fff].lighting; + light_intensity = TmapInfo[sidep.tmap_num].lighting + TmapInfo[get_texture_index(sidep.tmap_num2)].lighting; if (light_intensity) { auto &vcvertptr = Vertices.vcptr; const auto segment_center = compute_segment_center(vcvertptr, segp); @@ -1884,7 +1884,7 @@ void set_ambient_sound_flags() * added. Skip this side. */ continue; - const auto texture_flags = TmapInfo[uside.tmap_num].flags | TmapInfo[uside.tmap_num2 & 0x3fff].flags; + const auto texture_flags = TmapInfo[uside.tmap_num].flags | TmapInfo[get_texture_index(uside.tmap_num2)].flags; /* These variables do not need to be named, but naming them * is the easiest way to establish sequence points, so that * `sound_flag` is passed to `ambient_mark_bfs` only after diff --git a/similar/main/gameseq.cpp b/similar/main/gameseq.cpp index b45404643..9c6f969b0 100644 --- a/similar/main/gameseq.cpp +++ b/similar/main/gameseq.cpp @@ -780,9 +780,9 @@ static void set_sound_sources(fvcsegptridx &vcsegptridx, fvcvertptr &vcvertptr) Dont_start_sound_objects = 1; const auto get_eclip_for_tmap = [](const d_level_unique_tmap_info_state::TmapInfo_array &TmapInfo, const unique_side &side) { - if (const auto tm2 = side.tmap_num2) + if (const auto tm2 = side.tmap_num2; tm2 != texture2_value::None) { - const auto ec = TmapInfo[tm2 & 0x3fff].eclip_num; + const auto ec = TmapInfo[get_texture_index(tm2)].eclip_num; #if defined(DXX_BUILD_DESCENT_II) if (ec != eclip_none) #endif @@ -902,7 +902,8 @@ static ushort netmisc_calc_checksum() do_checksum_calc(reinterpret_cast(&s), 2, &sum1, &sum2); s = INTEL_SHORT(uside.tmap_num); do_checksum_calc(reinterpret_cast(&s), 2, &sum1, &sum2); - s = INTEL_SHORT(uside.tmap_num2); + s = static_cast(uside.tmap_num2); + s = INTEL_SHORT(s); do_checksum_calc(reinterpret_cast(&s), 2, &sum1, &sum2); range_for (auto &k, uside.uvls) { diff --git a/similar/main/multi.cpp b/similar/main/multi.cpp index 02062ca1f..a7aff23a8 100644 --- a/similar/main/multi.cpp +++ b/similar/main/multi.cpp @@ -4163,7 +4163,8 @@ void multi_send_light_specific (const playernum_t pnum, const vcsegptridx_t segn range_for (auto &i, segnum->unique_segment::sides) { - PUT_INTEL_SHORT(&multibuf[count], i.tmap_num2); count+=2; + PUT_INTEL_SHORT(&multibuf[count], static_cast(i.tmap_num2)); + count+=2; } multi_send_data_direct(multibuf, pnum, 2); } @@ -4185,7 +4186,10 @@ static void multi_do_light (const ubyte *buf) { auto &LevelSharedDestructibleLightState = LevelSharedSegmentState.DestructibleLights; subtract_light(LevelSharedDestructibleLightState, segp, i); - side_array[i].tmap_num2 = GET_INTEL_SHORT(&buf[4 + (2 * i)]); + const auto tmap_num2 = texture2_value{GET_INTEL_SHORT(&buf[4 + (2 * i)])}; + if (get_texture_index(tmap_num2) >= Textures.size()) + continue; + side_array[i].tmap_num2 = tmap_num2; } } } diff --git a/similar/main/net_udp.cpp b/similar/main/net_udp.cpp index 4c917efb2..a6a241390 100644 --- a/similar/main/net_udp.cpp +++ b/similar/main/net_udp.cpp @@ -1848,16 +1848,21 @@ static void net_udp_process_monitor_vector(uint32_t vector) return; range_for (unique_segment &seg, vmsegptr) { - int tm, ec, bm; range_for (auto &j, seg.sides) { - if ( ((tm = j.tmap_num2) != 0) && - (ec = TmapInfo[tm & 0x3fff].eclip_num) != eclip_none && - (bm = Effects[ec].dest_bm_num) != ~0u) + const auto tm = j.tmap_num2; + if (tm == texture2_value::None) + continue; + const auto ec = TmapInfo[get_texture_index(tm)].eclip_num; + if (ec == eclip_none) + continue; + const int bm = Effects[ec].dest_bm_num; + if (bm == ~0u) + continue; { if (vector & 1) { - j.tmap_num2 = bm | (tm&0xc000); + j.tmap_num2 = build_texture2_value(bm, get_texture_rotation_high(tm)); } if (!(vector >>= 1)) return; @@ -1916,10 +1921,10 @@ static unsigned net_udp_create_monitor_vector(void) { range_for (auto &j, seg->unique_segment::sides) { - const unsigned tm2 = j.tmap_num2; - if (!tm2) + const auto tm2 = j.tmap_num2; + if (tm2 == texture2_value::None) continue; - const unsigned masked_tm2 = tm2 & 0x3fff; + const auto masked_tm2 = get_texture_index(tm2); const unsigned ec = TmapInfo[masked_tm2].eclip_num; { if (ec != eclip_none && diff --git a/similar/main/newdemo.cpp b/similar/main/newdemo.cpp index 4d5ffb100..bb130ac69 100644 --- a/similar/main/newdemo.cpp +++ b/similar/main/newdemo.cpp @@ -1483,7 +1483,7 @@ void newdemo_record_wall_set_tmap_num1(const vcsegidx_t seg, const unsigned side nd_write_short(tmap); } -void newdemo_record_wall_set_tmap_num2(const vcsegidx_t seg, const unsigned side, const vcsegidx_t cseg, const unsigned cside, const int16_t tmap) +void newdemo_record_wall_set_tmap_num2(const vcsegidx_t seg, const unsigned side, const vcsegidx_t cseg, const unsigned cside, const texture2_value tmap) { pause_game_world_time p; nd_write_byte(ND_EVENT_WALL_SET_TMAP_NUM2); @@ -1491,7 +1491,7 @@ void newdemo_record_wall_set_tmap_num2(const vcsegidx_t seg, const unsigned side nd_write_byte(side); nd_write_short(cseg); nd_write_byte(cside); - nd_write_short(tmap); + nd_write_short(static_cast(tmap)); } void newdemo_record_multi_cloak(int pnum) @@ -1650,7 +1650,7 @@ void newdemo_set_new_level(int level_num) const auto &side = vcsegptr(w.segnum)->unique_segment::sides[w.sidenum]; nd_write_short (side.tmap_num); - nd_write_short (side.tmap_num2); + nd_write_short(static_cast(side.tmap_num2)); nd_record_v_juststarted=0; } } @@ -1693,7 +1693,7 @@ static void newdemo_record_oneframeevent_update(int wallupdate) auto &uside = seg->unique_segment::sides[side]; if (const auto tmap_num = uside.tmap_num) newdemo_record_wall_set_tmap_num1(w.segnum,side,w.segnum,side,tmap_num); - if (const auto tmap_num2 = uside.tmap_num2) + if (const auto tmap_num2 = uside.tmap_num2; tmap_num2 != texture2_value::None) newdemo_record_wall_set_tmap_num2(w.segnum,side,w.segnum,side,tmap_num2); } } @@ -2046,10 +2046,13 @@ static void newdemo_pop_ctrlcen_triggers() const auto anim_num = vcwallptr(wall_num)->clip_num; auto &wa = WallAnims[anim_num]; const auto n = wa.num_frames; - const auto t = wa.flags & WCF_TMAP1 - ? &unique_side::tmap_num - : &unique_side::tmap_num2; - seg->unique_segment::sides[side].*t = csegp->unique_segment::sides[cside].*t = wa.frames[n-1]; + auto &seg0uside = seg->unique_segment::sides[side]; + auto &seg1uside = csegp->unique_segment::sides[cside]; + const auto next_tmap = wa.frames[n - 1]; + if (wa.flags & WCF_TMAP1) + seg0uside.tmap_num = seg1uside.tmap_num = next_tmap; + else + seg0uside.tmap_num2 = seg1uside.tmap_num2 = texture2_value{next_tmap}; } } @@ -2856,11 +2859,9 @@ static int newdemo_read_frame_information(int rewrite) break; } if ((Newdemo_vcr_state != ND_STATE_PAUSED) && (Newdemo_vcr_state != ND_STATE_REWINDING) && (Newdemo_vcr_state != ND_STATE_ONEFRAMEBACKWARD)) { - assert(tmap != 0); unique_segment &s0 = *vmsegptr(seg); auto &tmap_num2 = s0.sides[side].tmap_num2; - assert(tmap_num2 != 0); - tmap_num2 = vmsegptr(cseg)->unique_segment::sides[cside].tmap_num2 = tmap; + tmap_num2 = vmsegptr(cseg)->unique_segment::sides[cside].tmap_num2 = texture2_value{tmap}; } break; } @@ -3147,10 +3148,13 @@ static int newdemo_read_frame_information(int rewrite) const auto &&cside = find_connect_side(segp, csegp); const auto anim_num = vmwallptr(sseg.sides[side].wall_num)->clip_num; auto &wa = WallAnims[anim_num]; - const auto t = wa.flags & WCF_TMAP1 - ? &unique_side::tmap_num - : &unique_side::tmap_num2; - segp->unique_segment::sides[side].*t = csegp->unique_segment::sides[cside].*t = wa.frames[0]; + auto &seg0uside = segp->unique_segment::sides[side]; + auto &seg1uside = csegp->unique_segment::sides[cside]; + const auto next_tmap = wa.frames[0]; + if (wa.flags & WCF_TMAP1) + seg0uside.tmap_num = seg1uside.tmap_num = next_tmap; + else + seg0uside.tmap_num2 = seg1uside.tmap_num2 = texture2_value{next_tmap}; } break; } @@ -3295,7 +3299,9 @@ static int newdemo_read_frame_information(int rewrite) auto &side = vmsegptr(w.segnum)->unique_segment::sides[w.sidenum]; nd_read_short (&side.tmap_num); - nd_read_short (&side.tmap_num2); + uint16_t tmap_num2; + nd_read_short(&tmap_num2); + side.tmap_num2 = texture2_value{tmap_num2}; if (rewrite) { @@ -3303,7 +3309,7 @@ static int newdemo_read_frame_information(int rewrite) nd_write_byte (w.flags); nd_write_byte (w.state); nd_write_short (side.tmap_num); - nd_write_short (side.tmap_num2); + nd_write_short(static_cast(side.tmap_num2)); } } diff --git a/similar/main/paging.cpp b/similar/main/paging.cpp index 008febee4..8b107f81e 100644 --- a/similar/main/paging.cpp +++ b/similar/main/paging.cpp @@ -269,10 +269,10 @@ static void paging_touch_side(const d_eclip_array &Effects, const Textures_array auto &uside = segp.u.sides[sidenum]; const auto tmap1 = uside.tmap_num; paging_touch_wall_effects(Effects, Textures, Vclip, tmap1); - if (const auto tmap2 = uside.tmap_num2) + if (const auto tmap2 = uside.tmap_num2; tmap2 != texture2_value::None) { texmerge_get_cached_bitmap( tmap1, tmap2 ); - paging_touch_wall_effects(Effects, Textures, Vclip, tmap2 & 0x3FFF); + paging_touch_wall_effects(Effects, Textures, Vclip, get_texture_index(tmap2)); } else { PIGGY_PAGE_IN( Textures[tmap1] ); } diff --git a/similar/main/render.cpp b/similar/main/render.cpp index 26d1a933a..36b6f8317 100644 --- a/similar/main/render.cpp +++ b/similar/main/render.cpp @@ -221,7 +221,7 @@ static inline int is_alphablend_eclip(int eclip_num) // they are used for our hideously hacked in headlight system. // vp is a pointer to vertex ids. // tmap1, tmap2 are texture map ids. tmap2 is the pasty one. -static void render_face(grs_canvas &canvas, const shared_segment &segp, const unsigned sidenum, const unsigned nv, const std::array &vp, const unsigned tmap1, const unsigned tmap2, std::array uvl_copy, const WALL_IS_DOORWAY_result_t wid_flags) +static void render_face(grs_canvas &canvas, const shared_segment &segp, const unsigned sidenum, const unsigned nv, const std::array &vp, const unsigned tmap1, const texture2_value tmap2, std::array uvl_copy, const WALL_IS_DOORWAY_result_t wid_flags) { auto &LevelUniqueControlCenterState = LevelUniqueObjectState.ControlCenterState; auto &TmapInfo = LevelUniqueTmapInfoState.TmapInfo; @@ -269,9 +269,11 @@ static void render_face(grs_canvas &canvas, const shared_segment &segp, const un { PIGGY_PAGE_IN(Textures[tmap1]); bm = &GameBitmaps[Textures[tmap1].index]; - if (tmap2){ - PIGGY_PAGE_IN(Textures[tmap2&0x3FFF]); - bm2 = &GameBitmaps[Textures[tmap2&0x3FFF].index]; + if (tmap2 != texture2_value::None) + { + const auto texture2 = Textures[get_texture_index(tmap2)]; + PIGGY_PAGE_IN(texture2); + bm2 = &GameBitmaps[texture2.index]; if (bm2->get_flag_mask(BM_FLAG_SUPER_TRANSPARENT)) { bm2 = nullptr; @@ -280,9 +282,9 @@ static void render_face(grs_canvas &canvas, const shared_segment &segp, const un } }else #endif - // New code for overlapping textures... - if (tmap2 != 0) { + if (tmap2 != texture2_value::None) + { bm = &texmerge_get_cached_bitmap( tmap1, tmap2 ); } else { bm = &GameBitmaps[Textures[tmap1].index]; @@ -363,7 +365,7 @@ static void render_face(grs_canvas &canvas, const shared_segment &segp, const un #if DXX_USE_OGL if (bm2){ - g3_draw_tmap_2(canvas, nv, pointlist, uvl_copy, dyn_light, *bm, *bm2, ((tmap2 & 0xC000) >> 14) & 3); + g3_draw_tmap_2(canvas, nv, pointlist, uvl_copy, dyn_light, *bm, *bm2, get_texture_rotation_low(tmap2)); }else #endif g3_draw_tmap(canvas, nv, pointlist, uvl_copy, dyn_light, *bm); @@ -380,7 +382,7 @@ static void render_face(grs_canvas &canvas, const shared_segment &segp, const un // ---------------------------------------------------------------------------- // Only called if editor active. // Used to determine which face was clicked on. -static void check_face(grs_canvas &canvas, const vmsegidx_t segnum, const unsigned sidenum, const unsigned facenum, const unsigned nv, const std::array &vp, const unsigned tmap1, const unsigned tmap2, const std::array &uvl_copy) +static void check_face(grs_canvas &canvas, const vmsegidx_t segnum, const unsigned sidenum, const unsigned facenum, const unsigned nv, const std::array &vp, const unsigned tmap1, const texture2_value tmap2, const std::array &uvl_copy) { #if DXX_USE_EDITOR if (_search_mode) { @@ -445,7 +447,7 @@ static void check_face(grs_canvas &canvas, const vmsegidx_t segnum, const unsign } template -static inline void check_render_face(grs_canvas &canvas, std::index_sequence, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array &ovp, const unsigned tmap1, const unsigned tmap2, const std::array &uvlp, const WALL_IS_DOORWAY_result_t wid_flags, const std::size_t nv) +static inline void check_render_face(grs_canvas &canvas, std::index_sequence, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array &ovp, const unsigned tmap1, const texture2_value tmap2, const std::array &uvlp, const WALL_IS_DOORWAY_result_t wid_flags, const std::size_t nv) { const std::array vp{{ovp[N]...}}; const std::array uvl_copy{{ @@ -456,7 +458,7 @@ static inline void check_render_face(grs_canvas &canvas, std::index_sequence -static inline void check_render_face(grs_canvas &canvas, std::index_sequence is, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array &vp, const unsigned tmap1, const unsigned tmap2, const std::array &uvlp, const WALL_IS_DOORWAY_result_t wid_flags) +static inline void check_render_face(grs_canvas &canvas, std::index_sequence is, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array &vp, const unsigned tmap1, const texture2_value tmap2, const std::array &uvlp, const WALL_IS_DOORWAY_result_t wid_flags) { check_render_face(canvas, is, segnum, sidenum, facenum, vp, tmap1, tmap2, uvlp, wid_flags, 4); } @@ -465,7 +467,7 @@ static inline void check_render_face(grs_canvas &canvas, std::index_sequence -static inline void check_render_face(grs_canvas &canvas, std::index_sequence, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array &vp, const unsigned tmap1, const unsigned tmap2, const std::array &uvlp, const WALL_IS_DOORWAY_result_t wid_flags) +static inline void check_render_face(grs_canvas &canvas, std::index_sequence, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array &vp, const unsigned tmap1, const texture2_value tmap2, const std::array &uvlp, const WALL_IS_DOORWAY_result_t wid_flags) { check_render_face(canvas, std::index_sequence(), segnum, sidenum, facenum, vp, tmap1, tmap2, uvlp, wid_flags, 3); } diff --git a/similar/main/state.cpp b/similar/main/state.cpp index 1e2330dae..7eea49633 100644 --- a/similar/main/state.cpp +++ b/similar/main/state.cpp @@ -1666,7 +1666,8 @@ int state_restore_all_sub(const d_level_shared_destructible_light_state &LevelSh int current_level; char id[5]; fix tmptime32 = 0; - std::array, MAX_SEGMENTS> TempTmapNum, TempTmapNum2; + std::array, MAX_SEGMENTS> TempTmapNum; + std::array, MAX_SEGMENTS> TempTmapNum2; #if defined(DXX_BUILD_DESCENT_I) static constexpr std::integral_constant secret{}; @@ -2034,7 +2035,7 @@ int state_restore_all_sub(const d_level_shared_destructible_light_state &LevelSh { segp->shared_segment::sides[j].wall_num = PHYSFSX_readSXE16(fp, swap); TempTmapNum[segp][j] = PHYSFSX_readSXE16(fp, swap); - TempTmapNum2[segp][j] = PHYSFSX_readSXE16(fp, swap); + TempTmapNum2[segp][j] = static_cast(PHYSFSX_readSXE16(fp, swap)); } } diff --git a/similar/main/switch.cpp b/similar/main/switch.cpp index 5102b68bf..0244e5a3f 100644 --- a/similar/main/switch.cpp +++ b/similar/main/switch.cpp @@ -106,7 +106,8 @@ static int do_light_on(const d_level_shared_destructible_light_state &LevelShare const auto op = [&LevelSharedDestructibleLightState, &Flickering_light_state, &TmapInfo, &ret](const vmsegptridx_t segnum, const unsigned sidenum) { //check if tmap2 casts light before turning the light on. This //is to keep us from turning on blown-out lights - if (TmapInfo[segnum->unique_segment::sides[sidenum].tmap_num2 & 0x3fff].lighting) { + const auto tm2 = get_texture_index(segnum->unique_segment::sides[sidenum].tmap_num2); + if (TmapInfo[tm2].lighting) { ret |= add_light(LevelSharedDestructibleLightState, segnum, sidenum); //any light sets flag enable_flicker(Flickering_light_state, segnum, sidenum); } @@ -123,7 +124,8 @@ static int do_light_off(const d_level_shared_destructible_light_state &LevelShar const auto op = [&LevelSharedDestructibleLightState, &Flickering_light_state, &TmapInfo, &ret](const vmsegptridx_t segnum, const unsigned sidenum) { //check if tmap2 casts light before turning the light off. This //is to keep us from turning off blown-out lights - if (TmapInfo[segnum->unique_segment::sides[sidenum].tmap_num2 & 0x3fff].lighting) { + const auto tm2 = get_texture_index(segnum->unique_segment::sides[sidenum].tmap_num2); + if (TmapInfo[tm2].lighting) { ret |= subtract_light(LevelSharedDestructibleLightState, segnum, sidenum); //any light sets flag disable_flicker(Flickering_light_state, segnum, sidenum); } diff --git a/similar/main/texmerge.cpp b/similar/main/texmerge.cpp index 46309797a..0425b791a 100644 --- a/similar/main/texmerge.cpp +++ b/similar/main/texmerge.cpp @@ -31,6 +31,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "rle.h" #include "timer.h" #include "piggy.h" +#include "segment.h" #include "texmerge.h" #include "piggy.h" @@ -50,7 +51,7 @@ struct TEXTURE_CACHE { grs_bitmap_ptr bitmap; grs_bitmap * bottom_bmp; grs_bitmap * top_bmp; - int orient; + texture2_rotation_high orient; fix64 last_time_used; }; @@ -140,23 +141,23 @@ static void merge_textures_case(const unsigned wh, const uint8_t *const top_data * for each byte processed. */ template -static void merge_textures(unsigned orient, const grs_bitmap &expanded_bottom_bmp, const grs_bitmap &expanded_top_bmp, uint8_t *const dest_data) +static void merge_textures(const texture2_rotation_high orient, const grs_bitmap &expanded_bottom_bmp, const grs_bitmap &expanded_top_bmp, uint8_t *const dest_data) { const auto &top_data = expanded_top_bmp.bm_data; const auto &bottom_data = expanded_bottom_bmp.bm_data; const auto wh = expanded_bottom_bmp.bm_w; switch (orient) { - case 0: + case texture2_rotation_high::Normal: merge_textures_case(wh, top_data, bottom_data, dest_data); break; - case 1: + case texture2_rotation_high::_1: merge_textures_case(wh, top_data, bottom_data, dest_data); break; - case 2: + case texture2_rotation_high::_2: merge_textures_case(wh, top_data, bottom_data, dest_data); break; - case 3: + case texture2_rotation_high::_3: merge_textures_case(wh, top_data, bottom_data, dest_data); break; } @@ -177,7 +178,6 @@ int texmerge_init() i.last_time_used = -1; i.top_bmp = NULL; i.bottom_bmp = NULL; - i.orient = -1; } return 1; @@ -190,7 +190,6 @@ void texmerge_flush() i.last_time_used = -1; i.top_bmp = NULL; i.bottom_bmp = NULL; - i.orient = -1; } } @@ -206,16 +205,16 @@ void texmerge_close() //--unused-- int info_printed = 0; -grs_bitmap &texmerge_get_cached_bitmap(unsigned tmap_bottom, unsigned tmap_top) +grs_bitmap &texmerge_get_cached_bitmap(const unsigned tmap_bottom, const texture2_value tmap_top) { grs_bitmap *bitmap_top, *bitmap_bottom; - int orient; int lowest_time_used; - bitmap_top = &GameBitmaps[Textures[tmap_top&0x3FFF].index]; + auto &texture_top = Textures[get_texture_index(tmap_top)]; + bitmap_top = &GameBitmaps[texture_top.index]; bitmap_bottom = &GameBitmaps[Textures[tmap_bottom].index]; - orient = ((tmap_top&0xC000)>>14) & 3; + const auto orient = get_texture_rotation_high(tmap_top); lowest_time_used = Cache[0].last_time_used; auto least_recently_used = &Cache.front(); @@ -237,12 +236,12 @@ grs_bitmap &texmerge_get_cached_bitmap(unsigned tmap_bottom, unsigned tmap_top) // Make sure the bitmaps are paged in... - PIGGY_PAGE_IN(Textures[tmap_top&0x3FFF]); + PIGGY_PAGE_IN(texture_top); PIGGY_PAGE_IN(Textures[tmap_bottom]); if (bitmap_bottom->bm_w != bitmap_bottom->bm_h || bitmap_top->bm_w != bitmap_top->bm_h) - Error("Texture width != texture height!\nbottom tmap = %u; bottom bitmap = %u; bottom width = %u; bottom height = %u\ntop tmap = %u; top bitmap = %u; top width=%u; top height=%u", tmap_bottom, Textures[tmap_bottom].index, bitmap_bottom->bm_w, bitmap_bottom->bm_h, tmap_top, Textures[tmap_top & 0x3fff].index, bitmap_top->bm_w, bitmap_top->bm_h); + Error("Texture width != texture height!\nbottom tmap = %u; bottom bitmap = %u; bottom width = %u; bottom height = %u\ntop tmap = %hu; top bitmap = %u; top width=%u; top height=%u", tmap_bottom, Textures[tmap_bottom].index, bitmap_bottom->bm_w, bitmap_bottom->bm_h, static_cast(tmap_top), texture_top.index, bitmap_top->bm_w, bitmap_top->bm_h); if (bitmap_bottom->bm_w != bitmap_top->bm_w || bitmap_bottom->bm_h != bitmap_top->bm_h) - Error("Top and Bottom textures have different size!\nbottom tmap = %u; bottom bitmap = %u; bottom width = %u; bottom height = %u\ntop tmap = %u; top bitmap = %u; top width=%u; top height=%u", tmap_bottom, Textures[tmap_bottom].index, bitmap_bottom->bm_w, bitmap_bottom->bm_h, tmap_top, Textures[tmap_top & 0x3fff].index, bitmap_top->bm_w, bitmap_top->bm_h); + Error("Top and Bottom textures have different size!\nbottom tmap = %u; bottom bitmap = %u; bottom width = %u; bottom height = %u\ntop tmap = %hu; top bitmap = %u; top width=%u; top height=%u", tmap_bottom, Textures[tmap_bottom].index, bitmap_bottom->bm_w, bitmap_bottom->bm_h, static_cast(tmap_top), texture_top.index, bitmap_top->bm_w, bitmap_top->bm_h); least_recently_used->bitmap = gr_create_bitmap(bitmap_bottom->bm_w, bitmap_bottom->bm_h); #if DXX_USE_OGL diff --git a/similar/main/wall.cpp b/similar/main/wall.cpp index a5b0043b9..11edb1176 100644 --- a/similar/main/wall.cpp +++ b/similar/main/wall.cpp @@ -142,7 +142,7 @@ struct find_cloaked_wall_predicate static std::pair get_transparency_check_values(const unique_side &side) { - if (const uint_fast32_t masked_tmap_num2 = side.tmap_num2 & 0x3FFF) + if (const auto masked_tmap_num2 = static_cast(get_texture_index(side.tmap_num2))) return {masked_tmap_num2, BM_FLAG_SUPER_TRANSPARENT}; return {side.tmap_num, BM_FLAG_TRANSPARENT}; } @@ -278,12 +278,12 @@ void wall_set_tmap_num(const wclip &anim, const vmsegptridx_t seg, const unsigne newdemo_record_wall_set_tmap_num1(seg,side,csegp,cside,tmap); } } else { - assert(tmap != 0 && uside.tmap_num2 != 0); - if (tmap != uside.tmap_num2 || tmap != cuside.tmap_num2) + const texture2_value t2{tmap}; + if (t2 != uside.tmap_num2 || t2 != cuside.tmap_num2) { - uside.tmap_num2 = cuside.tmap_num2 = tmap; + uside.tmap_num2 = cuside.tmap_num2 = t2; if (newdemo_state == ND_STATE_RECORDING) - newdemo_record_wall_set_tmap_num2(seg,side,csegp,cside,tmap); + newdemo_record_wall_set_tmap_num2(seg,side,csegp,cside,t2); } } } @@ -1514,7 +1514,7 @@ class blast_nearby_glass_context fvcvertptr &vcvertptr; fvcwallptr &vcwallptr; visited_segment_bitarray_t visited; - unsigned can_blast(const int16_t &tmap_num2) const; + unsigned can_blast(texture2_value tmap_num2) const; public: blast_nearby_glass_context(const object &obj, const fix damage, const d_eclip_array &Effects, const GameBitmaps_array &GameBitmaps, const Textures_array &Textures, const TmapInfo_array &TmapInfo, const d_vclip_array &Vclip, fvcvertptr &vcvertptr, fvcwallptr &vcwallptr) : obj(obj), damage(damage), Effects(Effects), GameBitmaps(GameBitmaps), @@ -1527,9 +1527,9 @@ public: void process_segment(vmsegptridx_t segp, unsigned steps_remaining); }; -unsigned blast_nearby_glass_context::can_blast(const int16_t &tmap_num2) const +unsigned blast_nearby_glass_context::can_blast(const texture2_value tmap_num2) const { - const auto tm = tmap_num2 & 0x3fff; //tm without flags + const auto tm = get_texture_index(tmap_num2); //tm without flags auto &ti = TmapInfo[tm]; const auto ec = ti.eclip_num; if (ec == eclip_none) @@ -1554,7 +1554,7 @@ void blast_nearby_glass_context::process_segment(const vmsegptridx_t segp, const // Process only walls which have glass. auto &&uside = e.value; - if (const auto &tmap_num2 = uside.tmap_num2) + if (const auto tmap_num2 = uside.tmap_num2; tmap_num2 != texture2_value::None) { if (can_blast(tmap_num2)) {