diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 1aabd24959..bb272be545 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,8 @@ +December 27, 2007 +- Removed DCanvas::Blit(), as it's no longer used. +- Added a function to create a texture from a stand-alone PNG file. The save/ + load menus now use this to get their thumbnails. + December 27, 2007 (Changes by Graf Zahl) - Fixed: DFrameBuffer::CopyPixelData copied data as RGBA instead of BGRA. - Temporarily changed FPNGTexture and FDDSTexture to always create True Color diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 7fbde744af..692d72b40f 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -254,7 +254,7 @@ static FState *PlayerState; static int PlayerTics; static int PlayerRotation; -static DCanvas *SavePic; +static FTexture *SavePic; static FBrokenLines *SaveComment; static List SaveGames; static FSaveGameNode *TopSaveGame; @@ -1039,7 +1039,7 @@ static void M_ExtractSaveData (const FSaveGameNode *node) } // Extract pic - SavePic = M_CreateCanvasFromPNG (png); + SavePic = FPNGTexture::CreateFromFile(png, node->Filename); delete png; } @@ -1099,8 +1099,11 @@ static void M_DrawSaveLoadCommon () M_DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight); if (SavePic != NULL) { - screen->Blit(savepicLeft, savepicTop, savepicWidth, savepicHeight, - SavePic, 0, 0, SavePic->GetWidth(), SavePic->GetHeight()); + screen->DrawTexture(SavePic, savepicLeft, savepicTop, + DTA_DestWidth, savepicWidth, + DTA_DestHeight, savepicHeight, + DTA_Masked, false, + TAG_DONE); } else { diff --git a/src/m_png.cpp b/src/m_png.cpp index dd7d35ebce..0b10b3383e 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -30,9 +30,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** -** Currently, only 256-color paletted images are supported, as these are all -** that ZDoom needs to support. Expect this to become more complete in the -** future if I decide to add support for graphic patches stored as PNGs. */ // HEADER FILES ------------------------------------------------------------ @@ -454,66 +451,6 @@ void M_FreePNG (PNGHandle *png) delete png; } -//========================================================================== -// -// M_CreateCanvasFromPNG -// -// Creates a simple canvas containing the contents of the PNG file's IDAT -// chunk(s). Only 8-bit images are supported. -// -//========================================================================== - -DCanvas *M_CreateCanvasFromPNG (PNGHandle *png) -{ - IHDR imageHeader; - DSimpleCanvas *canvas; - int width, height; - unsigned int chunklen; - - if (M_FindPNGChunk (png, MAKE_ID('I','H','D','R')) == 0) - { - return NULL; - } - if (png->File->Read (&imageHeader, sizeof(IHDR)) != sizeof(IHDR)) - { - return NULL; - } - if (imageHeader.Width == 0 || - imageHeader.Height == 0 || - // Only images that M_CreatePNG can write are supported - imageHeader.BitDepth != 8 || - imageHeader.ColorType != 3 || - imageHeader.Compression != 0 || - imageHeader.Filter != 0 || - imageHeader.Interlace != 0 - ) - { - return NULL; - } - chunklen = M_FindPNGChunk (png, MAKE_ID('I','D','A','T')); - if (chunklen == 0) - { - return NULL; - } - - width = BigLong((int)imageHeader.Width); - height = BigLong((int)imageHeader.Height); - canvas = new DSimpleCanvas (width, height); - if (canvas == NULL) - { - return NULL; - } - canvas->Lock (); - bool success = M_ReadIDAT (png->File, canvas->GetBuffer(), width, height, canvas->GetPitch(), 8, 3, 0, chunklen); - canvas->Unlock (); - if (!success) - { - delete canvas; - canvas = NULL; - } - return canvas; -} - //========================================================================== // // ReadIDAT diff --git a/src/m_png.h b/src/m_png.h index 3755ecdcfb..e37eecc2b2 100644 --- a/src/m_png.h +++ b/src/m_png.h @@ -100,10 +100,6 @@ unsigned int M_NextPNGChunk (PNGHandle *png, DWORD chunkID); char *M_GetPNGText (PNGHandle *png, const char *keyword); bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buffsize); -// Creates a simple canvas containing the contents of the PNG file's IDAT -// chunk(s). Only 8-bit images are supported. -DCanvas *M_CreateCanvasFromPNG (PNGHandle *png); - // The file must be positioned at the start of the first IDAT. It reads // image data into the provided buffer. Returns true on success. bool M_ReadIDAT (FileReader *file, BYTE *buffer, int width, int height, int pitch, diff --git a/src/r_data.h b/src/r_data.h index 169079e9ff..a30b2bd865 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -243,13 +243,15 @@ public: int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); bool UseBasePalette(); -protected: + static FTexture *CreateFromFile (PNGHandle *png, const FString &filename); +protected: static bool Check (FileReader &file); static FTexture *Create (FileReader &file, int lumpnum); - FPNGTexture (FileReader &lump, int lumpnum, int width, int height, BYTE bitdepth, BYTE colortype, BYTE interlace); + FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, BYTE bitdepth, BYTE colortype, BYTE interlace); int SourceLump; + FString SourceFile; BYTE *Pixels; Span **Spans; diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index 6816e2f2a3..958835cfcd 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -101,13 +101,44 @@ FTexture *FPNGTexture::Create(FileReader & data, int lumpnum) } } - return new FPNGTexture (data, lumpnum, BigLong((int)width), BigLong((int)height), + return new FPNGTexture (data, lumpnum, FString(), BigLong((int)width), BigLong((int)height), bitdepth, colortype, interlace); } -FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height, +FTexture *FPNGTexture::CreateFromFile(PNGHandle *png, const FString &filename) +{ + DWORD width, height; + BYTE bitdepth, colortype, compression, filter, interlace; + + if (M_FindPNGChunk(png, MAKE_ID('I','H','D','R')) == 0) + { + return NULL; + } + + // Check the IHDR to make sure it's a type of PNG we support. + (*png->File) >> width >> height + >> bitdepth >> colortype >> compression >> filter >> interlace; + + if (compression != 0 || filter != 0 || interlace > 1) + { + return NULL; + } + if (!((1 << colortype) & 0x5D)) + { + return NULL; + } + if (!((1 << bitdepth) & 0x116)) + { + return NULL; + } + + return new FPNGTexture (*png->File, -1, filename, BigLong((int)width), BigLong((int)height), + bitdepth, colortype, interlace); +} + +FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, BYTE depth, BYTE colortype, BYTE interlace) -: SourceLump(lumpnum), Pixels(0), Spans(0), +: SourceLump(lumpnum), SourceFile(filename), Pixels(0), Spans(0), BitDepth(depth), ColorType(colortype), Interlace(interlace), PaletteMap(0), PaletteSize(0), StartOfIDAT(0) { @@ -318,7 +349,16 @@ const BYTE *FPNGTexture::GetPixels () void FPNGTexture::MakeTexture () { - FWadLump lump = Wads.OpenLumpNum (SourceLump); + FileReader *lump; + + if (SourceLump >= 0) + { + lump = new FWadLump(Wads.OpenLumpNum(SourceLump)); + } + else + { + lump = new FileReader(SourceFile.GetChars()); + } Pixels = new BYTE[Width*Height]; if (StartOfIDAT == 0) @@ -328,12 +368,12 @@ void FPNGTexture::MakeTexture () else { DWORD len, id; - lump.Seek (StartOfIDAT, SEEK_SET); - lump >> len >> id; + lump->Seek (StartOfIDAT, SEEK_SET); + (*lump) >> len >> id; if (ColorType == 0 || ColorType == 3) /* Grayscale and paletted */ { - M_ReadIDAT (&lump, Pixels, Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); + M_ReadIDAT (lump, Pixels, Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); if (Width == Height) { @@ -369,7 +409,7 @@ void FPNGTexture::MakeTexture () BYTE *in, *out; int x, y, pitch, backstep; - M_ReadIDAT (&lump, tempix, Width, Height, Width*bytesPerPixel, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); + M_ReadIDAT (lump, tempix, Width, Height, Width*bytesPerPixel, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); in = tempix; out = Pixels; @@ -437,6 +477,7 @@ void FPNGTexture::MakeTexture () delete[] tempix; } } + delete lump; if (Spans == NULL) { Spans = CreateSpans (Pixels); @@ -454,50 +495,60 @@ int FPNGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? PalEntry pe[256]; DWORD len, id; - FWadLump lump = Wads.OpenLumpNum (SourceLump); + FileReader *lump; static char bpp[]={1, 0, 3, 1, 2, 0, 4}; int pixwidth = Width * bpp[ColorType]; int transpal=false; - lump.Seek (33, SEEK_SET); + if (SourceLump >= 0) + { + lump = new FWadLump(Wads.OpenLumpNum(SourceLump)); + } + else + { + lump = new FileReader(SourceFile.GetChars()); + } + + lump->Seek (33, SEEK_SET); for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map - lump >> len >> id; + (*lump) >> len >> id; while (id != MAKE_ID('I','D','A','T') && id != MAKE_ID('I','E','N','D')) { len = BigLong((unsigned int)len); switch (id) { default: - lump.Seek (len, SEEK_CUR); + lump->Seek (len, SEEK_CUR); break; case MAKE_ID('P','L','T','E'): for(int i=0;i> pe[i].r >> pe[i].g >> pe[i].b; + (*lump) >> pe[i].r >> pe[i].g >> pe[i].b; } break; case MAKE_ID('t','R','N','S'): for(DWORD i=0;i> pe[i].a; + (*lump) >> pe[i].a; pe[i].a=255-pe[i].a; // use inverse alpha so the default palette can be used unchanged if (pe[i].a!=0 && pe[i].a!=255) transpal = true; } break; } - lump >> len >> len; // Skip CRC + (*lump) >> len >> len; // Skip CRC id = MAKE_ID('I','E','N','D'); - lump >> id; + (*lump) >> id; } BYTE * Pixels = new BYTE[pixwidth * Height]; - lump.Seek (StartOfIDAT, SEEK_SET); - lump >> len >> id; - M_ReadIDAT (&lump, Pixels, Width, Height, pixwidth, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); + lump->Seek (StartOfIDAT, SEEK_SET); + (*lump) >> len >> id; + M_ReadIDAT (lump, Pixels, Width, Height, pixwidth, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); + delete lump; switch (ColorType) { diff --git a/src/v_video.cpp b/src/v_video.cpp index 1fec6538d5..1889f47580 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -562,68 +562,6 @@ static void BuildTransTable (const PalEntry *palette) Col2RGB8_LessPrecision[64] = Col2RGB8[64]; } -void DCanvas::Blit (int destx, int desty, int destwidth, int destheight, DCanvas *src, - int srcx, int srcy, int srcwidth, int srcheight) -{ - fixed_t fracxstep, fracystep; - fixed_t fracx, fracy; - int x, y; - bool lockthis, locksrc; - - if ( (lockthis = (LockCount == 0)) ) - { - if (Lock ()) - { // Surface was lost, so nothing to blit - Unlock (); - return; - } - } - - if ( (locksrc = (src->LockCount == 0)) ) - { - src->Lock (); - } - - fracy = srcy << FRACBITS; - fracystep = (srcheight << FRACBITS) / destheight; - fracxstep = (srcwidth << FRACBITS) / destwidth; - - BYTE *destline, *srcline; - BYTE *destbuffer = Buffer; - BYTE *srcbuffer = src->Buffer; - - if (fracxstep == FRACUNIT) - { - for (y = desty; y < desty + destheight; y++, fracy += fracystep) - { - memcpy (destbuffer + y * Pitch + destx, - srcbuffer + (fracy >> FRACBITS) * src->Pitch + srcx, - destwidth); - } - } - else - { - for (y = desty; y < desty + destheight; y++, fracy += fracystep) - { - srcline = srcbuffer + (fracy >> FRACBITS) * src->Pitch + srcx; - destline = destbuffer + y * Pitch + destx; - for (x = fracx = 0; x < destwidth; x++, fracx += fracxstep) - { - destline[x] = srcline[fracx >> FRACBITS]; - } - } - } - - if (lockthis) - { - Unlock (); - } - if (locksrc) - { - src->Unlock (); - } -} - void DCanvas::CalcGamma (float gamma, BYTE gammalookup[256]) { // I found this formula on the web at diff --git a/src/v_video.h b/src/v_video.h index 40f4342d7d..c5a9a26f9d 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -146,9 +146,6 @@ public: virtual void Unlock () = 0; virtual bool IsLocked () { return Buffer != NULL; } // Returns true if the surface is locked - // Copy blocks from one canvas to another - virtual void Blit (int destx, int desty, int destwidth, int destheight, DCanvas *src, int srcx, int srcy, int srcwidth, int srcheight); - // Draw a linear block of pixels into the canvas virtual void DrawBlock (int x, int y, int width, int height, const BYTE *src) const; diff --git a/src/w_wad.h b/src/w_wad.h index 63d5c219d4..4ae10e6e38 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -95,7 +95,7 @@ void BloodCrypt (void *data, int key, int len); // A very loose reference to a lump on disk. This is really just a wrapper // around the main wad's FILE object with a different length recorded. Since -// the two lumps from the same wad share the same FILE, you cannot read from +// two lumps from the same wad share the same FILE, you cannot read from // both of them independantly. class FWadLump : public FileReader { diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 20991b4dda..1b1051d147 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -320,6 +320,7 @@ bool D3DFB::CreateResources () } if (FAILED(D3DDevice->CreatePixelShader (GammaFixerDef, &GammaFixerShader))) { + Printf ("Windowed mode gamma will not work.\n"); GammaFixerShader = NULL; } CurPixelShader = NULL; @@ -1371,9 +1372,6 @@ bool D3DFB::Begin2D() Update(); In2D = 2; - // Set default state for 2D rendering. - SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - return true; }