02 Jan 2008
This commit is contained in:
parent
2761b9d8ec
commit
f031d6f60a
|
@ -27,6 +27,7 @@ DDS Converter 2.1
|
|||
//==================================================
|
||||
// то, что уже готово
|
||||
//==================================================
|
||||
+добавлена поддержка текстур из первого дуума (с прозрачностью)
|
||||
+запущена в строй wadlib
|
||||
+добавлена поддержка ВСЕХ существующих типов внутри вадов
|
||||
+добавлена поддержка wad-файлов
|
||||
|
|
|
@ -31,7 +31,6 @@ void InitPlatform ( uint funcname, int argc, char **argv )
|
|||
char source[64], gamedir[64];
|
||||
|
||||
basepool = Mem_AllocPool( "Temp" );
|
||||
zonepool = Mem_AllocPool( "Zone" );
|
||||
|
||||
// for custom cmdline parsing
|
||||
com_argc = argc;
|
||||
|
@ -113,6 +112,7 @@ void RunPlatform ( void )
|
|||
strcpy(searchmask[3], "*.lmp" ); // quake1 menu images
|
||||
strcpy(searchmask[4], "*.mip" ); // quake1 textures
|
||||
strcpy(searchmask[5], "*.fnt" ); // half-life fonts
|
||||
strcpy(searchmask[6], "*.flat"); // doom1 textures
|
||||
Msg("Processing images ...\n\n");
|
||||
break;
|
||||
case BSPLIB:
|
||||
|
|
|
@ -557,7 +557,7 @@ void ROQ_ProcessAudio( void )
|
|||
{
|
||||
return;
|
||||
|
||||
if(!strlen(soundname)) return;
|
||||
if(!com.strlen(soundname)) return;
|
||||
|
||||
com.strcpy( tempoutname, movieoutname );
|
||||
FS_StripExtension( tempoutname );
|
||||
|
|
|
@ -98,6 +98,7 @@ extern uint image_ptr; // common moveable pointer
|
|||
|
||||
// image lib utilites
|
||||
extern uint *d_currentpal;
|
||||
bool dds_save_image( const char *name, rgbdata_t *pix, int saveformat );
|
||||
bool Image_Copy8bitRGBA(const byte *in, byte *out, int pixels); // convert indexed image to RGBA
|
||||
rgbdata_t *Image_CopyRGBA8bit( rgbdata_t *pix, int numcolors ); // convert RGBA image to indexed
|
||||
void Image_RoundDimensions(int *scaled_width, int *scaled_height);
|
||||
|
|
|
@ -9,21 +9,41 @@
|
|||
|
||||
#define Sum(c) ((c)->r + (c)->g + (c)->b)
|
||||
|
||||
bool dds_write_header( vfile_t *f, rgbdata_t *pix, uint cubemap_flags )
|
||||
/*
|
||||
===============
|
||||
GetImageSize
|
||||
|
||||
calculate buffer size for current miplevel
|
||||
===============
|
||||
*/
|
||||
uint GetImageSize( int block, int width, int height, int depth, int bpp, int rgbcount )
|
||||
{
|
||||
uint BlockSize = 0;
|
||||
|
||||
if(block == 0) BlockSize = width * height * bpp;
|
||||
else if(block > 0) BlockSize = ((width + 3)/4) * ((height + 3)/4) * depth * block;
|
||||
else if(block < 0 && rgbcount > 0) BlockSize = width * height * depth * rgbcount;
|
||||
else BlockSize = width * height * abs(block);
|
||||
|
||||
return BlockSize;
|
||||
}
|
||||
|
||||
bool dds_write_header( vfile_t *f, rgbdata_t *pix, uint cubemap_flags, uint savetype )
|
||||
{
|
||||
uint dwFourCC, dwFlags1 = 0, dwFlags2 = 0, dwCaps1 = 0;
|
||||
uint dwLinearSize, dwBlockSize, dwCaps2 = 0;
|
||||
uint dwIdent = DDSHEADER, dwSize = 124, dwSize2 = 32;
|
||||
uint dwWidth, dwHeight, dwDepth, dwMipCount = 1;
|
||||
|
||||
if(!pix || pix->buffer )
|
||||
if(!pix || !pix->buffer )
|
||||
return false;
|
||||
|
||||
// setup flags
|
||||
dwFlags1 |= DDS_LINEARSIZE | DDS_MIPMAPCOUNT | DDS_WIDTH | DDS_HEIGHT | DDS_CAPS | DDS_PIXELFORMAT;
|
||||
dwFlags1 |= DDS_LINEARSIZE | DDS_WIDTH | DDS_HEIGHT | DDS_CAPS | DDS_PIXELFORMAT;
|
||||
dwFlags2 |= DDS_FOURCC;
|
||||
if( pix->numLayers > 1) dwFlags1 |= DDS_DEPTH;
|
||||
|
||||
switch( pix->type )
|
||||
switch( savetype )
|
||||
{
|
||||
case PF_DXT1:
|
||||
dwFourCC = TYPE_DXT1;
|
||||
|
@ -53,25 +73,29 @@ bool dds_write_header( vfile_t *f, rgbdata_t *pix, uint cubemap_flags )
|
|||
MsgDev( D_ERROR, "dds_write_header: unsupported type %s\n", PFDesc[pix->type].name );
|
||||
return false;
|
||||
}
|
||||
dwWidth = pix->width;
|
||||
dwHeight = pix->height;
|
||||
|
||||
VFS_Write(f, &dwIdent, sizeof(uint));
|
||||
VFS_Write(f, &dwSize, sizeof(uint));
|
||||
VFS_Write(f, &dwFlags1, sizeof(uint));
|
||||
VFS_Write(f, &pix->height, sizeof(uint));
|
||||
VFS_Write(f, &pix->width, sizeof(uint));
|
||||
VFS_Write(f, &dwHeight, sizeof(uint));
|
||||
VFS_Write(f, &dwWidth, sizeof(uint));
|
||||
|
||||
dwBlockSize = PFDesc[pix->type].block;
|
||||
dwLinearSize = (((pix->width + 3)/4) * ((pix->height + 3)/4)) * dwBlockSize * pix->numLayers;
|
||||
dwBlockSize = PFDesc[savetype].block;
|
||||
dwLinearSize = GetImageSize(PFDesc[savetype].block, pix->width, pix->height, pix->numLayers, PFDesc[savetype].bpp, pix->bitsCount / 8 );
|
||||
//dwLinearSize = (((pix->width + 3)/4) * ((pix->height + 3)/4)) * dwBlockSize * pix->numLayers;
|
||||
VFS_Write(f, &dwLinearSize, sizeof(uint)); // TODO: use dds_get_linear_size
|
||||
|
||||
if (pix->numLayers > 1)
|
||||
{
|
||||
VFS_Write(f, &pix->numLayers, sizeof(uint));
|
||||
dwDepth = pix->numLayers;
|
||||
VFS_Write(f, &dwDepth, sizeof(uint));
|
||||
dwCaps2 |= DDS_VOLUME;
|
||||
}
|
||||
else VFS_Write(f, 0, sizeof(uint));
|
||||
|
||||
VFS_Write(f, &pix->numMips, sizeof(uint));
|
||||
VFS_Write(f, &dwMipCount, sizeof(uint));
|
||||
VFS_Write(f, 0, sizeof(uint));
|
||||
VFS_Write(f, pix->color, sizeof(vec3_t));
|
||||
VFS_Write(f, &pix->bump_scale, sizeof(float));
|
||||
|
@ -140,6 +164,49 @@ void ChooseEndpoints(word *Block, word *ex0, word *ex1)
|
|||
*ex1 = Block[Lowest];
|
||||
}
|
||||
|
||||
void CorrectEndDXT1( word *ex0, word *ex1, bool HasAlpha )
|
||||
{
|
||||
word Temp;
|
||||
|
||||
if( HasAlpha )
|
||||
{
|
||||
if(*ex0 > *ex1)
|
||||
{
|
||||
Temp = *ex0;
|
||||
*ex0 = *ex1;
|
||||
*ex1 = Temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*ex0 < *ex1)
|
||||
{
|
||||
Temp = *ex0;
|
||||
*ex0 = *ex1;
|
||||
*ex1 = Temp;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void PreMult(word *Data, byte *Alpha)
|
||||
{
|
||||
color24 Colour;
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ShortToColor888(Data[i], &Colour);
|
||||
Colour.r = (byte)(((uint)Colour.r * Alpha[i]) >> 8);
|
||||
Colour.g = (byte)(((uint)Colour.g * Alpha[i]) >> 8);
|
||||
Colour.b = (byte)(((uint)Colour.b * Alpha[i]) >> 8);
|
||||
Data[i] = Color888ToShort(&Colour);
|
||||
ShortToColor888(Data[i], &Colour);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ChooseAlphaEndpoints( byte *Block, byte *a0, byte *a1)
|
||||
{
|
||||
uint i, Lowest = 0xFF, Highest = 0;
|
||||
|
@ -153,6 +220,41 @@ void ChooseAlphaEndpoints( byte *Block, byte *a0, byte *a1)
|
|||
*a1 = Highest;
|
||||
}
|
||||
|
||||
// Assumed to be 16-bit (5:6:5).
|
||||
bool GetBlock( word *Block, word *Data, rgbdata_t *pix, uint XPos, uint YPos)
|
||||
{
|
||||
uint x, y, i = 0, Offset = YPos * pix->width + XPos;
|
||||
|
||||
for( y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
if(x < pix->width && y < pix->height)
|
||||
Block[i++] = Data[Offset + x];
|
||||
else Block[i++] = Data[Offset];
|
||||
}
|
||||
Offset += pix->width;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetAlphaBlock( byte *Block, byte *Data, rgbdata_t *pix, uint XPos, uint YPos)
|
||||
{
|
||||
uint x, y, i = 0, Offset = YPos * pix->width + XPos;
|
||||
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
if (x < pix->width && y < pix->height)
|
||||
Block[i++] = Data[Offset + x];
|
||||
else Block[i++] = Data[Offset];
|
||||
}
|
||||
Offset += pix->width;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Get3DcBlock( byte *Block, byte *Data, rgbdata_t *pix, uint XPos, uint YPos, int channel )
|
||||
{
|
||||
uint x, y, i = 0, Offset = 2*(YPos * pix->width + XPos) + channel;
|
||||
|
@ -162,7 +264,7 @@ bool Get3DcBlock( byte *Block, byte *Data, rgbdata_t *pix, uint XPos, uint YPos,
|
|||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
if(x < pix->width && y < pix->height)
|
||||
Block[i++] = Data[Offset + 2*x];
|
||||
Block[i++] = Data[Offset + 2 * x];
|
||||
else Block[i++] = Data[Offset];
|
||||
}
|
||||
Offset += 2 * pix->width;
|
||||
|
@ -170,6 +272,184 @@ bool Get3DcBlock( byte *Block, byte *Data, rgbdata_t *pix, uint XPos, uint YPos,
|
|||
return true;
|
||||
}
|
||||
|
||||
byte* GetAlpha( rgbdata_t *pix )
|
||||
{
|
||||
byte *Alpha;
|
||||
uint i, j, Bpc, Size, AlphaOff;
|
||||
|
||||
Bpc = PFDesc[pix->type].bpc;
|
||||
if( Bpc == 0 ) return NULL;
|
||||
|
||||
Size = pix->width * pix->height * pix->numLayers * PFDesc[pix->type].bpp;
|
||||
Alpha = (byte*)Mem_Alloc( Sys.imagepool, Size / PFDesc[pix->type].bpp * Bpc);
|
||||
|
||||
if( pix->type == PF_LUMINANCE_ALPHA )
|
||||
AlphaOff = 2;
|
||||
else AlphaOff = 4;
|
||||
|
||||
for (i = AlphaOff - 1, j = 0; i < Size; i += AlphaOff, j++ )
|
||||
Alpha[j] = pix->buffer[i];
|
||||
|
||||
return Alpha;
|
||||
}
|
||||
|
||||
uint RMSAlpha( byte *Orig, byte *Test )
|
||||
{
|
||||
uint RMS = 0, i;
|
||||
int d;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
d = Orig[i] - Test[i];
|
||||
RMS += d*d;
|
||||
}
|
||||
return RMS;
|
||||
}
|
||||
|
||||
uint Distance(color24 *c1, color24 *c2)
|
||||
{
|
||||
return (c1->r - c2->r) * (c1->r - c2->r) + (c1->g - c2->g) * (c1->g - c2->g) + (c1->b - c2->b) * (c1->b - c2->b);
|
||||
}
|
||||
|
||||
uint GenBitMask( word ex0, word ex1, uint NumCols, word *In, byte *Alpha, color24 *OutCol )
|
||||
{
|
||||
uint i, j, Closest, Dist, BitMask = 0;
|
||||
byte Mask[16];
|
||||
color24 c, Colours[4];
|
||||
|
||||
ShortToColor888(ex0, &Colours[0]);
|
||||
ShortToColor888(ex1, &Colours[1]);
|
||||
if (NumCols == 3)
|
||||
{
|
||||
Colours[2].r = (Colours[0].r + Colours[1].r) / 2;
|
||||
Colours[2].g = (Colours[0].g + Colours[1].g) / 2;
|
||||
Colours[2].b = (Colours[0].b + Colours[1].b) / 2;
|
||||
Colours[3].r = (Colours[0].r + Colours[1].r) / 2;
|
||||
Colours[3].g = (Colours[0].g + Colours[1].g) / 2;
|
||||
Colours[3].b = (Colours[0].b + Colours[1].b) / 2;
|
||||
}
|
||||
else
|
||||
{ // NumCols == 4
|
||||
Colours[2].r = (2 * Colours[0].r + Colours[1].r + 1) / 3;
|
||||
Colours[2].g = (2 * Colours[0].g + Colours[1].g + 1) / 3;
|
||||
Colours[2].b = (2 * Colours[0].b + Colours[1].b + 1) / 3;
|
||||
Colours[3].r = (Colours[0].r + 2 * Colours[1].r + 1) / 3;
|
||||
Colours[3].g = (Colours[0].g + 2 * Colours[1].g + 1) / 3;
|
||||
Colours[3].b = (Colours[0].b + 2 * Colours[1].b + 1) / 3;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (Alpha)
|
||||
{
|
||||
// Test to see if we have 1-bit transparency
|
||||
if (Alpha[i] < 128)
|
||||
{
|
||||
Mask[i] = 3; // Transparent
|
||||
if (OutCol)
|
||||
{
|
||||
OutCol[i].r = Colours[3].r;
|
||||
OutCol[i].g = Colours[3].g;
|
||||
OutCol[i].b = Colours[3].b;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if no transparency, try to find which colour is the closest.
|
||||
Closest = UINT_MAX;
|
||||
ShortToColor888(In[i], &c);
|
||||
for (j = 0; j < NumCols; j++)
|
||||
{
|
||||
Dist = Distance(&c, &Colours[j]);
|
||||
if( Dist < Closest )
|
||||
{
|
||||
Closest = Dist;
|
||||
Mask[i] = j;
|
||||
if( OutCol )
|
||||
{
|
||||
OutCol[i].r = Colours[j].r;
|
||||
OutCol[i].g = Colours[j].g;
|
||||
OutCol[i].b = Colours[j].b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
BitMask |= (Mask[i] << (i*2));
|
||||
}
|
||||
return BitMask;
|
||||
}
|
||||
|
||||
|
||||
void GenAlphaBitMask( byte a0, byte a1, byte *In, byte *Mask, byte *Out )
|
||||
{
|
||||
byte Alphas[8], M[16];
|
||||
uint i, j, Closest, Dist;
|
||||
|
||||
Alphas[0] = a0;
|
||||
Alphas[1] = a1;
|
||||
|
||||
// 8-alpha or 6-alpha block?
|
||||
if (a0 > a1)
|
||||
{
|
||||
// 8-alpha block: derive the other six alphas.
|
||||
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
|
||||
Alphas[2] = (6 * Alphas[0] + 1 * Alphas[1] + 3) / 7; // bit code 010
|
||||
Alphas[3] = (5 * Alphas[0] + 2 * Alphas[1] + 3) / 7; // bit code 011
|
||||
Alphas[4] = (4 * Alphas[0] + 3 * Alphas[1] + 3) / 7; // bit code 100
|
||||
Alphas[5] = (3 * Alphas[0] + 4 * Alphas[1] + 3) / 7; // bit code 101
|
||||
Alphas[6] = (2 * Alphas[0] + 5 * Alphas[1] + 3) / 7; // bit code 110
|
||||
Alphas[7] = (1 * Alphas[0] + 6 * Alphas[1] + 3) / 7; // bit code 111
|
||||
}
|
||||
else
|
||||
{
|
||||
// 6-alpha block.
|
||||
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
|
||||
Alphas[2] = (4 * Alphas[0] + 1 * Alphas[1] + 2) / 5; // Bit code 010
|
||||
Alphas[3] = (3 * Alphas[0] + 2 * Alphas[1] + 2) / 5; // Bit code 011
|
||||
Alphas[4] = (2 * Alphas[0] + 3 * Alphas[1] + 2) / 5; // Bit code 100
|
||||
Alphas[5] = (1 * Alphas[0] + 4 * Alphas[1] + 2) / 5; // Bit code 101
|
||||
Alphas[6] = 0x00; // Bit code 110
|
||||
Alphas[7] = 0xFF; // Bit code 111
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
Closest = UINT_MAX;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
Dist = abs((int)In[i] - (int)Alphas[j]);
|
||||
if (Dist < Closest)
|
||||
{
|
||||
Closest = Dist;
|
||||
M[i] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Out )
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
Out[i] = Alphas[M[i]];
|
||||
}
|
||||
}
|
||||
|
||||
// First three bytes.
|
||||
Mask[0] = (M[0]) | (M[1] << 3) | ((M[2] & 0x03) << 6);
|
||||
Mask[1] = ((M[2] & 0x04) >> 2) | (M[3] << 1) | (M[4] << 4) | ((M[5] & 0x01) << 7);
|
||||
Mask[2] = ((M[5] & 0x06) >> 1) | (M[6] << 2) | (M[7] << 5);
|
||||
|
||||
// Second three bytes.
|
||||
Mask[3] = (M[8]) | (M[9] << 3) | ((M[10] & 0x03) << 6);
|
||||
Mask[4] = ((M[10] & 0x04) >> 2) | (M[11] << 1) | (M[12] << 4) | ((M[13] & 0x01) << 7);
|
||||
Mask[5] = ((M[13] & 0x06) >> 1) | (M[14] << 2) | (M[15] << 5);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
word *dds_compress_565( rgbdata_t *pix )
|
||||
{
|
||||
|
@ -189,11 +469,11 @@ word *dds_compress_565( rgbdata_t *pix )
|
|||
}
|
||||
break;
|
||||
case PF_RGBA_32:
|
||||
for (i = 0, j = 0; i < pix->size; i += 4, j++)
|
||||
for( i = 0, j = 0; i < pix->size; i += 4, j++ )
|
||||
{
|
||||
Data[j] = (pix->buffer[i+0] >> 3) << 11;
|
||||
Data[j] |= (pix->buffer[i+1] >> 2) << 5;
|
||||
Data[j] |= pix->buffer[i+2] >> 3;
|
||||
Data[j] |= (pix->buffer[i+0]>>3)<<11;
|
||||
Data[j] |= (pix->buffer[i+1]>>2)<<5;
|
||||
Data[j] |= (pix->buffer[i+2]>>3);
|
||||
}
|
||||
break;
|
||||
case PF_RGB_24_FLIP:
|
||||
|
@ -335,7 +615,7 @@ uint dds_compress_dxt( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
bool HasAlpha;
|
||||
uint Count = 0;
|
||||
|
||||
if(!pix || pix->buffer )
|
||||
if(!pix || !pix->buffer )
|
||||
return 0;
|
||||
|
||||
if( saveformat == PF_ATI2N)
|
||||
|
@ -370,7 +650,7 @@ uint dds_compress_dxt( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
}
|
||||
Mem_Free( Data3Dc );
|
||||
}
|
||||
else if( saveformat == IL_ATI1N )
|
||||
else if( saveformat == PF_ATI1N )
|
||||
{
|
||||
rgbdata_t *lum = NULL;
|
||||
if (PFDesc[pix->type].bpp != 1)
|
||||
|
@ -407,7 +687,7 @@ uint dds_compress_dxt( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
Data = dds_compress_565( pix );
|
||||
if(!Data) return 0;
|
||||
|
||||
Alpha = ilGetAlpha(IL_UNSIGNED_BYTE);
|
||||
Alpha = GetAlpha( pix );
|
||||
if(!Alpha)
|
||||
{
|
||||
Mem_Free(Data);
|
||||
|
@ -430,142 +710,144 @@ uint dds_compress_dxt( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
|
||||
switch( saveformat )
|
||||
{
|
||||
case IL_DXT1:
|
||||
|
||||
for (z = 0; z < pix->numLayers; z++) {
|
||||
for (y = 0; y < Image->Height; y += 4) {
|
||||
for (x = 0; x < Image->Width; x += 4) {
|
||||
GetAlphaBlock(AlphaBlock, Runner8, Image, x, y);
|
||||
HasAlpha = IL_FALSE;
|
||||
for (i = 0 ; i < 16; i++) {
|
||||
if (AlphaBlock[i] < 128) {
|
||||
HasAlpha = IL_TRUE;
|
||||
break;
|
||||
}
|
||||
case PF_DXT1:
|
||||
for (z = 0; z < pix->numLayers; z++)
|
||||
{
|
||||
for (y = 0; y < pix->height; y += 4)
|
||||
{
|
||||
for (x = 0; x < pix->width; x += 4)
|
||||
{
|
||||
GetAlphaBlock(AlphaBlock, Runner8, pix, x, y);
|
||||
HasAlpha = false;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if(AlphaBlock[i] < 128)
|
||||
{
|
||||
HasAlpha = true;
|
||||
break;
|
||||
}
|
||||
|
||||
GetBlock(Block, Runner16, Image, x, y);
|
||||
ChooseEndpoints(Block, &ex0, &ex1);
|
||||
CorrectEndDXT1(&ex0, &ex1, HasAlpha);
|
||||
SaveLittleUShort(ex0);
|
||||
SaveLittleUShort(ex1);
|
||||
if (HasAlpha)
|
||||
BitMask = GenBitMask(ex0, ex1, 3, Block, AlphaBlock, NULL);
|
||||
else
|
||||
BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
SaveLittleUInt(BitMask);
|
||||
Count += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Runner16 += Image->Width * Image->Height;
|
||||
|
||||
Runner8 += Image->Width * Image->Height;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*case IL_DXT2:
|
||||
for (y = 0; y < Image->Height; y += 4) {
|
||||
for (x = 0; x < Image->Width; x += 4) {
|
||||
GetAlphaBlock(AlphaBlock, Alpha, Image, x, y);
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
iputc((ILubyte)(((AlphaBlock[i] >> 4) << 4) | (AlphaBlock[i+1] >> 4)));
|
||||
}
|
||||
|
||||
GetBlock(Block, Data, Image, x, y);
|
||||
PreMult(Block, AlphaBlock);
|
||||
GetBlock(Block, Runner16, pix, x, y);
|
||||
ChooseEndpoints(Block, &ex0, &ex1);
|
||||
SaveLittleUShort(ex0);
|
||||
SaveLittleUShort(ex1);
|
||||
CorrectEndDXT1(&ex0, &ex1, HasAlpha);
|
||||
VFS_Write(f, &ex0, sizeof(word));
|
||||
VFS_Write(f, &ex1, sizeof(word));
|
||||
if (HasAlpha) BitMask = GenBitMask(ex0, ex1, 3, Block, AlphaBlock, NULL);
|
||||
else BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
VFS_Write(f, AlphaBitMask, sizeof(uint));
|
||||
Count += 8;
|
||||
}
|
||||
}
|
||||
Runner16 += pix->width * pix->height;
|
||||
Runner8 += pix->width * pix->height;
|
||||
}
|
||||
break;
|
||||
case PF_DXT2:
|
||||
for (y = 0; y < pix->height; y += 4)
|
||||
{
|
||||
for (x = 0; x < pix->width; x += 4)
|
||||
{
|
||||
GetAlphaBlock(AlphaBlock, Runner8, pix, x, y);
|
||||
for (i = 0; i < 16; i += 2)
|
||||
{
|
||||
byte tempBlock = ((AlphaBlock[i]>>4)<<4) | (AlphaBlock[i+1]>>4);
|
||||
VFS_Write(f, &tempBlock, 1 );
|
||||
}
|
||||
GetBlock(Block, Runner16, pix, x, y);
|
||||
PreMult(Block, AlphaBlock);
|
||||
ChooseEndpoints(Block, &ex0, &ex1);
|
||||
VFS_Write(f, &ex0, sizeof(word));
|
||||
VFS_Write(f, &ex1, sizeof(word));
|
||||
BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
VFS_Write(f, &AlphaBitMask, sizeof(uint));
|
||||
Count += 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PF_DXT3:
|
||||
for (z = 0; z < pix->numLayers; z++)
|
||||
{
|
||||
for (y = 0; y < pix->height; y += 4)
|
||||
{
|
||||
for (x = 0; x < pix->width; x += 4)
|
||||
{
|
||||
GetAlphaBlock(AlphaBlock, Runner8, pix, x, y);
|
||||
for (i = 0; i < 16; i += 2)
|
||||
{
|
||||
byte tempBlock = ((AlphaBlock[i]>>4)<<4) | (AlphaBlock[i+1]>>4);
|
||||
VFS_Write(f, &tempBlock, 1 );
|
||||
}
|
||||
GetBlock(Block, Runner16, pix, x, y);
|
||||
ChooseEndpoints(Block, &t0, &t1);
|
||||
ex0 = max(t0, t1);
|
||||
ex1 = min(t0, t1);
|
||||
CorrectEndDXT1(&ex0, &ex1, 0);
|
||||
VFS_Write(f, &ex0, sizeof(word));
|
||||
VFS_Write(f, &ex1, sizeof(word));
|
||||
BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
SaveLittleUInt(BitMask);
|
||||
}
|
||||
}
|
||||
break;*/
|
||||
|
||||
case IL_DXT3:
|
||||
|
||||
for (z = 0; z < Image->Depth; z++) {
|
||||
for (y = 0; y < Image->Height; y += 4) {
|
||||
for (x = 0; x < Image->Width; x += 4) {
|
||||
GetAlphaBlock(AlphaBlock, Runner8, Image, x, y);
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
iputc((ILubyte)(((AlphaBlock[i+1] >> 4) << 4) | (AlphaBlock[i] >> 4)));
|
||||
}
|
||||
|
||||
GetBlock(Block, Runner16, Image, x, y);
|
||||
ChooseEndpoints(Block, &t0, &t1);
|
||||
ex0 = IL_MAX(t0, t1);
|
||||
ex1 = IL_MIN(t0, t1);
|
||||
CorrectEndDXT1(&ex0, &ex1, 0);
|
||||
SaveLittleUShort(ex0);
|
||||
SaveLittleUShort(ex1);
|
||||
BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
SaveLittleUInt(BitMask);
|
||||
Count += 16;
|
||||
}
|
||||
VFS_Write(f, AlphaBitMask, sizeof(uint));
|
||||
Count += 16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Runner16 += Image->Width * Image->Height;
|
||||
|
||||
Runner8 += Image->Width * Image->Height;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case IL_RXGB:
|
||||
case IL_DXT5:
|
||||
|
||||
for (z = 0; z < Image->Depth; z++) {
|
||||
for (y = 0; y < Image->Height; y += 4) {
|
||||
for (x = 0; x < Image->Width; x += 4) {
|
||||
GetAlphaBlock(AlphaBlock, Runner8, Image, x, y);
|
||||
ChooseAlphaEndpoints(AlphaBlock, &a0, &a1);
|
||||
GenAlphaBitMask(a0, a1, AlphaBlock, AlphaBitMask, NULL/*AlphaOut*/);
|
||||
/*Rms2 = RMSAlpha(AlphaBlock, AlphaOut);
|
||||
GenAlphaBitMask(a0, a1, 8, AlphaBlock, AlphaBitMask, AlphaOut);
|
||||
Rms1 = RMSAlpha(AlphaBlock, AlphaOut);
|
||||
if (Rms2 <= Rms1) { // Yeah, we have to regenerate...
|
||||
GenAlphaBitMask(a0, a1, 6, AlphaBlock, AlphaBitMask, AlphaOut);
|
||||
Rms2 = a1; // Just reuse Rms2 as a temporary variable...
|
||||
a1 = a0;
|
||||
a0 = Rms2;
|
||||
}*/
|
||||
iputc(a0);
|
||||
iputc(a1);
|
||||
iwrite(AlphaBitMask, 1, 6);
|
||||
|
||||
GetBlock(Block, Runner16, Image, x, y);
|
||||
ChooseEndpoints(Block, &t0, &t1);
|
||||
ex0 = IL_MAX(t0, t1);
|
||||
ex1 = IL_MIN(t0, t1);
|
||||
CorrectEndDXT1(&ex0, &ex1, 0);
|
||||
SaveLittleUShort(ex0);
|
||||
SaveLittleUShort(ex1);
|
||||
BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
SaveLittleUInt(BitMask);
|
||||
Count += 16;
|
||||
}
|
||||
Runner16 += pix->width * pix->height;
|
||||
Runner8 += pix->width * pix->height;
|
||||
}
|
||||
break;
|
||||
case PF_RXGB:
|
||||
case PF_DXT5:
|
||||
for (z = 0; z < pix->numLayers; z++)
|
||||
{
|
||||
for (y = 0; y < pix->height; y += 4)
|
||||
{
|
||||
for (x = 0; x < pix->width; x += 4)
|
||||
{
|
||||
GetAlphaBlock(AlphaBlock, Runner8, pix, x, y);
|
||||
ChooseAlphaEndpoints(AlphaBlock, &a0, &a1);
|
||||
GenAlphaBitMask(a0, a1, AlphaBlock, AlphaBitMask, NULL/*AlphaOut*/);
|
||||
VFS_Write(f, &a0, sizeof(byte));
|
||||
VFS_Write(f, &a1, sizeof(byte));
|
||||
VFS_Write(f, &AlphaBitMask, sizeof(byte) * 6 );
|
||||
GetBlock(Block, Runner16, pix, x, y);
|
||||
ChooseEndpoints(Block, &t0, &t1);
|
||||
ex0 = max(t0, t1);
|
||||
ex1 = min(t0, t1);
|
||||
CorrectEndDXT1(&ex0, &ex1, 0);
|
||||
VFS_Write(f, &ex0, sizeof(word));
|
||||
VFS_Write(f, &ex1, sizeof(word));
|
||||
BitMask = GenBitMask(ex0, ex1, 4, Block, NULL, NULL);
|
||||
VFS_Write(f, &BitMask, sizeof(uint));
|
||||
Count += 16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Runner16 += Image->Width * Image->Height;
|
||||
|
||||
Runner8 += Image->Width * Image->Height;
|
||||
|
||||
}
|
||||
break;
|
||||
Runner16 += pix->width * pix->height;
|
||||
Runner8 += pix->width * pix->height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ifree(Data);
|
||||
ifree(Alpha);
|
||||
} //else no 3dc
|
||||
|
||||
Mem_Free( Data );
|
||||
Mem_Free( Alpha);
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
bool dds_save_image( const char *name, rgbdata_t *pix, int saveformat )
|
||||
{
|
||||
file_t *file;
|
||||
vfile_t *vhandle;
|
||||
|
||||
file = FS_Open( name, "wb" ); // create real file
|
||||
vhandle = VFS_Open( file, "w" ); // create virtual file
|
||||
|
||||
dds_write_header( vhandle, pix, 0, saveformat );
|
||||
if(!dds_compress_dxt( vhandle, saveformat, pix ))
|
||||
{
|
||||
Msg("dds_save_image: can't create dds file\n");
|
||||
return false;
|
||||
}
|
||||
file = VFS_Close( vhandle ); // write buffer into hdd
|
||||
FS_Close( file );
|
||||
|
||||
return true;
|
||||
}
|
|
@ -124,7 +124,7 @@ void Image_GetPaletteD1( void )
|
|||
if(!d1palette_init)
|
||||
{
|
||||
Image_SetPalette( palette_d1, d_8toD1table );
|
||||
d_8toD1table[255] = 247; // 247 is transparent
|
||||
d_8toD1table[247] = 0; // 247 is transparent
|
||||
d1palette_init = true;
|
||||
}
|
||||
d_currentpal = d_8toD1table;
|
||||
|
@ -486,6 +486,77 @@ bool LoadWAL( char *name, char *buffer, int filesize )
|
|||
return FS_AddMipmapToPack( buffer + ofs[0], image_width, image_height );
|
||||
}
|
||||
|
||||
bool LoadFLD( char *name, char *buffer, int filesize )
|
||||
{
|
||||
flat_t flat;
|
||||
vfile_t *f;
|
||||
word column_loop, row_loop;
|
||||
int i, column_offset, pointer_position, first_pos;
|
||||
byte *Data, post, topdelta, length;
|
||||
|
||||
if(filesize < (int)sizeof(flat))
|
||||
{
|
||||
MsgWarn("LoadFLD: file (%s) have invalid size\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// stupid copypaste from DevIL, but it works
|
||||
f = VFS_Create( buffer, filesize );
|
||||
first_pos = VFS_Tell( f );
|
||||
VFS_Read(f, &flat, sizeof(flat));
|
||||
|
||||
image_width = LittleShort( flat.width );
|
||||
image_height = LittleShort( flat.height );
|
||||
flat.desc[0] = LittleShort( flat.desc[0] );
|
||||
flat.desc[1] = LittleShort( flat.desc[1] );
|
||||
if(!Image_ValidSize( name )) return false;
|
||||
Data = (byte *)Mem_Alloc( Sys.imagepool, image_width * image_height );
|
||||
memset( Data, 247, image_width * image_height ); // set default transparency
|
||||
image_num_layers = 1;
|
||||
image_type = PF_RGBA_32;
|
||||
|
||||
for( column_loop = 0; column_loop < image_width; column_loop++ )
|
||||
{
|
||||
VFS_Read(f, &column_offset, sizeof(int));
|
||||
pointer_position = VFS_Tell( f );
|
||||
VFS_Seek( f, first_pos + column_offset, SEEK_SET );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if(VFS_Read(f, &topdelta, 1) != 1) return false;
|
||||
if(topdelta == 255) break;
|
||||
if(VFS_Read(f, &length, 1) != 1) return false;
|
||||
if(VFS_Read(f, &post, 1) != 1) return false;
|
||||
|
||||
for (row_loop = 0; row_loop < length; row_loop++)
|
||||
{
|
||||
if(VFS_Read(f, &post, 1) != 1) return false;
|
||||
if(row_loop + topdelta < image_height)
|
||||
Data[(row_loop + topdelta) * image_width + column_loop] = post;
|
||||
}
|
||||
VFS_Read(f, &post, 1);
|
||||
}
|
||||
VFS_Seek(f, pointer_position, SEEK_SET );
|
||||
}
|
||||
VFS_Close( f );
|
||||
|
||||
// scan for transparency
|
||||
for (i = 0; i < image_width * image_height; i++)
|
||||
{
|
||||
if( Data[i] == 247 )
|
||||
{
|
||||
image_flags |= IMAGE_HAS_ALPHA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Image_GetPaletteD1();
|
||||
FS_AddMipmapToPack( Data, image_width, image_height );
|
||||
Mem_Free( Data );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
LoadLMP
|
||||
|
@ -1843,6 +1914,7 @@ loadformat_t load_formats[] =
|
|||
{"textures/%s%s.%s", "pcx", LoadPCX},
|
||||
{"textures/%s%s.%s", "lmp", LoadLMP},
|
||||
{"textures/%s%s.%s", "fnt", LoadFNT},
|
||||
{"textures/%s%s.%s", "flat",LoadFLD},
|
||||
{"textures/%s%s.%s", "pal", LoadPAL},
|
||||
{"%s%s.%s", "dds", LoadDDS},
|
||||
{"%s%s.%s", "tga", LoadTGA},
|
||||
|
@ -1852,6 +1924,7 @@ loadformat_t load_formats[] =
|
|||
{"%s%s.%s", "pcx", LoadPCX},
|
||||
{"%s%s.%s", "lmp", LoadLMP},
|
||||
{"%s%s.%s", "fnt", LoadFNT},
|
||||
{"%s%s.%s", "flat",LoadFLD},
|
||||
{"%s%s.%s", "pal", LoadPAL},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -2080,7 +2153,7 @@ void FS_FreeImage( rgbdata_t *pack )
|
|||
image_size = 0;
|
||||
}
|
||||
|
||||
bool SaveBMP( const char *filename, byte *data, int width, int height, bool alpha, int imagetype, byte *palette )
|
||||
bool SaveBMP( const char *filename, rgbdata_t *pix )
|
||||
{
|
||||
file_t *pfile = NULL;
|
||||
BITMAPFILEHEADER bmfh;
|
||||
|
@ -2094,23 +2167,24 @@ bool SaveBMP( const char *filename, byte *data, int width, int height, bool alph
|
|||
int i, rc = 0;
|
||||
|
||||
// bogus parameter check
|
||||
if(!palette || !data ) return false;
|
||||
if(!pix->palette || !pix->buffer )
|
||||
return false;
|
||||
|
||||
pfile = FS_Open( filename, "wb");
|
||||
if(!pfile) return false;
|
||||
|
||||
switch( imagetype )
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_INDEXED_24:
|
||||
case PF_INDEXED_32:
|
||||
break;
|
||||
default:
|
||||
MsgWarn("SaveBMP: unsupported image type %s\n", PFDesc[imagetype].name );
|
||||
MsgWarn("SaveBMP: unsupported image type %s\n", PFDesc[pix->type].name );
|
||||
return false;
|
||||
}
|
||||
|
||||
biTrueWidth = ((width + 3) & ~3);
|
||||
cbBmpBits = biTrueWidth * height;
|
||||
biTrueWidth = ((pix->width + 3) & ~3);
|
||||
cbBmpBits = biTrueWidth * pix->height;
|
||||
cbPalBytes = 256 * sizeof( RGBQUAD );
|
||||
|
||||
// Bogus file header check
|
||||
|
@ -2124,9 +2198,9 @@ bool SaveBMP( const char *filename, byte *data, int width, int height, bool alph
|
|||
FS_Write( pfile, &bmfh, sizeof(bmfh));
|
||||
|
||||
// size of structure
|
||||
bmih.biSize = sizeof bmih;
|
||||
bmih.biSize = sizeof(bmih);
|
||||
bmih.biWidth = biTrueWidth;
|
||||
bmih.biHeight = height;
|
||||
bmih.biHeight = pix->height;
|
||||
bmih.biPlanes = 1;
|
||||
bmih.biBitCount = 8;
|
||||
bmih.biCompression = BI_RGB;
|
||||
|
@ -2138,7 +2212,7 @@ bool SaveBMP( const char *filename, byte *data, int width, int height, bool alph
|
|||
|
||||
// Write info header
|
||||
FS_Write( pfile, &bmih, sizeof(bmih));
|
||||
pb = palette;
|
||||
pb = pix->palette;
|
||||
|
||||
// copy over used entries
|
||||
for (i = 0; i < (int)bmih.biClrUsed; i++)
|
||||
|
@ -2154,13 +2228,13 @@ bool SaveBMP( const char *filename, byte *data, int width, int height, bool alph
|
|||
FS_Write( pfile, rgrgbPalette, cbPalBytes );
|
||||
pbBmpBits = Mem_Alloc( Sys.imagepool, cbBmpBits );
|
||||
|
||||
pb = data;
|
||||
pb += (height - 1) * width;
|
||||
pb = pix->buffer;
|
||||
pb += (pix->height - 1) * pix->width;
|
||||
|
||||
for(i = 0; i < bmih.biHeight; i++)
|
||||
{
|
||||
memmove(&pbBmpBits[biTrueWidth * i], pb, width);
|
||||
pb -= width;
|
||||
memmove(&pbBmpBits[biTrueWidth * i], pb, pix->width);
|
||||
pb -= pix->width;
|
||||
}
|
||||
|
||||
// write bitmap bits (remainder of file)
|
||||
|
@ -2175,7 +2249,7 @@ bool SaveBMP( const char *filename, byte *data, int width, int height, bool alph
|
|||
SaveTGA
|
||||
=============
|
||||
*/
|
||||
bool SaveTGA( const char *filename, byte *data, int width, int height, bool alpha, int imagetype, byte *palette )
|
||||
bool SaveTGA( const char *filename, rgbdata_t *pix )
|
||||
{
|
||||
int y, outsize, pixel_size;
|
||||
const byte *bufend, *in;
|
||||
|
@ -2183,44 +2257,44 @@ bool SaveTGA( const char *filename, byte *data, int width, int height, bool alph
|
|||
const char *comment = "Generated by Xash ImageLib\0";
|
||||
char mergedname[MAX_SYSPATH];
|
||||
|
||||
if(alpha) outsize = width * height * 4 + 18 + com_strlen(comment);
|
||||
else outsize = width * height * 3 + 18 + com_strlen(comment);
|
||||
if( pix->flags & IMAGE_HAS_ALPHA ) outsize = pix->width * pix->height * 4 + 18 + com_strlen(comment);
|
||||
else outsize = pix->width * pix->height * 3 + 18 + com_strlen(comment);
|
||||
|
||||
com_strncpy(mergedname, filename, MAX_SYSPATH );
|
||||
if(mergedname[0] == '*') mergedname[0] = '!'; // quake1 issues
|
||||
|
||||
buffer = (byte *)Malloc( outsize );
|
||||
memset (buffer, 0, 18);
|
||||
memset( buffer, 0, 18 );
|
||||
|
||||
// prepare header
|
||||
buffer[0] = com_strlen(comment); // tga comment length
|
||||
buffer[2] = 2; // uncompressed type
|
||||
buffer[12] = (width >> 0) & 0xFF;
|
||||
buffer[13] = (width >> 8) & 0xFF;
|
||||
buffer[14] = (height >> 0) & 0xFF;
|
||||
buffer[15] = (height >> 8) & 0xFF;
|
||||
buffer[16] = alpha ? 32 : 24;
|
||||
buffer[17] = alpha ? 8 : 0; // 8 bits of alpha
|
||||
com_strncpy(buffer + 18, comment, com_strlen(comment));
|
||||
buffer[12] = (pix->width >> 0) & 0xFF;
|
||||
buffer[13] = (pix->width >> 8) & 0xFF;
|
||||
buffer[14] = (pix->height >> 0) & 0xFF;
|
||||
buffer[15] = (pix->height >> 8) & 0xFF;
|
||||
buffer[16] = ( pix->flags & IMAGE_HAS_ALPHA ) ? 32 : 24;
|
||||
buffer[17] = ( pix->flags & IMAGE_HAS_ALPHA ) ? 8 : 0; // 8 bits of alpha
|
||||
com_strncpy( buffer + 18, comment, com_strlen(comment));
|
||||
out = buffer + 18 + com_strlen(comment);
|
||||
|
||||
// get image description
|
||||
switch( imagetype )
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_RGB_24_FLIP:
|
||||
case PF_RGB_24: pixel_size = 3; break;
|
||||
case PF_RGBA_32: pixel_size = 4; break;
|
||||
default:
|
||||
MsgWarn("SaveTGA: unsupported image type %s\n", PFDesc[imagetype].name );
|
||||
MsgWarn("SaveTGA: unsupported image type %s\n", PFDesc[pix->type].name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// flip buffer
|
||||
switch( imagetype )
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_RGB_24_FLIP:
|
||||
// glReadPixels rotating image at 180 degrees, flip it
|
||||
for (in = data; in < data + width * height * pixel_size; in += pixel_size)
|
||||
for (in = pix->buffer; in < pix->buffer + pix->width * pix->height * pixel_size; in += pixel_size)
|
||||
{
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
|
@ -2230,36 +2304,48 @@ bool SaveTGA( const char *filename, byte *data, int width, int height, bool alph
|
|||
case PF_RGB_24:
|
||||
case PF_RGBA_32:
|
||||
// swap rgba to bgra and flip upside down
|
||||
for (y = height - 1; y >= 0; y--)
|
||||
for (y = pix->height - 1; y >= 0; y--)
|
||||
{
|
||||
in = data + y * width * pixel_size;
|
||||
bufend = in + width * pixel_size;
|
||||
in = pix->buffer + y * pix->width * pixel_size;
|
||||
bufend = in + pix->width * pixel_size;
|
||||
for ( ;in < bufend; in += pixel_size)
|
||||
{
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
if(alpha) *out++ = in[3];
|
||||
if( pix->flags & IMAGE_HAS_ALPHA )
|
||||
*out++ = in[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MsgDev(D_NOTE, "Writing %s[%d]\n", mergedname, alpha ? 32 : 24 );
|
||||
MsgDev(D_NOTE, "Writing %s[%d]\n", mergedname, (pix->flags & IMAGE_HAS_ALPHA) ? 32 : 24 );
|
||||
FS_WriteFile( mergedname, buffer, outsize );
|
||||
|
||||
Mem_Free( buffer );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
SaveDDS
|
||||
=============
|
||||
*/
|
||||
bool SaveDDS( const char *filename, rgbdata_t *pix )
|
||||
{
|
||||
return dds_save_image( filename, pix, PF_DXT5 ); //FIXME
|
||||
}
|
||||
|
||||
typedef struct saveformat_s
|
||||
{
|
||||
char *formatstring;
|
||||
char *ext;
|
||||
bool (*savefunc)(char *filename, byte *data, int width, int height, bool alpha, int imagetype, byte *pal );
|
||||
bool (*savefunc)( char *filename, rgbdata_t *pix );
|
||||
} saveformat_t;
|
||||
|
||||
saveformat_t save_formats[] =
|
||||
{
|
||||
{"%s%s.%s", "dds", SaveDDS},
|
||||
{"%s%s.%s", "tga", SaveTGA},
|
||||
{"%s%s.%s", "bmp", SaveBMP},
|
||||
{NULL, NULL}
|
||||
|
@ -2278,7 +2364,7 @@ void FS_SaveImage( const char *filename, rgbdata_t *pix )
|
|||
const char *ext = FS_FileExtension( filename );
|
||||
char path[128], savename[128];
|
||||
bool anyformat = !stricmp(ext, "") ? true : false;
|
||||
int i, filesize = 0;
|
||||
int filesize = 0;
|
||||
byte *data;
|
||||
bool has_alpha = false;
|
||||
|
||||
|
@ -2298,7 +2384,7 @@ void FS_SaveImage( const char *filename, rgbdata_t *pix )
|
|||
if( anyformat || !com_stricmp( ext, format->ext ))
|
||||
{
|
||||
com_sprintf( path, format->formatstring, savename, "", format->ext );
|
||||
if( format->savefunc( path, data, pix->width, pix->height, has_alpha, pix->type, pix->palette ))
|
||||
if( format->savefunc( path, pix ))
|
||||
return; // saved
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ FILE *logfile;
|
|||
dll_info_t common_dll = { "common.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t engine_dll = { "engine.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t editor_dll = { "editor.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t idconv_dll = { "comres.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
|
||||
static const char *show_credits = "\n\n\n\n\tCopyright XashXT Group 2007 ©\n\t\
|
||||
All Rights Reserved\n\n\t Visit www.xash.ru\n";
|
||||
|
@ -250,6 +251,16 @@ void Sys_LookupInstance( void )
|
|||
com_strcpy(Sys.log_path, "editor.log" ); // xash3d root directory
|
||||
com_strcpy(Sys.caption, va("Xash3D Editor ver.%g", XASH_VERSION ));
|
||||
}
|
||||
else if(!com_strcmp(Sys.progname, "host_convertor"))
|
||||
{
|
||||
Sys.app_name = HOST_CONVERTOR;
|
||||
Sys.con_readonly = true;
|
||||
Sys.log_active = true; // always create log
|
||||
if(!Sys.debug) Sys.con_showalways = true;
|
||||
Sys.linked_dll = &idconv_dll; // pointer to comres.dll info
|
||||
com_sprintf(Sys.log_path, "%s/convert.log", sys_rootdir ); // same as .exe file
|
||||
com_strcpy(Sys.caption, va("Resource Convertor ver.%g", XASH_VERSION ));
|
||||
}
|
||||
else if(!com_strcmp(Sys.progname, "bsplib"))
|
||||
{
|
||||
Sys.app_name = BSPLIB;
|
||||
|
@ -334,6 +345,7 @@ void Sys_CreateInstance( void )
|
|||
case HOST_NORMAL:
|
||||
case HOST_DEDICATED:
|
||||
case HOST_EDITOR:
|
||||
case HOST_CONVERTOR:
|
||||
case BSPLIB:
|
||||
case QCCLIB:
|
||||
case ROQLIB:
|
||||
|
@ -377,6 +389,7 @@ void Sys_CreateInstance( void )
|
|||
break;
|
||||
case HOST_EDITOR:
|
||||
Con_ShowConsole( false );
|
||||
case HOST_CONVERTOR:
|
||||
case BSPLIB:
|
||||
case QCCLIB:
|
||||
case ROQLIB:
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) XashXT Group 2007
|
||||
//=======================================================================
|
||||
|
||||
#include "../rundll.h"
|
||||
|
||||
Run32( host_convertor );
|
|
@ -0,0 +1,28 @@
|
|||
#include <winver.h>
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define VER_FILEVERSION 0,1
|
||||
#define VER_FILEVERSION_STR "0.1"
|
||||
#define VER_PRODUCTVERSION 0,1
|
||||
#define VER_PRODUCTVERSION_STR "0.1"
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FF_PRERELEASE | VS_FF_PATCHED
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
#define VER_COMPANYNAME_STR "XashXT Group"
|
||||
#define VER_LEGALCOPYRIGHT_STR "XashXT 2007"
|
||||
#define VER_PRODUCTNAME_STR "idconv"
|
||||
|
||||
#define VER_ANSICP
|
||||
|
||||
#define VER_FILEDESCRIPTION_STR "Doom\Quake\Hl Convertor"
|
||||
#define VER_ORIGINALFILENAME_STR "idconv.exe"
|
||||
#define VER_INTERNALNAME_STR "host_convertor"
|
||||
|
||||
#include <common.ver>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "tool.ico"
|
|
@ -0,0 +1,28 @@
|
|||
#=============================
|
||||
# Makefile to build xash utils
|
||||
# Author: Unkle Mike <xash.ru>
|
||||
#
|
||||
# Please associate .nmake files as NMAKE.EXE "/f" "%1" for build this file
|
||||
#=============================
|
||||
|
||||
!include <win32.mak>
|
||||
|
||||
MAINTARGET = idconv
|
||||
OBJS = $(MAINTARGET).obj
|
||||
RES = $(MAINTARGET).rc
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj idconv.res
|
||||
$(link) $(OBJS) idconv.res /out:"idconv.exe" /subsystem:windows /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
@echo ‘ª®¯¨à®¢ ® ä ©«®¢: 1.
|
||||
clean:
|
||||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
idconv.res : idconv.rc
|
||||
$(RC) $(RCFLAGS) /r idconv.rc
|
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -136,6 +136,10 @@ SOURCE=.\common\filesystem.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\image_save.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\imglib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -20,6 +20,10 @@ cd ..
|
|||
cd imglib
|
||||
makefile.nmake
|
||||
|
||||
cd ..
|
||||
cd idconv
|
||||
makefile.nmake
|
||||
|
||||
cd ..
|
||||
cd install
|
||||
makefile.nmake
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// basefiles.h - xash supported formats
|
||||
//=======================================================================
|
||||
#ifndef BASE_FILES_H
|
||||
#define BASE_FILES_H
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
.aur particle file format
|
||||
==============================================================================
|
||||
*/
|
||||
#define IDAURORAHEADER (('R'<<24)+('U'<<16)+('A'<<8)+'I') // little-endian "IAUR"
|
||||
#define AURORA_VERSION 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width, height;
|
||||
int origin_x, origin_y; // raster coordinates inside pic
|
||||
char name[MAX_SKINNAME]; // name of pcx file
|
||||
} daurframe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int numframes;
|
||||
|
||||
// aurora description
|
||||
float startcolor[3]; // RGBA
|
||||
float finalcolor[3]; // RGBA
|
||||
float startalpha; // alpha-value
|
||||
float finalalpha;
|
||||
float framerate;
|
||||
byte rendermode;
|
||||
|
||||
|
||||
dsprframe_t frames[1]; // variable sized
|
||||
} daurora_t;
|
||||
|
||||
#endif//BASE_FILES_H
|
|
@ -131,6 +131,7 @@ enum host_state
|
|||
HOST_OFFLINE = 0, // host_init( funcname *arg ) same much as:
|
||||
HOST_NORMAL, // "host_shared"
|
||||
HOST_DEDICATED, // "host_dedicated"
|
||||
HOST_CONVERTOR, // "host_convertor"
|
||||
HOST_EDITOR, // "host_editor"
|
||||
BSPLIB, // "bsplib"
|
||||
IMGLIB, // "imglib"
|
||||
|
|
|
@ -1544,6 +1544,20 @@ typedef struct wal_s
|
|||
|
||||
.LMP image format (Quake1 gfx lumps)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct flat_s
|
||||
{
|
||||
short width;
|
||||
short height;
|
||||
short desc[2]; // probably not used
|
||||
} flat_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.LMP image format (Quake1 gfx lumps)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct lmp_s
|
||||
|
|
12
xash.dsw
12
xash.dsw
|
@ -15,6 +15,18 @@ Package=<4>
|
|||
|
||||
###############################################################################
|
||||
|
||||
Project: "comres"=".\comres\comres.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "editor"=".\editor\editor.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
|
|
Reference in New Issue