diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h index f4c7ec11e7..5c37873c85 100644 --- a/src/swrenderer/drawers/r_draw.h +++ b/src/swrenderer/drawers/r_draw.h @@ -71,6 +71,7 @@ namespace swrenderer virtual void DrawTranslatedColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawShadedColumn(const SpriteDrawerArgs &args) = 0; + virtual void DrawAddClampShadedColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawAddClampColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawSubClampColumn(const SpriteDrawerArgs &args) = 0; diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index 5bfcf8d77c..07f3138a92 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -1412,6 +1412,48 @@ namespace swrenderer } } + void DrawColumnAddClampShadedPalCommand::Execute(DrawerThread *thread) + { + int count; + uint8_t *dest; + fixed_t frac, fracstep; + + count = args.Count(); + dest = args.Dest(); + + fracstep = args.TextureVStep(); + frac = args.TextureVPos(); + + count = thread->count_for_thread(args.DestY(), count); + if (count <= 0) + return; + + int pitch = args.Viewport()->RenderTarget->GetPitch(); + dest = thread->dest_for_thread(args.DestY(), pitch, dest); + frac += fracstep * thread->skipped_by_thread(args.DestY()); + fracstep *= thread->num_cores; + pitch *= thread->num_cores; + + const uint8_t *source = args.TexturePixels(); + const uint8_t *colormap = args.Colormap(args.Viewport()); + //uint32_t *fgstart = &Col2RGB8[0][args.SolidColor()]; // if someone wants to write the 555's, be my guest. + const PalEntry *palette = GPalette.BaseColors; + + int color = args.SolidColor(); + do + { + uint32_t val = source[frac >> FRACBITS]; + + int r = (palette[*dest].r * (255) + palette[color].r * val) >> 10; + int g = (palette[*dest].g * (255) + palette[color].g * val) >> 10; + int b = (palette[*dest].b * (255) + palette[color].b * val) >> 10; + *dest = RGB256k.RGB[clamp(r,0,63)][clamp(g,0,63)][clamp(b,0,63)]; + + dest += pitch; + frac += fracstep; + } while (--count); + } + void DrawColumnAddClampPalCommand::Execute(DrawerThread *thread) { int count; diff --git a/src/swrenderer/drawers/r_draw_pal.h b/src/swrenderer/drawers/r_draw_pal.h index cca11e9347..8d2a726c7e 100644 --- a/src/swrenderer/drawers/r_draw_pal.h +++ b/src/swrenderer/drawers/r_draw_pal.h @@ -65,6 +65,7 @@ namespace swrenderer class DrawColumnTranslatedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; class DrawColumnTlatedAddPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; class DrawColumnShadedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; + class DrawColumnAddClampShadedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; class DrawColumnAddClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; class DrawColumnAddClampTranslatedPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; class DrawColumnSubClampPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; @@ -236,6 +237,7 @@ namespace swrenderer void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawAddClampShadedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } diff --git a/src/swrenderer/drawers/r_draw_rgba.cpp b/src/swrenderer/drawers/r_draw_rgba.cpp index daf4fba7f3..8778414e63 100644 --- a/src/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/swrenderer/drawers/r_draw_rgba.cpp @@ -156,6 +156,11 @@ namespace swrenderer Queue->Push(args); } + void SWTruecolorDrawers::DrawAddClampShadedColumn(const SpriteDrawerArgs &args) + { + Queue->Push(args); + } + void SWTruecolorDrawers::DrawAddClampColumn(const SpriteDrawerArgs &args) { Queue->Push(args); diff --git a/src/swrenderer/drawers/r_draw_rgba.h b/src/swrenderer/drawers/r_draw_rgba.h index 67768fb3b9..b7bb610c4d 100644 --- a/src/swrenderer/drawers/r_draw_rgba.h +++ b/src/swrenderer/drawers/r_draw_rgba.h @@ -243,6 +243,7 @@ namespace swrenderer void DrawTranslatedColumn(const SpriteDrawerArgs &args) override; void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override; void DrawShadedColumn(const SpriteDrawerArgs &args) override; + void DrawAddClampShadedColumn(const SpriteDrawerArgs &args) override; void DrawAddClampColumn(const SpriteDrawerArgs &args) override; void DrawAddClampTranslatedColumn(const SpriteDrawerArgs &args) override; void DrawSubClampColumn(const SpriteDrawerArgs &args) override; diff --git a/src/swrenderer/drawers/r_draw_sprite32_sse2.h b/src/swrenderer/drawers/r_draw_sprite32_sse2.h index 3f10a86f83..90a221ea6e 100644 --- a/src/swrenderer/drawers/r_draw_sprite32_sse2.h +++ b/src/swrenderer/drawers/r_draw_sprite32_sse2.h @@ -29,10 +29,11 @@ namespace swrenderer { namespace DrawSprite32TModes { - enum class SpriteBlendModes { Copy, Opaque, Shaded, AddClamp, SubClamp, RevSubClamp }; + enum class SpriteBlendModes { Copy, Opaque, Shaded, AddClampShaded, AddClamp, SubClamp, RevSubClamp }; struct CopySprite { static const int Mode = (int)SpriteBlendModes::Copy; }; struct OpaqueSprite { static const int Mode = (int)SpriteBlendModes::Opaque; }; struct ShadedSprite { static const int Mode = (int)SpriteBlendModes::Shaded; }; + struct AddClampShadedSprite { static const int Mode = (int)SpriteBlendModes::AddClampShaded; }; struct AddClampSprite { static const int Mode = (int)SpriteBlendModes::AddClamp; }; struct SubClampSprite { static const int Mode = (int)SpriteBlendModes::SubClamp; }; struct RevSubClampSprite { static const int Mode = (int)SpriteBlendModes::RevSubClamp; }; @@ -381,6 +382,16 @@ namespace swrenderer outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); return outcolor; } + else if (BlendT::Mode == (int)SpriteBlendModes::AddClampShaded) + { + __m128i alpha = _mm_set_epi16(ifgshade1, ifgshade1, ifgshade1, ifgshade1, ifgshade0, ifgshade0, ifgshade0, ifgshade0); + + fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, alpha), 8); + __m128i outcolor = _mm_add_epi16(fgcolor, bgcolor); + outcolor = _mm_packus_epi16(outcolor, _mm_setzero_si128()); + outcolor = _mm_or_si128(outcolor, _mm_set1_epi32(0xff000000)); + return outcolor; + } else { uint32_t alpha0 = APART(ifgcolor0); @@ -448,6 +459,7 @@ namespace swrenderer typedef DrawSprite32T FillSpriteRevSubClamp32Command; typedef DrawSprite32T DrawSpriteShaded32Command; + typedef DrawSprite32T DrawSpriteAddClampShaded32Command; typedef DrawSprite32T DrawSpriteTranslated32Command; typedef DrawSprite32T DrawSpriteTranslatedAddClamp32Command; diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index 67f203a3c2..116a5037bb 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -432,12 +432,15 @@ namespace swrenderer colfunc = &SWPixelFormatDrawers::DrawFuzzColumn; return true; } - else if (style == LegacyRenderStyles[STYLE_Shaded]) + else if (style == LegacyRenderStyles[STYLE_Shaded] || style == LegacyRenderStyles[STYLE_AddShaded]) { // Shaded drawer only gets 16 levels of alpha because it saves memory. if ((alpha >>= 12) == 0 || basecolormap == nullptr) return false; - colfunc = &SWPixelFormatDrawers::DrawShadedColumn; + if (style == LegacyRenderStyles[STYLE_Shaded]) + colfunc = &SWPixelFormatDrawers::DrawShadedColumn; + else + colfunc = &SWPixelFormatDrawers::DrawAddClampShadedColumn; drawer_needs_pal_input = true; CameraLight *cameraLight = CameraLight::Instance(); dc_color = cameraLight->FixedColormap() ? cameraLight->FixedColormap()->Maps[APART(color)] : basecolormap->Maps[APART(color)];