mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- 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. SVN r652 (trunk)
This commit is contained in:
parent
c911e995a9
commit
522e7fe07f
10 changed files with 88 additions and 161 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<PaletteSize;i++)
|
||||
{
|
||||
lump >> 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<len;i++)
|
||||
{
|
||||
lump >> 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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue