09 Aug 2008

This commit is contained in:
g-cont 2008-08-09 00:00:00 +04:00 committed by Alibek Omarov
parent ac89e87d67
commit 1a8fe4546e
49 changed files with 1945 additions and 616 deletions

View File

@ -36,4 +36,3 @@ launch\sprite\
launch\studio\
launch\viewer\
launch\extragen\
launch\uninstall\

View File

@ -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();

573
common/spritegen.c.old Normal file
View File

@ -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 );
}

View File

@ -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" );
}

View File

@ -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");

View File

@ -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" );
}

View File

@ -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"))))
{

View File

@ -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
}

View File

@ -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

View File

@ -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 );

View File

@ -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;
}

View File

@ -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 ))

View File

@ -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 ))
{

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 );

View File

@ -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

View File

@ -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;

View File

@ -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;
}

BIN
launch/png._lib Normal file

Binary file not shown.

BIN
launch/png.lib Normal file

Binary file not shown.

View File

@ -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;

View File

@ -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

View File

@ -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 $<

View File

@ -1,7 +0,0 @@
//=======================================================================
// Copyright (C) XashXT Group 2007
//=======================================================================
#include "../rundll.h"
Run32( uninstall );

View File

@ -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:

View File

@ -20,10 +20,6 @@ cd ..
cd studio
makefile.nmake
cd ..
cd uninstall
makefile.nmake
cd ..
cd viewer
makefile.nmake

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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
}
/*

View File

@ -232,7 +232,6 @@ typedef struct rmodel_s
byte *mempool;
int numframes;
int num_textures; // count of textures what a really loaded
int flags;

View File

@ -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;
}

View File

@ -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;

View File

@ -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 )

View File

@ -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));
}
}

View File

@ -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);
}

View File

@ -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 );

View File

@ -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;

View File

@ -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 );
}

View File

@ -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 );

View File

@ -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 ))
{

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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
забэкапить результат