diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5ded5254d..0e5eee406 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,8 @@ April 14, 2008 (Changes by Graf Zahl) +- Added rotation 90° angles only) and mirroring to the Multipatch texture + composition code. +- Fixed: The game crashed when a level was ended while a player was morphed + by a powerup. - Fixed: A_VileAttack positioned the fire on the wrong side of the target. - Reorganized the HackHack code so that the image creation was moved into MakeTexture. This was necessary because Unload deleted the pixel data @@ -19,7 +23,7 @@ April 14, 2008 (Changes by Graf Zahl) - Fixed: A few calls to P_SpawnPlayerMissile passed 0 as angle April 13, 2008 (Changes by Graf Zahl) -- Fixed a few bufs in the parser for composite textures. +- Fixed a few bugs in the parser for composite textures. - Changed: When loading Zips all patches in the patches/ directory should be loaded, not only those used by a texture in TEXTUREx. - Disabled timidity_mastervolume for the internal Timidity again because diff --git a/src/g_doom/doom_sbar.cpp b/src/g_doom/doom_sbar.cpp index fffe725b7..94ed7787e 100644 --- a/src/g_doom/doom_sbar.cpp +++ b/src/g_doom/doom_sbar.cpp @@ -211,7 +211,7 @@ private: void Unload (); ~FDoomStatusBarTexture (); void SetPlayerRemap(FRemapTable *remap); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); FTextureFormat GetFormat() { @@ -1093,10 +1093,11 @@ void DDoomStatusBar::FDoomStatusBarTexture::MakeTexture () if (multiplayer) DrawToBar("STFBANY", 143, 1, STBFremap? STBFremap->Remap : NULL); } -int DDoomStatusBar::FDoomStatusBarTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int DDoomStatusBar::FDoomStatusBarTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { FTexture *tex; + // rotate is never used here BaseTexture->CopyTrueColorPixels(buffer, buf_pitch, buf_height, x, y); if (!deathmatch) { diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 13d5edab4..348aafc9d 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -163,7 +163,13 @@ bool P_UndoPlayerMorph (player_t *player, bool force) angle_t angle; pmo = player->mo; - if (pmo->tracer == NULL) + // [MH] + // Checks pmo as well; the PowerMorph destroyer will + // try to unmorph the player; if the destroyer runs + // because the level or game is ended while morphed, + // by the time it gets executed the morphed player + // pawn instance may have already been destroyed. + if (pmo == NULL || pmo->tracer == NULL) { return false; } diff --git a/src/r_data.h b/src/r_data.h index b438d5601..cbc984735 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -94,7 +94,7 @@ public: void Unload (); virtual void SetFrontSkyLayer (); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); int GetSourceLump() { return DefinitionLump; } protected: @@ -105,9 +105,8 @@ protected: struct TexPart { SWORD OriginX, OriginY; - BYTE Mirror:2; - BYTE Rotate:2; - BYTE textureOwned:1; + BYTE Rotate; + bool textureOwned; FTexture *Texture; TexPart(); @@ -262,7 +261,7 @@ public: const BYTE *GetPixels (); void Unload (); FTextureFormat GetFormat (); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); bool UseBasePalette(); int GetSourceLump() { return SourceLump; } @@ -330,7 +329,7 @@ protected: void DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbuf = NULL); void DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbuf = NULL); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); bool UseBasePalette(); friend class FTexture; @@ -346,7 +345,7 @@ public: const BYTE *GetPixels (); void Unload (); FTextureFormat GetFormat (); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); bool UseBasePalette(); int GetSourceLump() { return SourceLump; } @@ -398,7 +397,7 @@ public: void Unload (); FTextureFormat GetFormat (); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); bool UseBasePalette(); int GetSourceLump() { return SourceLump; } @@ -455,7 +454,7 @@ public: void Unload (); FTextureFormat GetFormat (); - int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate); bool UseBasePalette(); int GetSourceLump() { return SourceLump; } diff --git a/src/r_defs.h b/src/r_defs.h index f8c744e11..d44d1b5ae 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -794,7 +794,7 @@ public: // Returns the whole texture, stored in column-major order virtual const BYTE *GetPixels () = 0; - virtual int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); + virtual int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate=0); int CopyTrueColorTranslated(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, FRemapTable *remap); virtual bool UseBasePalette(); virtual int GetSourceLump() { return -1; } @@ -824,7 +824,12 @@ public: virtual void SetFrontSkyLayer(); - void CopyToBlock (BYTE *dest, int dwidth, int dheight, int x, int y, const BYTE *translation=NULL); + void CopyToBlock (BYTE *dest, int dwidth, int dheight, int x, int y, const BYTE *translation=NULL) + { + CopyToBlock(dest, dwidth, dheight, x, y, 0, translation); + } + + void CopyToBlock (BYTE *dest, int dwidth, int dheight, int x, int y, int rotate, const BYTE *translation=NULL); // Returns true if the next call to GetPixels() will return an image different from the // last call to GetPixels(). This should be considered valid only if a call to CheckModified() diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index 07191d626..c0053a658 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -742,7 +742,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu // //=========================================================================== -int FDDSTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int FDDSTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { FWadLump lump = Wads.OpenLumpNum (SourceLump); @@ -768,7 +768,7 @@ int FDDSTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height } // All formats decompress to RGBA. - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, TexBuffer, Width, Height, 4, Width*4, CF_RGBA); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, TexBuffer, Width, Height, 4, Width*4, rotate, CF_RGBA); delete [] TexBuffer; return -1; } diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index 6e7c642a7..74028f2d0 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -332,7 +332,7 @@ void FJPEGTexture::MakeTexture () // //=========================================================================== -int FJPEGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int FJPEGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { PalEntry pe[256]; @@ -376,18 +376,18 @@ int FJPEGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_heigh { case JCS_RGB: screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height, - 3, cinfo.output_width * cinfo.output_components, CF_RGB); + 3, cinfo.output_width * cinfo.output_components, rotate, CF_RGB); break; case JCS_GRAYSCALE: for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height, - 1, cinfo.output_width, pe); + 1, cinfo.output_width, rotate, pe); break; case JCS_CMYK: screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, CF_CMYK); + 4, cinfo.output_width * cinfo.output_components, rotate, CF_CMYK); break; default: diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 297e96a6f..fb7a1e4c8 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -292,10 +292,65 @@ void FMultiPatchTexture::MakeTexture () for (int i = 0; i < NumParts; ++i) { Parts[i].Texture->CopyToBlock (Pixels, Width, Height, - Parts[i].OriginX, Parts[i].OriginY); + Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate); } } +//=========================================================================== +// +// FMultipatchTexture::CopyTrueColorPixels +// +// Preserves the palettes of each individual patch +// +//=========================================================================== + +int FMultiPatchTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) +{ + int retv = -1; + + for(int i=0;iCopyTrueColorPixels(buffer, buf_pitch, buf_height, + x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate); + + if (ret > retv) retv = ret; + } + return retv; +} + +//========================================================================== +// +// FMultiPatchTexture :: GetFormat +// +// only returns 'paletted' if all patches use the base palette. +// +//========================================================================== + +FTextureFormat FMultiPatchTexture::GetFormat() +{ + if (NumParts == 1) return Parts[0].Texture->GetFormat(); + return UseBasePalette() ? TEX_Pal : TEX_RGB; +} + + +//=========================================================================== +// +// FMultipatchTexture::UseBasePalette +// +// returns true if all patches in the texture use the unmodified base +// palette. +// +//=========================================================================== + +bool FMultiPatchTexture::UseBasePalette() +{ + for(int i=0;iUseBasePalette()) return false; + } + return true; +} + //========================================================================== // // FMultiPatchTexture :: CheckForHacks @@ -423,61 +478,6 @@ void FMultiPatchTexture::CheckForHacks () } } -//=========================================================================== -// -// FMultipatchTexture::CopyTrueColorPixels -// -// Preserves the palettes of each individual patch -// -//=========================================================================== - -int FMultiPatchTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) -{ - int retv = -1; - - for(int i=0;iCopyTrueColorPixels(buffer, buf_pitch, buf_height, - x+Parts[i].OriginX, y+Parts[i].OriginY); - - if (ret > retv) retv = ret; - } - return retv; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetFormat -// -// only returns 'paletted' if all patches use the base palette. -// -//========================================================================== - -FTextureFormat FMultiPatchTexture::GetFormat() -{ - if (NumParts == 1) return Parts[0].Texture->GetFormat(); - return UseBasePalette() ? TEX_Pal : TEX_RGB; -} - - -//=========================================================================== -// -// FMultipatchTexture::UseBasePalette -// -// returns true if all patches in the texture use the unmodified base -// palette. -// -//=========================================================================== - -bool FMultiPatchTexture::UseBasePalette() -{ - for(int i=0;iUseBasePalette()) return false; - } - return true; -} - //========================================================================== // // FMultiPatchTexture :: TexPart :: TexPart @@ -487,7 +487,7 @@ bool FMultiPatchTexture::UseBasePalette() FMultiPatchTexture::TexPart::TexPart() { OriginX = OriginY = 0; - Mirror = Rotate = 0; + Rotate = 0; textureOwned = false; Texture = NULL; } @@ -680,6 +680,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part) sc.MustGetString(); int texno = TexMan.CheckForTexture(sc.String, TEX_WallPatch); + int Mirror = 0; if (texno < 0) { @@ -705,37 +706,39 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part) sc.MustGetNumber(); part.OriginY = sc.Number; - /* not yet implemented - if (sc.CheckString("{"); + if (sc.CheckString("{")) { while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("flipx")) { - part.Mirror |= 1; + Mirror |= 1; } else if (sc.Compare("flipy")) { - part.Mirror |= 2; + Mirror |= 2; } else if (sc.Compare("rotate")) { sc.MustGetNumber(); - if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != 270) + if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) { - sc.ScriptError("Rotation must be 0, 90, 180 or 270 degrees"); + sc.ScriptError("Rotation must be 0, 90, 180 or -90 degrees"); } - part.Rotate = sc.Number / 90; + part.Rotate = (sc.Number / 90) & 3; } } } - if (part.Mirror & 2) + if (Mirror & 2) { - part.Rotate = (part.Rotate + 180) % 360; - part.Mirror &= 1; + part.Rotate = (part.Rotate + 2) & 3; + Mirror ^= 1; + } + if (Mirror & 1) + { + part.Rotate |= 4; } - */ } @@ -804,7 +807,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) if (Parts->OriginX == 0 && Parts->OriginY == 0 && Parts->Texture->GetWidth() == Width && Parts->Texture->GetHeight() == Height && - Parts->Mirror == 0 && Parts->Rotate == 0) + Parts->Rotate == 0) { bRedirect = true; } diff --git a/src/textures/pcxtexture.cpp b/src/textures/pcxtexture.cpp index 87d622eaa..3239966c2 100644 --- a/src/textures/pcxtexture.cpp +++ b/src/textures/pcxtexture.cpp @@ -418,7 +418,7 @@ void FPCXTexture::MakeTexture() // //=========================================================================== -int FPCXTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int FPCXTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { PalEntry pe[256]; PCXHeader header; @@ -472,14 +472,14 @@ int FPCXTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height lump.Seek(sizeof(header), SEEK_SET); ReadPCX8bits (Pixels, lump, &header); } - screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 1, Width, pe); + screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 1, Width, rotate, pe); } else { Pixels = new BYTE[Width*Height * 3]; BYTE * row = buffer; ReadPCX24bits (Pixels, lump, &header, 3); - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 3, Width*3, CF_RGB); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 3, Width*3, rotate, CF_RGB); } delete [] Pixels; return 0; diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index 915b4cd87..64550b690 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -490,7 +490,7 @@ void FPNGTexture::MakeTexture () // //=========================================================================== -int FPNGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int FPNGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? PalEntry pe[256]; @@ -554,20 +554,20 @@ int FPNGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height { case 0: case 3: - screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 1, Width, pe); + screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 1, Width, rotate, pe); break; case 2: - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 3, pixwidth, CF_RGB); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGB); break; case 4: - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 2, pixwidth, CF_IA); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 2, pixwidth, rotate, CF_IA); transpal = -1; break; case 6: - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 4, pixwidth, CF_RGBA); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, Pixels, Width, Height, 4, pixwidth, rotate, CF_RGBA); transpal = -1; break; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 989a64a27..953a2a211 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -270,7 +270,7 @@ void FTexture::FreeSpans (Span **spans) const M_Free (spans); } -void FTexture::CopyToBlock (BYTE *dest, int dwidth, int dheight, int xpos, int ypos, const BYTE *translation) +void FTexture::CopyToBlock (BYTE *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const BYTE *translation) { const BYTE *pixels = GetPixels(); int srcwidth = Width; @@ -278,7 +278,7 @@ void FTexture::CopyToBlock (BYTE *dest, int dwidth, int dheight, int xpos, int y int step_x = Height; int step_y = 1; - if (ClipCopyPixelRect(dwidth, dheight, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y)) + if (ClipCopyPixelRect(dwidth, dheight, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate)) { dest += ypos + dheight * xpos; if (translation == NULL) @@ -288,7 +288,7 @@ void FTexture::CopyToBlock (BYTE *dest, int dwidth, int dheight, int xpos, int y int pos = x * dheight; for (int y = 0; y < srcheight; y++, pos++) { - // the optimizer is doing a good enough job here so there's no need to make this harder to read. + // the optimizer is doing a good enough job here so there's no need to optimize this by hand BYTE v = pixels[y * step_y + x * step_x]; if (v != 0) dest[pos] = v; } @@ -476,13 +476,13 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt) // //=========================================================================== -int FTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int FTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { PalEntry *palette = screen->GetPalette(); palette[0].a=255; // temporarily modify the first color's alpha screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, GetPixels(), Width, Height, Height, 1, - palette); + rotate, palette); palette[0].a=0; return 0; @@ -494,7 +494,7 @@ int FTexture::CopyTrueColorTranslated(BYTE *buffer, int buf_pitch, int buf_heigh palette[0].a=255; // temporarily modify the first color's alpha screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, GetPixels(), Width, Height, Height, 1, - palette); + 0, palette); palette[0].a=0; return 0; diff --git a/src/textures/tgatexture.cpp b/src/textures/tgatexture.cpp index a670a3883..09d0b53fe 100644 --- a/src/textures/tgatexture.cpp +++ b/src/textures/tgatexture.cpp @@ -384,7 +384,7 @@ void FTGATexture::MakeTexture () // //=========================================================================== -int FTGATexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y) +int FTGATexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y, int rotate) { PalEntry pe[256]; FWadLump lump = Wads.OpenLumpNum (SourceLump); @@ -469,7 +469,7 @@ int FTGATexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height switch (hdr.img_type & 7) { case 1: // paletted - screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, pe); + screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, pe); break; case 2: // RGB @@ -477,21 +477,21 @@ int FTGATexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height { case 15: case 16: - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_RGB555); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_RGB555); break; case 24: - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGR); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_BGR); break; case 32: if ((hdr.img_desc&15)!=8) // 32 bits without a valid alpha channel { - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGR); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_BGR); } else { - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGRA); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_BGRA); transval = -1; } break; @@ -506,11 +506,11 @@ int FTGATexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height { case 8: for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // gray map - screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, pe); + screen->CopyPixelData(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, pe); break; case 16: - screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_I16); + screen->CopyPixelDataRGB(buffer, buf_pitch, buf_height, x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_I16); break; default: diff --git a/src/v_video.cpp b/src/v_video.cpp index a35b7af9a..4aa7043ec 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1191,15 +1191,92 @@ static CopyFunc copyfuncs[]={ iCopyColors }; - //=========================================================================== // // Clips the copy area for CopyPixelData functions // //=========================================================================== bool ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy, - const BYTE *&patch, int &srcwidth, int &srcheight, int step_x, int step_y) + const BYTE *&patch, int &srcwidth, int &srcheight, + int &pstep_x, int &pstep_y, int rotate) { + int pixxoffset; + int pixyoffset; + + int step_x; + int step_y; + + // First adjust the settings for the intended rotation + switch (rotate) + { + default: + case 0: // normal + pixxoffset = 0; + pixyoffset = 0; + step_x = pstep_x; + step_y = pstep_y; + break; + + case 1: // rotate 90° right + pixxoffset = 0; + pixyoffset = srcheight - 1; + step_x = -pstep_y; + step_y = pstep_x; + break; + + case 2: // rotate 180° + pixxoffset = srcwidth - 1; + pixyoffset = srcheight - 1; + step_x = -pstep_x; + step_y = -pstep_y; + break; + + case 3: // rotate 90° left + pixxoffset = srcwidth - 1; + pixyoffset = 0; + step_x = pstep_y; + step_y = -pstep_x; + break; + + case 4: // flip horizontally + pixxoffset = srcwidth - 1; + pixyoffset = 0; + step_x = -pstep_x; + step_y = pstep_y; + break; + + case 5: // flip horizontally and rotate 90° right + pixxoffset = srcwidth - 1; + pixyoffset = srcheight - 1; + step_x = -pstep_y; + step_y = -pstep_x; + break; + + case 6: // flip vertically + pixxoffset = 0; + pixyoffset = srcheight - 1; + step_x = pstep_x; + step_y = -pstep_y; + break; + + case 7: // flip horizontally and rotate 90° left + pixxoffset = 0; + pixyoffset = 0; + step_x = pstep_y; + step_y = pstep_x; + break; + } + if (rotate&1) + { + int v = srcwidth; + srcwidth = srcheight; + srcheight = v; + } + + patch += pixxoffset * pstep_x + pixyoffset * pstep_y; + pstep_x = step_x; + pstep_y = step_y; + // clip source rectangle to destination if (originx<0) { @@ -1229,6 +1306,7 @@ bool ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy, return true; } + //=========================================================================== // // True Color texture copy function @@ -1236,9 +1314,9 @@ bool ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy, //=========================================================================== void DFrameBuffer::CopyPixelDataRGB(BYTE *buffer, int texpitch, int texheight, int originx, int originy, const BYTE *patch, int srcwidth, int srcheight, int step_x, int step_y, - int ct) + int rotate, int ct) { - if (ClipCopyPixelRect(texpitch/4, texheight, originx, originy, patch, srcwidth, srcheight, step_x, step_y)) + if (ClipCopyPixelRect(texpitch/4, texheight, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate)) { buffer+=4*originx + texpitch*originy; for (int y=0;y