diff --git a/docs/rh-log.txt b/docs/rh-log.txt index b28dba941..dfbb8cc12 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,12 @@ December 20, 2007 (Changes by Graf Zahl) +- Fixed: FTexture::~FTexture() must destroy the associated native texture + if present. +- Modified GZDoom's true color texture copy functions and added them + to generate 32 bit D3D textures. Paletted TGAs and PCXs are also handled + this way but I don't think these 2 formats are worth some more special + handling. + (Question: Is it worth it to implement special handling for paletted PNGs + so that they are used as 8 bit textures internally?) - Fixed: DCanvas::Blit unlocked the destination twice instead of unlocking both dest and src. Also changed this function so that it is owned by the destination canvas of the operation which is necessary if it needs to diff --git a/src/r_data.h b/src/r_data.h index 05f7080c7..646f14300 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -85,9 +85,12 @@ public: const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); + FTextureFormat GetFormat(); void Unload (); virtual void SetFrontSkyLayer (); + int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y); + protected: BYTE *Pixels; Span **Spans; @@ -237,6 +240,8 @@ public: const BYTE *GetPixels (); void Unload (); FTextureFormat GetFormat (); + int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y); + bool UseBasePalette(); protected: @@ -312,6 +317,8 @@ public: const BYTE *GetPixels (); void Unload (); FTextureFormat GetFormat (); + int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y); + bool UseBasePalette(); protected: @@ -361,6 +368,9 @@ public: void Unload (); FTextureFormat GetFormat (); + int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y); + bool UseBasePalette(); + protected: int SourceLump; BYTE *Pixels; @@ -412,6 +422,10 @@ public: const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); void Unload (); + FTextureFormat GetFormat (); + + int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y); + bool UseBasePalette(); protected: int SourceLump; diff --git a/src/r_defs.h b/src/r_defs.h index b4a10fad5..e5a4b6151 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -664,6 +664,9 @@ public: // Returns the whole texture, stored in column-major order virtual const BYTE *GetPixels () = 0; + + virtual int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y); + virtual bool UseBasePalette(); virtual void Unload () = 0; @@ -677,7 +680,7 @@ public: void KillNative(); // Fill the native texture buffer with pixel data for this image - virtual void FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt); + virtual void FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt); int GetWidth () { return Width; } int GetHeight () { return Height; } diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index f9a178662..f11a7affc 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -323,3 +323,91 @@ void FJPEGTexture::MakeTexture () } } + +//=========================================================================== +// +// FJPEGTexture::CopyTrueColorPixels +// +// Preserves the full color information (unlike software mode) +// +//=========================================================================== + +int FJPEGTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y) +{ + PalEntry pe[256]; + + FWadLump lump = Wads.OpenLumpNum (SourceLump); + JSAMPLE *buff = NULL; + + jpeg_decompress_struct cinfo; + jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error(&jerr); + cinfo.err->output_message = JPEG_OutputMessage; + cinfo.err->error_exit = JPEG_ErrorExit; + jpeg_create_decompress(&cinfo); + + try + { + FLumpSourceMgr sourcemgr(&lump, &cinfo); + jpeg_read_header(&cinfo, TRUE); + + if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || + (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || + (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) + { + Printf (TEXTCOLOR_ORANGE "Unsupported color format\n"); + throw -1; + } + jpeg_start_decompress(&cinfo); + + int yc = 0; + buff = new BYTE[cinfo.output_height * cinfo.output_width * cinfo.output_components]; + + + while (cinfo.output_scanline < cinfo.output_height) + { + BYTE * ptr = buff + cinfo.output_width * cinfo.output_components * yc; + jpeg_read_scanlines(&cinfo, &ptr, 1); + yc++; + } + + switch (cinfo.out_color_space) + { + case JCS_RGB: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height, + 3, cinfo.output_width * cinfo.output_components, 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_width, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height, + 1, cinfo.output_width, pe); + break; + + case JCS_CMYK: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height, + 4, cinfo.output_width * cinfo.output_components, CF_CMYK); + break; + } + jpeg_finish_decompress(&cinfo); + } + catch(int) + { + Printf (TEXTCOLOR_ORANGE " in JPEG texture %s\n", Name); + } + jpeg_destroy_decompress(&cinfo); + if (buff != NULL) delete [] buff; + return 0; +} + + +//=========================================================================== +// +// +//=========================================================================== + +bool FJPEGTexture::UseBasePalette() +{ + return false; +} diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index ead41cb24..b8d97a34c 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -371,6 +371,40 @@ void FMultiPatchTexture::CheckForHacks () } } +//=========================================================================== +// +// FMultipatchTexture::CopyTrueColorPixels +// +// Preserves the palettes of each individual patch +// +//=========================================================================== + +int FMultiPatchTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y) +{ + int retv = -1; + + for(int i=0;iCopyTrueColorPixels(buffer, buf_width, buf_height, + x+Parts[i].OriginX, y+Parts[i].OriginY); + + if (ret > retv) retv = ret; + } + return retv; +} + +FTextureFormat FMultiPatchTexture::GetFormat() +{ + if (NumParts == 1) return Parts[0].Texture->GetFormat(); + + for(int i=0;iUseBasePalette()) return TEX_RGB; + } + return TEX_Pal; +} + + void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int patcheslump, int firstdup, bool texture1) { FPatchLookup *patchlookup; diff --git a/src/textures/pcxtexture.cpp b/src/textures/pcxtexture.cpp index 2cc8028d5..5a9e14bce 100644 --- a/src/textures/pcxtexture.cpp +++ b/src/textures/pcxtexture.cpp @@ -111,6 +111,12 @@ void FPCXTexture::Unload () } } +FTextureFormat FPCXTexture::GetFormat() +{ + return TEX_RGB; +} + + const BYTE *FPCXTexture::GetColumn (unsigned int column, const Span **spans_out) { if (Pixels == NULL) @@ -404,3 +410,88 @@ void FPCXTexture::MakeTexture() } } +//=========================================================================== +// +// FPCXTexture::CopyTrueColorPixels +// +// Preserves the full color information (unlike software mode) +// +//=========================================================================== + +int FPCXTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y) +{ + PalEntry pe[256]; + PCXHeader header; + int bitcount; + BYTE * Pixels; + + FWadLump lump = Wads.OpenLumpNum(SourceLump); + + lump.Read(&header, sizeof(header)); + + bitcount = header.bitsPerPixel * header.numColorPlanes; + + if (bitcount < 24) + { + Pixels = new BYTE[Width*Height]; + if (bitcount < 8) + { + for (int i=0;i<16;i++) + { + pe[i] = PalEntry(header.palette[i*3],header.palette[i*3+1],header.palette[i*3+2]); + } + + switch (bitcount) + { + default: + case 1: + ReadPCX1bit (Pixels, lump, &header); + break; + + case 4: + ReadPCX4bits (Pixels, lump, &header); + break; + } + } + else if (bitcount == 8) + { + BYTE c; + lump.Seek(-769, SEEK_END); + lump >> c; + c=0x0c; // Apparently there's many non-compliant PCXs out there... + if (c !=0x0c) + { + for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map + } + else for(int i=0;i<256;i++) + { + BYTE r,g,b; + lump >> r >> g >> b; + pe[i] = PalEntry(r,g,b); + } + lump.Seek(sizeof(header), SEEK_SET); + ReadPCX8bits (Pixels, lump, &header); + } + screen->CopyPixelData(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 1, Width, pe); + } + else + { + Pixels = new BYTE[Width*Height * 3]; + BYTE * row = buffer; + ReadPCX24bits (Pixels, lump, &header, 3); + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 3, Width*3, CF_RGB); + } + delete [] Pixels; + return 0; +} + + +//=========================================================================== +// +// +//=========================================================================== + +bool FPCXTexture::UseBasePalette() +{ + return false; +} diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index 17c6e85e1..a7dfce558 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -438,3 +438,99 @@ void FPNGTexture::MakeTexture () } } +//=========================================================================== +// +// FPNGTexture::CopyTrueColorPixels +// +//=========================================================================== + +int FPNGTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y) +{ + // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? + PalEntry pe[256]; + DWORD len, id; + FWadLump lump = Wads.OpenLumpNum (SourceLump); + static char bpp[]={1, 0, 3, 1, 2, 0, 4}; + int pixwidth = Width * bpp[ColorType]; + int transpal=false; + + 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; + 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); + break; + + case MAKE_ID('P','L','T','E'): + for(int i=0;i> 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; + 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 + id = MAKE_ID('I','E','N','D'); + 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)); + + switch (ColorType) + { + case 0: + case 3: + screen->CopyPixelData(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 1, Width, pe); + break; + + case 2: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 3, pixwidth, CF_RGB); + break; + + case 4: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 2, pixwidth, CF_IA); + transpal = -1; + break; + + case 6: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 4, pixwidth, CF_RGBA); + transpal = -1; + break; + + default: + break; + + } + delete[] Pixels; + return transpal; +} + + +//=========================================================================== +// +// This doesn't check if the palette is identical with the base palette +// I don't think it's worth the hassle because it's only of importance +// when compositing multipatch textures. +// +//=========================================================================== + +bool FPNGTexture::UseBasePalette() +{ + return false; +} diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index e9650a15c..1535207b2 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -125,6 +125,7 @@ FTexture::FTexture () FTexture::~FTexture () { + KillNative(); } bool FTexture::CheckModified () @@ -428,19 +429,19 @@ void FTexture::KillNative() // color data. Note that the buffer expects row-major data, since that's // generally more convenient for any non-Doom image formats, and it doesn't // need to be used by any of Doom's column drawing routines. -void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt) +void FTexture::FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt) { const BYTE *pix; int x, y, w, h, stride; w = GetWidth(); h = GetHeight(); - pix = GetPixels(); switch (fmt) { case TEX_Pal: case TEX_Gray: + pix = GetPixels(); stride = pitch - w; for (y = 0; y < h; ++y) { @@ -456,23 +457,7 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt) break; case TEX_RGB: - stride = pitch - w * 4; - for (y = 0; y < h; ++y) - { - const BYTE *pix2 = pix; - for (x = 0; x < w; ++x) - { - const PalEntry *pal = &GPalette.BaseColors[*pix2]; - buff[0] = pal->b; - buff[1] = pal->g; - buff[2] = pal->r; - buff[3] = pal->a; - buff += 4; - pix2 += h; - } - pix++; - buff += stride; - } + CopyTrueColorPixels(buff, pitch, height, 0, 0); break; default: @@ -480,6 +465,37 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt) } } +//=========================================================================== +// +// FTexture::CopyTrueColorPixels +// +// this is the generic case that can handle +// any properly implemented texture for software rendering. +// Its drawback is that it is limited to the base palette which is +// why all classes that handle different palettes should subclass this +// method +// +//=========================================================================== + +int FTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y) +{ + PalEntry * palette = screen->GetPalette(); + palette[0].a=255; // temporarily modify the first color's alpha + screen->CopyPixelData(buffer, buf_width, buf_height, x, y, + GetPixels(), Width, Height, Height, 1, + palette); + + palette[0].a=0; + return 0; +} + +bool FTexture::UseBasePalette() +{ + return true; +} + + + FDummyTexture::FDummyTexture () { Width = 64; diff --git a/src/textures/tgatexture.cpp b/src/textures/tgatexture.cpp index 982acac35..51c257e9f 100644 --- a/src/textures/tgatexture.cpp +++ b/src/textures/tgatexture.cpp @@ -378,5 +378,159 @@ void FTGATexture::MakeTexture () } } +//=========================================================================== +// +// FTGATexture::CopyTrueColorPixels +// +//=========================================================================== +int FTGATexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y) +{ + PalEntry pe[256]; + FWadLump lump = Wads.OpenLumpNum (SourceLump); + TGAHeader hdr; + WORD w; + BYTE r,g,b,a; + BYTE * sbuffer; + int transval = 0; + lump.Read(&hdr, sizeof(hdr)); + lump.Seek(hdr.id_len, SEEK_CUR); + +#ifdef WORDS_BIGENDIAN + hdr.width = LittleShort(hdr.width); + hdr.height = LittleShort(hdr.height); + hdr.cm_first = LittleShort(hdr.cm_first); + hdr.cm_length = LittleShort(hdr.cm_length); +#endif + + if (hdr.has_cm) + { + memset(pe, 0, 256*sizeof(PalEntry)); + for (int i = hdr.cm_first; i < hdr.cm_first + hdr.cm_length && i < 256; i++) + { + switch (hdr.cm_size) + { + case 15: + case 16: + lump >> w; + r = (w & 0x001F) << 3; + g = (w & 0x03E0) >> 2; + b = (w & 0x7C00) >> 7; + a = 255; + break; + + case 24: + lump >> b >> g >> r; + a=255; + break; + + case 32: + lump >> b >> g >> r >> a; + if ((hdr.img_desc&15)!=8) a=255; + else if (a!=0 && a!=255) transval = true; + break; + + default: // should never happen + r=g=b=a=0; + break; + } + pe[i] = PalEntry(255-a, r, g, b); + } + } + + int Size = Width * Height * (hdr.bpp>>3); + sbuffer = new BYTE[Size]; + + if (hdr.img_type < 4) // uncompressed + { + lump.Read(sbuffer, Size); + } + else // compressed + { + ReadCompressed(lump, sbuffer, hdr.bpp>>3); + } + + BYTE * ptr = sbuffer; + int step_x = (hdr.bpp>>3); + int Pitch = Width * step_x; + + if (hdr.img_desc&32) + { + ptr += (Width-1) * step_x; + step_x =- step_x; + } + if (!(hdr.img_desc&64)) + { + ptr += (Height-1) * Pitch; + Pitch = -Pitch; + } + + switch (hdr.img_type & 7) + { + case 1: // paletted + screen->CopyPixelData(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, pe); + break; + + case 2: // RGB + switch (hdr.bpp) + { + case 15: + case 16: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_RGB555); + break; + + case 24: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGR); + break; + + case 32: + if ((hdr.img_desc&15)!=8) // 32 bits without a valid alpha channel + { + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGR); + } + else + { + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGRA); + transval = -1; + } + break; + + default: + break; + } + break; + + case 3: // Grayscale + switch (hdr.bpp) + { + case 8: + for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // gray map + screen->CopyPixelData(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, pe); + break; + + case 16: + screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_I16); + break; + + default: + break; + } + break; + + default: + break; + } + delete [] sbuffer; + return transval; +} + +//=========================================================================== +// +// +//=========================================================================== + +bool FTGATexture::UseBasePalette() +{ + return false; +} diff --git a/src/v_video.cpp b/src/v_video.cpp index f2fed2caa..53be5d75e 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -797,6 +797,137 @@ FNativeTexture *DFrameBuffer::CreatePalette(const PalEntry *pal) return NULL; } +//=========================================================================== +// +// multi-format pixel copy with colormap application +// requires one of the previously defined conversion classes to work +// +//=========================================================================== +template +void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step) +{ + for(int i=0;i, + iCopyColors, + iCopyColors, + iCopyColors, + iCopyColors, + iCopyColors, + iCopyColors, + iCopyColors, + iCopyColors +}; + + +//=========================================================================== +// +// Clips the copy area for CopyPixelData functions +// +//=========================================================================== +bool DFrameBuffer::ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy, + const BYTE *&patch, int &srcwidth, int &srcheight, int step_x, int step_y) +{ + // clip source rectangle to destination + if (originx<0) + { + srcwidth+=originx; + patch-=originx*step_x; + originx=0; + if (srcwidth<=0) return false; + } + if (originx+srcwidth>texwidth) + { + srcwidth=texwidth-originx; + if (srcwidth<=0) return false; + } + + if (originy<0) + { + srcheight+=originy; + patch-=originy*step_y; + originy=0; + if (srcheight<=0) return false; + } + if (originy+srcheight>texheight) + { + srcheight=texheight-originy; + if (srcheight<=0) return false; + } + return true; +} + +//=========================================================================== +// +// True Color texture copy function +// +//=========================================================================== +void DFrameBuffer::CopyPixelDataRGB(BYTE * buffer, int texwidth, int texheight, int originx, int originy, + const BYTE * patch, int srcwidth, int srcheight, int step_x, int step_y, + int ct) +{ + if (ClipCopyPixelRect(texwidth, texheight, originx, originy, patch, srcwidth, srcheight, step_x, step_y)) + { + buffer+=4*originx + 4*texwidth*originy; + for (int y=0;y(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-palette[v].a))/255, 0, 255); + } + } + } + } +} + FNativeTexture::~FNativeTexture() { } diff --git a/src/v_video.h b/src/v_video.h index c1c8b6796..52566c305 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -316,6 +316,16 @@ public: // Create a palette texture from a 256-entry palette. virtual FNativeTexture *CreatePalette(const PalEntry *pal); + // texture copy functions + virtual void CopyPixelDataRGB(BYTE * buffer, int texwidth, int texheight, int originx, int originy, + const BYTE * patch, int pix_width, int pix_height, int step_x, int step_y, + int ct); + + virtual void CopyPixelData(BYTE * buffer, int texwidth, int texheight, int originx, int originy, + const BYTE * patch, int pix_width, int pix_height, + int step_x, int step_y, PalEntry * palette); + + #ifdef _WIN32 virtual void PaletteChanged () = 0; virtual int QueryNewPalette () = 0; @@ -327,6 +337,10 @@ protected: DFrameBuffer () {} + bool ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy, + const BYTE *&patch, int &srcwidth, int &srcheight, int step_x, int step_y); + + int RateX; private: @@ -385,4 +399,107 @@ extern "C" void ASM_PatchPitch (void); int CheckRatio (int width, int height); extern const int BaseRatioSizes[5][4]; + +//=========================================================================== +// +// True color conversion classes for the different pixel formats +// used by the supported texture formats +// +//=========================================================================== +struct cRGB +{ + static unsigned char R(const unsigned char * p) { return p[0]; } + static unsigned char G(const unsigned char * p) { return p[1]; } + static unsigned char B(const unsigned char * p) { return p[2]; } + static unsigned char A(const unsigned char * p) { return 255; } + static int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; } +}; + +struct cRGBA +{ + static unsigned char R(const unsigned char * p) { return p[0]; } + static unsigned char G(const unsigned char * p) { return p[1]; } + static unsigned char B(const unsigned char * p) { return p[2]; } + static unsigned char A(const unsigned char * p) { return p[3]; } + static int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; } +}; + +struct cIA +{ + static unsigned char R(const unsigned char * p) { return p[0]; } + static unsigned char G(const unsigned char * p) { return p[0]; } + static unsigned char B(const unsigned char * p) { return p[0]; } + static unsigned char A(const unsigned char * p) { return p[1]; } + static int Gray(const unsigned char * p) { return p[0]; } +}; + +struct cCMYK +{ + static unsigned char R(const unsigned char * p) { return p[3] - (((256-p[0])*p[3]) >> 8); } + static unsigned char G(const unsigned char * p) { return p[3] - (((256-p[1])*p[3]) >> 8); } + static unsigned char B(const unsigned char * p) { return p[3] - (((256-p[2])*p[3]) >> 8); } + static unsigned char A(const unsigned char * p) { return 255; } + static int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; } +}; + +struct cBGR +{ + static unsigned char R(const unsigned char * p) { return p[2]; } + static unsigned char G(const unsigned char * p) { return p[1]; } + static unsigned char B(const unsigned char * p) { return p[0]; } + static unsigned char A(const unsigned char * p) { return 255; } + static int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; } +}; + +struct cBGRA +{ + static unsigned char R(const unsigned char * p) { return p[2]; } + static unsigned char G(const unsigned char * p) { return p[1]; } + static unsigned char B(const unsigned char * p) { return p[0]; } + static unsigned char A(const unsigned char * p) { return p[3]; } + static int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; } +}; + +struct cI16 +{ + static unsigned char R(const unsigned char * p) { return p[1]; } + static unsigned char G(const unsigned char * p) { return p[1]; } + static unsigned char B(const unsigned char * p) { return p[1]; } + static unsigned char A(const unsigned char * p) { return 255; } + static int Gray(const unsigned char * p) { return p[1]; } +}; + +struct cRGB555 +{ + static unsigned char R(const unsigned char * p) { return (((*(WORD*)p)&0x1f)<<3); } + static unsigned char G(const unsigned char * p) { return (((*(WORD*)p)&0x3e0)>>2); } + static unsigned char B(const unsigned char * p) { return (((*(WORD*)p)&0x7c00)>>7); } + static unsigned char A(const unsigned char * p) { return p[1]; } + static int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; } +}; + +struct cPalEntry +{ + static unsigned char R(const unsigned char * p) { return ((PalEntry*)p)->r; } + static unsigned char G(const unsigned char * p) { return ((PalEntry*)p)->g; } + static unsigned char B(const unsigned char * p) { return ((PalEntry*)p)->b; } + static unsigned char A(const unsigned char * p) { return ((PalEntry*)p)->a; } + static int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; } +}; + +enum ColorType +{ + CF_RGB, + CF_RGBA, + CF_IA, + CF_CMYK, + CF_BGR, + CF_BGRA, + CF_I16, + CF_RGB555, + CF_PalEntry +}; + + + #endif // __V_VIDEO_H__ diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 90ba57252..9fdebaebe 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1200,7 +1200,7 @@ bool D3DTex::Update() { return false; } - GameTex->FillBuffer((BYTE *)lrect.pBits, lrect.Pitch, ToTexFmt(desc.Format)); + GameTex->FillBuffer((BYTE *)lrect.pBits, lrect.Pitch, rect.bottom, ToTexFmt(desc.Format)); Tex->UnlockRect(0); return true; }