From b04118032ee1b0ee6e03ee3293543e7155fe73ed Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 1 Nov 2016 22:58:53 +0100 Subject: [PATCH 01/11] Fix wrapping and scaling issue for the U texture coordinate for sprites --- src/r_things.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index cad434fa5..6ef4e8027 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -954,15 +954,14 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor return; tx += tex->GetWidth() * thingxscalemul; - double dtx2 = tx * xscale; - x2 = centerx + xs_RoundToInt(dtx2); + x2 = centerx + xs_RoundToInt(tx * xscale); // off the left side or too small? if ((x2 < WindowLeft || x2 <= x1)) return; xscale = spriteScale.X * xscale / tex->Scale.X; - iscale = (fixed_t)(tex->GetWidth() / (dtx2 - dtx1) * FRACUNIT); + iscale = (fixed_t)(FRACUNIT / xscale); // Round towards zero to avoid wrapping in edge cases double yscale = spriteScale.Y / tex->Scale.Y; @@ -990,7 +989,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->xiscale = iscale; } - vis->startfrac += (fixed_t)(vis->xiscale * (vis->x1 - centerx - dtx1 + 0.5 * thingxscalemul)); + vis->startfrac += (fixed_t)(vis->xiscale * (vis->x1 - centerx + 0.5 - dtx1)); } else { From 4b4d7a07685c5cbf752db9c9b8df4b1a8015d37d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 4 Nov 2016 02:03:23 +0100 Subject: [PATCH 02/11] Add texturefrac bounds clamping to R_DrawMaskedColumn to avoid buffer overruns --- src/r_things.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/r_things.cpp b/src/r_things.cpp index 6ef4e8027..e7d130fa8 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -281,6 +281,15 @@ void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span, bool us dc_source = column; dc_dest = (ylookup[dc_yl] + dc_x) + dc_destorg; dc_count = dc_yh - dc_yl + 1; + + fixed_t maxfrac = ((top + length) << FRACBITS) - 1; + dc_texturefrac = MAX(dc_texturefrac, 0); + dc_texturefrac = MIN(dc_texturefrac, maxfrac); + if (dc_iscale > 0) + dc_count = MIN(dc_count, (maxfrac - dc_texturefrac + dc_iscale - 1) / dc_iscale); + else if (dc_iscale < 0) + dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale)); + if (useRt) hcolfunc_pre(); else From 7755a3525aeff2936baaad1d1d79ed89045186a4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 4 Nov 2016 11:17:22 +0100 Subject: [PATCH 03/11] - do not allow menu slider values very close to zero. They not only can produce a glitched number display but also some weird inconsistencies when operating a slider. --- src/menu/optionmenuitems.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 76718809e..0fadeca37 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -671,6 +671,7 @@ public: { return FOptionMenuItem::MenuEvent(mkey, fromcontroller); } + if (fabs(value) < FLT_EPSILON) value = 0; SetSliderValue(clamp(value, mMin, mMax)); S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); return true; From 540f20882ee1a9827feec5ff7125cc1f8d9241b8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 4 Nov 2016 11:32:57 +0100 Subject: [PATCH 04/11] - fixed: Degeneration should use the same base health value as all the rest of the engine. - also replaced deh.MaxHealth in the bot code which was the only other remaining case where this was used as health limiter. --- src/b_think.cpp | 2 +- src/p_user.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/b_think.cpp b/src/b_think.cpp index 5a98b5c1a..d097db864 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -358,7 +358,7 @@ void DBot::WhatToGet (AActor *item) } else if ((typeis (Megasphere) || typeis (Soulsphere) || typeis (HealthBonus)) && player->mo->health >= deh.MaxSoulsphere) return; - else if (item->IsKindOf (RUNTIME_CLASS(AHealth)) && player->mo->health >= deh.MaxHealth /*MAXHEALTH*/) + else if (item->IsKindOf (RUNTIME_CLASS(AHealth)) && player->mo->health >= player->mo->GetMaxHealth() + player->mo->stamina) return; if ((dest == NULL || diff --git a/src/p_user.cpp b/src/p_user.cpp index b7bd4c2ec..4a15e7f18 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2677,10 +2677,11 @@ void P_PlayerThink (player_t *player) // Apply degeneration. if (dmflags2 & DF2_YES_DEGENERATION) { - if ((level.time % TICRATE) == 0 && player->health > deh.MaxHealth) + int maxhealth = player->mo->GetMaxHealth() + player->mo->stamina; + if ((level.time % TICRATE) == 0 && player->health > maxhealth) { - if (player->health - 5 < deh.MaxHealth) - player->health = deh.MaxHealth; + if (player->health - 5 < maxhealth) + player->health = maxhealth; else player->health--; From faea61cf0177832ff668b1c07bb24c9064c33104 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 4 Nov 2016 12:43:23 +0100 Subject: [PATCH 05/11] - fixed: Turbo messages were printed, even when no turbo mode was active. --- src/g_game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index ec79d59e6..810a29da1 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1172,7 +1172,7 @@ void G_Ticker () } // check for turbo cheats - if (cmd->ucmd.forwardmove > TURBOTHRESHOLD && + if (turbo > 100.f && cmd->ucmd.forwardmove > TURBOTHRESHOLD && !(gametic&31) && ((gametic>>5)&(MAXPLAYERS-1)) == i ) { Printf ("%s is turbo!\n", players[i].userinfo.GetName()); From 60ae4a8568d9fc929c803036fa16fa0f9bfb68a2 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 5 Nov 2016 04:02:30 +0100 Subject: [PATCH 06/11] Replace build wallscan with a rewritten version that tile and scale correctly --- src/r_segs.cpp | 791 +++++++++++++++++++------------------------------ 1 file changed, 303 insertions(+), 488 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 45e3044d3..ae33332de 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1066,56 +1066,188 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) return; } -// prevlineasm1 is like vlineasm1 but skips the loop if only drawing one pixel -inline fixed_t prevline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, BYTE *dest) +struct WallscanSampler { - dc_iscale = vince; - dc_colormap = colormap; - dc_count = count; - dc_texturefrac = vplce; - dc_source = bufplce; - dc_dest = dest; - return doprevline1 (); -} + WallscanSampler() { } + WallscanSampler(int y1, float swal, double yrepeat, fixed_t xoffset, FTexture *texture, const BYTE*(*getcol)(FTexture *texture, int x)); -void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, - double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) + uint32_t uv_pos; + uint32_t uv_step; + uint32_t uv_max; + + const BYTE *source; + uint32_t height; +}; + +WallscanSampler::WallscanSampler(int y1, float swal, double yrepeat, fixed_t xoffset, FTexture *texture, const BYTE*(*getcol)(FTexture *texture, int x)) { - int x, fracbits; - int y1ve[4], y2ve[4], u4, d4, z; - char bad; - float light = rw_light - rw_lightstep; - SDWORD xoffset; - BYTE *basecolormapdata; - double iscale; + height = texture->GetHeight(); - // This function also gets used to draw skies. Unlike BUILD, skies are - // drawn by visplane instead of by bunch, so these checks are invalid. - //if ((uwal[x1] > viewheight) && (uwal[x2] > viewheight)) return; - //if ((dwal[x1] < 0) && (dwal[x2] < 0)) return; - - if (rw_pic->UseType == FTexture::TEX_Null) + int uv_fracbits = 32 - texture->HeightBits; + if (uv_fracbits != 32) { - return; + uv_max = height << uv_fracbits; + + // Find start uv in [0-base_height[ range. + // Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range. + double uv_stepd = swal * yrepeat; + double v = (dc_texturemid + uv_stepd * (y1 - CenterY + 0.5)) / height; + v = v - floor(v); + v *= height; + v *= (1 << uv_fracbits); + + uv_pos = (uint32_t)v; + uv_step = xs_ToFixed(uv_fracbits, uv_stepd); + if (uv_step == 0) // To prevent divide by zero elsewhere + uv_step = 1; + } + else + { // Hack for one pixel tall textures + uv_pos = 0; + uv_step = 0; + uv_max = 1; } -//extern cycle_t WallScanCycles; -//clock (WallScanCycles); + source = getcol(texture, xoffset >> FRACBITS); +} - rw_pic->GetHeight(); // Make sure texture size is loaded - fracbits = 32 - rw_pic->HeightBits; +// Draw a column with support for non-power-of-two ranges +void wallscan_drawcol1(int x, int y1, int y2, WallscanSampler &sampler, DWORD(*draw1column)()) +{ + if (sampler.uv_max == 0) // power of two + { + int count = y2 - y1; + + dc_source = sampler.source; + dc_dest = (ylookup[y1] + x) + dc_destorg; + dc_count = count; + dc_iscale = sampler.uv_step; + dc_texturefrac = sampler.uv_pos; + draw1column(); + + uint64_t step64 = sampler.uv_step; + uint64_t pos64 = sampler.uv_pos; + sampler.uv_pos = (uint32_t)(pos64 + step64 * count); + } + else + { + uint32_t uv_pos = sampler.uv_pos; + + uint32_t left = y2 - y1; + while (left > 0) + { + uint32_t available = sampler.uv_max - uv_pos; + uint32_t next_uv_wrap = available / sampler.uv_step; + if (available % sampler.uv_step != 0) + next_uv_wrap++; + uint32_t count = MIN(left, next_uv_wrap); + + dc_source = sampler.source; + dc_dest = (ylookup[y1] + x) + dc_destorg; + dc_count = count; + dc_iscale = sampler.uv_step; + dc_texturefrac = uv_pos; + draw1column(); + + left -= count; + uv_pos += sampler.uv_step * count; + if (uv_pos >= sampler.uv_max) + uv_pos -= sampler.uv_max; + } + + sampler.uv_pos = uv_pos; + } +} + +// Draw four columns with support for non-power-of-two ranges +void wallscan_drawcol4(int x, int y1, int y2, WallscanSampler *sampler, void(*draw4columns)()) +{ + if (sampler[0].uv_max == 0) // power of two, no wrap handling needed + { + int count = y2 - y1; + for (int i = 0; i < 4; i++) + { + bufplce[i] = sampler[i].source; + vplce[i] = sampler[i].uv_pos; + vince[i] = sampler[i].uv_step; + + uint64_t step64 = sampler[i].uv_step; + uint64_t pos64 = sampler[i].uv_pos; + sampler[i].uv_pos = (uint32_t)(pos64 + step64 * count); + } + dc_dest = (ylookup[y1] + x) + dc_destorg; + dc_count = count; + draw4columns(); + } + else + { + dc_dest = (ylookup[y1] + x) + dc_destorg; + for (int i = 0; i < 4; i++) + { + bufplce[i] = sampler[i].source; + } + + uint32_t left = y2 - y1; + while (left > 0) + { + // Find which column wraps first + uint32_t count = left; + for (int i = 0; i < 4; i++) + { + uint32_t available = sampler[i].uv_max - sampler[i].uv_pos; + uint32_t next_uv_wrap = available / sampler[i].uv_step; + if (available % sampler[i].uv_step != 0) + next_uv_wrap++; + count = MIN(next_uv_wrap, count); + } + + // Draw until that column wraps + for (int i = 0; i < 4; i++) + { + vplce[i] = sampler[i].uv_pos; + vince[i] = sampler[i].uv_step; + } + dc_count = count; + draw4columns(); + + // Wrap the uv position + for (int i = 0; i < 4; i++) + { + sampler[i].uv_pos += sampler[i].uv_step * count; + if (sampler[i].uv_pos >= sampler[i].uv_max) + sampler[i].uv_pos -= sampler[i].uv_max; + } + + left -= count; + } + } +} + +typedef DWORD(*Draw1ColumnFuncPtr)(); +typedef void(*Draw4ColumnsFuncPtr)(); + +void wallscan_any( + int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, + const BYTE *(*getcol)(FTexture *tex, int x), + void(setupwallscan(int bits, Draw1ColumnFuncPtr &draw1, Draw4ColumnsFuncPtr &draw2))) +{ + if (rw_pic->UseType == FTexture::TEX_Null) + return; + + fixed_t xoffset = rw_offset; + + rw_pic->GetHeight(); // To ensure that rw_pic->HeightBits has been set + int fracbits = 32 - rw_pic->HeightBits; if (fracbits == 32) { // Hack for one pixel tall textures fracbits = 0; yrepeat = 0; dc_texturemid = 0; } - setupvline(fracbits); - xoffset = rw_offset; - basecolormapdata = basecolormap->Maps; - x = x1; - //while ((umost[x] > dmost[x]) && (x < x2)) x++; + DWORD(*draw1column)(); + void(*draw4columns)(); + setupwallscan(fracbits, draw1column, draw4columns); bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); if (fixed) @@ -1126,128 +1258,175 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l palookupoffse[3] = dc_colormap; } - for(; (x < x2) && (x & 3); ++x) + if (fixedcolormap) + dc_colormap = fixedcolormap; + else + dc_colormap = basecolormap->Maps; + + float light = rw_light; + + // Calculate where 4 column alignment begins and ends: + int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2); + int aligned_x2 = clamp(x2 / 4 * 4, x1, x2); + + // First unaligned columns: + for (int x = x1; x < aligned_x1; x++, light += rw_lightstep) { - light += rw_lightstep; - y1ve[0] = uwal[x];//max(uwal[x],umost[x]); - y2ve[0] = dwal[x];//min(dwal[x],dmost[x]); - if (y2ve[0] <= y1ve[0]) continue; - assert (y1ve[0] < viewheight); - assert (y2ve[0] <= viewheight); + int y1 = uwal[x]; + int y2 = dwal[x]; + if (y2 <= y1) + continue; if (!fixed) - { // calculate lighting - dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } + dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); - dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); - dc_dest = ylookup[y1ve[0]] + x + dc_destorg; - dc_count = y2ve[0] - y1ve[0]; - iscale = swal[x] * yrepeat; - dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); - - dovline1(); + WallscanSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, rw_pic, getcol); + wallscan_drawcol1(x, y1, y2, sampler, draw1column); } - for(; x < x2-3; x += 4) + // The aligned columns + for (int x = aligned_x1; x < aligned_x2; x += 4) { - bad = 0; - for (z = 3; z>= 0; --z) - { - y1ve[z] = uwal[x+z];//max(uwal[x+z],umost[x+z]); - y2ve[z] = dwal[x+z];//min(dwal[x+z],dmost[x+z])-1; - if (y2ve[z] <= y1ve[z]) { bad += 1<> FRACBITS); - iscale = swal[x + z] * yrepeat; - vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 0.5)); - } - if (bad == 15) + float lights[4]; + for (int i = 0; i < 4; i++) { - light += rw_lightstep * 4; - continue; + lights[i] = light; + light += rw_lightstep; } - if (!fixed) + WallscanSampler sampler[4]; + for (int i = 0; i < 4; i++) + sampler[i] = WallscanSampler(y1[i], swal[x + i], yrepeat, lwal[x + i] + xoffset, rw_pic, getcol); + + // Figure out where we vertically can start and stop drawing 4 columns in one go + int middle_y1 = y1[0]; + int middle_y2 = y2[0]; + for (int i = 1; i < 4; i++) { - for (z = 0; z < 4; ++z) + middle_y1 = MAX(y1[i], middle_y1); + middle_y2 = MIN(y2[i], middle_y2); + } + + // If we got an empty column in our set we cannot draw 4 columns in one go: + bool empty_column_in_set = false; + for (int i = 0; i < 4; i++) + { + if (y2[i] <= y1[i]) + empty_column_in_set = true; + } + + if (empty_column_in_set || middle_y2 <= middle_y1) + { + for (int i = 0; i < 4; i++) { - light += rw_lightstep; - palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - } + if (y2[i] <= y1[i]) + continue; - u4 = MAX(MAX(y1ve[0],y1ve[1]),MAX(y1ve[2],y1ve[3])); - d4 = MIN(MIN(y2ve[0],y2ve[1]),MIN(y2ve[2],y2ve[3])); - - if ((bad != 0) || (u4 >= d4)) - { - for (z = 0; z < 4; ++z) - { - if (!(bad & 1)) - { - prevline1(vince[z],palookupoffse[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+x+z+dc_destorg); - } - bad >>= 1; + if (!fixed) + dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT); + wallscan_drawcol1(x + i, y1[i], y2[i], sampler[i], draw1column); } continue; } - for (z = 0; z < 4; ++z) + // Draw the first rows where not all 4 columns are active + for (int i = 0; i < 4; i++) { - if (u4 > y1ve[z]) - { - vplce[z] = prevline1(vince[z],palookupoffse[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+x+z+dc_destorg); - } + if (!fixed) + dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT); + + if (y1[i] < middle_y1) + wallscan_drawcol1(x + i, y1[i], middle_y1, sampler[i], draw1column); } - if (d4 > u4) + // Draw the area where all 4 columns are active + if (!fixed) { - dc_count = d4-u4; - dc_dest = ylookup[u4]+x+dc_destorg; - dovline4(); - } - - BYTE *i = x+ylookup[d4]+dc_destorg; - for (z = 0; z < 4; ++z) - { - if (y2ve[z] > d4) + for (int i = 0; i < 4; i++) { - prevline1(vince[z],palookupoffse[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); + palookupoffse[i] = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT); } } + wallscan_drawcol4(x, middle_y1, middle_y2, sampler, draw4columns); + + // Draw the last rows where not all 4 columns are active + for (int i = 0; i < 4; i++) + { + if (!fixed) + dc_colormap = basecolormap->Maps + (GETPALOOKUP(lights[i], wallshade) << COLORMAPSHIFT); + + if (middle_y2 < y2[i]) + wallscan_drawcol1(x + i, middle_y2, y2[i], sampler[i], draw1column); + } } - for(;xMaps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); - dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); - dc_dest = ylookup[y1ve[0]] + x + dc_destorg; - dc_count = y2ve[0] - y1ve[0]; - iscale = swal[x] * yrepeat; - dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); - - dovline1(); + WallscanSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, rw_pic, getcol); + wallscan_drawcol1(x, y1, y2, sampler, draw1column); } -//unclock (WallScanCycles); + NetUpdate(); +} - NetUpdate (); +void wallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) +{ + wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4) + { + setupvline(bits); + line1 = dovline1; + line4 = dovline4; + }); +} + +void maskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) +{ + if (!rw_pic->bMasked) // Textures that aren't masked can use the faster wallscan. + { + wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol); + } + else + { + wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4) + { + setupmvline(bits); + line1 = domvline1; + line4 = domvline4; + }); + } +} + +void transmaskwallscan(int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) +{ + static fixed_t(*tmvline1)(); + static void(*tmvline4)(); + if (!R_GetTransMaskDrawers(&tmvline1, &tmvline4)) + { + // The current translucency is unsupported, so draw with regular maskwallscan instead. + maskwallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol); + } + else + { + wallscan_any(x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol, [](int bits, Draw1ColumnFuncPtr &line1, Draw4ColumnsFuncPtr &line4) + { + setuptmvline(bits); + line1 = reinterpret_cast(tmvline1); + line4 = tmvline4; + }); + } } void wallscan_striped (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat) @@ -1423,370 +1602,6 @@ static void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *d } } -inline fixed_t mvline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, BYTE *dest) -{ - dc_iscale = vince; - dc_colormap = colormap; - dc_count = count; - dc_texturefrac = vplce; - dc_source = bufplce; - dc_dest = dest; - return domvline1 (); -} - -void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, - double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) -{ - int x, fracbits; - BYTE *p; - int y1ve[4], y2ve[4], u4, d4, startx, dax, z; - char bad; - float light = rw_light - rw_lightstep; - SDWORD xoffset; - BYTE *basecolormapdata; - double iscale; - - if (rw_pic->UseType == FTexture::TEX_Null) - { - return; - } - - if (!rw_pic->bMasked) - { // Textures that aren't masked can use the faster wallscan. - wallscan (x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol); - return; - } - -//extern cycle_t WallScanCycles; -//clock (WallScanCycles); - - rw_pic->GetHeight(); // Make sure texture size is loaded - fracbits = 32- rw_pic->HeightBits; - if (fracbits == 32) - { // Hack for one pixel tall textures - fracbits = 0; - yrepeat = 0; - dc_texturemid = 0; - } - setupmvline(fracbits); - xoffset = rw_offset; - basecolormapdata = basecolormap->Maps; - - x = startx = x1; - p = x + dc_destorg; - - bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); - if (fixed) - { - palookupoffse[0] = dc_colormap; - palookupoffse[1] = dc_colormap; - palookupoffse[2] = dc_colormap; - palookupoffse[3] = dc_colormap; - } - - for(; (x < x2) && ((size_t)p & 3); ++x, ++p) - { - light += rw_lightstep; - y1ve[0] = uwal[x];//max(uwal[x],umost[x]); - y2ve[0] = dwal[x];//min(dwal[x],dmost[x]); - if (y2ve[0] <= y1ve[0]) continue; - - if (!fixed) - { // calculate lighting - dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - - dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); - dc_dest = ylookup[y1ve[0]] + p; - dc_count = y2ve[0] - y1ve[0]; - iscale = swal[x] * yrepeat; - dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); - - domvline1(); - } - - for(; x < x2-3; x += 4, p+= 4) - { - bad = 0; - for (z = 3, dax = x+3; z >= 0; --z, --dax) - { - y1ve[z] = uwal[dax]; - y2ve[z] = dwal[dax]; - if (y2ve[z] <= y1ve[z]) { bad += 1<> FRACBITS); - iscale = swal[dax] * yrepeat; - vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 0.5)); - } - if (bad == 15) - { - light += rw_lightstep * 4; - continue; - } - - if (!fixed) - { - for (z = 0; z < 4; ++z) - { - light += rw_lightstep; - palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - } - - u4 = MAX(MAX(y1ve[0],y1ve[1]),MAX(y1ve[2],y1ve[3])); - d4 = MIN(MIN(y2ve[0],y2ve[1]),MIN(y2ve[2],y2ve[3])); - - if ((bad != 0) || (u4 >= d4)) - { - for (z = 0; z < 4; ++z) - { - if (!(bad & 1)) - { - mvline1(vince[z],palookupoffse[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); - } - bad >>= 1; - } - continue; - } - - for (z = 0; z < 4; ++z) - { - if (u4 > y1ve[z]) - { - vplce[z] = mvline1(vince[z],palookupoffse[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); - } - } - - if (d4 > u4) - { - dc_count = d4-u4; - dc_dest = ylookup[u4]+p; - domvline4(); - } - - BYTE *i = p+ylookup[d4]; - for (z = 0; z < 4; ++z) - { - if (y2ve[z] > d4) - { - mvline1(vince[z],palookupoffse[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); - } - } - } - for(; x < x2; ++x, ++p) - { - light += rw_lightstep; - y1ve[0] = uwal[x]; - y2ve[0] = dwal[x]; - if (y2ve[0] <= y1ve[0]) continue; - - if (!fixed) - { // calculate lighting - dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - - dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); - dc_dest = ylookup[y1ve[0]] + p; - dc_count = y2ve[0] - y1ve[0]; - iscale = swal[x] * yrepeat; - dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); - - domvline1(); - } - -//unclock(WallScanCycles); - - NetUpdate (); -} - -inline void preptmvline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, BYTE *dest) -{ - dc_iscale = vince; - dc_colormap = colormap; - dc_count = count; - dc_texturefrac = vplce; - dc_source = bufplce; - dc_dest = dest; -} - -void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, - double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) -{ - fixed_t (*tmvline1)(); - void (*tmvline4)(); - int x, fracbits; - BYTE *p; - int y1ve[4], y2ve[4], u4, d4, startx, dax, z; - char bad; - float light = rw_light - rw_lightstep; - SDWORD xoffset; - BYTE *basecolormapdata; - double iscale; - - if (rw_pic->UseType == FTexture::TEX_Null) - { - return; - } - - if (!R_GetTransMaskDrawers (&tmvline1, &tmvline4)) - { - // The current translucency is unsupported, so draw with regular maskwallscan instead. - maskwallscan (x1, x2, uwal, dwal, swal, lwal, yrepeat, getcol); - return; - } - -//extern cycle_t WallScanCycles; -//clock (WallScanCycles); - - rw_pic->GetHeight(); // Make sure texture size is loaded - fracbits = 32 - rw_pic->HeightBits; - if (fracbits == 32) - { // Hack for one pixel tall textures - fracbits = 0; - yrepeat = 0; - dc_texturemid = 0; - } - setuptmvline(fracbits); - xoffset = rw_offset; - basecolormapdata = basecolormap->Maps; - fixed_t centeryfrac = FLOAT2FIXED(CenterY); - - x = startx = x1; - p = x + dc_destorg; - - bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); - if (fixed) - { - palookupoffse[0] = dc_colormap; - palookupoffse[1] = dc_colormap; - palookupoffse[2] = dc_colormap; - palookupoffse[3] = dc_colormap; - } - - for(; (x < x2) && ((size_t)p & 3); ++x, ++p) - { - light += rw_lightstep; - y1ve[0] = uwal[x];//max(uwal[x],umost[x]); - y2ve[0] = dwal[x];//min(dwal[x],dmost[x]); - if (y2ve[0] <= y1ve[0]) continue; - - if (!fixed) - { // calculate lighting - dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - - dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); - dc_dest = ylookup[y1ve[0]] + p; - dc_count = y2ve[0] - y1ve[0]; - iscale = swal[x] * yrepeat; - dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); - - tmvline1(); - } - - for(; x < x2-3; x += 4, p+= 4) - { - bad = 0; - for (z = 3, dax = x+3; z >= 0; --z, --dax) - { - y1ve[z] = uwal[dax]; - y2ve[z] = dwal[dax]; - if (y2ve[z] <= y1ve[z]) { bad += 1<> FRACBITS); - iscale = swal[dax] * yrepeat; - vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + vince[z] * (y1ve[z] - CenterY + 0.5)); - } - if (bad == 15) - { - light += rw_lightstep * 4; - continue; - } - - if (!fixed) - { - for (z = 0; z < 4; ++z) - { - light += rw_lightstep; - palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - } - - u4 = MAX(MAX(y1ve[0],y1ve[1]),MAX(y1ve[2],y1ve[3])); - d4 = MIN(MIN(y2ve[0],y2ve[1]),MIN(y2ve[2],y2ve[3])); - - if ((bad != 0) || (u4 >= d4)) - { - for (z = 0; z < 4; ++z) - { - if (!(bad & 1)) - { - preptmvline1(vince[z],palookupoffse[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); - tmvline1(); - } - bad >>= 1; - } - continue; - } - - for (z = 0; z < 4; ++z) - { - if (u4 > y1ve[z]) - { - preptmvline1(vince[z],palookupoffse[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); - vplce[z] = tmvline1(); - } - } - - if (d4 > u4) - { - dc_count = d4-u4; - dc_dest = ylookup[u4]+p; - tmvline4(); - } - - BYTE *i = p+ylookup[d4]; - for (z = 0; z < 4; ++z) - { - if (y2ve[z] > d4) - { - preptmvline1(vince[z],palookupoffse[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); - tmvline1(); - } - } - } - for(; x < x2; ++x, ++p) - { - light += rw_lightstep; - y1ve[0] = uwal[x]; - y2ve[0] = dwal[x]; - if (y2ve[0] <= y1ve[0]) continue; - - if (!fixed) - { // calculate lighting - dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); - } - - dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); - dc_dest = ylookup[y1ve[0]] + p; - dc_count = y2ve[0] - y1ve[0]; - iscale = swal[x] * yrepeat; - dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); - - tmvline1(); - } - -//unclock(WallScanCycles); - - NetUpdate (); -} - // // R_RenderSegLoop // Draws zero, one, or two textures for walls. From dd1f72bbf91f50a7a782f84da63b9242bedc887b Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 4 Nov 2016 23:27:04 -0400 Subject: [PATCH 07/11] - Check the version of FMOD in CMake to produce an error on the condition that OpenAL is also enabled and the FMOD version is low enough to also export Xiph symbols. --- src/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 09e220143..576da3647 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -282,6 +282,19 @@ if( NOT NO_FMOD ) if( EXISTS "${FMOD_INCLUDE_DIR}/fmod_common.h" ) set( FMOD_STUDIO YES ) + set( FMOD_VERSION_FILE "fmod_common.h" ) + else() + set( FMOD_STUDIO NO ) + set( FMOD_VERSION_FILE "fmod.h" ) + endif() + + file( STRINGS "${FMOD_INCLUDE_DIR}/${FMOD_VERSION_FILE}" FMOD_VERSION_LINE REGEX "^#define[ \t]+FMOD_VERSION[ \t]+0x[0-9]+$" ) + string( REGEX REPLACE "^#define[ \t]+FMOD_VERSION[ \t]+0x([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])$" "\\1.\\2.\\3" FMOD_VERSION "${FMOD_VERSION_LINE}" ) + message( STATUS "FMOD version: ${FMOD_VERSION}" ) + + # FMOD Ex didn't hide xiph symbols in the past (not applicable to Win32 since symbols are hidden by default there). + if( NOT WIN32 AND NOT FMOD_STUDIO AND NOT NO_OPENAL AND "${FMOD_VERSION}" VERSION_LESS "4.36.00") + message( SEND_ERROR "Use of FMOD Ex ${FMOD_VERSION} with OpenAL will result in crashes. Either update FMOD to 4.36 or later or set NO_OPENAL." ) endif() else() message( STATUS "Could not find FMOD include files" ) From ae28c9b29cdf3f88b6fc335f229aa9f4536df83c Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 5 Nov 2016 22:09:38 -0500 Subject: [PATCH 08/11] Fix divide by 0 in new wallscan functions with 1-pixel tall textures --- src/r_segs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index ae33332de..369722242 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1114,7 +1114,7 @@ WallscanSampler::WallscanSampler(int y1, float swal, double yrepeat, fixed_t xof // Draw a column with support for non-power-of-two ranges void wallscan_drawcol1(int x, int y1, int y2, WallscanSampler &sampler, DWORD(*draw1column)()) { - if (sampler.uv_max == 0) // power of two + if (sampler.uv_max == 0 || sampler.uv_step == 0) // power of two { int count = y2 - y1; @@ -1162,7 +1162,7 @@ void wallscan_drawcol1(int x, int y1, int y2, WallscanSampler &sampler, DWORD(*d // Draw four columns with support for non-power-of-two ranges void wallscan_drawcol4(int x, int y1, int y2, WallscanSampler *sampler, void(*draw4columns)()) { - if (sampler[0].uv_max == 0) // power of two, no wrap handling needed + if (sampler[0].uv_max == 0 || sampler[0].uv_step == 0) // power of two, no wrap handling needed { int count = y2 - y1; for (int i = 0; i < 4; i++) From dbc54fbca0d93b9b9f71f218ed3020c8a2057a9a Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 5 Nov 2016 22:29:02 -0500 Subject: [PATCH 09/11] Fix FillSimplePoly() for 1-pixel tall or wide textures --- src/v_draw.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index bef732894..d50bea6cc 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1348,10 +1348,26 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, R_SetupSpanBits(tex); R_SetSpanColormap(colormap != NULL ? &colormap->Maps[clamp(shade >> FRACBITS, 0, NUMCOLORMAPS-1) * 256] : identitymap); R_SetSpanSource(tex->GetPixels()); - scalex = double(1u << (32 - ds_xbits)) / scalex; - scaley = double(1u << (32 - ds_ybits)) / scaley; - ds_xstep = xs_RoundToInt(cosrot * scalex); - ds_ystep = xs_RoundToInt(sinrot * scaley); + if (ds_xbits != 0) + { + scalex = double(1u << (32 - ds_xbits)) / scalex; + ds_xstep = xs_RoundToInt(cosrot * scalex); + } + else + { // Texture is one pixel wide. + scalex = 0; + ds_xstep = 0; + } + if (ds_ybits != 0) + { + scaley = double(1u << (32 - ds_ybits)) / scaley; + ds_ystep = xs_RoundToInt(sinrot * scaley); + } + else + { // Texture is one pixel tall. + scaley = 0; + ds_ystep = 0; + } // Travel down the right edge and create an outline of that edge. pt1 = toppt; From 55ee78fc0b133c88b35bc8bde26ca2aa216032c5 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 5 Nov 2016 22:49:33 -0500 Subject: [PATCH 10/11] Add bottomclip parameter to FillSimplePoly() for the software implementation - Polygons will be clipped to bottomclip. If this is zero or below, they will be clipped to the bottom of the screen instead. This keeps the polygons from overwriting the status bar border for sofware 2D. The hardware version ignores it, since it always draws the status bar border every frame. --- src/am_map.cpp | 3 ++- src/v_draw.cpp | 17 +++++++++++------ src/v_video.h | 2 +- src/win32/fb_d3d9.cpp | 9 +++++++-- src/win32/win32iface.h | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 9292e81d9..d74927b68 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2046,7 +2046,8 @@ void AM_drawSubsectors() scale / scaley, rotation, colormap, - floorlight + floorlight, + f_y + f_h ); } } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index d50bea6cc..8483b9844 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1282,7 +1282,7 @@ void DCanvas::FinishSimplePolys() void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, - FDynamicColormap *colormap, int lightlevel) + FDynamicColormap *colormap, int lightlevel, int bottomclip) { #ifndef NO_SWRENDER // Use an equation similar to player sprites to determine shade @@ -1300,6 +1300,11 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, return; } + if (bottomclip <= 0) + { + bottomclip = Height; + } + // Find the extents of the polygon, in particular the highest and lowest points. for (botpt = toppt = 0, boty = topy = points[0].Y, leftx = rightx = points[0].X, i = 1; i <= npoints; ++i) { @@ -1322,7 +1327,7 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, rightx = points[i].X; } } - if (topy >= Height || // off the bottom of the screen + if (topy >= bottomclip || // off the bottom of the screen boty <= 0 || // off the top of the screen leftx >= Width || // off the right of the screen rightx <= 0) // off the left of the screen @@ -1377,13 +1382,13 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, { x = FLOAT2FIXED(points[pt1].X + 0.5f); y2 = xs_RoundToInt(points[pt2].Y + 0.5f); - if (y1 >= y2 || (y1 < 0 && y2 < 0) || (y1 >= Height && y2 >= Height)) + if (y1 >= y2 || (y1 < 0 && y2 < 0) || (y1 >= bottomclip && y2 >= bottomclip)) { } else { fixed_t xinc = FLOAT2FIXED((points[pt2].X - points[pt1].X) / (points[pt2].Y - points[pt1].Y)); - int y3 = MIN(y2, Height); + int y3 = MIN(y2, bottomclip); if (y1 < 0) { x += xinc * -y1; @@ -1408,13 +1413,13 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, { x = FLOAT2FIXED(points[pt1].X + 0.5f); y2 = xs_RoundToInt(points[pt2].Y + 0.5f); - if (y1 >= y2 || (y1 < 0 && y2 < 0) || (y1 >= Height && y2 >= Height)) + if (y1 >= y2 || (y1 < 0 && y2 < 0) || (y1 >= bottomclip && y2 >= bottomclip)) { } else { fixed_t xinc = FLOAT2FIXED((points[pt2].X - points[pt1].X) / (points[pt2].Y - points[pt1].Y)); - int y3 = MIN(y2, Height); + int y3 = MIN(y2, bottomclip); if (y1 < 0) { x += xinc * -y1; diff --git a/src/v_video.h b/src/v_video.h index d19a3b06e..890ab6d63 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -224,7 +224,7 @@ public: // Fill a simple polygon with a texture virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, - struct FDynamicColormap *colormap, int lightlevel); + struct FDynamicColormap *colormap, int lightlevel, int bottomclip); // Set an area to a specified color virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32 color); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 8bb680dbd..10ab11c72 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -3084,11 +3084,16 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo // // Here, "simple" means that a simple triangle fan can draw it. // +// Bottomclip is ignored by this implementation, since the hardware renderer +// will unconditionally draw the status bar border every frame on top of the +// polygons, so there's no need to waste time setting up a special scissor +// rectangle here and needlessly forcing separate batches. +// //========================================================================== void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel) + DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip) { // Use an equation similar to player sprites to determine shade double fadelevel = clamp((LIGHT2SHADE(lightlevel)/65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); @@ -3109,7 +3114,7 @@ void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, } if (In2D < 2) { - Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel); + Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel, bottomclip); return; } if (!InScene) diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 9b2754eae..b5262089b 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -265,7 +265,7 @@ public: void DrawPixel(int x, int y, int palcolor, uint32 rgbcolor); void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel); + DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip) override; bool WipeStartScreen(int type); void WipeEndScreen(); bool WipeDo(int ticks); From 640bf2a6d4f878a0262bfa28e77d5b003311d834 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 6 Nov 2016 17:07:44 -0500 Subject: [PATCH 11/11] - Fixed: SBarInfo didn't support animated images in some places. --- src/g_shared/sbarinfo_commands.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index d105ab818..b3aecb0b5 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -241,7 +241,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl applyscale = false; } if(type == PLAYERICON) - texture = TexMan[statusBar->CPlayer->mo->ScoreIcon]; + texture = TexMan(statusBar->CPlayer->mo->ScoreIcon); else if(type == AMMO1) { AAmmo *ammo = statusBar->ammo1; @@ -270,7 +270,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl { AInventory *item = statusBar->CPlayer->mo->FindInventory(); if (item != NULL) - texture = TexMan[item->Icon]; + texture = TexMan(item->Icon); } else if(type == HEXENARMOR_ARMOR || type == HEXENARMOR_SHIELD || type == HEXENARMOR_HELM || type == HEXENARMOR_AMULET) { @@ -290,7 +290,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl } } else if(type == INVENTORYICON) - texture = TexMan[sprite]; + texture = TexMan(sprite); else if(type == SELECTEDINVENTORYICON && statusBar->CPlayer->mo->InvSel != NULL) texture = TexMan(statusBar->CPlayer->mo->InvSel->Icon); else if(image >= 0) @@ -312,7 +312,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl spawnScaleY = item->Scale.Y; } - texture = TexMan[icon]; + texture = TexMan(icon); } enum ImageType @@ -2436,22 +2436,22 @@ class CommandDrawKeyBar : public SBarInfoCommand { if(!vertical) { - statusBar->DrawGraphic(TexMan[item->Icon], x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan[item->Icon]->GetScaledHeight()+2 : rowIconSize; + statusBar->DrawGraphic(TexMan(item->Icon), x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); + rowWidth = rowIconSize == -1 ? TexMan(item->Icon)->GetScaledHeight()+2 : rowIconSize; } else { - statusBar->DrawGraphic(TexMan[item->Icon], x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan[item->Icon]->GetScaledWidth()+2 : rowIconSize; + statusBar->DrawGraphic(TexMan(item->Icon), x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); + rowWidth = rowIconSize == -1 ? TexMan(item->Icon)->GetScaledWidth()+2 : rowIconSize; } // If cmd.special is -1 then the slot size is auto detected if(iconSize == -1) { if(!vertical) - slotOffset += (reverse ? -1 : 1) * (TexMan[item->Icon]->GetScaledWidth() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan(item->Icon)->GetScaledWidth() + 2); else - slotOffset += (reverse ? -1 : 1) * (TexMan[item->Icon]->GetScaledHeight() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan(item->Icon)->GetScaledHeight() + 2); } else slotOffset += (reverse ? -iconSize : iconSize);