19 Jul 2008
This commit is contained in:
parent
8adcced8b8
commit
9759bb3d12
|
@ -39,7 +39,7 @@ void CL_ScreenshotGetName( int lastnum, char *filename )
|
|||
if(lastnum < 0 || lastnum > 9999)
|
||||
{
|
||||
// bound
|
||||
com.sprintf( filename, "scrshots/%s/shot9999.dds", cl.configstrings[CS_NAME] );
|
||||
com.sprintf( filename, "scrshots/%s/shot9999.tga", cl.configstrings[CS_NAME] );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ void CL_ScreenshotGetName( int lastnum, char *filename )
|
|||
lastnum -= c * 10;
|
||||
d = lastnum;
|
||||
|
||||
com.sprintf( filename, "scrshots/%s/shot%i%i%i%i.dds", cl.configstrings[CS_NAME], a, b, c, d );
|
||||
com.sprintf( filename, "scrshots/%s/shot%i%i%i%i.tga", cl.configstrings[CS_NAME], a, b, c, d );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -96,7 +96,7 @@ void CL_LevelShot_f( void )
|
|||
char checkname[MAX_OSPATH];
|
||||
|
||||
// check for exist
|
||||
com.sprintf( checkname, "gfx/background/%s.dds", cl.configstrings[CS_NAME] );
|
||||
com.sprintf( checkname, "gfx/background/%s.tga", 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" );
|
||||
}
|
||||
|
|
|
@ -90,4 +90,6 @@ static fields_t cl_reqfields[] =
|
|||
{16, 2, "flags"}
|
||||
};
|
||||
|
||||
#define PROG_CRC_CLIENT 9488
|
||||
|
||||
#endif//CL_EDICT_H
|
|
@ -738,6 +738,7 @@ void UI_Init( void )
|
|||
prog->init_cmd = VM_Cmd_Init;
|
||||
prog->reset_cmd = VM_Cmd_Reset;
|
||||
prog->error_cmd = VM_Error;
|
||||
prog->filecrc = PROG_CRC_UIMENU;
|
||||
|
||||
PRVM_LoadProgs( GI->uimenu_prog, 0, NULL, UI_NUM_REQFIELDS, ui_reqfields );
|
||||
*prog->time = cls.realtime * 0.001f;
|
||||
|
|
|
@ -609,6 +609,7 @@ void CL_InitClientProgs( void )
|
|||
prog->free_edict = CL_FreeEdict;
|
||||
prog->count_edicts = CL_CountEdicts;
|
||||
prog->load_edict = CL_LoadEdict;
|
||||
prog->filecrc = PROG_CRC_CLIENT;
|
||||
|
||||
// using default builtins
|
||||
prog->init_cmd = VM_Cmd_Init;
|
||||
|
|
|
@ -108,4 +108,6 @@ static fields_t ui_reqfields[] =
|
|||
{93, 2, "find2"}
|
||||
};
|
||||
|
||||
#define PROG_CRC_UIMENU 2460
|
||||
|
||||
#endif//UI_EDICT_H
|
|
@ -294,4 +294,6 @@ static fields_t sv_reqfields[] =
|
|||
{264, 1, "oldmodel"}
|
||||
};
|
||||
|
||||
#define PROG_CRC_SERVER 1320
|
||||
|
||||
#endif//SV_EDICT_H
|
|
@ -2463,6 +2463,7 @@ void SV_InitServerProgs( void )
|
|||
prog->free_edict = SV_FreeEdict;
|
||||
prog->count_edicts = SV_CountEdicts;
|
||||
prog->load_edict = SV_LoadEdict;
|
||||
prog->filecrc = PROG_CRC_SERVER;
|
||||
|
||||
// using default builtins
|
||||
prog->init_cmd = VM_Cmd_Init;
|
||||
|
|
103
imglib/img_dds.c
103
imglib/img_dds.c
|
@ -139,19 +139,15 @@ static void Image_BaseColorSearch( byte *blkaddr, byte srccolors[4][4][4], byte
|
|||
|
||||
if( nrcolor[0] == 0 ) nrcolor[0] = 1;
|
||||
if( nrcolor[1] == 0 ) nrcolor[1] = 1;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
if((testcolor[0][i] + blockerrlin[0][i] / nrcolor[0]) <= 0)
|
||||
testcolor[0][i] = 0;
|
||||
else testcolor[0][i] = (testcolor[0][i] + blockerrlin[0][i] / nrcolor[0]);
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
if((testcolor[1][i] + blockerrlin[1][i] / nrcolor[1]) >= 255)
|
||||
testcolor[1][i] = 255;
|
||||
else testcolor[1][i] = (testcolor[1][i] + blockerrlin[1][i] / nrcolor[1]);
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
int newvalue = testcolor[j][i] + blockerrlin[j][i] / nrcolor[j];
|
||||
if( newvalue <= 0 ) testcolor[j][i] = 0;
|
||||
else if( newvalue >= 255 ) testcolor[j][i] = 255;
|
||||
else testcolor[j][i] = newvalue;
|
||||
}
|
||||
}
|
||||
|
||||
if((abs(testcolor[0][0] - testcolor[1][0]) < 8) && (abs(testcolor[0][1] - testcolor[1][1]) < 4) && (abs(testcolor[0][2] - testcolor[1][2]) < 8))
|
||||
|
@ -259,8 +255,12 @@ static void Image_StoreBlock( byte *blkaddr, byte srccolors[4][4][4], byte *best
|
|||
|
||||
if( color0 < color1 )
|
||||
{
|
||||
tempcolor = color0; color0 = color1; color1 = tempcolor;
|
||||
colorptr = bestcolor[0]; bestcolor[0] = bestcolor[1]; bestcolor[1] = colorptr;
|
||||
tempcolor = color0;
|
||||
color0 = color1;
|
||||
color1 = tempcolor;
|
||||
colorptr = bestcolor[0];
|
||||
bestcolor[0] = bestcolor[1];
|
||||
bestcolor[1] = colorptr;
|
||||
}
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
|
@ -372,7 +372,7 @@ static void Image_StoreBlock( byte *blkaddr, byte srccolors[4][4][4], byte *best
|
|||
}
|
||||
}
|
||||
|
||||
static void Image_EncodeColorBlock( byte *blkaddr, byte srccolors[4][4][4], int numxpixels, int numypixels, uint type )
|
||||
static void Image_EncodeColorBlock( byte *blkaddr, byte srccolors[4][4][4], int numxpixels, int numypixels, uint type, int flags )
|
||||
{
|
||||
// simplistic approach. We need two base colors, simply use the "highest" and the "lowest" color
|
||||
// present in the picture as base colors
|
||||
|
@ -413,6 +413,13 @@ static void Image_EncodeColorBlock( byte *blkaddr, byte srccolors[4][4][4], int
|
|||
}
|
||||
}
|
||||
|
||||
if( type != PF_DXT1 )
|
||||
{
|
||||
// manually set alpha for DXT3 or DXT5
|
||||
if( flags & IMAGE_HAS_ALPHA ) haveAlpha = true;
|
||||
else haveAlpha = false;
|
||||
}
|
||||
|
||||
// make sure the original color values won't get touched...
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
|
@ -431,6 +438,18 @@ static void Image_EncodeColorBlock( byte *blkaddr, byte srccolors[4][4][4], int
|
|||
Image_StoreBlock( blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha );
|
||||
}
|
||||
|
||||
static void Image_StoreAlphaBlock( byte *blkaddr, byte alphabase1, byte alphabase2, byte alphaenc[16] )
|
||||
{
|
||||
*blkaddr++ = alphabase1;
|
||||
*blkaddr++ = alphabase2;
|
||||
*blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5);
|
||||
*blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5);
|
||||
}
|
||||
|
||||
static void Image_EncodeDXT5alpha( byte *blkaddr, byte srccolors[4][4][4], int numxpixels, int numypixels )
|
||||
{
|
||||
byte alphabase[2], alphause[2];
|
||||
|
@ -486,8 +505,8 @@ static void Image_EncodeDXT5alpha( byte *blkaddr, byte srccolors[4][4][4], int n
|
|||
// find best encoding for alpha0 > alpha1
|
||||
// it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true
|
||||
alphablockerror1 = 0x0;
|
||||
alphablockerror2 = 0xFFFFFF;
|
||||
alphablockerror3 = 0xFFFFFF;
|
||||
alphablockerror2 = 0xffffffff;
|
||||
alphablockerror3 = 0xffffffff;
|
||||
|
||||
if( alphaabsmin ) alphause[0] = 0;
|
||||
else alphause[0] = alphabase[0];
|
||||
|
@ -788,38 +807,10 @@ static void Image_EncodeDXT5alpha( byte *blkaddr, byte srccolors[4][4][4], int n
|
|||
|
||||
// write the alpha values and encoding back.
|
||||
if((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3))
|
||||
{
|
||||
*blkaddr++ = alphause[1];
|
||||
*blkaddr++ = alphause[0];
|
||||
*blkaddr++ = alphaenc1[0] | (alphaenc1[1] << 3) | ((alphaenc1[2] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc1[2] >> 2) | (alphaenc1[3] << 1) | (alphaenc1[4] << 4) | ((alphaenc1[5] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc1[5] >> 1) | (alphaenc1[6] << 2) | (alphaenc1[7] << 5);
|
||||
*blkaddr++ = alphaenc1[8] | (alphaenc1[9] << 3) | ((alphaenc1[10] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc1[10] >> 2) | (alphaenc1[11] << 1) | (alphaenc1[12] << 4) | ((alphaenc1[13] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc1[13] >> 1) | (alphaenc1[14] << 2) | (alphaenc1[15] << 5);
|
||||
}
|
||||
Image_StoreAlphaBlock( blkaddr, alphause[1], alphause[0], alphaenc1 );
|
||||
else if( alphablockerror2 <= alphablockerror3 )
|
||||
{
|
||||
*blkaddr++ = alphabase[0];
|
||||
*blkaddr++ = alphabase[1];
|
||||
*blkaddr++ = alphaenc2[0] | (alphaenc2[1] << 3) | ((alphaenc2[2] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc2[2] >> 2) | (alphaenc2[3] << 1) | (alphaenc2[4] << 4) | ((alphaenc2[5] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc2[5] >> 1) | (alphaenc2[6] << 2) | (alphaenc2[7] << 5);
|
||||
*blkaddr++ = alphaenc2[8] | (alphaenc2[9] << 3) | ((alphaenc2[10] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc2[10] >> 2) | (alphaenc2[11] << 1) | (alphaenc2[12] << 4) | ((alphaenc2[13] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc2[13] >> 1) | (alphaenc2[14] << 2) | (alphaenc2[15] << 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
*blkaddr++ = alphatest[0];
|
||||
*blkaddr++ = alphatest[1];
|
||||
*blkaddr++ = alphaenc3[0] | (alphaenc3[1] << 3) | ((alphaenc3[2] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc3[2] >> 2) | (alphaenc3[3] << 1) | (alphaenc3[4] << 4) | ((alphaenc3[5] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc3[5] >> 1) | (alphaenc3[6] << 2) | (alphaenc3[7] << 5);
|
||||
*blkaddr++ = alphaenc3[8] | (alphaenc3[9] << 3) | ((alphaenc3[10] & 3) << 6);
|
||||
*blkaddr++ = (alphaenc3[10] >> 2) | (alphaenc3[11] << 1) | (alphaenc3[12] << 4) | ((alphaenc3[13] & 1) << 7);
|
||||
*blkaddr++ = (alphaenc3[13] >> 1) | (alphaenc3[14] << 2) | (alphaenc3[15] << 5);
|
||||
}
|
||||
Image_StoreAlphaBlock( blkaddr, alphabase[0], alphabase[1], alphaenc2 );
|
||||
else Image_StoreAlphaBlock( blkaddr, (byte)alphatest[0], (byte)alphatest[1], alphaenc3 );
|
||||
}
|
||||
|
||||
static void Image_ExtractColors( byte srcpixels[4][4][4], const byte *srcaddr, int srcRowStride, int numxpixels, int numypixels, int comps )
|
||||
|
@ -1509,9 +1500,9 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
{
|
||||
byte srcpixels[4][4][4];
|
||||
int numxpixels, numypixels;
|
||||
byte *blkaddr, *dest, *flip = NULL;
|
||||
int i, j, width, height;
|
||||
const byte *srcaddr;
|
||||
byte *blkaddr, *dest;
|
||||
size_t dst_size;
|
||||
int srccomps;
|
||||
|
||||
|
@ -1528,14 +1519,13 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
int x, y, c;
|
||||
byte *in = pix->buffer;
|
||||
uint line = pix->width * srccomps;
|
||||
byte *out = Mem_Alloc( zonepool, pix->size ); // alloc src image size
|
||||
|
||||
flip = Mem_Alloc( zonepool, 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++)
|
||||
pix->buffer[y*line+x*srccomps+c] = *in;
|
||||
//FIXME: Mem_Free( pix->buffer );
|
||||
pix->buffer = out;
|
||||
flip[y*line+x*srccomps+c] = *in;
|
||||
pix->buffer = flip;
|
||||
}
|
||||
|
||||
blkaddr = dest = Mem_Alloc( zonepool, dst_size ); // alloc dst image size
|
||||
|
@ -1553,7 +1543,7 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
if( width > i + 3 ) numxpixels = 4;
|
||||
else numxpixels = width - i;
|
||||
Image_ExtractColors( srcpixels, srcaddr, width, numxpixels, numypixels, srccomps );
|
||||
Image_EncodeColorBlock( blkaddr, srcpixels, numxpixels, numypixels, saveformat );
|
||||
Image_EncodeColorBlock( blkaddr, srcpixels, numxpixels, numypixels, saveformat, pix->flags );
|
||||
srcaddr += srccomps * numxpixels;
|
||||
blkaddr += 8;
|
||||
}
|
||||
|
@ -1579,7 +1569,7 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
*blkaddr++ = (srcpixels[2][2][3] >> 4) | (srcpixels[2][3][3] & 0xf0);
|
||||
*blkaddr++ = (srcpixels[3][0][3] >> 4) | (srcpixels[3][1][3] & 0xf0);
|
||||
*blkaddr++ = (srcpixels[3][2][3] >> 4) | (srcpixels[3][3][3] & 0xf0);
|
||||
Image_EncodeColorBlock( blkaddr, srcpixels, numxpixels, numypixels, saveformat );
|
||||
Image_EncodeColorBlock( blkaddr, srcpixels, numxpixels, numypixels, saveformat, pix->flags );
|
||||
srcaddr += srccomps * numxpixels;
|
||||
blkaddr += 8;
|
||||
}
|
||||
|
@ -1599,7 +1589,7 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
|
||||
Image_ExtractColors( srcpixels, srcaddr, width, numxpixels, numypixels, srccomps );
|
||||
Image_EncodeDXT5alpha( blkaddr, srcpixels, numxpixels, numypixels );
|
||||
Image_EncodeColorBlock( blkaddr + 8, srcpixels, numxpixels, numypixels, saveformat );
|
||||
Image_EncodeColorBlock( blkaddr + 8, srcpixels, numxpixels, numypixels, saveformat, pix->flags );
|
||||
srcaddr += srccomps * numxpixels;
|
||||
blkaddr += 16;
|
||||
}
|
||||
|
@ -1612,6 +1602,7 @@ size_t Image_CompressDXT( vfile_t *f, int saveformat, rgbdata_t *pix )
|
|||
}
|
||||
dst_size = VFS_Write( f, dest, dst_size );
|
||||
if( dest ) Mem_Free( dest );
|
||||
if( flip ) Mem_Free( flip );
|
||||
|
||||
return dst_size;
|
||||
}
|
||||
|
|
|
@ -1393,9 +1393,9 @@ void FS_CreateGameInfo( const char *filename )
|
|||
com_strncat(buffer, va("gamemode\t\t\"singleplayer\"\rgamekey\t\t\"%s\"", GI.key), MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nstartmap\t\t\"newmap\"\n\n", MAX_SYSPATH );
|
||||
com_strncat(buffer, "// name or each prog (\"\" - ignore to load)", MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nserver\t\t\"server.dat\"", MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nclient\t\t\"client.dat\"", MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nuimenu\t\t\"uimenu.dat\"", MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nserver\t\t\"vprogs/server.dat\"", MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nclient\t\t\"vprogs/client.dat\"", MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nuimenu\t\t\"vrpogs/uimenu.dat\"", MAX_SYSPATH );
|
||||
|
||||
FS_WriteFile( filename, buffer, com_strlen(buffer));
|
||||
Mem_Free( buffer );
|
||||
|
|
|
@ -309,6 +309,7 @@ enum
|
|||
PRVM_SERVERPROG = 0,
|
||||
PRVM_CLIENTPROG,
|
||||
PRVM_MENUPROG,
|
||||
PRVM_DECOMPILED,
|
||||
PRVM_MAXPROGS, // must be last
|
||||
};
|
||||
|
||||
|
@ -561,6 +562,7 @@ typedef struct prvm_prog_s
|
|||
ddef_t *fielddefs;
|
||||
ddef_t *globaldefs;
|
||||
dstatement_t *statements;
|
||||
includeddatafile_t *sources; // debug version include packed source files
|
||||
int *linenums; // debug versions only
|
||||
type_t *types;
|
||||
int edict_size; // in bytes
|
||||
|
|
|
@ -423,6 +423,7 @@ typedef struct vprogs_exp_s
|
|||
// compiler functions
|
||||
void ( *PrepareDAT )( const char *dir, const char *name );
|
||||
void ( *CompileDAT )( void );
|
||||
bool ( *DecompileDAT )( void );
|
||||
|
||||
// edict operations
|
||||
void (*WriteGlobals)( vfile_t *f );
|
||||
|
|
|
@ -570,7 +570,7 @@ bool VID_ScreenShot( const char *filename, bool levelshot )
|
|||
r_shot->width = r_width->integer;
|
||||
r_shot->height = r_height->integer;
|
||||
r_shot->type = PF_RGB_24_FLIP;
|
||||
r_shot->hint = PF_DXT3; // save format
|
||||
r_shot->hint = PF_RGB_24; // save format
|
||||
r_shot->size = r_shot->width * r_shot->height * 3;
|
||||
r_shot->numLayers = 1;
|
||||
r_shot->numMips = 1;
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
#include "pal_utils.h"
|
||||
|
||||
dll_info_t imglib_dll = { "imglib.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(imglib_exp_t) };
|
||||
dll_info_t vprogs_dll = { "vprogs.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(vprogs_exp_t) };
|
||||
imglib_exp_t *Image;
|
||||
vprogs_exp_t *PRVM;
|
||||
stdlib_api_t com;
|
||||
byte *basepool;
|
||||
byte *zonepool;
|
||||
|
@ -112,7 +114,8 @@ so do it manually
|
|||
*/
|
||||
void InitConvertor ( uint funcname, int argc, char **argv )
|
||||
{
|
||||
launch_t CreateImglib;
|
||||
launch_t CreateImglib, CreateVprogs;
|
||||
string source, gamedir;
|
||||
|
||||
// init pools
|
||||
basepool = Mem_AllocPool( "Temp" );
|
||||
|
@ -123,13 +126,34 @@ void InitConvertor ( uint funcname, int argc, char **argv )
|
|||
CreateImglib = (void *)imglib_dll.main;
|
||||
Image = CreateImglib( &com, NULL ); // second interface not allowed
|
||||
|
||||
FS_InitRootDir(".");
|
||||
Image->Init( funcname ); // initialize image support
|
||||
switch( funcname )
|
||||
{
|
||||
case RIPP_QCCDEC:
|
||||
Sys_LoadLibrary( &vprogs_dll ); // load qcclib
|
||||
CreateVprogs = (void *)vprogs_dll.main;
|
||||
PRVM = CreateVprogs( &com, NULL ); // second interface not allowed
|
||||
|
||||
PRVM->Init( funcname, argc, argv );
|
||||
|
||||
if(!FS_GetParmFromCmdLine("-dir", gamedir ))
|
||||
com.strncpy( gamedir, ".", sizeof(gamedir));
|
||||
if(!FS_GetParmFromCmdLine("+dat", source ))
|
||||
com.strncpy( source, "progs.dat", sizeof(source));
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
PRVM->PrepareDAT( gamedir, source );
|
||||
break;
|
||||
default:
|
||||
FS_InitRootDir(".");
|
||||
Image->Init( funcname ); // initialize image support
|
||||
break;
|
||||
}
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
Msg("Converting ...\n\n");
|
||||
}
|
||||
|
||||
void RunConvertor ( void )
|
||||
void RunConvertor( void )
|
||||
{
|
||||
search_t *search;
|
||||
string errorstring;
|
||||
|
@ -183,9 +207,13 @@ void RunConvertor ( void )
|
|||
AddMask( "*.snd" );
|
||||
AddMask( "*.mus" );
|
||||
break;
|
||||
case RIPP_BSPDEC:
|
||||
case RIPP_QCCDEC:
|
||||
if(PRVM->DecompileDAT())
|
||||
numConvertedRes++;
|
||||
break;
|
||||
case RIPP_BSPDEC:
|
||||
Sys_Break(" not implemented\n");
|
||||
break;
|
||||
case HOST_OFFLINE:
|
||||
default: return;
|
||||
}
|
||||
|
@ -197,7 +225,7 @@ void RunConvertor ( void )
|
|||
}
|
||||
|
||||
// directory to extract
|
||||
com.strncpy(gs_gamedir, "tmpQuArK", sizeof(gs_gamedir));
|
||||
com.strncpy( gs_gamedir, "tmpQuArK", sizeof(gs_gamedir));
|
||||
|
||||
// search by mask
|
||||
for( i = 0; i < num_searchmask; i++)
|
||||
|
@ -214,7 +242,7 @@ void RunConvertor ( void )
|
|||
}
|
||||
Mem_Free( search );
|
||||
}
|
||||
if(numConvertedRes == 0)
|
||||
if( numConvertedRes == 0 )
|
||||
{
|
||||
for(j = 0; j < 16; j++)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ bool PCX_ConvertImage( const char *name, char *buffer, int filesize )
|
|||
MsgDev( D_ERROR, "ConvPCX: (%s) have illegal pixel size '%d'\n", name, pcx.bits_per_pixel );
|
||||
return false;
|
||||
}
|
||||
if(pic.width > 640 || pic.height > 640 || pic.width <= 0 || pic.height <= 0)
|
||||
if(pic.width >= 640 || pic.height >= 480 || pic.width <= 0 || pic.height <= 0)
|
||||
{
|
||||
MsgDev( D_ERROR, "ConvPCX: (%s) dimensions out of range [%dx%d]\n", name, pic.width, pic.height );
|
||||
return false;
|
||||
|
@ -89,7 +89,7 @@ bool PCX_ConvertImage( const char *name, char *buffer, int filesize )
|
|||
for (i = 0; i < s; i++)
|
||||
{
|
||||
p = pbuf[i];
|
||||
if (p == 255)
|
||||
if( p == 255 )
|
||||
{
|
||||
pic.flags |= IMAGE_HAS_ALPHA; // found alpha channel
|
||||
((byte *)&trans[i])[0] = ((byte *)&d_currentpal[0])[0];
|
||||
|
|
|
@ -282,6 +282,7 @@ bool ConvLMP( const char *name, char *buffer, int filesize )
|
|||
pic.buffer = (byte *)Mem_Alloc(zonepool, pic.size );
|
||||
pic.numLayers = 1;
|
||||
pic.type = PF_RGBA_32;
|
||||
pic.hint = PF_RGBA_32;
|
||||
|
||||
// half-life 1.0.0.1 lmp version with palette
|
||||
if( filesize > (int)sizeof(lmp) + pixels )
|
||||
|
@ -301,7 +302,7 @@ bool ConvLMP( const char *name, char *buffer, int filesize )
|
|||
FS_StripExtension((char *)name );
|
||||
Conv_GetPaletteLMP( pal, LUMP_NORMAL );
|
||||
Conv_Copy8bitRGBA( fin, pic.buffer, pixels );
|
||||
Image->SaveImage(va("%s/gfx/%s.tga", gs_gamedir, name ), &pic ); // save converted image
|
||||
Image->SaveImage(va("%s/%s.tga", gs_gamedir, name ), &pic ); // save converted image
|
||||
Mem_Free( pic.buffer ); // release buffer
|
||||
Msg("%s.lmp\n", name ); // echo to console about current image
|
||||
|
||||
|
|
2
todo.log
2
todo.log
|
@ -45,7 +45,7 @@ fopen
|
|||
|
||||
|
||||
NEW RENDERER
|
||||
1. Доделать поддержку DXT-форматов
|
||||
1. Доделать поддержку DXT-форматов OK
|
||||
2. Íîðìàëüíàÿ ëèíêîâêà OpenGL32.dll
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,794 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// pr_decomp.c - progs decompiler
|
||||
//=======================================================================
|
||||
|
||||
#include "vprogs.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
type_t **ofstype;
|
||||
byte *ofsflags;
|
||||
file_t *file;
|
||||
|
||||
char *PR_VarAtOfs( int ofs )
|
||||
{
|
||||
static char buf[MAX_INPUTLINE];
|
||||
int typen;
|
||||
ddef_t *def;
|
||||
|
||||
if( ofsflags[ofs] & 8 ) def = PRVM_ED_GlobalAtOfs( ofs );
|
||||
else def = NULL;
|
||||
|
||||
if( !def )
|
||||
{
|
||||
if( ofsflags[ofs] & 3 )
|
||||
{
|
||||
if( ofstype[ofs] ) com.sprintf( buf, "_v_%s_%i", ofstype[ofs]->name, ofs );
|
||||
else com.sprintf( buf, "_v_%i", ofs );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ofstype[ofs] )
|
||||
{
|
||||
typen = ofstype[ofs]->type;
|
||||
goto evaluate_immediate;
|
||||
}
|
||||
else com.sprintf( buf, "_c_%i", ofs );
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
if(!PRVM_GetString( def->s_name ) || !com.strcmp(PRVM_GetString( def->s_name ), "IMMEDIATE" ))
|
||||
{
|
||||
if( vm.prog->types ) typen = vm.prog->types[def->type & ~DEF_SHARED].type;
|
||||
else typen = def->type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
|
||||
|
||||
evaluate_immediate:
|
||||
switch( typen )
|
||||
{
|
||||
case ev_float:
|
||||
com.sprintf( buf, "%f", PRVM_G_FLOAT(ofs));
|
||||
return buf;
|
||||
case ev_vector:
|
||||
com.sprintf( buf, "\'%f %f %f\'", PRVM_G_FLOAT(ofs+0), PRVM_G_FLOAT(ofs+1), PRVM_G_FLOAT(ofs+2));
|
||||
return buf;
|
||||
case ev_string:
|
||||
{
|
||||
char *s, *s2;
|
||||
|
||||
s = buf;
|
||||
*s++ = '\"';
|
||||
s2 = vm.prog->strings + PRVM_G_INT( ofs );
|
||||
|
||||
if( s2 )
|
||||
{
|
||||
while( *s2 )
|
||||
{
|
||||
if( *s2 == '\n' )
|
||||
{
|
||||
*s++ = '\\';
|
||||
*s++ = 'n';
|
||||
s2++;
|
||||
}
|
||||
else if( *s2 == '\"' )
|
||||
{
|
||||
*s++ = '\\';
|
||||
*s++ = '\"';
|
||||
s2++;
|
||||
}
|
||||
else if( *s2 == '\t' )
|
||||
{
|
||||
*s++ = '\\';
|
||||
*s++ = 't';
|
||||
s2++;
|
||||
}
|
||||
else *s++ = *s2++;
|
||||
}
|
||||
*s++ = '\"';
|
||||
*s++ = '\0';
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
case ev_pointer:
|
||||
com.sprintf( buf, "_c_pointer_%i", ofs );
|
||||
return buf;
|
||||
default:
|
||||
com.sprintf( buf, "_c_%i", ofs );
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return (char *)PRVM_GetString( def->s_name );
|
||||
}
|
||||
|
||||
int PR_ImmediateReadLater( uint ofs, int firstst )
|
||||
{
|
||||
dstatement_t *st;
|
||||
|
||||
|
||||
if( ofsflags[ofs] & 8 ) return false; // this is a global/local/pramater, not a temp
|
||||
if(!(ofsflags[ofs] & 3)) return false; // this is a constant.
|
||||
|
||||
for( st = &((dstatement_t*)vm.prog->statements)[firstst]; ; st++, firstst++ )
|
||||
{
|
||||
// if written, return false, if read, return true.
|
||||
if( st->op >= OP_CALL0 && st->op <= OP_CALL8 )
|
||||
{
|
||||
if( ofs == OFS_RETURN ) return false;
|
||||
if( ofs < OFS_PARM0 + 3*((uint)st->op - OP_CALL0 ))
|
||||
return true;
|
||||
}
|
||||
else if( pr_opcodes[st->op].associative == ASSOC_RIGHT )
|
||||
{
|
||||
if( ofs == st->b ) return false;
|
||||
if( ofs == st->a ) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( st->a == ofs ) return true;
|
||||
if( st->b == ofs ) return true;
|
||||
if( st->c == ofs ) return false;
|
||||
}
|
||||
|
||||
// we missed our chance. (return/done ends any code coherancy).
|
||||
if( st->op == OP_DONE || st->op == OP_RETURN )
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int PR_ProductReadLater( int stnum )
|
||||
{
|
||||
dstatement_t *st = &((dstatement_t*)vm.prog->statements)[stnum];
|
||||
|
||||
if( pr_opcodes[st->op].priority == -1 )
|
||||
{
|
||||
if( st->op >= OP_CALL0 && st->op <= OP_CALL7 )
|
||||
return PR_ImmediateReadLater( OFS_RETURN, stnum + 1 );
|
||||
return false; // these don't have products...
|
||||
}
|
||||
|
||||
if( pr_opcodes[st->op].associative == ASSOC_RIGHT )
|
||||
return PR_ImmediateReadLater( st->b, stnum + 1 );
|
||||
else return PR_ImmediateReadLater( st->c, stnum + 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
PR_WriteStatementProducingOfs
|
||||
|
||||
recursive, works backwards
|
||||
=======================
|
||||
*/
|
||||
void PR_WriteStatementProducingOfs( int lastnum, int firstpossible, int ofs )
|
||||
{
|
||||
dstatement_t *st;
|
||||
ddef_t *def;
|
||||
int i;
|
||||
|
||||
if( ofs == 0 ) longjmp( pr_parse_abort, 1 );
|
||||
|
||||
for( ; lastnum >= firstpossible; lastnum-- )
|
||||
{
|
||||
st = &((dstatement_t*)vm.prog->statements)[lastnum];
|
||||
if( st->op >= OP_CALL0 && st->op < OP_CALL7 )
|
||||
{
|
||||
if( ofs != OFS_RETURN ) continue;
|
||||
PR_WriteStatementProducingOfs( lastnum - 1, firstpossible, st->a );
|
||||
FS_Printf( file, "(" );
|
||||
for( i = 0; i < st->op - OP_CALL0; i++ )
|
||||
{
|
||||
PR_WriteStatementProducingOfs( lastnum-1, firstpossible, OFS_PARM0 + i*3 );
|
||||
if( i != st->op - OP_CALL0 - 1 ) FS_Printf( file, ", " );
|
||||
}
|
||||
FS_Printf( file, ")" );
|
||||
return;
|
||||
}
|
||||
else if( pr_opcodes[st->op].associative == ASSOC_RIGHT )
|
||||
{
|
||||
if( st->b != ofs ) continue;
|
||||
if(!PR_ImmediateReadLater( st->b, lastnum + 1 ))
|
||||
{
|
||||
FS_Printf( file, "(" );
|
||||
PR_WriteStatementProducingOfs( lastnum - 1, firstpossible, st->b );
|
||||
FS_Printf( file, " " );
|
||||
FS_Printf( file, pr_opcodes[st->op].name );
|
||||
FS_Printf( file, " ");
|
||||
PR_WriteStatementProducingOfs( lastnum - 1, firstpossible, st->a );
|
||||
FS_Printf( file, ")" );
|
||||
return;
|
||||
}
|
||||
PR_WriteStatementProducingOfs( lastnum - 1, firstpossible, st->a );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( st->c != ofs ) continue;
|
||||
|
||||
if(!PR_ImmediateReadLater( st->c, lastnum + 1 ))
|
||||
{
|
||||
PR_WriteStatementProducingOfs( lastnum - 1, firstpossible, st->c );
|
||||
FS_Printf( file, " = " );
|
||||
}
|
||||
FS_Printf( file, "(" );
|
||||
PR_WriteStatementProducingOfs( lastnum-1, firstpossible, st->a );
|
||||
|
||||
if( !com.strcmp( pr_opcodes[st->op].name, "." ))
|
||||
FS_Printf( file, pr_opcodes[st->op].name ); // extra spaces around .s are ugly.
|
||||
else
|
||||
{
|
||||
FS_Printf( file, " " );
|
||||
FS_Printf( file, pr_opcodes[st->op].name);
|
||||
FS_Printf( file, " " );
|
||||
}
|
||||
PR_WriteStatementProducingOfs( lastnum-1, firstpossible, st->b );
|
||||
FS_Printf( file, ")" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
def = PRVM_ED_GlobalAtOfs( ofs );
|
||||
if( def )
|
||||
{
|
||||
if(!com.strcmp( PRVM_GetString( def->s_name ), "IMMEDIATE" ))
|
||||
FS_Printf( file, "%s", PR_VarAtOfs( ofs ));
|
||||
else FS_Printf( file, "%s", PRVM_GetString( def->s_name ));
|
||||
}
|
||||
else FS_Printf( file, "%s", PR_VarAtOfs( ofs ));
|
||||
}
|
||||
|
||||
int PR_WriteStatement( int stnum, int firstpossible )
|
||||
{
|
||||
int count, skip;
|
||||
dstatement_t *st = &((dstatement_t*)vm.prog->statements)[stnum];
|
||||
|
||||
switch( st->op )
|
||||
{
|
||||
case OP_IFNOT:
|
||||
count = (signed short)st->b;
|
||||
FS_Printf(file, "if (");
|
||||
PR_WriteStatementProducingOfs( stnum, firstpossible, st->a );
|
||||
FS_Printf( file, ")\r\n" );
|
||||
FS_Printf( file, "{\r\n" );
|
||||
firstpossible = stnum + 1;
|
||||
count--;
|
||||
stnum++;
|
||||
while( count )
|
||||
{
|
||||
if(PR_ProductReadLater( stnum ))
|
||||
{
|
||||
count--;
|
||||
stnum++;
|
||||
continue;
|
||||
}
|
||||
skip = PR_WriteStatement( stnum, firstpossible );
|
||||
count -= skip;
|
||||
stnum += skip;
|
||||
}
|
||||
FS_Printf( file, "}\r\n" );
|
||||
st = &((dstatement_t*)vm.prog->statements)[stnum];
|
||||
if( st->op == OP_GOTO )
|
||||
{
|
||||
count = (signed short)st->b;
|
||||
count--;
|
||||
stnum++;
|
||||
|
||||
FS_Printf( file, "else\r\n" );
|
||||
FS_Printf( file, "{\r\n" );
|
||||
while( count )
|
||||
{
|
||||
if( PR_ProductReadLater( stnum ))
|
||||
{
|
||||
count--;
|
||||
stnum++;
|
||||
continue;
|
||||
}
|
||||
skip = PR_WriteStatement( stnum, firstpossible );
|
||||
count -= skip;
|
||||
stnum += skip;
|
||||
}
|
||||
FS_Printf( file, "}\r\n" );
|
||||
}
|
||||
break;
|
||||
case OP_IF:
|
||||
longjmp( pr_parse_abort, 1 );
|
||||
break;
|
||||
case OP_GOTO:
|
||||
longjmp( pr_parse_abort, 1 );
|
||||
break;
|
||||
case OP_RETURN:
|
||||
case OP_DONE:
|
||||
if( st->a ) PR_WriteStatementProducingOfs( stnum - 1, firstpossible, st->a );
|
||||
break;
|
||||
case OP_CALL0:
|
||||
case OP_CALL1:
|
||||
case OP_CALL2:
|
||||
case OP_CALL3:
|
||||
case OP_CALL4:
|
||||
case OP_CALL5:
|
||||
case OP_CALL6:
|
||||
case OP_CALL7:
|
||||
PR_WriteStatementProducingOfs( stnum, firstpossible, OFS_RETURN );
|
||||
FS_Printf( file, ";\r\n" );
|
||||
break;
|
||||
default:
|
||||
if( pr_opcodes[st->op].associative == ASSOC_RIGHT )
|
||||
PR_WriteStatementProducingOfs( stnum, firstpossible, st->b );
|
||||
else PR_WriteStatementProducingOfs( stnum, firstpossible, st->c );
|
||||
FS_Printf( file, ";\r\n" );
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void PR_WriteAsmStatements( file_t *f, int num, const char *functionname )
|
||||
{
|
||||
int stn = vm.prog->functions[num].first_statement;
|
||||
int fileofs, ofs, i;
|
||||
dstatement_t *st = NULL;
|
||||
ddef_t *def;
|
||||
opcode_t *op;
|
||||
prvm_eval_t *v;
|
||||
|
||||
// we wrote this one...
|
||||
if( !functionname && stn < 0 ) return;
|
||||
|
||||
if( stn >= 0 )
|
||||
{
|
||||
for( stn = vm.prog->functions[num].first_statement; stn < (signed int)vm.prog->progs->numstatements; stn++ )
|
||||
{
|
||||
st = &((dstatement_t*)vm.prog->statements)[stn];
|
||||
if( st->op == OP_DONE || st->op == OP_RETURN )
|
||||
{
|
||||
if( !st->a ) FS_Printf(f, "void(");
|
||||
else if( ofstype[st->a] )
|
||||
{
|
||||
FS_Printf( f, "%s", ofstype[st->a]->name );
|
||||
FS_Printf( f, "(" );
|
||||
}
|
||||
else FS_Printf( f, "function(" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
st = NULL;
|
||||
stn = vm.prog->functions[num].first_statement;
|
||||
}
|
||||
else FS_Printf( f, "function(" );
|
||||
for( ofs = vm.prog->functions[num].parm_start, i = 0; i < vm.prog->functions[num].numparms; i++, ofs += vm.prog->functions[num].parm_size[i] )
|
||||
{
|
||||
ofsflags[ofs] |= 4;
|
||||
|
||||
def = PRVM_ED_GlobalAtOfs( ofs );
|
||||
if( def && stn >= 0 )
|
||||
{
|
||||
if( st ) FS_Printf( f, ", " );
|
||||
st = (void *)0xffff;
|
||||
|
||||
if( !PRVM_GetString( def->s_name ))
|
||||
{
|
||||
char mem[64];
|
||||
com.sprintf( mem, "_p_%i", def->ofs );
|
||||
def->s_name = PRVM_SetTempString( mem );
|
||||
}
|
||||
|
||||
if( vm.prog->types )
|
||||
{
|
||||
FS_Printf( f, "%s %s", vm.prog->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, PRVM_GetString( def->s_name ));
|
||||
}
|
||||
else
|
||||
switch( def->type&~(DEF_SHARED|DEF_SAVEGLOBAL))
|
||||
{
|
||||
case ev_string:
|
||||
FS_Printf( f, "%s %s", "string", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_float:
|
||||
FS_Printf(f, "%s %s", "float", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_entity:
|
||||
FS_Printf(f, "%s %s", "entity", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_vector:
|
||||
FS_Printf(f, "%s %s", "vector", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
default:
|
||||
FS_Printf(f, "%s %s", "unknown", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for( ofs = vm.prog->functions[num].parm_start + vm.prog->functions[num].numparms, i = vm.prog->functions[num].numparms; i < vm.prog->functions[num].locals; i++, ofs++ )
|
||||
ofsflags[ofs] |= 4;
|
||||
|
||||
if( !PRVM_GetString( vm.prog->functions[num].s_name ))
|
||||
{
|
||||
if( !functionname )
|
||||
{
|
||||
char mem[64];
|
||||
com.sprintf( mem, "_bi_%i", num );
|
||||
vm.prog->functions[num].s_name = PRVM_SetTempString( mem );
|
||||
}
|
||||
else vm.prog->functions[num].s_name = PRVM_SetTempString( functionname );
|
||||
}
|
||||
|
||||
FS_Printf( f, ") %s", PRVM_GetString( vm.prog->functions[num].s_name ));
|
||||
|
||||
if( stn < 0 )
|
||||
{
|
||||
stn *= -1;
|
||||
FS_Printf( f, " = #%i;\r\n", stn );
|
||||
return;
|
||||
}
|
||||
|
||||
if( functionname )
|
||||
{
|
||||
// parsing defs
|
||||
FS_Printf(f, ";\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fileofs = FS_Seek( f, 0, SEEK_CUR );
|
||||
if( setjmp(pr_parse_abort))
|
||||
{
|
||||
FS_Printf( f, "*/\r\n" );
|
||||
FS_Printf( f, " = asm {\r\n" );
|
||||
|
||||
stn = vm.prog->functions[num].first_statement;
|
||||
for( ofs = vm.prog->functions[num].parm_start + vm.prog->functions[num].numparms, i = vm.prog->functions[num].numparms; i < vm.prog->functions[num].locals; i++, ofs++ )
|
||||
{
|
||||
def = PRVM_ED_GlobalAtOfs( ofs );
|
||||
if( def )
|
||||
{
|
||||
v = (prvm_eval_t *)&((int *)vm.prog->globals.gp)[def->ofs];
|
||||
if( vm.prog->types )
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", vm.prog->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, PRVM_GetString( def->s_name ));
|
||||
else
|
||||
{
|
||||
if(!PRVM_GetString( def->s_name ))
|
||||
{
|
||||
char mem[64];
|
||||
com.sprintf( mem, "_l_%i", def->ofs );
|
||||
def->s_name = PRVM_SetTempString( mem );
|
||||
}
|
||||
|
||||
switch( def->type&~(DEF_SHARED|DEF_SAVEGLOBAL))
|
||||
{
|
||||
case ev_string:
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", "string", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_float:
|
||||
FS_Printf(f, "\tlocal %s %s;\r\n", "float", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_entity:
|
||||
FS_Printf(f, "\tlocal %s %s;\r\n", "entity", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_vector:
|
||||
if(!VectorIsNull( v->vector ))
|
||||
FS_Printf( f, "\tlocal vector %s = '%f %f %f';\r\n", PRVM_GetString( def->s_name ), v->vector[0], v->vector[1], v->vector[2] );
|
||||
else FS_Printf( f, "\tlocal %s %s;\r\n", "vector", PRVM_GetString( def->s_name ));
|
||||
ofs += 2; // skip floats;
|
||||
break;
|
||||
default:
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", "unknown", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
st = &((dstatement_t*)vm.prog->statements)[stn];
|
||||
if( !st->op ) break; // end of function statement!
|
||||
|
||||
op = &pr_opcodes[st->op];
|
||||
FS_Printf( f, "\t%s", op->opname );
|
||||
|
||||
if( op->priority == -1 && op->associative == ASSOC_RIGHT )
|
||||
{
|
||||
// last param is a goto
|
||||
if( op->type_b == &type_void )
|
||||
{
|
||||
if( st->a ) FS_Printf( f, " %i", (signed short)st->a );
|
||||
}
|
||||
else if( op->type_c == &type_void )
|
||||
{
|
||||
if( st->a ) FS_Printf( f, " %s", PR_VarAtOfs(st->a));
|
||||
if( st->b ) FS_Printf( f, " %i", (signed short)st->b );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( st->a ) FS_Printf( f, " %s", PR_VarAtOfs(st->a));
|
||||
if( st->b ) FS_Printf( f, " %s", PR_VarAtOfs(st->b));
|
||||
if( st->c ) FS_Printf( f, " %i", (signed short)st->c ); // rightness means it uses a as c
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( st->a )
|
||||
{
|
||||
if( op->type_a == NULL ) FS_Printf( f, " %i", (signed short)st->a );
|
||||
else FS_Printf(f, " %s", PR_VarAtOfs(st->a));
|
||||
}
|
||||
if( st->b )
|
||||
{
|
||||
if( op->type_b == NULL ) FS_Printf( f, " %i", (signed short)st->b );
|
||||
else FS_Printf( f, " %s", PR_VarAtOfs(st->b));
|
||||
}
|
||||
if( st->c && op->associative != ASSOC_RIGHT )
|
||||
{
|
||||
// rightness means it uses a as c
|
||||
if( op->type_c == NULL ) FS_Printf( f, " %i", (signed short)st->c );
|
||||
else FS_Printf( f, " %s", PR_VarAtOfs(st->c));
|
||||
}
|
||||
}
|
||||
FS_Printf( f, ";\r\n" );
|
||||
stn++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !com.strcmp(PRVM_GetString( vm.prog->functions[num].s_name ), "SUB_Remove" ))
|
||||
file = NULL;
|
||||
file = f;
|
||||
FS_Printf( f, "/*\r\n" );
|
||||
|
||||
FS_Printf( f, " =\r\n{\r\n" );
|
||||
|
||||
for( ofs = vm.prog->functions[num].parm_start + vm.prog->functions[num].numparms, i = vm.prog->functions[num].numparms; i < vm.prog->functions[num].locals; i++, ofs++ )
|
||||
{
|
||||
def = PRVM_ED_GlobalAtOfs( ofs );
|
||||
if( def )
|
||||
{
|
||||
v = (prvm_eval_t *)&((int *)vm.prog->globals.gp)[def->ofs];
|
||||
if( vm.prog->types) FS_Printf( f, "\tlocal %s %s;\r\n", vm.prog->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, PRVM_GetString( def->s_name ));
|
||||
else
|
||||
{
|
||||
if(!PRVM_GetString( def->s_name ))
|
||||
{
|
||||
char mem[64];
|
||||
com.sprintf( mem, "_l_%i", def->ofs );
|
||||
def->s_name = PRVM_SetTempString( mem );
|
||||
}
|
||||
|
||||
switch( def->type&~(DEF_SHARED|DEF_SAVEGLOBAL))
|
||||
{
|
||||
case ev_string:
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", "string", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_float:
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", "float", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_entity:
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", "entity", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
case ev_vector:
|
||||
if(!VectorIsNull( v->vector ))
|
||||
FS_Printf( f, "\tlocal vector %s = '%f %f %f';\r\n", PRVM_GetString( def->s_name ), v->vector[0], v->vector[1], v->vector[2] );
|
||||
else FS_Printf( f, "\tlocal %s %s;\r\n", "vector", PRVM_GetString( def->s_name ));
|
||||
ofs += 2; // skip floats;
|
||||
break;
|
||||
default:
|
||||
FS_Printf( f, "\tlocal %s %s;\r\n", "unknown", PRVM_GetString( def->s_name ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( stn = vm.prog->functions[num].first_statement; stn < (signed int)vm.prog->progs->numstatements; stn++ )
|
||||
{
|
||||
if( PR_ProductReadLater( stn )) continue;
|
||||
st = &((dstatement_t*)vm.prog->statements)[stn];
|
||||
if( !st->op ) break;
|
||||
PR_WriteStatement( stn, vm.prog->functions[num].first_statement );
|
||||
}
|
||||
longjmp( pr_parse_abort, 1 );
|
||||
}
|
||||
FS_Printf( f, "};\r\n" );
|
||||
}
|
||||
|
||||
|
||||
void PR_FigureOutTypes( void )
|
||||
{
|
||||
ddef_t *def;
|
||||
opcode_t *op;
|
||||
uint i, p;
|
||||
dstatement_t *st;
|
||||
int parmofs[MAX_PARMS];
|
||||
|
||||
ofstype = Qalloc(sizeof(*ofstype ) * 65535);
|
||||
ofsflags = Qalloc(sizeof(*ofsflags) * 65535);
|
||||
|
||||
maxtypeinfos = 256;
|
||||
qcc_typeinfo = (void *)Qalloc( sizeof(type_t) * maxtypeinfos );
|
||||
numtypeinfos = 0;
|
||||
|
||||
memset( ofstype, 0, sizeof(*ofstype)*65535);
|
||||
memset( ofsflags, 0, sizeof(*ofsflags)*65535);
|
||||
|
||||
type_void = PR_NewType( "void", ev_void );
|
||||
type_string = PR_NewType( "string", ev_string );
|
||||
type_float = PR_NewType( "float", ev_float );
|
||||
type_vector = PR_NewType( "vector", ev_vector );
|
||||
type_entity = PR_NewType( "entity", ev_entity );
|
||||
type_field = PR_NewType( "field", ev_field );
|
||||
type_function = PR_NewType( "function", ev_function );
|
||||
type_pointer = PR_NewType( "pointer", ev_pointer );
|
||||
type_integer = PR_NewType( "integer", ev_integer );
|
||||
type_floatfield = PR_NewType("fieldfloat", ev_field);
|
||||
type_floatfield->aux_type = type_float;
|
||||
type_pointer->aux_type = PR_NewType( "pointeraux", ev_float );
|
||||
type_function->aux_type = type_void;
|
||||
|
||||
for( i = 0, st = vm.prog->statements; i < vm.prog->progs->numstatements; i++, st++ )
|
||||
{
|
||||
op = &pr_opcodes[st->op];
|
||||
if( st->op >= OP_CALL1 && st->op <= OP_CALL8 )
|
||||
{
|
||||
for( p = 0; p < (uint)st->op - OP_CALL0; p++ )
|
||||
ofstype[parmofs[p]] = ofstype[OFS_PARM0 + p * 3];
|
||||
}
|
||||
else if( op->associative == ASSOC_RIGHT )
|
||||
{
|
||||
// assignment
|
||||
ofsflags[st->b] |= 1;
|
||||
if( st->b >= OFS_PARM0 && st->b < RESERVED_OFS )
|
||||
parmofs[(st->b-OFS_PARM0)/3] = st->a;
|
||||
|
||||
if( op->type_c && op->type_c != &type_void )
|
||||
ofstype[st->a] = *op->type_c;
|
||||
if( op->type_b && op->type_b != &type_void )
|
||||
ofstype[st->b] = *op->type_b;
|
||||
}
|
||||
else if( op->type_c )
|
||||
{
|
||||
ofsflags[st->c] |= 2;
|
||||
|
||||
if( st->c >= OFS_PARM0 && st->b < RESERVED_OFS ) // too complicated
|
||||
parmofs[(st->b-OFS_PARM0)/3] = 0;
|
||||
if( op->type_a && op->type_a != &type_void )
|
||||
ofstype[st->a] = *op->type_a;
|
||||
if( op->type_b && op->type_b != &type_void )
|
||||
ofstype[st->b] = *op->type_b;
|
||||
if( op->type_c && op->type_c != &type_void )
|
||||
ofstype[st->c] = *op->type_c;
|
||||
}
|
||||
}
|
||||
for( i = 0; i < vm.prog->progs->numglobaldefs; i++ )
|
||||
{
|
||||
def = &vm.prog->globaldefs[i];
|
||||
ofsflags[def->ofs] |= 8;
|
||||
switch( def->type )
|
||||
{
|
||||
case ev_float:
|
||||
ofstype[def->ofs] = type_float;
|
||||
break;
|
||||
case ev_string:
|
||||
ofstype[def->ofs] = type_string;
|
||||
break;
|
||||
case ev_vector:
|
||||
ofstype[def->ofs] = type_vector;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PR_Decompile( void )
|
||||
{
|
||||
uint i, fld = 0;
|
||||
int type;
|
||||
prvm_eval_t *v;
|
||||
file_t *f;
|
||||
|
||||
if(!FS_FileExists( sourcefilename ))
|
||||
return false;
|
||||
|
||||
PRVM_LoadProgs( sourcefilename, 0, NULL, 0, NULL );
|
||||
f = FS_Open( "qcdtest/defs.qc", "w" );
|
||||
FS_Print( f, "// decompiled code can contain little type info.\r\n" );
|
||||
|
||||
PR_FigureOutTypes();
|
||||
|
||||
for( i = 1; i < vm.prog->progs->numglobaldefs; i++ )
|
||||
{
|
||||
if( !com.strcmp(PRVM_GetString( vm.prog->globaldefs[i].s_name ), "IMMEDIATE" ))
|
||||
continue;
|
||||
|
||||
if( ofsflags[vm.prog->globaldefs[i].ofs] & 4 )
|
||||
continue; // this is a local.
|
||||
|
||||
if( vm.prog->types )
|
||||
type = vm.prog->types[vm.prog->globaldefs[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
|
||||
else type = vm.prog->globaldefs[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
|
||||
v = (prvm_eval_t *)&((int *)vm.prog->globals.gp)[vm.prog->globaldefs[i].ofs];
|
||||
|
||||
if(!PRVM_GetString( vm.prog->globaldefs[i].s_name ))
|
||||
{
|
||||
char mem[64];
|
||||
if( ofsflags[vm.prog->globaldefs[i].ofs] & 3 )
|
||||
{
|
||||
ofsflags[vm.prog->globaldefs[i].ofs] &= ~8;
|
||||
continue; // this is a constant...
|
||||
}
|
||||
|
||||
com.sprintf( mem, "_g_%i", vm.prog->globaldefs[i].ofs );
|
||||
vm.prog->globaldefs[i].s_name = PRVM_SetTempString( mem );
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case ev_void:
|
||||
FS_Printf( f, "void %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_string:
|
||||
if( v->string && *(vm.prog->strings + v->_int ))
|
||||
FS_Printf( f, "string %s = \"%s\";\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ), PRVM_GetString( v->_int ));
|
||||
else FS_Printf( f, "string %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_float:
|
||||
if( v->_float ) FS_Printf( f, "float %s = %f;\r\n", PRVM_GetString( vm.prog->globaldefs[i].s_name ), v->_float);
|
||||
else FS_Printf( f, "float %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_vector:
|
||||
if(!VectorIsNull( v->vector ))
|
||||
FS_Printf( f, "vector %s = '%f %f %f';\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ), v->vector[0], v->vector[1], v->vector[2]);
|
||||
else FS_Printf( f, "vector %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
i += 3; // skip the floats
|
||||
break;
|
||||
case ev_entity:
|
||||
FS_Printf( f, "entity %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_field:
|
||||
fld++; // wierd
|
||||
if( !v->_int ) FS_Printf( f, "var " );
|
||||
switch( vm.prog->fielddefs[fld].type )
|
||||
{
|
||||
case ev_string:
|
||||
FS_Printf(f, ".string %s;", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_float:
|
||||
FS_Printf(f, ".float %s;", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_vector:
|
||||
FS_Printf(f, ".float %s;", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_entity:
|
||||
FS_Printf(f, ".float %s;", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_function:
|
||||
FS_Printf(f, ".void() %s;", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
default:
|
||||
FS_Printf(f, "field %s;", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
}
|
||||
if( v->_int ) FS_Printf( f, "/* %i */", v->_int );
|
||||
FS_Printf( f, "\r\n" );
|
||||
break;
|
||||
case ev_function:
|
||||
// wierd
|
||||
PR_WriteAsmStatements( f, ((int *)vm.prog->globals.gp)[vm.prog->globaldefs[i].ofs], PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_pointer:
|
||||
FS_Printf( f, "pointer %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_integer:
|
||||
FS_Printf( f, "integer %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_union:
|
||||
FS_Printf(f, "union %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
case ev_struct:
|
||||
FS_Printf(f, "struct %s;\r\n", PRVM_GetString(vm.prog->globaldefs[i].s_name ));
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
for( i = 0; i < vm.prog->progs->numfunctions; i++ )
|
||||
{
|
||||
PR_WriteAsmStatements( f, i, NULL );
|
||||
}
|
||||
FS_Close( f );
|
||||
|
||||
return true;
|
||||
}
|
|
@ -259,15 +259,15 @@ void PRVM_ED_Free (edict_t *ed)
|
|||
PRVM_ED_GlobalAtOfs
|
||||
============
|
||||
*/
|
||||
ddef_t *PRVM_ED_GlobalAtOfs (int ofs)
|
||||
ddef_t *PRVM_ED_GlobalAtOfs( int ofs )
|
||||
{
|
||||
ddef_t *def;
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<vm.prog->progs->numglobaldefs ; i++)
|
||||
for( i = 0; i < vm.prog->progs->numglobaldefs; i++ )
|
||||
{
|
||||
def = &vm.prog->globaldefs[i];
|
||||
if (def->ofs == ofs)
|
||||
if( def->ofs == ofs )
|
||||
return def;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1244,7 +1244,7 @@ void PRVM_LoadLNO( const char *progname )
|
|||
PRVM_LoadProgs
|
||||
===============
|
||||
*/
|
||||
void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int numedfields, fields_t *ed_field)
|
||||
void PRVM_LoadProgs( const char *filename, int numedfunc, char **ed_func, int numedfields, fields_t *ed_field )
|
||||
{
|
||||
dstatement_t *st;
|
||||
ddef_t *infielddefs;
|
||||
|
@ -1259,16 +1259,13 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
}
|
||||
|
||||
if( vm.prog->progs ) Mem_Free( vm.prog->progs ); // release progs file
|
||||
vm.prog->progs = (dprograms_t *)FS_LoadFile(va("vprogs/%s", filename ), &filesize);
|
||||
vm.prog->progs = (dprograms_t *)FS_LoadFile(va("%s", filename ), &filesize);
|
||||
|
||||
if (vm.prog->progs == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
|
||||
PRVM_ERROR("PRVM_LoadProgs: couldn't load %s for %s\n", filename, PRVM_NAME);
|
||||
|
||||
MsgDev(D_INFO, "%s programs occupy %iK.\n", PRVM_NAME, filesize/1024);
|
||||
vm.prog->filecrc = CRC_Block((byte *)vm.prog->progs, filesize);
|
||||
|
||||
// byte swap the header
|
||||
SwapBlock((int *)vm.prog->progs, sizeof(*vm.prog->progs));
|
||||
SwapBlock((int *)vm.prog->progs, sizeof(*vm.prog->progs)); // byte swap the header
|
||||
|
||||
switch( vm.prog->progs->version )
|
||||
{
|
||||
|
@ -1276,29 +1273,27 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
vm.prog->intsize = 16;
|
||||
break;
|
||||
case FPROGS_VERSION:
|
||||
if(vm.prog->progs->ident == VPROGSHEADER16)
|
||||
if( vm.prog->progs->ident == VPROGSHEADER16 )
|
||||
vm.prog->intsize = 16;
|
||||
if(vm.prog->progs->ident == VPROGSHEADER32)
|
||||
if( vm.prog->progs->ident == VPROGSHEADER32 )
|
||||
vm.prog->intsize = 32;
|
||||
break;
|
||||
case VPROGS_VERSION:
|
||||
default:
|
||||
PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, vm.prog->progs->version, VPROGS_VERSION);
|
||||
PRVM_ERROR( "%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, vm.prog->progs->version, VPROGS_VERSION);
|
||||
break;
|
||||
}
|
||||
|
||||
// try to recognize progs.dat by crc
|
||||
switch(vm.prog->progs->crc)
|
||||
if( PRVM_GetProgNr() == PRVM_DECOMPILED )
|
||||
{
|
||||
case PROG_CRC_SERVER:
|
||||
case PROG_CRC_CLIENT:
|
||||
case PROG_CRC_UIMENU:
|
||||
break;
|
||||
default:
|
||||
PRVM_ERROR("%s: %s system vars have been modified, progdefs.h is out of date", PRVM_NAME, filename);
|
||||
break;
|
||||
MsgDev(D_INFO, "Prepare %s [CRC %d]\n", filename, vm.prog->progs->crc );
|
||||
}
|
||||
MsgDev(D_INFO, "Loading %s [CRC %d]\n", filename, vm.prog->progs->crc );
|
||||
else if( vm.prog->progs->crc != vm.prog->filecrc )
|
||||
{
|
||||
PRVM_ERROR("%s: %s system vars have been modified, progdefs.h is out of date %d\n", PRVM_NAME, filename );
|
||||
}
|
||||
else MsgDev(D_INFO, "Loading %s [CRC %d]\n", filename, vm.prog->progs->crc );
|
||||
|
||||
// set initial pointers
|
||||
vm.prog->statements = (dstatement_t *)((byte *)vm.prog->progs + vm.prog->progs->ofs_statements);
|
||||
|
@ -1308,12 +1303,19 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
vm.prog->strings = (char *)vm.prog->progs + vm.prog->progs->ofs_strings;
|
||||
vm.prog->globals.gp = (float *)((byte *)vm.prog->progs + vm.prog->progs->ofs_globals);
|
||||
|
||||
// debug info
|
||||
if(vm.prog->progs->ofslinenums) vm.prog->linenums = (int *)((byte *)vm.prog->progs + vm.prog->progs->ofslinenums);
|
||||
if(vm.prog->progs->ofs_types) vm.prog->types = (type_t *)((byte *)vm.prog->progs + vm.prog->progs->ofs_types);
|
||||
if( vm.prog->progs->version >= FPROGS_VERSION )
|
||||
{
|
||||
// debug info
|
||||
if( vm.prog->progs->ofsfiles )
|
||||
vm.prog->sources = (includeddatafile_t*)((byte *)vm.prog->progs + vm.prog->progs->ofsfiles);
|
||||
if( vm.prog->progs->ofslinenums )
|
||||
vm.prog->linenums = (int *)((byte *)vm.prog->progs + vm.prog->progs->ofslinenums);
|
||||
if( vm.prog->progs->ofs_types )
|
||||
vm.prog->types = (type_t *)((byte *)vm.prog->progs + vm.prog->progs->ofs_types);
|
||||
}
|
||||
|
||||
// decompress progs if needed
|
||||
if (vm.prog->progs->blockscompressed & COMP_STATEMENTS)
|
||||
if( vm.prog->progs->blockscompressed & COMP_STATEMENTS )
|
||||
{
|
||||
switch(vm.prog->intsize)
|
||||
{
|
||||
|
@ -1334,7 +1336,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->progs->blockscompressed & COMP_DEFS)
|
||||
if( vm.prog->progs->blockscompressed & COMP_DEFS )
|
||||
{
|
||||
switch(vm.prog->intsize)
|
||||
{
|
||||
|
@ -1355,7 +1357,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->progs->blockscompressed & COMP_FIELDS)
|
||||
if( vm.prog->progs->blockscompressed & COMP_FIELDS )
|
||||
{
|
||||
switch(vm.prog->intsize)
|
||||
{
|
||||
|
@ -1376,7 +1378,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->progs->blockscompressed & COMP_FUNCTIONS)
|
||||
if( vm.prog->progs->blockscompressed & COMP_FUNCTIONS )
|
||||
{
|
||||
len = sizeof(dfunction_t) * vm.prog->progs->numfunctions;
|
||||
complen = LittleLong(*(int*)dfunctions);
|
||||
|
@ -1388,7 +1390,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->progs->blockscompressed & COMP_STRINGS)
|
||||
if( vm.prog->progs->blockscompressed & COMP_STRINGS )
|
||||
{
|
||||
len = sizeof(char) * vm.prog->progs->numstrings;
|
||||
complen = LittleLong(*(int*)vm.prog->strings);
|
||||
|
@ -1402,7 +1404,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->progs->blockscompressed & COMP_GLOBALS)
|
||||
if( vm.prog->progs->blockscompressed & COMP_GLOBALS )
|
||||
{
|
||||
len = sizeof(float) * vm.prog->progs->numglobals;
|
||||
complen = LittleLong(*(int*)vm.prog->globals.gp);
|
||||
|
@ -1414,7 +1416,19 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->linenums && vm.prog->progs->blockscompressed & COMP_LINENUMS)
|
||||
if( vm.prog->sources ) // source always are packed
|
||||
{
|
||||
int i, numsources = LittleLong(*(int*)vm.prog->sources);
|
||||
includeddatafile_t *src = (includeddatafile_t *)(((int *)vm.prog->sources)+1);
|
||||
|
||||
for( i = 0; i < numsources; i++, src++ )
|
||||
{
|
||||
Msg("Source: %s\n", src->filename );
|
||||
Msg("Ofs, size: %d, %d\n", src->ofs, src->size );
|
||||
}
|
||||
}
|
||||
|
||||
if( vm.prog->linenums && vm.prog->progs->blockscompressed & COMP_LINENUMS )
|
||||
{
|
||||
len = sizeof(int) * vm.prog->progs->numstatements;
|
||||
complen = LittleLong(*(int*)vm.prog->linenums);
|
||||
|
@ -1426,7 +1440,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
filesize += len - complen - sizeof(int); //merge filesize
|
||||
}
|
||||
|
||||
if (vm.prog->types && vm.prog->progs->blockscompressed & COMP_TYPES)
|
||||
if( vm.prog->types && vm.prog->progs->blockscompressed & COMP_TYPES )
|
||||
{
|
||||
len = sizeof(type_t) * vm.prog->progs->numtypes;
|
||||
complen = LittleLong(*(int*)vm.prog->types);
|
||||
|
@ -1440,9 +1454,9 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
|
||||
vm.prog->stringssize = 0;
|
||||
|
||||
for (i = 0; vm.prog->stringssize < vm.prog->progs->numstrings; i++)
|
||||
for( i = 0; vm.prog->stringssize < vm.prog->progs->numstrings; i++ )
|
||||
{
|
||||
if (vm.prog->progs->ofs_strings + vm.prog->stringssize >= (int)filesize)
|
||||
if( vm.prog->progs->ofs_strings + vm.prog->stringssize >= (int)filesize )
|
||||
PRVM_ERROR ("%s: %s strings go past end of file", PRVM_NAME, filename);
|
||||
vm.prog->stringssize += (int)com.strlen(vm.prog->strings + vm.prog->stringssize) + 1;
|
||||
}
|
||||
|
@ -1495,16 +1509,16 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
}
|
||||
|
||||
// append the ed fields
|
||||
for (i = 0; i < (int)numedfields; i++)
|
||||
for( i = 0; i < (int)numedfields; i++ )
|
||||
{
|
||||
vm.prog->fielddefs[vm.prog->progs->numfielddefs].type = ed_field[i].type;
|
||||
vm.prog->fielddefs[vm.prog->progs->numfielddefs].ofs = ed_field[i].ofs;
|
||||
vm.prog->fielddefs[vm.prog->progs->numfielddefs].s_name = PRVM_SetEngineString(ed_field[i].name);
|
||||
vm.prog->fielddefs[vm.prog->progs->numfielddefs].s_name = PRVM_SetEngineString( ed_field[i].name );
|
||||
}
|
||||
|
||||
// check ed functions
|
||||
for(i=0 ; i < numedfunc ; i++)
|
||||
if(PRVM_ED_FindFunction(ed_func[i]) == 0)
|
||||
for( i = 0; i < numedfunc; i++ )
|
||||
if( PRVM_ED_FindFunction( ed_func[i] ) == 0 )
|
||||
PRVM_ERROR("%s: %s not found in %s",PRVM_NAME, ed_func[i], filename);
|
||||
|
||||
for (i=0 ; i<vm.prog->progs->numglobals ; i++)
|
||||
|
@ -1669,7 +1683,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
|
|||
|
||||
// set flags & ddef_ts in prog
|
||||
vm.prog->flag = 0;
|
||||
vm.prog->pev = PRVM_ED_FindGlobal("pev"); // critical stuff
|
||||
vm.prog->pev = PRVM_ED_FindGlobal( "pev" ); // critical stuff
|
||||
|
||||
if( PRVM_ED_FindGlobal("time") && PRVM_ED_FindGlobal("time")->type & ev_float )
|
||||
vm.prog->time = &PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs);
|
||||
|
|
|
@ -563,6 +563,13 @@ extern int numtypeinfos;
|
|||
extern int maxtypeinfos;
|
||||
extern int numtemps;
|
||||
|
||||
//
|
||||
// pr_main.c
|
||||
//
|
||||
void PR_InitCompile( const char *name );
|
||||
void PR_InitDecompile( const char *name );
|
||||
bool PRVM_DecompileProgs( void );
|
||||
|
||||
//
|
||||
// pr_utils.c
|
||||
//
|
||||
|
@ -660,4 +667,9 @@ void PR_BeginCompilation ( void );
|
|||
bool PR_ContinueCompile ( void );
|
||||
void PR_FinishCompilation ( void );
|
||||
|
||||
//
|
||||
// pr_decomp.c
|
||||
//
|
||||
bool PR_Decompile( void );
|
||||
|
||||
#endif//PR_LOCAL_H
|
|
@ -35,18 +35,19 @@ int *statement_linenums;
|
|||
char sourcedir[MAX_SYSPATH];
|
||||
cachedsourcefile_t *sourcefile;
|
||||
dfunction_t *functions;
|
||||
int numfunctions;
|
||||
ddef_t *qcc_globals;
|
||||
int numglobaldefs;
|
||||
ddef_t *fields;
|
||||
int numfielddefs;
|
||||
bool pr_warning[WARN_MAX];
|
||||
int target_version;
|
||||
bool bodylessfuncs;
|
||||
type_t *qcc_typeinfo;
|
||||
int numtypeinfos;
|
||||
int maxtypeinfos;
|
||||
int prvm_developer;
|
||||
int numfunctions;
|
||||
ddef_t *qcc_globals;
|
||||
int numglobaldefs;
|
||||
ddef_t *fields;
|
||||
int numfielddefs;
|
||||
bool pr_warning[WARN_MAX];
|
||||
int target_version;
|
||||
bool bodylessfuncs;
|
||||
type_t *qcc_typeinfo;
|
||||
int numtypeinfos;
|
||||
int maxtypeinfos;
|
||||
int prvm_developer;
|
||||
int host_instance;
|
||||
vprogs_exp_t vm;
|
||||
|
||||
hashtable_t compconstantstable;
|
||||
|
@ -61,7 +62,7 @@ cvar_t *prvm_traceqc;
|
|||
cvar_t *prvm_boundscheck;
|
||||
cvar_t *prvm_statementprofiling;
|
||||
|
||||
void PR_SetDefaultProperties (void)
|
||||
void PR_SetDefaultProperties( void )
|
||||
{
|
||||
const_t *cnst;
|
||||
int i, j;
|
||||
|
@ -158,7 +159,7 @@ PR_Init
|
|||
initialize compiler and hash tables
|
||||
===================
|
||||
*/
|
||||
void PR_Init( const char *name )
|
||||
void PR_InitCompile( const char *name )
|
||||
{
|
||||
static char parmname[12][MAX_PARMS];
|
||||
static temp_t ret_temp;
|
||||
|
@ -245,6 +246,28 @@ void PR_Init( const char *name )
|
|||
}
|
||||
}
|
||||
|
||||
void PR_InitDecompile( const char *name )
|
||||
{
|
||||
string progsname;
|
||||
|
||||
com.strncpy( sourcefilename, name, sizeof(sourcefilename));
|
||||
FS_FileBase( name, progsname );
|
||||
|
||||
PRVM_InitProg( PRVM_DECOMPILED );
|
||||
|
||||
vm.prog->reserved_edicts = 1;
|
||||
vm.prog->loadintoworld = true;
|
||||
vm.prog->name = copystring( progsname );
|
||||
vm.prog->builtins = NULL;
|
||||
vm.prog->numbuiltins = 0;
|
||||
vm.prog->max_edicts = 4096;
|
||||
vm.prog->limit_edicts = 4096;
|
||||
vm.prog->edictprivate_size = sizeof(vm_edict_t);
|
||||
vm.prog->error_cmd = VM_Error;
|
||||
vm.prog->flag |= PRVM_OP_STATE; // enable op_state feature
|
||||
vm.prog->progs_mempool = qccpool;
|
||||
}
|
||||
|
||||
void PRVM_Init( uint funcname, int argc, char **argv )
|
||||
{
|
||||
char dev_level[4];
|
||||
|
@ -253,6 +276,7 @@ void PRVM_Init( uint funcname, int argc, char **argv )
|
|||
com_argv = argv;
|
||||
|
||||
qccpool = Mem_AllocPool( "VM progs" );
|
||||
host_instance = funcname;
|
||||
|
||||
if(FS_GetParmFromCmdLine("-dev", dev_level ))
|
||||
prvm_developer = com.atoi(dev_level);
|
||||
|
@ -274,7 +298,7 @@ void PRVM_Init( uint funcname, int argc, char **argv )
|
|||
prvm_statementprofiling = Cvar_Get ("prvm_statementprofiling", "0", 0, "counts how many times each QC statement has been executed" );
|
||||
prvm_maxedicts = Cvar_Get( "prvm_maxedicts", "4096", CVAR_SYSTEMINFO, "user limit edicts number fof server, client and renderer, absolute limit 65535" );
|
||||
|
||||
if( funcname == HOST_NORMAL || funcname == HOST_DEDICATED )
|
||||
if( host_instance == HOST_NORMAL || host_instance == HOST_DEDICATED )
|
||||
{
|
||||
// dump internal copies of progs into hdd if missing
|
||||
if(!FS_FileExists("vprogs/server.dat")) FS_WriteFile( "vprogs/server.dat", server_dat, sizeof(server_dat));
|
||||
|
@ -290,8 +314,24 @@ void PRVM_Shutdown( void )
|
|||
|
||||
void PRVM_PrepareProgs( const char *dir, const char *name )
|
||||
{
|
||||
FS_InitRootDir((char *)dir);
|
||||
PR_Init( name );
|
||||
switch( host_instance )
|
||||
{
|
||||
case COMP_QCCLIB:
|
||||
FS_InitRootDir((char *)dir);
|
||||
PR_InitCompile( name );
|
||||
break;
|
||||
case RIPP_QCCDEC:
|
||||
FS_InitRootDir((char *)dir);
|
||||
PR_InitDecompile( name );
|
||||
break;
|
||||
case HOST_NORMAL:
|
||||
case HOST_DEDICATED:
|
||||
PR_InitCompile( name );
|
||||
break;
|
||||
default:
|
||||
Sys_Break("PRVM_PrepareProgs: can't prepare progs for instance %d\n", host_instance );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PRVM_CompileProgs( void )
|
||||
|
@ -301,6 +341,11 @@ void PRVM_CompileProgs( void )
|
|||
PR_FinishCompilation();
|
||||
}
|
||||
|
||||
bool PRVM_DecompileProgs( void )
|
||||
{
|
||||
return PR_Decompile();
|
||||
}
|
||||
|
||||
vprogs_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, void *unused )
|
||||
{
|
||||
com = *input;
|
||||
|
@ -312,6 +357,7 @@ vprogs_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, void *unused )
|
|||
vm.Free = PRVM_Shutdown;
|
||||
vm.PrepareDAT = PRVM_PrepareProgs;
|
||||
vm.CompileDAT = PRVM_CompileProgs;
|
||||
vm.DecompileDAT = PRVM_DecompileProgs;
|
||||
|
||||
vm.WriteGlobals = PRVM_ED_WriteGlobals;
|
||||
vm.ParseGlobals = PRVM_ED_ParseGlobals;
|
||||
|
|
|
@ -294,11 +294,11 @@ int PR_WriteSourceFiles(file_t *h, dprograms_t *progs, bool sourceaswell)
|
|||
if (!num) return 0;
|
||||
|
||||
idf = Qalloc(sizeof(includeddatafile_t) * num);
|
||||
for (f = sourcefile, num = 0; f; f = f->next)
|
||||
for( f = sourcefile, num = 0; f; f = f->next )
|
||||
{
|
||||
if (f->type == FT_CODE && !sourceaswell)
|
||||
if( f->type == FT_CODE && !sourceaswell )
|
||||
continue;
|
||||
com.strcpy(idf[num].filename, f->filename);
|
||||
com.strcpy( idf[num].filename, f->filename );
|
||||
idf[num].size = f->size;
|
||||
idf[num].compmethod = CMPW_DEFLATE;
|
||||
idf[num].ofs = FS_Tell(h);
|
||||
|
@ -306,8 +306,8 @@ int PR_WriteSourceFiles(file_t *h, dprograms_t *progs, bool sourceaswell)
|
|||
num++;
|
||||
}
|
||||
ofs = FS_Tell(h);
|
||||
FS_Write(h, &num, sizeof(int));
|
||||
FS_Write(h, idf, sizeof(includeddatafile_t)*num);
|
||||
FS_Write( h, &num, sizeof(int));
|
||||
FS_Write( h, idf, sizeof(includeddatafile_t) * num );
|
||||
sourcefile = NULL;
|
||||
|
||||
return ofs;
|
||||
|
@ -538,15 +538,15 @@ word PR_WriteProgdefs (char *filename)
|
|||
PR_Message("Quake1 unmodified progs.dat\n");
|
||||
if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "progs.dat");
|
||||
break;
|
||||
case PROG_CRC_SERVER:
|
||||
case 1320:
|
||||
PR_Message("Xash3D unmodified server.dat\n");
|
||||
if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "server.dat");
|
||||
break;
|
||||
case PROG_CRC_CLIENT:
|
||||
case 9488:
|
||||
PR_Message("Xash3D unmodified client.dat\n");
|
||||
if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "client.dat");
|
||||
break;
|
||||
case PROG_CRC_UIMENU:
|
||||
case 2460:
|
||||
PR_Message("Xash3D unmodified uimenu.dat\n");
|
||||
if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "uimenu.dat");
|
||||
break;
|
||||
|
|
|
@ -117,6 +117,10 @@ SOURCE=.\pr_comp.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\pr_decomp.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\pr_edict.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -23,10 +23,6 @@ extern int prvm_developer;
|
|||
|
||||
#define Host_Error com.error
|
||||
|
||||
#define PROG_CRC_SERVER 1320
|
||||
#define PROG_CRC_CLIENT 9488
|
||||
#define PROG_CRC_UIMENU 2460
|
||||
|
||||
enum op_state
|
||||
{
|
||||
OP_DONE, // 0
|
||||
|
@ -357,7 +353,7 @@ void PRVM_MEM_IncreaseEdicts(void);
|
|||
edict_t *PRVM_ED_Alloc (void);
|
||||
void PRVM_ED_Free (edict_t *ed);
|
||||
void PRVM_ED_ClearEdict (edict_t *e);
|
||||
|
||||
ddef_t *PRVM_ED_GlobalAtOfs( int ofs );
|
||||
void PRVM_PrintFunctionStatements (const char *name);
|
||||
void PRVM_ED_Print(edict_t *ed);
|
||||
void PRVM_ED_Write (vfile_t *f, edict_t *ed);
|
||||
|
|
Reference in New Issue