09 Aug 2008
This commit is contained in:
parent
ac89e87d67
commit
1a8fe4546e
|
@ -36,4 +36,3 @@ launch\sprite\
|
|||
launch\studio\
|
||||
launch\viewer\
|
||||
launch\extragen\
|
||||
launch\uninstall\
|
|
@ -16,14 +16,16 @@
|
|||
dsprite_t sprite;
|
||||
byte *spritepool;
|
||||
byte *sprite_pal;
|
||||
byte *frame_buffer;
|
||||
int frame_width;
|
||||
int frame_height;
|
||||
rgbdata_t *frame = NULL;
|
||||
char spriteoutname[MAX_SYSPATH];
|
||||
float frameinterval;
|
||||
int framecount;
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
bool need_resample;
|
||||
bool ignore_resample;
|
||||
int resample_w;
|
||||
int resample_h;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -231,6 +233,36 @@ void Cmd_Framerate( void )
|
|||
frameinterval = bound( MIN_INTERVAL, (1.0f/framerate), MAX_INTERVAL );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Resample
|
||||
|
||||
syntax: "$resample <w h>"
|
||||
===============
|
||||
*/
|
||||
void Cmd_Resample( void )
|
||||
{
|
||||
if(Com_TryToken())
|
||||
{
|
||||
resample_w = com.atoi( com_token );
|
||||
resample_h = com.atoi(Com_GetToken( false ));
|
||||
}
|
||||
else resample_w = resample_h = 0; // Image_Resample will be found nearest pow2
|
||||
if(!ignore_resample ) need_resample = true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_NoResample
|
||||
|
||||
syntax: "$noresample"
|
||||
===============
|
||||
*/
|
||||
void Cmd_NoResample( void )
|
||||
{
|
||||
ignore_resample = true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Load
|
||||
|
@ -242,51 +274,23 @@ void Cmd_Load( void )
|
|||
{
|
||||
char *framename;
|
||||
static byte base_pal[256*3];
|
||||
rgbdata_t *pic;
|
||||
|
||||
framename = Com_GetToken( false );
|
||||
|
||||
pic = FS_LoadImage( framename, error_bmp, error_bmp_size );
|
||||
if( !pic ) Sys_Break( "unable to load %s\n", framename ); // no error.bmp, missing frame...
|
||||
Image_ConvertPalette( pic );
|
||||
|
||||
// copy frame info
|
||||
if( frame_buffer ) Mem_Free( frame_buffer ); // clear previous frame
|
||||
frame_buffer = Mem_Alloc( spritepool, pic->size );
|
||||
if( !sprite_pal ) sprite_pal = Mem_Alloc( spritepool, 768 );// this does nothing :)
|
||||
Mem_Copy( frame_buffer, pic->buffer, pic->size );
|
||||
Mem_Copy( sprite_pal, pic->palette, 768 );
|
||||
frame_width = pic->width;
|
||||
frame_height = pic->height;
|
||||
if( pic ) FS_FreeImage( pic );
|
||||
|
||||
if( sprite.numframes == 0 ) Mem_Copy( base_pal, sprite_pal, sizeof( base_pal ));
|
||||
else if( memcmp( base_pal, sprite_pal, sizeof( base_pal )))
|
||||
if( frame ) FS_FreeImage( frame );
|
||||
frame = FS_LoadImage( framename, error_bmp, error_bmp_size );
|
||||
if( !frame ) Sys_Break( "unable to load %s\n", framename ); // no error.bmp, missing frame...
|
||||
Image_ConvertPalette( frame ); // get 24-bit palettes
|
||||
if( sprite.numframes == 0 ) Mem_Copy( base_pal, frame->palette, sizeof( base_pal ));
|
||||
else if( memcmp( base_pal, frame->palette, sizeof( base_pal )))
|
||||
MsgDev( D_WARN, "Cmd_Load: %s doesn't share a pallette with the previous frame\n", framename );
|
||||
sprite_pal = (byte *)(&base_pal[0]);
|
||||
|
||||
Msg( "grabbing %s\n", framename );
|
||||
if(Com_TryToken())
|
||||
{
|
||||
uint line = frame_width;
|
||||
byte *fout, *fin;
|
||||
int x, y;
|
||||
|
||||
fin = frame_buffer;
|
||||
fout = Mem_Alloc( spritepool, frame_width * frame_height );
|
||||
|
||||
if(Com_MatchToken("flip_x"))
|
||||
{
|
||||
for( y = 0; y < frame_height; y++ )
|
||||
for( x = frame_width - 1; x >= 0; x--)
|
||||
fout[y*line+x] = *fin;
|
||||
}
|
||||
else if(Com_MatchToken("flip_y"))
|
||||
{
|
||||
for( y = frame_height - 1; y >= 0; y-- )
|
||||
for( x = 0; x < frame_width; x++)
|
||||
fout[y*line+x] = *fin;
|
||||
}
|
||||
Mem_Free( frame_buffer );
|
||||
frame_buffer = fout;
|
||||
if(Com_MatchToken("flip_x")) Image_Process( &frame, IMAGE_FLIP_X, true );
|
||||
else if(Com_MatchToken("flip_y")) Image_Process( &frame, IMAGE_FLIP_Y, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,13 +304,15 @@ syntax "$frame xoffset yoffset width height <interval> <origin x> <origin y>"
|
|||
void Cmd_Frame( void )
|
||||
{
|
||||
int x, y, xl, yl, xh, yh, w, h;
|
||||
int org_x, org_y;
|
||||
int pixels, linedelta;
|
||||
bool resampled = false;
|
||||
dframe_t *pframe;
|
||||
byte *fin, *plump;
|
||||
|
||||
if( !frame_buffer ) Sys_Break( "frame not loaded\n" );
|
||||
if( !frame || !frame->buffer ) Sys_Break( "frame not loaded\n" );
|
||||
if( framecount >= MAX_FRAMES ) Sys_Break( "too many frames in package\n" );
|
||||
pixels = frame_width * frame_height;
|
||||
pixels = frame->width * frame->height;
|
||||
xl = com.atoi(Com_GetToken(false));
|
||||
yl = com.atoi(Com_GetToken(false));
|
||||
w = com.atoi(Com_GetToken(false));
|
||||
|
@ -314,26 +320,13 @@ void Cmd_Frame( void )
|
|||
|
||||
if((xl & 0x07)||(yl & 0x07)||(w & 0x07)||(h & 0x07))
|
||||
{
|
||||
// render will be resampled image, just throw warning
|
||||
MsgDev( D_WARN, "frame dimensions not multiples of 8\n" );
|
||||
if( need_resample )
|
||||
resampled = Image_Resample( &frame, resample_w, resample_h, true );
|
||||
MsgDev( D_NOTE, "frame dimensions not multiples of 8\n" );
|
||||
}
|
||||
if((w > MAX_FRAME_DIM) || (h > MAX_FRAME_DIM))
|
||||
Sys_Break( "sprite has a dimension longer than %d\n", MAX_FRAME_DIM );
|
||||
|
||||
if((w > frame_width) || (h > frame_height))
|
||||
{
|
||||
w = frame_width;
|
||||
h = frame_height;
|
||||
MsgDev( D_WARN, "frame size [%ix%i] longer than image [%ix%i]\n", w, h, frame_width, frame_height );
|
||||
}
|
||||
xh = xl + w;
|
||||
yh = yl + h;
|
||||
|
||||
plump = (byte *)Mem_Alloc( spritepool, sizeof(dframe_t) + (w * h));
|
||||
pframe = (dframe_t *)plump;
|
||||
frames[framecount].pdata = plump;
|
||||
frames[framecount].type = SPR_SINGLE;
|
||||
|
||||
// get interval
|
||||
if( Com_TryToken())
|
||||
{
|
||||
|
@ -349,25 +342,48 @@ void Cmd_Frame( void )
|
|||
// use default interval
|
||||
frames[framecount].interval = (float)0.05f;
|
||||
}
|
||||
|
||||
|
||||
if(Com_TryToken())
|
||||
{
|
||||
pframe->origin[0] = -com.atoi(com_token);
|
||||
pframe->origin[1] = com.atoi(Com_GetToken(false));
|
||||
org_x = -com.atoi(com_token);
|
||||
org_y = com.atoi(Com_GetToken(false));
|
||||
}
|
||||
else if((origin_x != 0) && (origin_y != 0))
|
||||
{
|
||||
// write shared origin
|
||||
pframe->origin[0] = -origin_x;
|
||||
pframe->origin[1] = origin_y;
|
||||
org_x = -origin_x;
|
||||
org_y = origin_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use center of image
|
||||
pframe->origin[0] = -(w>>1);
|
||||
pframe->origin[1] = h>>1;
|
||||
org_x = -(w>>1);
|
||||
org_y = h>>1;
|
||||
}
|
||||
|
||||
// merge all sprite info
|
||||
if( need_resample && resampled )
|
||||
{
|
||||
// check for org[n] == size[n] and org[n] == size[n]/2
|
||||
// another cases will be not changed
|
||||
if( org_x == -w ) org_x = -frame->width;
|
||||
else if( org_x == -(w>>1)) org_x = -frame->width>>1;
|
||||
if( org_y == h ) org_y = frame->height;
|
||||
else if( org_y == (h>>1)) org_y = frame->height>>1;
|
||||
w = frame->width;
|
||||
h = frame->height;
|
||||
}
|
||||
|
||||
xh = xl + w;
|
||||
yh = yl + h;
|
||||
|
||||
plump = (byte *)Mem_Alloc( spritepool, sizeof(dframe_t) + (w * h));
|
||||
pframe = (dframe_t *)plump;
|
||||
frames[framecount].pdata = plump;
|
||||
frames[framecount].type = SPR_SINGLE;
|
||||
|
||||
pframe->origin[0] = org_x;
|
||||
pframe->origin[1] = org_y;
|
||||
pframe->width = w;
|
||||
pframe->height = h;
|
||||
|
||||
|
@ -376,9 +392,10 @@ void Cmd_Frame( void )
|
|||
if(h > sprite.bounds[1]) sprite.bounds[1] = h;
|
||||
|
||||
plump = (byte *)(pframe + 1); // move pointer
|
||||
fin = frame_buffer + yl * frame_width + xl;
|
||||
linedelta = frame_width - w;
|
||||
fin = frame->buffer + yl * frame->width + xl;
|
||||
linedelta = frame->width - w;
|
||||
|
||||
// apply scissor to source
|
||||
for( y = yl; y < yh; y++ )
|
||||
{
|
||||
for( x = xl; x < xh; x++ )
|
||||
|
@ -425,6 +442,7 @@ void Cmd_Group( bool angled )
|
|||
groupframe = framecount++;
|
||||
|
||||
frames[groupframe].type = angled ? SPR_ANGLED : SPR_GROUP;
|
||||
need_resample = resample_w = resample_h = 0; // invalidate resample for group
|
||||
frames[groupframe].numgroupframes = 0;
|
||||
|
||||
while( 1 )
|
||||
|
@ -437,7 +455,8 @@ void Cmd_Group( bool angled )
|
|||
if(Com_MatchToken( "{" )) is_started = 1;
|
||||
else if(Com_MatchToken( "}" )) break; // end of group
|
||||
else if(Com_MatchToken( "$framerate" )) Cmd_Framerate();
|
||||
else if(Com_MatchToken("$frame"))
|
||||
else if(Com_MatchToken( "$resample" )) Cmd_Resample();
|
||||
else if(Com_MatchToken( "$frame" ))
|
||||
{
|
||||
Cmd_Frame();
|
||||
frames[groupframe].numgroupframes++;
|
||||
|
@ -458,6 +477,9 @@ void Cmd_Group( bool angled )
|
|||
framecount--, sprite.numframes--;
|
||||
MsgDev(D_WARN, "Cmd_Group: Remove angled group with invalid framecount\n" );
|
||||
}
|
||||
|
||||
// back to single frames, invalidate resample
|
||||
need_resample = resample_w = resample_h = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -529,10 +551,12 @@ bool ParseSpriteScript (void)
|
|||
{
|
||||
ResetSpriteInfo();
|
||||
|
||||
while (1)
|
||||
while( 1 )
|
||||
{
|
||||
if(!Com_GetToken (true)) break;
|
||||
if (Com_MatchToken( "$spritename" )) Cmd_Spritename();
|
||||
else if (Com_MatchToken( "$noresample" )) Cmd_NoResample();
|
||||
else if (Com_MatchToken( "$resample" )) Cmd_Resample();
|
||||
else if (Com_MatchToken( "$texture" )) Cmd_RenderMode();
|
||||
else if (Com_MatchToken( "$facetype" )) Cmd_FaceType();
|
||||
else if (Com_MatchToken( "$origin" )) Cmd_Origin();
|
||||
|
|
|
@ -0,0 +1,573 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// sprlib.c - sprite generator
|
||||
//=======================================================================
|
||||
|
||||
#include "platform.h"
|
||||
#include "byteorder.h"
|
||||
#include "utils.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
#define MAX_FRAMES 512
|
||||
#define MAX_FRAME_DIM 512
|
||||
#define MIN_INTERVAL 0.001f
|
||||
#define MAX_INTERVAL 64.0f
|
||||
|
||||
dsprite_t sprite;
|
||||
byte *spritepool;
|
||||
byte *sprite_pal;
|
||||
byte *frame_buffer;
|
||||
int frame_width;
|
||||
int frame_height;
|
||||
char spriteoutname[MAX_SYSPATH];
|
||||
float frameinterval;
|
||||
int framecount;
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
|
||||
struct
|
||||
{
|
||||
frametype_t type; // single frame or group of frames
|
||||
void *pdata; // either a dspriteframe_t or group info
|
||||
float interval; // only used for frames in groups
|
||||
int numgroupframes; // only used by group headers
|
||||
} frames[MAX_FRAMES];
|
||||
|
||||
/*
|
||||
============
|
||||
WriteFrame
|
||||
============
|
||||
*/
|
||||
void WriteFrame( file_t *f, int framenum )
|
||||
{
|
||||
dframe_t *pframe;
|
||||
|
||||
pframe = (dframe_t *)frames[framenum].pdata;
|
||||
pframe->origin[0] = LittleLong( pframe->origin[0] );
|
||||
pframe->origin[1] = LittleLong( pframe->origin[1] );
|
||||
pframe->width = LittleLong (pframe->width);
|
||||
pframe->height = LittleLong (pframe->height);
|
||||
|
||||
// write frame as 32-bit indexed image
|
||||
FS_Write(f, pframe, sizeof(*pframe));
|
||||
FS_Write(f, (byte *)(pframe + 1), pframe->height * pframe->width );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
WriteSprite
|
||||
============
|
||||
*/
|
||||
void WriteSprite( file_t *f )
|
||||
{
|
||||
int i;
|
||||
short cnt = 256;
|
||||
int curframe = 0;
|
||||
int groupframe = 0;
|
||||
|
||||
// calculate bounding radius
|
||||
sprite.boundingradius = sqrt(((sprite.bounds[0]>>1) * (sprite.bounds[0]>>1))
|
||||
+ ((sprite.bounds[1]>>1) * (sprite.bounds[1]>>1)));
|
||||
|
||||
// write out the sprite header
|
||||
SwapBlock((int *)&sprite, sizeof(dsprite_t));
|
||||
FS_Write( f, &sprite, sizeof(sprite));
|
||||
|
||||
// write out palette (768 bytes)
|
||||
FS_Write( f, (void *)&cnt, sizeof(cnt));
|
||||
FS_Write( f, sprite_pal, cnt * 3 );
|
||||
|
||||
for (i = 0; i < sprite.numframes; i++)
|
||||
{
|
||||
FS_Write( f, &frames[curframe].type, sizeof(frames[curframe].type));
|
||||
if( frames[curframe].type == SPR_SINGLE )
|
||||
{
|
||||
// single (non-grouped) frame
|
||||
WriteFrame( f, curframe );
|
||||
curframe++;
|
||||
}
|
||||
else // angled or sequence
|
||||
{
|
||||
int j, numframes;
|
||||
dspritegroup_t dsgroup;
|
||||
float totinterval;
|
||||
|
||||
groupframe = curframe;
|
||||
curframe++;
|
||||
numframes = frames[groupframe].numgroupframes;
|
||||
|
||||
// set and write the group header
|
||||
dsgroup.numframes = LittleLong( numframes );
|
||||
FS_Write( f, &dsgroup, sizeof(dsgroup));
|
||||
totinterval = 0.0f; // write the interval array
|
||||
|
||||
for( j = 0; j < numframes; j++ )
|
||||
{
|
||||
dspriteinterval_t temp;
|
||||
|
||||
totinterval += frames[groupframe+1+j].interval;
|
||||
temp.interval = LittleFloat(totinterval);
|
||||
FS_Write(f, &temp, sizeof(temp));
|
||||
}
|
||||
for( j = 0; j < numframes; j++ )
|
||||
{
|
||||
WriteFrame(f, curframe);
|
||||
curframe++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
WriteSPRFile
|
||||
==============
|
||||
*/
|
||||
bool WriteSPRFile( void )
|
||||
{
|
||||
file_t *f;
|
||||
uint i, groups = 0, grpframes = 0, sngframes = framecount;
|
||||
|
||||
if( sprite.numframes == 0 )
|
||||
{
|
||||
MsgDev(D_WARN, "WriteSPRFile: ignoring blank sprite %s\n", spriteoutname );
|
||||
return false;
|
||||
}
|
||||
f = FS_Open( spriteoutname, "wb" );
|
||||
Msg("writing %s\n", spriteoutname );
|
||||
WriteSprite( f );
|
||||
FS_Close( f );
|
||||
|
||||
// release framebuffer
|
||||
for( i = 0; i < framecount; i++)
|
||||
{
|
||||
if( frames[i].pdata ) Mem_Free( frames[i].pdata );
|
||||
if( frames[i].numgroupframes )
|
||||
{
|
||||
groups++;
|
||||
sngframes -= frames[i].numgroupframes;
|
||||
grpframes += frames[i].numgroupframes;
|
||||
}
|
||||
}
|
||||
|
||||
// display info about current sprite
|
||||
if( groups )
|
||||
{
|
||||
Msg("%d group%s,", groups, groups > 1 ? "s":"" );
|
||||
Msg(" contain %d frame%s\n", grpframes, grpframes > 1 ? "s":"" );
|
||||
}
|
||||
if( sngframes - groups )
|
||||
Msg("%d ungrouped frame%s\n", sngframes - groups, (sngframes - groups) > 1 ? "s" : "" );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Type
|
||||
|
||||
syntax: "$type preset"
|
||||
===============
|
||||
*/
|
||||
void Cmd_Type( void )
|
||||
{
|
||||
Com_GetToken (false);
|
||||
|
||||
if (Com_MatchToken( "vp_parallel_upright" )) sprite.type = SPR_FWD_PARALLEL_UPRIGHT;
|
||||
else if (Com_MatchToken( "facing_upright" )) sprite.type = SPR_FACING_UPRIGHT;
|
||||
else if (Com_MatchToken( "vp_parallel" )) sprite.type = SPR_FWD_PARALLEL;
|
||||
else if (Com_MatchToken( "oriented" )) sprite.type = SPR_ORIENTED;
|
||||
else if (Com_MatchToken( "vp_parallel_oriented")) sprite.type = SPR_FWD_PARALLEL_ORIENTED;
|
||||
else sprite.type = SPR_FWD_PARALLEL; // default
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_RenderMode
|
||||
|
||||
syntax: "$rendermode preset"
|
||||
===============
|
||||
*/
|
||||
void Cmd_RenderMode( void )
|
||||
{
|
||||
Com_GetToken( false );
|
||||
|
||||
if (Com_MatchToken( "additive")) sprite.texFormat = SPR_ADDITIVE;
|
||||
else if (Com_MatchToken( "normal")) sprite.texFormat = SPR_NORMAL;
|
||||
else if (Com_MatchToken( "indexalpha")) sprite.texFormat = SPR_INDEXALPHA;
|
||||
else if (Com_MatchToken( "alphatest")) sprite.texFormat = SPR_ALPHTEST;
|
||||
else if (Com_MatchToken( "glow")) sprite.texFormat = SPR_ADDGLOW;
|
||||
else sprite.texFormat = SPR_ADDITIVE; // default
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_FaceType
|
||||
|
||||
syntax: "$facetype"
|
||||
==============
|
||||
*/
|
||||
void Cmd_FaceType( void )
|
||||
{
|
||||
Com_GetToken( false );
|
||||
|
||||
if (Com_MatchToken( "normal")) sprite.facetype = SPR_SINGLE_FACE;
|
||||
else if (Com_MatchToken( "twoside")) sprite.facetype = SPR_DOUBLE_FACE;
|
||||
else if (Com_MatchToken( "xcross")) sprite.facetype = SPR_XCROSS_FACE;
|
||||
else sprite.facetype = SPR_SINGLE_FACE; // default
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Framerate
|
||||
|
||||
syntax: "$framerate value"
|
||||
===============
|
||||
*/
|
||||
void Cmd_Framerate( void )
|
||||
{
|
||||
float framerate = com.atof(Com_GetToken(false));
|
||||
if(framerate <= 0.0f) return; // negative framerate not allowed
|
||||
frameinterval = bound( MIN_INTERVAL, (1.0f/framerate), MAX_INTERVAL );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Load
|
||||
|
||||
syntax "$load fire01.bmp"
|
||||
===============
|
||||
*/
|
||||
void Cmd_Load( void )
|
||||
{
|
||||
char *framename;
|
||||
static byte base_pal[256*3];
|
||||
rgbdata_t *pic;
|
||||
|
||||
framename = Com_GetToken( false );
|
||||
|
||||
pic = FS_LoadImage( framename, error_bmp, error_bmp_size );
|
||||
if( !pic ) Sys_Break( "unable to load %s\n", framename ); // no error.bmp, missing frame...
|
||||
Image_ConvertPalette( pic );
|
||||
Msg( "grabbing %s\n", framename );
|
||||
|
||||
if(Com_TryToken())
|
||||
{
|
||||
if(Com_MatchToken("flip_x")) Image_Process( &pic, IMAGE_FLIP_X, true );
|
||||
else if(Com_MatchToken("flip_y")) Image_Process( &pic, IMAGE_FLIP_Y, true );
|
||||
}
|
||||
|
||||
// copy frame info
|
||||
if( frame_buffer ) Mem_Free( frame_buffer ); // clear previous frame
|
||||
frame_buffer = Mem_Alloc( spritepool, pic->size );
|
||||
if( !sprite_pal ) sprite_pal = Mem_Alloc( spritepool, 768 );// this does nothing :)
|
||||
Mem_Copy( frame_buffer, pic->buffer, pic->size );
|
||||
Mem_Copy( sprite_pal, pic->palette, 768 );
|
||||
frame_width = pic->width;
|
||||
frame_height = pic->height;
|
||||
if( sprite.numframes == 0 ) Mem_Copy( base_pal, sprite_pal, sizeof( base_pal ));
|
||||
else if( memcmp( base_pal, sprite_pal, sizeof( base_pal )))
|
||||
MsgDev( D_WARN, "Cmd_Load: %s doesn't share a pallette with the previous frame\n", framename );
|
||||
|
||||
if( pic ) FS_FreeImage( pic );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Frame
|
||||
|
||||
syntax "$frame xoffset yoffset width height <interval> <origin x> <origin y>"
|
||||
===============
|
||||
*/
|
||||
void Cmd_Frame( void )
|
||||
{
|
||||
int x, y, xl, yl, xh, yh, w, h;
|
||||
int pixels, linedelta;
|
||||
dframe_t *pframe;
|
||||
byte *fin, *plump;
|
||||
|
||||
if( !frame_buffer ) Sys_Break( "frame not loaded\n" );
|
||||
if( framecount >= MAX_FRAMES ) Sys_Break( "too many frames in package\n" );
|
||||
pixels = frame_width * frame_height;
|
||||
xl = com.atoi(Com_GetToken(false));
|
||||
yl = com.atoi(Com_GetToken(false));
|
||||
w = com.atoi(Com_GetToken(false));
|
||||
h = com.atoi(Com_GetToken(false));
|
||||
|
||||
if((xl & 0x07)||(yl & 0x07)||(w & 0x07)||(h & 0x07))
|
||||
{
|
||||
// render will be resampled image, just throw warning
|
||||
MsgDev( D_NOTE, "frame dimensions not multiples of 8\n" );
|
||||
}
|
||||
if((w > MAX_FRAME_DIM) || (h > MAX_FRAME_DIM))
|
||||
Sys_Break( "sprite has a dimension longer than %d\n", MAX_FRAME_DIM );
|
||||
|
||||
if((w > frame_width) || (h > frame_height))
|
||||
{
|
||||
w = frame_width;
|
||||
h = frame_height;
|
||||
MsgDev( D_WARN, "frame size [%ix%i] longer than image [%ix%i]\n", w, h, frame_width, frame_height );
|
||||
}
|
||||
xh = xl + w;
|
||||
yh = yl + h;
|
||||
|
||||
plump = (byte *)Mem_Alloc( spritepool, sizeof(dframe_t) + (w * h));
|
||||
pframe = (dframe_t *)plump;
|
||||
frames[framecount].pdata = plump;
|
||||
frames[framecount].type = SPR_SINGLE;
|
||||
|
||||
// get interval
|
||||
if( Com_TryToken())
|
||||
{
|
||||
frames[framecount].interval = bound(MIN_INTERVAL, com.atof(com_token), MAX_INTERVAL );
|
||||
|
||||
}
|
||||
else if( frameinterval != 0 )
|
||||
{
|
||||
frames[framecount].interval = frameinterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use default interval
|
||||
frames[framecount].interval = (float)0.05f;
|
||||
}
|
||||
|
||||
if(Com_TryToken())
|
||||
{
|
||||
pframe->origin[0] = -com.atoi(com_token);
|
||||
pframe->origin[1] = com.atoi(Com_GetToken(false));
|
||||
}
|
||||
else if((origin_x != 0) && (origin_y != 0))
|
||||
{
|
||||
// write shared origin
|
||||
pframe->origin[0] = -origin_x;
|
||||
pframe->origin[1] = origin_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use center of image
|
||||
pframe->origin[0] = -(w>>1);
|
||||
pframe->origin[1] = h>>1;
|
||||
}
|
||||
|
||||
pframe->width = w;
|
||||
pframe->height = h;
|
||||
|
||||
// adjust maxsize
|
||||
if(w > sprite.bounds[0]) sprite.bounds[0] = w;
|
||||
if(h > sprite.bounds[1]) sprite.bounds[1] = h;
|
||||
|
||||
plump = (byte *)(pframe + 1); // move pointer
|
||||
fin = frame_buffer + yl * frame_width + xl;
|
||||
linedelta = frame_width - w;
|
||||
|
||||
for( y = yl; y < yh; y++ )
|
||||
{
|
||||
for( x = xl; x < xh; x++ )
|
||||
*plump++ = *fin++;
|
||||
fin += linedelta;
|
||||
}
|
||||
framecount++;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_SpriteUnknown
|
||||
|
||||
syntax: "blabla"
|
||||
==============
|
||||
*/
|
||||
void Cmd_SpriteUnknown( void )
|
||||
{
|
||||
MsgDev( D_WARN, "Cmd_SpriteUnknown: bad command %s\n", com_token);
|
||||
while(Com_TryToken());
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Group
|
||||
|
||||
syntax:
|
||||
$group or $angled
|
||||
{
|
||||
$load fire01.bmp
|
||||
$frame xoffset yoffset width height <interval> <origin x> <origin y>
|
||||
$load fire02.bmp
|
||||
$frame xoffset yoffset width height <interval> <origin x> <origin y>"
|
||||
$load fire03.bmp
|
||||
$frame xoffset yoffset width height <interval> <origin x> <origin y>
|
||||
}
|
||||
===============
|
||||
*/
|
||||
void Cmd_Group( bool angled )
|
||||
{
|
||||
int groupframe;
|
||||
int is_started = 0;
|
||||
|
||||
groupframe = framecount++;
|
||||
|
||||
frames[groupframe].type = angled ? SPR_ANGLED : SPR_GROUP;
|
||||
frames[groupframe].numgroupframes = 0;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if(!Com_GetToken(true))
|
||||
{
|
||||
if( is_started ) Sys_Break("missing }\n");
|
||||
break;
|
||||
}
|
||||
if(Com_MatchToken( "{" )) is_started = 1;
|
||||
else if(Com_MatchToken( "}" )) break; // end of group
|
||||
else if(Com_MatchToken( "$framerate" )) Cmd_Framerate();
|
||||
else if(Com_MatchToken("$frame"))
|
||||
{
|
||||
Cmd_Frame();
|
||||
frames[groupframe].numgroupframes++;
|
||||
}
|
||||
else if(Com_MatchToken("$load" )) Cmd_Load();
|
||||
else if(is_started) Sys_Break("missing }\n");
|
||||
else Cmd_SpriteUnknown(); // skip unknown commands
|
||||
}
|
||||
if( frames[groupframe].numgroupframes == 0 )
|
||||
{
|
||||
// don't create blank groups, rewind frames
|
||||
framecount--, sprite.numframes--;
|
||||
MsgDev( D_WARN, "Cmd_Group: remove blank group\n" );
|
||||
}
|
||||
else if( angled && frames[groupframe].numgroupframes != 8 )
|
||||
{
|
||||
// don't create blank groups, rewind frames
|
||||
framecount--, sprite.numframes--;
|
||||
MsgDev(D_WARN, "Cmd_Group: Remove angled group with invalid framecount\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Origin
|
||||
|
||||
syntax: $origin "x_pos y_pos"
|
||||
===============
|
||||
*/
|
||||
static void Cmd_Origin( void )
|
||||
{
|
||||
origin_x = com.atoi(Com_GetToken (false));
|
||||
origin_y = com.atoi(Com_GetToken (false));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_Rand
|
||||
|
||||
syntax: $rand
|
||||
===============
|
||||
*/
|
||||
static void Cmd_Rand( void )
|
||||
{
|
||||
sprite.synctype = ST_RAND;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_Spritename
|
||||
|
||||
syntax: "$spritename outname"
|
||||
==============
|
||||
*/
|
||||
void Cmd_Spritename (void)
|
||||
{
|
||||
com.strcpy( spriteoutname, Com_GetToken(false));
|
||||
FS_DefaultExtension( spriteoutname, ".spr" );
|
||||
}
|
||||
|
||||
void ResetSpriteInfo( void )
|
||||
{
|
||||
// set default sprite parms
|
||||
spriteoutname[0] = 0;
|
||||
FS_FileBase(gs_filename, spriteoutname );
|
||||
FS_DefaultExtension( spriteoutname, ".spr" );
|
||||
|
||||
memset (&sprite, 0, sizeof(sprite));
|
||||
memset(frames, 0, sizeof(frames));
|
||||
framecount = origin_x = origin_y = 0;
|
||||
frameinterval = 0.0f;
|
||||
|
||||
sprite.bounds[0] = -9999;
|
||||
sprite.bounds[1] = -9999;
|
||||
sprite.ident = IDSPRITEHEADER;
|
||||
sprite.version = SPRITE_VERSION;
|
||||
sprite.type = SPR_FWD_PARALLEL;
|
||||
sprite.facetype = SPR_SINGLE_FACE;
|
||||
sprite.synctype = ST_SYNC;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
ParseScript
|
||||
===============
|
||||
*/
|
||||
bool ParseSpriteScript (void)
|
||||
{
|
||||
ResetSpriteInfo();
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(!Com_GetToken (true)) break;
|
||||
if (Com_MatchToken( "$spritename" )) Cmd_Spritename();
|
||||
else if (Com_MatchToken( "$texture" )) Cmd_RenderMode();
|
||||
else if (Com_MatchToken( "$facetype" )) Cmd_FaceType();
|
||||
else if (Com_MatchToken( "$origin" )) Cmd_Origin();
|
||||
else if (Com_MatchToken( "$rand" )) Cmd_Rand();
|
||||
else if (Com_MatchToken( "$load" )) Cmd_Load();
|
||||
else if (Com_MatchToken( "$type" )) Cmd_Type();
|
||||
else if (Com_MatchToken( "$frame" ))
|
||||
{
|
||||
Cmd_Frame();
|
||||
sprite.numframes++;
|
||||
}
|
||||
else if (Com_MatchToken( "$group" ))
|
||||
{
|
||||
Cmd_Group( false );
|
||||
sprite.numframes++;
|
||||
}
|
||||
else if (Com_MatchToken( "$angled" ))
|
||||
{
|
||||
Cmd_Group( true );
|
||||
sprite.numframes++;
|
||||
}
|
||||
else if (!Com_ValidScript( QC_SPRITEGEN )) return false;
|
||||
else Cmd_SpriteUnknown();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CompileCurrentSprite( const char *name )
|
||||
{
|
||||
bool load = false;
|
||||
|
||||
if(name) strcpy( gs_filename, name );
|
||||
FS_DefaultExtension( gs_filename, ".qc" );
|
||||
load = Com_LoadScript( gs_filename, NULL, 0 );
|
||||
|
||||
if( load )
|
||||
{
|
||||
if(!ParseSpriteScript())
|
||||
return false;
|
||||
return WriteSPRFile();
|
||||
}
|
||||
|
||||
Msg("%s not found\n", gs_filename );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompileSpriteModel ( byte *mempool, const char *name, byte parms )
|
||||
{
|
||||
if( mempool ) spritepool = mempool;
|
||||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "can't allocate memory pool.\nAbort compilation\n");
|
||||
return false;
|
||||
}
|
||||
return CompileCurrentSprite( name );
|
||||
}
|
|
@ -92,7 +92,7 @@ bool Com_ValidScript( int scripttype )
|
|||
Msg("%s probably spritegen qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
}
|
||||
else if (Com_MatchToken("$frame") && scripttype != QC_SPRITEGEN )
|
||||
else if (Com_MatchToken("$resample") && scripttype != QC_SPRITEGEN )
|
||||
{
|
||||
Msg("%s probably spritegen qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
|
@ -107,22 +107,12 @@ bool Com_ValidScript( int scripttype )
|
|||
Msg("%s probably studio qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
}
|
||||
else if(Com_MatchToken( "$videoname" ) && scripttype != QC_ROQLIB )
|
||||
{
|
||||
Msg("%s probably roq movie qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
}
|
||||
else if(Com_MatchToken( "$framemask" ) && scripttype != QC_ROQLIB )
|
||||
{
|
||||
Msg("%s probably roq movie qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
}
|
||||
else if(Com_MatchToken( "$wadname" ) && scripttype != QC_WADLIB )
|
||||
{
|
||||
Msg("%s probably wadlib qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
}
|
||||
else if(Com_MatchToken( "$addlump" ) && scripttype != QC_WADLIB )
|
||||
else if(Com_MatchToken( "$gfxpic" ) && scripttype != QC_WADLIB )
|
||||
{
|
||||
Msg("%s probably wadlib qc.script, skipping...\n", gs_filename );
|
||||
return false;
|
||||
|
@ -134,7 +124,7 @@ void Com_CheckToken( const char *match )
|
|||
{
|
||||
Com_GetToken( true );
|
||||
|
||||
if( Com_MatchToken( match ))
|
||||
if(!Com_MatchToken( match ))
|
||||
{
|
||||
Sys_Break( "\"%s\" not found\n" );
|
||||
}
|
||||
|
|
601
common/wadlib.c
601
common/wadlib.c
|
@ -5,17 +5,131 @@
|
|||
|
||||
#include "platform.h"
|
||||
#include "byteorder.h"
|
||||
#include "mathlib.h"
|
||||
#include "utils.h"
|
||||
|
||||
char wadoutname[MAX_SYSPATH];
|
||||
static dlumpinfo_t wadlumps[MAX_FILES_IN_WAD];
|
||||
static char lumpname[MAX_SYSPATH];
|
||||
dwadinfo_t wadfile; // main header
|
||||
byte *wadpool;
|
||||
int wadheader;
|
||||
int numlumps = 0;
|
||||
bool compress_lumps = false;
|
||||
bool allow_compression = false;
|
||||
float linearpalette[256][3];
|
||||
int color_used[256];
|
||||
float maxdistortion;
|
||||
int colors_used;
|
||||
byte pixdata[256];
|
||||
file_t *handle = NULL;
|
||||
rgbdata_t *image = NULL;
|
||||
vec3_t d_color;
|
||||
|
||||
byte Pal_AddColor( float r, float g, float b )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 255; i++ )
|
||||
{
|
||||
if( !color_used[i] )
|
||||
{
|
||||
linearpalette[i][0] = r;
|
||||
linearpalette[i][1] = g;
|
||||
linearpalette[i][2] = b;
|
||||
if( r < 0.0 ) r = 0.0;
|
||||
if( r > 1.0 ) r = 1.0;
|
||||
image->palette[i*3+0] = pow( r, 1.0 / 2.2) * 255;
|
||||
if( g < 0.0 ) g = 0.0;
|
||||
if( g > 1.0 ) g = 1.0;
|
||||
image->palette[i*3+1] = pow( g, 1.0 / 2.2) * 255;
|
||||
if( b < 0.0 ) b = 0.0;
|
||||
if( b > 1.0 ) b = 1.0;
|
||||
image->palette[i*3+2] = pow( b, 1.0 / 2.2) * 255;
|
||||
color_used[i] = 1;
|
||||
colors_used++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Mip_AveragePixels
|
||||
|
||||
FIXME: share this code by imglib someday
|
||||
=============
|
||||
*/
|
||||
byte Mip_AveragePixels( int count )
|
||||
{
|
||||
float r = 0, g = 0, b = 0;
|
||||
int i, pix, vis = 0;
|
||||
float bestdistortion, distortion;
|
||||
int bestcolor;
|
||||
vec3_t color;
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
pix = pixdata[i];
|
||||
r += linearpalette[pix][0];
|
||||
g += linearpalette[pix][1];
|
||||
b += linearpalette[pix][2];
|
||||
}
|
||||
|
||||
r /= count;
|
||||
g /= count;
|
||||
b /= count;
|
||||
|
||||
r += d_color[0];
|
||||
g += d_color[1];
|
||||
b += d_color[2];
|
||||
|
||||
// find the best color
|
||||
bestdistortion = 3.0;
|
||||
bestcolor = -1;
|
||||
|
||||
for( i = 0; i < 255; i++ )
|
||||
{
|
||||
if( color_used[i] )
|
||||
{
|
||||
pix = i;
|
||||
|
||||
VectorSet( color, r-linearpalette[i][0], g-linearpalette[i][1], b-linearpalette[i][2]);
|
||||
distortion = DotProduct( color, color );
|
||||
if( distortion < bestdistortion )
|
||||
{
|
||||
if( !distortion )
|
||||
{
|
||||
VectorClear( d_color ); // no distortion yet
|
||||
return pix; // perfect match
|
||||
}
|
||||
|
||||
bestdistortion = distortion;
|
||||
bestcolor = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( bestdistortion > 0.001 && colors_used < 255 )
|
||||
{
|
||||
bestcolor = Pal_AddColor( r, g, b );
|
||||
VectorClear( d_color );
|
||||
bestdistortion = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// error diffusion
|
||||
d_color[0] = r - linearpalette[bestcolor][0];
|
||||
d_color[1] = g - linearpalette[bestcolor][1];
|
||||
d_color[2] = b - linearpalette[bestcolor][2];
|
||||
}
|
||||
|
||||
if( bestdistortion > maxdistortion )
|
||||
maxdistortion = bestdistortion;
|
||||
|
||||
// index in palette (new or completely matched)
|
||||
return bestcolor;
|
||||
}
|
||||
|
||||
void Wad3_NewWad( void )
|
||||
{
|
||||
|
@ -27,40 +141,15 @@ void Wad3_NewWad( void )
|
|||
numlumps = 0;
|
||||
}
|
||||
|
||||
int Lump_GetFileType( const char *name, byte *buf )
|
||||
{
|
||||
const char *ext = FS_FileExtension( name );
|
||||
|
||||
if(!buf) return TYPE_NONE;
|
||||
|
||||
// otherwise get file type by extension
|
||||
if(!com.stricmp( ext, "mip" )) return TYPE_MIPTEX2; // half-life texture
|
||||
else if(!com.stricmp( ext, "lmp" )) return TYPE_QPIC; // hud pics
|
||||
else if(!com.stricmp( ext, "pal" )) return TYPE_QPAL; // palette
|
||||
else if(!com.stricmp( ext, "txt" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "aur" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "lst" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "qc" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "qh" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "c" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "h" )) return TYPE_SCRIPT; // text file
|
||||
else if(!com.stricmp( ext, "dat" )) return TYPE_VPROGS; // qc progs
|
||||
else if(!com.stricmp( ext, "raw" )) return TYPE_RAW; // raw data
|
||||
|
||||
// no compares found
|
||||
return TYPE_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
AddLump
|
||||
===============
|
||||
*/
|
||||
void Wad3_AddLump( const char *name, bool compress )
|
||||
void Wad3_AddLump( const byte *buffer, size_t lumpsize, int lump_type, bool compress )
|
||||
{
|
||||
dlumpinfo_t *info;
|
||||
byte *buffer;
|
||||
int ofs, type, length;
|
||||
int ofs;
|
||||
|
||||
if( numlumps >= MAX_FILES_IN_WAD )
|
||||
{
|
||||
|
@ -69,24 +158,9 @@ void Wad3_AddLump( const char *name, bool compress )
|
|||
}
|
||||
|
||||
// we can load file from another wad
|
||||
buffer = FS_LoadFile( name, &length );
|
||||
type = Lump_GetFileType( name, buffer );
|
||||
|
||||
if(!buffer)
|
||||
if( !buffer || !lumpsize )
|
||||
{
|
||||
MsgDev( D_ERROR, "Wad3_AddLump: file %s not found\n", name );
|
||||
return;
|
||||
}
|
||||
if(type == TYPE_NONE)
|
||||
{
|
||||
MsgDev( D_ERROR, "Wad3_AddLump: file %s have unsupported type\n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
FS_FileBase( name, lumpname );
|
||||
if(com.strlen(lumpname) > WAD3_NAMELEN)
|
||||
{
|
||||
MsgDev( D_ERROR, "Wad3_AddLump: %s have too long name, max %d symbols\n", lumpname, WAD3_NAMELEN );
|
||||
MsgDev( D_ERROR, "Wad3_AddLump: file %s not found\n", lumpname );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -94,19 +168,20 @@ void Wad3_AddLump( const char *name, bool compress )
|
|||
if( !handle ) Wad3_NewWad();
|
||||
|
||||
info = &wadlumps[numlumps];
|
||||
|
||||
// lumpname must be prepared with Wad3_CleanupName first!
|
||||
com.strncpy( info->name, lumpname, WAD3_NAMELEN );
|
||||
com.strupr( info->name, info->name );
|
||||
ofs = FS_Tell( handle );
|
||||
info->filepos = LittleLong( ofs );
|
||||
info->type = (char)type;
|
||||
info->type = (char)lump_type;
|
||||
numlumps++; // increase lump number
|
||||
|
||||
if( compress )
|
||||
{
|
||||
vfile_t *h = VFS_Open( handle, "wz" );
|
||||
vfile_t *h = VFS_Open( handle, "wz" );
|
||||
info->compression = CMP_ZLIB;
|
||||
info->size = length; // realsize
|
||||
VFS_Write( h, buffer, length );
|
||||
info->size = lumpsize; // realsize
|
||||
VFS_Write( h, buffer, lumpsize );
|
||||
handle = VFS_Close( h ); // go back to real filesystem
|
||||
ofs = FS_Tell( handle ); // ofs - info->filepos returns compressed size
|
||||
info->disksize = LittleLong( ofs - info->filepos );
|
||||
|
@ -114,70 +189,367 @@ void Wad3_AddLump( const char *name, bool compress )
|
|||
else
|
||||
{
|
||||
info->compression = CMP_NONE;
|
||||
info->size = info->disksize = LittleLong( length );
|
||||
FS_Write( handle, buffer, length ); // just write file
|
||||
info->size = info->disksize = LittleLong( lumpsize );
|
||||
FS_Write( handle, buffer, lumpsize ); // just write file
|
||||
}
|
||||
Mem_Free( buffer );
|
||||
MsgDev(D_INFO, "AddLump: %s, size %d\n", info->name, info->disksize );
|
||||
Msg( "AddLump: %s, size %d\n", info->name, info->disksize );
|
||||
}
|
||||
|
||||
void Wad3_CleanupName( string name, bool havealpha )
|
||||
{
|
||||
string tempname;
|
||||
|
||||
lumpname[0] = '\0';
|
||||
FS_FileBase( name, tempname );
|
||||
if(com.strlen( tempname ) > WAD3_NAMELEN )
|
||||
{
|
||||
// windows style cutoff long names
|
||||
tempname[14] = '~';
|
||||
tempname[15] = '1';
|
||||
}
|
||||
|
||||
// half-life designers probably forget to clear alpha in some "non-alpha" textures :)
|
||||
// rendermode == SOLID it's a greatest hack to avoid transparency for +0BUTTONSUIT, +0C3A1_NRC1 etc
|
||||
|
||||
com.strcat( lumpname, tempname );
|
||||
tempname[16] = '\0'; // cutoff all other
|
||||
|
||||
// and turn big letters
|
||||
com.strupr( lumpname, lumpname );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_GrabMip
|
||||
|
||||
$mipmap filename x y width height
|
||||
==============
|
||||
*/
|
||||
void Cmd_GrabMip( void )
|
||||
{
|
||||
int i, j, x, y, xl, yl, xh, yh, w, h;
|
||||
byte *plump, *screen_p, *source, testpixel;
|
||||
bool resampled = false;
|
||||
int miplevel, mipstep;
|
||||
int xx, yy, count;
|
||||
int linedelta;
|
||||
size_t plump_size;
|
||||
string mipname;
|
||||
byte *lump;
|
||||
mip_t *mip;
|
||||
|
||||
Com_GetToken( false );
|
||||
com.strncpy( mipname, com_token, MAX_STRING );
|
||||
|
||||
// load mip image or replaced with error.bmp
|
||||
image = FS_LoadImage( mipname, error_bmp, error_bmp_size );
|
||||
if( !image )
|
||||
{
|
||||
// no fatal error, just ignore this image for adding into wad-archive
|
||||
MsgDev( D_ERROR, "Cmd_LoadMip: unable to loading %s\n", mipname );
|
||||
return;
|
||||
}
|
||||
|
||||
Wad3_CleanupName( mipname, (image->flags & IMAGE_HAS_ALPHA ));
|
||||
|
||||
Image_ConvertPalette( image ); // turn into 24-bit mode
|
||||
if(Com_TryToken())
|
||||
{
|
||||
xl = com.atoi( com_token );
|
||||
yl = com.atoi(Com_GetToken( false ));
|
||||
w = com.atoi(Com_GetToken( false ));
|
||||
h = com.atoi(Com_GetToken( false ));
|
||||
}
|
||||
else
|
||||
{
|
||||
xl = yl = 0;
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
}
|
||||
|
||||
// just resample image if need
|
||||
if(( w & 15) || (h & 15)) resampled = Image_Resample( &image, 0, 0, true );
|
||||
|
||||
if( resampled )
|
||||
{
|
||||
// updates image size
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
}
|
||||
|
||||
xh = xl + w;
|
||||
yh = yl + h;
|
||||
|
||||
// mip_t + mipmap0[w>>0*h>>0] + mipmap1[w>>1*h>>1] + mipmap2[w>>2*h>>2] + mipmap3[w>>3*h>>3]
|
||||
// + numolors[short] + palette[768];
|
||||
plump_size = (int)sizeof(*mip) + ((w * h * 85)>>6) + sizeof(short) + 768;
|
||||
plump = lump = (byte *)Mem_Alloc( wadpool, plump_size );
|
||||
|
||||
mip = (mip_t *)plump;
|
||||
mip->width = LittleLong( w );
|
||||
mip->height = LittleLong( h );
|
||||
com.strncpy( mip->name, lumpname, WAD3_NAMELEN );
|
||||
plump = (byte *)&mip->offsets[4];
|
||||
|
||||
screen_p = image->buffer + yl * image->width + xl;
|
||||
linedelta = image->width - w;
|
||||
|
||||
source = plump;
|
||||
mip->offsets[0] = LittleLong( plump - (byte *)mip );
|
||||
|
||||
// apply scissor to source
|
||||
for( y = yl; y < yh; y++ )
|
||||
{
|
||||
for( x = xl; x < xh; x++ )
|
||||
*plump++ = *screen_p++;
|
||||
screen_p += linedelta;
|
||||
}
|
||||
|
||||
// calculate gamma corrected linear palette
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
// assume textures are done at 2.2, we want to remap them at 1.0
|
||||
float f = image->palette[i*3+j] / 255.0;
|
||||
linearpalette[i][j] = pow( f, 2.2 );
|
||||
}
|
||||
}
|
||||
|
||||
maxdistortion = 0;
|
||||
if(!(image->flags & IMAGE_HAS_ALPHA ))
|
||||
{
|
||||
// figure out what palette entries are actually used
|
||||
colors_used = 0;
|
||||
memset( color_used, 0, sizeof(int) * 256 );
|
||||
|
||||
for( x = 0; x < w; x++ )
|
||||
{
|
||||
for( y = 0; y < h; y++ )
|
||||
{
|
||||
if(!color_used[source[y * w + x]])
|
||||
{
|
||||
color_used[source[y * w + x]] = 1;
|
||||
colors_used++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// assume palette full if it's a transparent texture
|
||||
colors_used = 256;
|
||||
memset( color_used, 1, sizeof(int) * 256 );
|
||||
}
|
||||
|
||||
// subsample for greater mip levels
|
||||
for( miplevel = 1; miplevel < 4; miplevel++ )
|
||||
{
|
||||
int pixTest;
|
||||
|
||||
VectorClear( d_color ); // no distortion yet
|
||||
mip->offsets[miplevel] = LittleLong(plump - (byte *)mip);
|
||||
|
||||
mipstep = 1<<miplevel;
|
||||
pixTest = (int)((float)(mipstep * mipstep) * 0.4 ); // 40% of pixels
|
||||
|
||||
for( y = 0; y < h; y += mipstep )
|
||||
{
|
||||
for( x = 0; x < w; x += mipstep )
|
||||
{
|
||||
count = 0;
|
||||
for( yy = 0; yy < mipstep; yy++ )
|
||||
{
|
||||
for( xx = 0; xx < mipstep; xx++ )
|
||||
{
|
||||
testpixel = source[(y + yy) * w + x + xx];
|
||||
|
||||
// if 255 is not transparent, or this isn't
|
||||
// a transparent pixel add it in to the image filter
|
||||
if(!(image->flags & IMAGE_HAS_ALPHA ) || testpixel != 255)
|
||||
{
|
||||
pixdata[count] = testpixel;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// solid pixels account for < 40% of this pixel, make it transparent
|
||||
if( count <= pixTest ) *plump++ = 255;
|
||||
else *plump++ = Mip_AveragePixels( count );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*(word*)plump = 256; // palette size
|
||||
plump += sizeof(short);
|
||||
|
||||
Mem_Copy( plump, image->palette, 768 );
|
||||
plump += 768;
|
||||
|
||||
// write out and release intermediate buffers
|
||||
Wad3_AddLump( lump, plump_size, TYPE_MIPTEX2, false );
|
||||
FS_FreeImage( image );
|
||||
Mem_Free( lump );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_GrabPic
|
||||
|
||||
$gfxpic filename x y width height
|
||||
==============
|
||||
*/
|
||||
void Cmd_GrabPic( void )
|
||||
{
|
||||
int x, y, xl, yl, xh, yh;
|
||||
byte *plump, *lump;
|
||||
size_t plump_size;
|
||||
string picname;
|
||||
lmp_t *pic;
|
||||
|
||||
Com_GetToken( false );
|
||||
com.strncpy( picname, com_token, MAX_STRING );
|
||||
|
||||
// load mip image or replaced with error.bmp
|
||||
image = FS_LoadImage( picname, error_bmp, error_bmp_size );
|
||||
if( !image )
|
||||
{
|
||||
// no fatal error, just ignore this image for adding into wad-archive
|
||||
MsgDev( D_ERROR, "Cmd_LoadPic: unable to loading %s\n", picname );
|
||||
return;
|
||||
}
|
||||
|
||||
Image_ConvertPalette( image ); // turn into 24-bit mode
|
||||
|
||||
if(Com_TryToken())
|
||||
{
|
||||
xl = com.atoi(Com_GetToken( false ));
|
||||
yl = com.atoi(Com_GetToken( false ));
|
||||
xh = xl + com.atoi(Com_GetToken( false ));
|
||||
yh = yl + com.atoi(Com_GetToken( false ));
|
||||
}
|
||||
else
|
||||
{
|
||||
xl = yl = 0;
|
||||
xh = image->width;
|
||||
yh = image->height;
|
||||
}
|
||||
|
||||
Wad3_CleanupName( picname, false ); // don't add { symbol to the final name
|
||||
|
||||
if( xh < xl || yh < yl || xl < 0 || yl < 0 )
|
||||
{
|
||||
xl = yl = 0;
|
||||
xh = image->width;
|
||||
yh = image->height;
|
||||
}
|
||||
|
||||
// lmp_t + picture[w*h] + numolors[short] + palette[768];
|
||||
plump_size = (int)sizeof(*pic) + (xh * yh) + sizeof(short) + 768;
|
||||
plump = lump = (byte *)Mem_Alloc( wadpool, plump_size );
|
||||
pic = (lmp_t *)plump;
|
||||
pic->width = LittleLong( xh - xl );
|
||||
pic->height = LittleLong( yh - yl );
|
||||
|
||||
// apply scissor to source
|
||||
plump = (byte *)(pic + 1);
|
||||
for( y = yl; y < yh; y++ )
|
||||
for( x = xl; x < xh; x++ )
|
||||
*plump++ = (*(image->buffer + (y) * image->width + x));
|
||||
|
||||
*(word*)plump = 256; // palette size
|
||||
plump += sizeof(short);
|
||||
Mem_Copy( plump, image->palette, 768 );
|
||||
plump += 768;
|
||||
|
||||
// write out and release intermediate buffers
|
||||
Wad3_AddLump( lump, plump_size, TYPE_QPIC, false );
|
||||
FS_FreeImage( image );
|
||||
Mem_Free( lump );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_GrabScript
|
||||
|
||||
$script filename
|
||||
==============
|
||||
*/
|
||||
void Cmd_GrabScript( void )
|
||||
{
|
||||
byte *lump;
|
||||
size_t plump_size;
|
||||
string textname;
|
||||
|
||||
Com_GetToken( false );
|
||||
com.strncpy( textname, com_token, MAX_STRING );
|
||||
|
||||
// load mip image or replaced with error.bmp
|
||||
lump = FS_LoadFile( textname, &plump_size );
|
||||
|
||||
if( !lump || !plump_size )
|
||||
{
|
||||
// no fatal error, just ignore this image for adding into wad-archive
|
||||
MsgDev( D_ERROR, "Cmd_LoadScript: unable to loading %s\n", textname );
|
||||
return;
|
||||
}
|
||||
Wad3_CleanupName( textname, false ); // don't add { symbol to the final name
|
||||
|
||||
// write out and release intermediate buffers
|
||||
Wad3_AddLump( lump, plump_size, TYPE_SCRIPT, true ); // always compress text files
|
||||
Mem_Free( lump );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_GrabProgs
|
||||
|
||||
$vprogs filename
|
||||
==============
|
||||
*/
|
||||
void Cmd_GrabProgs( void )
|
||||
{
|
||||
byte *lump;
|
||||
size_t plump_size;
|
||||
string datname;
|
||||
dprograms_t *hdr;
|
||||
|
||||
Com_GetToken( false );
|
||||
com.strncpy( datname, com_token, MAX_STRING );
|
||||
|
||||
// load mip image or replaced with error.bmp
|
||||
lump = FS_LoadFile( datname, &plump_size );
|
||||
|
||||
if( !lump || !plump_size || plump_size < sizeof(dprograms_t))
|
||||
{
|
||||
// no fatal error, just ignore this image for adding into wad-archive
|
||||
MsgDev( D_ERROR, "Cmd_LoadProgs: unable to loading %s\n", datname );
|
||||
return;
|
||||
}
|
||||
// validate progs
|
||||
hdr = (dprograms_t *)lump;
|
||||
|
||||
if( hdr->ident != VPROGSHEADER32 || hdr->version != VPROGS_VERSION )
|
||||
{
|
||||
// no fatal error, just ignore this image for adding into wad-archive
|
||||
MsgDev( D_ERROR, "Cmd_LoadProgs: %s invalid progs version, ignore\n", datname );
|
||||
Mem_Free( lump );
|
||||
return;
|
||||
}
|
||||
Wad3_CleanupName( datname, false ); // don't add { symbol to the final name
|
||||
|
||||
// write out and release intermediate buffers
|
||||
Wad3_AddLump( lump, plump_size, TYPE_VPROGS, !hdr->flags ); // release progs may be already packed
|
||||
Mem_Free( lump );
|
||||
}
|
||||
|
||||
void Cmd_WadName( void )
|
||||
{
|
||||
com.strncpy( wadoutname, Com_GetToken(false), sizeof(wadoutname));
|
||||
FS_StripExtension( wadoutname );
|
||||
FS_DefaultExtension( wadoutname, ".wad" );
|
||||
}
|
||||
|
||||
void Cmd_AddLump( void )
|
||||
{
|
||||
char filename[MAX_SYSPATH];
|
||||
bool compress = false;
|
||||
|
||||
Com_GetToken( false );
|
||||
com.strncpy( filename, com_token, sizeof(filename));
|
||||
|
||||
if( allow_compression )
|
||||
{
|
||||
if(Com_TryToken()) compress = true;
|
||||
if(compress_lumps) compress = true;
|
||||
}
|
||||
|
||||
Wad3_AddLump( filename, compress );
|
||||
}
|
||||
|
||||
void Cmd_AddLumps( void )
|
||||
{
|
||||
int i, compress = false;
|
||||
search_t *t;
|
||||
|
||||
Com_GetToken( false );
|
||||
t = FS_Search( com_token, true );
|
||||
if(!t) return;
|
||||
|
||||
if( allow_compression )
|
||||
{
|
||||
if(Com_TryToken()) compress = true;
|
||||
if(compress_lumps) compress = true;
|
||||
}
|
||||
|
||||
for(i = 0; i < t->numfilenames; i++)
|
||||
{
|
||||
Wad3_AddLump( t->filenames[i], compress );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_WadCompress
|
||||
|
||||
syntax: "$compression"
|
||||
==============
|
||||
*/
|
||||
void Cmd_WadCompress( void )
|
||||
{
|
||||
if( allow_compression )
|
||||
compress_lumps = true;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Cmd_WadUnknown
|
||||
|
@ -196,10 +568,8 @@ void ResetWADInfo( void )
|
|||
FS_FileBase( gs_filename, wadoutname ); // kill path and ext
|
||||
FS_DefaultExtension( wadoutname, ".wad" ); // set new ext
|
||||
|
||||
memset (&wadheader, 0, sizeof(wadheader));
|
||||
memset( &wadheader, 0, sizeof(wadheader));
|
||||
wadheader = IDWAD3HEADER;
|
||||
allow_compression = true;
|
||||
compress_lumps = false;
|
||||
numlumps = 0;
|
||||
handle = NULL;
|
||||
}
|
||||
|
@ -212,15 +582,16 @@ ParseScript
|
|||
bool ParseWADfileScript( void )
|
||||
{
|
||||
ResetWADInfo();
|
||||
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if(!Com_GetToken (true))break;
|
||||
|
||||
if (Com_MatchToken( "$wadname" )) Cmd_WadName();
|
||||
else if (Com_MatchToken( "$compression" )) Cmd_WadCompress();
|
||||
else if (Com_MatchToken( "$addlump" )) Cmd_AddLump();
|
||||
else if (Com_MatchToken( "$addlumps" )) Cmd_AddLumps();
|
||||
else if (Com_MatchToken( "$mipmap" )) Cmd_GrabMip();
|
||||
else if (Com_MatchToken( "$gfxpic" )) Cmd_GrabPic();
|
||||
else if (Com_MatchToken( "$script" )) Cmd_GrabScript();
|
||||
else if (Com_MatchToken( "$vprogs" )) Cmd_GrabProgs();
|
||||
else if (!Com_ValidScript( QC_WADLIB )) return false;
|
||||
else Cmd_WadUnknown();
|
||||
}
|
||||
|
@ -253,7 +624,7 @@ bool BuildCurrentWAD( const char *name )
|
|||
{
|
||||
bool load = false;
|
||||
|
||||
if(name) com.strncpy( gs_filename, name, sizeof(gs_filename));
|
||||
if( name ) com.strncpy( gs_filename, name, sizeof(gs_filename));
|
||||
FS_DefaultExtension( gs_filename, ".qc" );
|
||||
load = Com_LoadScript( gs_filename, NULL, 0 );
|
||||
|
||||
|
@ -270,7 +641,7 @@ bool BuildCurrentWAD( const char *name )
|
|||
|
||||
bool CompileWad3Archive( byte *mempool, const char *name, byte parms )
|
||||
{
|
||||
if(mempool) studiopool = mempool;
|
||||
if( mempool ) wadpool = mempool;
|
||||
else
|
||||
{
|
||||
Msg("Wadlib: can't allocate memory pool.\nAbort compilation\n");
|
||||
|
|
|
@ -146,7 +146,7 @@ void CL_LevelShot_f( void )
|
|||
string checkname;
|
||||
|
||||
// check for exist
|
||||
com.sprintf( checkname, "gfx/background/%s.tga", cl.configstrings[CS_NAME] );
|
||||
com.sprintf( checkname, "gfx/background/%s.png", cl.configstrings[CS_NAME] );
|
||||
if(!FS_FileExists( checkname )) re->ScrShot( checkname, true );
|
||||
else Msg("levelshot for this map already created\nFirst remove old image if you wants do it again\n" );
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
str = MSG_ReadString( msg );
|
||||
|
||||
// get splash name
|
||||
Cvar_Set( "cl_levelshot_name", va("background/%s.tga", str ));
|
||||
Cvar_Set( "cl_levelshot_name", va("background/%s.png", str ));
|
||||
Cvar_SetValue("scr_loading", 0.0f ); // reset progress bar
|
||||
if(!FS_FileExists(va("gfx/%s", Cvar_VariableString("cl_levelshot_name"))))
|
||||
{
|
||||
|
|
|
@ -519,7 +519,7 @@ void Host_Error( const char *error, ... )
|
|||
if( recursive )
|
||||
{
|
||||
Msg("Host_RecursiveError: %s", hosterror2 );
|
||||
com.error( hosterror1 );
|
||||
com.error( va( "%s", hosterror1 ));
|
||||
return; // don't multiple executes
|
||||
}
|
||||
|
||||
|
|
|
@ -622,7 +622,7 @@ FS_FileBase
|
|||
Extracts the base name of a file (no path, no extension, assumes '/' as path separator)
|
||||
============
|
||||
*/
|
||||
void FS_FileBase( const char *in, char *out )
|
||||
void _FS_FileBase( const char *in, char *out, bool kill_backwardslash )
|
||||
{
|
||||
int len, start, end;
|
||||
|
||||
|
@ -639,12 +639,27 @@ void FS_FileBase( const char *in, char *out )
|
|||
|
||||
// Scan backward for '/'
|
||||
start = len - 1;
|
||||
while ( start >= 0 && in[start] != '/' && in[start] != '\\' )
|
||||
start--;
|
||||
|
||||
if ( start < 0 || ( in[start] != '/' && in[start] != '\\' ) )
|
||||
start = 0;
|
||||
else start++;
|
||||
if( kill_backwardslash )
|
||||
{
|
||||
while ( start >= 0 && in[start] != '/' && in[start] != '\\' )
|
||||
start--;
|
||||
|
||||
if ( start < 0 || ( in[start] != '/' && in[start] != '\\' ) )
|
||||
start = 0;
|
||||
else start++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: some doomwads using backward slash as part of animation name
|
||||
// e.g. vile\1, so ignore backward slash for wads
|
||||
while ( start >= 0 && in[start] != '/' )
|
||||
start--;
|
||||
|
||||
if ( start < 0 || in[start] != '/' )
|
||||
start = 0;
|
||||
else start++;
|
||||
}
|
||||
|
||||
// Length of new sting
|
||||
len = end - start + 1;
|
||||
|
@ -654,6 +669,11 @@ void FS_FileBase( const char *in, char *out )
|
|||
out[len] = 0;
|
||||
}
|
||||
|
||||
void FS_FileBase( const char *in, char *out )
|
||||
{
|
||||
_FS_FileBase( in, out, true );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
FS_LoadPackPAK
|
||||
|
@ -838,7 +858,7 @@ static bool FS_AddPack_Fullpath(const char *pakfile, bool *already_loaded, bool
|
|||
if(already_loaded) *already_loaded = false;
|
||||
|
||||
if(!com_stricmp(ext, "pak")) pak = FS_LoadPackPAK (pakfile);
|
||||
else if(!com_stricmp(ext, "pk2")) pak = FS_LoadPackPK2(pakfile);
|
||||
else if(!com_stricmp(ext, "pk2")) pak = FS_LoadPackPK3(pakfile);
|
||||
else if(!com_stricmp(ext, "pk3")) pak = FS_LoadPackPK3(pakfile);
|
||||
else Msg("\"%s\" does not have a pack extension\n", pakfile);
|
||||
|
||||
|
@ -1096,7 +1116,7 @@ static bool FS_AddWad3File( const char *filename )
|
|||
com_strncpy(w->lumps[i].name, doomlumps[i].name, 9 );
|
||||
w->lumps[i].type = TYPE_NONE;
|
||||
w->lumps[i].compression = CMP_NONE;
|
||||
|
||||
|
||||
// textures begin
|
||||
if(!com_stricmp("P_START", w->lumps[i].name ))
|
||||
{
|
||||
|
@ -1113,6 +1133,11 @@ static bool FS_AddWad3File( const char *filename )
|
|||
flat_images = true;
|
||||
continue; // skip identifier
|
||||
}
|
||||
else if (!com_stricmp("P3_START", w->lumps[i].name ))
|
||||
{
|
||||
flat_images = true;
|
||||
continue; // skip identifier
|
||||
}
|
||||
else if(!com_stricmp("S_START", w->lumps[i].name ))
|
||||
{
|
||||
skin_images = true;
|
||||
|
@ -1130,6 +1155,7 @@ static bool FS_AddWad3File( const char *filename )
|
|||
else if(!com_stricmp("P_END", w->lumps[i].name )) flat_images = false;
|
||||
else if(!com_stricmp("P1_END", w->lumps[i].name )) flat_images = false;
|
||||
else if(!com_stricmp("P2_END", w->lumps[i].name )) flat_images = false;
|
||||
else if(!com_stricmp("P3_END", w->lumps[i].name )) flat_images = false;
|
||||
else if(!com_stricmp("S_END", w->lumps[i].name )) skin_images = false;
|
||||
else flmp_images = false;
|
||||
|
||||
|
@ -1165,7 +1191,7 @@ static bool FS_AddWad3File( const char *filename )
|
|||
com_strnlwr(w->lumps[i].name, w->lumps[i].name, sizeof(w->lumps[i].name));
|
||||
}
|
||||
// and leaves the file open
|
||||
MsgDev(D_INFO, "Adding %s wadfile: %s (%i lumps)\n", type, filename, numlumps );
|
||||
MsgDev( D_INFO, "Adding %s wadfile: %s (%i lumps)\n", type, filename, numlumps );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1242,7 +1268,7 @@ const char *FS_FileWithoutPath (const char *in)
|
|||
FS_ExtractFilePath
|
||||
============
|
||||
*/
|
||||
void FS_ExtractFilePath(const char* const path, char* dest)
|
||||
void FS_ExtractFilePath( const char* const path, char* dest )
|
||||
{
|
||||
const char* src;
|
||||
src = path + com_strlen(path) - 1;
|
||||
|
@ -1251,8 +1277,12 @@ void FS_ExtractFilePath(const char* const path, char* dest)
|
|||
while (src != path && !(*(src - 1) == '\\' || *(src - 1) == '/'))
|
||||
src--;
|
||||
|
||||
Mem_Copy(dest, path, src - path);
|
||||
dest[src - path - 1] = 0; // cutoff backslash
|
||||
if( src != path )
|
||||
{
|
||||
Mem_Copy(dest, path, src - path);
|
||||
dest[src - path - 1] = 0; // cutoff backslash
|
||||
}
|
||||
else com_strcpy( dest, "" ); // file without path
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1950,15 +1980,17 @@ static byte *FS_OpenWadFile( const char *name, fs_offset_t *filesizeptr, int mat
|
|||
|
||||
// no wads loaded
|
||||
if(!fs_searchwads) return NULL;
|
||||
|
||||
|
||||
// note: wad images can't have real pathes
|
||||
// so, extarct base name from path
|
||||
FS_FileBase( name, basename );
|
||||
if(filesizeptr) *filesizeptr = 0;
|
||||
_FS_FileBase( name, basename, false );
|
||||
if( filesizeptr ) *filesizeptr = 0;
|
||||
|
||||
MsgDev( D_NOTE, "FS_OpenWadFile: %s\n", basename );
|
||||
|
||||
if(com_strlen(basename) > WAD3_NAMELEN )
|
||||
{
|
||||
Msg("FS_OpenWad3File: %s too long name\n", basename );
|
||||
MsgDev( D_NOTE, "FS_OpenWadFile: %s too long name\n", basename );
|
||||
return NULL;
|
||||
}
|
||||
com_strnlwr( basename, texname, WAD3_NAMELEN );
|
||||
|
@ -2022,13 +2054,13 @@ byte *FS_LoadFileFromWAD( const char *path, fs_offset_t *filesizeptr )
|
|||
{
|
||||
wadtype_t *type;
|
||||
const char *ext = FS_FileExtension( path );
|
||||
bool anyformat = !com_stricmp(ext, "") ? true : false;
|
||||
bool anyformat = !com_stricmp( ext, "" ) ? true : false;
|
||||
byte *f;
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( type = wad_types; type->ext; type++ )
|
||||
{
|
||||
if(anyformat || !com_stricmp( ext, type->ext ))
|
||||
if( anyformat || !com_stricmp( ext, type->ext ))
|
||||
{
|
||||
f = FS_OpenWadFile( path, filesizeptr, type->type );
|
||||
if( f ) return f; // found
|
||||
|
@ -2056,7 +2088,7 @@ file_t* _FS_Open( const char* filepath, const char* mode, bool quiet )
|
|||
{
|
||||
if (FS_CheckNastyPath(filepath, false))
|
||||
{
|
||||
MsgDev( D_ERROR, "FS_Open: (\"%s\", \"%s\"): nasty filename rejected\n", filepath, mode );
|
||||
MsgDev( D_NOTE, "FS_Open: (\"%s\", \"%s\"): nasty filename rejected\n", filepath, mode );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2570,7 +2602,7 @@ byte *FS_LoadFile (const char *path, fs_offset_t *filesizeptr )
|
|||
}
|
||||
else buf = FS_LoadFileFromWAD( path, &filesize );
|
||||
|
||||
if(filesizeptr) *filesizeptr = filesize;
|
||||
if( filesizeptr ) *filesizeptr = filesize;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -2847,16 +2879,27 @@ static search_t *_FS_Search( const char *pattern, int caseinsensitive, int quiet
|
|||
wadfile_t *w; // names will be associated with lump types
|
||||
const char *ext = FS_FileExtension( pattern );
|
||||
bool anyformat = !com_stricmp(ext, "*") ? true : false;
|
||||
char lumpname[MAX_SYSPATH];
|
||||
bool anywadname = true;
|
||||
string lumpname, wadname;
|
||||
|
||||
// using wadname as part of path to file
|
||||
// this pretty solution for "dead" lumps (duplicated files in different wads)
|
||||
FS_FileBase( pattern, lumpname );
|
||||
FS_ExtractFilePath( pattern, wadname );
|
||||
if(com_strlen(wadname))
|
||||
{
|
||||
FS_FileBase( wadname, wadname );
|
||||
anywadname = false;
|
||||
}
|
||||
|
||||
// lookup all wads in list
|
||||
for( k = 0; k < Mem_ArraySize( fs_searchwads ); k++ )
|
||||
{
|
||||
w = (wadfile_t *)Mem_GetElement( fs_searchwads, k );
|
||||
if( !w ) continue;
|
||||
|
||||
if(com_stricmp( wadname, w->name ) && !anywadname )
|
||||
continue;
|
||||
|
||||
for(i = 0; i < (uint)w->numlumps; i++)
|
||||
{
|
||||
for (type = wad_types; type->ext; type++)
|
||||
|
@ -2986,13 +3029,6 @@ void FS_SaveEnvironmentVariables( char *pPath )
|
|||
SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0, SMTO_NORMAL, 10, NULL); // system update message
|
||||
}
|
||||
|
||||
void FS_FreeEnvironmentVariables( void )
|
||||
{
|
||||
// save new path
|
||||
REG_SetValue(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\Environment", "Xash3D", "" );
|
||||
SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0, SMTO_NORMAL, 10, NULL); // system update message
|
||||
}
|
||||
|
||||
static void FS_BuildPath( char *pPath, char *pOut )
|
||||
{
|
||||
// set working directory
|
||||
|
|
|
@ -64,33 +64,6 @@ typedef struct flat_s
|
|||
/*
|
||||
========================================================================
|
||||
|
||||
.LMP image format (Quake1 gfx lumps)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct lmp_s
|
||||
{
|
||||
uint width;
|
||||
uint height;
|
||||
} lmp_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.MIP image format (Quake1 textures)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct mip_s
|
||||
{
|
||||
char name[16];
|
||||
uint width, height;
|
||||
uint offsets[4]; // four mip maps stored
|
||||
} mip_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.BMP image format
|
||||
|
||||
========================================================================
|
||||
|
@ -412,6 +385,7 @@ extern byte *image_rgba; // image pointer (see image_type for details)
|
|||
extern byte *image_palette; // palette pointer
|
||||
extern uint *d_currentpal; // installed version of internal palette
|
||||
extern cvar_t *img_oldformats;
|
||||
extern cvar_t *fs_wadsupport;
|
||||
|
||||
bool Image_AddMipmapToPack( const byte *in, int width, int height, bool expand );
|
||||
void Image_RoundDimensions( int *scaled_width, int *scaled_height );
|
||||
|
@ -460,6 +434,7 @@ bool Image_SavePNG( const char *name, rgbdata_t *pix, int saveformat );
|
|||
// img_utils.c
|
||||
//
|
||||
bool Image_ValidSize( const char *name );
|
||||
bool Image_LumpValidSize( const char *name );
|
||||
bool Image_DecompressDXTC( rgbdata_t **image ); // compilers version of decompressor
|
||||
bool Image_DecompressARGB( rgbdata_t **image );
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ bool Image_LoadBMP( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
|
||||
// fill in unused entires will 0, 0, 0
|
||||
// FIXME: change to 0 0 255 ?
|
||||
for( i = bhdr.colors; i < 256; i++ )
|
||||
{
|
||||
*pb++ = 0;
|
||||
|
@ -133,7 +132,7 @@ bool Image_LoadBMP( const char *name, const byte *buffer, size_t filesize )
|
|||
image_type = PF_INDEXED_32; // scaled up to 32 bit
|
||||
|
||||
// scan for transparency
|
||||
for( i = 0; i < image_size; i++ )
|
||||
for( i = 0; i < image_width * image_height; i++ )
|
||||
{
|
||||
if( pbBmpBits[i] == 255 )
|
||||
{
|
||||
|
@ -160,6 +159,9 @@ bool Image_SaveBMP( const char *name, rgbdata_t *pix, int saveformat )
|
|||
dword biTrueWidth;
|
||||
int i, rc = 0;
|
||||
|
||||
if(FS_FileExists( name ))
|
||||
return false; // already existed
|
||||
|
||||
// bogus parameter check
|
||||
if( !pix->palette || !pix->buffer )
|
||||
return false;
|
||||
|
@ -221,18 +223,27 @@ bool Image_SaveBMP( const char *name, rgbdata_t *pix, int saveformat )
|
|||
else rgrgbPalette[i].rgbReserved = 0;
|
||||
}
|
||||
|
||||
// make last color is 0 0 255, xwad expect this
|
||||
if( pix->flags & IMAGE_HAS_ALPHA )
|
||||
{
|
||||
rgrgbPalette[255].rgbRed = 0x00;
|
||||
rgrgbPalette[255].rgbGreen = 0x00;
|
||||
rgrgbPalette[255].rgbBlue = 0xFF;
|
||||
rgrgbPalette[255].rgbReserved = 0x00;
|
||||
}
|
||||
|
||||
// write palette( bmih.biClrUsed entries )
|
||||
cbPalBytes = bmih.biClrUsed * sizeof( RGBQUAD );
|
||||
FS_Write( pfile, rgrgbPalette, cbPalBytes );
|
||||
pbBmpBits = Mem_Alloc( Sys.imagepool, cbBmpBits );
|
||||
memset( pbBmpBits, 0xFF, cbBmpBits ); // fill buffer with black color
|
||||
|
||||
pb = pix->buffer;
|
||||
pb += (pix->height - 1) * pix->width;
|
||||
|
||||
for( i = 0; i < bmih.biHeight; i++ )
|
||||
{
|
||||
// FIXME: replace with Mem_Move
|
||||
memmove( &pbBmpBits[biTrueWidth * i], pb, pix->width );
|
||||
Mem_Copy( &pbBmpBits[biTrueWidth * i], pb, pix->width );
|
||||
pb -= pix->width;
|
||||
}
|
||||
|
||||
|
|
|
@ -1420,7 +1420,6 @@ word *Image_Compress565( rgbdata_t *pix )
|
|||
switch ( pix->type )
|
||||
{
|
||||
case PF_RGB_24:
|
||||
case PF_RGB_24_FLIP:
|
||||
for (i = 0, j = 0; i < SizeOfData; i += 3, j++)
|
||||
{
|
||||
Data[j] = (pix->buffer[i+0] >> 3) << 11;
|
||||
|
@ -1479,13 +1478,6 @@ byte *Image_Compress88( rgbdata_t *pix )
|
|||
Data[j+1] = pix->buffer[i+0];
|
||||
}
|
||||
break;
|
||||
case PF_RGB_24_FLIP:
|
||||
for (i = 0, j = 0; i < pix->size; i += 3, j += 2)
|
||||
{
|
||||
Data[j+0] = pix->buffer[i+1];
|
||||
Data[j+1] = pix->buffer[i+2];
|
||||
}
|
||||
break;
|
||||
case PF_LUMINANCE:
|
||||
case PF_LUMINANCE_ALPHA:
|
||||
for (i = 0, j = 0; i < pix->size; i++, j += 2)
|
||||
|
@ -1514,21 +1506,6 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
height = pix->height;
|
||||
dst_size = Image_DXTGetLinearSize( saveformat, width, height, 1, 0 );
|
||||
srccomps = PFDesc[pix->type].bpp;
|
||||
|
||||
if( pix->type == PF_RGB_24_FLIP )
|
||||
{
|
||||
int x, y, c;
|
||||
byte *in = pix->buffer;
|
||||
uint line = pix->width * srccomps;
|
||||
|
||||
flip = Mem_Alloc( Sys.imagepool, pix->size ); // alloc src image size
|
||||
for( y = pix->height - 1; y >= 0; y-- )
|
||||
for( x = 0; x < pix->width; x++ )
|
||||
for( c = 0; c < srccomps; c++, in++)
|
||||
flip[y*line+x*srccomps+c] = *in;
|
||||
pix->buffer = flip;
|
||||
}
|
||||
|
||||
blkaddr = dest = Mem_Alloc( Sys.imagepool, dst_size ); // alloc dst image size
|
||||
|
||||
switch( saveformat )
|
||||
|
@ -1836,8 +1813,19 @@ bool Image_LoadDDS( const char *name, const byte *buffer, size_t filesize )
|
|||
|
||||
bool Image_SaveDDS( const char *name, rgbdata_t *pix, int saveformat )
|
||||
{
|
||||
file_t *file = FS_Open( name, "wb" ); // create real file
|
||||
vfile_t *vhandle = VFS_Open( file, "w" ); // create virtual file
|
||||
file_t *file; // real file
|
||||
vfile_t *vhandle; // virtual file
|
||||
|
||||
if(FS_FileExists( name )) return false; // already existed
|
||||
|
||||
file = FS_Open( name, "wb" );
|
||||
if( !file ) return false;
|
||||
vhandle = VFS_Open( file, "w" );
|
||||
if( !vhandle )
|
||||
{
|
||||
FS_Close( file );
|
||||
return false;
|
||||
}
|
||||
|
||||
Image_DXTWriteHeader( vhandle, pix, 0, saveformat );
|
||||
if(!Image_CompressDXT( vhandle, saveformat, pix ))
|
||||
|
|
|
@ -36,9 +36,11 @@ typedef struct loadformat_s
|
|||
|
||||
static loadformat_t load_formats0[] =
|
||||
{
|
||||
{"textures/%s%s.%s", "dds", Image_LoadDDS},
|
||||
{"textures/%s%s.%s", "tga", Image_LoadTGA},
|
||||
{"textures/%s%s.%s", "dds", Image_LoadDDS}, // cubemaps, textures
|
||||
{"textures/%s%s.%s", "png", Image_LoadPNG}, // levelshot save as .png
|
||||
{"textures/%s%s.%s", "tga", Image_LoadTGA}, // all other
|
||||
{"%s%s.%s", "dds", Image_LoadDDS},
|
||||
{"%s%s.%s", "png", Image_LoadPNG},
|
||||
{"%s%s.%s", "tga", Image_LoadTGA},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
@ -253,7 +255,6 @@ void FS_GetImageColor( rgbdata_t *pic )
|
|||
}
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
case PF_RGB_24_FLIP:
|
||||
for( j = 0; j < texels; j++, buffer += 3 )
|
||||
{
|
||||
color[0] += buffer[0];
|
||||
|
@ -315,6 +316,7 @@ rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t buffsi
|
|||
case 1: desired_formats = load_formats1; break; // tga, dds, jpg, png, mip
|
||||
case 2: desired_formats = load_formats2; break; // tga, dds, jpg, png, mip, bmp, pcx, wal, lmp
|
||||
case 3: desired_formats = load_formats3; break; // tga, dds, jpg, png, mip, bmp, pcx, wal, lmp, flat, pal
|
||||
default: desired_formats = load_formats0; break; // tga, dds
|
||||
}
|
||||
break;
|
||||
case HOST_SPRITE:
|
||||
|
@ -343,7 +345,7 @@ rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t buffsi
|
|||
if(!anyformat) MsgDev(D_NOTE, "Note: %s will be loading only with ext .%s\n", loadname, ext );
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = desired_formats; format->formatstring; format++)
|
||||
for( format = desired_formats; format && format->formatstring; format++)
|
||||
{
|
||||
if( anyformat || !com_stricmp(ext, format->ext ))
|
||||
{
|
||||
|
@ -365,7 +367,7 @@ rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t buffsi
|
|||
// maybe it skybox or cubemap ?
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
for( format = desired_formats; format->formatstring; format++ )
|
||||
for( format = desired_formats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( anyformat || !com_stricmp(ext, format->ext ))
|
||||
{
|
||||
|
@ -404,7 +406,7 @@ load_internal:
|
|||
// try to load image from const buffer (e.g. const byte blank_frame )
|
||||
com_strncpy( texname, filename, sizeof(texname) - 1);
|
||||
|
||||
for( format = desired_formats; format->formatstring; format++ )
|
||||
for( format = desired_formats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( anyformat || !com_stricmp( ext, format->ext ))
|
||||
{
|
||||
|
|
251
launch/img_png.c
251
launch/img_png.c
|
@ -3,10 +3,109 @@
|
|||
// img_png.c - png format load & save
|
||||
//=======================================================================
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "launch.h"
|
||||
#include "byteorder.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
#define PNG_LIBPNG_VER_STRING "1.2.4"
|
||||
#define PNG_COLOR_MASK_PALETTE 1
|
||||
#define PNG_COLOR_MASK_COLOR 2
|
||||
#define PNG_COLOR_MASK_ALPHA 4
|
||||
#define PNG_COLOR_TYPE_GRAY 0
|
||||
#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
|
||||
#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
|
||||
#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
|
||||
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
|
||||
#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
|
||||
#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
|
||||
#define PNG_INFO_tRNS 0x0010
|
||||
|
||||
extern void png_set_sig_bytes (void*, int);
|
||||
extern int png_sig_cmp (const byte*, size_t, size_t);
|
||||
extern void* png_create_read_struct (const char*, void*, void*, void*);
|
||||
extern void* png_create_info_struct (void*);
|
||||
extern void png_read_info (void*, void*);
|
||||
extern void png_set_expand (void*);
|
||||
extern void png_set_gray_1_2_4_to_8 (void*);
|
||||
extern void png_set_palette_to_rgb (void*);
|
||||
extern void png_set_tRNS_to_alpha (void*);
|
||||
extern void png_set_gray_to_rgb (void*);
|
||||
extern void png_set_filler (void*, uint, int);
|
||||
extern void png_read_update_info (void*, void*);
|
||||
extern void png_read_image (void*, byte**);
|
||||
extern void png_read_end (void*, void*);
|
||||
extern void png_destroy_read_struct (void**, void**, void**);
|
||||
extern void png_set_read_fn (void*, void*, void*);
|
||||
extern uint png_get_valid (void*, void*, uint);
|
||||
extern uint png_get_rowbytes (void*, void*);
|
||||
extern byte png_get_channels (void*, void*);
|
||||
extern byte png_get_bit_depth (void*, void*);
|
||||
extern uint png_get_IHDR (void*, void*, uint*, uint*, int *, int *, int *, int *, int *);
|
||||
extern char* png_get_libpng_ver (void*);
|
||||
extern void png_set_strip_16 (void*);
|
||||
extern void* png_create_write_struct (const char*, void*, void*, void*);
|
||||
extern void png_set_IHDR (void*, void*, uint, uint, int, int, int, int, int);
|
||||
extern void png_set_write_fn (void*, void*, void*, void* );
|
||||
extern void png_write_image (void*, byte**);
|
||||
extern void png_write_info (void*, void*);
|
||||
extern void png_set_compression_level (void*, int);
|
||||
extern void png_destroy_write_struct (void *, void*);
|
||||
extern void png_init_io (void *, void* );
|
||||
extern void png_write_end (void*, void* );
|
||||
|
||||
// this struct is only used for status information during loading
|
||||
static struct
|
||||
{
|
||||
const byte *tmpBuf;
|
||||
file_t *file;
|
||||
byte ioBuffer[MAX_MSGLEN];
|
||||
int tmpBuflength;
|
||||
int tmpi;
|
||||
uint FRowBytes;
|
||||
byte **FRowPtrs;
|
||||
byte *Data;
|
||||
int BitDepth;
|
||||
int bpp;
|
||||
int color;
|
||||
uint height;
|
||||
uint width;
|
||||
int il; // interlace
|
||||
int cmp;
|
||||
int flt;
|
||||
} png;
|
||||
|
||||
void png_fread( void *unused, byte *data, size_t length )
|
||||
{
|
||||
size_t l = png.tmpBuflength - png.tmpi;
|
||||
|
||||
if( l < length )
|
||||
{
|
||||
MsgDev( D_WARN, "png_fread: overrun by %i bytes\n", length - l );
|
||||
// a read going past the end of the file, fill in the remaining bytes
|
||||
// with 0 just to be consistent
|
||||
memset( data + l, 0, length - l );
|
||||
length = l;
|
||||
}
|
||||
Mem_Copy( data, png.tmpBuf + png.tmpi, length );
|
||||
png.tmpi += (int)length;
|
||||
}
|
||||
|
||||
void png_fwrite( void *file, byte *data, size_t length )
|
||||
{
|
||||
FS_Write( png.file, data, length );
|
||||
}
|
||||
|
||||
void png_error_fn( void *unused, const char *message )
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadPNG: %s\n", message );
|
||||
}
|
||||
|
||||
void png_warning_fn( void *unused, const char *message )
|
||||
{
|
||||
MsgDev( D_WARN, "Image_LoadPNG: %s\n", message );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Image_LoadPNG
|
||||
|
@ -14,7 +113,100 @@ Image_LoadPNG
|
|||
*/
|
||||
bool Image_LoadPNG( const char *name, const byte *buffer, size_t filesize )
|
||||
{
|
||||
return false;
|
||||
uint y;
|
||||
void *fin, *pnginfo;
|
||||
|
||||
// FIXME: register an error handler so that abort() won't be called on error
|
||||
|
||||
if(png_sig_cmp((char*)buffer, 0, filesize ))
|
||||
return false;
|
||||
fin = (void *)png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, (void *)png_error_fn, (void *)png_warning_fn );
|
||||
if( !fin ) return false;
|
||||
|
||||
if(setjmp((int*)fin))
|
||||
{
|
||||
png_destroy_read_struct( &fin, &pnginfo, 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
pnginfo = png_create_info_struct( fin );
|
||||
if( !pnginfo )
|
||||
{
|
||||
png_destroy_read_struct( &fin, &pnginfo, 0 );
|
||||
return false;
|
||||
}
|
||||
png_set_sig_bytes( fin, 0);
|
||||
|
||||
memset(&png, 0, sizeof( png ));
|
||||
png.tmpBuf = buffer;
|
||||
png.tmpBuflength = filesize;
|
||||
png.tmpi = 0;
|
||||
png.color = PNG_COLOR_TYPE_RGB;
|
||||
png_set_read_fn( fin, png.ioBuffer, (void *)png_fread );
|
||||
png_read_info( fin, pnginfo );
|
||||
png_get_IHDR( fin, pnginfo, &png.width, &png.height,&png.BitDepth, &png.color, &png.il, &png.cmp, &png.flt );
|
||||
image_width = png.width;
|
||||
image_height = png.height;
|
||||
|
||||
if(!Image_ValidSize( name ))
|
||||
{
|
||||
png_destroy_read_struct( &fin, &pnginfo, 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( png.color == PNG_COLOR_TYPE_PALETTE )
|
||||
{
|
||||
png_set_palette_to_rgb( fin );
|
||||
png_set_filler( fin, 255, 1 );
|
||||
}
|
||||
|
||||
if( png.color == PNG_COLOR_TYPE_GRAY && png.BitDepth < 8 )
|
||||
png_set_gray_1_2_4_to_8( fin );
|
||||
|
||||
if( png_get_valid( fin, pnginfo, PNG_INFO_tRNS ))
|
||||
png_set_tRNS_to_alpha( fin );
|
||||
|
||||
if( png.BitDepth >= 8 && png.color == PNG_COLOR_TYPE_RGB )
|
||||
png_set_filler( fin, 255, 1 );
|
||||
|
||||
if( png.color == PNG_COLOR_TYPE_GRAY || png.color == PNG_COLOR_TYPE_GRAY_ALPHA )
|
||||
{
|
||||
png_set_gray_to_rgb( fin );
|
||||
png_set_filler( fin, 255, 1 );
|
||||
}
|
||||
|
||||
if( png.BitDepth < 8 ) png_set_expand( fin );
|
||||
else if( png.BitDepth == 16 ) png_set_strip_16( fin );
|
||||
|
||||
png_read_update_info( fin, pnginfo );
|
||||
png.FRowBytes = png_get_rowbytes( fin, pnginfo );
|
||||
png.bpp = png_get_channels( fin, pnginfo );
|
||||
png.FRowPtrs = (byte **)Mem_Alloc( Sys.imagepool, png.height * sizeof(*png.FRowPtrs));
|
||||
|
||||
if( png.FRowPtrs )
|
||||
{
|
||||
png.Data = (byte *)Mem_Alloc( Sys.imagepool, png.height * png.FRowBytes );
|
||||
if( png.Data )
|
||||
{
|
||||
for( y = 0; y < png.height; y++ )
|
||||
png.FRowPtrs[y] = png.Data + y * png.FRowBytes;
|
||||
png_read_image( fin, png.FRowPtrs );
|
||||
}
|
||||
Mem_Free( png.FRowPtrs );
|
||||
}
|
||||
|
||||
png_read_end( fin, pnginfo );
|
||||
png_destroy_read_struct( &fin, &pnginfo, 0 );
|
||||
|
||||
image_size = png.height * png.width * 4;
|
||||
image_type = PF_RGBA_32;
|
||||
image_width = png.width;
|
||||
image_height = png.height;
|
||||
image_rgba = png.Data;
|
||||
image_num_layers = 1;
|
||||
image_num_mips = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -24,5 +216,60 @@ Image_SavePNG
|
|||
*/
|
||||
bool Image_SavePNG( const char *name, rgbdata_t *pix, int saveformat )
|
||||
{
|
||||
return false;
|
||||
void *fin;
|
||||
void *info;
|
||||
byte **row;
|
||||
int i, pixel_size;
|
||||
|
||||
if(FS_FileExists( name )) return false; // already existed
|
||||
|
||||
// get image description
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_RGB_24: pixel_size = 3; break;
|
||||
case PF_RGBA_32: pixel_size = 4; break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "Image_SavePNG: unsupported image type %s\n", PFDesc[pix->type].name );
|
||||
return false;
|
||||
}
|
||||
|
||||
png.file = FS_Open( name, "wb" );
|
||||
if( !png.file ) return false;
|
||||
|
||||
if(!(fin = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL )))
|
||||
{
|
||||
FS_Close( png.file );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!(info = png_create_info_struct( fin )))
|
||||
{
|
||||
png_destroy_write_struct( &fin, NULL );
|
||||
FS_Close( png.file );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(setjmp((int*)fin))
|
||||
{
|
||||
png_destroy_write_struct( &fin, &info );
|
||||
FS_Close( png.file );
|
||||
return false;
|
||||
}
|
||||
|
||||
png_init_io( fin, png.file );
|
||||
png_set_write_fn( fin, png.ioBuffer, (void *)png_fwrite, NULL );
|
||||
png_set_compression_level( fin, 9 ); // Z_BEST_COMPRESSION
|
||||
png_set_IHDR( fin, info, pix->width, pix->height, 8, PNG_COLOR_TYPE_RGB, 0, 0, 0 );
|
||||
png_write_info( fin, info );
|
||||
|
||||
row = Mem_Alloc( Sys.imagepool, pix->height * sizeof(byte*));
|
||||
for( i = 0; i < pix->height; i++ )
|
||||
row[i] = pix->buffer + i * pix->width * pixel_size;
|
||||
png_write_image( fin, row );
|
||||
png_write_end( fin, info );
|
||||
Mem_Free( row );
|
||||
png_destroy_write_struct( &fin, &info );
|
||||
FS_Close( png.file );
|
||||
|
||||
return true;
|
||||
}
|
|
@ -370,7 +370,7 @@ bool Image_SaveTGA( const char *name, rgbdata_t *pix, int saveformat )
|
|||
byte *buffer, *out;
|
||||
const char *comment = "Generated by Xash ImageLib\0";
|
||||
|
||||
if(FS_FileExists(name)) return false; // already existed
|
||||
if(FS_FileExists( name )) return false; // already existed
|
||||
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 );
|
||||
|
||||
|
@ -392,26 +392,16 @@ bool Image_SaveTGA( const char *name, rgbdata_t *pix, int saveformat )
|
|||
// get image description
|
||||
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:
|
||||
MsgDev( D_ERROR, "SaveTGA: unsupported image type %s\n", PFDesc[pix->type].name );
|
||||
MsgDev( D_ERROR, "Image_SaveTGA: unsupported image type %s\n", PFDesc[pix->type].name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// flip buffer
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_RGB_24_FLIP:
|
||||
// glReadPixels rotating image at 180 degrees, flip it
|
||||
for (in = pix->buffer; in < pix->buffer + pix->width * pix->height * pixel_size; in += pixel_size)
|
||||
{
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
}
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
case PF_RGBA_32:
|
||||
// swap rgba to bgra and flip upside down
|
||||
|
|
|
@ -137,6 +137,17 @@ bool Image_ValidSize( const char *name )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Image_LumpValidSize( const char *name )
|
||||
{
|
||||
if( image_width > 640 || image_height > 640 || image_width <= 0 || image_height <= 0 )
|
||||
{
|
||||
if(!com_stristr( name, "#internal" )) // internal errors are silent
|
||||
MsgDev(D_WARN, "Image_LumpValidSize: (%s) dims out of range[%dx%d]\n", name, image_width,image_height );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vec_t Image_NormalizeColor( vec3_t in, vec3_t out )
|
||||
{
|
||||
float max, scale;
|
||||
|
@ -210,7 +221,7 @@ void Image_GetPaletteD1( void )
|
|||
if(!d1palette_init)
|
||||
{
|
||||
Image_SetPalette( palette_d1, d_8toD1table );
|
||||
d_8toD1table[247] = 0; // 247 is transparent
|
||||
d_8toD1table[247] = 0; // Image_LoadFLT will be convert transparency from 247 into 255 color
|
||||
d1palette_init = true;
|
||||
}
|
||||
d_currentpal = d_8toD1table;
|
||||
|
@ -265,7 +276,7 @@ void Image_GetPaletteLMP( const byte *pal, int rendermode )
|
|||
d_8to24table[255] &= LittleLong(0xffffff);
|
||||
d_currentpal = d_8to24table;
|
||||
}
|
||||
else if(rendermode == LUMP_QFONT)
|
||||
else if( rendermode == LUMP_QFONT )
|
||||
{
|
||||
// quake1 base palette and font palette have some diferences
|
||||
Image_SetPalette( palette_q1, d_8to24table );
|
||||
|
@ -281,12 +292,7 @@ void Image_ConvertPalTo24bit( rgbdata_t *pic )
|
|||
byte *converted;
|
||||
int i;
|
||||
|
||||
if( !pic || !pic->buffer )
|
||||
{
|
||||
MsgDev(D_ERROR,"Image_ConvertPalTo24bit: image not loaded\n");
|
||||
return;
|
||||
}
|
||||
if( !pic->palette )
|
||||
if( !pic || !pic->palette )
|
||||
{
|
||||
MsgDev(D_ERROR,"Image_ConvertPalTo24bit: no palette found\n");
|
||||
return;
|
||||
|
@ -742,6 +748,27 @@ void Image_Resample24Nolerp( const void *indata, int inwidth, int inheight, void
|
|||
}
|
||||
}
|
||||
|
||||
void Image_Resample8Nolerp( const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight )
|
||||
{
|
||||
int i, j;
|
||||
byte *in, *inrow;
|
||||
uint frac, fracstep;
|
||||
byte *out = (byte *)outdata;
|
||||
|
||||
in = (byte *)indata;
|
||||
fracstep = inwidth * 0x10000 / outwidth;
|
||||
for( i = 0; i < outheight; i++, out += outwidth )
|
||||
{
|
||||
inrow = in + inwidth*(i*inheight/outheight);
|
||||
frac = fracstep>>1;
|
||||
for( j = 0; j < outwidth; j++ )
|
||||
{
|
||||
out[j] = inrow[frac>>16];
|
||||
frac += fracstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_Resample
|
||||
|
@ -753,14 +780,18 @@ byte *Image_ResampleInternal( const void *indata, int inwidth, int inheight, int
|
|||
byte *outdata;
|
||||
|
||||
// nothing to resample ?
|
||||
if (inwidth == outwidth && inheight == outheight)
|
||||
if( inwidth == outwidth && inheight == outheight )
|
||||
return (byte *)indata;
|
||||
|
||||
// alloc new buffer
|
||||
switch( type )
|
||||
{
|
||||
case PF_INDEXED_24:
|
||||
case PF_INDEXED_32:
|
||||
outdata = (byte *)Mem_Alloc( Sys.imagepool, outwidth * outheight );
|
||||
Image_Resample8Nolerp( indata, inwidth, inheight, outdata, outwidth, outheight );
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
case PF_RGB_24_FLIP:
|
||||
outdata = (byte *)Mem_Alloc( Sys.imagepool, outwidth * outheight * 3 );
|
||||
if( quality ) Image_Resample24Lerp( indata, inwidth, inheight, outdata, outwidth, outheight );
|
||||
else Image_Resample24Nolerp( indata, inwidth, inheight, outdata, outwidth, outheight );
|
||||
|
@ -800,21 +831,10 @@ bool Image_Resample( rgbdata_t **image, int width, int height, bool free_baseima
|
|||
out = Image_ResampleInternal((uint *)pix->buffer, pix->width, pix->height, w, h, pix->type );
|
||||
if( out != pix->buffer )
|
||||
{
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_RGBA_32:
|
||||
pixel = 4;
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
case PF_RGB_24_FLIP:
|
||||
pixel = 3;
|
||||
break;
|
||||
default:
|
||||
pixel = 4;
|
||||
}
|
||||
|
||||
pixel = PFDesc[pix->type].bpp;
|
||||
|
||||
// if image was resampled
|
||||
MsgDev(D_NOTE, "Resample image from[%d x %d] to [%d x %d]\n", pix->width, pix->height, w, h );
|
||||
MsgDev( D_NOTE, "Resample image from[%d x %d] to [%d x %d]\n", pix->width, pix->height, w, h );
|
||||
if( free_baseimage ) Mem_Free( pix->buffer ); // free original image buffer
|
||||
|
||||
// change image params
|
||||
|
@ -830,15 +850,56 @@ bool Image_Resample( rgbdata_t **image, int width, int height, bool free_baseima
|
|||
|
||||
bool Image_Process( rgbdata_t **pix, int adjust_type, bool free_baseimage )
|
||||
{
|
||||
int w, h;
|
||||
int w, h, x, y, c, bpp;
|
||||
rgbdata_t *pic = *pix;
|
||||
|
||||
byte *fout, *fin;
|
||||
uint line;
|
||||
|
||||
// check for buffers
|
||||
if(!pic || !pic->buffer) return false;
|
||||
|
||||
// check for support formats
|
||||
switch( pic->type )
|
||||
{
|
||||
case PF_INDEXED_24:
|
||||
case PF_INDEXED_32:
|
||||
case PF_RGB_24:
|
||||
case PF_RGBA_32:
|
||||
break;
|
||||
default:
|
||||
MsgDev(D_ERROR, "Image_Process: can't processing format %s\n", PFDesc[pic->type].name );
|
||||
return false;
|
||||
}
|
||||
|
||||
bpp = PFDesc[pic->type].bpp;
|
||||
w = pic->width;
|
||||
h = pic->height;
|
||||
line = pic->width * bpp;
|
||||
fin = pic->buffer;
|
||||
fout = Mem_Alloc( Sys.imagepool, w * h * bpp );
|
||||
|
||||
//TODO: implement
|
||||
return false;
|
||||
switch( adjust_type )
|
||||
{
|
||||
case IMAGE_FLIP_X:
|
||||
for( y = 0; y < h; y++ )
|
||||
for( x = w - 1; x >= 0; x-- )
|
||||
for( c = 0; c < bpp; c++, fin++ )
|
||||
fout[y*line+x*bpp+c] = *fin;
|
||||
break;
|
||||
case IMAGE_FLIP_Y:
|
||||
for( y = h - 1; y >= 0; y-- )
|
||||
for( x = 0; x < w; x++ )
|
||||
for( c = 0; c < bpp; c++, fin++ )
|
||||
fout[y*line+x*bpp+c] = *fin;
|
||||
break;
|
||||
default:
|
||||
MsgDev(D_ERROR, "Image_Process: unknown transformation %d\n", adjust_type );
|
||||
break;
|
||||
}
|
||||
|
||||
if( free_baseimage ) Mem_Free( pic->buffer );
|
||||
pic->buffer = fout;
|
||||
*pix = pic;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -16,7 +16,7 @@ bool Image_LoadPAL( const char *name, const byte *buffer, size_t filesize )
|
|||
{
|
||||
if( filesize != 768 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadPAL: file (%s) have invalid size\n", name );
|
||||
MsgDev( D_ERROR, "Image_LoadPAL: (%s) have invalid size (%d should be %d)\n", name, filesize, 768 );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,10 @@ bool Image_LoadPAL( const char *name, const byte *buffer, size_t filesize )
|
|||
Image_CopyPalette32bit();
|
||||
|
||||
image_rgba = NULL; // only palette, not real image
|
||||
image_size = image_width = image_height = 0;
|
||||
image_num_mips = image_num_layers = 0;
|
||||
image_flags = IMAGE_ONLY_PALETTE;
|
||||
image_width = image_height = 0;
|
||||
image_size = 1024;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -82,11 +83,17 @@ bool Image_LoadFLT( const char *name, const byte *buffer, size_t filesize )
|
|||
{
|
||||
flat_t flat;
|
||||
vfile_t *f;
|
||||
byte temp[4];
|
||||
bool result = false;
|
||||
int trans_threshold = 0;
|
||||
word column_loop, row_loop;
|
||||
int i, column_offset, pointer_position, first_pos;
|
||||
byte *Data, post, topdelta, length;
|
||||
|
||||
// wadsupport disabled, so nothing to load
|
||||
if( Sys.app_name == HOST_NORMAL && !fs_wadsupport->integer )
|
||||
return false;
|
||||
|
||||
if(filesize < (int)sizeof(flat))
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadFLAT: file (%s) have invalid size\n", name );
|
||||
|
@ -102,7 +109,7 @@ bool Image_LoadFLT( const char *name, const byte *buffer, size_t filesize )
|
|||
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;
|
||||
if(!Image_LumpValidSize( 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;
|
||||
|
@ -115,14 +122,14 @@ bool Image_LoadFLT( const char *name, const byte *buffer, size_t filesize )
|
|||
|
||||
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;
|
||||
if(VFS_Read(f, &topdelta, 1) != 1) goto img_trunc;
|
||||
if( topdelta == 255 ) break;
|
||||
if(VFS_Read(f, &length, 1) != 1) goto img_trunc;
|
||||
if(VFS_Read(f, &post, 1) != 1) goto img_trunc;
|
||||
|
||||
for (row_loop = 0; row_loop < length; row_loop++)
|
||||
{
|
||||
if(VFS_Read(f, &post, 1) != 1) return false;
|
||||
if(VFS_Read(f, &post, 1) != 1) goto img_trunc;
|
||||
if(row_loop + topdelta < image_height)
|
||||
Data[(row_loop + topdelta) * image_width + column_loop] = post;
|
||||
}
|
||||
|
@ -132,23 +139,40 @@ bool Image_LoadFLT( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
VFS_Close( f );
|
||||
|
||||
// scan for transparency
|
||||
for (i = 0; i < image_width * image_height; i++)
|
||||
// swap colors in image, and check for transparency
|
||||
for( i = 0; i < image_width * image_height; i++ )
|
||||
{
|
||||
if( Data[i] == 247 )
|
||||
{
|
||||
image_flags |= IMAGE_HAS_ALPHA;
|
||||
break;
|
||||
Data[i] = 255;
|
||||
trans_threshold++;
|
||||
}
|
||||
else if( Data[i] == 255 ) Data[i] = 247;
|
||||
}
|
||||
|
||||
// yes it's really transparent texture
|
||||
// otherwise transparency it's product of lazy designers (or painters ?)
|
||||
if( trans_threshold > 10 ) image_flags |= IMAGE_HAS_ALPHA;
|
||||
|
||||
image_type = PF_INDEXED_32; // scaled up to 32-bit
|
||||
Image_GetPaletteD1();
|
||||
|
||||
result = FS_AddMipmapToPack( Data, image_width, image_height, false );
|
||||
Mem_Free( Data );
|
||||
// move 247 color to 255 position
|
||||
if( d_currentpal )
|
||||
{
|
||||
Mem_Copy( temp, &d_currentpal[247], 4 );
|
||||
Mem_Copy( &d_currentpal[247], &d_currentpal[255], 4 );
|
||||
Mem_Copy( &d_currentpal[247], temp, 4 );
|
||||
}
|
||||
|
||||
result = FS_AddMipmapToPack( Data, image_width, image_height, false );
|
||||
if( Data ) Mem_Free( Data );
|
||||
return result;
|
||||
img_trunc:
|
||||
VFS_Close( f );
|
||||
Mem_Free( Data );
|
||||
MsgDev( D_NOTE, "Image_LoadFLAT: probably it's not a .flat image)\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -162,6 +186,10 @@ bool Image_LoadLMP( const char *name, const byte *buffer, size_t filesize )
|
|||
byte *fin, *pal;
|
||||
int pixels;
|
||||
|
||||
// wadsupport disabled, so nothing to load
|
||||
if( Sys.app_name == HOST_NORMAL && !fs_wadsupport->integer )
|
||||
return false;
|
||||
|
||||
if( filesize < (int)sizeof(lmp))
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadLMP: file (%s) have invalid size\n", name );
|
||||
|
@ -182,8 +210,6 @@ bool Image_LoadLMP( const char *name, const byte *buffer, size_t filesize )
|
|||
|
||||
if(!Image_ValidSize( name )) return false;
|
||||
image_num_mips = 1;
|
||||
|
||||
image_rgba = (byte *)Mem_Alloc(Sys.imagepool, image_width * image_height );
|
||||
image_num_layers = 1;
|
||||
|
||||
// half-life 1.0.0.1 lmp version with palette
|
||||
|
@ -196,7 +222,7 @@ bool Image_LoadLMP( const char *name, const byte *buffer, size_t filesize )
|
|||
else pal += sizeof(short);
|
||||
}
|
||||
else pal = NULL;
|
||||
if(fin[0] == 255) image_flags |= IMAGE_HAS_ALPHA;
|
||||
if( fin[0] == 255 ) image_flags |= IMAGE_HAS_ALPHA;
|
||||
|
||||
Image_GetPaletteLMP( pal, LUMP_NORMAL );
|
||||
image_type = PF_INDEXED_32; // scaled up to 32 bit
|
||||
|
@ -215,6 +241,10 @@ bool Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
|
|||
int ofs[4], rendermode;
|
||||
int i, pixels, numcolors;
|
||||
|
||||
// wadsupport disabled, so nothing to load
|
||||
if( Sys.app_name == HOST_NORMAL && !fs_wadsupport->integer )
|
||||
return false;
|
||||
|
||||
if( filesize < (int)sizeof(mip))
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadMIP: file (%s) have invalid size\n", name );
|
||||
|
|
|
@ -54,7 +54,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /opt:nowin98
|
||||
# ADD LINK32 zlib.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
|
||||
# ADD LINK32 zlib.lib png.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\launch\!release
|
||||
InputPath=\Xash3D\src_main\temp\launch\!release\launch.dll
|
||||
|
@ -90,7 +90,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 zlib.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /pdbtype:sept
|
||||
# ADD LINK32 zlib.lib png.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /pdbtype:sept
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\launch\!debug
|
||||
InputPath=\Xash3D\src_main\temp\launch\!debug\launch.dll
|
||||
|
|
|
@ -292,8 +292,7 @@ void FS_DefaultExtension (char *path, const char *extension );
|
|||
bool FS_GetParmFromCmdLine( char *parm, char *out );
|
||||
void FS_ExtractFilePath(const char* const path, char* dest);
|
||||
void FS_UpdateEnvironmentVariables( void );
|
||||
void FS_FreeEnvironmentVariables( void );
|
||||
const char *FS_FileWithoutPath (const char *in);
|
||||
const char *FS_FileWithoutPath( const char *in );
|
||||
extern char sys_rootdir[];
|
||||
extern char *fs_argv[];
|
||||
extern int fs_argc;
|
||||
|
|
|
@ -789,16 +789,20 @@ get token on current or newline
|
|||
*/
|
||||
char *SC_GetToken( bool newline )
|
||||
{
|
||||
if( Sys.app_name == HOST_BSPLIB )
|
||||
switch( Sys.app_name )
|
||||
{
|
||||
case HOST_BSPLIB:
|
||||
case HOST_SPRITE:
|
||||
case HOST_STUDIO:
|
||||
case HOST_WADLIB:
|
||||
// don't handle single characters
|
||||
if(SC_ReadTokenSimple( newline ))
|
||||
return token;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
default:
|
||||
if(SC_ReadToken( newline ))
|
||||
return token;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -328,7 +328,7 @@ strchr
|
|||
find one charcster in string
|
||||
============
|
||||
*/
|
||||
char *com_strchr(const char *s, char c)
|
||||
char *com_strchr( const char *s, char c )
|
||||
{
|
||||
int len = com_strlen(s);
|
||||
|
||||
|
@ -343,7 +343,7 @@ strrchr
|
|||
find one charcster in string
|
||||
============
|
||||
*/
|
||||
char *com_strrchr(const char *s, char c)
|
||||
char *com_strrchr( const char *s, char c )
|
||||
{
|
||||
int len = com_strlen(s);
|
||||
s += len;
|
||||
|
|
|
@ -277,13 +277,6 @@ void Sys_LookupInstance( void )
|
|||
com_strcpy(Sys.caption, "About");
|
||||
Sys.con_showcredits = true;
|
||||
}
|
||||
else if(!com_strcmp(Sys.progname, "uninstall")) // write path into registry
|
||||
{
|
||||
Sys.app_name = HOST_UNINSTALL;
|
||||
Sys.linked_dll = NULL; // no need to loading library
|
||||
Sys.log_active = Sys.developer = Sys.debug = 0; // clear all dbg states
|
||||
Sys.con_silentmode = true;
|
||||
}
|
||||
else if(!com_strcmp(Sys.progname, "normal"))
|
||||
{
|
||||
if( dedicated )
|
||||
|
@ -402,10 +395,6 @@ void Sys_CreateInstance( void )
|
|||
case HOST_CREDITS:
|
||||
Sys_Break( show_credits );
|
||||
break;
|
||||
case HOST_UNINSTALL:
|
||||
FS_FreeEnvironmentVariables();
|
||||
Sys_Exit();
|
||||
break;
|
||||
case HOST_OFFLINE:
|
||||
Sys_Break( "Host offline\n" );
|
||||
break;
|
||||
|
@ -415,7 +404,7 @@ void Sys_CreateInstance( void )
|
|||
Sys.Init( fs_argc, fs_argv );
|
||||
|
||||
// post initializations
|
||||
switch(Sys.app_name)
|
||||
switch( Sys.app_name )
|
||||
{
|
||||
case HOST_NORMAL:
|
||||
Con_ShowConsole( false ); // hide console
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#=============================
|
||||
# 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 = uninstall
|
||||
OBJS = $(MAINTARGET).obj
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj
|
||||
$(link) $(OBJS) /out:"uninstall.exe" /subsystem:windows /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\bin\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
@echo ‘Ş®Ż¨ŕ®˘ ® ä ©«®˘: 1.
|
||||
clean:
|
||||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
|
@ -1,7 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) XashXT Group 2007
|
||||
//=======================================================================
|
||||
|
||||
#include "../rundll.h"
|
||||
|
||||
Run32( uninstall );
|
|
@ -16,7 +16,7 @@ default: $(MAINTARGET).exe
|
|||
$(MAINTARGET).exe: $(MAINTARGET).obj viewer.res
|
||||
$(link) $(OBJS) viewer.res /out:"viewer.exe" /subsystem:windows /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp $(MAINTARGET).res > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\$(MAINTARGET).exe
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
@echo ‘Ş®Ż¨ŕ®˘ ® ä ©«®˘: 1.
|
||||
clean:
|
||||
|
|
|
@ -20,10 +20,6 @@ cd ..
|
|||
cd studio
|
||||
makefile.nmake
|
||||
|
||||
cd ..
|
||||
cd uninstall
|
||||
makefile.nmake
|
||||
|
||||
cd ..
|
||||
cd viewer
|
||||
makefile.nmake
|
||||
|
|
|
@ -82,7 +82,6 @@ CM_FreeModel
|
|||
*/
|
||||
void CM_FreeModel( cmodel_t *mod )
|
||||
{
|
||||
Msg("free model %s\n", mod->name );
|
||||
Mem_FreePool( &mod->mempool );
|
||||
memset( mod, 0, sizeof(*mod));
|
||||
mod = NULL;
|
||||
|
|
|
@ -144,6 +144,34 @@ typedef struct
|
|||
char name[16]; // must be null terminated
|
||||
} dlumpinfo_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.LMP image format (Half-Life gfx.wad lumps)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct lmp_s
|
||||
{
|
||||
uint width;
|
||||
uint height;
|
||||
} lmp_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.MIP image format (half-Life textures)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct mip_s
|
||||
{
|
||||
char name[16];
|
||||
uint width;
|
||||
uint height;
|
||||
uint offsets[4]; // four mip maps stored
|
||||
} mip_t;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
BRUSH MODELS
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//=======================================================================
|
||||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// ref_dllapi.h - shared ifaces between engine parts
|
||||
//=======================================================================
|
||||
|
@ -15,7 +15,6 @@ enum host_state
|
|||
{ // paltform states
|
||||
HOST_OFFLINE = 0, // host_init( g_Instance ) same much as:
|
||||
HOST_CREDITS, // "splash" "©anyname" (easter egg)
|
||||
HOST_UNINSTALL, // "uninstall" "uninstall"
|
||||
HOST_DEDICATED, // "normal" "#gamename"
|
||||
HOST_NORMAL, // "normal" "gamename"
|
||||
HOST_BSPLIB, // "bsplib" "bsplib"
|
||||
|
@ -320,7 +319,6 @@ enum comp_format
|
|||
PF_RGBA_32, // already prepared ".bmp", ".tga" or ".jpg" image
|
||||
PF_ARGB_32, // uncompressed dds image
|
||||
PF_RGB_24, // uncompressed dds or another 24-bit image
|
||||
PF_RGB_24_FLIP, // flip image for screenshots
|
||||
PF_DXT1, // nvidia DXT1 format
|
||||
PF_DXT3, // nvidia DXT3 format
|
||||
PF_DXT5, // nvidia DXT5 format
|
||||
|
@ -347,12 +345,11 @@ typedef struct bpc_desc_s
|
|||
static const bpc_desc_t PFDesc[] =
|
||||
{
|
||||
{PF_UNKNOWN, "raw", 0x1908, 0x1401, 0, 0, 0 },
|
||||
{PF_INDEXED_24, "pal 24", 0x1908, 0x1401, 3, 1, 0 },// expand data to RGBA buffer
|
||||
{PF_INDEXED_32, "pal 32", 0x1908, 0x1401, 4, 1, 0 },
|
||||
{PF_INDEXED_24, "pal 24", 0x1908, 0x1401, 1, 1, 0 },// expand data to RGBA buffer
|
||||
{PF_INDEXED_32, "pal 32", 0x1908, 0x1401, 1, 1, 0 },
|
||||
{PF_RGBA_32, "RGBA 32",0x1908, 0x1401, 4, 1, -4 },
|
||||
{PF_ARGB_32, "ARGB 32",0x1908, 0x1401, 4, 1, -4 },
|
||||
{PF_RGB_24, "RGB 24", 0x1908, 0x1401, 3, 1, -3 },
|
||||
{PF_RGB_24_FLIP, "RGB 24", 0x1908, 0x1401, 3, 1, -3 },
|
||||
{PF_DXT1, "DXT1", 0x1908, 0x1401, 4, 1, 8 },
|
||||
{PF_DXT3, "DXT3", 0x1908, 0x1401, 4, 1, 16 },
|
||||
{PF_DXT5, "DXT5", 0x1908, 0x1401, 4, 1, 16 },
|
||||
|
@ -372,6 +369,12 @@ static const bpc_desc_t PFDesc[] =
|
|||
#define IMAGE_CUBEMAP_FLIP 0x00000010 // it's a cubemap with flipped sides( dds pack )
|
||||
#define IMAGE_ONLY_PALETTE 0x00000020 // image not valid, returns palette only
|
||||
|
||||
enum img_process
|
||||
{
|
||||
IMAGE_FLIP_X = 0,
|
||||
IMAGE_FLIP_Y,
|
||||
};
|
||||
|
||||
typedef struct rgbdata_s
|
||||
{
|
||||
word width; // image width
|
||||
|
|
|
@ -1111,16 +1111,17 @@ bool VID_ScreenShot( const char *filename, bool levelshot )
|
|||
r_shot = Z_Malloc( sizeof(rgbdata_t));
|
||||
r_shot->width = r_width->integer;
|
||||
r_shot->height = r_height->integer;
|
||||
r_shot->type = PF_RGB_24_FLIP;
|
||||
r_shot->hint = PF_RGB_24; // save format
|
||||
r_shot->type = PF_RGB_24;
|
||||
r_shot->hint = PF_DXT5; // save format
|
||||
r_shot->size = r_shot->width * r_shot->height * 3;
|
||||
r_shot->palette = NULL;
|
||||
r_shot->numLayers = 1;
|
||||
r_shot->numMips = 1;
|
||||
r_shot->palette = NULL;
|
||||
r_shot->buffer = r_framebuffer;
|
||||
|
||||
if( levelshot ) Image_Resample( &r_shot, 512, 384, false ); // resample to 512x384
|
||||
else VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // adjust brightness
|
||||
Image_Process( &r_shot, IMAGE_FLIP_Y, false );
|
||||
|
||||
// write image
|
||||
FS_SaveImage( filename, r_shot );
|
||||
|
|
|
@ -904,7 +904,6 @@ void Mod_LoadBrushModel (rmodel_t *mod, void *buffer)
|
|||
|
||||
mod->numframes = 2; // regular and alternate animation
|
||||
mod->registration_sequence = registration_sequence; // register model
|
||||
loadmodel->num_textures = 0; // waiting for load
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -232,7 +232,6 @@ typedef struct rmodel_s
|
|||
byte *mempool;
|
||||
|
||||
int numframes;
|
||||
int num_textures; // count of textures what a really loaded
|
||||
|
||||
int flags;
|
||||
|
||||
|
|
|
@ -947,6 +947,7 @@ static bool R_AddEntityToScene( refdef_t *fd, entity_state_t *s1, entity_state_t
|
|||
|
||||
// copy state to render
|
||||
refent->index = s1->number;
|
||||
refent->ent_type = s1->ed_type;
|
||||
refent->prev.frame = s2->model.frame;
|
||||
refent->backlerp = 1.0f - lerpfrac;
|
||||
refent->renderamt = s1->renderamt;
|
||||
|
@ -1315,18 +1316,9 @@ bool R_UploadImage( const char *name, int index )
|
|||
if( !r_worldmodel ) return false;
|
||||
loadmodel = r_worldmodel;
|
||||
|
||||
// all textures are loaded
|
||||
if( !com.strcmp( loadmodel->name, name ) && loadmodel->num_textures == loadmodel->numtexinfo )
|
||||
return false;
|
||||
|
||||
com.strncpy( filename, Mod_GetStringFromTable( loadmodel->texinfo[index].texid ), sizeof(filename));
|
||||
texture = R_FindImage( filename, NULL, 0, it_wall );
|
||||
|
||||
if(!texture) Msg("returned null image!\n");
|
||||
if(texture == r_notexture ) Msg("returned r_notexture!\n");
|
||||
|
||||
if( texture ) loadmodel->texinfo[index].image = texture;
|
||||
loadmodel->num_textures++;
|
||||
loadmodel->texinfo[index].image = texture;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
*/
|
||||
string frame_prefix;
|
||||
byte *spr_palette;
|
||||
|
||||
static byte pal[256][4];
|
||||
|
||||
/*
|
||||
====================
|
||||
Sprite model loader
|
||||
|
@ -35,11 +36,19 @@ dframetype_t *R_SpriteLoadFrame( rmodel_t *mod, void *pin, mspriteframe_t **ppfr
|
|||
|
||||
width = LittleLong (pinframe->width);
|
||||
height = LittleLong (pinframe->height);
|
||||
size = width * height * 4;
|
||||
size = width * height;
|
||||
|
||||
pspriteframe = Mem_Alloc(mod->mempool, sizeof (mspriteframe_t));
|
||||
memset (pspriteframe, 0, sizeof (mspriteframe_t));
|
||||
spr_frame = (rgbdata_t *)Mem_Alloc( mod->mempool, sizeof(rgbdata_t));
|
||||
spr_frame->buffer = (byte *)Mem_Alloc( mod->mempool, size );
|
||||
spr_frame->palette = (byte *)Mem_Alloc( mod->mempool, 1024 );
|
||||
Mem_Copy( spr_frame->buffer, (byte *)(pinframe + 1), size );
|
||||
Mem_Copy( spr_frame->palette, spr_palette, 1024 );
|
||||
spr_frame->flags = IMAGE_HAS_ALPHA;
|
||||
spr_frame->type = PF_INDEXED_32;
|
||||
spr_frame->size = size; // for bounds checking
|
||||
spr_frame->numLayers = 1;
|
||||
spr_frame->numMips = 1;
|
||||
*ppframe = pspriteframe;
|
||||
|
||||
pspriteframe->width = spr_frame->width = width;
|
||||
|
@ -52,17 +61,10 @@ dframetype_t *R_SpriteLoadFrame( rmodel_t *mod, void *pin, mspriteframe_t **ppfr
|
|||
pspriteframe->left = origin[0];
|
||||
pspriteframe->right = width + origin[0];
|
||||
pspriteframe->texnum = 0;
|
||||
spr_frame->type = PF_INDEXED_32;
|
||||
spr_frame->flags = IMAGE_HAS_ALPHA;
|
||||
spr_frame->palette = spr_palette;
|
||||
spr_frame->numLayers = 1;
|
||||
spr_frame->numMips = 1;
|
||||
|
||||
// extract sprite name from path
|
||||
FS_FileBase( mod->name, name );
|
||||
com.strcat(name, va("_%s_%i%i", frame_prefix, framenum/10, framenum%10 ));
|
||||
spr_frame->size = width * height * 4; // for bounds checking
|
||||
spr_frame->buffer = (byte *)(pinframe + 1);
|
||||
|
||||
image = R_LoadImage( name, spr_frame, it_sprite );
|
||||
if( image )
|
||||
|
@ -74,7 +76,7 @@ dframetype_t *R_SpriteLoadFrame( rmodel_t *mod, void *pin, mspriteframe_t **ppfr
|
|||
else MsgDev(D_WARN, "%s has null frame %d\n", image->name, framenum );
|
||||
|
||||
FS_FreeImage( spr_frame );
|
||||
return (dframetype_t *)((byte *)(pinframe + 1) + spr_frame->size);
|
||||
return (dframetype_t *)((byte *)(pinframe + 1) + size );
|
||||
}
|
||||
|
||||
dframetype_t *R_SpriteLoadGroup( rmodel_t *mod, void * pin, mspriteframe_t **ppframe, int framenum )
|
||||
|
@ -120,7 +122,6 @@ void R_SpriteLoadModel( rmodel_t *mod, void *buffer )
|
|||
short *numi;
|
||||
msprite_t *psprite;
|
||||
dframetype_t *pframetype;
|
||||
static byte pal[256][4];
|
||||
int i, size, numframes;
|
||||
|
||||
pin = (dsprite_t *)buffer;
|
||||
|
|
|
@ -100,7 +100,7 @@ image_t *R_StudioLoadTexture( rmodel_t *mod, mstudiotexture_t *ptexture, byte *p
|
|||
r_skin.numMips = 1;
|
||||
r_skin.palette = pin + ptexture->width * ptexture->height + ptexture->index;
|
||||
r_skin.buffer = pin + ptexture->index; // texdata
|
||||
r_skin.size = ptexture->width * ptexture->height * 3; // for bounds cheking
|
||||
r_skin.size = ptexture->width * ptexture->height; // for bounds cheking
|
||||
|
||||
// load studio texture and bind it
|
||||
image = R_LoadImage( ptexture->name, &r_skin, it_skin );
|
||||
|
@ -627,8 +627,7 @@ StudioPlayerBlend
|
|||
void R_StudioPlayerBlend( mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitch )
|
||||
{
|
||||
// calc up/down pointing
|
||||
if( mirror_render ) *pBlend = (*pPitch * -3);
|
||||
else *pBlend = (*pPitch * 3);
|
||||
*pBlend = (*pPitch * 3);
|
||||
|
||||
if( *pBlend < pseqdesc->blendstart[0] )
|
||||
{
|
||||
|
@ -698,6 +697,11 @@ void R_StudioSetUpTransform( void )
|
|||
angles[i] += d * f;
|
||||
}
|
||||
}
|
||||
else if( m_pCurrentEntity->ent_type == ED_CLIENT )
|
||||
{
|
||||
// don't rotate player model, only aim
|
||||
angles[PITCH] = 0;
|
||||
}
|
||||
else if( m_pCurrentEntity->movetype != MOVETYPE_NONE )
|
||||
{
|
||||
VectorCopy( m_pCurrentEntity->angles, angles );
|
||||
|
@ -1904,25 +1908,6 @@ bool R_StudioDrawModel( int pass, int flags )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*if( mirror_render && m_pCurrentEntity->renderfx & RF_PLAYERMODEL )
|
||||
{
|
||||
entity_state_t *plr = ri.GetLocalPlayer();
|
||||
ref_entity_t *save_ent = m_pCurrentEntity;
|
||||
int newflags = (STUDIO_EVENTS|STUDIO_RENDER|STUDIO_MIRROR);
|
||||
int save_interp;
|
||||
|
||||
save_interp = m_fDoInterp;
|
||||
m_fDoInterp = 0;
|
||||
|
||||
// draw as though it were a player
|
||||
m_pCurrentEntity = &r_newrefdef.entities[plr->number];
|
||||
|
||||
R_StudioDrawPlayer( pass, newflags );
|
||||
|
||||
m_fDoInterp = save_interp;
|
||||
m_pCurrentEntity = save_ent;
|
||||
}*/
|
||||
|
||||
R_StudioSetupRender( pass );
|
||||
R_StudioSetUpTransform();
|
||||
if( flags & STUDIO_RENDER )
|
||||
|
@ -2174,7 +2159,7 @@ int R_StudioDrawPlayer( int pass, int flags )
|
|||
// MsgDev( D_INFO, "DrawPlayer %d %d (%d)\n", r_framecount, pplayer->player_index, m_pCurrentEntity->sequence );
|
||||
// MsgDev( D_INFO, "Player %.2f %.2f %.2f\n", pplayer->velocity[0], pplayer->velocity[1], pplayer->velocity[2] );
|
||||
|
||||
if( pplayer->number < 0 || pplayer->number >= ri.GetMaxClients())
|
||||
if( pplayer->number < 0 || pplayer->number > ri.GetMaxClients())
|
||||
return 0;
|
||||
|
||||
if( pplayer->model.gaitsequence )
|
||||
|
|
|
@ -236,7 +236,7 @@ bool R_GetPixelFormat( rgbdata_t *pic, imagetype_t type )
|
|||
if(image_desc.flags & IMAGE_CUBEMAP)
|
||||
totalsize *= 6;
|
||||
|
||||
if(totalsize != pic->size) // sanity check
|
||||
if( totalsize != pic->size ) // sanity check
|
||||
{
|
||||
MsgDev(D_WARN, "R_GetPixelFormat: invalid image size (%i should be %i)\n", pic->size, totalsize );
|
||||
return false;
|
||||
|
@ -850,7 +850,6 @@ bool qrsDecompressedTexImage2D( uint target, int level, int internalformat, uint
|
|||
}
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
case PF_RGB_24_FLIP:
|
||||
// 24-bit image, that will not expanded to RGBA in imglib.dll for some reasons
|
||||
for (i = 0; i < width * height; i++ )
|
||||
{
|
||||
|
@ -1106,12 +1105,12 @@ image_t *R_FindImage( char *name, const byte *buffer, size_t size, imagetype_t t
|
|||
rgbdata_t *pic = NULL;
|
||||
int i;
|
||||
|
||||
if (!name ) return r_notexture;
|
||||
if( !name ) return r_notexture;
|
||||
|
||||
// look for it
|
||||
for (i = 0, image = gltextures; i < numgltextures; i++, image++)
|
||||
for( i = 0, image = gltextures; i < numgltextures; i++, image++ )
|
||||
{
|
||||
if (!com.strcmp( name, image->name ))
|
||||
if( !com.stricmp( name, image->name ))
|
||||
{
|
||||
// prolonge registration
|
||||
image->registration_sequence = registration_sequence;
|
||||
|
@ -1119,9 +1118,13 @@ image_t *R_FindImage( char *name, const byte *buffer, size_t size, imagetype_t t
|
|||
}
|
||||
}
|
||||
|
||||
pic = FS_LoadImage(name, buffer, size ); //loading form disk or buffer
|
||||
image = R_LoadImage(name, pic, type ); //upload into video buffer
|
||||
FS_FreeImage( pic ); //free image
|
||||
pic = FS_LoadImage( name, buffer, size ); //loading form disk or buffer
|
||||
if( pic )
|
||||
{
|
||||
image = R_LoadImage( name, pic, type ); //upload into video buffer
|
||||
FS_FreeImage( pic ); //free image
|
||||
}
|
||||
else image = r_notexture;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -1260,15 +1263,15 @@ void R_ImageFreeUnused(void)
|
|||
r_notexture->registration_sequence = registration_sequence;
|
||||
r_particletexture->registration_sequence = registration_sequence;
|
||||
|
||||
for (i = 0, image = gltextures; i < numgltextures; i++, image++)
|
||||
for( i = 0, image = gltextures; i < numgltextures; i++, image++ )
|
||||
{
|
||||
// used this sequence
|
||||
if (image->registration_sequence == registration_sequence) continue;
|
||||
if (!image->registration_sequence) continue; // free image_t slot
|
||||
if (image->type == it_pic) continue; // don't free pics
|
||||
if (image->type == it_sky || image->type == it_cubemap)
|
||||
for(k = 0; k < 6; k++) pglDeleteTextures (1, &image->texnum[k] );
|
||||
else pglDeleteTextures (1, &image->texnum[0] );
|
||||
if( image->registration_sequence == registration_sequence ) continue;
|
||||
if( !image->name[0] ) continue; // free image_t slot
|
||||
if( image->type == it_pic ) continue; // don't free pics
|
||||
if( image->type == it_sky || image->type == it_cubemap )
|
||||
for( k = 0; k < 6; k++ ) pglDeleteTextures (1, &image->texnum[k] );
|
||||
else pglDeleteTextures( 1, &image->texnum[0] );
|
||||
memset(image, 0, sizeof(*image));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,13 +28,6 @@ typedef struct
|
|||
int dataofs[4]; // [nummiptex]
|
||||
} dmiptexlump_t;
|
||||
|
||||
typedef struct mip_s
|
||||
{
|
||||
char name[16];
|
||||
uint width, height;
|
||||
uint offsets[4]; // four mip maps stored
|
||||
} mip_t;
|
||||
|
||||
byte* bsp_base;
|
||||
bool bsp_halflife = false;
|
||||
|
||||
|
@ -198,7 +191,7 @@ bool Conv_CheckWad( const char *wadname )
|
|||
// and check wadnames in case
|
||||
if(!com.stricmp( wadname, "tnt.wad" ) && game_family == GAME_DOOM1 )
|
||||
{
|
||||
Msg("Wow! Doom2 TNT!\n" );
|
||||
Msg("Wow! Doom2 na TNT!\n" );
|
||||
}
|
||||
return (game_family != GAME_GENERIC);
|
||||
}
|
|
@ -76,6 +76,7 @@ bool ConvertResource( const char *filename )
|
|||
return true; // converted ok
|
||||
}
|
||||
}
|
||||
if( buffer ) Mem_Free( buffer ); // release buffer
|
||||
}
|
||||
}
|
||||
MsgDev(D_WARN, "ConvertResource: couldn't load \"%s\"\n", basename );
|
||||
|
@ -132,6 +133,7 @@ void Conv_DetectGameType( void )
|
|||
break;
|
||||
}
|
||||
if( search ) Mem_Free( search );
|
||||
ClrMask();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -146,8 +148,8 @@ void InitConvertor ( int argc, char **argv )
|
|||
{
|
||||
|
||||
// init pools
|
||||
basepool = Mem_AllocPool( "Temp" );
|
||||
zonepool = Mem_AllocPool( "Zone" );
|
||||
basepool = Mem_AllocPool( "Ripper Temp" );
|
||||
zonepool = Mem_AllocPool( "Ripper Zone" );
|
||||
FS_InitRootDir(".");
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
|
@ -170,11 +172,29 @@ void RunConvertor( void )
|
|||
switch( game_family )
|
||||
{
|
||||
case GAME_DOOM1:
|
||||
AddMask( "*.skn" ); // Doom1 sprite models
|
||||
AddMask( "*.flp" ); // Doom1 pics
|
||||
AddMask( "*.flt" ); // Doom1 textures
|
||||
AddMask( "*.snd" ); // Doom1 sounds
|
||||
AddMask( "*.mus" ); // Doom1 music
|
||||
search = FS_Search("*.wad", true );
|
||||
if( search )
|
||||
{
|
||||
// make sure, that we stored all files from all wads
|
||||
for( i = 0; i < search->numfilenames; i++ )
|
||||
{
|
||||
AddMask(va("%s/*.flt", search->filenames[i]));
|
||||
AddMask(va("%s/*.flp", search->filenames[i]));
|
||||
AddMask(va("%s/*.skn", search->filenames[i]));
|
||||
AddMask(va("%s/*.snd", search->filenames[i]));
|
||||
AddMask(va("%s/*.mus", search->filenames[i]));
|
||||
}
|
||||
Mem_Free( search );
|
||||
}
|
||||
else
|
||||
{
|
||||
// just use global mask
|
||||
AddMask( "*.skn" ); // Doom1 sprite models
|
||||
AddMask( "*.flp" ); // Doom1 pics
|
||||
AddMask( "*.flt" ); // Doom1 textures
|
||||
AddMask( "*.snd" ); // Doom1 sounds
|
||||
AddMask( "*.mus" ); // Doom1 music
|
||||
}
|
||||
break;
|
||||
case GAME_HEXEN2:
|
||||
case GAME_QUAKE1:
|
||||
|
@ -200,7 +220,7 @@ void RunConvertor( void )
|
|||
AddMask(va("%s/*.wal", search->filenames[i]));
|
||||
Mem_Free( search );
|
||||
}
|
||||
AddMask( "*.wal" ); // Quake2 textures
|
||||
else AddMask( "*.wal" ); // Quake2 textures
|
||||
AddMask( "*.sp2" ); // Quake2 sprites
|
||||
AddMask( "*.pcx" ); // Quake2 sprites
|
||||
AddMask( "sprites/*.sp2" ); // Quake2 sprites
|
||||
|
@ -215,26 +235,39 @@ void RunConvertor( void )
|
|||
Sys_Break("Sorry, nothing to decompile (not implemeneted yet)\n" );
|
||||
break;
|
||||
case GAME_HALFLIFE:
|
||||
search = FS_Search("*.wad", true );
|
||||
if( search )
|
||||
{
|
||||
// find subdirectories
|
||||
for( i = 0; i < search->numfilenames; i++ )
|
||||
{
|
||||
AddMask(va("%s/*.mip", search->filenames[i]));
|
||||
AddMask(va("%s/*.lmp", search->filenames[i]));
|
||||
}
|
||||
Mem_Free( search );
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to use generic mask
|
||||
AddMask( "*.mip" );
|
||||
AddMask( "*.lmp" );
|
||||
}
|
||||
AddMask( "maps/*.bsp" ); // textures from bsp
|
||||
AddMask( "sprites/*.spr" ); // Half-Life sprites
|
||||
AddMask( "gfx/*.lmp" ); // some images
|
||||
AddMask( "*.mip" ); // all textures from wads
|
||||
AddMask( "*.spr" );
|
||||
AddMask( "*.lmp" );
|
||||
break;
|
||||
case GAME_XASH3D:
|
||||
Sys_Break("Sorry, but a can't decompile himself\n" );
|
||||
break;
|
||||
case HOST_OFFLINE:
|
||||
default: Sys_Break("Sorry, game family not recognized\n" );
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// using custom mask
|
||||
if(FS_GetParmFromCmdLine("-file", gs_searchmask ))
|
||||
{
|
||||
ClrMask(); // clear all previous masks
|
||||
AddMask( gs_searchmask ); // custom mask
|
||||
}
|
||||
else if(!game_family ) Sys_Break( "Sorry, game family not recognized\n" );
|
||||
|
||||
// directory to extract
|
||||
com.strncpy( gs_gamedir, fs_defaultdir->string, sizeof(gs_gamedir));
|
||||
|
@ -257,7 +290,7 @@ void RunConvertor( void )
|
|||
}
|
||||
if( numConvertedRes == 0 )
|
||||
{
|
||||
for(j = 0; j < 16; j++)
|
||||
for(j = 0; j < MAX_SEARCHMASK; j++)
|
||||
{
|
||||
if(!com.strlen(searchmask[j])) continue;
|
||||
com.strncat(errorstring, va("%s ", searchmask[j]), MAX_STRING );
|
||||
|
|
|
@ -113,8 +113,9 @@ bool ConvPAL( const char *name, char *buffer, int filesize )
|
|||
|
||||
if( pic && pic->palette )
|
||||
{
|
||||
Image_ConvertPalette( pic );
|
||||
FS_StripExtension((char *)name );
|
||||
FS_WriteFile( va("%s.pal", name ), pic->palette, 1024 );// expands to 32bit
|
||||
FS_WriteFile( va("%s/%s.pal", gs_gamedir, name ), pic->palette, 768 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.pal\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
// this also uses by SP2_ConvertFrame
|
||||
bool PCX_ConvertImage( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.pcx", buffer, filesize );
|
||||
|
@ -28,35 +29,5 @@ ConvPCX
|
|||
*/
|
||||
bool ConvPCX( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
string picname, path;
|
||||
|
||||
FS_FileBase( name, picname );
|
||||
if(!com.strnicmp("num", picname, 3 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/fonts/%s", picname );
|
||||
else if(!com.strnicmp("anum", picname, 4 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/fonts/%s", picname );
|
||||
else if(!com.strnicmp("conchars", picname, 8 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/fonts/%s", picname );
|
||||
else if(!com.strnicmp("a_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/hud/%s", picname );
|
||||
else if(!com.strnicmp("p_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/hud/%s", picname );
|
||||
else if(!com.strnicmp("k_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/hud/%s", picname );
|
||||
else if(!com.strnicmp("i_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/hud/%s", picname );
|
||||
else if(!com.strnicmp("w_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/hud/%s", picname );
|
||||
else if(!com.strnicmp("m_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/menu/%s", picname );
|
||||
else if(!com.strnicmp("m_", picname, 2 ))
|
||||
com.snprintf( path, MAX_STRING, "gfx/menu/%s", picname );
|
||||
else com.snprintf( path, MAX_STRING, "gfx/common/%s", picname );
|
||||
|
||||
if(PCX_ConvertImage( path, buffer, filesize ))
|
||||
{
|
||||
Msg("%s\n", name ); // echo to console about current image
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return PCX_ConvertImage( name, buffer, filesize );
|
||||
}
|
|
@ -10,9 +10,51 @@
|
|||
string nextanimchain;
|
||||
file_t *f;
|
||||
|
||||
bool Conv_WriteShader( const char *shaderpath, const char *imagepath, float *rad, float scale, int flags, int contents )
|
||||
void Conv_RoundDimensions( int *scaled_width, int *scaled_height )
|
||||
{
|
||||
file_t *f;
|
||||
int width, height;
|
||||
|
||||
for( width = 1; width < *scaled_width; width <<= 1 );
|
||||
for( height = 1; height < *scaled_height; height <<= 1 );
|
||||
|
||||
*scaled_width = bound( 1, width, 512 );
|
||||
*scaled_height = bound( 1, height, 512 );
|
||||
}
|
||||
|
||||
bool Conv_WriteShader( const char *shaderpath, const char *imagepath, rgbdata_t *p, float *rad, float scale, int flags, int contents )
|
||||
{
|
||||
file_t *f;
|
||||
string qcname, qcpath, temp, lumpname;
|
||||
|
||||
// write also wadlist.qc for xwad compiler
|
||||
FS_ExtractFilePath( imagepath, temp );
|
||||
FS_FileBase( imagepath, lumpname );
|
||||
FS_FileBase( temp, qcname );
|
||||
FS_DefaultExtension( qcname, ".qc" );
|
||||
com.snprintf( qcpath, MAX_STRING, "%s/%s/%s", gs_gamedir, temp, qcname );
|
||||
|
||||
if(FS_FileExists( qcpath ))
|
||||
{
|
||||
// already exist, search for current name
|
||||
f = FS_Open( qcpath, "a" ); // append
|
||||
}
|
||||
else
|
||||
{
|
||||
FS_StripExtension( qcname ); // no need anymore
|
||||
f = FS_Open( qcpath, "w" ); // new file
|
||||
// write description
|
||||
FS_Print(f,"//=======================================================================\n");
|
||||
FS_Print(f,"//\t\t\tCopyright XashXT Group 2007 ©\n");
|
||||
FS_Print(f,"//\t\t\twritten by Xash Miptex Decompiler\n");
|
||||
FS_Print(f,"//=======================================================================\n");
|
||||
FS_Printf(f,"$wadname\t%s.wad\n\n", qcname );
|
||||
}
|
||||
|
||||
if( f && p )
|
||||
{
|
||||
FS_Printf(f,"$mipmap\t%s\t0 0 %d %d\n", lumpname, p->width, p->height );
|
||||
FS_Close( f ); // all done
|
||||
}
|
||||
|
||||
// nothing to write
|
||||
if(!flags && !contents && !com.strlen(nextanimchain))
|
||||
|
@ -224,19 +266,22 @@ bool Conv_CreateShader( const char *name, rgbdata_t *pic, const char *ext, const
|
|||
VectorCopy( pic->color, radiocity );
|
||||
intencity = pic->bump_scale;
|
||||
}
|
||||
return Conv_WriteShader( shaderpath, imagepath, radiocity, intencity, flags, contents );
|
||||
return Conv_WriteShader( shaderpath, imagepath, pic, radiocity, intencity, flags, contents );
|
||||
}
|
||||
|
||||
void Skin_WriteSequence( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
Conv_RoundDimensions( &flat.bounds[0], &flat.bounds[1] );
|
||||
|
||||
// time to dump frames :)
|
||||
if( flat.angledframes == 8 )
|
||||
{
|
||||
// angled group is full, dump it!
|
||||
FS_Print(f, "\n$angled\n{\n" );
|
||||
FS_Printf(f, "\t// frame '%c'\n", flat.frame[0].name[4] );
|
||||
FS_Printf(f, "\t$resample\t\t%d %d\n", flat.bounds[0], flat.bounds[1] );
|
||||
for( i = 0; i < 8; i++)
|
||||
{
|
||||
FS_Printf(f,"\t$load\t\t%s.bmp", flat.frame[i].name );
|
||||
|
@ -252,6 +297,7 @@ void Skin_WriteSequence( void )
|
|||
// single frame stored
|
||||
FS_Print(f, "\n" );
|
||||
FS_Printf(f, "// frame '%c'\n", flat.frame[0].name[4] );
|
||||
FS_Printf(f,"$resample\t\t%d %d\n", flat.bounds[0], flat.bounds[1] );
|
||||
FS_Printf(f,"$load\t\t%s.bmp\n", flat.frame[0].name );
|
||||
FS_Printf(f,"$frame\t\t0 0 %d %d", flat.frame[0].width, flat.frame[0].height );
|
||||
FS_Printf(f, " 0.1 %d %d\n", flat.frame[0].origin[0], flat.frame[0].origin[1]);
|
||||
|
@ -263,6 +309,7 @@ void Skin_WriteSequence( void )
|
|||
// mirrored group is always flipped
|
||||
FS_Print(f, "\n$angled\n{\n" );
|
||||
FS_Printf(f, "\t// frame '%c' (mirrored form '%c')\n", flat.frame[0].name[6],flat.frame[0].name[4]);
|
||||
FS_Printf(f, "\t$resample\t\t%d %d\n", flat.bounds[0], flat.bounds[1] );
|
||||
for( i = 2; i > -1; i--)
|
||||
{
|
||||
FS_Printf(f,"\t$load\t\t%s.bmp flip_x\n", flat.frame[i].name );
|
||||
|
@ -278,6 +325,7 @@ void Skin_WriteSequence( void )
|
|||
FS_Print(f, "}\n" );
|
||||
}
|
||||
|
||||
flat.bounds[0] = flat.bounds[1] = 0;
|
||||
memset( &flat.frame, 0, sizeof(flat.frame));
|
||||
flat.angledframes = flat.normalframes = flat.mirrorframes = 0; // clear all
|
||||
}
|
||||
|
@ -300,6 +348,10 @@ void Skin_FindSequence( const char *name, rgbdata_t *pic )
|
|||
|
||||
if( flat.animation == header[4] )
|
||||
{
|
||||
// update bounds
|
||||
if( flat.bounds[0] < pic->width ) flat.bounds[0] = pic->width;
|
||||
if( flat.bounds[1] < pic->height) flat.bounds[1] = pic->height;
|
||||
|
||||
// continue collect frames
|
||||
if( headlen == 6 )
|
||||
{
|
||||
|
@ -349,7 +401,7 @@ void Skin_FindSequence( const char *name, rgbdata_t *pic )
|
|||
}
|
||||
}
|
||||
|
||||
void Skin_ProcessScript( const char *name )
|
||||
void Skin_ProcessScript( const char *wad, const char *name )
|
||||
{
|
||||
if(flat.in_progress )
|
||||
{
|
||||
|
@ -362,8 +414,9 @@ void Skin_ProcessScript( const char *name )
|
|||
{
|
||||
// start from scratch
|
||||
com.strncpy( flat.membername, name, 5 );
|
||||
f = FS_Open( va("%s/models/%s.qc", gs_gamedir, flat.membername ), "w" );
|
||||
f = FS_Open( va("%s/sprites/%s/%s.qc", gs_gamedir, wad, flat.membername ), "w" );
|
||||
flat.in_progress = true;
|
||||
flat.bounds[0] = flat.bounds[1] = 0;
|
||||
|
||||
// write description
|
||||
FS_Print(f,"//=======================================================================\n");
|
||||
|
@ -374,7 +427,8 @@ void Skin_ProcessScript( const char *name )
|
|||
// write sprite header
|
||||
FS_Printf(f, "\n$spritename\t%s.spr\n", flat.membername );
|
||||
FS_Print(f, "$type\t\tfacing_upright\n" ); // constant
|
||||
FS_Print(f, "$texture\t\tindexalpha\n");
|
||||
FS_Print(f, "$texture\t\talphatest\n");
|
||||
FS_Print(f, "$noresample\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,10 +442,10 @@ void Skin_FinalizeScript( void )
|
|||
flat.in_progress = false;
|
||||
}
|
||||
|
||||
void Skin_CreateScript( const char *name, rgbdata_t *pic )
|
||||
void Skin_CreateScript( const char *wad, const char *name, rgbdata_t *pic )
|
||||
{
|
||||
if(com.strnicmp( name, flat.membername, 4 ))
|
||||
Skin_ProcessScript( name );
|
||||
Skin_ProcessScript( wad, name );
|
||||
|
||||
if( flat.in_progress )
|
||||
Skin_FindSequence( name, pic );
|
||||
|
|
|
@ -376,9 +376,6 @@ bool Conv_Mus2Mid( const char *musicname, byte *buffer, int bufsize )
|
|||
}
|
||||
if( ouch ) MsgDev(D_WARN, "Conv_Mus2Mid: %s.mus - end of file probably corrupted\n", musicname );
|
||||
|
||||
// write normal .mid file
|
||||
if(FS_FileExists(va("%s/music/%s.mid", gs_gamedir, musicname )))
|
||||
return false; // already existed
|
||||
f = FS_Open(va("%s/music/%s.mid", gs_gamedir, musicname ), "wb" );
|
||||
file_mid = VFS_Open( f, "w" );
|
||||
|
||||
|
@ -403,6 +400,9 @@ bool ConvMID( const char *name, char *buffer, int filesize )
|
|||
{
|
||||
string musicname;
|
||||
|
||||
if(FS_FileExists(va("%s/music/%s.mid", gs_gamedir, musicname )))
|
||||
return true; // already existed
|
||||
|
||||
FS_FileBase( name, musicname );
|
||||
if(Conv_Mus2Mid( musicname, buffer, filesize ))
|
||||
{
|
||||
|
|
|
@ -57,6 +57,12 @@ typedef struct
|
|||
//
|
||||
// sprite_decompiler.c
|
||||
//
|
||||
const char *SPR_Ext( void )
|
||||
{
|
||||
if( spr.truecolor )
|
||||
return "tga";
|
||||
return "bmp";
|
||||
}
|
||||
|
||||
void *SPR_ConvertFrame( const char *name, void *pin, int framenum, int groupframenum )
|
||||
{
|
||||
|
@ -91,9 +97,9 @@ void *SPR_ConvertFrame( const char *name, void *pin, int framenum, int groupfram
|
|||
else
|
||||
{
|
||||
pixels = width * height;
|
||||
pix.palette = (byte *)(&spr.palette[0][0]);
|
||||
pix.palette = (byte *)Mem_Alloc( zonepool, 1024 );
|
||||
Mem_Copy( pix.palette, &spr.palette, 1024 );
|
||||
pix.type = PF_INDEXED_32;
|
||||
Image_ConvertPalette( &pix );
|
||||
Mem_Copy( fout, fin, pixels );
|
||||
}
|
||||
|
||||
|
@ -125,10 +131,10 @@ void *SPR_ConvertFrame( const char *name, void *pin, int framenum, int groupfram
|
|||
pix.buffer = fout;
|
||||
if( spr.texFormat >= SPR_INDEXALPHA )
|
||||
pix.flags |= IMAGE_HAS_ALPHA;
|
||||
|
||||
if( spr.truecolor )
|
||||
FS_SaveImage( va("%s/sprites/%s.tga", gs_gamedir, framename ), &pix );
|
||||
else FS_SaveImage( va("%s/sprites/%s.bmp", gs_gamedir, framename ), &pix );
|
||||
if( !spr.truecolor ) Image_ConvertPalette( &pix );
|
||||
|
||||
FS_SaveImage( va("%s/sprites/%s.%s", gs_gamedir, framename, SPR_Ext()), &pix );
|
||||
if( pix.palette ) Mem_Free( pix.palette ); // free palette
|
||||
Mem_Free( fout ); // release buffer
|
||||
|
||||
// jump to next frame
|
||||
|
@ -189,7 +195,7 @@ bool SPR_WriteScript( const char *name )
|
|||
// frames description
|
||||
for( i = 0; i < spr.totalframes - spr.numgroup; i++)
|
||||
{
|
||||
FS_Printf(f,"$load\t\t%s.bmp\n", spr.frame[i].name );
|
||||
FS_Printf(f,"$load\t\t%s.%s\n", spr.frame[i].name, SPR_Ext());
|
||||
FS_Printf(f,"$frame\t\t0 0 %d %d", spr.frame[i].width, spr.frame[i].height );
|
||||
if(!spr.frame[i].origin[0] && !spr.frame[i].origin[1]) FS_Print(f, "\n" );
|
||||
else FS_Printf(f, " %.1f %d %d\n", 0.1f, spr.frame[i].origin[0],spr.frame[i].origin[1]);
|
||||
|
@ -200,7 +206,7 @@ bool SPR_WriteScript( const char *name )
|
|||
FS_Print(f, "$group\n{\n" );
|
||||
for( j = 0; j < spr.group[i].numframes; j++)
|
||||
{
|
||||
FS_Printf(f,"\t$load\t\t%s.bmp\n", spr.group[i].frame[j].name );
|
||||
FS_Printf(f,"\t$load\t\t%s.%s\n", spr.group[i].frame[j].name, SPR_Ext());
|
||||
FS_Printf(f,"\t$frame\t\t0 0 %d %d", spr.group[i].frame[j].width, spr.group[i].frame[j].height );
|
||||
if( spr.group[i].interval[j] ) FS_Printf(f, " %g", spr.group[i].interval[j] );
|
||||
if(!spr.group[i].frame[j].origin[0] && !spr.group[i].frame[j].origin[1]) FS_Print(f, "\n" );
|
||||
|
@ -242,7 +248,7 @@ bool ConvSPR( const char *name, char *buffer, int filesize )
|
|||
{
|
||||
case SPRITEQ1_VERSION:
|
||||
spr.totalframes = LittleLong( pin->numframes );
|
||||
spr.texFormat = SPR_INDEXALPHA; // constant
|
||||
spr.texFormat = SPR_ALPHTEST; // constant
|
||||
spr.type = LittleLong( pin->type );
|
||||
|
||||
// palette setup
|
||||
|
|
|
@ -107,7 +107,7 @@ bool ConvSP2( const char *name, char *buffer, int filesize )
|
|||
return false;
|
||||
}
|
||||
spr.totalframes = LittleLong (pin->numframes);
|
||||
spr.texFormat = SPR_INDEXALPHA; // constant
|
||||
spr.texFormat = SPR_ALPHTEST; // constant
|
||||
spr.type = SPR_VP_PARALLEL;
|
||||
|
||||
// byte swap everything
|
||||
|
|
|
@ -15,15 +15,23 @@ ConvSKN
|
|||
bool ConvSKN( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.flt", buffer, filesize );
|
||||
string savedname, skinname, wad;
|
||||
int k, l;
|
||||
|
||||
if( pic )
|
||||
{
|
||||
string skinpath;
|
||||
FS_FileBase( name, skinpath );
|
||||
FS_SaveImage(va("%s/sprites/%s.bmp", gs_gamedir, skinpath ), pic );
|
||||
Skin_CreateScript( skinpath, pic );
|
||||
com.strncpy( savedname, name, MAX_STRING );
|
||||
k = com.strlen( com.strchr( savedname, '\\' ));
|
||||
l = com.strlen( savedname );
|
||||
if( k ) savedname[l-k] = '#'; // stupid doom2 name "vile1\"
|
||||
FS_ExtractFilePath( name, wad );
|
||||
FS_StripExtension( savedname );
|
||||
FS_FileBase( savedname, skinname );
|
||||
|
||||
FS_SaveImage( va("%s/sprites/%s.bmp", gs_gamedir, savedname ), pic );
|
||||
Skin_CreateScript( wad, skinname, pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.skin\n", skinpath ); // echo to console about current skin
|
||||
Msg("%s/%s.bmp\n", wad, skinname ); // echo to console about current skin
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -37,14 +45,23 @@ ConvFLT
|
|||
bool ConvFLT( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.flt", buffer, filesize );
|
||||
string savedname, tempname, path;
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension( (char *)name );
|
||||
FS_SaveImage(va("%s/textures/%s.bmp", gs_gamedir, name ), pic );
|
||||
Conv_CreateShader( name, pic, "flt", NULL, 0, 0 );
|
||||
com.strncpy( savedname, name, MAX_STRING );
|
||||
if( pic->flags & IMAGE_HAS_ALPHA )
|
||||
{
|
||||
FS_ExtractFilePath( savedname, path );
|
||||
FS_FileBase( savedname, tempname );
|
||||
com.snprintf( savedname, MAX_STRING, "%s/{%s", path, tempname );
|
||||
}
|
||||
else FS_StripExtension( savedname );
|
||||
|
||||
FS_SaveImage(va("%s/textures/%s.bmp", gs_gamedir, savedname ), pic );
|
||||
Conv_CreateShader( savedname, pic, "flt", NULL, 0, 0 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.flat\n", name ); // echo to console about current texture
|
||||
Msg("%s.bmp\n", savedname ); // echo to console about current texture
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -58,14 +75,13 @@ ConvFLP
|
|||
bool ConvFLP( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.flt", buffer, filesize );
|
||||
string savedname;
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_FileBase( name, savedname );
|
||||
FS_SaveImage(va("%s/gfx/%s.bmp", gs_gamedir, savedname ), pic );
|
||||
FS_StripExtension( (char *)name );
|
||||
FS_SaveImage(va("%s/gfx/%s.bmp", gs_gamedir, name ), pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.flmp\n", savedname ); // echo to console about current pic
|
||||
Msg("%s.bmp\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -78,24 +94,36 @@ ConvMIP
|
|||
*/
|
||||
bool ConvMIP( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.mip", buffer, filesize );
|
||||
rgbdata_t *pic;
|
||||
string savedname, path;
|
||||
int k, l;
|
||||
|
||||
if(com.stristr( name, "gfx/conchars" )) // AGRHHHHHHH!!!!!!!!!!!!!!!!111
|
||||
pic = FS_LoadImage( "conchars", buffer, filesize );
|
||||
else if(com.stristr( name, "colormap" ))
|
||||
return true; // colormap not needs anywhere
|
||||
else if(com.stristr( name, "palette" ))
|
||||
return ConvPAL( name, buffer, filesize );
|
||||
else pic = FS_LoadImage( "#internal.mip", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_FileBase( name, savedname );
|
||||
com.strncpy( savedname, name, MAX_STRING );
|
||||
k = com.strlen( com.strchr( savedname, '*' ));
|
||||
l = com.strlen( savedname );
|
||||
if( k ) savedname[l-k] = '!'; // quake1 issues
|
||||
FS_StripExtension( savedname );
|
||||
|
||||
if(!com.stricmp( savedname, "gfx/conchars" ))
|
||||
com.snprintf( path, MAX_STRING, "%s/gfx/%s.bmp", gs_gamedir, savedname );
|
||||
else com.snprintf( path, MAX_STRING, "%s/textures/%s.bmp", gs_gamedir, savedname );
|
||||
if(com.stristr( name, "gfx/conchars" ))
|
||||
com.snprintf( path, MAX_STRING, "%s/%s.bmp", gs_gamedir, savedname );
|
||||
else
|
||||
{
|
||||
com.snprintf( path, MAX_STRING, "%s/textures/%s.bmp", gs_gamedir, savedname );
|
||||
Conv_CreateShader( savedname, pic, "mip", NULL, 0, 0 ); // replace * with ! in shader too
|
||||
}
|
||||
FS_SaveImage( path, pic );
|
||||
Conv_CreateShader( name, pic, "mip", NULL, 0, 0 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.mip\n", savedname ); // echo to console about current pic
|
||||
Msg("%s.bmp\n", savedname ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -108,15 +136,20 @@ ConvLMP
|
|||
*/
|
||||
bool ConvLMP( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.lmp", buffer, filesize );
|
||||
string savedname;
|
||||
rgbdata_t *pic;
|
||||
|
||||
if(com.stristr( name, "colormap" ))
|
||||
return true; // colormap not needs anywhere
|
||||
else if(com.stristr( name, "palette" ))
|
||||
return ConvPAL( name, buffer, filesize );
|
||||
else pic = FS_LoadImage( "#internal.lmp", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_FileBase( name, savedname );
|
||||
FS_SaveImage(va("%s/gfx/%s.bmp", gs_gamedir, savedname ), pic );
|
||||
FS_StripExtension( (char *)name );
|
||||
FS_SaveImage(va("%s/%s.bmp", gs_gamedir, name ), pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.lmp\n", savedname ); // echo to console about current pic
|
||||
Msg("%s.bmp\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef struct angled_s
|
|||
struct angledframe_s
|
||||
{
|
||||
angled_t frame[8]; // angled group or single frame
|
||||
int bounds[2]; // group or frame maxsizes
|
||||
byte angledframes; // count of angled frames max == 8
|
||||
byte normalframes; // count of anim frames max == 1
|
||||
byte mirrorframes; // animation mirror stored
|
||||
|
@ -105,7 +106,7 @@ _inline const char *SPR_RenderType( void )
|
|||
}
|
||||
|
||||
void Skin_FinalizeScript( void );
|
||||
void Skin_CreateScript( const char *name, rgbdata_t *pic );
|
||||
void Skin_CreateScript( const char *wad, const char *name, rgbdata_t *pic );
|
||||
bool Conv_CreateShader( const char *name, rgbdata_t *pic, const char *ext, const char *anim, int surf, int cnt );
|
||||
void Conv_GetPaletteQ2( void );
|
||||
void Conv_GetPaletteQ1( void );
|
||||
|
|
35
todo.log
35
todo.log
|
@ -20,45 +20,18 @@ GLOBAL:
|
|||
|
||||
TODO LIST
|
||||
придумать как вернуть cmodel_t обратно в physic.dll
|
||||
баг с повторной загрузкой некоторых карт (исчезают все текстуры - становятся белыми)
|
||||
включить интерполяцию для studio моделей
|
||||
научить игрока лазить по лестницам
|
||||
Провериться боундс-чекером на течку
|
||||
Найти наконец эту йобанную утечку
|
||||
Перенести ripper.dll в common.dll
|
||||
Поддержка Jpg чтение\запись
|
||||
Поддержка bmp 8-bit чтение\запись
|
||||
перевести движок на matrix4x4 instead of matrix3x4
|
||||
избавится от идиотскова RF_TRANSLUCENT
|
||||
Кстати приделать thirdperson чтобы удобнее было настраивать StudioDrawPlayer
|
||||
Упорядочить EF_, RF_ ed_type проверки
|
||||
uninstall.exe кстати нихрена не работает :(
|
||||
Переместить ripper.dll обратно в common.dll
|
||||
Поддержка Png
|
||||
убить все декомпиляционные утилиты, оставить одну универсальную
|
||||
Генерация qc-скриптов для текстур из вадов
|
||||
Написать Image_process
|
||||
код создания скриптов для дуумовских спрайтов где-то глючит
|
||||
декомпилятор спрайтов переделать обратно в bmp (вместо tga)
|
||||
Image_Processing FLIP_X, FLIP_Y (PF_INDEXED_24, PF_INDEXED_32, PF_RGB_24, PF_RGBA_32)
|
||||
Image_Resample (PF_INDEXED_24, PF_INDEXED_32) - перенести ResizeTexture
|
||||
исправить баг в studiomdl.exe (не компилирует модели, в которых более 86 анимаций)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
включить интерполяцию для studio моделей
|
||||
перевести движок на matrix4x4 instead of matrix3x4
|
||||
перенести и упорядочить все ресурсы из старых релизов Xash
|
||||
забэкапить результат
|
||||
|
||||
|
||||
|
||||
|
|
Reference in New Issue