mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2026-06-17 10:47:45 +02:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
450
Code/ww3d2/bitmaphandler.h
Normal file
450
Code/ww3d2/bitmaphandler.h
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BITMAPHANDLER_H
|
||||
#define BITMAPHANDLER_H
|
||||
|
||||
#include "always.h"
|
||||
#include "ww3dformat.h"
|
||||
|
||||
void Bitmap_Assert(bool condition);
|
||||
|
||||
class BitmapHandlerClass
|
||||
{
|
||||
public:
|
||||
// Read pixel at given address
|
||||
WWINLINE static void Read_B8G8R8A8(
|
||||
unsigned char* argb,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp);
|
||||
|
||||
// Read pixel at given address
|
||||
WWINLINE static void Read_B8G8R8A8(
|
||||
unsigned& argb,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp);
|
||||
|
||||
// Read pixel from surface
|
||||
WWINLINE static void Read_B8G8R8A8(
|
||||
unsigned& argb,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp);
|
||||
|
||||
WWINLINE static void Write_B8G8R8A8(
|
||||
unsigned char* dest_ptr,
|
||||
WW3DFormat dest_format,
|
||||
const unsigned char* argb);
|
||||
|
||||
WWINLINE static void Write_B8G8R8A8(
|
||||
unsigned char* dest_ptr,
|
||||
WW3DFormat dest_format,
|
||||
const unsigned& argb);
|
||||
|
||||
WWINLINE static void Copy_Pixel(
|
||||
unsigned char* dest_ptr,
|
||||
WW3DFormat dest_format,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp);
|
||||
|
||||
WWINLINE static unsigned Combine_A8R8G8B8(
|
||||
unsigned bgra1,
|
||||
unsigned bgra2,
|
||||
unsigned bgra3,
|
||||
unsigned bgra4);
|
||||
|
||||
static void Create_Mipmap_B8G8R8A8(
|
||||
unsigned char* dest_surface,
|
||||
unsigned dest_surface_pitch,
|
||||
unsigned char* src_surface,
|
||||
unsigned src_surface_pitch,
|
||||
unsigned width,
|
||||
unsigned height);
|
||||
|
||||
static void Copy_Image_Generate_Mipmap(
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
unsigned char* dest_surface,
|
||||
unsigned dest_pitch,
|
||||
WW3DFormat dest_format,
|
||||
unsigned char* src_surface,
|
||||
unsigned src_pitch,
|
||||
WW3DFormat src_format,
|
||||
unsigned char* mip_surface,
|
||||
unsigned mip_pitch);
|
||||
|
||||
static void Copy_Image(
|
||||
unsigned char* dest_surface,
|
||||
unsigned dest_surface_width,
|
||||
unsigned dest_surface_height,
|
||||
unsigned dest_surface_pitch,
|
||||
WW3DFormat dest_surface_format,
|
||||
unsigned char* src_surface,
|
||||
unsigned src_surface_width,
|
||||
unsigned src_surface_height,
|
||||
unsigned src_surface_pitch,
|
||||
WW3DFormat src_surface_format,
|
||||
const unsigned char* src_palette,
|
||||
unsigned src_palette_bpp,
|
||||
bool generate_mip_level);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Read color value of given type in BGRA (D3D) byte order. Regarless
|
||||
// of the source format the color value is converted to 32-bit format.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
WWINLINE void BitmapHandlerClass::Read_B8G8R8A8(
|
||||
unsigned char* argb,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp)
|
||||
{
|
||||
switch (src_format) {
|
||||
case WW3D_FORMAT_A8R8G8B8:
|
||||
case WW3D_FORMAT_X8R8G8B8:
|
||||
*(unsigned*)argb=*(unsigned*)src_ptr;
|
||||
break;
|
||||
case WW3D_FORMAT_R8G8B8:
|
||||
*argb++=src_ptr[0];
|
||||
*argb++=src_ptr[1];
|
||||
*argb++=src_ptr[2];
|
||||
*argb++=0xff;
|
||||
break;
|
||||
case WW3D_FORMAT_A4R4G4B4:
|
||||
{
|
||||
unsigned short tmp;
|
||||
tmp=*(unsigned short*)src_ptr;
|
||||
*argb++=((tmp&0x000f)<<4);
|
||||
*argb++=((tmp&0x00f0));
|
||||
*argb++=((tmp&0x0f00)>>4);
|
||||
*argb++=((tmp&0xf000)>>8);
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_A1R5G5B5:
|
||||
{
|
||||
unsigned short tmp;
|
||||
tmp=*(unsigned short*)src_ptr;
|
||||
argb[3]=tmp&0x8000 ? 0xff : 0x0;
|
||||
argb[2]=(tmp>>7)&0xf8;
|
||||
argb[1]=(tmp>>2)&0xf8;
|
||||
argb[0]=(tmp<<3)&0xf8;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_R5G6B5:
|
||||
{
|
||||
unsigned short tmp;
|
||||
tmp=*(unsigned short*)src_ptr;
|
||||
argb[3]=0xff;
|
||||
argb[2]=(tmp>>8)&0xf8;
|
||||
argb[1]=(tmp>>3)&0xfc;
|
||||
argb[0]=(tmp<<3)&0xf8;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_R3G3B2:
|
||||
{
|
||||
unsigned char tmp=*src_ptr;
|
||||
argb[3]=0xff;
|
||||
argb[2]=tmp&0xe0;
|
||||
argb[1]=(tmp<<3)&0xe0;
|
||||
argb[0]=(tmp<<6)&0xc0;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_L8:
|
||||
{
|
||||
unsigned char tmp=*src_ptr++;
|
||||
*argb++=tmp;
|
||||
*argb++=tmp;
|
||||
*argb++=tmp;
|
||||
*argb++=0xff;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_A8:
|
||||
{
|
||||
*argb++=0;
|
||||
*argb++=0;
|
||||
*argb++=0;
|
||||
*argb++=*src_ptr++;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_P8:
|
||||
{
|
||||
unsigned char index=*src_ptr++;
|
||||
switch (palette_bpp) {
|
||||
case 4:
|
||||
*argb++=palette[palette_bpp*index+3];
|
||||
*argb++=palette[palette_bpp*index+2];
|
||||
*argb++=palette[palette_bpp*index+1];
|
||||
*argb++=palette[palette_bpp*index+0];
|
||||
break;
|
||||
case 3:
|
||||
*argb++=palette[palette_bpp*index+2];
|
||||
*argb++=palette[palette_bpp*index+1];
|
||||
*argb++=palette[palette_bpp*index+0];
|
||||
*argb++=0xff;
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
default:
|
||||
Bitmap_Assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_DXT1:
|
||||
case WW3D_FORMAT_DXT2:
|
||||
case WW3D_FORMAT_DXT3:
|
||||
case WW3D_FORMAT_DXT4:
|
||||
case WW3D_FORMAT_DXT5:
|
||||
default: Bitmap_Assert(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
WWINLINE void BitmapHandlerClass::Read_B8G8R8A8(
|
||||
unsigned& argb,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp)
|
||||
{
|
||||
Read_B8G8R8A8((unsigned char*)&argb,src_ptr,src_format,palette,palette_bpp);
|
||||
}
|
||||
|
||||
// Read pixel from surface
|
||||
WWINLINE void BitmapHandlerClass::Read_B8G8R8A8(
|
||||
unsigned& argb,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp)
|
||||
{
|
||||
if (x<0 || y<0 || x>=width || y>=height) {
|
||||
argb=0;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned bpp=Get_Bytes_Per_Pixel(src_format);
|
||||
Read_B8G8R8A8(
|
||||
argb,
|
||||
src_ptr+bpp*x+width*bpp*y,
|
||||
src_format,
|
||||
palette,
|
||||
palette_bpp);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Write color value of given type in BGRA (D3D) byte order. The source value
|
||||
// is always 32 bit and it is converted to defined destination format.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
WWINLINE void BitmapHandlerClass::Write_B8G8R8A8(
|
||||
unsigned char* dest_ptr,
|
||||
WW3DFormat dest_format,
|
||||
const unsigned char* argb)
|
||||
{
|
||||
switch (dest_format) {
|
||||
case WW3D_FORMAT_A8R8G8B8:
|
||||
case WW3D_FORMAT_X8R8G8B8:
|
||||
*(unsigned*)dest_ptr=*(unsigned*)argb;
|
||||
break;
|
||||
case WW3D_FORMAT_R8G8B8:
|
||||
*dest_ptr++=*argb++;
|
||||
*dest_ptr++=*argb++;
|
||||
*dest_ptr++=*argb++;
|
||||
break;
|
||||
case WW3D_FORMAT_A4R4G4B4:
|
||||
{
|
||||
unsigned short tmp;
|
||||
tmp=((argb[3])&0xf0)<<8;
|
||||
tmp|=((argb[2])&0xf0)<<4;
|
||||
tmp|=((argb[1])&0xf0);
|
||||
tmp|=((argb[0])&0xf0)>>4;
|
||||
*(unsigned short*)dest_ptr=tmp;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_A1R5G5B5:
|
||||
{
|
||||
unsigned short tmp;
|
||||
tmp=argb[3] ? 0x8000 : 0x0;
|
||||
tmp|=((argb[2])&0xf8)<<7;
|
||||
tmp|=((argb[1])&0xf8)<<2;
|
||||
tmp|=((argb[0])&0xf8)>>3;
|
||||
*(unsigned short*)dest_ptr=tmp;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_R5G6B5:
|
||||
{
|
||||
unsigned short tmp;
|
||||
tmp=((argb[2])&0xf8)<<8;
|
||||
tmp|=((argb[1])&0xfc)<<3;
|
||||
tmp|=((argb[0])&0xf8)>>3;
|
||||
*(unsigned short*)dest_ptr=tmp;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_R3G3B2:
|
||||
{
|
||||
unsigned char tmp;
|
||||
tmp=((argb[2])&0xe0);
|
||||
tmp|=((argb[1])&0xe0)>>3;
|
||||
tmp|=((argb[0])&0xc0)>>6;
|
||||
*(unsigned short*)dest_ptr=tmp;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_L8:
|
||||
{
|
||||
// CIE Req. 709: Y709 = 0.2125R + 0.7154G + 0.0721B
|
||||
unsigned char tmp = (unsigned char) ( (
|
||||
((unsigned int)argb[0] * (unsigned int)0x1275) + // 0.0721B
|
||||
((unsigned int)argb[1] * (unsigned int)0xB725) + // 0.7154G (rounded up so FF, FF, FF becomes FF)
|
||||
((unsigned int)argb[2] * (unsigned int)0x3666) // 0.2125R
|
||||
) >> 16);
|
||||
*dest_ptr++=tmp;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_A8:
|
||||
{
|
||||
*dest_ptr++=*argb++;
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_DXT1:
|
||||
case WW3D_FORMAT_DXT2:
|
||||
case WW3D_FORMAT_DXT3:
|
||||
case WW3D_FORMAT_DXT4:
|
||||
case WW3D_FORMAT_DXT5:
|
||||
case WW3D_FORMAT_P8: // Paletted destination not supported
|
||||
default: Bitmap_Assert(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
WWINLINE void BitmapHandlerClass::Write_B8G8R8A8(
|
||||
unsigned char* dest_ptr,
|
||||
WW3DFormat dest_format,
|
||||
const unsigned& argb)
|
||||
{
|
||||
Write_B8G8R8A8(dest_ptr,dest_format,(unsigned char*)&argb);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Copy pixel. Perform color space conversion if needed. The source and
|
||||
// destination are always D3D-style BGRA.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
WWINLINE void BitmapHandlerClass::Copy_Pixel(
|
||||
unsigned char* dest_ptr,
|
||||
WW3DFormat dest_format,
|
||||
const unsigned char* src_ptr,
|
||||
WW3DFormat src_format,
|
||||
const unsigned char* palette,
|
||||
unsigned palette_bpp)
|
||||
{
|
||||
// Color space conversion needed?
|
||||
|
||||
if (dest_format==src_format) {
|
||||
switch (dest_format) {
|
||||
case WW3D_FORMAT_A8R8G8B8:
|
||||
case WW3D_FORMAT_X8R8G8B8:
|
||||
*(unsigned*)dest_ptr=*(unsigned*)src_ptr;
|
||||
break;
|
||||
case WW3D_FORMAT_R8G8B8:
|
||||
*dest_ptr++=src_ptr[0];
|
||||
*dest_ptr++=src_ptr[1];
|
||||
*dest_ptr++=src_ptr[2];
|
||||
break;
|
||||
case WW3D_FORMAT_A4R4G4B4:
|
||||
{
|
||||
unsigned short tmp=*(unsigned short*)src_ptr;
|
||||
*(unsigned short*)dest_ptr=((tmp&0x000f)<<12)|((tmp&0x00f0)<<4)|((tmp&0x0f00)>>4)|((tmp&0xf000)>>12);
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_A1R5G5B5:
|
||||
{
|
||||
unsigned short tmp=*(unsigned short*)src_ptr;
|
||||
*(unsigned short*)dest_ptr=((tmp&0x001f)<<11)|((tmp&0x03e0)<<1)|((tmp&0x7c00)>>9)|((tmp&0x8000)>>15);
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_R5G6B5:
|
||||
{
|
||||
unsigned short tmp=*(unsigned short*)src_ptr;
|
||||
*(unsigned short*)dest_ptr=((tmp&0x001f)<<11)|(tmp&0x07e0)|((tmp&0xf800)>>11);
|
||||
}
|
||||
break;
|
||||
case WW3D_FORMAT_R3G3B2:
|
||||
case WW3D_FORMAT_L8:
|
||||
case WW3D_FORMAT_A8: *dest_ptr++=*src_ptr++;
|
||||
break;
|
||||
case WW3D_FORMAT_P8: // Paletted destinations not supported
|
||||
default: Bitmap_Assert(0); break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned b8g8r8a8;
|
||||
Read_B8G8R8A8(b8g8r8a8,src_ptr,src_format,palette,palette_bpp);
|
||||
Write_B8G8R8A8(dest_ptr,dest_format,b8g8r8a8);
|
||||
}
|
||||
}
|
||||
|
||||
WWINLINE unsigned BitmapHandlerClass::Combine_A8R8G8B8(
|
||||
unsigned bgra1,
|
||||
unsigned bgra2,
|
||||
unsigned bgra3,
|
||||
unsigned bgra4)
|
||||
{
|
||||
bgra1&=0xfcfcfcfc;
|
||||
bgra2&=0xfcfcfcfc;
|
||||
bgra3&=0xfcfcfcfc;
|
||||
bgra4&=0xfcfcfcfc;
|
||||
bgra1>>=2;
|
||||
bgra2>>=2;
|
||||
bgra3>>=2;
|
||||
bgra4>>=2;
|
||||
bgra1+=bgra2;
|
||||
bgra3+=bgra4;
|
||||
bgra1+=bgra3;
|
||||
return bgra1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user