Use enum class for tmap_num2

Define separate enum values for rotation data in both the high bits,
where it is usually kept, and the low bits, where it is sometimes used
for math or comparisons.

Define an enum value to represent the composite of the index and the
rotation, since the composite is not suitable for use as an array
subscript.  Add helper functions to extract the component pieces.
This commit is contained in:
Kp 2020-08-24 01:31:28 +00:00
parent da66b1d9b8
commit 6d3dce4e16
36 changed files with 278 additions and 186 deletions

View file

@ -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 <std::size_t N>
static inline void g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const std::array<cg3s_point *, N> &pointlist, const std::array<g3s_uvl, N> &uvl_list, const std::array<g3s_lrgb, N> &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<cg3s_point *, N> &pointlist, const std::array<g3s_uvl, N> &uvl_list, const std::array<g3s_lrgb, N> &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

View file

@ -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<fix, 0> DEFAULT_LIGHTING{}; // (F1_0/2)

View file

@ -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

View file

@ -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);

View file

@ -148,10 +148,75 @@ struct shared_side
std::array<vms_vector, 2> 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<uint16_t>(texture2_rotation_low::_1) << TEXTURE2_ROTATION_SHIFT,
_2 = static_cast<uint16_t>(texture2_rotation_low::_2) << TEXTURE2_ROTATION_SHIFT,
_3 = static_cast<uint16_t>(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<texture2_rotation_high>(static_cast<uint32_t>(t) + (1u << TEXTURE2_ROTATION_SHIFT)));
}
static constexpr uint16_t get_texture_index(const texture2_value t)
{
return static_cast<uint16_t>(t) & TEXTURE2_ROTATION_INDEX_MASK;
}
static constexpr texture2_rotation_high get_texture_rotation_high(const texture2_value t)
{
return static_cast<texture2_rotation_high>(static_cast<uint16_t>(t) & ~TEXTURE2_ROTATION_INDEX_MASK);
}
static constexpr texture2_rotation_low get_texture_rotation_low(const texture2_rotation_high t)
{
return static_cast<texture2_rotation_low>(static_cast<uint16_t>(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<texture2_value>(t | static_cast<unsigned>(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<uvl, 4> uvls;
};

View file

@ -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 */

View file

@ -222,8 +222,8 @@ struct wclip : public prohibit_void_ptr<wclip>
fix play_time;
uint16_t num_frames;
union {
std::array<int16_t, MAX_CLIP_FRAMES> frames;
std::array<int16_t, MAX_CLIP_FRAMES_D1> d1_frames;
std::array<uint16_t, MAX_CLIP_FRAMES> frames;
std::array<uint16_t, MAX_CLIP_FRAMES_D1> d1_frames;
};
short open_sound;
short close_sound;

View file

@ -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<int, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY> 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;

View file

@ -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);

View file

@ -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 {

View file

@ -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
}
}
}

View file

@ -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<segnum_t>(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<unsigned>(get_texture_rotation_low(uside.tmap_num2)));
}
//--------------- Current_vertex_numbers -------------

View file

@ -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;

View file

@ -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;

View file

@ -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<uint16_t>(tmap_num2));
range_for (auto &i, seg.u.sides[sidenum].uvls)
{

View file

@ -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 = {};

View file

@ -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;

View file

@ -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));
}
}
}

View file

@ -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<int, 0> 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<unsigned>(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)];

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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<unsigned>(f2i(u*bm->bm_w)) % bm->bm_w;

View file

@ -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;
}

View file

@ -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<uint16_t>(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<texture2_value>(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 = {};
}
}

View file

@ -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);

View file

@ -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

View file

@ -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<uint8_t *>(&s), 2, &sum1, &sum2);
s = INTEL_SHORT(uside.tmap_num);
do_checksum_calc(reinterpret_cast<uint8_t *>(&s), 2, &sum1, &sum2);
s = INTEL_SHORT(uside.tmap_num2);
s = static_cast<uint16_t>(uside.tmap_num2);
s = INTEL_SHORT(s);
do_checksum_calc(reinterpret_cast<uint8_t *>(&s), 2, &sum1, &sum2);
range_for (auto &k, uside.uvls)
{

View file

@ -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<uint16_t>(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;
}
}
}

View file

@ -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 &&

View file

@ -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<uint16_t>(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<uint16_t>(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<uint16_t>(side.tmap_num2));
}
}

View file

@ -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] );
}

View file

@ -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<unsigned, 4> &vp, const unsigned tmap1, const unsigned tmap2, std::array<g3s_uvl, 4> 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<unsigned, 4> &vp, const unsigned tmap1, const texture2_value tmap2, std::array<g3s_uvl, 4> 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<unsigned, 4> &vp, const unsigned tmap1, const unsigned tmap2, const std::array<g3s_uvl, 4> &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<unsigned, 4> &vp, const unsigned tmap1, const texture2_value tmap2, const std::array<g3s_uvl, 4> &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 <std::size_t... N>
static inline void check_render_face(grs_canvas &canvas, std::index_sequence<N...>, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array<unsigned, 4> &ovp, const unsigned tmap1, const unsigned tmap2, const std::array<uvl, 4> &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<N...>, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array<unsigned, 4> &ovp, const unsigned tmap1, const texture2_value tmap2, const std::array<uvl, 4> &uvlp, const WALL_IS_DOORWAY_result_t wid_flags, const std::size_t nv)
{
const std::array<unsigned, 4> vp{{ovp[N]...}};
const std::array<g3s_uvl, 4> uvl_copy{{
@ -456,7 +458,7 @@ static inline void check_render_face(grs_canvas &canvas, std::index_sequence<N..
}
template <std::size_t N0, std::size_t N1, std::size_t N2, std::size_t N3>
static inline void check_render_face(grs_canvas &canvas, std::index_sequence<N0, N1, N2, N3> is, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array<unsigned, 4> &vp, const unsigned tmap1, const unsigned tmap2, const std::array<uvl, 4> &uvlp, const WALL_IS_DOORWAY_result_t wid_flags)
static inline void check_render_face(grs_canvas &canvas, std::index_sequence<N0, N1, N2, N3> is, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array<unsigned, 4> &vp, const unsigned tmap1, const texture2_value tmap2, const std::array<uvl, 4> &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<N0,
* are default constructed, gcc zero initializes all members.
*/
template <std::size_t N0, std::size_t N1, std::size_t N2>
static inline void check_render_face(grs_canvas &canvas, std::index_sequence<N0, N1, N2>, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array<unsigned, 4> &vp, const unsigned tmap1, const unsigned tmap2, const std::array<uvl, 4> &uvlp, const WALL_IS_DOORWAY_result_t wid_flags)
static inline void check_render_face(grs_canvas &canvas, std::index_sequence<N0, N1, N2>, const vcsegptridx_t segnum, const unsigned sidenum, const unsigned facenum, const std::array<unsigned, 4> &vp, const unsigned tmap1, const texture2_value tmap2, const std::array<uvl, 4> &uvlp, const WALL_IS_DOORWAY_result_t wid_flags)
{
check_render_face(canvas, std::index_sequence<N0, N1, N2, 3>(), segnum, sidenum, facenum, vp, tmap1, tmap2, uvlp, wid_flags, 3);
}

View file

@ -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<std::array<short, MAX_SIDES_PER_SEGMENT>, MAX_SEGMENTS> TempTmapNum, TempTmapNum2;
std::array<std::array<short, MAX_SIDES_PER_SEGMENT>, MAX_SEGMENTS> TempTmapNum;
std::array<std::array<texture2_value, MAX_SIDES_PER_SEGMENT>, MAX_SEGMENTS> TempTmapNum2;
#if defined(DXX_BUILD_DESCENT_I)
static constexpr std::integral_constant<secret_restore, secret_restore::none> 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<texture2_value>(PHYSFSX_readSXE16(fp, swap));
}
}

View file

@ -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);
}

View file

@ -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 <typename texture_transform>
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<texture_transform, merge_texture_0>(wh, top_data, bottom_data, dest_data);
break;
case 1:
case texture2_rotation_high::_1:
merge_textures_case<texture_transform, merge_texture_1>(wh, top_data, bottom_data, dest_data);
break;
case 2:
case texture2_rotation_high::_2:
merge_textures_case<texture_transform, merge_texture_2>(wh, top_data, bottom_data, dest_data);
break;
case 3:
case texture2_rotation_high::_3:
merge_textures_case<texture_transform, merge_texture_3>(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<uint16_t>(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<uint16_t>(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

View file

@ -142,7 +142,7 @@ struct find_cloaked_wall_predicate
static std::pair<uint_fast32_t, uint_fast32_t> 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<uint_fast32_t>(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))
{