diff --git a/src/c_console.cpp b/src/c_console.cpp index 12d76adba..8da82d852 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1294,7 +1294,6 @@ void C_FullConsole () primaryLevel->Music = ""; S_Start (); P_FreeLevelData (); - V_SetBlend (0,0,0,0); } else { diff --git a/src/d_main.cpp b/src/d_main.cpp index 365b54938..ebb17e3d6 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1247,7 +1247,6 @@ void D_DoAdvanceDemo (void) return; } - V_SetBlend (0,0,0,0); players[consoleplayer].playerstate = PST_LIVE; // not reborn usergame = false; // no save / end game here paused = 0; @@ -2698,8 +2697,6 @@ void D_DoomMain (void) } else { - // let the renderer reinitialize some stuff if needed - screen->InitPalette(); // These calls from inside V_Init2 are still necessary C_NewModeAdjust(); D_StartTitle (); // start up intro loop diff --git a/src/g_game.cpp b/src/g_game.cpp index dd5e73e75..a3375b5ca 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2100,6 +2100,56 @@ static void PutSaveComment (FSerializer &arc) arc.AddString("Comment", comment); } +void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown) +{ + PalEntry palette[256]; + PalEntry modulateColor; + auto blend = screen->CalcBlend(viewsector, &modulateColor); + int pixelsize = 1; + // Apply the screen blend, because the renderer does not provide this. + if (ssformat == SS_RGB) + { + int numbytes = width * height * 3; + pixelsize = 3; + if (modulateColor != 0xffffffff) + { + float r = modulateColor.r / 255.f; + float g = modulateColor.g / 255.f; + float b = modulateColor.b / 255.f; + for (int i = 0; i < numbytes; i += 3) + { + scr[i] = uint8_t(scr[i] * r); + scr[i + 1] = uint8_t(scr[i + 1] * g); + scr[i + 2] = uint8_t(scr[i + 2] * b); + } + } + float iblendfac = 1.f - blend.W; + blend.X *= blend.W; + blend.Y *= blend.W; + blend.Z *= blend.W; + for (int i = 0; i < numbytes; i += 3) + { + scr[i] = uint8_t(scr[i] * iblendfac + blend.X); + scr[i + 1] = uint8_t(scr[i + 1] * iblendfac + blend.Y); + scr[i + 2] = uint8_t(scr[i + 2] * iblendfac + blend.Z); + } + } + else + { + // Apply the screen blend to the palette. The colormap related parts get skipped here because these are already part of the image. + DoBlending(GPalette.BaseColors, palette, 256, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z), uint8_t(blend.W*255)); + } + + int pitch = width * pixelsize; + if (upsidedown) + { + scr += ((height - 1) * width * pixelsize); + pitch *= -1; + } + + M_CreatePNG(file, scr, ssformat == SS_PAL? palette : nullptr, ssformat, width, height, pitch, Gamma); +} + static void PutSavePic (FileWriter *file, int width, int height) { if (width <= 0 || height <= 0 || !storesavepic) diff --git a/src/gamedata/textures/image.cpp b/src/gamedata/textures/image.cpp index f047b8137..bbc621627 100644 --- a/src/gamedata/textures/image.cpp +++ b/src/gamedata/textures/image.cpp @@ -173,7 +173,7 @@ TArray FImageSource::GetPalettedPixels(int conversion) int FImageSource::CopyPixels(FBitmap *bmp, int conversion) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. - PalEntry *palette = screen->GetPalette(); + PalEntry *palette = GPalette.BaseColors; for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values auto ppix = CreatePalettedPixels(conversion); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 9affb04ad..f1dd8b9a0 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -211,7 +211,6 @@ int DIntermissionScreenFader::Responder (event_t *ev) { if (ev->type == EV_KeyDown) { - V_SetBlend(0,0,0,0); return -1; } return Super::Responder(ev); @@ -852,7 +851,6 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t s { DIntermissionController::CurrentIntermission->Destroy(); } - V_SetBlend (0,0,0,0); S_StopAllChannels (); gameaction = ga_nothing; gamestate = GS_FINALE; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 2bf798b13..4b3438bc4 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -612,12 +612,6 @@ void M_ScreenShot (const char *filename) auto buffer = screen->GetScreenshotBuffer(pitch, color_type, gamma); if (buffer.Size() > 0) { - PalEntry palette[256]; - - if (color_type == SS_PAL) - { - screen->GetFlashedPalette(palette); - } file = FileWriter::Open(autoname); if (file == NULL) { @@ -626,12 +620,12 @@ void M_ScreenShot (const char *filename) } if (writepcx) { - WritePCXfile(file, buffer.Data(), palette, color_type, + WritePCXfile(file, buffer.Data(), nullptr, color_type, screen->GetWidth(), screen->GetHeight(), pitch); } else { - WritePNGfile(file, buffer.Data(), palette, color_type, + WritePNGfile(file, buffer.Data(), nullptr, color_type, screen->GetWidth(), screen->GetHeight(), pitch, gamma); } delete file; diff --git a/src/rendering/gl/renderer/gl_renderer.cpp b/src/rendering/gl/renderer/gl_renderer.cpp index 38a0ad604..662365724 100644 --- a/src/rendering/gl/renderer/gl_renderer.cpp +++ b/src/rendering/gl/renderer/gl_renderer.cpp @@ -67,6 +67,8 @@ EXTERN_CVAR(Bool, cl_capfps) extern bool NoInterpolateView; +void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown); + namespace OpenGLRenderer { @@ -370,9 +372,11 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i // strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers glFinish(); - uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3); + int numpixels = width * height; + uint8_t * scr = (uint8_t *)M_Malloc(numpixels * 3); glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr); - M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma); + + DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, true); M_Free(scr); // Switch back the screen render buffers diff --git a/src/rendering/swrenderer/r_swrenderer.cpp b/src/rendering/swrenderer/r_swrenderer.cpp index a2863ec71..cf153551f 100644 --- a/src/rendering/swrenderer/r_swrenderer.cpp +++ b/src/rendering/swrenderer/r_swrenderer.cpp @@ -208,10 +208,11 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide }); } +void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown); + void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) { DCanvas pic(width, height, false); - PalEntry palette[256]; // Take a snapshot of the player's view if (V_IsPolyRenderer()) @@ -230,11 +231,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi r_viewpoint = mScene.MainThread()->Viewport->viewpoint; r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } - auto blend = screen->CalcBlend(r_viewpoint.sector, nullptr); - const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z)); - screen->SetFlash(bcolor, int(blend.W * 256)); - screen->GetFlashedPalette (palette); - M_CreatePNG (file, pic.GetPixels(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma); + DoWriteSavePic(file, SS_PAL, pic.GetPixels(), width, height, r_viewpoint.sector, false); } void FSoftwareRenderer::DrawRemainingPlayerSprites() diff --git a/src/v_framebuffer.cpp b/src/v_framebuffer.cpp index 26a86623a..c026133c0 100644 --- a/src/v_framebuffer.cpp +++ b/src/v_framebuffer.cpp @@ -202,11 +202,6 @@ void DFrameBuffer::DrawRateStuff () // //========================================================================== -void DFrameBuffer::GetFlashedPalette(PalEntry pal[256]) -{ - DoBlending(SourcePalette, pal, 256, Flash.r, Flash.g, Flash.b, Flash.a); -} - void DFrameBuffer::Update() { CheckBench(); @@ -225,24 +220,6 @@ void DFrameBuffer::Update() } } -PalEntry *DFrameBuffer::GetPalette() -{ - return SourcePalette; -} - -bool DFrameBuffer::SetFlash(PalEntry rgb, int amount) -{ - Flash = PalEntry(amount, rgb.r, rgb.g, rgb.b); - return true; -} - -void DFrameBuffer::GetFlash(PalEntry &rgb, int &amount) -{ - rgb = Flash; - rgb.a = 0; - amount = Flash.a; -} - void DFrameBuffer::SetClearColor(int color) { PalEntry pe = GPalette.BaseColors[color]; @@ -293,18 +270,6 @@ FTexture *DFrameBuffer::WipeEndScreen() return nullptr; } -//========================================================================== -// -// DFrameBuffer :: InitPalette -// -//========================================================================== - -void DFrameBuffer::InitPalette() -{ - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256); - UpdatePalette(); -} - //========================================================================== // // DFrameBuffer :: GetCaps diff --git a/src/v_palette.cpp b/src/v_palette.cpp index e598fa290..0c3427cd3 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -443,29 +443,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in } } -void V_SetBlend (int blendr, int blendg, int blendb, int blenda) -{ - // Don't do anything if the new blend is the same as the old - if (((blenda|BlendA) == 0) || - (blendr == BlendR && - blendg == BlendG && - blendb == BlendB && - blenda == BlendA)) - return; - - V_ForceBlend (blendr, blendg, blendb, blenda); -} - -void V_ForceBlend (int blendr, int blendg, int blendb, int blenda) -{ - BlendR = blendr; - BlendG = blendg; - BlendB = blendb; - BlendA = blenda; - - screen->SetFlash (PalEntry (BlendR, BlendG, BlendB), BlendA); -} - CCMD (testblend) { FString colorstring; diff --git a/src/v_palette.h b/src/v_palette.h index a9a7e476b..703891656 100644 --- a/src/v_palette.h +++ b/src/v_palette.h @@ -77,23 +77,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in void ReadPalette(int lumpnum, uint8_t *buffer); void InitPalette (); -// V_SetBlend() -// input: blendr: red component of blend -// blendg: green component of blend -// blendb: blue component of blend -// blenda: alpha component of blend -// -// Applies the blend to all palettes with PALETTEF_BLEND flag -void V_SetBlend (int blendr, int blendg, int blendb, int blenda); - -// V_ForceBlend() -// -// Normally, V_SetBlend() does nothing if the new blend is the -// same as the old. This function will perform the blending -// even if the blend hasn't changed. -void V_ForceBlend (int blendr, int blendg, int blendb, int blenda); - - EXTERN_CVAR (Int, paletteflash) enum PaletteFlashFlags { diff --git a/src/v_video.cpp b/src/v_video.cpp index d82d18eb9..9d091a51e 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -696,9 +696,6 @@ void V_Init (bool restart) // Update screen palette when restarting else { - PalEntry *palette = screen->GetPalette (); - for (int i = 0; i < 256; ++i) - *palette++ = GPalette.BaseColors[i]; screen->UpdatePalette(); } diff --git a/src/v_video.h b/src/v_video.h index d4fedf17c..826532853 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -352,9 +352,6 @@ private: protected: int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; - PalEntry Flash = 0; // Only needed to support some cruft in the interface that only makes sense for the software renderer - PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from - public: // Hardware render state that needs to be exposed to the API independent part of the renderer. For ease of access this is stored in the base class. int hwcaps = 0; // Capability flags @@ -404,26 +401,12 @@ public: // Make the surface visible. virtual void Update (); - // Return a pointer to 256 palette entries that can be written to. - PalEntry *GetPalette (); - // Stores the palette with flash blended in into 256 dwords - void GetFlashedPalette (PalEntry palette[256]); - // Mark the palette as changed. It will be updated on the next Update(). virtual void UpdatePalette() {} virtual void SetGamma() {} - // Sets a color flash. RGB is the color, and amount is 0-256, with 256 - // being all flash and 0 being no flash. Returns false if the hardware - // does not support this. (Always true for now, since palettes can always - // be flashed.) - bool SetFlash (PalEntry rgb, int amount); - - // Converse of SetFlash - void GetFlash (PalEntry &rgb, int &amount); - // Returns true if running fullscreen. virtual bool IsFullscreen () = 0; virtual void ToggleFullscreen(bool yes) {} @@ -475,7 +458,6 @@ public: } // Report a game restart - void InitPalette(); void SetClearColor(int color); virtual uint32_t GetCaps(); virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 1849d471c..dedda4602 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -761,7 +761,6 @@ void WI_Start(wbstartstruct_t *wbstartstruct) } } - V_SetBlend(0, 0, 0, 0); S_StopAllChannels(); for (auto Level : AllLevels()) {