diff --git a/src/r_draw_pal.cpp b/src/r_draw_pal.cpp index 90dcc9c3b..fbe372fb8 100644 --- a/src/r_draw_pal.cpp +++ b/src/r_draw_pal.cpp @@ -3445,4 +3445,85 @@ namespace swrenderer dest[x] = colormap[dest[x]]; } while (++x <= x2); } + + ///////////////////////////////////////////////////////////////////////////// + + namespace + { + static uint32_t particle_texture[16 * 16] = + { + 1 * 1, 2 * 1, 3 * 1, 4 * 1, 5 * 1, 6 * 1, 7 * 1, 8 * 1, 8 * 1, 7 * 1, 6 * 1, 5 * 1, 4 * 1, 3 * 1, 2 * 1, 1 * 1, + 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 8 * 2, 7 * 2, 6 * 2, 5 * 2, 4 * 2, 3 * 2, 2 * 2, 1 * 2, + 1 * 3, 2 * 3, 3 * 3, 4 * 3, 5 * 3, 6 * 3, 7 * 3, 8 * 3, 8 * 3, 7 * 3, 6 * 3, 5 * 3, 4 * 3, 3 * 3, 2 * 3, 1 * 3, + 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, 7 * 4, 8 * 4, 8 * 4, 7 * 4, 6 * 4, 5 * 4, 4 * 4, 3 * 4, 2 * 4, 1 * 4, + 1 * 5, 2 * 5, 3 * 5, 4 * 5, 5 * 5, 6 * 5, 7 * 5, 8 * 5, 8 * 5, 7 * 5, 6 * 5, 5 * 5, 4 * 5, 3 * 5, 2 * 5, 1 * 5, + 1 * 6, 2 * 6, 3 * 6, 4 * 6, 5 * 6, 6 * 6, 7 * 6, 8 * 6, 8 * 6, 7 * 6, 6 * 6, 5 * 6, 4 * 6, 3 * 6, 2 * 6, 1 * 6, + 1 * 7, 2 * 7, 3 * 7, 4 * 7, 5 * 7, 6 * 7, 7 * 7, 8 * 7, 8 * 7, 7 * 7, 6 * 7, 5 * 7, 4 * 7, 3 * 7, 2 * 7, 1 * 7, + 1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 8 * 8, 7 * 8, 6 * 8, 5 * 8, 4 * 8, 3 * 8, 2 * 8, 1 * 8, + 1 * 8, 2 * 8, 3 * 8, 4 * 8, 5 * 8, 6 * 8, 7 * 8, 8 * 8, 8 * 8, 7 * 8, 6 * 8, 5 * 8, 4 * 8, 3 * 8, 2 * 8, 1 * 8, + 1 * 7, 2 * 7, 3 * 7, 4 * 7, 5 * 7, 6 * 7, 7 * 7, 8 * 7, 8 * 7, 7 * 7, 6 * 7, 5 * 7, 4 * 7, 3 * 7, 2 * 7, 1 * 7, + 1 * 6, 2 * 6, 3 * 6, 4 * 6, 5 * 6, 6 * 6, 7 * 6, 8 * 6, 8 * 6, 7 * 6, 6 * 6, 5 * 6, 4 * 6, 3 * 6, 2 * 6, 1 * 6, + 1 * 5, 2 * 5, 3 * 5, 4 * 5, 5 * 5, 6 * 5, 7 * 5, 8 * 5, 8 * 5, 7 * 5, 6 * 5, 5 * 5, 4 * 5, 3 * 5, 2 * 5, 1 * 5, + 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, 7 * 4, 8 * 4, 8 * 4, 7 * 4, 6 * 4, 5 * 4, 4 * 4, 3 * 4, 2 * 4, 1 * 4, + 1 * 3, 2 * 3, 3 * 3, 4 * 3, 5 * 3, 6 * 3, 7 * 3, 8 * 3, 8 * 3, 7 * 3, 6 * 3, 5 * 3, 4 * 3, 3 * 3, 2 * 3, 1 * 3, + 1 * 2, 2 * 2, 3 * 2, 4 * 2, 5 * 2, 6 * 2, 7 * 2, 8 * 2, 8 * 2, 7 * 2, 6 * 2, 5 * 2, 4 * 2, 3 * 2, 2 * 2, 1 * 2, + 1 * 1, 2 * 1, 3 * 1, 4 * 1, 5 * 1, 6 * 1, 7 * 1, 8 * 1, 8 * 1, 7 * 1, 6 * 1, 5 * 1, 4 * 1, 3 * 1, 2 * 1, 1 * 1 + }; + } + + DrawParticleColumnPalCommand::DrawParticleColumnPalCommand(uint8_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx) + { + _dest = dest; + _pitch = pitch; + _count = count; + _fg = fg; + _alpha = alpha; + _fracposx = fracposx; + _dest_y = dest_y; + } + + void DrawParticleColumnPalCommand::Execute(DrawerThread *thread) + { + int count = thread->count_for_thread(_dest_y, _count); + if (count <= 0) + return; + + uint8_t *dest = thread->dest_for_thread(_dest_y, _pitch, _dest); + int pitch = _pitch * thread->num_cores; + + const uint32_t *source = &particle_texture[(_fracposx >> FRACBITS) * 16]; + uint32_t particle_alpha = _alpha; + + uint32_t fracstep = 16 * FRACUNIT / _count; + uint32_t fracpos = fracstep * thread->skipped_by_thread(_dest_y) + fracstep / 2; + fracstep *= thread->num_cores; + + uint32_t fg_red = (_fg >> 16) & 0xff; + uint32_t fg_green = (_fg >> 8) & 0xff; + uint32_t fg_blue = _fg & 0xff; + + for (int y = 0; y < count; y++) + { + uint32_t alpha = (source[fracpos >> FRACBITS] * particle_alpha) >> 6; + uint32_t inv_alpha = 256 - alpha; + + int bg = *dest; + uint32_t bg_red = GPalette.BaseColors[bg].r; + uint32_t bg_green = GPalette.BaseColors[bg].g; + uint32_t bg_blue = GPalette.BaseColors[bg].b; + + uint32_t red = (fg_red * alpha + bg_red * inv_alpha) / 256; + uint32_t green = (fg_green * alpha + bg_green * inv_alpha) / 256; + uint32_t blue = (fg_blue * alpha + bg_blue * inv_alpha) / 256; + + *dest = RGB256k.All[((red >> 2) << 12) | ((green >> 2) << 6) | (blue >> 2)]; + dest += pitch; + fracpos += fracstep; + } + } + + FString DrawParticleColumnPalCommand::DebugInfo() + { + return "DrawParticle"; + } } diff --git a/src/r_draw_pal.h b/src/r_draw_pal.h index 5b901152c..79152665c 100644 --- a/src/r_draw_pal.h +++ b/src/r_draw_pal.h @@ -260,4 +260,20 @@ namespace swrenderer const uint8_t *_colormap; uint8_t *_destorg; }; + + class DrawParticleColumnPalCommand : public DrawerCommand + { + public: + DrawParticleColumnPalCommand(uint8_t *dest, int dest_y, int pitch, int count, uint32_t fg, uint32_t alpha, uint32_t fracposx); + void Execute(DrawerThread *thread) override; + FString DebugInfo() override; + + private: + uint8_t *_dest; + int _pitch; + int _count; + uint32_t _fg; + uint32_t _alpha; + uint32_t _fracposx; + }; } diff --git a/src/r_things.cpp b/src/r_things.cpp index 40fbf782a..b7883a242 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -59,6 +59,7 @@ #include "r_segs.h" #include "r_3dfloors.h" #include "r_draw_rgba.h" +#include "r_draw_pal.h" #include "v_palette.h" #include "r_data/r_translate.h" #include "r_data/colormaps.h" @@ -2712,105 +2713,9 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis) } } -//inline int clamp(int x, int y, int z) { return ((x < y) ? x : (z < y) ? z : y); } - -void R_DrawParticle (vissprite_t *vis) -{ - if (r_swtruecolor) - return R_DrawParticle_rgba(vis); - - DWORD *bg2rgb; - int spacing; - BYTE *dest; - DWORD fg; - BYTE color = vis->Style.BaseColormap->Maps[(vis->Style.ColormapNum << COLORMAPSHIFT) + vis->startfrac]; - int yl = vis->y1; - int ycount = vis->y2 - yl + 1; - int x1 = vis->x1; - int countbase = vis->x2 - x1; - - R_DrawMaskedSegsBehindParticle (vis); - - DrawerCommandQueue::WaitForWorkers(); - - // vis->renderflags holds translucency level (0-255) - fixed_t fglevel, bglevel; - - { - DWORD *fg2rgb; - - fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff; - bglevel = FRACUNIT-fglevel; - fg2rgb = Col2RGB8[fglevel>>10]; - bg2rgb = Col2RGB8[bglevel>>10]; - fg = fg2rgb[color]; - } - - /* - - spacing = RenderTarget->GetPitch() - countbase; - dest = ylookup[yl] + x1 + dc_destorg; - - do - { - int count = countbase; - do - { - DWORD bg = bg2rgb[*dest]; - bg = (fg+bg) | 0x1f07c1f; - *dest++ = RGB32k.All[bg & (bg>>15)]; - } while (--count); - dest += spacing; - } while (--ycount);*/ - - // original was row-wise - // width = countbase - // height = ycount - - spacing = RenderTarget->GetPitch(); - - if (!r_blendmethod) - { - for (int x = x1; x < (x1+countbase); x++) - { - dc_x = x; - if (R_ClipSpriteColumnWithPortals(vis)) - continue; - dest = ylookup[yl] + x + dc_destorg; - for (int y = 0; y < ycount; y++) - { - DWORD bg = bg2rgb[*dest]; - bg = (fg+bg) | 0x1f07c1f; - *dest = RGB32k.All[bg & (bg>>15)]; - dest += spacing; - } - } - } - else - { - for (int x = x1; x < (x1+countbase); x++) - { - dc_x = x; - if (R_ClipSpriteColumnWithPortals(vis)) - continue; - dest = ylookup[yl] + x + dc_destorg; - for (int y = 0; y < ycount; y++) - { - uint32_t dest_r = MIN((GPalette.BaseColors[*dest].r * bglevel + GPalette.BaseColors[color].r * fglevel) >> 18, 63); - uint32_t dest_g = MIN((GPalette.BaseColors[*dest].g * bglevel + GPalette.BaseColors[color].g * fglevel) >> 18, 63); - uint32_t dest_b = MIN((GPalette.BaseColors[*dest].b * bglevel + GPalette.BaseColors[color].b * fglevel) >> 18, 63); - - *dest = RGB256k.RGB[dest_r][dest_g][dest_b]; - dest += spacing; - } - } - } -} - -void R_DrawParticle_rgba(vissprite_t *vis) +void R_DrawParticle(vissprite_t *vis) { int spacing; - uint32_t *dest; BYTE color = vis->Style.BaseColormap->Maps[vis->startfrac]; int yl = vis->y1; int ycount = vis->y2 - yl + 1; @@ -2833,13 +2738,27 @@ void R_DrawParticle_rgba(vissprite_t *vis) uint32_t fracstepx = 16 * FRACUNIT / countbase; uint32_t fracposx = fracstepx / 2; - for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) + if (r_swtruecolor) { - dc_x = x; - if (R_ClipSpriteColumnWithPortals(vis)) - continue; - dest = ylookup[yl] + x + (uint32_t*)dc_destorg; - DrawerCommandQueue::QueueCommand(dest, yl, spacing, ycount, fg, alpha, fracposx); + for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) + { + dc_x = x; + if (R_ClipSpriteColumnWithPortals(vis)) + continue; + uint32_t *dest = ylookup[yl] + x + (uint32_t*)dc_destorg; + DrawerCommandQueue::QueueCommand(dest, yl, spacing, ycount, fg, alpha, fracposx); + } + } + else + { + for (int x = x1; x < (x1 + countbase); x++, fracposx += fracstepx) + { + dc_x = x; + if (R_ClipSpriteColumnWithPortals(vis)) + continue; + uint8_t *dest = ylookup[yl] + x + dc_destorg; + DrawerCommandQueue::QueueCommand(dest, yl, spacing, ycount, fg, alpha, fracposx); + } } } diff --git a/src/r_things.h b/src/r_things.h index 2fa8786a9..7f00ce177 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -101,7 +101,6 @@ struct vissprite_t }; void R_DrawParticle (vissprite_t *); -void R_DrawParticle_rgba (vissprite_t *); void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside);