28 Oct 2008
This commit is contained in:
parent
64cdd0a43b
commit
15dbaeb3aa
|
@ -17,7 +17,6 @@ baserc\
|
|||
viewer\
|
||||
physic\
|
||||
render\
|
||||
ripper\
|
||||
vprogs\
|
||||
vsound\
|
||||
common\
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
//=======================================================================
|
||||
|
||||
#include <windows.h>
|
||||
#include "basetypes.h"
|
||||
#include "ref_dllapi.h"
|
||||
#include "launch_api.h"
|
||||
#include "baserc_api.h"
|
||||
|
||||
// resources
|
||||
#include "images.h"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef BSPLIB_H
|
||||
#define BSPLIB_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "platform.h"
|
||||
#include "utils.h"
|
||||
#include "mathlib.h"
|
||||
|
|
|
@ -35,7 +35,7 @@ int EmitShader( const char *shader )
|
|||
|
||||
if( i == MAX_MAP_SHADERS ) Sys_Break( "MAX_MAP_SHADERS limit exceeded\n" );
|
||||
numshaders++;
|
||||
com.strncpy( dshaders[i].name, shader, MAX_QPATH );
|
||||
com.strncpy( dshaders[i].name, shader, MAX_SHADERPATH );
|
||||
|
||||
si = FindShader( shader );
|
||||
dshaders[i].flags = si->surfaceFlags;
|
||||
|
@ -195,7 +195,7 @@ void SetLightStyles( void )
|
|||
char *t;
|
||||
bsp_entity_t *e;
|
||||
int i, j, k, stylenum = 0;
|
||||
char lighttargets[64][MAX_QPATH];
|
||||
char lighttargets[64][64];
|
||||
|
||||
|
||||
// any light that is controlled (has a targetname)
|
||||
|
@ -247,7 +247,7 @@ void SetLightStyles( void )
|
|||
Msg( "switchable lightstyles limit (%i) exceeded at entity #%i\n", 64, i );
|
||||
break; // nothing to process
|
||||
}
|
||||
com.strncpy( lighttargets[j], t, MAX_QPATH );
|
||||
com.strncpy( lighttargets[j], t, 64 );
|
||||
stylenum++;
|
||||
}
|
||||
SetKeyValue( e, "style", va( "%i", 32 + j ));
|
||||
|
|
|
@ -687,7 +687,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack
|
|||
prevmight = (long *)prevstack->mightsee;
|
||||
cansee = (long *)passage->cansee;
|
||||
might = (long *)stack.mightsee;
|
||||
memcpy(might, prevmight, portalbytes);
|
||||
Mem_Copy(might, prevmight, portalbytes);
|
||||
if( p->status == stat_done )
|
||||
portalvis = (long *)p->portalvis;
|
||||
else portalvis = (long *)p->portalflood;
|
||||
|
|
|
@ -125,6 +125,30 @@ SOURCE=.\bsplib\bsplib.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\conv_bsplumps.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\conv_doom.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\conv_image.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\conv_main.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\conv_shader.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\conv_sprite.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bsplib\facebsp.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -237,6 +261,10 @@ SOURCE=.\platform.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper\ripper.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\utils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
|
@ -11,12 +11,35 @@
|
|||
dll_info_t vprogs_dll = { "vprogs.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(vprogs_exp_t) };
|
||||
vprogs_exp_t *PRVM;
|
||||
stdlib_api_t com;
|
||||
byte *basepool;
|
||||
byte *zonepool;
|
||||
byte *error_bmp;
|
||||
size_t error_bmp_size;
|
||||
static double start, end;
|
||||
uint app_name = 0;
|
||||
|
||||
#define MAX_SEARCHMASK 256
|
||||
string searchmask[MAX_SEARCHMASK];
|
||||
int num_searchmask = 0;
|
||||
string gs_searchmask;
|
||||
string gs_gamedir;
|
||||
byte *basepool;
|
||||
byte *zonepool;
|
||||
byte *error_bmp;
|
||||
size_t error_bmp_size;
|
||||
static double start, end;
|
||||
uint app_name = HOST_OFFLINE;
|
||||
|
||||
void ClrMask( void )
|
||||
{
|
||||
num_searchmask = 0;
|
||||
memset( searchmask, 0, MAX_STRING * MAX_SEARCHMASK );
|
||||
}
|
||||
|
||||
void AddMask( const char *mask )
|
||||
{
|
||||
if( num_searchmask >= MAX_SEARCHMASK )
|
||||
{
|
||||
MsgDev( D_WARN, "AddMask: searchlist is full\n" );
|
||||
return;
|
||||
}
|
||||
com.strncpy( searchmask[num_searchmask], mask, MAX_STRING );
|
||||
num_searchmask++;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -29,7 +52,7 @@ so do it manually
|
|||
void InitPlatform ( int argc, char **argv )
|
||||
{
|
||||
byte bspflags = 0, qccflags = 0, roqflags = 0;
|
||||
char source[64], gamedir[64];
|
||||
string source, gamedir;
|
||||
launch_t CreateVprogs;
|
||||
|
||||
basepool = Mem_AllocPool( "Temp" );
|
||||
|
@ -76,11 +99,13 @@ void InitPlatform ( int argc, char **argv )
|
|||
case HOST_SPRITE:
|
||||
case HOST_STUDIO:
|
||||
case HOST_WADLIB:
|
||||
case HOST_RIPPER:
|
||||
FS_InitRootDir(".");
|
||||
|
||||
// initialize ImageLibrary
|
||||
Image_Init( NULL, IL_KEEP_8BIT );
|
||||
start = Sys_DoubleTime();
|
||||
Msg( "\n\n" ); // tabulation
|
||||
break;
|
||||
case HOST_OFFLINE:
|
||||
break;
|
||||
|
@ -91,80 +116,85 @@ void RunPlatform( void )
|
|||
{
|
||||
search_t *search;
|
||||
bool (*CompileMod)( byte *mempool, const char *name, byte parms ) = NULL;
|
||||
char filename[MAX_QPATH], typemod[16], searchmask[8][16], errorstring[256];
|
||||
cvar_t *fs_defaultdir = Cvar_Get( "fs_defaultdir", "tmpQuArK", CVAR_SYSTEMINFO, NULL );
|
||||
byte parms = 0; // future expansion
|
||||
int i, j, numCompiledMods = 0;
|
||||
string errorstring;
|
||||
|
||||
memset( searchmask, 0, 8 * 16 );
|
||||
memset( errorstring, 0, 256 );
|
||||
// directory to extract
|
||||
com.strncpy( gs_gamedir, fs_defaultdir->string, sizeof( gs_gamedir ));
|
||||
memset( errorstring, 0, MAX_STRING );
|
||||
ClrMask();
|
||||
|
||||
switch(app_name)
|
||||
switch( app_name )
|
||||
{
|
||||
case HOST_SPRITE:
|
||||
CompileMod = CompileSpriteModel;
|
||||
com.strcpy(typemod, "sprites" );
|
||||
com.strcpy(searchmask[0], "*.qc" );
|
||||
AddMask( "*.qc" );
|
||||
break;
|
||||
case HOST_STUDIO:
|
||||
CompileMod = CompileStudioModel;
|
||||
com.strcpy(typemod, "models" );
|
||||
com.strcpy(searchmask[0], "*.qc" );
|
||||
AddMask( "*.qc" );
|
||||
break;
|
||||
case HOST_BSPLIB:
|
||||
com.strcpy(typemod, "maps" );
|
||||
com.strcpy(searchmask[0], "*.map" );
|
||||
AddMask( "*.map" );
|
||||
CompileBSPModel();
|
||||
break;
|
||||
case HOST_WADLIB:
|
||||
CompileMod = CompileWad3Archive;
|
||||
com.strcpy(typemod, "wads" );
|
||||
com.strcpy(searchmask[0], "*.qc" );
|
||||
AddMask( "*.qc" );
|
||||
break;
|
||||
case HOST_RIPPER:
|
||||
CompileMod = ConvertResource;
|
||||
Conv_RunSearch();
|
||||
break;
|
||||
case HOST_QCCLIB:
|
||||
com.strcpy(typemod, "progs" );
|
||||
com.strcpy(searchmask[0], "*.src" );
|
||||
AddMask( "*.src" );
|
||||
PRVM->CompileDAT();
|
||||
break;
|
||||
case HOST_OFFLINE:
|
||||
com.strcpy(typemod, "things" );
|
||||
com.strcpy(searchmask[0], "*.*" );
|
||||
break;
|
||||
}
|
||||
if(!CompileMod) goto elapced_time; // jump to shutdown
|
||||
if( !CompileMod ) goto elapced_time; // jump to shutdown
|
||||
|
||||
zonepool = Mem_AllocPool( "compiler" );
|
||||
if(!FS_GetParmFromCmdLine( "-file", filename ))
|
||||
// using custom mask
|
||||
if(FS_GetParmFromCmdLine( "-file", gs_searchmask ))
|
||||
{
|
||||
// search by mask
|
||||
for( i = 0; i < 8; i++)
|
||||
{
|
||||
// skip blank mask
|
||||
if(!com.strlen(searchmask[i])) continue;
|
||||
search = FS_Search( searchmask[i], true );
|
||||
if(!search) continue; // try next mask
|
||||
|
||||
for( j = 0; j < search->numfilenames; j++ )
|
||||
{
|
||||
if(CompileMod( zonepool, search->filenames[j], parms ))
|
||||
numCompiledMods++;
|
||||
}
|
||||
}
|
||||
if(numCompiledMods == 0)
|
||||
{
|
||||
for(j = 0; j < 8; j++)
|
||||
{
|
||||
if(!strlen(searchmask[j])) continue;
|
||||
strcat(errorstring, va("%s ", searchmask[j]));
|
||||
}
|
||||
Sys_Break("no %sfound in this folder!\n", errorstring );
|
||||
}
|
||||
ClrMask(); // clear all previous masks
|
||||
AddMask( gs_searchmask ); // custom mask
|
||||
}
|
||||
else CompileMod( zonepool, filename, parms );
|
||||
zonepool = Mem_AllocPool( "compiler" );
|
||||
Msg( "Converting ...\n\n" );
|
||||
|
||||
// search by mask
|
||||
for( i = 0; i < num_searchmask; i++ )
|
||||
{
|
||||
// skip blank mask
|
||||
if(!com.strlen( searchmask[i] )) continue;
|
||||
search = FS_Search( searchmask[i], true );
|
||||
if( !search ) continue; // try next mask
|
||||
|
||||
for( j = 0; j < search->numfilenames; j++ )
|
||||
{
|
||||
if(CompileMod( zonepool, search->filenames[j], parms ))
|
||||
numCompiledMods++;
|
||||
}
|
||||
Mem_Free( search );
|
||||
}
|
||||
if( numCompiledMods == 0 )
|
||||
{
|
||||
if( !num_searchmask ) com.strncpy( errorstring, "files", MAX_STRING );
|
||||
for( j = 0; j < num_searchmask; j++ )
|
||||
{
|
||||
if(!com.strlen( searchmask[j] )) continue;
|
||||
com.strncat( errorstring, va("%s ", searchmask[j]), MAX_STRING );
|
||||
}
|
||||
Sys_Break( "no %s found in this folder!\n", errorstring );
|
||||
}
|
||||
elapced_time:
|
||||
end = Sys_DoubleTime();
|
||||
Msg ("%5.3f seconds elapsed\n", end - start);
|
||||
if(numCompiledMods > 1) Msg("total %d %s compiled\n", numCompiledMods, typemod );
|
||||
Msg( "%5.3f seconds elapsed\n", end - start );
|
||||
if( numCompiledMods > 1) Msg("total %d files proceed\n", numCompiledMods );
|
||||
}
|
||||
|
||||
void FreePlatform ( void )
|
||||
|
@ -174,6 +204,11 @@ void FreePlatform ( void )
|
|||
PRVM->Free();
|
||||
Sys_FreeLibrary( &vprogs_dll ); // free qcclib
|
||||
}
|
||||
else if( app_name == HOST_RIPPER )
|
||||
{
|
||||
// finalize qc-script
|
||||
Skin_FinalizeScript();
|
||||
}
|
||||
|
||||
Mem_Check(); // check for leaks
|
||||
Mem_FreePool( &basepool );
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
#ifndef BASEPLATFORM_H
|
||||
#define BASEPLATFORM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <windows.h>
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
|
||||
//=====================================
|
||||
|
@ -19,4 +17,17 @@ void InitPlatform ( int argc, char **argv ); // init host
|
|||
void RunPlatform ( void ); // host frame
|
||||
void ClosePlatform ( void ); // close host
|
||||
|
||||
//=====================================
|
||||
// extragen export
|
||||
//=====================================
|
||||
bool ConvertResource( byte *mempool, const char *filename, byte parms );
|
||||
void Skin_FinalizeScript( void );
|
||||
void Conv_RunSearch( void );
|
||||
|
||||
// shared tools
|
||||
void ClrMask( void );
|
||||
void AddMask( const char *mask );
|
||||
extern string searchmask[];
|
||||
extern int num_searchmask;
|
||||
|
||||
#endif//BASEPLATFORM_H
|
|
@ -4,7 +4,7 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
#define VDBSPMODHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'V') // little-endian "VBSP" hl2 bsp's
|
||||
#define IDIWADHEADER (('D'<<24)+('A'<<16)+('W'<<8)+'I') // little-endian "IWAD" doom1 game wad
|
||||
|
@ -34,7 +34,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
int nummiptex;
|
||||
int dataofs[4]; // [nummiptex]
|
||||
int dataofs[4]; // [nummiptex]
|
||||
} dmiptexlump_t;
|
||||
|
||||
byte* bsp_base;
|
||||
|
@ -49,7 +49,7 @@ void Conv_BspTextures( const char *name, lump_t *l, const char *ext )
|
|||
int *dofs, size;
|
||||
byte *buffer;
|
||||
|
||||
if(!l->filelen) return; // no textures stored
|
||||
if( !l->filelen ) return; // no textures stored
|
||||
FS_FileBase( name, genericname );
|
||||
|
||||
m = (dmiptexlump_t *)(bsp_base + l->fileofs);
|
||||
|
@ -58,8 +58,8 @@ void Conv_BspTextures( const char *name, lump_t *l, const char *ext )
|
|||
|
||||
for (i = 0; i < m->nummiptex; i++)
|
||||
{
|
||||
dofs[i] = LittleLong(dofs[i]);
|
||||
if (dofs[i] == -1) continue;
|
||||
dofs[i] = LittleLong( dofs[i] );
|
||||
if( dofs[i] == -1 ) continue;
|
||||
|
||||
// needs to simulate directly loading
|
||||
mip = (mip_t *)((byte *)m + dofs[i]);
|
||||
|
@ -74,7 +74,8 @@ void Conv_BspTextures( const char *name, lump_t *l, const char *ext )
|
|||
if( k ) mip->name[com.strlen(mip->name)-k] = '!'; // quake1 issues
|
||||
// some Q1 mods contains blank names (e.g. "after the fall")
|
||||
if(!com.strlen( mip->name )) com.snprintf( mip->name, 16, "%s_%d", genericname, i );
|
||||
ConvMIP(va("miptex/%s", mip->name ), buffer, size, ext ); // convert it
|
||||
if(!FS_FileExists( va( "%s/%s/%s.%s", gs_gamedir, name, mip->name, ext )))
|
||||
ConvMIP( va("%s/%s", name, mip->name ), buffer, size, ext ); // convert it
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,702 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// conv_doom.c - convert doom1\2 resources
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// doom .mus files
|
||||
#define MUSIDHEADER ((0x1A<<24)+('S'<<16)+('U'<<8)+'M') // little-endian "MUS "
|
||||
#define MIDIDHEADER "MThd\000\000\000\006\000\001"
|
||||
#define TRACKMAGIC1 "\000\377\003\035"
|
||||
#define TRACKMAGIC2 "\000\377\057\000"
|
||||
#define TRACKMAGIC3 "\000\377\002\026"
|
||||
#define TRACKMAGIC4 "\000\377\131\002\000\000"
|
||||
#define TRACKMAGIC5 "\000\377\121\003\011\243\032"
|
||||
#define TRACKMAGIC6 "\000\377\057\000"
|
||||
|
||||
#define MIDBUFFER 0x20000
|
||||
#define last(e) ((byte)(e & 0x80))
|
||||
#define event_type(e) ((byte)((e & 0x7F)>>4))
|
||||
#define channel(e) ((byte)(e & 0x0F))
|
||||
#define mid_write1 VFS_Write
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
word ScoreLength;
|
||||
word ScoreStart;
|
||||
word channels; // count of primary channels
|
||||
word SecChannels; // count of secondary channels
|
||||
word InstrCnt;
|
||||
word dummy;
|
||||
word *instruments;
|
||||
} mus_t;
|
||||
|
||||
struct track_s
|
||||
{
|
||||
dword current;
|
||||
char vel;
|
||||
long DeltaTime;
|
||||
byte LastEvent;
|
||||
char *data; // primary data
|
||||
};
|
||||
|
||||
// doom spritemodel_qc
|
||||
typedef struct angled_s
|
||||
{
|
||||
char name[10]; // copy of skin name
|
||||
|
||||
int width; // lumpwidth
|
||||
int height; // lumpheight
|
||||
int origin[2]; // monster origin
|
||||
byte xmirrored; // swap left and right
|
||||
} angled_t;
|
||||
|
||||
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
|
||||
|
||||
char membername[8]; // current model name, four characsters
|
||||
char animation; // current animation number
|
||||
bool in_progress; // current state
|
||||
file_t *f; // skin script
|
||||
} flat;
|
||||
|
||||
static size_t mid_write2( vfile_t *file, const uint *ptr, size_t size )
|
||||
{
|
||||
uint i, rev = 0;
|
||||
|
||||
for( i = 0; (size_t)i < size; i++ )
|
||||
rev = (rev << 8) + (((*ptr) >>(i*8)) & 0xFF) ;
|
||||
|
||||
return VFS_Write( file, &rev, size );
|
||||
}
|
||||
|
||||
static void Conv_WriteMIDheader( vfile_t *file, uint ntrks, uint division )
|
||||
{
|
||||
mid_write1( file, MIDIDHEADER, 10 );
|
||||
mid_write2( file, &ntrks, 2 );
|
||||
mid_write2( file, &division, 2 );
|
||||
}
|
||||
|
||||
static void Conv_WriteTrack( vfile_t *file, int tracknum, struct track_s track[] )
|
||||
{
|
||||
uint size;
|
||||
size_t quot, rem;
|
||||
|
||||
// do we risk overflow here ?
|
||||
size = (uint)track[tracknum].current + 4;
|
||||
mid_write1( file, "MTrk", 4 );
|
||||
if( !tracknum ) size += 33;
|
||||
|
||||
mid_write2( file, &size, 4 );
|
||||
if( !tracknum) mid_write1( file, TRACKMAGIC1 "written by Xash MusLib Ripper", 33 );
|
||||
quot = (size_t)(track[tracknum].current / 4096);
|
||||
rem = (size_t)(track[tracknum].current - quot * 4096);
|
||||
mid_write1( file, track[tracknum].data, 4096 * quot );
|
||||
mid_write1( file, ((const byte *)track[tracknum].data) + 4096 * quot, rem );
|
||||
mid_write1( file, TRACKMAGIC2, 4 );
|
||||
}
|
||||
|
||||
static void Conv_WriteFirstTrack( vfile_t *file )
|
||||
{
|
||||
uint size = 43;
|
||||
|
||||
mid_write1( file, "MTrk", 4);
|
||||
mid_write2( file, &size, 4 );
|
||||
mid_write1( file, TRACKMAGIC3, 4 );
|
||||
mid_write1( file, "by XashXT Group 2008 ©", 22 );
|
||||
mid_write1( file, TRACKMAGIC4, 6 );
|
||||
mid_write1( file, TRACKMAGIC5, 7 );
|
||||
mid_write1( file, TRACKMAGIC6, 4 );
|
||||
}
|
||||
|
||||
static bool Conv_ReadMusHeader( vfile_t *f, mus_t *hdr )
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
VFS_Read( f, &hdr->ident, 4 );
|
||||
if( hdr->ident != MUSIDHEADER )
|
||||
return false;
|
||||
|
||||
VFS_Read(f, &(hdr->ScoreLength), sizeof(word));
|
||||
VFS_Read(f, &(hdr->ScoreStart), sizeof(word));
|
||||
VFS_Read(f, &(hdr->channels), sizeof(word));
|
||||
VFS_Read(f, &(hdr->SecChannels), sizeof(word));
|
||||
VFS_Read(f, &(hdr->InstrCnt), sizeof(word));
|
||||
VFS_Read(f, &(hdr->dummy), sizeof(word));
|
||||
hdr->instruments = (word *)Mem_Alloc( basepool, hdr->InstrCnt * sizeof(word));
|
||||
|
||||
if(VFS_Read( f, hdr->instruments, hdr->InstrCnt * sizeof(word)) != hdr->InstrCnt * sizeof(word))
|
||||
result = false;
|
||||
Mem_Free( hdr->instruments );
|
||||
return result;
|
||||
}
|
||||
|
||||
static char Conv_GetChannel( signed char MUS2MIDchannel[] )
|
||||
{
|
||||
signed char old15 = MUS2MIDchannel[15], max = -1;
|
||||
int i;
|
||||
|
||||
MUS2MIDchannel[15] = -1;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
if( MUS2MIDchannel[i] > max )
|
||||
max = MUS2MIDchannel[i];
|
||||
}
|
||||
MUS2MIDchannel[15] = old15;
|
||||
return (max == 8 ? 10 : max + 1);
|
||||
}
|
||||
|
||||
static void Conv_FreeTracks( struct track_s track[] )
|
||||
{
|
||||
int i ;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
if(track[i].data) Mem_Free( track[i].data ) ;
|
||||
}
|
||||
}
|
||||
|
||||
static uint Conv_ReadTime( vfile_t *file )
|
||||
{
|
||||
register uint time = 0;
|
||||
int newbyte;
|
||||
|
||||
do
|
||||
{
|
||||
VFS_Read( file, &newbyte, 1 );
|
||||
if( newbyte != EOF ) time = (time << 7) + (newbyte & 0x7F);
|
||||
} while((newbyte != EOF) && (newbyte & 0x80));
|
||||
return time ;
|
||||
}
|
||||
|
||||
static void Conv_WriteByte( char MIDItrack, char byte, struct track_s track[] )
|
||||
{
|
||||
uint pos;
|
||||
|
||||
pos = track[MIDItrack].current;
|
||||
if( pos < MIDBUFFER )
|
||||
{
|
||||
// need to reallocte ?
|
||||
track[MIDItrack].data[pos] = byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
Conv_FreeTracks( track );
|
||||
Sys_Break("Not enough memory" );
|
||||
}
|
||||
track[MIDItrack].current++;
|
||||
}
|
||||
|
||||
static void Conv_WriteVarLen( int tracknum, register uint value, struct track_s track[] )
|
||||
{
|
||||
register uint buffer;
|
||||
|
||||
buffer = value & 0x7f;
|
||||
while((value >>= 7))
|
||||
{
|
||||
buffer<<= 8;
|
||||
buffer |= 0x80;
|
||||
buffer += (value & 0x7f);
|
||||
}
|
||||
while( 1 )
|
||||
{
|
||||
Conv_WriteByte( tracknum, buffer, track );
|
||||
if( buffer & 0x80 ) buffer >>= 8;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool Conv_Mus2Mid( const char *musicname, byte *buffer, int bufsize )
|
||||
{
|
||||
struct track_s track[16];
|
||||
word TrackCnt = 0;
|
||||
word division = 90;
|
||||
byte et, MUSchannel, MIDIchannel, MIDItrack, NewEvent;
|
||||
uint i, DeltaTime, TotalTime = 0, n = 0;
|
||||
char event, data, ouch = 0;
|
||||
signed char MUS2MIDchannel[16];
|
||||
vfile_t *file_mid, *file_mus = VFS_Create( buffer, bufsize );
|
||||
file_t *f;
|
||||
static mus_t MUSh;
|
||||
byte MUS2MIDcontrol[15] =
|
||||
{
|
||||
0, // program change - not a MIDI control change
|
||||
0x00, // bank select
|
||||
0x01, // modulation pot
|
||||
0x07, // volume
|
||||
0x0A, // pan pot
|
||||
0x0B, // expression pot
|
||||
0x5B, // reverb depth
|
||||
0x5D, // chorus depth
|
||||
0x40, // sustain pedal
|
||||
0x43, // soft pedal
|
||||
0x78, // all sounds off
|
||||
0x7B, // all notes off
|
||||
0x7E, // mono
|
||||
0x7F, // poly
|
||||
0x79 // reset all controllers
|
||||
}, MIDIchan2track[16];
|
||||
|
||||
if(!Conv_ReadMusHeader( file_mus, &MUSh ))
|
||||
{
|
||||
VFS_Close( file_mus );
|
||||
MsgDev(D_ERROR, "Conv_Mus2Mid: can't read mus header\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( VFS_Seek( file_mus, MUSh.ScoreStart, SEEK_SET ))
|
||||
{
|
||||
VFS_Close( file_mus );
|
||||
MsgDev(D_ERROR,"Conv_Mus2Mid: can't seek scores\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( MUSh.channels > 15 )
|
||||
{
|
||||
VFS_Close( file_mus );
|
||||
MsgDev(D_ERROR,"Conv_Mus2Mid: too many channels\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
MUS2MIDchannel[i] = -1;
|
||||
track[i].current = 0;
|
||||
track[i].vel = 64;
|
||||
track[i].DeltaTime = 0;
|
||||
track[i].LastEvent = 0;
|
||||
track[i].data = NULL;
|
||||
}
|
||||
|
||||
VFS_Read( file_mus, &event, 1 );
|
||||
et = event_type( event );
|
||||
MUSchannel = channel( event );
|
||||
|
||||
while((et != 6) && !VFS_Eof( file_mus ) && (event != EOF))
|
||||
{
|
||||
if( MUS2MIDchannel[MUSchannel] == -1 )
|
||||
{
|
||||
MIDIchannel = MUS2MIDchannel[MUSchannel] = (MUSchannel == 15 ? 9:Conv_GetChannel(MUS2MIDchannel));
|
||||
MIDItrack = MIDIchan2track[MIDIchannel] = (byte)(TrackCnt++);
|
||||
track[MIDItrack].data = (char *)Mem_Alloc( basepool, MIDBUFFER );
|
||||
}
|
||||
else
|
||||
{
|
||||
MIDIchannel = MUS2MIDchannel[MUSchannel];
|
||||
MIDItrack = MIDIchan2track [MIDIchannel];
|
||||
}
|
||||
Conv_WriteVarLen( MIDItrack, track[MIDItrack].DeltaTime, track );
|
||||
track[MIDItrack].DeltaTime = 0;
|
||||
|
||||
switch( et )
|
||||
{
|
||||
case 0: // release note
|
||||
NewEvent = 0x90 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, data, track );
|
||||
Conv_WriteByte( MIDItrack, 0, track );
|
||||
break;
|
||||
case 1:
|
||||
NewEvent = 0x90 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, data & 0x7F, track );
|
||||
if( data & 0x80 ) VFS_Read( file_mus, &track[MIDItrack].vel, 1 );
|
||||
Conv_WriteByte( MIDItrack, track[MIDItrack].vel, track );
|
||||
break;
|
||||
case 2:
|
||||
NewEvent = 0xE0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, (data & 1) << 6, track );
|
||||
Conv_WriteByte( MIDItrack, data >> 1, track );
|
||||
break;
|
||||
case 3:
|
||||
NewEvent = 0xB0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, MUS2MIDcontrol[data], track );
|
||||
if( data == 12 ) Conv_WriteByte( MIDItrack, MUSh.channels + 1, track );
|
||||
else Conv_WriteByte( MIDItrack, 0, track );
|
||||
break;
|
||||
case 4:
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
if( data )
|
||||
{
|
||||
NewEvent = 0xB0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
Conv_WriteByte( MIDItrack, MUS2MIDcontrol[data], track );
|
||||
}
|
||||
else
|
||||
{
|
||||
NewEvent = 0xC0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
}
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, data, track );
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
Conv_FreeTracks( track );
|
||||
MsgDev(D_ERROR, "Conv_Mus2Mid: bad event\n" );
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(last( event ))
|
||||
{
|
||||
DeltaTime = Conv_ReadTime( file_mus );
|
||||
TotalTime += DeltaTime;
|
||||
for( i = 0; i < (int)TrackCnt; i++ )
|
||||
track[i].DeltaTime += DeltaTime;
|
||||
}
|
||||
VFS_Read( file_mus, &event, 1 );
|
||||
if( event != EOF )
|
||||
{
|
||||
et = event_type( event );
|
||||
MUSchannel = channel( event );
|
||||
}
|
||||
else ouch = 1;
|
||||
}
|
||||
if( ouch ) MsgDev(D_WARN, "Conv_Mus2Mid: %s.mus - end of file probably corrupted\n", musicname );
|
||||
|
||||
f = FS_Open(va("%s/%s.mid", gs_gamedir, musicname ), "wb" );
|
||||
file_mid = VFS_Open( f, "w" );
|
||||
|
||||
Conv_WriteMIDheader( file_mid, TrackCnt + 1, division );
|
||||
Conv_WriteFirstTrack( file_mid );
|
||||
|
||||
for( i = 0; i < (int)TrackCnt; i++ )
|
||||
Conv_WriteTrack( file_mid, i, track );
|
||||
Conv_FreeTracks( track );
|
||||
FS_Close(VFS_Close( file_mid ));
|
||||
VFS_Close( file_mus );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Skin_RoundDimensions( int *scaled_width, int *scaled_height )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
void Skin_WriteSequence( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
Skin_RoundDimensions( &flat.bounds[0], &flat.bounds[1] );
|
||||
|
||||
// time to dump frames :)
|
||||
if( flat.angledframes == 8 )
|
||||
{
|
||||
// angled group is full, dump it!
|
||||
FS_Print( flat.f, "\n$angled\n{\n" );
|
||||
FS_Printf( flat.f, "\t// frame '%c'\n", flat.frame[0].name[4] );
|
||||
FS_Printf( flat.f, "\t$resample\t\t%d %d\n", flat.bounds[0], flat.bounds[1] );
|
||||
for( i = 0; i < 8; i++)
|
||||
{
|
||||
FS_Printf( flat.f,"\t$load\t\t%s.bmp", flat.frame[i].name );
|
||||
if( flat.frame[i].xmirrored ) FS_Print( flat.f," flip_x\n");
|
||||
else FS_Print( flat.f, "\n" );
|
||||
FS_Printf( flat.f,"\t$frame\t\t0 0 %d %d", flat.frame[i].width, flat.frame[i].height );
|
||||
FS_Printf( flat.f, " 0.1 %d %d\n", flat.frame[i].origin[0], flat.frame[i].origin[1] );
|
||||
}
|
||||
FS_Print( flat.f, "}\n" );
|
||||
}
|
||||
else if( flat.normalframes == 1 )
|
||||
{
|
||||
// single frame stored
|
||||
FS_Print( flat.f, "\n" );
|
||||
FS_Printf( flat.f, "// frame '%c'\n", flat.frame[0].name[4] );
|
||||
FS_Printf( flat.f,"$resample\t\t%d %d\n", flat.bounds[0], flat.bounds[1] );
|
||||
FS_Printf( flat.f,"$load\t\t%s.bmp\n", flat.frame[0].name );
|
||||
FS_Printf( flat.f,"$frame\t\t0 0 %d %d", flat.frame[0].width, flat.frame[0].height );
|
||||
FS_Printf( flat.f, " 0.1 %d %d\n", flat.frame[0].origin[0], flat.frame[0].origin[1]);
|
||||
}
|
||||
|
||||
// drop mirror frames too
|
||||
if( flat.mirrorframes == 8 )
|
||||
{
|
||||
// mirrored group is always flipped
|
||||
FS_Print( flat.f, "\n$angled\n{\n" );
|
||||
FS_Printf( flat.f, "\t//frame '%c' (mirror '%c')\n", flat.frame[0].name[6], flat.frame[0].name[4] );
|
||||
FS_Printf( flat.f, "\t$resample\t\t%d %d\n", flat.bounds[0], flat.bounds[1] );
|
||||
for( i = 2; i > -1; i--)
|
||||
{
|
||||
FS_Printf( flat.f,"\t$load\t\t%s.bmp flip_x\n", flat.frame[i].name );
|
||||
FS_Printf( flat.f,"\t$frame\t\t0 0 %d %d", flat.frame[i].width, flat.frame[i].height );
|
||||
FS_Printf( flat.f, " 0.1 %d %d\n", flat.frame[i].origin[0], flat.frame[i].origin[1] );
|
||||
}
|
||||
for( i = 7; i > 2; i--)
|
||||
{
|
||||
FS_Printf( flat.f,"\t$load\t\t%s.bmp flip_x\n", flat.frame[i].name );
|
||||
FS_Printf( flat.f,"\t$frame\t\t0 0 %d %d", flat.frame[i].width, flat.frame[i].height );
|
||||
FS_Printf( flat.f, " 0.1 %d %d\n", flat.frame[i].origin[0], flat.frame[i].origin[1] );
|
||||
}
|
||||
FS_Print( flat.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
|
||||
}
|
||||
|
||||
void Skin_FindSequence( const char *name, rgbdata_t *pic )
|
||||
{
|
||||
uint headlen;
|
||||
char num, header[10];
|
||||
|
||||
// create header from flat name
|
||||
com.strncpy( header, name, 10 );
|
||||
headlen = com.strlen( name );
|
||||
|
||||
if( flat.animation != header[4] )
|
||||
{
|
||||
// write animation
|
||||
Skin_WriteSequence();
|
||||
flat.animation = header[4];
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
num = header[5] - '0';
|
||||
if(num == 0) flat.normalframes++; // animation frame
|
||||
if(num == 8) num = 0; // merge
|
||||
flat.angledframes++; // angleframe stored
|
||||
com.strncpy( flat.frame[num].name, header, 9 );
|
||||
flat.frame[num].width = pic->width;
|
||||
flat.frame[num].height = pic->height;
|
||||
flat.frame[num].origin[0] = pic->width>>1; // center
|
||||
flat.frame[num].origin[1] = pic->height; // floor
|
||||
flat.frame[num].xmirrored = false;
|
||||
}
|
||||
else if( headlen == 8 )
|
||||
{
|
||||
// normal image
|
||||
num = header[5] - '0';
|
||||
if(num == 8) num = 0; // merge
|
||||
com.strncpy( flat.frame[num].name, header, 9 );
|
||||
flat.frame[num].width = pic->width;
|
||||
flat.frame[num].height = pic->height;
|
||||
flat.frame[num].origin[0] = pic->width>>1; // center
|
||||
flat.frame[num].origin[1] = pic->height; // floor
|
||||
flat.frame[num].xmirrored = false;
|
||||
flat.angledframes++; // frame stored
|
||||
|
||||
if( header[4] != header[6] )
|
||||
{
|
||||
// mirrored groups
|
||||
flat.mirrorframes++;
|
||||
return;
|
||||
}
|
||||
|
||||
// mirrored image
|
||||
num = header[7] - '0'; // angle it's a direct acess to group
|
||||
if(num == 8) num = 0; // merge
|
||||
com.strncpy( flat.frame[num].name, header, 9 );
|
||||
flat.frame[num].width = pic->width;
|
||||
flat.frame[num].height = pic->height;
|
||||
flat.frame[num].origin[0] = pic->width>>1; // center
|
||||
flat.frame[num].origin[1] = pic->height; // floor
|
||||
flat.frame[num].xmirrored = true; // it's mirror frame
|
||||
flat.angledframes++; // frame stored
|
||||
}
|
||||
else Sys_Break( "Skin_CreateScript: invalid name %s\n", name ); // this never happens
|
||||
}
|
||||
}
|
||||
|
||||
void Skin_ProcessScript( const char *wad, const char *name )
|
||||
{
|
||||
if( flat.in_progress )
|
||||
{
|
||||
// finish script
|
||||
Skin_WriteSequence();
|
||||
FS_Close( flat.f );
|
||||
flat.in_progress = false;
|
||||
}
|
||||
if( !flat.in_progress )
|
||||
{
|
||||
// start from scratch
|
||||
com.strncpy( flat.membername, name, 5 );
|
||||
flat.f = FS_Open( va("%s/%s/%s.qc", gs_gamedir, wad, flat.membername ), "w" );
|
||||
flat.in_progress = true;
|
||||
flat.bounds[0] = flat.bounds[1] = 0;
|
||||
|
||||
// write description
|
||||
FS_Print( flat.f,"//=======================================================================\n");
|
||||
FS_Printf( flat.f,"//\t\t\tCopyright XashXT Group %s ©\n", timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Print( flat.f,"//\t\t\twritten by Xash Miptex Decompiler\n");
|
||||
FS_Print( flat.f,"//=======================================================================\n");
|
||||
|
||||
// write sprite header
|
||||
FS_Printf( flat.f, "\n$spritename\t%s.spr\n", flat.membername );
|
||||
FS_Print( flat.f, "$type\t\tfacing_upright\n" ); // constant
|
||||
FS_Print( flat.f, "$texture\t\talphatest\n");
|
||||
FS_Print( flat.f, "$noresample\n" ); // comment this commad by taste
|
||||
}
|
||||
}
|
||||
|
||||
// close sequence for unexpected concessions
|
||||
void Skin_FinalizeScript( void )
|
||||
{
|
||||
if( !flat.in_progress ) return;
|
||||
|
||||
// finish script
|
||||
Skin_WriteSequence();
|
||||
FS_Close( flat.f );
|
||||
flat.in_progress = false;
|
||||
}
|
||||
|
||||
void Skin_CreateScript( const char *name, rgbdata_t *pic )
|
||||
{
|
||||
string skinname, wadname;
|
||||
|
||||
FS_ExtractFilePath( name, wadname ); // wad name
|
||||
FS_FileBase( name, skinname ); // skinname
|
||||
|
||||
if(com.strnicmp( skinname, flat.membername, 4 ))
|
||||
Skin_ProcessScript( wadname, skinname );
|
||||
|
||||
if( flat.in_progress )
|
||||
Skin_FindSequence( skinname, pic );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvSKN
|
||||
============
|
||||
*/
|
||||
bool ConvSKN( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.flt", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Skin_CreateScript( name, pic );
|
||||
Msg( "%s.flat\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvFLP
|
||||
============
|
||||
*/
|
||||
bool ConvFLP( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.flt", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage(va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Msg("%s.flat\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvFLT
|
||||
============
|
||||
*/
|
||||
bool ConvFLT( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.flt", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
string savedname, tempname, path;
|
||||
|
||||
if( pic->flags & IMAGE_HAVE_ALPHA )
|
||||
{
|
||||
// insert '{' symbol for transparency textures
|
||||
FS_ExtractFilePath( name, path );
|
||||
FS_FileBase( name, tempname );
|
||||
com.snprintf( savedname, MAX_STRING, "%s/{%s", path, tempname );
|
||||
}
|
||||
else com.strncpy( savedname, name, MAX_STRING );
|
||||
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, savedname, ext ), pic );
|
||||
Conv_CreateShader( savedname, pic, "flt", NULL, 0, 0 );
|
||||
Msg("%s.flat\n", savedname ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvMID
|
||||
============
|
||||
*/
|
||||
bool ConvMID( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
if(Conv_Mus2Mid( name, buffer, filesize ))
|
||||
{
|
||||
Msg("%s.mus\n", name ); // echo to console
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// conv_image.c - convert various image type
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.WAL image format (Wally textures)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct wal_s
|
||||
{
|
||||
char name[32];
|
||||
uint width, height;
|
||||
uint offsets[4]; // four mip maps stored
|
||||
char animname[32]; // next frame in animation chain
|
||||
int flags;
|
||||
int contents;
|
||||
int value;
|
||||
} wal_t;
|
||||
|
||||
/*
|
||||
============
|
||||
ConvWAL
|
||||
============
|
||||
*/
|
||||
bool ConvWAL( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.wal", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
wal_t *wal = (wal_t *)buffer;
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Conv_CreateShader( name, pic, "wal", wal->animname, wal->flags, wal->contents );
|
||||
Msg("%s.wal\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvJPG
|
||||
=============
|
||||
*/
|
||||
bool ConvJPG( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.jpg", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Conv_CreateShader( name, pic, "jpg", NULL, 0, 0 );
|
||||
Msg( "%s.jpg\n", name, ext ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvPCX
|
||||
|
||||
this also uses by SP2_ConvertFrame
|
||||
=============
|
||||
*/
|
||||
bool ConvPCX( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.pcx", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
// pcx images not required shader because it hud pics or sprite frames
|
||||
Msg( "%s.pcx\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvVTF
|
||||
=============
|
||||
*/
|
||||
bool ConvVTF( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.vtf", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Conv_CreateShader( name, pic, "vtf", NULL, 0, 0 );
|
||||
Msg( "%s.vtf\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvMIP
|
||||
============
|
||||
*/
|
||||
bool ConvMIP( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.mip", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Conv_CreateShader( name, pic, "mip", NULL, 0, 0 );
|
||||
Msg("%s.mip\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvLMP
|
||||
============
|
||||
*/
|
||||
bool ConvLMP( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.lmp", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_SaveImage(va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
Msg("%s.lmp\n", name ); // echo to console
|
||||
FS_FreeImage( pic );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvRAW
|
||||
|
||||
write to disk without conversions
|
||||
============
|
||||
*/
|
||||
bool ConvRAW( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
if( FS_WriteFile( va("%s/%s.%s", gs_gamedir, name, ext ), buffer, filesize ))
|
||||
{
|
||||
Msg( "%s.%s\n", name, ext ); // echo to console
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -4,20 +4,9 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
stdlib_api_t com;
|
||||
byte *basepool;
|
||||
byte *zonepool;
|
||||
static double start, end;
|
||||
string gs_gamedir;
|
||||
string gs_searchmask;
|
||||
|
||||
#define MAX_SEARCHMASK 256
|
||||
string searchmask[MAX_SEARCHMASK];
|
||||
int num_searchmask = 0;
|
||||
bool write_qscsript;
|
||||
int game_family;
|
||||
bool write_qscsript;
|
||||
int game_family;
|
||||
|
||||
typedef struct convformat_s
|
||||
{
|
||||
|
@ -31,7 +20,7 @@ convformat_t convert_formats[] =
|
|||
{
|
||||
{"%s.%s", "spr", ConvSPR, "bmp" }, // quake1/half-life sprite
|
||||
{"%s.%s","spr32",ConvSPR, "tga" }, // spr32 sprite
|
||||
{"%s.%s", "sp2", ConvSP2, "bmp" }, // quake2 sprite
|
||||
{"%s.%s", "sp2", ConvSPR, "bmp" }, // quake2 sprite
|
||||
{"%s.%s", "jpg", ConvJPG, "tga" }, // quake3 textures
|
||||
{"%s.%s", "pcx", ConvPCX, "bmp" }, // quake2 pics
|
||||
{"%s.%s", "flt", ConvFLT, "bmp" }, // doom1 textures
|
||||
|
@ -42,8 +31,7 @@ convformat_t convert_formats[] =
|
|||
{"%s.%s", "vtf", ConvVTF, "dds" }, // Half-Life 2 materials
|
||||
{"%s.%s", "skn", ConvSKN, "bmp" }, // doom1 sprite models
|
||||
{"%s.%s", "bsp", ConvBSP, "bmp" }, // Quake1\Half-Life map textures
|
||||
{"%s.%s", "mus", ConvMID, "mid" }, // Quake1\Half-Life map textures
|
||||
{"%s.%s", "snd", ConvSND, "wav" }, // Quake1\Half-Life map textures
|
||||
{"%s.%s", "mus", ConvMID, "mid" }, // doom1\2 music files
|
||||
{"%s.%s", "txt", ConvRAW, "txt" }, // (hidden) Xash-extract scripts
|
||||
{"%s.%s", "dat", ConvRAW, "dat" }, // (hidden) Xash-extract progs
|
||||
{NULL, NULL, NULL, NULL } // list terminator
|
||||
|
@ -51,10 +39,21 @@ convformat_t convert_formats[] =
|
|||
|
||||
bool CheckForExist( const char *path, const char *ext )
|
||||
{
|
||||
if( game_family == GAME_DOOM1 )
|
||||
{
|
||||
string name, wad;
|
||||
|
||||
// HACK: additional check for { symbol
|
||||
FS_ExtractFilePath( path, wad );
|
||||
FS_FileBase( path, name );
|
||||
if(FS_FileExists( va( "%s/%s/{%s.%s", gs_gamedir, wad, name, ext )))
|
||||
return true;
|
||||
// fallback to normal checking
|
||||
}
|
||||
return FS_FileExists( va( "%s/%s.%s", gs_gamedir, path, ext ));
|
||||
}
|
||||
|
||||
bool ConvertResource( const char *filename )
|
||||
bool ConvertResource( byte *mempool, const char *filename, byte parms )
|
||||
{
|
||||
convformat_t *format;
|
||||
const char *ext = FS_FileExtension( filename );
|
||||
|
@ -77,7 +76,7 @@ bool ConvertResource( const char *filename )
|
|||
if( buffer && filesize > 0 )
|
||||
{
|
||||
// this path may contains wadname: wadfile/lumpname
|
||||
if( format->convfunc( path, buffer, filesize, format->ext2 ))
|
||||
if( format->convfunc( convname, buffer, filesize, format->ext2 ))
|
||||
{
|
||||
Mem_Free( buffer ); // release buffer
|
||||
return true; // converted ok
|
||||
|
@ -91,23 +90,6 @@ bool ConvertResource( const char *filename )
|
|||
return false;
|
||||
}
|
||||
|
||||
void ClrMask( void )
|
||||
{
|
||||
num_searchmask = 0;
|
||||
memset( searchmask, 0, MAX_STRING * MAX_SEARCHMASK );
|
||||
}
|
||||
|
||||
void AddMask( const char *mask )
|
||||
{
|
||||
if( num_searchmask >= MAX_SEARCHMASK )
|
||||
{
|
||||
MsgDev( D_WARN, "AddMask: searchlist is full\n" );
|
||||
return;
|
||||
}
|
||||
com.strncpy( searchmask[num_searchmask], mask, MAX_STRING );
|
||||
num_searchmask++;
|
||||
}
|
||||
|
||||
void Conv_DetectGameType( void )
|
||||
{
|
||||
int i;
|
||||
|
@ -144,38 +126,14 @@ void Conv_DetectGameType( void )
|
|||
ClrMask();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CommonInit
|
||||
|
||||
idconv.dll needs for some setup operations
|
||||
so do it manually
|
||||
==================
|
||||
*/
|
||||
void InitConvertor ( int argc, char **argv )
|
||||
{
|
||||
|
||||
// init pools
|
||||
basepool = Mem_AllocPool( "Ripper Temp" );
|
||||
zonepool = Mem_AllocPool( "Ripper Zone" );
|
||||
FS_InitRootDir(".");
|
||||
|
||||
start = Sys_DoubleTime();
|
||||
Msg("\n\n");
|
||||
}
|
||||
|
||||
void RunConvertor( void )
|
||||
void Conv_RunSearch( void )
|
||||
{
|
||||
search_t *search;
|
||||
string errorstring;
|
||||
int i, j, k, imageflags, numConvertedRes = 0;
|
||||
cvar_t *fs_defaultdir = Cvar_Get( "fs_defaultdir", "tmpQuArK", CVAR_SYSTEMINFO, NULL );
|
||||
int i, j, k, imageflags;
|
||||
|
||||
memset( errorstring, 0, MAX_STRING );
|
||||
ClrMask();
|
||||
Conv_DetectGameType();
|
||||
|
||||
if( game_family ) Msg("Game: %s family\n", game_names[game_family] );
|
||||
if( game_family ) Msg( "Game: %s family\n", game_names[game_family] );
|
||||
imageflags = IL_USE_LERPING;
|
||||
write_qscsript = false;
|
||||
|
||||
|
@ -191,7 +149,6 @@ void RunConvertor( void )
|
|||
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 );
|
||||
|
@ -202,7 +159,6 @@ void RunConvertor( void )
|
|||
AddMask( "*.skn" ); // Doom1 sprite models
|
||||
AddMask( "*.flp" ); // Doom1 pics
|
||||
AddMask( "*.flt" ); // Doom1 textures
|
||||
AddMask( "*.snd" ); // Doom1 sounds
|
||||
AddMask( "*.mus" ); // Doom1 music
|
||||
}
|
||||
imageflags |= IL_KEEP_8BIT;
|
||||
|
@ -322,7 +278,7 @@ void RunConvertor( void )
|
|||
Image_Init( "Quake4", imageflags );
|
||||
break;
|
||||
case GAME_HALFLIFE:
|
||||
search = FS_Search("*.wad", true );
|
||||
search = FS_Search( "*.wad", true );
|
||||
if( search )
|
||||
{
|
||||
// find subdirectories
|
||||
|
@ -353,71 +309,4 @@ void RunConvertor( void )
|
|||
Image_Init( "Generic", imageflags ); // everything else
|
||||
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));
|
||||
Msg( "Converting ...\n\n" );
|
||||
|
||||
// search by mask
|
||||
for( i = 0; i < num_searchmask; i++ )
|
||||
{
|
||||
// skip blank mask
|
||||
if(!com.strlen(searchmask[i])) continue;
|
||||
search = FS_Search( searchmask[i], true );
|
||||
if( !search ) continue; // try next mask
|
||||
|
||||
for( j = 0; j < search->numfilenames; j++ )
|
||||
{
|
||||
if(ConvertResource( search->filenames[j] ))
|
||||
numConvertedRes++;
|
||||
}
|
||||
Mem_Free( search );
|
||||
}
|
||||
if( numConvertedRes == 0 )
|
||||
{
|
||||
for(j = 0; j < MAX_SEARCHMASK; j++)
|
||||
{
|
||||
if(!com.strlen(searchmask[j])) continue;
|
||||
com.strncat(errorstring, va("%s ", searchmask[j]), MAX_STRING );
|
||||
}
|
||||
Sys_Break("no %s found in this folder!\n", errorstring );
|
||||
}
|
||||
|
||||
end = Sys_DoubleTime();
|
||||
Msg ("%5.3f seconds elapsed\n", end - start);
|
||||
if(numConvertedRes > 1) Msg("total %d files compiled\n", numConvertedRes );
|
||||
}
|
||||
|
||||
void CloseConvertor( void )
|
||||
{
|
||||
// finalize qc-script
|
||||
Skin_FinalizeScript();
|
||||
|
||||
Mem_Check(); // check for leaks
|
||||
Mem_FreePool( &basepool );
|
||||
Mem_FreePool( &zonepool );
|
||||
}
|
||||
|
||||
launch_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, void *unused )
|
||||
{
|
||||
static launch_exp_t Com;
|
||||
|
||||
com = *input;
|
||||
|
||||
// generic functions
|
||||
Com.api_size = sizeof(launch_exp_t);
|
||||
|
||||
Com.Init = InitConvertor;
|
||||
Com.Main = RunConvertor;
|
||||
Com.Free = CloseConvertor;
|
||||
|
||||
return &Com;
|
||||
}
|
|
@ -5,28 +5,61 @@
|
|||
|
||||
#include "ripper.h"
|
||||
#include "mathlib.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
// q2 wal contents
|
||||
#define CONTENTS_SOLID 0x00000001 // an eye is never valid in a solid
|
||||
#define CONTENTS_WINDOW 0x00000002 // translucent, but not watery
|
||||
#define CONTENTS_AUX 0x00000004
|
||||
#define CONTENTS_LAVA 0x00000008
|
||||
#define CONTENTS_SLIME 0x00000010
|
||||
#define CONTENTS_WATER 0x00000020
|
||||
#define CONTENTS_MIST 0x00000040
|
||||
|
||||
// remaining contents are non-visible, and don't eat brushes
|
||||
#define CONTENTS_AREAPORTAL 0x00008000
|
||||
#define CONTENTS_PLAYERCLIP 0x00010000
|
||||
#define CONTENTS_MONSTERCLIP 0x00020000
|
||||
|
||||
// currents can be added to any other contents, and may be mixed
|
||||
#define CONTENTS_CURRENT_0 0x00040000
|
||||
#define CONTENTS_CURRENT_90 0x00080000
|
||||
#define CONTENTS_CURRENT_180 0x00100000
|
||||
#define CONTENTS_CURRENT_270 0x00200000
|
||||
#define CONTENTS_CURRENT_UP 0x00400000
|
||||
#define CONTENTS_CURRENT_DOWN 0x00800000
|
||||
|
||||
#define CONTENTS_ORIGIN 0x01000000 // removed before BSP'ing an entity
|
||||
|
||||
#define CONTENTS_MONSTER 0x02000000 // should never be on a brush, only in game
|
||||
#define CONTENTS_DEADMONSTER 0x04000000
|
||||
#define CONTENTS_DETAIL 0x08000000 // brushes to be added after vis leafs
|
||||
#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
|
||||
#define CONTENTS_LADDER 0x20000000
|
||||
|
||||
#define SURF_LIGHT 0x00000001 // value will hold the light strength
|
||||
#define SURF_SLICK 0x00000002 // effects game physics
|
||||
#define SURF_SKY 0x00000004 // don't draw, but add to skybox
|
||||
#define SURF_WARP 0x00000008 // turbulent water warp
|
||||
#define SURF_TRANS33 0x00000010 // 33% opacity
|
||||
#define SURF_TRANS66 0x00000020 // 66% opacity
|
||||
#define SURF_FLOWING 0x00000040 // scroll towards angle
|
||||
#define SURF_NODRAW 0x00000080 // don't bother referencing the texture
|
||||
#define SURF_HINT 0x00000100 // make a primary bsp splitter
|
||||
#define SURF_SKIP 0x00000200 // completely ignore, allowing non-closed brushes
|
||||
|
||||
// xash 0.45 surfaces replacement table
|
||||
#define SURF_MIRROR 0x00010000 // mirror surface
|
||||
#define SURF_PORTAL 0x00020000 // portal surface
|
||||
|
||||
string nextanimchain;
|
||||
file_t *f;
|
||||
|
||||
void Conv_RoundDimensions( int *scaled_width, int *scaled_height )
|
||||
{
|
||||
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 = NULL;
|
||||
string wadname;
|
||||
string qcname, qcpath;
|
||||
string temp, lumpname;
|
||||
string wadname;
|
||||
|
||||
// write also wadlist.qc for xwad compiler
|
||||
FS_ExtractFilePath( imagepath, temp );
|
||||
|
@ -35,7 +68,7 @@ bool Conv_WriteShader( const char *shaderpath, const char *imagepath, rgbdata_t
|
|||
FS_FileBase( temp, wadname );
|
||||
FS_DefaultExtension( qcname, ".qc" );
|
||||
FS_DefaultExtension( wadname, ".wad" ); // check for wad later
|
||||
com.snprintf( qcpath, MAX_STRING, "%s/%s/%s", gs_gamedir, temp, qcname );
|
||||
com.snprintf( qcpath, MAX_STRING, "%s/%s/$%s", gs_gamedir, temp, qcname );
|
||||
|
||||
if( write_qscsript )
|
||||
{
|
||||
|
@ -50,7 +83,7 @@ bool Conv_WriteShader( const char *shaderpath, const char *imagepath, rgbdata_t
|
|||
f = FS_Open( qcpath, "w" ); // new file
|
||||
// write description
|
||||
FS_Print(f,"//=======================================================================\n");
|
||||
FS_Print(f,"//\t\t\tCopyright XashXT Group 2007 ©\n");
|
||||
FS_Printf(f,"//\t\t\tCopyright XashXT Group %s ©\n", timestamp( TIME_YEAR_ONLY ));
|
||||
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 );
|
||||
|
@ -83,7 +116,7 @@ bool Conv_WriteShader( const char *shaderpath, const char *imagepath, rgbdata_t
|
|||
f = FS_Open( shaderpath, "w" ); // new file
|
||||
// write description
|
||||
FS_Print(f,"//=======================================================================\n");
|
||||
FS_Print(f,"//\t\t\tCopyright XashXT Group 2007 ©\n");
|
||||
FS_Printf(f,"//\t\t\tCopyright XashXT Group %s ©\n", timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Print(f,"//\t\t\twritten by Xash Miptex Decompiler\n");
|
||||
FS_Print(f,"//=======================================================================\n");
|
||||
}
|
||||
|
@ -258,9 +291,8 @@ bool Conv_CreateShader( const char *name, rgbdata_t *pic, const char *ext, const
|
|||
FS_ExtractFilePath( name, shadername );
|
||||
FS_FileBase( shadername, shadername ); // remove "textures" from path
|
||||
FS_FileBase( name, imagename );
|
||||
com.snprintf( shaderpath, MAX_STRING, "%s/scripts/shaders/%s.txt", gs_gamedir, shadername );
|
||||
if(com.stristr(name, "textures")) com.snprintf( imagepath, MAX_STRING, "%s", name ); // full path
|
||||
else com.snprintf( imagepath, MAX_STRING, "textures/%s", name ); // build full path
|
||||
com.snprintf( shaderpath, MAX_STRING, "%s/shaders/%s.txt", gs_gamedir, shadername );
|
||||
com.snprintf( imagepath, MAX_STRING, "%s", name ); // full path
|
||||
nextanimchain[0] = 0; // clear chain
|
||||
|
||||
if(anim && com.strlen(anim)) // wally animname
|
||||
|
@ -277,186 +309,4 @@ bool Conv_CreateShader( const char *name, rgbdata_t *pic, const char *ext, const
|
|||
// FIXME: calculate image light color here
|
||||
}
|
||||
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 );
|
||||
if( flat.frame[i].xmirrored )FS_Print(f," flip_x\n");
|
||||
else FS_Print(f, "\n" );
|
||||
FS_Printf(f,"\t$frame\t\t0 0 %d %d", flat.frame[i].width, flat.frame[i].height );
|
||||
FS_Printf(f, " 0.1 %d %d\n", flat.frame[i].origin[0], flat.frame[i].origin[1] );
|
||||
}
|
||||
FS_Print(f, "}\n" );
|
||||
}
|
||||
else if( flat.normalframes == 1 )
|
||||
{
|
||||
// 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]);
|
||||
}
|
||||
|
||||
// drop mirror frames too
|
||||
if( flat.mirrorframes == 8 )
|
||||
{
|
||||
// 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 );
|
||||
FS_Printf(f,"\t$frame\t\t0 0 %d %d", flat.frame[i].width, flat.frame[i].height );
|
||||
FS_Printf(f, " 0.1 %d %d\n", flat.frame[i].origin[0], flat.frame[i].origin[1] );
|
||||
}
|
||||
for( i = 7; i > 2; i--)
|
||||
{
|
||||
FS_Printf(f,"\t$load\t\t%s.bmp flip_x\n", flat.frame[i].name );
|
||||
FS_Printf(f,"\t$frame\t\t0 0 %d %d", flat.frame[i].width, flat.frame[i].height );
|
||||
FS_Printf(f, " 0.1 %d %d\n", flat.frame[i].origin[0], flat.frame[i].origin[1] );
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
void Skin_FindSequence( const char *name, rgbdata_t *pic )
|
||||
{
|
||||
uint headlen;
|
||||
char num, header[10];
|
||||
|
||||
// create header from flat name
|
||||
com.strncpy( header, name, 10 );
|
||||
headlen = com.strlen( name );
|
||||
|
||||
if( flat.animation != header[4] )
|
||||
{
|
||||
// write animation
|
||||
Skin_WriteSequence();
|
||||
flat.animation = header[4];
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
num = header[5] - '0';
|
||||
if(num == 0) flat.normalframes++; // animation frame
|
||||
if(num == 8) num = 0; // merge
|
||||
flat.angledframes++; // angleframe stored
|
||||
com.strncpy( flat.frame[num].name, header, 9 );
|
||||
flat.frame[num].width = pic->width;
|
||||
flat.frame[num].height = pic->height;
|
||||
flat.frame[num].origin[0] = pic->width>>1; // center
|
||||
flat.frame[num].origin[1] = pic->height; // floor
|
||||
flat.frame[num].xmirrored = false;
|
||||
}
|
||||
else if( headlen == 8 )
|
||||
{
|
||||
// normal image
|
||||
num = header[5] - '0';
|
||||
if(num == 8) num = 0; // merge
|
||||
com.strncpy( flat.frame[num].name, header, 9 );
|
||||
flat.frame[num].width = pic->width;
|
||||
flat.frame[num].height = pic->height;
|
||||
flat.frame[num].origin[0] = pic->width>>1; // center
|
||||
flat.frame[num].origin[1] = pic->height; // floor
|
||||
flat.frame[num].xmirrored = false;
|
||||
flat.angledframes++; // frame stored
|
||||
|
||||
if( header[4] != header[6] )
|
||||
{
|
||||
// mirrored groups
|
||||
flat.mirrorframes++;
|
||||
return;
|
||||
}
|
||||
|
||||
// mirrored image
|
||||
num = header[7] - '0'; // angle it's a direct acess to group
|
||||
if(num == 8) num = 0; // merge
|
||||
com.strncpy( flat.frame[num].name, header, 9 );
|
||||
flat.frame[num].width = pic->width;
|
||||
flat.frame[num].height = pic->height;
|
||||
flat.frame[num].origin[0] = pic->width>>1; // center
|
||||
flat.frame[num].origin[1] = pic->height; // floor
|
||||
flat.frame[num].xmirrored = true; // it's mirror frame
|
||||
flat.angledframes++; // frame stored
|
||||
}
|
||||
else Sys_Break("Skin_CreateScript: invalid name %s\n", name );
|
||||
}
|
||||
}
|
||||
|
||||
void Skin_ProcessScript( const char *wad, const char *name )
|
||||
{
|
||||
if(flat.in_progress )
|
||||
{
|
||||
// finish script
|
||||
Skin_WriteSequence();
|
||||
FS_Close( f );
|
||||
flat.in_progress = false;
|
||||
}
|
||||
if(!flat.in_progress )
|
||||
{
|
||||
// start from scratch
|
||||
com.strncpy( flat.membername, name, 5 );
|
||||
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");
|
||||
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");
|
||||
|
||||
// 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\talphatest\n");
|
||||
FS_Print(f, "$noresample\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Skin_FinalizeScript( void )
|
||||
{
|
||||
if(!flat.in_progress ) return;
|
||||
|
||||
// finish script
|
||||
Skin_WriteSequence();
|
||||
FS_Close( f );
|
||||
flat.in_progress = false;
|
||||
}
|
||||
|
||||
void Skin_CreateScript( const char *wad, const char *name, rgbdata_t *pic )
|
||||
{
|
||||
if(com.strnicmp( name, flat.membername, 4 ))
|
||||
Skin_ProcessScript( wad, name );
|
||||
|
||||
if( flat.in_progress )
|
||||
Skin_FindSequence( name, pic );
|
||||
}
|
|
@ -0,0 +1,451 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// conv_sprite.c - convert q1\q2\hl\spr32 sprites
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
// sprite_decompiler.c
|
||||
#define SPR_VP_PARALLEL_UPRIGHT 0
|
||||
#define SPR_FACING_UPRIGHT 1
|
||||
#define SPR_VP_PARALLEL 2
|
||||
#define SPR_ORIENTED 3 // all axis are valid
|
||||
#define SPR_VP_PARALLEL_ORIENTED 4
|
||||
|
||||
#define SPR_NORMAL 0 // solid sprite
|
||||
#define SPR_ADDITIVE 1
|
||||
#define SPR_INDEXALPHA 2
|
||||
#define SPR_ALPHTEST 3
|
||||
#define SPR_ADDGLOW 4 // same as additive, but without depthtest
|
||||
|
||||
typedef struct frame_s
|
||||
{
|
||||
char name[64]; // framename
|
||||
|
||||
int width; // lumpwidth
|
||||
int height; // lumpheight
|
||||
int origin[2]; // monster origin
|
||||
} frame_t;
|
||||
|
||||
typedef struct group_s
|
||||
{
|
||||
frame_t frame[64]; // max groupframes
|
||||
float interval[64]; // frame intervals
|
||||
int numframes; // num group frames;
|
||||
} group_t;
|
||||
|
||||
struct qcsprite_s
|
||||
{
|
||||
group_t group[8]; // 64 frames for each group
|
||||
frame_t frame[512]; // or 512 ungroupped frames
|
||||
|
||||
int type; // rendering type
|
||||
int texFormat; // half-life texture
|
||||
bool truecolor; // spr32
|
||||
byte palette[256][4]; // shared palette
|
||||
|
||||
int numgroup; // groups counter
|
||||
int totalframes; // including group frames
|
||||
} spr;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.SPR sprite file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
#define IDSPRQ1HEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDSP"
|
||||
|
||||
#define SPRITEQ1_VERSION 1
|
||||
#define SPRITEHL_VERSION 2
|
||||
#define SPRITE32_VERSION 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int type;
|
||||
int boundingradius;
|
||||
int width;
|
||||
int height;
|
||||
int numframes;
|
||||
float beamlength;
|
||||
synctype_t synctype;
|
||||
} dspriteq1_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int type;
|
||||
int texFormat; // Half-Life stuff only
|
||||
float boundingradius; // software rendering stuff
|
||||
int width;
|
||||
int height;
|
||||
int numframes;
|
||||
float beamlength; // software rendering stuff
|
||||
synctype_t synctype;
|
||||
} dspritehl_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.SP2 sprite file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
#define IDSPRQ2HEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDS2"
|
||||
|
||||
#define SPRITEQ2_VERSION 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int origin_x;
|
||||
int origin_y; // raster coordinates inside pic
|
||||
char name[64]; // name of pcx file
|
||||
} dsprframeq2_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int numframes;
|
||||
dsprframeq2_t frames[1]; // variable sized
|
||||
} dspriteq2_t;
|
||||
|
||||
_inline const char *SPR_RenderMode( void )
|
||||
{
|
||||
switch( spr.texFormat )
|
||||
{
|
||||
case SPR_ADDGLOW: return "glow";
|
||||
case SPR_ALPHTEST: return "alphatest";
|
||||
case SPR_INDEXALPHA: return "indexalpha";
|
||||
case SPR_ADDITIVE: return "additive";
|
||||
case SPR_NORMAL: return "solid";
|
||||
default: return "normal";
|
||||
}
|
||||
}
|
||||
|
||||
_inline const char *SPR_RenderType( void )
|
||||
{
|
||||
switch( spr.type )
|
||||
{
|
||||
case SPR_ORIENTED: return "oriented";
|
||||
case SPR_VP_PARALLEL: return "vp_parallel";
|
||||
case SPR_FACING_UPRIGHT: return "facing_upright";
|
||||
case SPR_VP_PARALLEL_UPRIGHT: return "vp_parallel_upright";
|
||||
case SPR_VP_PARALLEL_ORIENTED: return "vp_parallel_oriented";
|
||||
default: return "oriented";
|
||||
}
|
||||
}
|
||||
|
||||
void *SPR_ConvertFrame( const char *name, const char *ext, void *pin, int framenum, int groupframenum )
|
||||
{
|
||||
rgbdata_t *pix;
|
||||
dspriteframe_t *pinframe;
|
||||
string framename;
|
||||
byte *fin, *fout;
|
||||
int i, pixels, width, height;
|
||||
|
||||
pinframe = (dspriteframe_t *)pin;
|
||||
width = LittleLong( pinframe->width );
|
||||
height = LittleLong( pinframe->height );
|
||||
fin = (byte *)(pinframe + 1);
|
||||
if( width <= 0 || height <= 0 )
|
||||
{
|
||||
// NOTE: in Q1 existing sprites with blank frames
|
||||
spr.totalframes--;
|
||||
return (void *)((byte *)(pinframe + 1));
|
||||
}
|
||||
|
||||
// extract sprite name from path
|
||||
FS_FileBase( name, framename );
|
||||
com.strcat( framename, va("_%i", framenum ));
|
||||
pixels = width * height;
|
||||
if( spr.truecolor ) pixels *= 4;
|
||||
|
||||
// frame exist, go next
|
||||
if( FS_FileExists( va("%s/sprites/%s.%s", gs_gamedir, framename, ext )))
|
||||
return (void *)((byte *)(pinframe + 1) + pixels );
|
||||
|
||||
if( spr.truecolor )
|
||||
{
|
||||
// HACKHACK: manually create rgbdata_t
|
||||
pix = Mem_Alloc( basepool, sizeof( *pix ));
|
||||
fout = Mem_Alloc( basepool, pixels );
|
||||
Mem_Copy( fout, fin, pixels );
|
||||
if( spr.texFormat >= SPR_INDEXALPHA )
|
||||
pix->flags |= IMAGE_HAVE_ALPHA;
|
||||
pix->type = PF_RGBA_32;
|
||||
pix->width = width;
|
||||
pix->height = height;
|
||||
pix->size = pixels;
|
||||
pix->numLayers = 1;
|
||||
pix->numMips = 1;
|
||||
pix->buffer = fout;
|
||||
}
|
||||
else
|
||||
{
|
||||
pix = FS_LoadImage( va( "#%s.spr", framename ), pin, pixels );
|
||||
Image_Process( &pix, 0, 0, IMAGE_PALTO24 );
|
||||
}
|
||||
|
||||
if( groupframenum )
|
||||
{
|
||||
i = groupframenum - 1;
|
||||
com.strncpy( spr.group[spr.numgroup].frame[i].name, framename, MAX_STRING );
|
||||
spr.group[spr.numgroup].frame[i].origin[0] = -(float)LittleLong(pinframe->origin[0]);
|
||||
spr.group[spr.numgroup].frame[i].origin[1] = (float)LittleLong(pinframe->origin[1]);
|
||||
spr.group[spr.numgroup].frame[i].width = (float)LittleLong(pinframe->width);
|
||||
spr.group[spr.numgroup].frame[i].height = (float)LittleLong(pinframe->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
com.strncpy( spr.frame[framenum].name, framename, MAX_STRING );
|
||||
spr.frame[framenum].origin[0] = -(float)LittleLong(pinframe->origin[0]);
|
||||
spr.frame[framenum].origin[1] = (float)LittleLong(pinframe->origin[1]);
|
||||
spr.frame[framenum].width = (float)LittleLong(pinframe->width);
|
||||
spr.frame[framenum].height = (float)LittleLong(pinframe->height);
|
||||
}
|
||||
|
||||
FS_SaveImage( va("%s/sprites/%s.%s", gs_gamedir, framename, ext ), pix );
|
||||
FS_FreeImage( pix ); // free image
|
||||
|
||||
// jump to next frame
|
||||
return (void *)((byte *)(pinframe + 1) + pixels ); // no mipmap stored
|
||||
}
|
||||
|
||||
bool SP2_ConvertFrame( const char *name, const char *ext, int framenum )
|
||||
{
|
||||
byte *fin;
|
||||
size_t filesize;
|
||||
string barename;
|
||||
|
||||
// store framename
|
||||
FS_FileBase( name, spr.frame[framenum].name );
|
||||
com.strncpy( barename, name, MAX_STRING );
|
||||
FS_StripExtension( barename );
|
||||
|
||||
if( FS_FileExists( va("%s/%s.%s", gs_gamedir, barename, ext )))
|
||||
return true;
|
||||
|
||||
fin = FS_LoadFile( name, &filesize );
|
||||
if( fin )
|
||||
{
|
||||
ConvPCX( barename, fin, filesize, ext );
|
||||
Mem_Free( fin );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void *SPR_ConvertGroup( const char *name, const char *ext, void *pin, int framenum )
|
||||
{
|
||||
dspritegroup_t *pingroup;
|
||||
int i, numframes;
|
||||
dspriteinterval_t *pin_intervals;
|
||||
void *ptemp;
|
||||
|
||||
pingroup = (dspritegroup_t *)pin;
|
||||
numframes = LittleLong( pingroup->numframes );
|
||||
pin_intervals = (dspriteinterval_t *)(pingroup + 1);
|
||||
|
||||
for (i = 0; i < numframes; i++)
|
||||
{
|
||||
spr.group[spr.numgroup].interval[i] = LittleLong( pin_intervals->interval );
|
||||
pin_intervals++;
|
||||
}
|
||||
|
||||
// update global numframes
|
||||
spr.group[spr.numgroup].numframes = numframes - 1;
|
||||
ptemp = (void *)pin_intervals;
|
||||
|
||||
for (i = 0; i < numframes; i++ )
|
||||
{
|
||||
ptemp = SPR_ConvertFrame( name, ext, ptemp, framenum + i, i + 1 );
|
||||
}
|
||||
spr.numgroup++;
|
||||
return ptemp;
|
||||
}
|
||||
|
||||
bool SPR_WriteScript( const char *name, const char *ext )
|
||||
{
|
||||
string shortname;
|
||||
int i, j;
|
||||
file_t *f;
|
||||
|
||||
FS_FileBase( name ,shortname );
|
||||
if( FS_FileExists( va("%s/sprites/%s.qc", gs_gamedir, shortname )))
|
||||
return true;
|
||||
f = FS_Open( va("%s/sprites/%s.qc", gs_gamedir, shortname ), "w" );
|
||||
|
||||
if( !f )
|
||||
{
|
||||
Msg( "Can't create qc-script \"%s.qc\"\n", shortname );
|
||||
return false;
|
||||
}
|
||||
|
||||
// description
|
||||
FS_Printf(f,"//=======================================================================\n");
|
||||
FS_Printf(f,"//\t\t\tCopyright XashXT Group %s ©\n", timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf(f,"//\t\t\twritten by Xash Miptex Decompiler\n", name );
|
||||
FS_Printf(f,"//=======================================================================\n");
|
||||
|
||||
// sprite header
|
||||
FS_Printf(f, "\n$spritename\t%s.spr\n", name );
|
||||
FS_Printf(f, "$type\t\t%s\n", SPR_RenderType());
|
||||
FS_Printf(f, "$texture\t\t%s\n\n", SPR_RenderMode());
|
||||
|
||||
// frames description
|
||||
for( i = 0; i < spr.totalframes - spr.numgroup; i++)
|
||||
{
|
||||
FS_Printf(f,"$load\t\t%s.%s\n", spr.frame[i].name, 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]);
|
||||
}
|
||||
|
||||
for( i = 0; i < spr.numgroup; i++ )
|
||||
{
|
||||
FS_Print(f, "$group\n{\n" );
|
||||
for( j = 0; j < spr.group[i].numframes; j++)
|
||||
{
|
||||
FS_Printf(f,"\t$load\t\t%s.%s\n", spr.group[i].frame[j].name, 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" );
|
||||
else FS_Printf(f, " %d %d\n", spr.group[i].frame[j].origin[0],spr.group[i].frame[j].origin[1]);
|
||||
}
|
||||
FS_Print(f, "}\n" );
|
||||
}
|
||||
|
||||
FS_Print(f,"\n" );
|
||||
FS_Close( f );
|
||||
Msg( "%s.spr\n", name ); // echo to console
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvSPR
|
||||
============
|
||||
*/
|
||||
bool ConvSPR( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
dframetype_t *pframetype = NULL;
|
||||
dspriteq2_t *pinq2;
|
||||
dspritehl_t *pinhl;
|
||||
dspriteq1_t *pin;
|
||||
short *numi;
|
||||
int i;
|
||||
|
||||
// defaulting to q1
|
||||
pin = (dspriteq1_t *)buffer;
|
||||
memset( &spr, 0, sizeof( spr ));
|
||||
|
||||
switch( LittleLong( pin->ident ))
|
||||
{
|
||||
case IDSPRQ1HEADER:
|
||||
switch( LittleLong( pin->version ))
|
||||
{
|
||||
case SPRITEQ1_VERSION:
|
||||
spr.totalframes = LittleLong( pin->numframes );
|
||||
spr.texFormat = SPR_ALPHTEST; // constant
|
||||
spr.type = LittleLong( pin->type );
|
||||
pframetype = (dframetype_t *)(pin + 1);
|
||||
spr.truecolor = false;
|
||||
break;
|
||||
case SPRITE32_VERSION:
|
||||
spr.totalframes = LittleLong( pin->numframes );
|
||||
spr.texFormat = SPR_ADDITIVE; // constant
|
||||
spr.type = LittleLong( pin->type );
|
||||
|
||||
pframetype = (dframetype_t *)(pin + 1);
|
||||
spr.truecolor = true;
|
||||
break;
|
||||
case SPRITEHL_VERSION:
|
||||
pinhl = (dspritehl_t *)buffer; // reorganize header
|
||||
spr.totalframes = LittleLong( pinhl->numframes );
|
||||
spr.texFormat = LittleLong( pinhl->texFormat );
|
||||
spr.type = LittleLong( pinhl->type );
|
||||
numi = (short *)(pinhl + 1);
|
||||
spr.truecolor = false;
|
||||
|
||||
if( LittleShort( *numi ) == 256 )
|
||||
{
|
||||
byte *src = (byte *)(numi + 1);
|
||||
rgbdata_t *pal = NULL;
|
||||
|
||||
// install palette
|
||||
switch( spr.texFormat )
|
||||
{
|
||||
case SPR_INDEXALPHA:
|
||||
case SPR_ALPHTEST:
|
||||
pal = FS_LoadImage( "#transparent.pal", src, 768 );
|
||||
break;
|
||||
case SPR_NORMAL:
|
||||
case SPR_ADDGLOW:
|
||||
case SPR_ADDITIVE:
|
||||
default:
|
||||
pal = FS_LoadImage( "#normal.pal", src, 768 );
|
||||
break;
|
||||
}
|
||||
|
||||
// get frametype for first frame
|
||||
pframetype = (dframetype_t *)(src + 768);
|
||||
//FS_FreeImage( pal ); // palette installed, no reason to keep this data
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg("\"%s.spr\" have invalid palette size\n", name );
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Msg("\"%s.%s\" unknown version %i\n", name, "spr", LittleLong( pin->version ));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case IDSPRQ2HEADER:
|
||||
switch( LittleLong( pin->version ))
|
||||
{
|
||||
case SPRITEQ2_VERSION:
|
||||
pinq2 = (dspriteq2_t *)buffer;
|
||||
spr.totalframes = LittleLong( pinq2->numframes );
|
||||
spr.texFormat = SPR_ALPHTEST; // constants
|
||||
spr.type = SPR_FWD_PARALLEL;
|
||||
spr.truecolor = false;
|
||||
for( i = 0; i < spr.totalframes; i++ )
|
||||
{
|
||||
spr.frame[i].width = LittleLong( pinq2->frames[i].width );
|
||||
spr.frame[i].height = LittleLong( pinq2->frames[i].height );
|
||||
spr.frame[i].origin[0] = LittleLong( pinq2->frames[i].origin_x );
|
||||
spr.frame[i].origin[1] = LittleLong( pinq2->frames[i].origin_y );
|
||||
SP2_ConvertFrame( pinq2->frames[i].name, ext, i );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Msg("\"%s.%s\" unknown version %i\n", name, "sp2", LittleLong( pin->version ));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Msg("\"%s\" have invalid header\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// .SPR save frames as normal images
|
||||
for( i = 0; pframetype && i < spr.totalframes; i++ )
|
||||
{
|
||||
frametype_t frametype = LittleLong( pframetype->type );
|
||||
|
||||
if( frametype == SPR_SINGLE )
|
||||
pframetype = (dframetype_t *)SPR_ConvertFrame( name, ext, (pframetype + 1), i, 0 );
|
||||
else pframetype = (dframetype_t *)SPR_ConvertGroup( name, ext, (pframetype + 1), i );
|
||||
}
|
||||
return SPR_WriteScript( name, ext ); // write script file and done
|
||||
}
|
|
@ -1,16 +1,14 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// idconv.h - Doom1\Quake\Hl convertor into Xash Formats
|
||||
// ripper.h - Xash Miptex Decompiler
|
||||
//=======================================================================
|
||||
#ifndef BASECONVERTOR_H
|
||||
#define BASECONVERTOR_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "basetypes.h"
|
||||
#include "ref_dllapi.h"
|
||||
#include "platform.h"
|
||||
|
||||
extern stdlib_api_t com;
|
||||
extern byte *zonepool;
|
||||
extern byte *basepool;
|
||||
extern string gs_gamedir;
|
||||
#define Sys_Error com.error
|
||||
extern vprogs_exp_t *PRVM;
|
||||
|
@ -18,6 +16,11 @@ extern uint app_name;
|
|||
extern bool write_qscsript;
|
||||
extern int game_family;
|
||||
|
||||
// common tools
|
||||
bool Conv_CreateShader( const char *name, rgbdata_t *pic, const char *ext, const char *anim, int surf, int cnt );
|
||||
bool Conv_CheckMap( const char *mapname ); // for detect gametype
|
||||
bool Conv_CheckWad( const char *wadname ); // for detect gametype
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GAME_GENERIC = 0,
|
||||
|
@ -55,8 +58,7 @@ static const char *game_names[] =
|
|||
//=====================================
|
||||
// convertor modules
|
||||
//=====================================
|
||||
bool ConvSPR( const char *name, byte *buffer, size_t filesize, const char *ext );// quake1, half-life and spr32 sprites
|
||||
bool ConvSP2( const char *name, byte *buffer, size_t filesize, const char *ext );// quake2 sprites
|
||||
bool ConvSPR( const char *name, byte *buffer, size_t filesize, const char *ext );// q1, q2, half-life and spr32 sprites
|
||||
bool ConvPCX( const char *name, byte *buffer, size_t filesize, const char *ext );// pcx images (can use custom palette)
|
||||
bool ConvFLT( const char *name, byte *buffer, size_t filesize, const char *ext );// Doom1 flat images (textures)
|
||||
bool ConvFLP( const char *name, byte *buffer, size_t filesize, const char *ext );// Doom1 flat images (menu pics)
|
||||
|
@ -68,7 +70,6 @@ bool ConvWAL( const char *name, byte *buffer, size_t filesize, const char *ext )
|
|||
bool ConvVTF( const char *name, byte *buffer, size_t filesize, const char *ext );// Quake2 textures
|
||||
bool ConvSKN( const char *name, byte *buffer, size_t filesize, const char *ext );// Doom1 sprite models
|
||||
bool ConvBSP( const char *name, byte *buffer, size_t filesize, const char *ext );// Extract textures from bsp (q1\hl)
|
||||
bool ConvSND( const char *name, byte *buffer, size_t filesize, const char *ext );// not implemented
|
||||
bool ConvMID( const char *name, byte *buffer, size_t filesize, const char *ext );// Doom1 music files (midi)
|
||||
bool ConvRAW( const char *name, byte *buffer, size_t filesize, const char *ext );// write file without converting
|
||||
bool ConvDAT( const char *name, byte *buffer, size_t filesize, const char *ext );// quakec progs into source.qc
|
|
@ -281,7 +281,7 @@ void Cmd_Load( void )
|
|||
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...
|
||||
flags |= IMAGE_PALTO24; // get 24-bit palettes
|
||||
Image_Process( &frame, 0, 0, IMAGE_PALTO24 );
|
||||
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 );
|
||||
|
|
|
@ -288,7 +288,7 @@ void WriteSequenceInfo( void )
|
|||
{
|
||||
pevent[j].frame = sequence[i]->event[j].frame - sequence[i]->frameoffset;
|
||||
pevent[j].event = sequence[i]->event[j].event;
|
||||
memcpy( pevent[j].options, sequence[i]->event[j].options, sizeof( pevent[j].options ));
|
||||
Mem_Copy( pevent[j].options, sequence[i]->event[j].options, sizeof( pevent[j].options ));
|
||||
}
|
||||
|
||||
ALIGN( pData );
|
||||
|
@ -571,7 +571,7 @@ void WriteModel( void )
|
|||
numCmdBytes = BuildTris( model[i]->pmesh[j]->triangle, model[i]->pmesh[j], &pCmdSrc );
|
||||
|
||||
pmesh[j].triindex = (pData - pStart);
|
||||
memcpy( pData, pCmdSrc, numCmdBytes );
|
||||
Mem_Copy( pData, pCmdSrc, numCmdBytes );
|
||||
pData += numCmdBytes;
|
||||
|
||||
ALIGN( pData );
|
||||
|
|
|
@ -15,68 +15,6 @@ char **com_argv;
|
|||
char gs_basedir[ MAX_SYSPATH ]; // initial dir before loading gameinfo.txt (used for compilers too)
|
||||
string gs_filename; // used for compilers only
|
||||
|
||||
unsigned __int64 __g_ProfilerStart;
|
||||
unsigned __int64 __g_ProfilerEnd;
|
||||
unsigned __int64 __g_ProfilerEnd2;
|
||||
unsigned __int64 __g_ProfilerSpare;
|
||||
unsigned __int64 __g_ProfilerTotalTicks;
|
||||
double __g_ProfilerTotalMsec;
|
||||
|
||||
void Profile_Store( void )
|
||||
{
|
||||
if (com.GameInfo->rdtsc)
|
||||
{
|
||||
__g_ProfilerSpare = __g_ProfilerEnd - __g_ProfilerStart - (__g_ProfilerEnd2 - __g_ProfilerEnd);
|
||||
}
|
||||
}
|
||||
|
||||
void Profile_RatioResults( void )
|
||||
{
|
||||
if (com.GameInfo->rdtsc)
|
||||
{
|
||||
unsigned __int64 total = __g_ProfilerEnd - __g_ProfilerStart - (__g_ProfilerEnd2 - __g_ProfilerEnd);
|
||||
double ratio;
|
||||
|
||||
if (total >= __g_ProfilerSpare)
|
||||
{
|
||||
ratio = (double)(total-__g_ProfilerSpare)/total;
|
||||
Msg("First code is %.2f%% faster\n", ratio * 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
ratio = (double)(__g_ProfilerSpare-total)/__g_ProfilerSpare;
|
||||
Msg("Second code is %.2f%% faster\n", ratio * 100);
|
||||
}
|
||||
}
|
||||
else MsgDev( D_ERROR, "--- Profiler not supported ---\n");
|
||||
}
|
||||
|
||||
void _Profile_Results( const char *function )
|
||||
{
|
||||
if (com.GameInfo->rdtsc)
|
||||
{
|
||||
unsigned __int64 total = __g_ProfilerEnd - __g_ProfilerStart - (__g_ProfilerEnd2 - __g_ProfilerEnd);
|
||||
double msec = (double)total / com.GameInfo->tickcount;
|
||||
Msg("Profiling stats for %s()\n", function );
|
||||
Msg("----- ticks: %I64d -----\n", total);
|
||||
Msg("----- secs %f ----- \n", msec );
|
||||
__g_ProfilerTotalTicks += total;
|
||||
__g_ProfilerTotalMsec += msec;
|
||||
}
|
||||
else MsgDev( D_ERROR, "--- Profiler not supported ---\n");
|
||||
}
|
||||
|
||||
void Profile_Time( void )
|
||||
{
|
||||
if (com.GameInfo->rdtsc)
|
||||
{
|
||||
Msg("Profiling results:\n");
|
||||
Msg("----- total ticks: %I64d -----\n", __g_ProfilerTotalTicks);
|
||||
Msg("----- total secs %f ----- \n", __g_ProfilerTotalMsec );
|
||||
}
|
||||
else MsgDev( D_ERROR, "--- Profiler not supported ---\n");
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Com_ValidScript
|
||||
|
|
|
@ -47,55 +47,13 @@ typedef struct wavefile_s
|
|||
#define BSP_ONLYVIS 0x02
|
||||
#define BSP_ONLYRAD 0x04
|
||||
#define BSP_FULLCOMPILE 0x08
|
||||
|
||||
#define ALIGN( a ) a = (byte *)((int)((byte *)a + 3) & ~ 3)
|
||||
|
||||
extern unsigned __int64 __g_ProfilerStart;
|
||||
extern unsigned __int64 __g_ProfilerEnd;
|
||||
extern unsigned __int64 __g_ProfilerEnd2;
|
||||
extern unsigned __int64 __g_ProfilerSpare;
|
||||
extern unsigned __int64 __g_ProfilerTotalTicks;
|
||||
extern double __g_ProfilerTotalMsec;
|
||||
extern int com_argc;
|
||||
extern char **com_argv;
|
||||
extern byte *basepool;
|
||||
extern byte *zonepool;
|
||||
|
||||
#define Profile_Start()\
|
||||
{\
|
||||
if (com.GameInfo->rdtsc) \
|
||||
{ \
|
||||
__asm pushad \
|
||||
__asm rdtsc \
|
||||
__asm mov DWORD PTR[__g_ProfilerStart+4], edx \
|
||||
__asm mov DWORD PTR[__g_ProfilerStart], eax \
|
||||
__asm popad \
|
||||
} \
|
||||
}
|
||||
|
||||
#define Profile_End()\
|
||||
{\
|
||||
if (GI.rdtsc) \
|
||||
{ \
|
||||
__asm pushad \
|
||||
__asm rdtsc \
|
||||
__asm mov DWORD PTR[__g_ProfilerEnd+4], edx \
|
||||
__asm mov DWORD PTR[__g_ProfilerEnd], eax \
|
||||
__asm popad \
|
||||
__asm pushad \
|
||||
__asm rdtsc \
|
||||
__asm mov DWORD PTR[__g_ProfilerEnd2+4], edx \
|
||||
__asm mov DWORD PTR[__g_ProfilerEnd2], eax \
|
||||
__asm popad \
|
||||
} \
|
||||
}
|
||||
|
||||
void Profile_RatioResults( void );
|
||||
void _Profile_Results( const char *function );
|
||||
void Profile_Store( void );
|
||||
void Profile_Time( void ); // total profile time
|
||||
#define Profile_Results( name ) _Profile_Results( #name )
|
||||
|
||||
extern stdlib_api_t com;
|
||||
extern vprogs_exp_t *PRVM;
|
||||
|
||||
|
|
|
@ -158,12 +158,12 @@ $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;
|
||||
byte *plump, *plump_end, *screen_p, *source;
|
||||
int miplevel, mipstep, flags = 0;
|
||||
byte *lump, testpixel;
|
||||
int xx, yy, count;
|
||||
int linedelta;
|
||||
size_t plump_size;
|
||||
byte *lump;
|
||||
mip_t *mip;
|
||||
|
||||
Com_GetToken( false );
|
||||
|
@ -194,11 +194,11 @@ void Cmd_GrabMip( void )
|
|||
h = image->height;
|
||||
}
|
||||
|
||||
// just resample image if need
|
||||
if(( w & 15) || (h & 15)) flags |= IMAGE_ROUND;
|
||||
// reflood image with new size
|
||||
if(( w & 15) || (h & 15)) flags |= IMAGE_ROUNDFILLER;
|
||||
Image_Process( &image, 0, 0, flags );
|
||||
|
||||
if( flags & IMAGE_ROUND )
|
||||
if( flags & IMAGE_ROUNDFILLER )
|
||||
{
|
||||
// updates image size
|
||||
w = image->width;
|
||||
|
@ -212,6 +212,7 @@ void Cmd_GrabMip( void )
|
|||
// + numolors[short] + palette[768];
|
||||
plump_size = (int)sizeof(*mip) + ((w * h * 85)>>6) + sizeof(short) + 768;
|
||||
plump = lump = (byte *)Mem_Alloc( wadpool, plump_size );
|
||||
plump_end = plump + plump_size; // sentinel
|
||||
|
||||
mip = (mip_t *)plump;
|
||||
mip->width = LittleLong( w );
|
||||
|
@ -309,13 +310,18 @@ void Cmd_GrabMip( void )
|
|||
}
|
||||
|
||||
*(word*)plump = 256; // palette size
|
||||
plump += sizeof(short);
|
||||
plump += sizeof( short );
|
||||
|
||||
Mem_Copy( plump, image->palette, 768 );
|
||||
plump += 768;
|
||||
// bounds checker
|
||||
if( plump + 768 == plump_end )
|
||||
{
|
||||
Mem_Copy( plump, image->palette, 768 );
|
||||
plump += 768;
|
||||
|
||||
// write out and release intermediate buffers
|
||||
Wad3_AddLump( lump, plump_size, TYPE_MIPTEX2, false );
|
||||
// write out and release intermediate buffers
|
||||
Wad3_AddLump( lump, plump_size, TYPE_MIPTEX2, false );
|
||||
}
|
||||
else MsgDev( D_WARN, "lump %s have invalid size, ignore\n", lumpname );
|
||||
FS_FreeImage( image );
|
||||
Mem_Free( lump );
|
||||
}
|
||||
|
|
|
@ -20,9 +20,6 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% common/common.dsp %CONFIG%"common - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% ripper/ripper.dsp %CONFIG%"ripper - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% physic/physic.dsp %CONFIG%"physic - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
|
@ -61,7 +58,6 @@ if exist baserc\baserc.plg del /f /q baserc\baserc.plg
|
|||
if exist engine\engine.plg del /f /q engine\engine.plg
|
||||
if exist launch\launch.plg del /f /q launch\launch.plg
|
||||
if exist common\common.plg del /f /q common\common.plg
|
||||
if exist ripper\ripper.plg del /f /q ripper\ripper.plg
|
||||
if exist physic\physic.plg del /f /q physic\physic.plg
|
||||
if exist render\render.plg del /f /q render\render.plg
|
||||
if exist viewer\viewer.plg del /f /q viewer\viewer.plg
|
||||
|
@ -71,5 +67,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
quake.exe -game tmpQuArK -log -debug -dev 4 +map dm_qstyle
|
||||
quake.exe -game tmpQuArK -log -debug -dev 5 +map dm_qstyle
|
||||
:done
|
|
@ -120,7 +120,7 @@ typedef struct
|
|||
//
|
||||
int servercount; // server identification for prespawns
|
||||
int playernum;
|
||||
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
|
||||
char configstrings[MAX_CONFIGSTRINGS][CS_SIZE];
|
||||
|
||||
//
|
||||
// locally derived information from server state
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <time.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
#include "net_msg.h"
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ perform Tab expansion
|
|||
void Field_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
char filename[MAX_QPATH];
|
||||
string filename;
|
||||
autocomplete_list_t *list;
|
||||
|
||||
completionField = field;
|
||||
|
|
|
@ -468,7 +468,7 @@ void Con_DrawSolidConsole (float frac)
|
|||
int lines;
|
||||
int currentColor;
|
||||
vec4_t color;
|
||||
char curtime[MAX_QPATH];
|
||||
string curtime;
|
||||
|
||||
lines = scr_height->integer * frac;
|
||||
if( lines <= 0 ) return;
|
||||
|
@ -487,7 +487,7 @@ void Con_DrawSolidConsole (float frac)
|
|||
|
||||
// draw current time
|
||||
re->SetColor(g_color_table[ColorIndex(COLOR_YELLOW)]);
|
||||
com.snprintf( curtime, MAX_QPATH, "%s ", timestamp( TIME_TIME_ONLY));
|
||||
com.snprintf( curtime, MAX_STRING, "%s ", timestamp( TIME_TIME_ONLY));
|
||||
i = com.strlen( curtime );
|
||||
for (x = 0; x < i; x++)
|
||||
SCR_DrawSmallChar(scr_width->integer - ( i - x ) * SMALLCHAR_WIDTH, (lines - (SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), curtime[x]);
|
||||
|
|
|
@ -49,7 +49,7 @@ bool Cmd_GetMapList( const char *s, char *completedname, int length )
|
|||
{
|
||||
const char *data = NULL;
|
||||
char *entities = NULL;
|
||||
char entfilename[MAX_QPATH];
|
||||
string entfilename;
|
||||
int ver = -1, lumpofs = 0, lumplen = 0;
|
||||
const char *ext = FS_FileExtension( t->filenames[i] );
|
||||
|
||||
|
@ -525,25 +525,25 @@ bool Cmd_GetGamesList( const char *s, char *completedname, int length )
|
|||
bool Cmd_CheckMapsList( void )
|
||||
{
|
||||
byte buf[MAX_SYSPATH]; // 1 kb
|
||||
char *buffer, string[MAX_STRING];
|
||||
char *buffer;
|
||||
string result;
|
||||
search_t *t;
|
||||
file_t *f;
|
||||
int i;
|
||||
|
||||
if(FS_FileExists("scripts/maps.lst"))
|
||||
if(FS_FileExists( "scripts/maps.lst" ))
|
||||
return true; // exist
|
||||
|
||||
t = FS_Search( "maps/*.bsp", false );
|
||||
if(!t) return false;
|
||||
|
||||
buffer = Z_Malloc( t->numfilenames * 2 * sizeof(string));
|
||||
buffer = Z_Malloc( t->numfilenames * 2 * sizeof( result ));
|
||||
for( i = 0; i < t->numfilenames; i++ )
|
||||
{
|
||||
const char *data = NULL;
|
||||
char *entities = NULL;
|
||||
char entfilename[MAX_QPATH];
|
||||
int ver = -1, lumpofs = 0, lumplen = 0;
|
||||
char mapname[MAX_QPATH], message[MAX_QPATH];
|
||||
string mapname, message, entfilename;
|
||||
|
||||
f = FS_Open(t->filenames[i], "rb");
|
||||
FS_FileBase( t->filenames[i], mapname );
|
||||
|
@ -605,7 +605,7 @@ bool Cmd_CheckMapsList( void )
|
|||
// means there is no title, so clear the message string now
|
||||
message[0] = 0;
|
||||
data = entities;
|
||||
com.strncpy(message, "No Title", MAX_QPATH);
|
||||
com.strncpy( message, "No Title", MAX_STRING );
|
||||
|
||||
while(Com_ParseToken( &data, true ))
|
||||
{
|
||||
|
@ -634,8 +634,8 @@ bool Cmd_CheckMapsList( void )
|
|||
if( f ) FS_Close(f);
|
||||
|
||||
// format: mapname "maptitle"\n
|
||||
com.sprintf(string, "%s \"%s\"\n", mapname, message );
|
||||
com.strcat(buffer, string); // add new string
|
||||
com.sprintf( result, "%s \"%s\"\n", mapname, message );
|
||||
com.strcat( buffer, result ); // add new string
|
||||
}
|
||||
}
|
||||
if( t ) Mem_Free(t); // free search result
|
||||
|
|
|
@ -118,7 +118,8 @@ static const net_desc_t NWDesc[] =
|
|||
|
||||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
// each config string can be at most MAX_QPATH characters.
|
||||
// each config string can be at most CS_SIZE characters.
|
||||
#define CS_SIZE 64 // size of one config string
|
||||
#define CS_NAME 0 // map name
|
||||
#define CS_MAPCHECKSUM 1 // level checksum (for catching cheater maps)
|
||||
#define CS_SKYNAME 2 // skybox name
|
||||
|
|
|
@ -92,7 +92,7 @@ typedef struct server_s
|
|||
cmodel_t *models[MAX_MODELS];
|
||||
cmodel_t *worldmodel;
|
||||
|
||||
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
|
||||
char configstrings[MAX_CONFIGSTRINGS][CS_SIZE];
|
||||
|
||||
// the multicast buffer is used to send a message to a set of clients
|
||||
// it is only used to marshall data until SV_Message is called
|
||||
|
|
|
@ -189,7 +189,7 @@ For development work
|
|||
*/
|
||||
void SV_Map_f( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
string filename;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
|
@ -197,7 +197,7 @@ void SV_Map_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
com.snprintf( filename, MAX_QPATH, "%s.bsp", Cmd_Argv(1));
|
||||
com.snprintf( filename, MAX_STRING, "%s.bsp", Cmd_Argv(1));
|
||||
if(!FS_FileExists(va("maps/%s", filename )))
|
||||
{
|
||||
Msg("Can't loading %s\n", filename );
|
||||
|
@ -230,7 +230,7 @@ SV_Load_f
|
|||
*/
|
||||
void SV_Load_f( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
string filename;
|
||||
|
||||
if(Cmd_Argc() != 2)
|
||||
{
|
||||
|
@ -238,7 +238,7 @@ void SV_Load_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
com.snprintf( filename, MAX_QPATH, "%s.bin", Cmd_Argv(1));
|
||||
com.snprintf( filename, MAX_STRING, "%s.bin", Cmd_Argv(1));
|
||||
if(!FS_FileExists(va("save/%s", filename )))
|
||||
{
|
||||
Msg("Can't loading %s\n", filename );
|
||||
|
@ -259,7 +259,7 @@ SV_Save_f
|
|||
*/
|
||||
void SV_Save_f( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
string filename;
|
||||
|
||||
if(Cmd_Argc() != 2)
|
||||
{
|
||||
|
@ -267,7 +267,7 @@ void SV_Save_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
com.snprintf( filename, MAX_QPATH, "%s.bin", Cmd_Argv(1));
|
||||
com.snprintf( filename, MAX_STRING, "%s.bin", Cmd_Argv(1));
|
||||
SV_WriteSaveFile( filename );
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,7 @@ Saves the state of the map just being exited and goes to a new map.
|
|||
*/
|
||||
void SV_ChangeLevel_f( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
string filename;
|
||||
int c = Cmd_Argc();
|
||||
|
||||
if( c != 2 && c != 3 )
|
||||
|
@ -289,7 +289,7 @@ void SV_ChangeLevel_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
com.snprintf( filename, MAX_QPATH, "%s.bsp", Cmd_Argv(1));
|
||||
com.snprintf( filename, MAX_STRING, "%s.bsp", Cmd_Argv(1));
|
||||
if(!FS_FileExists(va("maps/%s", filename )))
|
||||
{
|
||||
Msg("Can't loading %s\n", filename );
|
||||
|
@ -337,11 +337,11 @@ restarts current level
|
|||
*/
|
||||
void SV_Restart_f( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
string filename;
|
||||
|
||||
if(sv.state != ss_active) return;
|
||||
|
||||
com.strncpy( filename, svs.mapcmd, MAX_QPATH );
|
||||
com.strncpy( filename, svs.mapcmd, MAX_STRING );
|
||||
FS_StripExtension( filename );
|
||||
|
||||
// just sending console command
|
||||
|
|
|
@ -151,7 +151,7 @@ void SV_SpawnServer( const char *server, const char *savename )
|
|||
svs.timeleft = 0;
|
||||
|
||||
// save name for levels that don't set message
|
||||
com.strncpy( sv.configstrings[CS_NAME], server, MAX_QPATH );
|
||||
com.strncpy( sv.configstrings[CS_NAME], server, CS_SIZE );
|
||||
MSG_Init( &sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
||||
com.strcpy( sv.name, server );
|
||||
|
||||
|
|
|
@ -428,7 +428,7 @@ void Sav_LoadCfgString( wfile_t *l )
|
|||
|
||||
// unpack the cfg string data
|
||||
for( i = 0; i < numstrings; i++ )
|
||||
com.strncpy( sv.configstrings[i], StringTable_GetString( s_table, in[i] ), MAX_QPATH );
|
||||
com.strncpy( sv.configstrings[i], StringTable_GetString( s_table, in[i] ), CS_SIZE );
|
||||
}
|
||||
|
||||
void Sav_LoadAreaPortals( wfile_t *l )
|
||||
|
|
File diff suppressed because it is too large
Load Diff
11
launch/cmd.c
11
launch/cmd.c
|
@ -260,16 +260,17 @@ Cmd_Exec_f
|
|||
*/
|
||||
void Cmd_Exec_f (void)
|
||||
{
|
||||
char *f, rcpath[MAX_QPATH];
|
||||
int len;
|
||||
string rcpath;
|
||||
size_t len;
|
||||
|
||||
if (Cmd_Argc () != 2)
|
||||
char *f;
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg("exec <filename> : execute a script file\n");
|
||||
Msg( "exec <filename> : execute a script file\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
com_sprintf(rcpath, "scripts/config/%s", Cmd_Argv(1));
|
||||
com.snprintf( rcpath, MAX_STRING, "scripts/config/%s", Cmd_Argv(1));
|
||||
FS_DefaultExtension(rcpath, ".rc" ); // append as default
|
||||
|
||||
f = FS_LoadFile(rcpath, &len );
|
||||
|
|
|
@ -224,11 +224,11 @@ void Con_CreateConsole( void )
|
|||
HDC hDC;
|
||||
WNDCLASS wc;
|
||||
RECT rect;
|
||||
int nHeight;
|
||||
int swidth, sheight, fontsize;
|
||||
int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION;
|
||||
int CONSTYLE = WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_BORDER|WS_EX_CLIENTEDGE|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY;
|
||||
char Title[MAX_QPATH], FontName[MAX_QPATH];
|
||||
int nHeight;
|
||||
int swidth, sheight, fontsize;
|
||||
string Title, FontName;
|
||||
int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION;
|
||||
int CONSTYLE = WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_BORDER|WS_EX_CLIENTEDGE|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY;
|
||||
|
||||
if( Sys.con_silentmode ) return;
|
||||
Sys_InitLog();
|
||||
|
@ -241,7 +241,7 @@ void Con_CreateConsole( void )
|
|||
}
|
||||
Sys.Con_Print = Con_PrintW;
|
||||
|
||||
memset( &wc, 0, sizeof( wc ));
|
||||
Mem_Set( &wc, 0, sizeof( wc ));
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = (WNDPROC)Con_WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
|
@ -267,7 +267,7 @@ void Con_CreateConsole( void )
|
|||
rect.right = 536;
|
||||
rect.top = 0;
|
||||
rect.bottom = 280;
|
||||
com_strncpy(FontName, "Arial", MAX_QPATH );
|
||||
com.strncpy( FontName, "Arial", MAX_STRING );
|
||||
fontsize = 16;
|
||||
}
|
||||
else if( Sys.con_readonly )
|
||||
|
@ -276,7 +276,7 @@ void Con_CreateConsole( void )
|
|||
rect.right = 536;
|
||||
rect.top = 0;
|
||||
rect.bottom = 364;
|
||||
com_strncpy(FontName, "Fixedsys", MAX_QPATH );
|
||||
com.strncpy( FontName, "Fixedsys", MAX_STRING );
|
||||
fontsize = 8;
|
||||
}
|
||||
else // dedicated console
|
||||
|
@ -285,11 +285,11 @@ void Con_CreateConsole( void )
|
|||
rect.right = 540;
|
||||
rect.top = 0;
|
||||
rect.bottom = 392;
|
||||
com_strncpy(FontName, "System", MAX_QPATH );
|
||||
com.strncpy( FontName, "System", MAX_STRING );
|
||||
fontsize = 14;
|
||||
}
|
||||
|
||||
com_strncpy( Title, Sys.caption, MAX_QPATH );
|
||||
com.strncpy( Title, Sys.caption, MAX_STRING );
|
||||
AdjustWindowRect( &rect, DEDSTYLE, FALSE );
|
||||
|
||||
hDC = GetDC( GetDesktopWindow() );
|
||||
|
|
226
launch/cpuinfo.c
226
launch/cpuinfo.c
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "launch.h"
|
||||
|
||||
typedef signed __int64 int64;
|
||||
|
||||
// Processor Information:
|
||||
typedef struct cpuinfo_s
|
||||
{
|
||||
|
@ -137,7 +139,7 @@ const char* GetProcessorVendorId()
|
|||
static char VendorID[13];
|
||||
register_t vendor = cpuid(0);
|
||||
|
||||
memset( VendorID, 0, sizeof(VendorID) );
|
||||
Mem_Set( VendorID, 0, sizeof( VendorID ));
|
||||
if( !vendor.retval )
|
||||
{
|
||||
com_strcpy( VendorID, "Generic_x86" );
|
||||
|
@ -245,19 +247,22 @@ cpuinfo_t GetCPUInfo( void )
|
|||
SYSTEM_INFO si;
|
||||
|
||||
|
||||
if( pi.m_size == sizeof(pi) ) return pi;// Has the structure already been initialized and filled out?
|
||||
memset(&pi, 0, sizeof(pi)); // Redundant, but just in case the user somehow messes with the size.
|
||||
pi.m_size = sizeof(pi); // Fill out the structure, and return it:
|
||||
pi.m_speed = CalculateClockSpeed(); // Grab the processor frequency:
|
||||
pi.m_usNumLogicCore = LogicalProcessorsPerPackage();// Get the logical and physical processor counts:
|
||||
if( pi.m_size == sizeof( pi ))
|
||||
return pi; // has the structure already been initialized and filled out?
|
||||
Mem_Set( &pi, 0, sizeof( pi )); // redundant, but just in case the user somehow messes with the size.
|
||||
pi.m_size = sizeof(pi); // fill out the structure, and return it:
|
||||
pi.m_speed = CalculateClockSpeed(); // grab the processor frequency:
|
||||
|
||||
memset( &si, 0, sizeof(si) );
|
||||
// get the logical and physical processor counts:
|
||||
pi.m_usNumLogicCore = LogicalProcessorsPerPackage();
|
||||
|
||||
Mem_Set( &si, 0, sizeof( si ));
|
||||
GetSystemInfo( &si );
|
||||
|
||||
pi.m_usNumPhysCore = si.dwNumberOfProcessors / pi.m_usNumLogicCore;
|
||||
pi.m_usNumLogicCore *= pi.m_usNumPhysCore;
|
||||
|
||||
// Make sure I always report at least one, when running WinXP with the /ONECPU switch,
|
||||
// make sure I always report at least one, when running WinXP with the /ONECPU switch,
|
||||
// it likes to report 0 processors for some reason.
|
||||
if( pi.m_usNumPhysCore == 0 && pi.m_usNumLogicCore == 0 )
|
||||
{
|
||||
|
@ -278,6 +283,202 @@ cpuinfo_t GetCPUInfo( void )
|
|||
return pi;
|
||||
}
|
||||
|
||||
void Sys_InitMathlib( cpuinfo_t *cpu )
|
||||
{
|
||||
size_t size = 1024 * 1024;
|
||||
int i, start, min, result[8];
|
||||
void *buf0 = Malloc( size );
|
||||
void *buf1 = Malloc( size );
|
||||
int numchecks = 16; // iterations
|
||||
float a;
|
||||
|
||||
// testing sqrt
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 1; i < 800000; i++ ) a = sqrtf( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "crt_sqrt %i ms\n", result[0] );
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 1; i < 800000; i++ ) a = com_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+1] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "com_sqrt %i ms\n", result[1] );
|
||||
|
||||
if( cpu->m_b3DNow )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < 800000; i++ ) a = amd_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+2] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "amd_sqrt %i ms\n", result[2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[2] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "amd_sqrt not supported\n" );
|
||||
}
|
||||
|
||||
if( cpu->m_bSSE )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < 800000; i++ ) a = sse_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+3] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "sse_sqrt %i ms\n", result[3] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[3] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "sse_sqrt not supported\n" );
|
||||
}
|
||||
|
||||
min = min( result[0], min( result[1], min( result[2], result[3] )));
|
||||
if( min == result[0] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_sqrt\n");
|
||||
com.sqrt = sqrtf;
|
||||
}
|
||||
else if( min == result[1] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using com_sqrt\n");
|
||||
com.sqrt = com_sqrt;
|
||||
}
|
||||
else if( min == result[2] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using amd_sqrt\n");
|
||||
com.sqrt = amd_sqrt;
|
||||
}
|
||||
else if( min == result[3] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using sse_sqrt\n");
|
||||
com.sqrt = sse_sqrt;
|
||||
}
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _crt_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
|
||||
result[0] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "crt_memcpy %i ms\n", result[0] );
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _asm_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
|
||||
result[1] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "asm_memcpy %i ms\n", result[1] );
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _com_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
|
||||
result[2] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "com_memcpy %i ms\n", result[2] );
|
||||
|
||||
if( cpu->m_bMMX )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _mmx_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
|
||||
result[3] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "mmx_memcpy %i ms\n", result[3] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[3] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "mmx_memcpy not supported\n" );
|
||||
}
|
||||
|
||||
if( cpu->m_b3DNow )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _amd_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
|
||||
result[4] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "amd_memcpy %i ms\n", result[4] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[4] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "amd_memcpy not supported\n" );
|
||||
}
|
||||
|
||||
min = min( result[0], min( result[1], min( result[2], min( result[3], result[4] ))));
|
||||
if( min == result[0] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_memcpy\n" );
|
||||
com.memcpy = _crt_mem_copy;
|
||||
}
|
||||
else if( min == result[1] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using asm_memcpy\n" );
|
||||
com.memcpy = _asm_mem_copy;
|
||||
}
|
||||
else if( min == result[2] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using com_memcpy\n" );
|
||||
com.memcpy = _com_mem_copy;
|
||||
}
|
||||
else if( min == result[3] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using mmx_memcpy\n" );
|
||||
com.memcpy = _mmx_mem_copy;
|
||||
}
|
||||
else if( min == result[4] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using amd_memcpy\n" );
|
||||
com.memcpy = _amd_mem_copy;
|
||||
}
|
||||
|
||||
// memset
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _crt_mem_set( buf0, 0, size, __FILE__, __LINE__ );
|
||||
result[0] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "crt_memset %i ms\n", result[0] );
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _asm_mem_set( buf0, 0, size, __FILE__, __LINE__ );
|
||||
result[1] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "asm_memset %i ms\n", result[1] );
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _com_mem_set( buf0, 0, size, __FILE__, __LINE__ );
|
||||
result[2] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "com_memset %i ms\n", result[2] );
|
||||
|
||||
if( cpu->m_bMMX )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _mmx_mem_set( buf0, 0, size, __FILE__, __LINE__ );
|
||||
result[3] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "mmx_memset %i ms\n", result[3] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[3] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "mmx_memset not supported\n" );
|
||||
}
|
||||
|
||||
min = min( result[0], min( result[1], min( result[2], result[3] )));
|
||||
if( min == result[0] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_memset\n" );
|
||||
com.memset = _crt_mem_set;
|
||||
}
|
||||
else if( min == result[1] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using asm_memset\n" );
|
||||
com.memset = _asm_mem_set;
|
||||
}
|
||||
else if( min == result[2] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using com_memset\n" );
|
||||
com.memset = _com_mem_set;
|
||||
}
|
||||
else if( min == result[3] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using mmx_memset\n" );
|
||||
com.memset = _mmx_mem_set;
|
||||
}
|
||||
|
||||
// release test memory
|
||||
if( buf0 ) Mem_Free( buf0 );
|
||||
if( buf1 ) Mem_Free( buf1 );
|
||||
}
|
||||
|
||||
void Sys_InitCPU( void )
|
||||
{
|
||||
cpuinfo_t cpu = GetCPUInfo();
|
||||
|
@ -288,10 +489,8 @@ void Sys_InitCPU( void )
|
|||
double fFrequency = cpu.m_speed / 1000000.0;
|
||||
|
||||
// copy shared info
|
||||
GI.tickcount = cpu.m_speed; // used for profiling
|
||||
GI.cpufreq = (float)fFrequency;
|
||||
GI.cpunum = cpu.m_usNumLogicCore;
|
||||
GI.rdtsc = cpu.m_bRDTSC;
|
||||
|
||||
// Adjust to Ghz if nessecary:
|
||||
if( fFrequency > 1000.0 )
|
||||
|
@ -322,4 +521,9 @@ void Sys_InitCPU( void )
|
|||
MsgDev(D_INFO, "CPU: %s [%i core's %s]. Frequency: %.01f %s\n ", cpu.m_szCPUID, (int)cpu.m_usNumLogicCore, buffer, fFrequency, szFrequencyDenomination );
|
||||
}
|
||||
MsgDev(D_NOTE, "CPU Features: %s\n", szFeatureString );
|
||||
}
|
||||
|
||||
Com_BuildSqrtTable();
|
||||
Com_BuildSinCosTable();
|
||||
Sys_InitMathlib( &cpu );
|
||||
}
|
||||
|
||||
|
|
|
@ -155,8 +155,8 @@ byte CRC_BlockSequence(byte *base, int length, int sequence)
|
|||
if (sequence < 0) sequence = abs(sequence);
|
||||
p = chktbl + (sequence % (sizeof(chktbl) - 4));
|
||||
|
||||
if (length > 60) length = 60;
|
||||
memcpy(chkb, base, length);
|
||||
if( length > 60 ) length = 60;
|
||||
Mem_Copy( chkb, base, length );
|
||||
|
||||
chkb[length] = p[0];
|
||||
chkb[length + 1] = p[1];
|
||||
|
@ -285,7 +285,7 @@ void MD4Final( byte digest[16], MD4_CTX *context )
|
|||
MD4Update (context, PADDING, padLen);
|
||||
MD4Update (context, bits, 8);
|
||||
Encode (digest, context->state, 16);
|
||||
memset((POINTER)context, 0, sizeof (*context));
|
||||
Mem_Set((POINTER)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
static void MD4Transform (UINT4 state[4], const byte block[64])
|
||||
|
@ -352,7 +352,7 @@ static void MD4Transform (UINT4 state[4], const byte block[64])
|
|||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
memset((POINTER)x, 0, sizeof (x));
|
||||
Mem_Set((POINTER)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
static void Encode(byte *output, UINT4 *input, uint len)
|
||||
|
|
|
@ -722,7 +722,7 @@ void Cvar_Restart_f( void )
|
|||
|
||||
// clear the var completely, since we
|
||||
// can't remove the index from the list
|
||||
memset( var, 0, sizeof( var ));
|
||||
Mem_Set( var, 0, sizeof( var ));
|
||||
continue;
|
||||
}
|
||||
Cvar_Set( var->name, var->reset_string );
|
||||
|
|
|
@ -434,7 +434,7 @@ int matchpattern(const char *in, const char *pattern, bool caseinsensitive)
|
|||
|
||||
void stringlistinit( stringlist_t *list )
|
||||
{
|
||||
memset(list, 0, sizeof(*list));
|
||||
Mem_Set( list, 0, sizeof( *list ));
|
||||
}
|
||||
|
||||
void stringlistfreecontents(stringlist_t *list)
|
||||
|
@ -1606,8 +1606,8 @@ static file_t* FS_SysOpen( const char* filepath, const char* mode )
|
|||
}
|
||||
}
|
||||
|
||||
file = (file_t *)Mem_Alloc (fs_mempool, sizeof (*file));
|
||||
memset (file, 0, sizeof (*file));
|
||||
file = (file_t *)Mem_Alloc( fs_mempool, sizeof( *file ));
|
||||
Mem_Set( file, 0, sizeof( *file ));
|
||||
file->ungetc = EOF;
|
||||
|
||||
file->handle = open (filepath, mod | opt, 0666);
|
||||
|
@ -1660,7 +1660,7 @@ file_t *FS_OpenPackedFile( pack_t* pack, int pack_ind )
|
|||
}
|
||||
|
||||
file = (file_t *)Mem_Alloc (fs_mempool, sizeof (*file));
|
||||
memset (file, 0, sizeof (*file));
|
||||
Mem_Set( file, 0, sizeof( *file ));
|
||||
file->handle = dup_handle;
|
||||
file->flags = FILE_FLAG_PACKED;
|
||||
file->real_length = pfile->realsize;
|
||||
|
@ -2413,16 +2413,16 @@ FS_StripExtension
|
|||
*/
|
||||
void FS_StripExtension (char *path)
|
||||
{
|
||||
int length;
|
||||
size_t length;
|
||||
|
||||
length = com_strlen(path)-1;
|
||||
while (length > 0 && path[length] != '.')
|
||||
length = com.strlen( path ) - 1;
|
||||
while( length > 0 && path[length] != '.' )
|
||||
{
|
||||
length--;
|
||||
if (path[length] == '/' || path[length] == '\\' || path[length] == ':')
|
||||
if( path[length] == '/' || path[length] == '\\' || path[length] == ':' )
|
||||
return; // no extension
|
||||
}
|
||||
if (length) path[length] = 0;
|
||||
if( length ) path[length] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3283,7 +3283,7 @@ static bool W_ConvertIWADLumps( wfile_t *wad )
|
|||
// W_Open will be swap lump later
|
||||
wad->lumps[i].filepos = doomlumps[i].filepos;
|
||||
wad->lumps[i].size = wad->lumps[i].disksize = doomlumps[i].size;
|
||||
com_strnlwr( doomlumps[i].name, wad->lumps[i].name, 9 );
|
||||
com.strnlwr( doomlumps[i].name, wad->lumps[i].name, 9 );
|
||||
wad->lumps[i].compression = CMP_NONE;
|
||||
wad->lumps[i].type = TYPE_NONE;
|
||||
|
||||
|
@ -3340,6 +3340,11 @@ static bool W_ConvertIWADLumps( wfile_t *wad )
|
|||
if( skin_images ) wad->lumps[i].type = TYPE_SKIN; // mark as skin (sprite model)
|
||||
if(!com_strnicmp( wad->lumps[i].name, "D_", 2 )) wad->lumps[i].type = TYPE_MUS;
|
||||
if(!com_strnicmp( wad->lumps[i].name, "DS", 2 )) wad->lumps[i].type = TYPE_SND;
|
||||
|
||||
// remove invalid resources
|
||||
if(!com_strnicmp( wad->lumps[i].name, "ENDOOM", 6 )) wad->lumps[i].type = TYPE_NONE;
|
||||
if(!com_strnicmp( wad->lumps[i].name, "STEP1", 5 )) wad->lumps[i].type = TYPE_NONE;
|
||||
if(!com_strnicmp( wad->lumps[i].name, "STEP2", 5 )) wad->lumps[i].type = TYPE_NONE;
|
||||
}
|
||||
|
||||
Mem_Free( doomlumps ); // no need anymore
|
||||
|
@ -3616,9 +3621,7 @@ wfile_t *W_Open( const char *filename, const char *mode )
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// and leaves the file open
|
||||
MsgDev( D_LOAD, "W_Open: %s (%i lumps)\n", wad->filename, wad->numlumps );
|
||||
return wad;
|
||||
}
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ typedef struct jpg_s
|
|||
#define DDS_RGB 0x00000040L
|
||||
#define DDS_RGBA 0x00000041L // (DDS_RGB|DDS_ALPHAPIXELS)
|
||||
#define DDS_LUMINANCE 0x00020000L
|
||||
#define DDS_DUDV 0x00080000L
|
||||
|
||||
// dwCaps1
|
||||
#define DDS_COMPLEX 0x00000008L
|
||||
|
|
|
@ -164,9 +164,6 @@ bool Image_SaveBMP( const char *name, rgbdata_t *pix )
|
|||
if( !pix->palette || !pix->buffer )
|
||||
return false;
|
||||
|
||||
pfile = FS_Open( name, "wb");
|
||||
if(!pfile) return false;
|
||||
|
||||
switch( pix->type )
|
||||
{
|
||||
case PF_INDEXED_24:
|
||||
|
@ -177,7 +174,10 @@ bool Image_SaveBMP( const char *name, rgbdata_t *pix )
|
|||
return false;
|
||||
}
|
||||
|
||||
// NOTE: alig transparency column will sucessfully removed
|
||||
pfile = FS_Open( name, "wb");
|
||||
if( !pfile ) return false;
|
||||
|
||||
// NOTE: align transparency column will sucessfully removed
|
||||
// after create sprite or lump image, it's just standard requiriments
|
||||
biTrueWidth = ((pix->width + 3) & ~3);
|
||||
cbBmpBits = biTrueWidth * pix->height;
|
||||
|
@ -224,8 +224,8 @@ bool Image_SaveBMP( const char *name, rgbdata_t *pix )
|
|||
else rgrgbPalette[i].rgbReserved = 0;
|
||||
}
|
||||
|
||||
// make last color is 0 0 255, xwad expect this
|
||||
if( pix->flags & IMAGE_HAVE_ALPHA )
|
||||
// make last color is 0 0 255, xwad expect this (but ignore decals)
|
||||
if( com.strchr( name, '{' ) && pix->flags & IMAGE_HAVE_ALPHA && !(pix->flags & IMAGE_COLORINDEX))
|
||||
{
|
||||
rgrgbPalette[255].rgbRed = 0x00;
|
||||
rgrgbPalette[255].rgbGreen = 0x00;
|
||||
|
|
|
@ -989,12 +989,24 @@ bool Image_DXTWriteHeader( vfile_t *f, rgbdata_t *pix )
|
|||
switch( pix->type )
|
||||
{
|
||||
case PF_LUMINANCE:
|
||||
dwABitMask = 0x00FFFFFF;
|
||||
dwABitMask = 0x000000FF;
|
||||
dwFlags2 |= DDS_LUMINANCE;
|
||||
dwRGBBitCount = 8;
|
||||
break;
|
||||
case PF_UV_16:
|
||||
dwRBitMask = 0x000000FF;
|
||||
dwGBitMask = 0x0000FF00;
|
||||
dwFlags2 |= DDS_DUDV;
|
||||
dwRGBBitCount = 16;
|
||||
break;
|
||||
case PF_UV_32:
|
||||
dwRBitMask = 0x0000FFFF;
|
||||
dwGBitMask = 0xFFFF0000;
|
||||
dwFlags2 |= DDS_DUDV;
|
||||
dwRGBBitCount = 32;
|
||||
break;
|
||||
case PF_LUMINANCE_ALPHA:
|
||||
dwRBitMask = 0x00FF0000;
|
||||
dwRBitMask = 0x000000FF;
|
||||
dwABitMask = 0xFF000000;
|
||||
dwFlags2 |= DDS_LUMINANCE;
|
||||
dwFlags2 |= DDS_ALPHAPIXELS;
|
||||
|
@ -1007,6 +1019,13 @@ bool Image_DXTWriteHeader( vfile_t *f, rgbdata_t *pix )
|
|||
dwFlags2 |= DDS_RGB;
|
||||
dwRGBBitCount = 24;
|
||||
break;
|
||||
case PF_RGB_24:
|
||||
dwRBitMask = 0x00FF0000;
|
||||
dwGBitMask = 0x0000FF00;
|
||||
dwBBitMask = 0x000000FF;
|
||||
dwFlags2 |= DDS_RGB;
|
||||
dwRGBBitCount = 24;
|
||||
break;
|
||||
case PF_BGRA_32:
|
||||
dwRBitMask = 0x000000FF;
|
||||
dwGBitMask = 0x0000FF00;
|
||||
|
@ -1214,10 +1233,13 @@ bool Image_DXTWriteImage( vfile_t *f, rgbdata_t *pix )
|
|||
switch( pix->type )
|
||||
{
|
||||
case PF_BGR_24:
|
||||
case PF_RGB_24:
|
||||
case PF_BGRA_32:
|
||||
case PF_RGBA_32:
|
||||
case PF_LUMINANCE:
|
||||
case PF_LUMINANCE_ALPHA:
|
||||
case PF_UV_16:
|
||||
case PF_UV_32:
|
||||
case PF_DXT1:
|
||||
case PF_DXT3:
|
||||
case PF_DXT5:
|
||||
|
@ -1265,7 +1287,14 @@ void Image_DXTGetPixelFormat( dds_t *hdr )
|
|||
else
|
||||
{
|
||||
// this dds texture isn't compressed so write out ARGB or luminance format
|
||||
if( hdr->dsPixelFormat.dwFlags & DDS_LUMINANCE )
|
||||
if( hdr->dsPixelFormat.dwFlags & DDS_DUDV )
|
||||
{
|
||||
if( hdr->dsPixelFormat.dwRGBBitCount == 16 )
|
||||
image.type = PF_UV_16;
|
||||
else if( hdr->dsPixelFormat.dwRGBBitCount == 32 )
|
||||
image.type = PF_UV_32;
|
||||
}
|
||||
else if( hdr->dsPixelFormat.dwFlags & DDS_LUMINANCE )
|
||||
{
|
||||
if( hdr->dsPixelFormat.dwFlags & DDS_ALPHAPIXELS )
|
||||
image.type = PF_LUMINANCE_ALPHA;
|
||||
|
@ -1369,13 +1398,13 @@ uint Image_DXTCalcSize( const char *name, dds_t *hdr, size_t filesize )
|
|||
|
||||
void Image_AddRGBAToPack( uint target, int level, uint imageSize, const void* data )
|
||||
{
|
||||
// NOTE: just update bufer without checking for type
|
||||
// NOTE: just update bufer without checking for a type
|
||||
image.rgba = Mem_Realloc( Sys.imagepool, image.rgba, image.ptr + imageSize );
|
||||
Mem_Copy( image.rgba + image.ptr, data, imageSize ); // add mipmap or cubemapside
|
||||
|
||||
image.size += imageSize; // update image size
|
||||
image.ptr += imageSize;
|
||||
if( level ) image.num_mips++;
|
||||
image.num_mips++;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2297,7 +2326,7 @@ bool Image_LoadDDS( const char *name, const byte *buffer, size_t filesize )
|
|||
if( image.cmd_flags & IL_IGNORE_MIPS )
|
||||
image.cur_mips = 1;
|
||||
else image.cur_mips = image.num_mips;
|
||||
image.num_mips = 1;
|
||||
image.num_mips = 0; // clear mipcount
|
||||
|
||||
for( i = 0, offset = 0; i < numsides; i++, buf += offset )
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ int jpeg_huffmancode( huffman_table_t *table )
|
|||
code |= jpeg_read_bit();
|
||||
while(table->size[i] <= size)
|
||||
{
|
||||
if(table->code[i] == code)
|
||||
if( table->code[i] == code )
|
||||
return table->hval[i];
|
||||
i++;
|
||||
}
|
||||
|
@ -193,17 +193,17 @@ int jpeg_readmarkers( void )
|
|||
while( 1 )
|
||||
{
|
||||
marker = jpeg_read_byte();
|
||||
if(marker != 0xFF) return 0;
|
||||
if( marker != 0xFF ) return 0;
|
||||
|
||||
marker = jpeg_read_byte();
|
||||
if(marker != 0xD8)
|
||||
if( marker != 0xD8 )
|
||||
{
|
||||
length = jpeg_read_word();
|
||||
length -= 2;
|
||||
|
||||
switch(marker)
|
||||
switch( marker )
|
||||
{
|
||||
case 0xC0: // Baseline
|
||||
case 0xC0: // baseline
|
||||
jpg_file.data_precision = jpeg_read_byte();
|
||||
jpg_file.height = jpeg_read_word();
|
||||
jpg_file.width = jpeg_read_word();
|
||||
|
@ -219,22 +219,22 @@ int jpeg_readmarkers( void )
|
|||
jpg_file.component_info[i].t = jpeg_read_byte();
|
||||
}
|
||||
break;
|
||||
case 0xC1: // Extended sequetial, Huffman
|
||||
case 0xC2: // Progressive, Huffman
|
||||
case 0xC3: // Lossless, Huffman
|
||||
case 0xC5: // Differential sequential, Huffman
|
||||
case 0xC6: // Differential progressive, Huffman
|
||||
case 0xC7: // Differential lossless, Huffman
|
||||
case 0xC8: // Reserved for JPEG extensions
|
||||
case 0xC9: // Extended sequential, arithmetic
|
||||
case 0xCA: // Progressive, arithmetic
|
||||
case 0xCB: // Lossless, arithmetic
|
||||
case 0xCD: // Differential sequential, arithmetic
|
||||
case 0xCE: // Differential progressive, arithmetic
|
||||
case 0xCF: // Differential lossless, arithmetic
|
||||
return 0;
|
||||
case 0xC4: // Huffman table
|
||||
while(length > 0)
|
||||
case 0xC1: // extended sequetial, Huffman
|
||||
case 0xC2: // progressive, Huffman
|
||||
case 0xC3: // lossless, Huffman
|
||||
case 0xC5: // differential sequential, Huffman
|
||||
case 0xC6: // differential progressive, Huffman
|
||||
case 0xC7: // differential lossless, Huffman
|
||||
case 0xC8: // reserved for JPEG extensions
|
||||
case 0xC9: // extended sequential, arithmetic
|
||||
case 0xCA: // progressive, arithmetic
|
||||
case 0xCB: // lossless, arithmetic
|
||||
case 0xCD: // differential sequential, arithmetic
|
||||
case 0xCE: // differential progressive, arithmetic
|
||||
case 0xCF: // differential lossless, arithmetic
|
||||
return 0; // not supported yet
|
||||
case 0xC4: // huffman table
|
||||
while( length > 0 )
|
||||
{
|
||||
k = jpeg_read_byte();
|
||||
if(k & 0x10) hptr = &jpg_file.hac[k & 0x0F];
|
||||
|
@ -259,8 +259,8 @@ int jpeg_readmarkers( void )
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 0xDB: // Quantization table
|
||||
while(length > 0)
|
||||
case 0xDB: // quantization table
|
||||
while( length > 0 )
|
||||
{
|
||||
j = jpeg_read_byte();
|
||||
k = (j >> 4) & 0x0F;
|
||||
|
@ -273,17 +273,17 @@ int jpeg_readmarkers( void )
|
|||
if( k )length -= 64;
|
||||
}
|
||||
break;
|
||||
case 0xD9: // End of image (EOI)
|
||||
case 0xD9: // end of image (EOI)
|
||||
return 0;
|
||||
case 0xDA: // Start of scan (SOS)
|
||||
case 0xDA: // start of scan (SOS)
|
||||
j = jpeg_read_byte();
|
||||
for(i = 0; i < j; i++)
|
||||
{
|
||||
k = jpeg_read_byte();
|
||||
m = jpeg_read_byte();
|
||||
for(l = 0; l < jpg_file.num_components; l++)
|
||||
for( l = 0; l < jpg_file.num_components; l++ )
|
||||
{
|
||||
if(jpg_file.component_info[l].id == k)
|
||||
if( jpg_file.component_info[l].id == k )
|
||||
{
|
||||
jpg_file.component_info[l].td = (m >> 4) & 0x0F;
|
||||
jpg_file.component_info[l].ta = m & 0x0F;
|
||||
|
@ -296,11 +296,11 @@ int jpeg_readmarkers( void )
|
|||
jpg_file.scan.ah = (k >> 4) & 0x0F;
|
||||
jpg_file.scan.al = k & 0x0F;
|
||||
return 1;
|
||||
case 0xDD: // Restart interval
|
||||
case 0xDD: // restart interval
|
||||
jpg_file.restart_interval = jpeg_read_word();
|
||||
break;
|
||||
default:
|
||||
jpg_file.buffer += length; //move ptr
|
||||
jpg_file.buffer += length; // move ptr
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -344,12 +344,12 @@ void jpeg_decompress( void )
|
|||
scaleh[2] = jpg_file.component_info[0].h / jpg_file.component_info[2].h;
|
||||
scalev[2] = jpg_file.component_info[0].v / jpg_file.component_info[2].v;
|
||||
}
|
||||
memset(jpg_file.dc,0,sizeof(int) * 3);
|
||||
memset( jpg_file.dc, 0, sizeof(int) * 3);
|
||||
|
||||
for(Y = 0; Y < jpg_file.height; Y += jpg_file.component_info[0].v << 3)
|
||||
for( Y = 0; Y < jpg_file.height; Y += jpg_file.component_info[0].v << 3 )
|
||||
{
|
||||
if(jpg_file.restart_interval > 0) jpg_file.curbit = 0;
|
||||
for(X = 0; X < jpg_file.width; X += jpg_file.component_info[0].h << 3)
|
||||
if( jpg_file.restart_interval > 0 ) jpg_file.curbit = 0;
|
||||
for( X = 0; X < jpg_file.width; X += jpg_file.component_info[0].h << 3 )
|
||||
{
|
||||
for(plane = 0; plane < jpg_file.num_components; plane++)
|
||||
{
|
||||
|
@ -428,7 +428,7 @@ void jpeg_ycbcr2rgba( void )
|
|||
// convert YCbCr image to RGBA
|
||||
for(i = 0; i < jpg_file.width * jpg_file.height << 2; i += 4)
|
||||
{
|
||||
Y = jpg_file.data[i];
|
||||
Y = jpg_file.data[i + 0];
|
||||
Cb = jpg_file.data[i + 1] - 128;
|
||||
Cr = jpg_file.data[i + 2] - 128;
|
||||
|
||||
|
@ -447,7 +447,7 @@ void jpeg_ycbcr2rgba( void )
|
|||
jpg_file.data[i + 0] = R;
|
||||
jpg_file.data[i + 1] = G;
|
||||
jpg_file.data[i + 2] = B;
|
||||
jpg_file.data[i + 3] = 0xff;//alpha channel
|
||||
jpg_file.data[i + 3] = 0xff; // no alpha channel
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ Image_LoadJPG
|
|||
*/
|
||||
bool Image_LoadJPG( const char *name, const byte *buffer, size_t filesize )
|
||||
{
|
||||
memset(&jpg_file, 0, sizeof(jpg_file));
|
||||
memset( &jpg_file, 0, sizeof( jpg_file ));
|
||||
jpg_file.buffer = (byte *)buffer;
|
||||
|
||||
if(!jpeg_readmarkers())
|
||||
|
@ -482,7 +482,6 @@ bool Image_LoadJPG( const char *name, const byte *buffer, size_t filesize )
|
|||
|
||||
image.width = jpg_file.width;
|
||||
image.height = jpg_file.height;
|
||||
image.type = PF_RGBA_32;
|
||||
if(!Image_ValidSize( name )) return false;
|
||||
|
||||
image.size = jpg_file.width * jpg_file.height * 4;
|
||||
|
@ -492,9 +491,10 @@ bool Image_LoadJPG( const char *name, const byte *buffer, size_t filesize )
|
|||
if( jpg_file.num_components == 1 ) jpeg_gray2rgba();
|
||||
if( jpg_file.num_components == 3 ) jpeg_ycbcr2rgba();
|
||||
|
||||
image.rgba = jpg_file.data;
|
||||
image.type = PF_RGBA_32;
|
||||
image.num_layers = 1;
|
||||
image.num_mips = 1;
|
||||
image.rgba = jpg_file.data;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -84,6 +84,8 @@ const bpc_desc_t PFDesc[] =
|
|||
{PF_LUMINANCE, "LUM 8", 0x1909, 0x1401, 1, 1, -1 },
|
||||
{PF_LUMINANCE_16, "LUM 16", 0x1909, 0x1401, 2, 2, -2 },
|
||||
{PF_LUMINANCE_ALPHA,"LUM A", 0x190A, 0x1401, 2, 1, -2 },
|
||||
{PF_UV_16, "UV 16", 0x190A, 0x1401, 2, 1, -2 },
|
||||
{PF_UV_16, "UV 16", 0x190A, 0x1401, 2, 1, -4 },
|
||||
{PF_R_16F, "R 16f", 0x8884, 0x1406, 1, 4, -2 }, // FIXME: these NV extension, reinstall for ATI
|
||||
{PF_R_32F, "R 32f", 0x8885, 0x1406, 1, 4, -4 },
|
||||
{PF_GR_32F, "GR 32f", 0x8886, 0x1406, 2, 4, -4 },
|
||||
|
@ -109,6 +111,7 @@ void Image_Reset( void )
|
|||
image.num_layers = 1;
|
||||
image.source_type = 0;
|
||||
image.num_mips = 0;
|
||||
image.filter = CB_HINT_NO;
|
||||
image.type = PF_UNKNOWN;
|
||||
|
||||
// pointers will be saved with prevoius picture struct
|
||||
|
@ -383,7 +386,7 @@ load_internal:
|
|||
|
||||
if( !image.loadformats || image.loadformats->ext == NULL )
|
||||
MsgDev( D_NOTE, "FS_LoadImage: imagelib offline\n" );
|
||||
else if(!com_stristr( filename, "#internal" ))
|
||||
else if( filename[0] != '#' )
|
||||
MsgDev( D_WARN, "FS_LoadImage: couldn't load \"%s\"\n", loadname );
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -43,7 +43,7 @@ bool Image_LoadPCX( const char *name, const byte *buffer, size_t filesize )
|
|||
|
||||
if( pcx.bits_per_pixel != 8 || pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1)
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadPCX: (%s) have illegal pixel size '%d'\n", name, pcx.bits_per_pixel );
|
||||
MsgDev( D_ERROR, "Image_LoadPCX: (%s) have unknown version '%d'\n", name, pcx.version );
|
||||
return false;
|
||||
}
|
||||
if(!Image_ValidSize( name )) return false;
|
||||
|
@ -77,8 +77,8 @@ bool Image_LoadPCX( const char *name, const byte *buffer, size_t filesize )
|
|||
while(x < image.width) pix[x++] = 0;
|
||||
}
|
||||
|
||||
if( image.hint == IL_HINT_Q2 )
|
||||
Image_GetPaletteQ2();
|
||||
// NOTE: IL_HINT_Q2 does wrong result for sprite frames. use with caution
|
||||
if( image.hint == IL_HINT_Q2 ) Image_GetPaletteQ2();
|
||||
else Image_GetPalettePCX( palette );
|
||||
|
||||
// check for transparency
|
||||
|
|
|
@ -141,7 +141,7 @@ static const loadformat_t load_quake2[] =
|
|||
{
|
||||
{ "textures/%s%s.%s", "wal", Image_LoadWAL, IL_HINT_Q2 }, // map textures
|
||||
{ "%s%s.%s", "wal", Image_LoadWAL, IL_HINT_Q2 }, // map textures
|
||||
{ "%s%s.%s", "pcx", Image_LoadPCX, IL_HINT_Q2 }, // pics, skins, skies (force to ignore internal pcx-palette)
|
||||
{ "%s%s.%s", "pcx", Image_LoadPCX, IL_HINT_NO }, // pics, skins, skies (q2 palette does wrong result for some images)
|
||||
{ "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // skies (indexed TGA's? never see in Q2)
|
||||
{ NULL, NULL, NULL, IL_HINT_NO }
|
||||
};
|
||||
|
@ -1077,6 +1077,51 @@ byte *Image_ResampleInternal( const void *indata, int inwidth, int inheight, int
|
|||
return image.tempbuffer;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_Flood
|
||||
================
|
||||
*/
|
||||
byte *Image_FloodInternal( const byte *indata, int inwidth, int inheight, int outwidth, int outheight, int type )
|
||||
{
|
||||
bool quality = (image.cmd_flags & IL_USE_LERPING);
|
||||
int samples = PFDesc[type].bpp;
|
||||
int newsize, x, y, i;
|
||||
byte *in, *out;
|
||||
|
||||
// nothing to reflood ?
|
||||
if( inwidth == outwidth && inheight == outheight )
|
||||
return (byte *)indata;
|
||||
|
||||
// alloc new buffer
|
||||
switch( type )
|
||||
{
|
||||
case PF_INDEXED_24:
|
||||
case PF_INDEXED_32:
|
||||
case PF_RGB_24:
|
||||
case PF_BGR_24:
|
||||
case PF_BGRA_32:
|
||||
case PF_RGBA_32:
|
||||
in = ( byte *)indata;
|
||||
newsize = outwidth * outheight * samples;
|
||||
out = image.tempbuffer = (byte *)Mem_Realloc( Sys.imagepool, image.tempbuffer, newsize );
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_WARN, "Image_Flood: unsupported format %s\n", PFDesc[type].name );
|
||||
return (byte *)indata;
|
||||
}
|
||||
|
||||
if( samples == 1 ) memset( out, 0xFF, newsize ); // last palette color
|
||||
else memset( out, 0x00808080, newsize ); // gray (alpha leaved 0x00)
|
||||
|
||||
for( y = 0; y < outheight; y++ )
|
||||
for( x = 0; y < inheight && x < outwidth; x++ )
|
||||
for( i = 0; i < samples; i++ )
|
||||
if( x < inwidth ) *out++ = *in++;
|
||||
else *out++;
|
||||
return image.tempbuffer;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_Flip
|
||||
|
@ -1163,32 +1208,37 @@ void Image_Process( rgbdata_t **pix, int width, int height, uint flags )
|
|||
out = Image_FlipInternal( pic->buffer, &pic->width, &pic->height, pic->type, flags );
|
||||
if( pic->buffer != out ) Mem_Copy( pic->buffer, image.tempbuffer, pic->size );
|
||||
|
||||
if(( flags & IMAGE_RESAMPLE && width > 0 && height > 0 ) || flags & IMAGE_ROUND )
|
||||
if(( flags & IMAGE_RESAMPLE && width > 0 && height > 0 ) || flags & IMAGE_ROUND || flags & IMAGE_ROUNDFILLER )
|
||||
{
|
||||
int w, h;
|
||||
|
||||
if( flags & IMAGE_ROUND )
|
||||
if( flags & IMAGE_ROUND || flags & IMAGE_ROUNDFILLER )
|
||||
{
|
||||
w = pic->width;
|
||||
h = pic->height;
|
||||
|
||||
// round to nearest pow
|
||||
// NOTE: images with dims less than 8x8 may causing problems
|
||||
Image_RoundDimensions( &w, &h );
|
||||
w = bound( 8, w, IMAGE_MAXWIDTH ); // 8 - 4096
|
||||
h = bound( 8, h, IMAGE_MAXHEIGHT); // 8 - 4096
|
||||
}
|
||||
else
|
||||
{
|
||||
// custom size
|
||||
w = bound( 1, width, IMAGE_MAXWIDTH ); // maxwidth 4096
|
||||
h = bound( 1, height, IMAGE_MAXHEIGHT); // maxheight 4096
|
||||
// custom size (user choise without limitations)
|
||||
w = bound( 1, width, IMAGE_MAXWIDTH ); // 1 - 4096
|
||||
h = bound( 1, height, IMAGE_MAXHEIGHT); // 1 - 4096
|
||||
}
|
||||
out = Image_ResampleInternal((uint *)pic->buffer, pic->width, pic->height, w, h, pic->type );
|
||||
if( flags & IMAGE_ROUNDFILLER )
|
||||
out = Image_FloodInternal( pic->buffer, pic->width, pic->height, w, h, pic->type );
|
||||
else out = Image_ResampleInternal((uint *)pic->buffer, pic->width, pic->height, w, h, pic->type );
|
||||
|
||||
if( out != pic->buffer ) // resampled
|
||||
if( out != pic->buffer ) // resampled or filled
|
||||
{
|
||||
MsgDev( D_NOTE, "Image_Resample: from[%d x %d] to [%d x %d]\n", pic->width, pic->height, w, h );
|
||||
pic->width = w, pic->height = h;
|
||||
pic->size = w * h * PFDesc[pic->type].bpp;
|
||||
MsgDev( D_NOTE, "Image_Resample: from[%d x %d] to [%d x %d]\n", pic->width, pic->height, w, h );
|
||||
Mem_Free( pic->buffer ); // free original image buffer if allowed
|
||||
Mem_Free( pic->buffer ); // free original image buffer
|
||||
pic->buffer = Image_Copy( pic->size ); // unzone buffer (don't touch image.tempbuffer)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
#include "imagelib.h"
|
||||
|
||||
// VTF->DXT conversion supply structures
|
||||
// VTF->DXT supply conversion structures
|
||||
typedef struct
|
||||
{
|
||||
long ofs; // offset at start
|
||||
long ofs; // buffer + ofs
|
||||
size_t size; // map size
|
||||
} vlayer_t;
|
||||
|
||||
|
@ -30,12 +30,11 @@ typedef struct
|
|||
int numSides; // must be equal 1 or 7
|
||||
} vtex_t;
|
||||
|
||||
// NOTE: other VTF formats never used in games based on Source Engine
|
||||
pixformat_t Image_VTFFormat( vtf_format_t srcFormat )
|
||||
{
|
||||
switch( srcFormat )
|
||||
{
|
||||
case VTF_UNKNOWN:
|
||||
return VTF_UNKNOWN;
|
||||
case VTF_DXT1:
|
||||
case VTF_DXT1_ONEBITALPHA:
|
||||
return PF_DXT1;
|
||||
|
@ -48,37 +47,27 @@ pixformat_t Image_VTFFormat( vtf_format_t srcFormat )
|
|||
case VTF_BGR888:
|
||||
return PF_BGR_24;
|
||||
case VTF_UVWQ8888:
|
||||
return PF_RGBA_32;
|
||||
return PF_UV_32;
|
||||
case VTF_BGRA8888:
|
||||
return PF_BGRA_32;
|
||||
case VTF_UV88:
|
||||
return PF_LUMINANCE_ALPHA;
|
||||
#if 0
|
||||
return PF_UV_16;
|
||||
case VTF_RGBA8888:
|
||||
return PF_RGBA_32;
|
||||
case VTF_RGB888:
|
||||
return PF_RGB_24;
|
||||
case VTF_RGB565:
|
||||
return PF_RGB_16;
|
||||
case VTF_I8:
|
||||
return PF_LUMINANCE;
|
||||
case VTF_IA88:
|
||||
return PF_LUMINANCE_ALPHA;
|
||||
case VTF_P8:
|
||||
return PF_INDEXED_24;
|
||||
case VTF_ARGB8888:
|
||||
return PF_ARGB_32;
|
||||
#endif
|
||||
case VTF_UNKNOWN:
|
||||
return VTF_UNKNOWN;
|
||||
default: return PF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_VTFCalcMipmapSize
|
||||
Image_VTFCalcLowResSize
|
||||
|
||||
stupid idea - last miplevel (1x1) put at begin of buffer
|
||||
or DX8 format requries it, i'm don't know...
|
||||
lowres image hasn't mip-levels, frames or cubemap sides
|
||||
typically params: 16x16 DXT1 but can be missing
|
||||
================
|
||||
*/
|
||||
size_t Image_VTFCalcLowResSize( vtf_t *hdr )
|
||||
|
@ -91,24 +80,40 @@ size_t Image_VTFCalcLowResSize( vtf_t *hdr )
|
|||
// missing lowRes image for -1 value
|
||||
if( format != VTF_UNKNOWN )
|
||||
{
|
||||
w = hdr->lowResImageWidth;
|
||||
h = hdr->lowResImageHeight;
|
||||
w = LittleShort( hdr->lowResImageWidth );
|
||||
h = LittleShort( hdr->lowResImageHeight );
|
||||
buffsize = Image_DXTGetLinearSize( format, w, h, 1, 0 );
|
||||
}
|
||||
return buffsize;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_VTFCalcMipmapSize
|
||||
|
||||
stupid idea - last miplevel (1x1) put at begin of buffer
|
||||
or DX8 format requries it, i'm don't know...
|
||||
================
|
||||
*/
|
||||
size_t Image_VTFCalcMipmapSize( vtf_t *hdr, int mipNum )
|
||||
{
|
||||
size_t buffsize = 0;
|
||||
int w, h, mipsize;
|
||||
|
||||
w = max( 1, (hdr->width)>>mipNum);
|
||||
h = max( 1, (hdr->height)>>mipNum);
|
||||
w = max( 1, LittleShort(hdr->width)>>mipNum );
|
||||
h = max( 1, LittleShort(hdr->height)>>mipNum );
|
||||
mipsize = Image_DXTGetLinearSize( image.type, w, h, 1, 0 );
|
||||
return mipsize;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Image_VTFCalcImageSize
|
||||
|
||||
main image size not included header or lowres
|
||||
================
|
||||
*/
|
||||
size_t Image_VTFCalcImageSize( vtf_t *hdr, bool oldformat )
|
||||
{
|
||||
size_t buffsize = 0;
|
||||
|
@ -175,7 +180,7 @@ void Image_VTFSwapBuffer( vtf_t *hdr, const byte *input, size_t input_size, bool
|
|||
// NOTE: we needs to swap sides order
|
||||
vside_t *side = &texture->sides[texture->numSides-i-1];
|
||||
if( !oldformat && texture->numSides > 1 && i == 6 )
|
||||
continue; // skip envmap if needed
|
||||
continue; // skip envmap if present
|
||||
for( j = 0; j < side->nummips; j++ )
|
||||
{
|
||||
vmip_t *mip = &side->mips[j];
|
||||
|
@ -218,7 +223,7 @@ bool Image_LoadVTF( const char *name, const byte *buffer, size_t filesize )
|
|||
hdrSize = LittleLong( vtf.hdr_size );
|
||||
biasSize = 0;
|
||||
|
||||
if( LittleLong( vtf.ident ) != VTFHEADER ) return false; // it's not a dds file, just skip it
|
||||
if( LittleLong( vtf.ident ) != VTFHEADER ) return false; // it's not a vtf file, just skip it
|
||||
FS_FileBase( name, shortname );
|
||||
|
||||
// bounds check
|
||||
|
@ -230,7 +235,7 @@ bool Image_LoadVTF( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
|
||||
i = LittleLong( vtf.ver_minor );
|
||||
if( i == VTF_SUBVERSION0 && vtf.hdr_size == 64 ) oldformat = true; // missing envmap for cubemap images
|
||||
if( i == VTF_SUBVERSION0 && vtf.hdr_size == 64 ) oldformat = true; // 7.0 hasn't envmap for cubemap images
|
||||
// all other subversions are valid
|
||||
|
||||
image.width = LittleShort( vtf.width );
|
||||
|
@ -244,8 +249,8 @@ bool Image_LoadVTF( const char *name, const byte *buffer, size_t filesize )
|
|||
if( flags & VF_ENVMAP ) image.flags |= IMAGE_CUBEMAP;
|
||||
|
||||
vtfFormat = LittleLong( vtf.imageFormat );
|
||||
image.num_layers = LittleLong( vtf.num_frames );
|
||||
image.type = Image_VTFFormat( vtfFormat );
|
||||
image.num_layers = LittleLong( vtf.num_frames );
|
||||
image.num_mips = LittleLong( vtf.numMipLevels );
|
||||
|
||||
if( image.type == PF_UNKNOWN )
|
||||
|
@ -266,8 +271,8 @@ bool Image_LoadVTF( const char *name, const byte *buffer, size_t filesize )
|
|||
}
|
||||
else if( filesize < i ) return false; // corrupted texture or somewhat
|
||||
|
||||
fin += hdrSize + biasSize + lowResSize; // skip lowRes image
|
||||
image.size = resSize;
|
||||
fin += hdrSize + biasSize + lowResSize; // go to main image
|
||||
image.size = resSize; // base size can be merged after swapping
|
||||
|
||||
// convert VTF to DXT
|
||||
Image_VTFSwapBuffer( &vtf, fin, resSize, oldformat );
|
||||
|
@ -283,10 +288,8 @@ bool Image_LoadVTF( const char *name, const byte *buffer, size_t filesize )
|
|||
if( image.flags & IMAGE_CUBEMAP ) numsides = 6;
|
||||
Image_SetPixelFormat( image.width, image.height, image.num_layers ); // setup
|
||||
image.size = image.ptr = 0;
|
||||
if( image.cmd_flags & IL_IGNORE_MIPS )
|
||||
image.cur_mips = 1;
|
||||
else image.cur_mips = image.num_mips;
|
||||
image.num_mips = 1; // defaulting to one mip
|
||||
image.cur_mips = image.num_mips;
|
||||
image.num_mips = 0; // clear mipcount
|
||||
|
||||
for( i = 0, offset = 0; i < numsides; i++, buf += offset )
|
||||
{
|
||||
|
|
|
@ -1,316 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// img_vtf.c - vtf format load & save
|
||||
//=======================================================================
|
||||
|
||||
#include "imagelib.h"
|
||||
|
||||
// VTF->DXT conversion supply structures
|
||||
typedef struct
|
||||
{
|
||||
long ofs; // offset at start
|
||||
size_t size; // map size
|
||||
} vlayer_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vlayer_t layers[512]; // max frames or layers
|
||||
int numlayers;
|
||||
} vmip_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vmip_t mips[512]; // max frames or layers
|
||||
int nummips; // or cubemap counts
|
||||
} vside_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vside_t sides[CB_FACECOUNT];// 6 cubemap sides and one envmap
|
||||
int numSides; // must be equal 1 or 7
|
||||
} vtex_t;
|
||||
|
||||
pixformat_t Image_VTFFormat( vtf_format_t srcFormat )
|
||||
{
|
||||
switch( srcFormat )
|
||||
{
|
||||
case VTF_UNKNOWN:
|
||||
return VTF_UNKNOWN;
|
||||
case VTF_DXT1:
|
||||
case VTF_DXT1_ONEBITALPHA:
|
||||
return PF_DXT1;
|
||||
case VTF_DXT3:
|
||||
return PF_DXT3;
|
||||
case VTF_DXT5:
|
||||
return PF_DXT5;
|
||||
case VTF_RGBA16161616F:
|
||||
return PF_ABGR_64F;
|
||||
case VTF_BGR888:
|
||||
return PF_BGR_24;
|
||||
case VTF_UVWQ8888:
|
||||
return PF_RGBA_32;
|
||||
case VTF_BGRA8888:
|
||||
return PF_BGRA_32;
|
||||
case VTF_UV88:
|
||||
return PF_LUMINANCE_ALPHA;
|
||||
#if 0
|
||||
case VTF_RGBA8888:
|
||||
return PF_RGBA_32;
|
||||
case VTF_RGB888:
|
||||
return PF_RGB_24;
|
||||
case VTF_RGB565:
|
||||
return PF_RGB_16;
|
||||
case VTF_I8:
|
||||
return PF_LUMINANCE;
|
||||
case VTF_IA88:
|
||||
return PF_LUMINANCE_ALPHA;
|
||||
case VTF_P8:
|
||||
return PF_INDEXED_24;
|
||||
case VTF_ARGB8888:
|
||||
return PF_ARGB_32;
|
||||
#endif
|
||||
default: return PF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_VTFCalcMipmapSize
|
||||
|
||||
stupid idea - last miplevel (1x1) put at begin of buffer
|
||||
or DX8 format requries it, i'm don't know...
|
||||
================
|
||||
*/
|
||||
size_t Image_VTFCalcLowResSize( vtf_t *hdr )
|
||||
{
|
||||
size_t buffsize = 0;
|
||||
int w, h, format;
|
||||
|
||||
format = Image_VTFFormat( LittleLong( hdr->lowResImageFormat ));
|
||||
|
||||
// missing lowRes image for -1 value
|
||||
if( format != VTF_UNKNOWN )
|
||||
{
|
||||
w = hdr->lowResImageWidth;
|
||||
h = hdr->lowResImageHeight;
|
||||
buffsize = Image_DXTGetLinearSize( format, w, h, 1, 0 );
|
||||
}
|
||||
return buffsize;
|
||||
}
|
||||
|
||||
size_t Image_VTFCalcMipmapSize( vtf_t *hdr, int mipNum )
|
||||
{
|
||||
size_t buffsize = 0;
|
||||
int w, h, mipsize;
|
||||
|
||||
w = max( 1, (hdr->width)>>mipNum);
|
||||
h = max( 1, (hdr->height)>>mipNum);
|
||||
mipsize = Image_DXTGetLinearSize( image.type, w, h, 1, 0 );
|
||||
return mipsize;
|
||||
}
|
||||
|
||||
size_t Image_VTFCalcImageSize( vtf_t *hdr, bool oldformat )
|
||||
{
|
||||
size_t buffsize = 0;
|
||||
int i, numSides = 1;
|
||||
|
||||
if( image.flags & IMAGE_CUBEMAP ) numSides = (oldformat) ? 6 : CB_FACECOUNT;
|
||||
for( i = 0; i < image.num_mips; i++ )
|
||||
buffsize += Image_VTFCalcMipmapSize( hdr, i ) * image.num_layers * numSides;
|
||||
return buffsize;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Image_VTFSwapBuffer
|
||||
|
||||
VTF: <format>
|
||||
header: vtf_t
|
||||
lowResImage[lowResSize]
|
||||
mipmaps
|
||||
layers (frames)
|
||||
sides
|
||||
|
||||
DDS: <format>
|
||||
header: dds_t
|
||||
sides
|
||||
mipmaps
|
||||
layers
|
||||
================
|
||||
*/
|
||||
void Image_VTFSwapBuffer( vtf_t *hdr, const byte *input, size_t input_size, bool oldformat )
|
||||
{
|
||||
int numSides = (image.flags & IMAGE_CUBEMAP) ? oldformat ? 6 : CB_FACECOUNT : 1;
|
||||
vtex_t *texture = Mem_Alloc( Sys.imagepool, sizeof( vtex_t ));
|
||||
bool ignore_mips = (image.cmd_flags & IL_IGNORE_MIPS);
|
||||
uint i, j, k, out_size = 0;
|
||||
byte *src, *dst;
|
||||
|
||||
// output size can't be more than input size
|
||||
image.tempbuffer = Mem_Realloc( Sys.imagepool, image.tempbuffer, input_size );
|
||||
src = (byte *)(input + input_size);
|
||||
texture->numSides = numSides;
|
||||
dst = image.tempbuffer;
|
||||
|
||||
// build image representation table
|
||||
// NOTE: src = buffer + sizeof(vtf_t) + lowResSize;
|
||||
for( i = 0; i < image.num_mips; i++ )
|
||||
{
|
||||
for( j = 0; j < image.num_layers; j++ )
|
||||
{
|
||||
for( k = 0; k < numSides; k++ )
|
||||
{
|
||||
texture->sides[k].mips[i].layers[j].size = Image_VTFCalcMipmapSize( hdr, i );
|
||||
src -= texture->sides[k].mips[i].layers[j].size;
|
||||
texture->sides[k].mips[i].layers[j].ofs = src - input;
|
||||
texture->sides[k].mips[i].numlayers++;
|
||||
texture->sides[k].nummips++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to DXT buffer
|
||||
for( i = 0; i < texture->numSides; i++ )
|
||||
{
|
||||
vside_t *side = &texture->sides[i];
|
||||
if( !oldformat && texture->numSides > 1 && i == 0 )
|
||||
continue; // skip envmap if needed
|
||||
for( j = 0; j < side->nummips; j++ )
|
||||
{
|
||||
vmip_t *mip = &side->mips[j];
|
||||
if( ignore_mips && j > 0 ) continue;
|
||||
for( k = 0; k < mip->numlayers; k++ )
|
||||
{
|
||||
vlayer_t *layer = &mip->layers[k];
|
||||
Mem_Copy( dst, input + layer->ofs, layer->size );
|
||||
out_size += layer->size;
|
||||
dst += layer->size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy swapped buffer back to the input file, because tempbuffer
|
||||
// too unreliable place for keep this data
|
||||
Mem_Copy((byte *)input, image.tempbuffer, out_size );
|
||||
if( ignore_mips ) image.num_mips = 1;
|
||||
if( texture ) Mem_Free( texture );
|
||||
image.size = out_size; // merge out size
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Image_LoadVTF
|
||||
=============
|
||||
*/
|
||||
bool Image_LoadVTF( const char *name, const byte *buffer, size_t filesize )
|
||||
{
|
||||
vtf_t vtf;
|
||||
byte *fin;
|
||||
string shortname;
|
||||
bool oldformat = false;
|
||||
int i, flags, vtfFormat;
|
||||
uint hdrSize, resSize, lowResSize;
|
||||
|
||||
fin = (byte *)buffer;
|
||||
Mem_Copy( &vtf, fin, sizeof( vtf ));
|
||||
hdrSize = LittleLong( vtf.hdr_size );
|
||||
|
||||
if( LittleLong( vtf.ident ) != VTFHEADER ) return false; // it's not a dds file, just skip it
|
||||
FS_FileBase( name, shortname );
|
||||
|
||||
// bounds check
|
||||
i = LittleLong( vtf.ver_major );
|
||||
if( i != VTF_VERSION )
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadVTF: %s has wrong ver (%i should be %i)\n", shortname, i, VTF_VERSION );
|
||||
return false;
|
||||
}
|
||||
|
||||
i = LittleLong( vtf.ver_minor );
|
||||
if( i == VTF_SUBVERSION0 && vtf.hdr_size == 64 )
|
||||
{
|
||||
MsgDev( D_NOTE, "Image_LoadVTF: ver 7.0 from hl2 beta\n" );
|
||||
oldformat = true; // missing envmap for cubemap images
|
||||
}
|
||||
else if( i == VTF_SUBVERSION1 && vtf.hdr_size == 64 )
|
||||
MsgDev( D_NOTE, "Image_LoadVTF: ver 7.1 without HDR\n" );
|
||||
else if( i == VTF_SUBVERSION2 && vtf.hdr_size == sizeof( vtf_t ))
|
||||
MsgDev( D_NOTE, "Image_LoadVTF: ver 7.2 with HDR\n" );
|
||||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadVTF: file (%s) has wrong subversion %i\n", shortname, i );
|
||||
return false;
|
||||
}
|
||||
|
||||
image.width = LittleShort( vtf.width );
|
||||
image.height = LittleShort( vtf.height );
|
||||
if(!Image_ValidSize( name )) return false;
|
||||
|
||||
// translate VF_flags into IMAGE_flags
|
||||
flags = LittleLong( vtf.flags );
|
||||
if((flags & VF_ONEBITALPHA) || (flags & VF_EIGHTBITALPHA))
|
||||
image.flags |= IMAGE_HAVE_ALPHA;
|
||||
if( flags & VF_ENVMAP ) image.flags |= IMAGE_CUBEMAP;
|
||||
|
||||
vtfFormat = LittleLong( vtf.imageFormat );
|
||||
image.num_layers = LittleLong( vtf.num_frames );
|
||||
image.type = Image_VTFFormat( vtfFormat );
|
||||
image.num_mips = LittleLong( vtf.numMipLevels );
|
||||
|
||||
if( image.type == PF_UNKNOWN )
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadVTF: file (%s) has unknown format %i\n", shortname, vtfFormat );
|
||||
return false;
|
||||
}
|
||||
|
||||
lowResSize = Image_VTFCalcLowResSize( &vtf);
|
||||
resSize = Image_VTFCalcImageSize( &vtf, (i == 0));
|
||||
i = hdrSize + lowResSize + resSize;
|
||||
|
||||
if( filesize != i )
|
||||
{
|
||||
MsgDev( D_ERROR, "Image_LoadVTF: %s have invalid size (%i, should be %i)\n", name, filesize, i );
|
||||
return false;
|
||||
}
|
||||
if( image.type == PF_RGBA_32 ) Msg("image PF_RGBA_32\n" );
|
||||
fin += hdrSize + lowResSize; // skip lowRes image
|
||||
image.size = resSize;
|
||||
|
||||
// convert VTF to DXT
|
||||
Image_VTFSwapBuffer( &vtf, fin, resSize, oldformat );
|
||||
|
||||
if( Image_ForceDecompress())
|
||||
{
|
||||
int offset, numsides = 1;
|
||||
uint target = 1;
|
||||
byte *buf = fin;
|
||||
|
||||
// if hardware loader is absent or image not power of two
|
||||
// or user want load current side from cubemap we run software decompressing
|
||||
if( image.flags & IMAGE_CUBEMAP ) numsides = 6;
|
||||
Image_SetPixelFormat( image.width, image.height, image.num_layers ); // setup
|
||||
image.size = image.ptr = 0;
|
||||
if( image.cmd_flags & IL_IGNORE_MIPS )
|
||||
image.cur_mips = 1;
|
||||
else image.cur_mips = image.num_mips;
|
||||
image.num_mips = 1; // defaulting to one mip
|
||||
|
||||
for( i = 0, offset = 0; i < numsides; i++, buf += offset )
|
||||
{
|
||||
Image_SetPixelFormat( image.curwidth, image.curheight, image.curdepth );
|
||||
offset = image.SizeOfFile; // move pointer
|
||||
|
||||
Image_DecompressDDS( buf, target + i );
|
||||
}
|
||||
// now we can change type to RGBA
|
||||
if( image.hint != IL_HINT_NO ) image.flags &= ~IMAGE_CUBEMAP; // side extracted
|
||||
image.type = PF_RGBA_32;
|
||||
}
|
||||
else
|
||||
{
|
||||
// vtf files will be uncompressed on a render. requires minimal of info for set this
|
||||
image.rgba = Mem_Alloc( Sys.imagepool, image.size );
|
||||
Mem_Copy( image.rgba, fin, image.size );
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -384,25 +384,22 @@ bool Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
|
|||
pixels = image.width * image.height;
|
||||
image.num_layers = 1;
|
||||
|
||||
if(image.hint != IL_HINT_Q1 && filesize >= (int)sizeof(mip) + ((pixels * 85)>>6) + sizeof(short) + 768)
|
||||
if( image.hint != IL_HINT_Q1 && filesize >= (int)sizeof(mip) + ((pixels * 85)>>6) + sizeof(short) + 768)
|
||||
{
|
||||
// half-life 1.0.0.1 mip version with palette
|
||||
fin = (byte *)buffer + mip.offsets[0];
|
||||
pal = (byte *)buffer + mip.offsets[0] + (((image.width * image.height) * 85)>>6);
|
||||
numcolors = BuffLittleShort( pal );
|
||||
if(numcolors != 256) pal = NULL; // corrupted mip ?
|
||||
if( numcolors != 256 ) pal = NULL; // corrupted mip ?
|
||||
else pal += sizeof(short); // skip colorsize
|
||||
// detect rendermode
|
||||
if( name[0] == '{' )
|
||||
if( com.strchr( name, '{' ))
|
||||
{
|
||||
rendermode = LUMP_TRANSPARENT;
|
||||
|
||||
// qlumpy used this color for transparent textures, otherwise it's decals
|
||||
if(pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255)
|
||||
rendermode = LUMP_TRANSPARENT;
|
||||
else
|
||||
{
|
||||
rendermode = LUMP_DECAL;
|
||||
image.flags |= IMAGE_COLORINDEX;
|
||||
}
|
||||
if( pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255 );
|
||||
else image.flags |= IMAGE_COLORINDEX;
|
||||
image.flags |= IMAGE_HAVE_ALPHA;
|
||||
}
|
||||
else rendermode = LUMP_NORMAL;
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
#include <io.h>
|
||||
#include <time.h>
|
||||
#include <winreg.h>
|
||||
#include <math.h>
|
||||
|
||||
#define LAUNCH_DLL // skip alias names
|
||||
#include "basetypes.h"
|
||||
#define LAUNCH_DLL // ignore alias names
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
|
||||
#define XASH_VERSION 0.51f // current version will be shared across gameinfo struct
|
||||
|
@ -232,6 +233,25 @@ char *va(const char *format, ...);
|
|||
long Com_RandomLong( long lMin, long lMax );
|
||||
float Com_RandomFloat( float fMin, float fMax );
|
||||
|
||||
//
|
||||
// math.c
|
||||
//
|
||||
void Com_BuildSqrtTable( void );
|
||||
void Com_BuildSinCosTable( void );
|
||||
|
||||
float com_sqrt( float x );
|
||||
float amd_sqrt( float x );
|
||||
float sse_sqrt( float x );
|
||||
|
||||
_inline float sqrtf( float x ) { return ((float)sqrt((double)x)); }
|
||||
_inline float sinf( float x ) { return ((float)sin((double)x)); }
|
||||
_inline float asinf( float x ) { return ((float)asin((double)x)); }
|
||||
_inline float cosf( float x ) { return ((float)cos((double)x)); }
|
||||
_inline float acosf( float x ) { return ((float)acos((double)x)); }
|
||||
_inline float tanf( float x ) { return ((float)tan((double)x)); }
|
||||
_inline float atan2f( float x, float y ) { return ((float)atan2((double)x,(double)y)); }
|
||||
void SinCos( float radians, float *sine, float *cosine );
|
||||
|
||||
//
|
||||
// memlib.c
|
||||
//
|
||||
|
@ -240,8 +260,15 @@ void Memory_Shutdown( void );
|
|||
void Memory_Init_Commands( void );
|
||||
void _mem_move(byte *poolptr, void **dest, void *src, size_t size, const char *filename, int fileline);
|
||||
void *_mem_realloc(byte *poolptr, void *memptr, size_t size, const char *filename, int fileline);
|
||||
void _mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
|
||||
void _mem_set(void *dest, int set, size_t size, const char *filename, int fileline);
|
||||
void _com_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
|
||||
void _crt_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
|
||||
void _asm_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
|
||||
void _mmx_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
|
||||
void _amd_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
|
||||
void _com_mem_set(void *dest, int set, size_t size, const char *filename, int fileline);
|
||||
void _crt_mem_set(void *dest, int set, size_t size, const char *filename, int fileline);
|
||||
void _asm_mem_set(void* dest, int set, size_t size, const char *filename, int fileline);
|
||||
void _mmx_mem_set(void* dest, int set, size_t size, const char *filename, int fileline);
|
||||
void *_mem_alloc(byte *poolptr, size_t size, const char *filename, int fileline);
|
||||
byte *_mem_allocpool(const char *name, const char *filename, int fileline);
|
||||
void _mem_freepool(byte **poolptr, const char *filename, int fileline);
|
||||
|
@ -263,8 +290,8 @@ bool _is_allocated( byte *poolptr, void *data );
|
|||
#define Mem_FreePool(pool) _mem_freepool(pool, __FILE__, __LINE__)
|
||||
#define Mem_EmptyPool(pool) _mem_emptypool(pool, __FILE__, __LINE__)
|
||||
#define Mem_Move(pool, dest, src, size ) _mem_move(pool, dest, src, size, __FILE__, __LINE__)
|
||||
#define Mem_Copy(dest, src, size ) _mem_copy(dest, src, size, __FILE__, __LINE__)
|
||||
#define Mem_Set(dest, val, size ) _mem_set(dest, val, size, __FILE__, __LINE__)
|
||||
#define Mem_Copy(dest, src, size ) com.memcpy(dest, src, size, __FILE__, __LINE__)
|
||||
#define Mem_Set(dest, val, size ) com.memset(dest, val, size, __FILE__, __LINE__)
|
||||
#define Mem_CreateArray( p, s, n ) _mem_alloc_array( p, s, n, __FILE__, __LINE__)
|
||||
#define Mem_RemoveArray( array ) _mem_free_array( array, __FILE__, __LINE__)
|
||||
#define Mem_AllocElement( array ) _mem_alloc_array_element( array, __FILE__, __LINE__)
|
||||
|
|
695
launch/memlib.c
695
launch/memlib.c
|
@ -14,6 +14,12 @@
|
|||
#define MEMHEADER_SENTINEL1 0xDEADF00D
|
||||
#define MEMHEADER_SENTINEL2 0xDF
|
||||
|
||||
#define TINY_BLOCK_COPY 64 // upper limit for movsd type copy
|
||||
#define IN_CACHE_COPY 64 * 1024 // upper limit for movq/movq copy w/SW prefetch
|
||||
#define UNCACHED_COPY 197 * 1024 // upper limit for movq/movntq w/SW prefetch
|
||||
#define BLOCK_PREFETCH_COPY infinity // no limit for movq/movntq w/block prefetch
|
||||
#define CACHEBLOCK 80h // number of 64-byte blocks (cache lines) for block prefetch
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PREFETCH_READ, // prefetch assuming that buffer is used for reading only
|
||||
|
@ -57,7 +63,7 @@ typedef struct mempool_s
|
|||
struct mempool_s *next; // linked into global mempool list
|
||||
const char *filename; // file name and line where Mem_AllocPool was called
|
||||
int fileline;
|
||||
char name[MAX_QPATH]; // name of the pool
|
||||
char name[32]; // name of the pool
|
||||
uint sentinel2; // should always be MEMHEADER_SENTINEL1
|
||||
} mempool_t;
|
||||
|
||||
|
@ -81,6 +87,427 @@ typedef struct memarray_s
|
|||
|
||||
mempool_t *poolchain = NULL; // critical stuff
|
||||
|
||||
// crt safe version
|
||||
void _crt_mem_copy( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
memcpy( dest, src, count );
|
||||
}
|
||||
|
||||
// q_memcpy
|
||||
void _com_mem_copy( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
if((((long)dest | (long)src | count) & 3) == 0 )
|
||||
{
|
||||
count>>=2;
|
||||
for( i = 0; i < count; i++ )
|
||||
((int *)dest)[i] = ((int *)src)[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < count; i++ )
|
||||
((byte *)dest)[i] = ((byte *)src)[i];
|
||||
}
|
||||
}
|
||||
|
||||
// mmx version
|
||||
void _mmx_mem_copy8B( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
_asm
|
||||
{
|
||||
mov esi, src
|
||||
mov edi, dest
|
||||
mov ecx, count
|
||||
shr ecx, 3 // 8 bytes per iteration
|
||||
loop1:
|
||||
movq mm1, [ESI] // read in source data
|
||||
movntq [EDI], mm1 // non-temporal stores
|
||||
|
||||
add esi, 8
|
||||
add edi, 8
|
||||
dec ecx
|
||||
jnz loop1
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
void _mmx_mem_copy64B( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
_asm
|
||||
{
|
||||
mov esi, src
|
||||
mov edi, dest
|
||||
mov ecx, count
|
||||
shr ecx, 6 // 64 bytes per iteration
|
||||
loop1:
|
||||
prefetchnta 64[ESI] // prefetch next loop, non-temporal
|
||||
prefetchnta 96[ESI]
|
||||
|
||||
movq mm1, [ESI] // read in source data
|
||||
movq mm2, 8[ESI]
|
||||
movq mm3, 16[ESI]
|
||||
movq mm4, 24[ESI]
|
||||
movq mm5, 32[ESI]
|
||||
movq mm6, 40[ESI]
|
||||
movq mm7, 48[ESI]
|
||||
movq mm0, 56[ESI]
|
||||
|
||||
movntq [EDI], mm1 // non-temporal stores
|
||||
movntq 8[EDI], mm2
|
||||
movntq 16[EDI], mm3
|
||||
movntq 24[EDI], mm4
|
||||
movntq 32[EDI], mm5
|
||||
movntq 40[EDI], mm6
|
||||
movntq 48[EDI], mm7
|
||||
movntq 56[EDI], mm0
|
||||
|
||||
add esi, 64
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz loop1
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
void _mmx_mem_copy2kB( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
byte buf[2048];
|
||||
byte *tbuf = &buf[0];
|
||||
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
mov esi, src
|
||||
mov ebx, count
|
||||
shr ebx, 11 // 2048 bytes at a time
|
||||
mov edi, dest
|
||||
loop2k:
|
||||
push edi // copy 2k into temporary buffer
|
||||
mov edi, tbuf
|
||||
mov ecx, 32
|
||||
loopMemToL1:
|
||||
prefetchnta 64[ESI] // prefetch next loop, non-temporal
|
||||
prefetchnta 96[ESI]
|
||||
|
||||
movq mm1, [ESI] // read in source data
|
||||
movq mm2, 8[ESI]
|
||||
movq mm3, 16[ESI]
|
||||
movq mm4, 24[ESI]
|
||||
movq mm5, 32[ESI]
|
||||
movq mm6, 40[ESI]
|
||||
movq mm7, 48[ESI]
|
||||
movq mm0, 56[ESI]
|
||||
|
||||
movq [EDI], mm1 // store into L1
|
||||
movq 8[EDI], mm2
|
||||
movq 16[EDI], mm3
|
||||
movq 24[EDI], mm4
|
||||
movq 32[EDI], mm5
|
||||
movq 40[EDI], mm6
|
||||
movq 48[EDI], mm7
|
||||
movq 56[EDI], mm0
|
||||
add esi, 64
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz loopMemToL1
|
||||
|
||||
pop edi // now copy from L1 to system memory
|
||||
push esi
|
||||
mov esi, tbuf
|
||||
mov ecx, 32
|
||||
loopL1ToMem:
|
||||
movq mm1, [ESI] // read in source data from L1
|
||||
movq mm2, 8[ESI]
|
||||
movq mm3, 16[ESI]
|
||||
movq mm4, 24[ESI]
|
||||
movq mm5, 32[ESI]
|
||||
movq mm6, 40[ESI]
|
||||
movq mm7, 48[ESI]
|
||||
movq mm0, 56[ESI]
|
||||
|
||||
movntq [EDI], mm1 // Non-temporal stores
|
||||
movntq 8[EDI], mm2
|
||||
movntq 16[EDI], mm3
|
||||
movntq 24[EDI], mm4
|
||||
movntq 32[EDI], mm5
|
||||
movntq 40[EDI], mm6
|
||||
movntq 48[EDI], mm7
|
||||
movntq 56[EDI], mm0
|
||||
|
||||
add esi, 64
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz loopL1ToMem
|
||||
|
||||
pop esi // do next 2k block
|
||||
dec ebx
|
||||
jnz loop2k
|
||||
pop ebx
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
void _mmx_mem_copy( void *dest, const void *src, size_t size, const char *filename, int fileline )
|
||||
{
|
||||
if( src == NULL || size <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
// if copying more than 16 bytes and we can copy 8 byte aligned
|
||||
if( size > 16 && !(((int)dest ^ (int)src) & 7 ))
|
||||
{
|
||||
byte *dest_p = (byte *)dest;
|
||||
byte *src_p = (byte *)src;
|
||||
int count = ((int)dest_p) & 7;
|
||||
|
||||
// copy up to the first 8 byte aligned boundary
|
||||
_crt_mem_copy( dest_p, src_p, count, filename, fileline );
|
||||
dest_p += count;
|
||||
src_p += count;
|
||||
count = size - count;
|
||||
|
||||
// if there are multiple blocks of 2kB
|
||||
if( count & ~4095 )
|
||||
{
|
||||
_mmx_mem_copy2kB( dest_p, src_p, count, filename, fileline );
|
||||
src_p += (count & ~2047);
|
||||
dest_p += (count & ~2047);
|
||||
count &= 2047;
|
||||
}
|
||||
// if there are blocks of 64 bytes
|
||||
if( count & ~63 )
|
||||
{
|
||||
_mmx_mem_copy64B( dest_p, src_p, count, filename, fileline );
|
||||
src_p += (count & ~63);
|
||||
dest_p += (count & ~63);
|
||||
count &= 63;
|
||||
}
|
||||
|
||||
// if there are blocks of 8 bytes
|
||||
if( count & ~7 )
|
||||
{
|
||||
_mmx_mem_copy8B( dest_p, src_p, count, filename, fileline );
|
||||
src_p += (count & ~7);
|
||||
dest_p += (count & ~7);
|
||||
count &= 7;
|
||||
}
|
||||
// copy any remaining bytes
|
||||
_crt_mem_copy( dest_p, src_p, count, filename, fileline );
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the regular one if we cannot copy 8 byte aligned
|
||||
_crt_mem_copy( dest, src, size, filename, fileline );
|
||||
}
|
||||
}
|
||||
|
||||
void _amd_mem_copy( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL ) Sys_Error( "Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
__asm
|
||||
{
|
||||
mov ecx, [count] // number of bytes to copy
|
||||
mov edi, [dest] // destination
|
||||
mov esi, [src] // source
|
||||
mov ebx, ecx // keep a copy of count
|
||||
|
||||
cld
|
||||
cmp ecx, TINY_BLOCK_COPY
|
||||
jb $memcopy_ic_3 // tiny? skip mmx copy
|
||||
|
||||
cmp ecx, 32*1024 // don't align between 32k-64k because
|
||||
jbe $memcopy_do_align // it appears to be slower
|
||||
cmp ecx, 64*1024
|
||||
jbe $memcopy_align_done
|
||||
$memcopy_do_align:
|
||||
mov ecx, 8 // a trick that's faster than rep movsb...
|
||||
sub ecx, edi // align destination to qword
|
||||
and ecx, 111b // get the low bits
|
||||
sub ebx, ecx // update copy count
|
||||
neg ecx // set up to jump into the array
|
||||
add ecx, offset $memcopy_align_done
|
||||
jmp ecx // jump to array of movsb's
|
||||
|
||||
align 4
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
movsb
|
||||
|
||||
$memcopy_align_done: // destination is dword aligned
|
||||
mov ecx, ebx // number of bytes left to copy
|
||||
shr ecx, 6 // get 64-byte block count
|
||||
jz $memcopy_ic_2 // finish the last few bytes
|
||||
|
||||
cmp ecx, IN_CACHE_COPY/64 // too big 4 cache? use uncached copy
|
||||
jae $memcopy_uc_test
|
||||
|
||||
align 16
|
||||
$memcopy_ic_1: // 64-byte block copies, in-cache copy
|
||||
|
||||
prefetchnta [esi + (200*64/34+192)] // start reading ahead
|
||||
|
||||
movq mm0, [esi+0] // read 64 bits
|
||||
movq mm1, [esi+8]
|
||||
movq [edi+0], mm0 // write 64 bits
|
||||
movq [edi+8], mm1 // NOTE: the normal movq writes the
|
||||
movq mm2, [esi+16] // data to cache; a cache line will be
|
||||
movq mm3, [esi+24] // allocated as needed, to store the data
|
||||
movq [edi+16], mm2
|
||||
movq [edi+24], mm3
|
||||
movq mm0, [esi+32]
|
||||
movq mm1, [esi+40]
|
||||
movq [edi+32], mm0
|
||||
movq [edi+40], mm1
|
||||
movq mm2, [esi+48]
|
||||
movq mm3, [esi+56]
|
||||
movq [edi+48], mm2
|
||||
movq [edi+56], mm3
|
||||
|
||||
add esi, 64 // update source pointer
|
||||
add edi, 64 // update destination pointer
|
||||
dec ecx // count down
|
||||
jnz $memcopy_ic_1 // last 64-byte block?
|
||||
|
||||
$memcopy_ic_2:
|
||||
mov ecx, ebx // has valid low 6 bits of the byte count
|
||||
$memcopy_ic_3:
|
||||
shr ecx, 2 // dword count
|
||||
and ecx, 1111b // only look at the "remainder" bits
|
||||
neg ecx // set up to jump into the array
|
||||
add ecx, offset $memcopy_last_few
|
||||
jmp ecx // jump to array of movsd's
|
||||
|
||||
$memcopy_uc_test:
|
||||
cmp ecx, UNCACHED_COPY/64 // big enough? use block prefetch copy
|
||||
jae $memcopy_bp_1
|
||||
|
||||
$memcopy_64_test:
|
||||
or ecx, ecx // tail end of block prefetch will jump here
|
||||
jz $memcopy_ic_2 // no more 64-byte blocks left
|
||||
|
||||
align 16
|
||||
$memcopy_uc_1: // 64-byte blocks, uncached copy
|
||||
|
||||
prefetchnta [esi + (200*64/34+192)] // start reading ahead
|
||||
|
||||
movq mm0,[esi+0] // read 64 bits
|
||||
add edi,64 // update destination pointer
|
||||
movq mm1,[esi+8]
|
||||
add esi,64 // update source pointer
|
||||
movq mm2,[esi-48]
|
||||
movntq [edi-64], mm0 // write 64 bits, bypassing the cache
|
||||
movq mm0,[esi-40] // NOTE: movntq also prevents the CPU
|
||||
movntq [edi-56], mm1 // from READING the destination address
|
||||
movq mm1,[esi-32] // into the cache, only to be over-written
|
||||
movntq [edi-48], mm2 // so that also helps performance
|
||||
movq mm2,[esi-24]
|
||||
movntq [edi-40], mm0
|
||||
movq mm0,[esi-16]
|
||||
movntq [edi-32], mm1
|
||||
movq mm1,[esi-8]
|
||||
movntq [edi-24], mm2
|
||||
movntq [edi-16], mm0
|
||||
dec ecx
|
||||
movntq [edi-8], mm1
|
||||
jnz $memcopy_uc_1 // last 64-byte block?
|
||||
|
||||
jmp $memcopy_ic_2 // almost done
|
||||
|
||||
$memcopy_bp_1: // large blocks, block prefetch copy
|
||||
|
||||
cmp ecx, CACHEBLOCK // big enough to run another prefetch loop?
|
||||
jl $memcopy_64_test // no, back to regular uncached copy
|
||||
|
||||
mov eax, CACHEBLOCK / 2 // block prefetch loop, unrolled 2X
|
||||
add esi, CACHEBLOCK * 64 // move to the top of the block
|
||||
align 16
|
||||
$memcopy_bp_2:
|
||||
mov edx, [esi-64] // grab one address per cache line
|
||||
mov edx, [esi-128] // grab one address per cache line
|
||||
sub esi, 128 // go reverse order
|
||||
dec eax // count down the cache lines
|
||||
jnz $memcopy_bp_2 // keep grabbing more lines into cache
|
||||
|
||||
mov eax, CACHEBLOCK // now that it's in cache, do the copy
|
||||
align 16
|
||||
$memcopy_bp_3:
|
||||
movq mm0, [esi ] // read 64 bits
|
||||
movq mm1, [esi+ 8]
|
||||
movq mm2, [esi+16]
|
||||
movq mm3, [esi+24]
|
||||
movq mm4, [esi+32]
|
||||
movq mm5, [esi+40]
|
||||
movq mm6, [esi+48]
|
||||
movq mm7, [esi+56]
|
||||
add esi, 64 // update source pointer
|
||||
movntq [edi ], mm0 // write 64 bits, bypassing cache
|
||||
movntq [edi+ 8], mm1 // NOTE: movntq also prevents the CPU
|
||||
movntq [edi+16], mm2 // from READING the destination address
|
||||
movntq [edi+24], mm3 // into the cache, only to be over-written,
|
||||
movntq [edi+32], mm4 // so that also helps performance
|
||||
movntq [edi+40], mm5
|
||||
movntq [edi+48], mm6
|
||||
movntq [edi+56], mm7
|
||||
add edi, 64 // update dest pointer
|
||||
|
||||
dec eax // count down
|
||||
|
||||
jnz $memcopy_bp_3 // keep copying
|
||||
sub ecx, CACHEBLOCK // update the 64-byte block count
|
||||
jmp $memcopy_bp_1 // keep processing chunks
|
||||
|
||||
align 4
|
||||
movsd
|
||||
movsd // perform last 1-15 dword copies
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd // perform last 1-7 dword copies
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
|
||||
$memcopy_last_few: // dword aligned from before movsd's
|
||||
mov ecx, ebx // has valid low 2 bits of the byte count
|
||||
and ecx, 11b // the last few cows must come home
|
||||
jz $memcopy_final // no more, let's leave
|
||||
rep movsb // the last 1, 2, or 3 bytes
|
||||
|
||||
$memcopy_final:
|
||||
emms // clean up the MMX state
|
||||
sfence // flush the write buffer
|
||||
mov eax, [dest] // ret value = destination pointer
|
||||
}
|
||||
}
|
||||
|
||||
void _mem_prefetch( const void *s, const uint bytes, e_prefetch type )
|
||||
{
|
||||
// write buffer prefetching is performed only if
|
||||
|
@ -117,7 +544,59 @@ skipClump:
|
|||
}
|
||||
}
|
||||
|
||||
void _mem_copy( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
void _mem_copy_dword( uint *dest, const uint constant, const uint count )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov edx,dest
|
||||
mov eax,constant
|
||||
mov ecx,count
|
||||
and ecx,~7
|
||||
jz padding
|
||||
sub ecx,8
|
||||
jmp loopu
|
||||
align 16
|
||||
loopu:
|
||||
test [edx+ecx*4 + 28],ebx // fetch next block destination to L1 cache
|
||||
mov [edx+ecx*4 + 0],eax
|
||||
mov [edx+ecx*4 + 4],eax
|
||||
mov [edx+ecx*4 + 8],eax
|
||||
mov [edx+ecx*4 + 12],eax
|
||||
mov [edx+ecx*4 + 16],eax
|
||||
mov [edx+ecx*4 + 20],eax
|
||||
mov [edx+ecx*4 + 24],eax
|
||||
mov [edx+ecx*4 + 28],eax
|
||||
sub ecx,8
|
||||
jge loopu
|
||||
padding: mov ecx,count
|
||||
mov ebx,ecx
|
||||
and ecx,7
|
||||
jz outta
|
||||
and ebx,~7
|
||||
lea edx,[edx+ebx*4] // advance dest pointer
|
||||
test [edx+0],eax // fetch destination to L1 cache
|
||||
cmp ecx,4
|
||||
jl skip4
|
||||
mov [edx+0],eax
|
||||
mov [edx+4],eax
|
||||
mov [edx+8],eax
|
||||
mov [edx+12],eax
|
||||
add edx,16
|
||||
sub ecx,4
|
||||
skip4: cmp ecx,2
|
||||
jl skip2
|
||||
mov [edx+0],eax
|
||||
mov [edx+4],eax
|
||||
add edx,8
|
||||
sub ecx,2
|
||||
skip2: cmp ecx,1
|
||||
jl outta
|
||||
mov [edx+0],eax
|
||||
outta:
|
||||
}
|
||||
}
|
||||
|
||||
void _asm_mem_copy( void *dest, const void *src, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
if( src == NULL || count <= 0 ) return; // nothing to copy
|
||||
if( dest == NULL) Sys_Error("Mem_Copy: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
@ -221,10 +700,186 @@ outta:
|
|||
}
|
||||
}
|
||||
|
||||
void _mem_set( void *dest, int set, size_t size, const char *filename, int fileline )
|
||||
void _crt_mem_set( void *dest, int set, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
// FIXME: implement
|
||||
Sys_Error("_mem_set: not implemented (called at %s:%i)\n", filename, fileline );
|
||||
if( dest == NULL ) Sys_Error( "Mem_Set: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
memset( dest, set, count );
|
||||
}
|
||||
|
||||
void _com_mem_set( void *dest, int set, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( dest == NULL ) Sys_Error( "Mem_Set: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if( !( ((long)dest | count) & 3 ))
|
||||
{
|
||||
count >>= 2;
|
||||
set = (set<<0) | (set<<8) | (set<<16) | (set<<24);
|
||||
for( i = 0; i < count; i++ ) ((int *)dest)[i] = set;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < count; i++ ) ((byte *)dest)[i] = set;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _asm_mem_set( void* dest, int set, size_t count, const char *filename, int fileline )
|
||||
{
|
||||
uint fillval;
|
||||
|
||||
if( dest == NULL ) Sys_Error( "Mem_Set: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if( count < 8 )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov edx,dest
|
||||
mov eax, set
|
||||
mov ah,al
|
||||
mov ebx,eax
|
||||
and ebx, 0xffff
|
||||
shl eax,16
|
||||
add eax,ebx // eax now contains pattern
|
||||
mov ecx,count
|
||||
cmp ecx,4
|
||||
jl skip4
|
||||
mov [edx],eax // copy first dword
|
||||
add edx,4
|
||||
sub ecx,4
|
||||
skip4: cmp ecx,2
|
||||
jl skip2
|
||||
mov word ptr [edx],ax // copy 2 bytes
|
||||
add edx,2
|
||||
sub ecx,2
|
||||
skip2: cmp ecx,0
|
||||
je skip1
|
||||
mov byte ptr [edx],al // copy single byte
|
||||
skip1:
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fillval = set;
|
||||
fillval = fillval|(fillval<<8);
|
||||
fillval = fillval|(fillval<<16); // fill dword with 8-bit pattern
|
||||
|
||||
_mem_copy_dword((uint *)(dest), fillval, count / 4 );
|
||||
|
||||
__asm // padding of 0-3 bytes
|
||||
{
|
||||
mov ecx,count
|
||||
mov eax,ecx
|
||||
and ecx,3
|
||||
jz skipA
|
||||
and eax,~3
|
||||
mov ebx,dest
|
||||
add ebx,eax
|
||||
mov eax,fillval
|
||||
cmp ecx,2
|
||||
jl skipB
|
||||
mov word ptr [ebx],ax
|
||||
cmp ecx,2
|
||||
je skipA
|
||||
mov byte ptr [ebx+2],al
|
||||
jmp skipA
|
||||
skipB:
|
||||
cmp ecx,0
|
||||
je skipA
|
||||
mov byte ptr [ebx],al
|
||||
skipA:
|
||||
}
|
||||
}
|
||||
|
||||
void _mmx_mem_set( void* dest, int set, size_t size, const char *filename, int fileline )
|
||||
{
|
||||
union
|
||||
{
|
||||
byte bytes[8];
|
||||
WORD words[4];
|
||||
DWORD dwords[2];
|
||||
} dat;
|
||||
|
||||
byte *dst = (byte *)dest;
|
||||
int count = size;
|
||||
|
||||
if( dest == NULL ) Sys_Error( "Mem_Set: dest == NULL (called at %s:%i)\n", filename, fileline );
|
||||
|
||||
while( count > 0 && (((int)dst) & 7) )
|
||||
{
|
||||
*dst = set;
|
||||
dst++;
|
||||
count--;
|
||||
}
|
||||
if( !count ) return;
|
||||
|
||||
dat.bytes[0] = set;
|
||||
dat.bytes[1] = set;
|
||||
dat.words[1] = dat.words[0];
|
||||
dat.dwords[1] = dat.dwords[0];
|
||||
|
||||
if( count >= 64 )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov edi, dst
|
||||
mov ecx, count
|
||||
shr ecx, 6 // 64 bytes per iteration
|
||||
movq mm1, dat // Read in source data
|
||||
movq mm2, mm1
|
||||
movq mm3, mm1
|
||||
movq mm4, mm1
|
||||
movq mm5, mm1
|
||||
movq mm6, mm1
|
||||
movq mm7, mm1
|
||||
movq mm0, mm1
|
||||
loop1:
|
||||
movntq 0[EDI], mm1 // Non-temporal stores
|
||||
movntq 8[EDI], mm2
|
||||
movntq 16[EDI], mm3
|
||||
movntq 24[EDI], mm4
|
||||
movntq 32[EDI], mm5
|
||||
movntq 40[EDI], mm6
|
||||
movntq 48[EDI], mm7
|
||||
movntq 56[EDI], mm0
|
||||
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz loop1
|
||||
}
|
||||
dst += ( count & ~63 );
|
||||
count &= 63;
|
||||
}
|
||||
|
||||
if ( count >= 8 )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov edi, dst
|
||||
mov ecx, count
|
||||
shr ecx, 3 // 8 bytes per iteration
|
||||
movq mm1, dat // Read in source data
|
||||
loop2:
|
||||
movntq 0[EDI], mm1 // Non-temporal stores
|
||||
|
||||
add edi, 8
|
||||
dec ecx
|
||||
jnz loop2
|
||||
}
|
||||
dst += (count & ~7);
|
||||
count &= 7;
|
||||
}
|
||||
|
||||
while( count > 0 )
|
||||
{
|
||||
*dst = set;
|
||||
dst++;
|
||||
count--;
|
||||
}
|
||||
|
||||
__asm
|
||||
{
|
||||
emms
|
||||
}
|
||||
}
|
||||
|
||||
void *_mem_alloc( byte *poolptr, size_t size, const char *filename, int fileline )
|
||||
|
@ -275,7 +930,7 @@ loopcontinue:;
|
|||
pool->realsize += sizeof(memclump_t);
|
||||
clump = malloc(sizeof(memclump_t));
|
||||
if (clump == NULL) Sys_Error("Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline);
|
||||
memset(clump, 0, sizeof(memclump_t));
|
||||
com.memset( clump, 0, sizeof( memclump_t ), filename, fileline );
|
||||
*clumpchainpointer = clump;
|
||||
clump->sentinel1 = MEMCLUMP_SENTINEL;
|
||||
clump->sentinel2 = MEMCLUMP_SENTINEL;
|
||||
|
@ -311,9 +966,9 @@ choseclump:
|
|||
mem->prev = NULL;
|
||||
pool->chain = mem;
|
||||
if (mem->next) mem->next->prev = mem;
|
||||
memset((void *)((byte *) mem + sizeof(memheader_t)), 0, mem->size);
|
||||
com.memset((void *)((byte *) mem + sizeof(memheader_t)), 0, mem->size, filename, fileline );
|
||||
|
||||
MsgDev(D_MEMORY, "Mem_Alloc: \"%s\"[%s], at (%s:%i)\n", pool->name, com_pretifymem( size, 1 ), filename, fileline );
|
||||
MsgDev( D_MEMORY, "Mem_Alloc: \"%s\"[%s], at (%s:%i)\n", pool->name, com_pretifymem( size, 1 ), filename, fileline );
|
||||
|
||||
return (void *)((byte *) mem + sizeof(memheader_t));
|
||||
}
|
||||
|
@ -364,8 +1019,8 @@ static void _mem_freeblock(memheader_t *mem, const char *filename, int fileline)
|
|||
break;
|
||||
}
|
||||
}
|
||||
pool->realsize -= sizeof(memclump_t);
|
||||
memset(clump, 0xBF, sizeof(memclump_t));
|
||||
pool->realsize -= sizeof( memclump_t );
|
||||
com.memset( clump, 0xBF, sizeof( memclump_t ), filename, fileline );
|
||||
free( clump );
|
||||
}
|
||||
else
|
||||
|
@ -403,7 +1058,7 @@ void *_mem_realloc(byte *poolptr, void *memptr, size_t size, const char *filenam
|
|||
// get size of old block
|
||||
memhdr = (memheader_t *)((byte *)memptr - sizeof(memheader_t));
|
||||
newsize = memhdr->size < size ? memhdr->size : size; // upper data can be trucnated!
|
||||
_mem_copy( nb, memptr, newsize, filename, fileline );
|
||||
com.memcpy( nb, memptr, newsize, filename, fileline );
|
||||
_mem_free( memptr, filename, fileline); // free unused old block
|
||||
}
|
||||
|
||||
|
@ -432,9 +1087,9 @@ void _mem_move(byte *poolptr, void **dest, void *src, size_t size, const char *f
|
|||
_mem_free( memptr, filename, fileline ); // release old buffer
|
||||
memptr = _mem_alloc( poolptr, size, filename, fileline ); // alloc new size
|
||||
}
|
||||
else memset( memptr, 0, size ); // no need to reallocate buffer
|
||||
else com.memset( memptr, 0x00, size, filename, fileline ); // no need to reallocate buffer
|
||||
|
||||
_mem_copy( memptr, src, size, filename, fileline ); // move memory...
|
||||
com.memcpy( memptr, src, size, filename, fileline ); // move memory...
|
||||
_mem_free( src, filename, fileline ); // ...and free old pointer
|
||||
|
||||
*dest = memptr;
|
||||
|
@ -444,8 +1099,8 @@ byte *_mem_allocpool(const char *name, const char *filename, int fileline)
|
|||
{
|
||||
mempool_t *pool;
|
||||
pool = (mempool_t *)malloc(sizeof(mempool_t));
|
||||
if (pool == NULL) Sys_Error("Mem_AllocPool: out of memory (allocpool at %s:%i)\n", filename, fileline);
|
||||
memset(pool, 0, sizeof(mempool_t));
|
||||
if( pool == NULL ) Sys_Error( "Mem_AllocPool: out of memory (allocpool at %s:%i)\n", filename, fileline );
|
||||
com.memset( pool, 0, sizeof(mempool_t), filename, fileline );
|
||||
|
||||
// fill header
|
||||
pool->sentinel1 = MEMHEADER_SENTINEL1;
|
||||
|
@ -459,7 +1114,7 @@ byte *_mem_allocpool(const char *name, const char *filename, int fileline)
|
|||
pool->next = poolchain;
|
||||
poolchain = pool;
|
||||
|
||||
MsgDev(D_MEMORY, "Create pool: \"%s\", at (%s:%i)\n", pool->name, filename, fileline );
|
||||
MsgDev( D_MEMORY, "Create pool: \"%s\", at (%s:%i)\n", pool->name, filename, fileline );
|
||||
return (byte *)((mempool_t *)pool);
|
||||
}
|
||||
|
||||
|
@ -480,10 +1135,10 @@ void _mem_freepool(byte **poolptr, const char *filename, int fileline)
|
|||
MsgDev(D_MEMORY, "Free pool: \"%s\", at (%s:%i)\n", pool->name, filename, fileline );
|
||||
|
||||
// free memory owned by the pool
|
||||
while (pool->chain) _mem_freeblock(pool->chain, filename, fileline);
|
||||
while (pool->chain) _mem_freeblock( pool->chain, filename, fileline );
|
||||
// free the pool itself
|
||||
memset(pool, 0xBF, sizeof(mempool_t));
|
||||
free(pool);
|
||||
com.memset( pool, 0xBF, sizeof( mempool_t ), filename, fileline );
|
||||
free( pool );
|
||||
*poolptr = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -580,7 +1235,7 @@ void *_mem_alloc_array_element( byte *arrayptr, const char *filename, int fileli
|
|||
l->arrays = _mem_alloc( l->mempool, l->maxarrays * sizeof(*l->arrays), filename, fileline);
|
||||
if (oldarrays)
|
||||
{
|
||||
_mem_copy(l->arrays, oldarrays, l->numarrays * sizeof(*l->arrays), filename, fileline);
|
||||
com.memcpy(l->arrays, oldarrays, l->numarrays * sizeof(*l->arrays), filename, fileline);
|
||||
_mem_free(oldarrays, filename, fileline);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ char *NET_ErrorString( void )
|
|||
|
||||
void NetadrToSockadr( netadr_t *a, struct sockaddr *s )
|
||||
{
|
||||
memset( s, 0, sizeof(*s));
|
||||
Mem_Set( s, 0, sizeof(*s));
|
||||
|
||||
if( a->type == NA_BROADCAST )
|
||||
{
|
||||
|
@ -170,15 +170,15 @@ void NetadrToSockadr( netadr_t *a, struct sockaddr *s )
|
|||
else if (a->type == NA_IPX)
|
||||
{
|
||||
((struct sockaddr_ipx *)s)->sa_family = AF_IPX;
|
||||
memcpy(((struct sockaddr_ipx *)s)->sa_netnum, &a->ipx[0], 4);
|
||||
memcpy(((struct sockaddr_ipx *)s)->sa_nodenum, &a->ipx[4], 6);
|
||||
Mem_Copy(((struct sockaddr_ipx *)s)->sa_netnum, &a->ipx[0], 4);
|
||||
Mem_Copy(((struct sockaddr_ipx *)s)->sa_nodenum, &a->ipx[4], 6);
|
||||
((struct sockaddr_ipx *)s)->sa_socket = a->port;
|
||||
}
|
||||
else if (a->type == NA_BROADCAST_IPX)
|
||||
{
|
||||
((struct sockaddr_ipx *)s)->sa_family = AF_IPX;
|
||||
memset(((struct sockaddr_ipx *)s)->sa_netnum, 0, 4);
|
||||
memset(((struct sockaddr_ipx *)s)->sa_nodenum, 0xff, 6);
|
||||
Mem_Set(((struct sockaddr_ipx *)s)->sa_netnum, 0, 4);
|
||||
Mem_Set(((struct sockaddr_ipx *)s)->sa_nodenum, 0xff, 6);
|
||||
((struct sockaddr_ipx *)s)->sa_socket = a->port;
|
||||
}
|
||||
}
|
||||
|
@ -195,8 +195,8 @@ void SockadrToNetadr( struct sockaddr *s, netadr_t *a )
|
|||
else if (s->sa_family == AF_IPX)
|
||||
{
|
||||
a->type = NA_IPX;
|
||||
memcpy(&a->ipx[0], ((struct sockaddr_ipx *)s)->sa_netnum, 4);
|
||||
memcpy(&a->ipx[4], ((struct sockaddr_ipx *)s)->sa_nodenum, 6);
|
||||
Mem_Copy(&a->ipx[0], ((struct sockaddr_ipx *)s)->sa_netnum, 4);
|
||||
Mem_Copy(&a->ipx[4], ((struct sockaddr_ipx *)s)->sa_nodenum, 6);
|
||||
a->port = ((struct sockaddr_ipx *)s)->sa_socket;
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ bool NET_StringToSockaddr( const char *s, struct sockaddr *sadr )
|
|||
int val;
|
||||
char copy[MAX_SYSPATH];
|
||||
|
||||
memset( sadr, 0, sizeof( *sadr ) );
|
||||
Mem_Set( sadr, 0, sizeof( *sadr ) );
|
||||
// check for an IPX address
|
||||
if(( com_strlen( s ) == 21 ) && ( s[8] == '.' ))
|
||||
{
|
||||
|
@ -329,7 +329,7 @@ bool NET_GetPacket( netadr_t *net_from, sizebuf_t *net_message )
|
|||
}
|
||||
if( net_socket == ip_socket )
|
||||
{
|
||||
memset( ((struct sockaddr_in *)&from)->sin_zero, 0, 8 );
|
||||
Mem_Set(((struct sockaddr_in *)&from)->sin_zero, 0, 8 );
|
||||
}
|
||||
|
||||
if( usingSocks && net_socket == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 )
|
||||
|
@ -398,7 +398,7 @@ void NET_SendPacket( int length, const void *data, netadr_t to )
|
|||
socksBuf[3] = 1; // address type: IPV4
|
||||
*(int *)&socksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr;
|
||||
*(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port;
|
||||
memcpy( &socksBuf[10], data, length );
|
||||
Mem_Copy( &socksBuf[10], data, length );
|
||||
ret = pSendTo( net_socket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) );
|
||||
}
|
||||
else ret = pSendTo( net_socket, data, length, 0, &addr, sizeof(addr) );
|
||||
|
@ -736,7 +736,7 @@ void NET_OpenSocks( int port )
|
|||
((struct sockaddr_in *)&socksRelayAddr)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)&socksRelayAddr)->sin_addr.s_addr = *(int *)&buf[4];
|
||||
((struct sockaddr_in *)&socksRelayAddr)->sin_port = *(short *)&buf[8];
|
||||
memset(((struct sockaddr_in *)&socksRelayAddr)->sin_zero, 0, 8 );
|
||||
Mem_Set(((struct sockaddr_in *)&socksRelayAddr)->sin_zero, 0, 8 );
|
||||
usingSocks = true;
|
||||
}
|
||||
|
||||
|
@ -775,8 +775,8 @@ int NET_IPXSocket( int port )
|
|||
}
|
||||
|
||||
address.sa_family = AF_IPX;
|
||||
memset( address.sa_netnum, 0, 4 );
|
||||
memset( address.sa_nodenum, 0, 6 );
|
||||
Mem_Set( address.sa_netnum, 0, 4 );
|
||||
Mem_Set( address.sa_nodenum, 0, 6 );
|
||||
if( port == PORT_ANY ) address.sa_socket = 0;
|
||||
else address.sa_socket = pHtons( (short)port );
|
||||
|
||||
|
|
|
@ -300,11 +300,12 @@ float com_atof(const char *str)
|
|||
|
||||
void com_atov( float *vec, const char *str, size_t siz )
|
||||
{
|
||||
char *pstr, *pfront, buffer[MAX_QPATH];
|
||||
string buffer;
|
||||
char *pstr, *pfront;
|
||||
int j;
|
||||
|
||||
com_strncpy( buffer, str, MAX_QPATH );
|
||||
memset( vec, 0, sizeof(vec_t) * siz);
|
||||
com.strncpy( buffer, str, MAX_STRING );
|
||||
Mem_Set( vec, 0, sizeof(vec_t) * siz );
|
||||
pstr = pfront = buffer;
|
||||
|
||||
for ( j = 0; j < siz; j++ )
|
||||
|
@ -422,13 +423,13 @@ timestamp
|
|||
*/
|
||||
const char* com_timestamp( int format )
|
||||
{
|
||||
static char timestamp [128];
|
||||
time_t crt_time;
|
||||
const struct tm *crt_tm;
|
||||
char timestring [64];
|
||||
static string timestamp;
|
||||
time_t crt_time;
|
||||
const struct tm *crt_tm;
|
||||
string timestring;
|
||||
|
||||
time (&crt_time);
|
||||
crt_tm = localtime (&crt_time);
|
||||
time( &crt_time );
|
||||
crt_tm = localtime( &crt_time );
|
||||
switch( format )
|
||||
{
|
||||
case TIME_FULL:
|
||||
|
@ -447,10 +448,14 @@ const char* com_timestamp( int format )
|
|||
// Build a timestamp that can use for filename (ex: "Nov2006-26 (19.14)");
|
||||
strftime(timestring, sizeof (timestring), "%b%Y-%d (%H.%M)", crt_tm);
|
||||
break;
|
||||
case TIME_YEAR_ONLY:
|
||||
// Build the date stamp year only (ex: "2006");
|
||||
strftime(timestring, sizeof (timestring), "%Y", crt_tm);
|
||||
break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
com_strcpy( timestamp, timestring );
|
||||
com.strncpy( timestamp, timestring, MAX_STRING );
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "launch.h"
|
||||
#include "baserc_api.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
#define MAX_QUED_EVENTS 256
|
||||
|
@ -21,7 +22,6 @@ int event_head, event_tail;
|
|||
dll_info_t common_dll = { "common.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t engine_dll = { "engine.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t viewer_dll = { "viewer.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t ripper_dll = { "ripper.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t baserc_dll = { "baserc.dll", NULL, "CreateAPI", NULL, NULL, false, sizeof(baserc_exp_t)};
|
||||
|
||||
static const char *show_credits = "\n\n\n\n\tCopyright XashXT Group 2007 ©\n\t\
|
||||
|
@ -59,8 +59,8 @@ void Sys_GetStdAPI( void )
|
|||
com.crc_blockchecksumkey = Com_BlockChecksumKey;
|
||||
|
||||
// memlib.c
|
||||
com.memcpy = _mem_copy;
|
||||
com.memset = _mem_set;
|
||||
com.memcpy = _crt_mem_copy; // first time using
|
||||
com.memset = _crt_mem_set; // first time using
|
||||
com.realloc = _mem_realloc;
|
||||
com.move = _mem_move;
|
||||
com.malloc = _mem_alloc;
|
||||
|
@ -201,6 +201,16 @@ void Sys_GetStdAPI( void )
|
|||
com.Com_RandomLong = Com_RandomLong;
|
||||
com.Com_RandomFloat = Com_RandomFloat;
|
||||
|
||||
// changed after called Sys_InitCPU
|
||||
com.sincos = SinCos; // fast sincos
|
||||
com.atan2 = atan2f; // fast arctan
|
||||
com.acos = acosf; // fast arccos
|
||||
com.asin = asinf; // fast arcsin
|
||||
com.sqrt = sqrtf; // fast sqrt
|
||||
com.sin = sinf; // fast sine
|
||||
com.cos = cosf; // fast cosine
|
||||
com.tan = tanf; // fast tan
|
||||
|
||||
// stdlib.c funcs
|
||||
com.strnupr = com_strnupr;
|
||||
com.strnlwr = com_strnlwr;
|
||||
|
@ -353,7 +363,7 @@ void Sys_LookupInstance( void )
|
|||
Sys.app_name = HOST_RIPPER;
|
||||
Sys.con_readonly = true;
|
||||
Sys.log_active = true; // always create log
|
||||
Sys.linked_dll = &ripper_dll; // pointer to wdclib.dll info
|
||||
Sys.linked_dll = &common_dll; // pointer to wdclib.dll info
|
||||
com_sprintf(Sys.log_path, "%s/decompile.log", sys_rootdir ); // default
|
||||
com_strcpy(Sys.caption, va("Quake Recource Extractor ver.%g", XASH_VERSION ));
|
||||
}
|
||||
|
@ -750,24 +760,24 @@ void Sys_Sleep( int msec)
|
|||
|
||||
void Sys_WaitForQuit( void )
|
||||
{
|
||||
MSG msg;
|
||||
MSG msg;
|
||||
|
||||
if(Sys.hooked_out)
|
||||
if( Sys.hooked_out )
|
||||
{
|
||||
// in-pipeline mode we don't want to wait for press any key
|
||||
if(abs((int)GetStdHandle(STD_OUTPUT_HANDLE)) <= 100)
|
||||
if(abs((int)GetStdHandle(STD_OUTPUT_HANDLE)) <= 100 )
|
||||
{
|
||||
Sys_Print("press any key to quit\n");
|
||||
system("@pause>nul\n"); // wait for quit
|
||||
Sys_Print( "press any key to quit\n" );
|
||||
system( "@pause>nul\n" ); // wait for quit
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_RegisterHotkeys();
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
Mem_Set( &msg, 0, sizeof( msg ));
|
||||
|
||||
// wait for the user to quit
|
||||
while(msg.message != WM_QUIT)
|
||||
while( msg.message != WM_QUIT )
|
||||
{
|
||||
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
{
|
||||
|
@ -845,10 +855,11 @@ void Sys_Init( void )
|
|||
|
||||
lpBuffer.dwLength = sizeof(MEMORYSTATUS);
|
||||
GlobalMemoryStatus( &lpBuffer );
|
||||
ZeroMemory( &Msec, sizeof(Msec));
|
||||
ZeroMemory( &Msec, sizeof( Msec )); // can't use memset - not init
|
||||
Sys.logfile = NULL;
|
||||
|
||||
Sys.hInstance = (HINSTANCE)GetModuleHandle( NULL ); // get current hInstance first
|
||||
// get current hInstance
|
||||
Sys.hInstance = (HINSTANCE)GetModuleHandle( NULL );
|
||||
|
||||
Sys_GetStdAPI();
|
||||
Sys.MSG_Init = NULL;
|
||||
|
@ -858,7 +869,7 @@ void Sys_Init( void )
|
|||
Sys.CPrint = NullPrint;
|
||||
Sys.Con_Print = NullPrint;
|
||||
|
||||
// some commands can turn engine into infinity loop,
|
||||
// some commands may turn engine into infinity loop,
|
||||
// e.g. xash.exe +game xash -game xash
|
||||
// so we clearing all cmd_args, but leave dbg states as well
|
||||
if( Sys.app_state != SYS_RESTART )
|
||||
|
@ -870,30 +881,28 @@ void Sys_Init( void )
|
|||
if(FS_CheckParm( "-log" )) Sys.log_active = true;
|
||||
if(FS_GetParmFromCmdLine( "-dev", dev_level )) Sys.developer = com_atoi(dev_level);
|
||||
|
||||
FS_UpdateEnvironmentVariables(); // set working directory
|
||||
FS_UpdateEnvironmentVariables(); // set working directory
|
||||
SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors
|
||||
if( Sys.hooked_out ) atexit( Sys_Abort );
|
||||
|
||||
Sys.con_showalways = true;
|
||||
Sys.con_readonly = true;
|
||||
Sys.con_showcredits = false;
|
||||
Sys.con_silentmode = false;
|
||||
Sys.stuffcmdsrun = false;
|
||||
// set default state
|
||||
Sys.con_showalways = Sys.con_readonly = true;
|
||||
Sys.con_showcredits = Sys.con_silentmode = Sys.stuffcmdsrun = false;
|
||||
|
||||
Sys_LookupInstance(); // init launcher
|
||||
Sys_LookupInstance(); // init launcher
|
||||
Con_CreateConsole();
|
||||
|
||||
// first text message into console or log
|
||||
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading launch.dll - ok\n" );
|
||||
|
||||
if(com_strlen( Sys.fmessage ) && !Sys.con_showcredits)
|
||||
if( com.strlen( Sys.fmessage ) && !Sys.con_showcredits )
|
||||
{
|
||||
Sys_Print( Sys.fmessage );
|
||||
Sys.fmessage[0] = '\0';
|
||||
}
|
||||
|
||||
Sys_InitCPU();
|
||||
Memory_Init();
|
||||
Sys_InitCPU();
|
||||
Cmd_Init();
|
||||
Cvar_Init();
|
||||
FS_Init();
|
||||
|
@ -1296,7 +1305,7 @@ sys_event_t Sys_GetEvent( void )
|
|||
}
|
||||
|
||||
// create an empty event to return
|
||||
memset( &ev, 0, sizeof(ev));
|
||||
Mem_Set( &ev, 0, sizeof( ev ));
|
||||
ev.time = timeGetTime();
|
||||
|
||||
return ev;
|
||||
|
@ -1304,10 +1313,10 @@ sys_event_t Sys_GetEvent( void )
|
|||
|
||||
bool Sys_GetModuleName( char *buffer, size_t length )
|
||||
{
|
||||
if(Sys.ModuleName[0] == '\0' )
|
||||
if( Sys.ModuleName[0] == '\0' )
|
||||
return false;
|
||||
|
||||
com_strncpy( buffer, Sys.ModuleName, length + 1 );
|
||||
com.strncpy( buffer, Sys.ModuleName, length + 1 );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,14 @@
|
|||
#include "launch.h"
|
||||
#include "mathlib.h"
|
||||
#include "const.h"
|
||||
#include "amd3dx.h"
|
||||
|
||||
#pragma warning( disable:4730 ) // "mixing _m64 and floating point expressions may result in incorrect code"
|
||||
#define SIN_TABLE_SIZE 256
|
||||
|
||||
static long idum = 0;
|
||||
static uint iFastSqrtTable[0x10000];
|
||||
static float fSinCosTable[SIN_TABLE_SIZE];
|
||||
|
||||
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
|
||||
#define IA 16807
|
||||
|
@ -19,6 +25,8 @@ static long idum = 0;
|
|||
#define AM (1.0/IM)
|
||||
#define EPS 1.2e-7
|
||||
#define RNMX (1.0 - EPS)
|
||||
#define FP_BITS( fp ) (*(dword *) &(fp))
|
||||
#define FTOIBIAS 12582912.f
|
||||
|
||||
void SeedRandomNumberGenerator( long lSeed )
|
||||
{
|
||||
|
@ -105,6 +113,91 @@ long Com_RandomLong( long lLow, long lHigh )
|
|||
return lLow + (n % x);
|
||||
}
|
||||
|
||||
// build the square root table
|
||||
void Com_BuildSqrtTable( void )
|
||||
{
|
||||
union { long l; float f; } dat;
|
||||
uint i;
|
||||
|
||||
// build the fast square root table
|
||||
for( i = 0; i <= 0x7FFF; i++ )
|
||||
{
|
||||
// build a float with the bit pattern i as mantissa
|
||||
// and an exponent of 0, stored as 127
|
||||
dat.l = (i<<8) | (0x7F<<23);
|
||||
dat.f = (float) sqrt(dat.f);
|
||||
|
||||
// take the square root then strip the first 7 bits of
|
||||
// the mantissa into the table
|
||||
iFastSqrtTable[i + 0x8000] = (dat.l & 0x7FFFFF);
|
||||
|
||||
// repeat the process, this time with an exponent of 1,
|
||||
// stored as 128
|
||||
dat.l = (i<<8) | (0x80<<23);
|
||||
dat.f = (float) sqrt(dat.f);
|
||||
|
||||
iFastSqrtTable[i] = (dat.l & 0x7FFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
void Com_BuildSinCosTable( void )
|
||||
{
|
||||
uint i;
|
||||
for( i = 0; i < SIN_TABLE_SIZE; i++ )
|
||||
fSinCosTable[i] = sin( i * M_PI2 / SIN_TABLE_SIZE );
|
||||
}
|
||||
|
||||
void SinCos( float radians, float *sine, float *cosine )
|
||||
{
|
||||
_asm
|
||||
{
|
||||
fld dword ptr [radians]
|
||||
fsincos
|
||||
|
||||
mov edx, dword ptr [cosine]
|
||||
mov eax, dword ptr [sine]
|
||||
|
||||
fstp dword ptr [edx]
|
||||
fstp dword ptr [eax]
|
||||
}
|
||||
}
|
||||
|
||||
float com_sqrt( float x )
|
||||
{
|
||||
// check for square root of 0
|
||||
if( FP_BITS( x ) == 0 ) return 0.0f;
|
||||
FP_BITS(x) = iFastSqrtTable[(FP_BITS(x)>>8)&0xFFFF]|((((FP_BITS(x)-0x3F800000)>>1)+0x3F800000)&0x7F800000);
|
||||
return x;
|
||||
}
|
||||
|
||||
float amd_sqrt( float x )
|
||||
{
|
||||
float root = 0.f;
|
||||
_asm
|
||||
{
|
||||
femms
|
||||
movd mm0, x
|
||||
PFRSQRT (mm1,mm0)
|
||||
punpckldq mm0, mm0
|
||||
PFMUL (mm0, mm1)
|
||||
movd root, mm0
|
||||
femms
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
float sse_sqrt( float x )
|
||||
{
|
||||
float root = 0.f;
|
||||
_asm
|
||||
{
|
||||
sqrtss xmm0, x
|
||||
movss root, xmm0
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_STRINGTABLE_SYSTEMS 8 // separately stringsystems
|
||||
|
||||
typedef struct stringtable_s
|
||||
|
|
|
@ -196,7 +196,7 @@ void BSP_LoadShaders( lump_t *l )
|
|||
|
||||
for( i = 0; i < cm.numshaders; i++, in++, out++)
|
||||
{
|
||||
com.strncpy( out->name, in->name, MAX_QPATH );
|
||||
com.strncpy( out->name, in->name, MAX_SHADERPATH );
|
||||
out->contentflags = LittleLong( in->contents );
|
||||
out->surfaceflags = LittleLong( in->flags );
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
|
||||
typedef struct physbody_s NewtonBody;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// baserc_api.h - xash resource library
|
||||
//=======================================================================
|
||||
#ifndef BASERC_API_H
|
||||
#define BASERC_API_H
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
BASERC.DLL INTERFACE
|
||||
|
||||
just a resource package library
|
||||
==============================================================================
|
||||
*/
|
||||
typedef struct baserc_exp_s
|
||||
{
|
||||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(baserc_exp_t)
|
||||
|
||||
byte *(*LoadFile)( const char *filename, fs_offset_t *size );
|
||||
} baserc_exp_t;
|
||||
|
||||
#endif//BASERC_API_H
|
|
@ -1,41 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// basetypes.h - base engine types
|
||||
//=======================================================================
|
||||
#ifndef BASETYPES_H
|
||||
#define BASETYPES_H
|
||||
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncation from const double to float (probably not needed)
|
||||
|
||||
#define MAX_QPATH 64 // FIXME: get rid of this
|
||||
#define MAX_STRING 256
|
||||
#define MAX_SYSPATH 1024
|
||||
#define MAX_MSGLEN 32768 // max length of network message
|
||||
|
||||
typedef enum { false, true } bool;
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long dword;
|
||||
typedef unsigned int uint;
|
||||
typedef signed __int64 int64;
|
||||
typedef int func_t;
|
||||
typedef int sound_t;
|
||||
typedef int model_t;
|
||||
typedef int video_t;
|
||||
typedef int string_t;
|
||||
typedef int shader_t;
|
||||
typedef float vec_t; // FIXME: remove
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef vec_t matrix3x3[3][3];
|
||||
typedef vec_t matrix3x4[3][4]; // FIXME: remove
|
||||
typedef vec_t matrix4x3[4][3]; // FIXME: remove
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
typedef vec_t gl_matrix[16]; // linear array
|
||||
typedef char string[MAX_STRING];
|
||||
|
||||
|
||||
#endif//BASETYPES_H
|
|
@ -21,9 +21,9 @@ _inline word WordSwap( word swap )
|
|||
|
||||
#define ShortSwap(x) WordSwap((short)x)
|
||||
|
||||
_inline uint UintSwap( uint swap )
|
||||
_inline uint UintSwap( uint *swap )
|
||||
{
|
||||
uint *i = &swap;
|
||||
uint *i = swap;
|
||||
|
||||
__asm {
|
||||
mov ebx, i
|
||||
|
@ -34,9 +34,8 @@ _inline uint UintSwap( uint swap )
|
|||
return *i;
|
||||
}
|
||||
|
||||
#define LongSwap(x) UintSwap((uint)x)
|
||||
|
||||
#define FloatSwap(x) UintSwap((uint)x)
|
||||
#define LongSwap(x) UintSwap((uint *)&x)
|
||||
#define FloatSwap(x) UintSwap((uint *)&x)
|
||||
|
||||
_inline double DoubleSwap( double swap )
|
||||
{
|
||||
|
@ -109,47 +108,45 @@ _inline double DoubleSwap( double swap )
|
|||
#define LittleDouble(l) DoubleSwap(l)
|
||||
#endif
|
||||
|
||||
//extract from buffer
|
||||
_inline dword BuffBigLong (const byte *buffer)
|
||||
// extract from buffer
|
||||
_inline dword BuffBigLong( const byte *buf )
|
||||
{
|
||||
return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
|
||||
return (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
|
||||
}
|
||||
|
||||
_inline word BuffBigShort (const byte *buffer)
|
||||
_inline word BuffBigShort( const byte *buf )
|
||||
{
|
||||
return (buffer[0] << 8) | buffer[1];
|
||||
return (buf[0]<<8)|buf[1];
|
||||
}
|
||||
|
||||
_inline float BuffBigFloat (const byte *buffer)
|
||||
_inline float BuffBigFloat( const byte *buf )
|
||||
{
|
||||
return BuffBigLong( buffer );//same as integer
|
||||
return BuffBigLong( buf );
|
||||
}
|
||||
|
||||
_inline double BuffBigDouble (const byte *buffer)
|
||||
_inline double BuffBigDouble( const byte *buf )
|
||||
{
|
||||
return (buffer[0] << 64) | (buffer[1] << 56) | (buffer[2] << 40) | (buffer[3] << 32)
|
||||
| (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
|
||||
return (buf[0]<<64)|(buf[1]<<56)|(buf[2]<<40)|(buf[3]<<32)|(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
|
||||
}
|
||||
|
||||
_inline dword BuffLittleLong (const byte *buffer)
|
||||
_inline dword BuffLittleLong( const byte *buf )
|
||||
{
|
||||
return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
|
||||
return (buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
|
||||
}
|
||||
|
||||
_inline word BuffLittleShort (const byte *buffer)
|
||||
_inline word BuffLittleShort( const byte *buf )
|
||||
{
|
||||
return (buffer[1] << 8) | buffer[0];
|
||||
return (buf[1]<<8)|buf[0];
|
||||
}
|
||||
|
||||
_inline float BuffLittleFloat (const byte *buffer)
|
||||
_inline float BuffLittleFloat( const byte *buf )
|
||||
{
|
||||
return BuffLittleLong( buffer );
|
||||
return BuffLittleLong( buf );
|
||||
}
|
||||
|
||||
_inline double BuffLittleDouble (const byte *buffer)
|
||||
_inline double BuffLittleDouble( const byte *buf )
|
||||
{
|
||||
return (buffer[7] << 64) | (buffer[6] << 56) | (buffer[5] << 40) | (buffer[4] << 32)
|
||||
| (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
|
||||
return (buf[7]<<64)|(buf[6]<<56)|(buf[5]<<40)|(buf[4]<<32)|(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -5,6 +5,52 @@
|
|||
#ifndef LAUNCH_APH_H
|
||||
#define LAUNCH_APH_H
|
||||
|
||||
// disable some warnings
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncation from const double to float
|
||||
|
||||
#define STRING_COLOR_TAG '^'
|
||||
#define MAX_STRING 256 // generic string
|
||||
#define MAX_SYSPATH 1024 // system filepath
|
||||
#define MAX_MSGLEN 32768 // max length of network message
|
||||
#define IsColorString(p) ( p && *(p) == STRING_COLOR_TAG && *((p)+1) && *((p)+1) != STRING_COLOR_TAG )
|
||||
#define bound(min, num, max) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
|
||||
#define DLLEXPORT __declspec( dllexport )
|
||||
|
||||
// generic engine types
|
||||
typedef enum { false, true } bool;
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long dword;
|
||||
typedef unsigned int uint;
|
||||
typedef int func_t;
|
||||
typedef int sound_t;
|
||||
typedef int model_t;
|
||||
typedef int video_t;
|
||||
typedef int string_t;
|
||||
typedef int shader_t;
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef vec_t matrix3x3[3][3];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
typedef char string[MAX_STRING];
|
||||
|
||||
// FIXME: get rid of this
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x3[4][3];
|
||||
typedef vec_t gl_matrix[16];
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT( n ) (1<<( n ))
|
||||
#endif
|
||||
|
||||
// platform instances
|
||||
typedef enum
|
||||
{
|
||||
|
@ -147,9 +193,7 @@ typedef struct gameinfo_s
|
|||
|
||||
// shared system info
|
||||
int cpunum; // count of cpu's
|
||||
int64 tickcount; // cpu frequency in 'ticks'
|
||||
float cpufreq; // cpu frequency in MHz
|
||||
bool rdtsc; // rdtsc support (profiler stuff)
|
||||
|
||||
string vprogs_dir; // default progs directory
|
||||
string source_dir; // default source directory
|
||||
|
@ -192,8 +236,10 @@ typedef struct dll_info_s
|
|||
internal image format
|
||||
|
||||
typically expanded to rgba buffer
|
||||
NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 == PF_RGB_888
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PF_UNKNOWN = 0,
|
||||
|
@ -217,6 +263,8 @@ typedef enum
|
|||
PF_LUMINANCE, // b&w dds image
|
||||
PF_LUMINANCE_16, // b&w hi-res image
|
||||
PF_LUMINANCE_ALPHA, // b&w dds image with alpha channel
|
||||
PF_UV_16, // EMBM two signed 8bit components
|
||||
PF_UV_32, // EMBM two signed 16bit components
|
||||
PF_R_16F, // red channel half-float image
|
||||
PF_R_32F, // red channel float image
|
||||
PF_GR_32F, // Green-Red channels half-float image (dudv maps)
|
||||
|
@ -270,6 +318,7 @@ typedef enum
|
|||
IMAGE_RESAMPLE = BIT(20), // resample image to specified dims
|
||||
IMAGE_PALTO24 = BIT(21), // turn 32-bit palette into 24-bit mode (only for indexed images)
|
||||
IMAGE_COMP_DXT = BIT(22), // compress image to DXT format
|
||||
IMAGE_ROUNDFILLER = BIT(23), // round image to nearest Pow2 and fill unused entries with single color
|
||||
} imgFlags_t;
|
||||
|
||||
typedef struct rgbdata_s
|
||||
|
@ -470,6 +519,16 @@ typedef struct stdilib_api_s
|
|||
long (*Com_RandomLong)( long lMin, long lMax ); // returns random integer
|
||||
float (*Com_RandomFloat)( float fMin, float fMax ); // returns random float
|
||||
|
||||
// mathlib.c funcs
|
||||
void (*sincos)( float x, float *sin, float *cos ); // fast sincos
|
||||
float (*atan2)( float x, float y ); // fast arctan
|
||||
float (*acos)( float x ); // fast arccos
|
||||
float (*asin)( float x ); // fast arcsin
|
||||
float (*sqrt)( float x ); // fast sqrt
|
||||
float (*sin)( float x ); // fast sine
|
||||
float (*cos)( float x ); // fast cosine
|
||||
float (*tan)( float x ); // fast tan
|
||||
|
||||
// stdlib.c funcs
|
||||
void (*strnupr)(const char *in, char *out, size_t size_out); // convert string to upper case
|
||||
void (*strnlwr)(const char *in, char *out, size_t size_out); // convert string to lower case
|
||||
|
@ -548,7 +607,7 @@ typedef struct cvar_s
|
|||
#define Mem_FreePool(pool) com.freepool(pool, __FILE__, __LINE__)
|
||||
#define Mem_EmptyPool(pool) com.clearpool(pool, __FILE__, __LINE__)
|
||||
#define Mem_Copy(dest, src, size ) com.memcpy(dest, src, size, __FILE__, __LINE__)
|
||||
#define Mem_Set(dest, val, size ) com.memcpy(dest, val, size, __FILE__, __LINE__)
|
||||
#define Mem_Set(dest, val, size ) com.memset(dest, val, size, __FILE__, __LINE__)
|
||||
#define Mem_Check() com.memcheck(__FILE__, __LINE__)
|
||||
#define Mem_CreateArray( p, s, n ) com.newarray( p, s, n, __FILE__, __LINE__)
|
||||
#define Mem_RemoveArray( array ) com.delarray( array, __FILE__, __LINE__)
|
||||
|
@ -754,6 +813,7 @@ misc utils
|
|||
#define StringTable_SetString com.st_setstring
|
||||
#define StringTable_Load com.st_load
|
||||
#define StringTable_Save com.st_save
|
||||
#define Com_Assert( x ) if( x ) com.abort( "assert failed at %s:%i\n", __FILE__, __LINE__ );
|
||||
|
||||
/*
|
||||
===========================================
|
||||
|
|
|
@ -157,6 +157,7 @@ BRUSH MODELS
|
|||
// other limits
|
||||
#define DVIS_PVS 0
|
||||
#define DVIS_PHS 1
|
||||
#define MAX_SHADERPATH 64
|
||||
#define MAX_KEY 128
|
||||
#define MAX_VALUE 512
|
||||
#define MAX_WORLD_COORD ( 128 * 1024 )
|
||||
|
@ -215,7 +216,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
char name[64]; // shader name
|
||||
char name[MAX_SHADERPATH];// shader name
|
||||
int contents; // texture contents (can be replaced by shader)
|
||||
int flags; // surface flags (can be replaced by shader)
|
||||
} dshader_t;
|
||||
|
|
|
@ -5,23 +5,7 @@
|
|||
#ifndef REF_DLLAPI_H
|
||||
#define REF_DLLAPI_H
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT( n ) (1<<( n ))
|
||||
#endif
|
||||
|
||||
#include "ref_dfiles.h"
|
||||
#include "launch_api.h"
|
||||
|
||||
#define STRING_COLOR_TAG '^'
|
||||
#define IsColorString(p) ( p && *(p) == STRING_COLOR_TAG && *((p)+1) && *((p)+1) != STRING_COLOR_TAG )
|
||||
#define bound(min, num, max) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
|
||||
|
||||
|
||||
typedef struct { uint b:5; uint g:6; uint r:5; } color16;
|
||||
typedef struct { byte r:8; byte g:8; byte b:8; } color24;
|
||||
|
@ -428,23 +412,6 @@ typedef struct launch_exp_s
|
|||
void (*MSG_Init)( sizebuf_t *buf, byte *data, size_t len ); // MSG init network buffer
|
||||
} launch_exp_t;
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
BASERC.DLL INTERFACE
|
||||
|
||||
just a resource package library
|
||||
==============================================================================
|
||||
*/
|
||||
typedef struct baserc_exp_s
|
||||
{
|
||||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(imglib_api_t)
|
||||
|
||||
byte *(*LoadFile)( const char *filename, fs_offset_t *size );
|
||||
} baserc_exp_t;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% common/common.dsp %CONFIG%"common - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% ripper/ripper.dsp %CONFIG%"ripper - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% physic/physic.dsp %CONFIG%"physic - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
|
@ -61,7 +58,6 @@ if exist baserc\baserc.plg del /f /q baserc\baserc.plg
|
|||
if exist engine\engine.plg del /f /q engine\engine.plg
|
||||
if exist launch\launch.plg del /f /q launch\launch.plg
|
||||
if exist common\common.plg del /f /q common\common.plg
|
||||
if exist ripper\ripper.plg del /f /q ripper\ripper.plg
|
||||
if exist physic\physic.plg del /f /q physic\physic.plg
|
||||
if exist render\render.plg del /f /q render\render.plg
|
||||
if exist viewer\viewer.plg del /f /q viewer\viewer.plg
|
||||
|
@ -71,5 +67,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
quake.exe -game tmpQuArK -dev 3 -debug -log +map qctest
|
||||
quake.exe -game tmpQuArK -dev 5 -debug -log +map qctest
|
||||
:done
|
|
@ -7,7 +7,7 @@
|
|||
#define R_LOCAL_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
#include "r_opengl.h"
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ void R_LoadShaders( const byte *base, const lump_t *l )
|
|||
|
||||
for ( i = 0; i < count; i++, in++, out++ )
|
||||
{
|
||||
com.strncpy( out->name, in->name, MAX_QPATH );
|
||||
com.strncpy( out->name, in->name, MAX_SHADERPATH );
|
||||
out->shader = r_defaultShader; // real shaders will load later
|
||||
out->contents = LittleLong( in->contents );
|
||||
out->flags = LittleLong( in->flags );
|
||||
|
|
|
@ -780,7 +780,7 @@ static bool R_ParseStageBumpMap( ref_shader_t *shader, shaderStage_t *stage, cha
|
|||
{
|
||||
stageBundle_t *bundle = stage->bundles[stage->numBundles - 1];
|
||||
uint flags = TF_NORMALMAP;
|
||||
char heightMap[MAX_QPATH];
|
||||
string heightMap;
|
||||
float bumpScale;
|
||||
char *tok;
|
||||
|
||||
|
|
|
@ -93,9 +93,11 @@ MISC STUDIO UTILS
|
|||
// extract texture filename from modelname
|
||||
char *R_ExtName( rmodel_t *mod )
|
||||
{
|
||||
static char texname[MAX_QPATH];
|
||||
com.strcpy( texname, mod->name );
|
||||
com.strcpy( &texname[com.strlen(texname) - 4], "T.mdl" );
|
||||
static string texname;
|
||||
|
||||
com.strncpy( texname, mod->name, MAX_STRING );
|
||||
FS_StripExtension( texname );
|
||||
com.strncat( texname, "T.mdl", MAX_STRING );
|
||||
return texname;
|
||||
}
|
||||
|
||||
|
|
|
@ -1183,12 +1183,13 @@ texture_t *R_LoadTexture( const char *name, rgbdata_t *pic, uint flags, float bu
|
|||
}
|
||||
|
||||
image = &r_textures[r_numTextures++];
|
||||
if( com.strlen( name ) >= sizeof(image->name)) MsgDev( D_WARN, "R_LoadImage: \"%s\" is too long", name);
|
||||
if( com.strlen( name ) >= sizeof(image->name)) MsgDev( D_WARN, "R_LoadTexture: \"%s\" is too long", name);
|
||||
|
||||
// nothing to load
|
||||
if( !pic || !pic->buffer )
|
||||
{
|
||||
// create notexture with another name
|
||||
MsgDev( D_WARN, "R_LoadTexture: can't loading %s\n", name );
|
||||
Mem_Copy( image, r_defaultTexture, sizeof( texture_t ));
|
||||
com.strncpy( image->name, name, sizeof( image->name ));
|
||||
image->registration_sequence = registration_sequence;
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_image.c - convert various image type
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvJPG
|
||||
|
||||
decompress jpeg to tga 32 bit
|
||||
=============
|
||||
*/
|
||||
bool ConvJPG( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.jpg", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension((char *)name );
|
||||
FS_SaveImage( va("%s/%s.tga", gs_gamedir, name ), pic ); // save converted image
|
||||
Conv_CreateShader( name, pic, "jpg", NULL, 0, 0 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.jpg\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvPCX
|
||||
|
||||
decompress pcx to bmp 8 bit indexed (runlength decompress)
|
||||
=============
|
||||
*/
|
||||
bool ConvPCX( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.pcx", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension((char *)name );
|
||||
FS_SaveImage( va("%s/%s.bmp", gs_gamedir, name ), pic ); // save converted image
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.pcx\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvPAL
|
||||
|
||||
get palette from wad (just in case, not really needed)
|
||||
============
|
||||
*/
|
||||
bool ConvPAL( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.pal", buffer, filesize );
|
||||
|
||||
if( pic && pic->palette )
|
||||
{
|
||||
FS_StripExtension((char *)name );
|
||||
FS_WriteFile( va("%s.pal", name ), pic->palette, 768 ); // expands to 32bit
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.pal\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvDAT
|
||||
|
||||
decompile progs.dat
|
||||
============
|
||||
*/
|
||||
bool ConvDAT( const char *name, char *buffer, int filesize )
|
||||
{
|
||||
return PRVM->DecompileDAT( name );
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_shader.c - analyze and write texture shader
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvJPG
|
||||
=============
|
||||
*/
|
||||
bool ConvJPG( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.jpg", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension((char *)name );
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic ); // save converted image
|
||||
Conv_CreateShader( name, pic, "jpg", NULL, 0, 0 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.jpg\n", name, ext ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_pcximage.c - convert pcximages
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
// this also uses by SP2_ConvertFrame
|
||||
bool ConvPCX( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.pcx", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension((char *)name );
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic ); // save converted image
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg( "%s.pcx\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_raw.c - extract hidden lumps
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
|
||||
/*
|
||||
============
|
||||
ConvRAW
|
||||
============
|
||||
*/
|
||||
bool ConvRAW( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
FS_WriteFile(va("%s/other/%s.ext", gs_gamedir, name, ext ), buffer, filesize );
|
||||
Msg("%s.%s\n", name, ext ); // echo to console aboutfile
|
||||
return true;
|
||||
}
|
|
@ -1,436 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_sound.c - convert wav-files
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MUSIDHEADER ((0x1A<<24)+('S'<<16)+('U'<<8)+'M') // little-endian "MUS "
|
||||
#define MIDIDHEADER "MThd\000\000\000\006\000\001"
|
||||
#define TRACKMAGIC1 "\000\377\003\035"
|
||||
#define TRACKMAGIC2 "\000\377\057\000"
|
||||
#define TRACKMAGIC3 "\000\377\002\026"
|
||||
#define TRACKMAGIC4 "\000\377\131\002\000\000"
|
||||
#define TRACKMAGIC5 "\000\377\121\003\011\243\032"
|
||||
#define TRACKMAGIC6 "\000\377\057\000"
|
||||
|
||||
#define MIDBUFFER 0x20000
|
||||
#define last(e) ((byte)(e & 0x80))
|
||||
#define event_type(e) ((byte)((e & 0x7F)>>4))
|
||||
#define channel(e) ((byte)(e & 0x0F))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
word ScoreLength;
|
||||
word ScoreStart;
|
||||
word channels; // count of primary channels
|
||||
word SecChannels; // count of secondary channels
|
||||
word InstrCnt;
|
||||
word dummy;
|
||||
word *instruments;
|
||||
} mus_t;
|
||||
|
||||
struct track_s
|
||||
{
|
||||
dword current;
|
||||
char vel;
|
||||
long DeltaTime;
|
||||
byte LastEvent;
|
||||
char *data; // primary data
|
||||
};
|
||||
|
||||
#define mid_write1 VFS_Write
|
||||
size_t mid_write2( vfile_t *file, const uint *ptr, size_t size )
|
||||
{
|
||||
uint i, rev = 0;
|
||||
|
||||
for( i = 0; (size_t)i < size; i++ )
|
||||
rev = (rev << 8) + (((*ptr) >>(i*8)) & 0xFF) ;
|
||||
|
||||
return VFS_Write( file, &rev, size );
|
||||
}
|
||||
|
||||
void Conv_WriteMIDheader( vfile_t *file, uint ntrks, uint division )
|
||||
{
|
||||
mid_write1( file, MIDIDHEADER, 10 );
|
||||
mid_write2( file, &ntrks, 2 );
|
||||
mid_write2( file, &division, 2 );
|
||||
}
|
||||
|
||||
void Conv_WriteTrack( vfile_t *file, int tracknum, struct track_s track[] )
|
||||
{
|
||||
uint size;
|
||||
size_t quot, rem;
|
||||
|
||||
// do we risk overflow here ?
|
||||
size = (uint)track[tracknum].current + 4;
|
||||
mid_write1( file, "MTrk", 4 );
|
||||
if( !tracknum ) size += 33;
|
||||
|
||||
mid_write2( file, &size, 4 );
|
||||
if( !tracknum) mid_write1( file, TRACKMAGIC1 "written by Xash MusLib Ripper", 33 );
|
||||
quot = (size_t)(track[tracknum].current / 4096);
|
||||
rem = (size_t)(track[tracknum].current - quot * 4096);
|
||||
mid_write1( file, track[tracknum].data, 4096 * quot );
|
||||
mid_write1( file, ((const byte *)track[tracknum].data) + 4096 * quot, rem );
|
||||
mid_write1( file, TRACKMAGIC2, 4 );
|
||||
}
|
||||
|
||||
void Conv_WriteFirstTrack( vfile_t *file )
|
||||
{
|
||||
uint size = 43;
|
||||
|
||||
mid_write1( file, "MTrk", 4);
|
||||
mid_write2( file, &size, 4 );
|
||||
mid_write1( file, TRACKMAGIC3, 4 );
|
||||
mid_write1( file, "by XashXT Group 2007 ©", 22 );
|
||||
mid_write1( file, TRACKMAGIC4, 6 );
|
||||
mid_write1( file, TRACKMAGIC5, 7 );
|
||||
mid_write1( file, TRACKMAGIC6, 4 );
|
||||
}
|
||||
|
||||
bool Conv_ReadMusHeader( vfile_t *f, mus_t *hdr )
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
VFS_Read( f, &hdr->ident, 4 );
|
||||
if( hdr->ident != MUSIDHEADER )
|
||||
return false;
|
||||
|
||||
VFS_Read(f, &(hdr->ScoreLength), sizeof(word));
|
||||
VFS_Read(f, &(hdr->ScoreStart), sizeof(word));
|
||||
VFS_Read(f, &(hdr->channels), sizeof(word));
|
||||
VFS_Read(f, &(hdr->SecChannels), sizeof(word));
|
||||
VFS_Read(f, &(hdr->InstrCnt), sizeof(word));
|
||||
VFS_Read(f, &(hdr->dummy), sizeof(word));
|
||||
hdr->instruments = (word *)Mem_Alloc( zonepool, hdr->InstrCnt * sizeof(word));
|
||||
|
||||
if(VFS_Read( f, hdr->instruments, hdr->InstrCnt * sizeof(word)) != hdr->InstrCnt * sizeof(word))
|
||||
result = false;
|
||||
Mem_Free( hdr->instruments );
|
||||
return result;
|
||||
}
|
||||
|
||||
char Conv_GetChannel( signed char MUS2MIDchannel[] )
|
||||
{
|
||||
signed char old15 = MUS2MIDchannel[15], max = -1;
|
||||
int i;
|
||||
|
||||
MUS2MIDchannel[15] = -1;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
if( MUS2MIDchannel[i] > max )
|
||||
max = MUS2MIDchannel[i];
|
||||
}
|
||||
MUS2MIDchannel[15] = old15;
|
||||
return (max == 8 ? 10 : max + 1);
|
||||
}
|
||||
|
||||
void Conv_FreeTracks( struct track_s track[] )
|
||||
{
|
||||
int i ;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
if(track[i].data) Mem_Free( track[i].data ) ;
|
||||
}
|
||||
}
|
||||
|
||||
uint Conv_ReadTime( vfile_t *file )
|
||||
{
|
||||
register uint time = 0;
|
||||
int newbyte;
|
||||
|
||||
do
|
||||
{
|
||||
VFS_Read( file, &newbyte, 1 );
|
||||
if( newbyte != EOF ) time = (time << 7) + (newbyte & 0x7F);
|
||||
} while((newbyte != EOF) && (newbyte & 0x80));
|
||||
return time ;
|
||||
}
|
||||
|
||||
void Conv_WriteByte( char MIDItrack, char byte, struct track_s track[] )
|
||||
{
|
||||
uint pos;
|
||||
|
||||
pos = track[MIDItrack].current;
|
||||
if( pos < MIDBUFFER )
|
||||
{
|
||||
// need to reallocte ?
|
||||
track[MIDItrack].data[pos] = byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
Conv_FreeTracks( track );
|
||||
Sys_Break("Not enough memory" );
|
||||
}
|
||||
track[MIDItrack].current++;
|
||||
}
|
||||
|
||||
void Conv_WriteVarLen( int tracknum, register uint value, struct track_s track[] )
|
||||
{
|
||||
register uint buffer;
|
||||
|
||||
buffer = value & 0x7f;
|
||||
while((value >>= 7))
|
||||
{
|
||||
buffer<<= 8;
|
||||
buffer |= 0x80;
|
||||
buffer += (value & 0x7f);
|
||||
}
|
||||
while( 1 )
|
||||
{
|
||||
Conv_WriteByte( tracknum, buffer, track );
|
||||
if( buffer & 0x80 ) buffer >>= 8;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Conv_Mus2Mid( const char *musicname, byte *buffer, int bufsize )
|
||||
{
|
||||
struct track_s track[16];
|
||||
word TrackCnt = 0;
|
||||
word division = 90;
|
||||
byte et, MUSchannel, MIDIchannel, MIDItrack, NewEvent;
|
||||
uint i, DeltaTime, TotalTime = 0, n = 0;
|
||||
char event, data, ouch = 0;
|
||||
signed char MUS2MIDchannel[16];
|
||||
vfile_t *file_mid, *file_mus = VFS_Create( buffer, bufsize );
|
||||
file_t *f;
|
||||
static mus_t MUSh;
|
||||
byte MUS2MIDcontrol[15] =
|
||||
{
|
||||
0, // program change - not a MIDI control change
|
||||
0x00, // bank select
|
||||
0x01, // modulation pot
|
||||
0x07, // volume
|
||||
0x0A, // pan pot
|
||||
0x0B, // expression pot
|
||||
0x5B, // reverb depth
|
||||
0x5D, // chorus depth
|
||||
0x40, // sustain pedal
|
||||
0x43, // soft pedal
|
||||
0x78, // all sounds off
|
||||
0x7B, // all notes off
|
||||
0x7E, // mono
|
||||
0x7F, // poly
|
||||
0x79 // reset all controllers
|
||||
}, MIDIchan2track[16];
|
||||
|
||||
if(!Conv_ReadMusHeader( file_mus, &MUSh ))
|
||||
{
|
||||
VFS_Close( file_mus );
|
||||
MsgDev(D_ERROR, "Conv_Mus2Mid: can't read mus header\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( VFS_Seek( file_mus, MUSh.ScoreStart, SEEK_SET ))
|
||||
{
|
||||
VFS_Close( file_mus );
|
||||
MsgDev(D_ERROR,"Conv_Mus2Mid: can't seek scores\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( MUSh.channels > 15 )
|
||||
{
|
||||
VFS_Close( file_mus );
|
||||
MsgDev(D_ERROR,"Conv_Mus2Mid: too many channels\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
MUS2MIDchannel[i] = -1;
|
||||
track[i].current = 0;
|
||||
track[i].vel = 64;
|
||||
track[i].DeltaTime = 0;
|
||||
track[i].LastEvent = 0;
|
||||
track[i].data = NULL;
|
||||
}
|
||||
|
||||
VFS_Read( file_mus, &event, 1 );
|
||||
et = event_type( event );
|
||||
MUSchannel = channel( event );
|
||||
|
||||
while((et != 6) && !VFS_Eof( file_mus ) && (event != EOF))
|
||||
{
|
||||
if( MUS2MIDchannel[MUSchannel] == -1 )
|
||||
{
|
||||
MIDIchannel = MUS2MIDchannel[MUSchannel] = (MUSchannel == 15 ? 9:Conv_GetChannel(MUS2MIDchannel));
|
||||
MIDItrack = MIDIchan2track[MIDIchannel] = (byte)(TrackCnt++);
|
||||
track[MIDItrack].data = (char *)Mem_Alloc( zonepool, MIDBUFFER );
|
||||
}
|
||||
else
|
||||
{
|
||||
MIDIchannel = MUS2MIDchannel[MUSchannel];
|
||||
MIDItrack = MIDIchan2track [MIDIchannel];
|
||||
}
|
||||
Conv_WriteVarLen( MIDItrack, track[MIDItrack].DeltaTime, track );
|
||||
track[MIDItrack].DeltaTime = 0;
|
||||
|
||||
switch( et )
|
||||
{
|
||||
case 0: // release note
|
||||
NewEvent = 0x90 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, data, track );
|
||||
Conv_WriteByte( MIDItrack, 0, track );
|
||||
break;
|
||||
case 1:
|
||||
NewEvent = 0x90 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, data & 0x7F, track );
|
||||
if( data & 0x80 ) VFS_Read( file_mus, &track[MIDItrack].vel, 1 );
|
||||
Conv_WriteByte( MIDItrack, track[MIDItrack].vel, track );
|
||||
break;
|
||||
case 2:
|
||||
NewEvent = 0xE0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, (data & 1) << 6, track );
|
||||
Conv_WriteByte( MIDItrack, data >> 1, track );
|
||||
break;
|
||||
case 3:
|
||||
NewEvent = 0xB0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, MUS2MIDcontrol[data], track );
|
||||
if( data == 12 ) Conv_WriteByte( MIDItrack, MUSh.channels + 1, track );
|
||||
else Conv_WriteByte( MIDItrack, 0, track );
|
||||
break;
|
||||
case 4:
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
if( data )
|
||||
{
|
||||
NewEvent = 0xB0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
Conv_WriteByte( MIDItrack, MUS2MIDcontrol[data], track );
|
||||
}
|
||||
else
|
||||
{
|
||||
NewEvent = 0xC0 | MIDIchannel;
|
||||
if( NewEvent != track[MIDItrack].LastEvent )
|
||||
{
|
||||
Conv_WriteByte( MIDItrack, NewEvent, track );
|
||||
track[MIDItrack].LastEvent = NewEvent;
|
||||
}
|
||||
else n++;
|
||||
}
|
||||
VFS_Read( file_mus, &data, 1 );
|
||||
Conv_WriteByte( MIDItrack, data, track );
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
Conv_FreeTracks( track );
|
||||
MsgDev(D_ERROR, "Conv_Mus2Mid: bad event\n" );
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(last( event ))
|
||||
{
|
||||
DeltaTime = Conv_ReadTime( file_mus );
|
||||
TotalTime += DeltaTime;
|
||||
for( i = 0; i < (int)TrackCnt; i++ )
|
||||
track[i].DeltaTime += DeltaTime;
|
||||
}
|
||||
VFS_Read( file_mus, &event, 1 );
|
||||
if( event != EOF )
|
||||
{
|
||||
et = event_type( event );
|
||||
MUSchannel = channel( event );
|
||||
}
|
||||
else ouch = 1;
|
||||
}
|
||||
if( ouch ) MsgDev(D_WARN, "Conv_Mus2Mid: %s.mus - end of file probably corrupted\n", musicname );
|
||||
|
||||
f = FS_Open(va("%s/music/%s.mid", gs_gamedir, musicname ), "wb" );
|
||||
file_mid = VFS_Open( f, "w" );
|
||||
|
||||
Conv_WriteMIDheader( file_mid, TrackCnt + 1, division );
|
||||
Conv_WriteFirstTrack( file_mid );
|
||||
|
||||
for( i = 0; i < (int)TrackCnt; i++ )
|
||||
Conv_WriteTrack( file_mid, i, track );
|
||||
Conv_FreeTracks( track );
|
||||
FS_Close(VFS_Close( file_mid ));
|
||||
VFS_Close( file_mus );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvMID
|
||||
============
|
||||
*/
|
||||
bool ConvMID( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
string musicname;
|
||||
|
||||
if(FS_FileExists( va("%s/music/%s.%s", gs_gamedir, musicname, ext )))
|
||||
return true; // already existed
|
||||
|
||||
FS_FileBase( name, musicname );
|
||||
if(Conv_Mus2Mid( musicname, buffer, filesize ))
|
||||
{
|
||||
Msg("%s.%s\n", musicname, ext ); // echo to console about current music
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvSND
|
||||
============
|
||||
*/
|
||||
bool ConvSND( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
string soundname;
|
||||
|
||||
FS_FileBase( name, soundname );
|
||||
|
||||
/*
|
||||
FIXME: write sound convertor
|
||||
1. Load doom sound as 8-bit unsigned 11 025 kHz uncompressed wav file (mono)
|
||||
2. Resample it to 16-bit signed 22 050 kHz (mono)
|
||||
3. Write wav header, write chunks
|
||||
FS_WriteFile(va("%s/sound/%s.wav", gs_gamedir, soundname ), buffer, filesize );
|
||||
Msg("%s.wav\n", soundname ); // echo to console about current sound
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
|
@ -1,309 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_sprite.c - convert q1\hl\spr32 sprites
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "mathlib.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.SPR sprite file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
#define IDSPRQ1HEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDSP"
|
||||
|
||||
#define SPRITEQ1_VERSION 1
|
||||
#define SPRITEHL_VERSION 2
|
||||
#define SPRITE32_VERSION 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int type;
|
||||
int boundingradius;
|
||||
int width;
|
||||
int height;
|
||||
int numframes;
|
||||
float beamlength;
|
||||
synctype_t synctype;
|
||||
} dspriteq1_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int type;
|
||||
int texFormat; // Half-Life stuff only
|
||||
float boundingradius; // software rendering stuff
|
||||
int width;
|
||||
int height;
|
||||
int numframes;
|
||||
float beamlength; // software rendering stuff
|
||||
synctype_t synctype;
|
||||
} dspritehl_t;
|
||||
|
||||
//
|
||||
// sprite_decompiler.c
|
||||
//
|
||||
void *SPR_ConvertFrame( const char *name, const char *ext, void *pin, int framenum, int groupframenum )
|
||||
{
|
||||
rgbdata_t *pix;
|
||||
dspriteframe_t *pinframe;
|
||||
string framename;
|
||||
byte *fin, *fout;
|
||||
int i, pixels, width, height;
|
||||
|
||||
pinframe = (dspriteframe_t *)pin;
|
||||
width = LittleLong( pinframe->width );
|
||||
height = LittleLong( pinframe->height );
|
||||
fin = (byte *)(pinframe + 1);
|
||||
if( width <= 0 || height <= 0 )
|
||||
{
|
||||
// NOTE: in Q1 existing sprites with blank frames
|
||||
spr.totalframes--;
|
||||
return (void *)((byte *)(pinframe + 1));
|
||||
}
|
||||
|
||||
// extract sprite name from path
|
||||
FS_FileBase( name, framename );
|
||||
com.strcat( framename, va("_%i", framenum ));
|
||||
pixels = width * height;
|
||||
|
||||
if( spr.truecolor )
|
||||
{
|
||||
// HACKHACK: manually create rgbdata_t
|
||||
pixels *= 4;
|
||||
pix = Mem_Alloc( zonepool, sizeof( *pix ));
|
||||
fout = Mem_Alloc( zonepool, pixels );
|
||||
Mem_Copy( fout, fin, pixels );
|
||||
if( spr.texFormat >= SPR_INDEXALPHA )
|
||||
pix->flags |= IMAGE_HAVE_ALPHA;
|
||||
pix->type = PF_RGBA_32;
|
||||
pix->width = width;
|
||||
pix->height = height;
|
||||
pix->size = pixels;
|
||||
pix->numLayers = 1;
|
||||
pix->numMips = 1;
|
||||
pix->buffer = fout;
|
||||
}
|
||||
else
|
||||
{
|
||||
pix = FS_LoadImage( va( "#%s.spr", framename ), pin, pixels );
|
||||
Image_Process( &pix, 0, 0, IMAGE_PALTO24 );
|
||||
}
|
||||
|
||||
if( groupframenum )
|
||||
{
|
||||
i = groupframenum - 1;
|
||||
com.strncpy( spr.group[spr.numgroup].frame[i].name, framename, MAX_STRING );
|
||||
spr.group[spr.numgroup].frame[i].origin[0] = -(float)LittleLong(pinframe->origin[0]);
|
||||
spr.group[spr.numgroup].frame[i].origin[1] = (float)LittleLong(pinframe->origin[1]);
|
||||
spr.group[spr.numgroup].frame[i].width = (float)LittleLong(pinframe->width);
|
||||
spr.group[spr.numgroup].frame[i].height = (float)LittleLong(pinframe->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
com.strncpy( spr.frame[framenum].name, framename, MAX_STRING );
|
||||
spr.frame[framenum].origin[0] = -(float)LittleLong(pinframe->origin[0]);
|
||||
spr.frame[framenum].origin[1] = (float)LittleLong(pinframe->origin[1]);
|
||||
spr.frame[framenum].width = (float)LittleLong(pinframe->width);
|
||||
spr.frame[framenum].height = (float)LittleLong(pinframe->height);
|
||||
}
|
||||
|
||||
FS_SaveImage( va("%s/sprites/%s.%s", gs_gamedir, framename, ext ), pix );
|
||||
FS_FreeImage( pix ); // free image
|
||||
|
||||
// jump to next frame
|
||||
return (void *)((byte *)(pinframe + 1) + pixels ); // no mipmap stored
|
||||
}
|
||||
|
||||
void *SPR_ConvertGroup( const char *name, const char *ext, void *pin, int framenum )
|
||||
{
|
||||
dspritegroup_t *pingroup;
|
||||
int i, numframes;
|
||||
dspriteinterval_t *pin_intervals;
|
||||
void *ptemp;
|
||||
|
||||
pingroup = (dspritegroup_t *)pin;
|
||||
numframes = LittleLong( pingroup->numframes );
|
||||
pin_intervals = (dspriteinterval_t *)(pingroup + 1);
|
||||
|
||||
for (i = 0; i < numframes; i++)
|
||||
{
|
||||
spr.group[spr.numgroup].interval[i] = LittleLong( pin_intervals->interval );
|
||||
pin_intervals++;
|
||||
}
|
||||
|
||||
// update global numframes
|
||||
spr.group[spr.numgroup].numframes = numframes - 1;
|
||||
ptemp = (void *)pin_intervals;
|
||||
|
||||
for (i = 0; i < numframes; i++ )
|
||||
{
|
||||
ptemp = SPR_ConvertFrame( name, ext, ptemp, framenum + i, i + 1 );
|
||||
}
|
||||
spr.numgroup++;
|
||||
return ptemp;
|
||||
}
|
||||
|
||||
bool SPR_WriteScript( const char *name, const char *ext )
|
||||
{
|
||||
int i, j;
|
||||
file_t *f = FS_Open( va("%s/sprites/%s.qc", gs_gamedir, name ), "w" );
|
||||
|
||||
if( !f )
|
||||
{
|
||||
Msg("Can't generate qc-script \"%s.qc\"\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// description
|
||||
FS_Printf(f,"//=======================================================================\n");
|
||||
FS_Printf(f,"//\t\t\tCopyright XashXT Group 2007 ©\n");
|
||||
FS_Printf(f,"//\t\t\twritten by Xash Miptex Decompiler\n", name );
|
||||
FS_Printf(f,"//=======================================================================\n");
|
||||
|
||||
// sprite header
|
||||
FS_Printf(f, "\n$spritename\t%s.spr\n", name );
|
||||
FS_Printf(f, "$type\t\t%s\n",SPR_RenderType());
|
||||
FS_Printf(f, "$texture\t\t%s\n\n",SPR_RenderMode());
|
||||
|
||||
// frames description
|
||||
for( i = 0; i < spr.totalframes - spr.numgroup; i++)
|
||||
{
|
||||
FS_Printf(f,"$load\t\t%s.%s\n", spr.frame[i].name, 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]);
|
||||
}
|
||||
|
||||
for( i = 0; i < spr.numgroup; i++ )
|
||||
{
|
||||
FS_Print(f, "$group\n{\n" );
|
||||
for( j = 0; j < spr.group[i].numframes; j++)
|
||||
{
|
||||
FS_Printf(f,"\t$load\t\t%s.%s\n", spr.group[i].frame[j].name, 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" );
|
||||
else FS_Printf(f, " %d %d\n", spr.group[i].frame[j].origin[0],spr.group[i].frame[j].origin[1]);
|
||||
}
|
||||
FS_Print(f, "}\n" );
|
||||
}
|
||||
|
||||
FS_Print(f,"\n" );
|
||||
FS_Close(f);
|
||||
Msg("%s.spr\n", name ); // echo to console about current sprite
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvSPR
|
||||
============
|
||||
*/
|
||||
bool ConvSPR( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
int i, version;
|
||||
dframetype_t *pframetype;
|
||||
string scriptname;
|
||||
rgbdata_t *pal = NULL;
|
||||
dspriteq1_t *pin;
|
||||
dspritehl_t *pinhl;
|
||||
short *numi;
|
||||
|
||||
pin = (dspriteq1_t *)buffer;
|
||||
version = LittleLong( pin->version );
|
||||
memset( &spr, 0, sizeof(spr));
|
||||
|
||||
if( pin->ident != IDSPRQ1HEADER )
|
||||
{
|
||||
Msg("\"%s\" have invalid header\n", name );
|
||||
return false;
|
||||
}
|
||||
switch( version )
|
||||
{
|
||||
case SPRITEQ1_VERSION:
|
||||
spr.totalframes = LittleLong( pin->numframes );
|
||||
spr.texFormat = SPR_ALPHTEST; // constant
|
||||
spr.type = LittleLong( pin->type );
|
||||
pframetype = (dframetype_t *)(pin + 1);
|
||||
spr.truecolor = false;
|
||||
break;
|
||||
case SPRITE32_VERSION:
|
||||
spr.totalframes = LittleLong( pin->numframes );
|
||||
spr.texFormat = SPR_ADDITIVE; // constant
|
||||
spr.type = LittleLong( pin->type );
|
||||
|
||||
pframetype = (dframetype_t *)(pin + 1);
|
||||
spr.truecolor = true;
|
||||
break;
|
||||
case SPRITEHL_VERSION:
|
||||
pinhl = (dspritehl_t *)buffer; // reorganize header
|
||||
spr.totalframes = LittleLong( pinhl->numframes );
|
||||
spr.texFormat = LittleLong( pinhl->texFormat );
|
||||
spr.type = LittleLong( pinhl->type );
|
||||
numi = (short *)(pinhl + 1);
|
||||
spr.truecolor = false;
|
||||
|
||||
if( LittleShort( *numi ) == 256 )
|
||||
{
|
||||
byte *src = (byte *)(numi + 1);
|
||||
|
||||
// install palette
|
||||
switch( spr.texFormat )
|
||||
{
|
||||
case SPR_INDEXALPHA:
|
||||
pal = FS_LoadImage( "#decal.pal", src, 768 );
|
||||
break;
|
||||
case SPR_ALPHTEST:
|
||||
pal = FS_LoadImage( "#transparent.pal", src, 768 );
|
||||
break;
|
||||
case SPR_NORMAL:
|
||||
case SPR_ADDGLOW:
|
||||
case SPR_ADDITIVE:
|
||||
default:
|
||||
pal = FS_LoadImage( "#normal.pal", src, 768 );
|
||||
break;
|
||||
}
|
||||
|
||||
// get frametype for first frame
|
||||
pframetype = (dframetype_t *)(src + 768);
|
||||
FS_FreeImage( pal ); // palette installed, no reason to keep this data
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg("\"%s.spr\" have invalid palette size\n", name );
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Msg("\"%s.spr\" unknown version\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// save frames as normal images
|
||||
for (i = 0; i < spr.totalframes; i++ )
|
||||
{
|
||||
frametype_t frametype = LittleLong( pframetype->type );
|
||||
|
||||
if( frametype == SPR_SINGLE )
|
||||
{
|
||||
pframetype = (dframetype_t *)SPR_ConvertFrame( name, ext, (pframetype + 1), i, 0 );
|
||||
}
|
||||
else if( frametype == SPR_GROUP )
|
||||
{
|
||||
pframetype = (dframetype_t *)SPR_ConvertGroup( name, ext, (pframetype + 1), i );
|
||||
}
|
||||
if( pframetype == NULL ) break; // technically an error
|
||||
}
|
||||
|
||||
// write script file and out
|
||||
FS_FileBase( name, scriptname );
|
||||
return SPR_WriteScript( scriptname, ext );
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_sprite2.c - convert quake2 sprites
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
bool PCX_ConvertImage( const char *name, char *buffer, int filesize );
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.SP2 sprite file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
#define SPRITEQ2_VERSION 2
|
||||
#define IDSPRQ2HEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDS2"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int origin_x;
|
||||
int origin_y; // raster coordinates inside pic
|
||||
char name[64]; // name of pcx file
|
||||
} dsprframeq2_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
int numframes;
|
||||
dsprframeq2_t frames[1]; // variable sized
|
||||
} dspriteq2_t;
|
||||
|
||||
//
|
||||
// sprite2_decompiler.c
|
||||
//
|
||||
void SP2_ConvertFrame( const char *name, const char *ext, int framenum )
|
||||
{
|
||||
byte *fin;
|
||||
int filesize;
|
||||
|
||||
// store framename
|
||||
FS_FileBase( name, spr.frame[framenum].name );
|
||||
|
||||
fin = FS_LoadFile( name, &filesize );
|
||||
ConvPCX( name, fin, filesize, ext );
|
||||
if( fin ) Mem_Free( fin ); // release buffer
|
||||
}
|
||||
|
||||
bool SP2_WriteScript( const char *name )
|
||||
{
|
||||
int i;
|
||||
file_t *f = FS_Open( va("%s/sprites/%s.qc", gs_gamedir, name ), "w" );
|
||||
|
||||
if( !f )
|
||||
{
|
||||
Msg("Can't write qc-script \"%s.qc\"\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// description
|
||||
FS_Printf(f,"//=======================================================================\n");
|
||||
FS_Printf(f,"//\t\t\tCopyright XashXT Group 2007 ©\n");
|
||||
FS_Printf(f,"//\t\t\twritten by Xash Miptex Decompiler\n", name );
|
||||
FS_Printf(f,"//=======================================================================\n");
|
||||
|
||||
// sprite header
|
||||
FS_Printf(f, "\n$spritename\t%s.spr\n", name );
|
||||
FS_Printf(f, "$type\t\t%s\n",SPR_RenderType());
|
||||
FS_Printf(f, "$texture\t\t%s\n\n",SPR_RenderMode());
|
||||
|
||||
// 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,"$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]);
|
||||
}
|
||||
|
||||
FS_Close(f);
|
||||
Msg("%s.sp2\n", name ); // echo to console about current sprite
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvSP2
|
||||
============
|
||||
*/
|
||||
bool ConvSP2( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
dspriteq2_t *pin;
|
||||
string scriptname;
|
||||
int i;
|
||||
|
||||
pin = (dspriteq2_t *)buffer;
|
||||
memset( &spr, 0, sizeof(spr));
|
||||
|
||||
if( LittleLong(pin->ident) != IDSPRQ2HEADER || LittleLong(pin->version) != SPRITEQ2_VERSION )
|
||||
{
|
||||
Msg("\"%s.spr\" it's not a Quake2 sprite\n", name );
|
||||
return false;
|
||||
}
|
||||
spr.totalframes = LittleLong( pin->numframes );
|
||||
spr.texFormat = SPR_ALPHTEST; // constant
|
||||
spr.type = SPR_VP_PARALLEL;
|
||||
|
||||
// byte swap everything
|
||||
for(i = 0; i < spr.totalframes; i++)
|
||||
{
|
||||
spr.frame[i].width = LittleLong(pin->frames[i].width);
|
||||
spr.frame[i].height = LittleLong(pin->frames[i].height);
|
||||
spr.frame[i].origin[0] = LittleLong(pin->frames[i].origin_x);
|
||||
spr.frame[i].origin[1] = LittleLong(pin->frames[i].origin_y);
|
||||
SP2_ConvertFrame( pin->frames[i].name, ext, i );
|
||||
}
|
||||
|
||||
// write script file and out
|
||||
FS_FileBase( name, scriptname );
|
||||
return SP2_WriteScript( scriptname );
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// conv_vtfimage.c - convert vtf materials
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
/*
|
||||
=============
|
||||
ConvVTF
|
||||
=============
|
||||
*/
|
||||
bool ConvVTF( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic;
|
||||
|
||||
FS_StripExtension((char *)name );
|
||||
pic = FS_LoadImage( va( "#%s.vtf", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
// NOTE: save vtf textures into dds for speedup reson
|
||||
// also avoid unneeded convertations DXT->RGBA->DXT
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic ); // save converted image
|
||||
Conv_CreateShader( name, pic, "vtf", NULL, 0, 0 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg( "%s.vtf\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_wadlumps.c - convert wad lumps
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "mathlib.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
/*
|
||||
============
|
||||
ConvSKN
|
||||
============
|
||||
*/
|
||||
bool ConvSKN( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.flt", buffer, filesize );
|
||||
string savedname, skinname, wad;
|
||||
|
||||
if( pic )
|
||||
{
|
||||
com.strncpy( savedname, name, MAX_STRING );
|
||||
FS_ExtractFilePath( name, wad );
|
||||
FS_StripExtension( savedname );
|
||||
FS_FileBase( savedname, skinname );
|
||||
|
||||
FS_SaveImage( va("%s/sprites/%s.%s", gs_gamedir, savedname, ext ), pic );
|
||||
Skin_CreateScript( wad, skinname, pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s/%s.flat\n", wad, skinname ); // echo to console about current skin
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvFLT
|
||||
============
|
||||
*/
|
||||
bool ConvFLT( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.flt", buffer, filesize );
|
||||
string savedname, tempname, path;
|
||||
|
||||
if( pic )
|
||||
{
|
||||
com.strncpy( savedname, name, MAX_STRING );
|
||||
if( pic->flags & IMAGE_HAVE_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.%s", gs_gamedir, savedname, ext ), pic );
|
||||
Conv_CreateShader( savedname, pic, "flt", NULL, 0, 0 );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.flat\n", savedname ); // echo to console about current texture
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvFLP
|
||||
============
|
||||
*/
|
||||
bool ConvFLP( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.flt", buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension( (char *)name );
|
||||
FS_SaveImage(va("%s/gfx/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.flat\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvMIP
|
||||
============
|
||||
*/
|
||||
bool ConvMIP( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.mip", buffer, filesize );
|
||||
string savedname, path;
|
||||
|
||||
if( pic )
|
||||
{
|
||||
com.strncpy( savedname, name, MAX_STRING );
|
||||
FS_StripExtension( savedname );
|
||||
com.snprintf( path, MAX_STRING, "%s/textures/%s.%s", gs_gamedir, savedname, ext );
|
||||
Conv_CreateShader( savedname, pic, "mip", NULL, 0, 0 ); // replace * with ! in shader too
|
||||
FS_SaveImage( path, pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.mip\n", savedname ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
ConvLMP
|
||||
============
|
||||
*/
|
||||
bool ConvLMP( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
rgbdata_t *pic = FS_LoadImage( va( "#%s.lmp", name ), buffer, filesize );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension( (char *)name );
|
||||
FS_SaveImage(va("%s/%s.%s", gs_gamedir, name, ext ), pic );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.lmp\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// conv_pcximage.c - convert pcximages
|
||||
//=======================================================================
|
||||
|
||||
#include "ripper.h"
|
||||
#include "qc_gen.h"
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.WAL image format (Wally textures)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct wal_s
|
||||
{
|
||||
char name[32];
|
||||
uint width, height;
|
||||
uint offsets[4]; // four mip maps stored
|
||||
char animname[32]; // next frame in animation chain
|
||||
int flags;
|
||||
int contents;
|
||||
int value;
|
||||
} wal_t;
|
||||
|
||||
/*
|
||||
============
|
||||
ConvWAL
|
||||
============
|
||||
*/
|
||||
bool ConvWAL( const char *name, byte *buffer, size_t filesize, const char *ext )
|
||||
{
|
||||
wal_t *wal;
|
||||
string shadername;
|
||||
int flags, value, contents; // wal additional parms
|
||||
rgbdata_t *pic = FS_LoadImage( "#internal.wal", buffer, filesize );
|
||||
|
||||
wal = (wal_t *)buffer;
|
||||
contents = LittleLong( wal->contents );
|
||||
flags = LittleLong( wal->flags );
|
||||
value = LittleLong( wal->value );
|
||||
|
||||
if( pic )
|
||||
{
|
||||
FS_StripExtension((char *)name );
|
||||
FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic ); // save converted image
|
||||
FS_FileBase( name, shadername );
|
||||
Conv_CreateShader( name, pic, "wal", wal->animname, flags, contents );
|
||||
FS_FreeImage( pic ); // release buffer
|
||||
Msg("%s.wal\n", name ); // echo to console about current pic
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
1198
ripper/pr_decomp.c
1198
ripper/pr_decomp.c
File diff suppressed because it is too large
Load Diff
159
ripper/qc_gen.h
159
ripper/qc_gen.h
|
@ -1,159 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// qc_gen.h - sprite\model qc generator
|
||||
//=======================================================================
|
||||
#ifndef QC_GEN_H
|
||||
#define QC_GEN_H
|
||||
|
||||
#include "byteorder.h"
|
||||
|
||||
// sprite types
|
||||
#define SPR_VP_PARALLEL_UPRIGHT 0
|
||||
#define SPR_FACING_UPRIGHT 1
|
||||
#define SPR_VP_PARALLEL 2
|
||||
#define SPR_ORIENTED 3 // all axis are valid
|
||||
#define SPR_VP_PARALLEL_ORIENTED 4
|
||||
|
||||
#define SPR_NORMAL 0 // solid sprite
|
||||
#define SPR_ADDITIVE 1
|
||||
#define SPR_INDEXALPHA 2
|
||||
#define SPR_ALPHTEST 3
|
||||
#define SPR_ADDGLOW 4 // same as additive, but without depthtest
|
||||
|
||||
// q2 wal contents
|
||||
#define CONTENTS_SOLID 0x00000001 // an eye is never valid in a solid
|
||||
#define CONTENTS_WINDOW 0x00000002 // translucent, but not watery
|
||||
#define CONTENTS_AUX 0x00000004
|
||||
#define CONTENTS_LAVA 0x00000008
|
||||
#define CONTENTS_SLIME 0x00000010
|
||||
#define CONTENTS_WATER 0x00000020
|
||||
#define CONTENTS_MIST 0x00000040
|
||||
|
||||
// remaining contents are non-visible, and don't eat brushes
|
||||
#define CONTENTS_AREAPORTAL 0x00008000
|
||||
#define CONTENTS_PLAYERCLIP 0x00010000
|
||||
#define CONTENTS_MONSTERCLIP 0x00020000
|
||||
|
||||
// currents can be added to any other contents, and may be mixed
|
||||
#define CONTENTS_CURRENT_0 0x00040000
|
||||
#define CONTENTS_CURRENT_90 0x00080000
|
||||
#define CONTENTS_CURRENT_180 0x00100000
|
||||
#define CONTENTS_CURRENT_270 0x00200000
|
||||
#define CONTENTS_CURRENT_UP 0x00400000
|
||||
#define CONTENTS_CURRENT_DOWN 0x00800000
|
||||
|
||||
#define CONTENTS_ORIGIN 0x01000000 // removed before BSP'ing an entity
|
||||
|
||||
#define CONTENTS_MONSTER 0x02000000 // should never be on a brush, only in game
|
||||
#define CONTENTS_DEADMONSTER 0x04000000
|
||||
#define CONTENTS_DETAIL 0x08000000 // brushes to be added after vis leafs
|
||||
#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
|
||||
#define CONTENTS_LADDER 0x20000000
|
||||
|
||||
#define SURF_LIGHT 0x00000001 // value will hold the light strength
|
||||
#define SURF_SLICK 0x00000002 // effects game physics
|
||||
#define SURF_SKY 0x00000004 // don't draw, but add to skybox
|
||||
#define SURF_WARP 0x00000008 // turbulent water warp
|
||||
#define SURF_TRANS33 0x00000010 // 33% opacity
|
||||
#define SURF_TRANS66 0x00000020 // 66% opacity
|
||||
#define SURF_FLOWING 0x00000040 // scroll towards angle
|
||||
#define SURF_NODRAW 0x00000080 // don't bother referencing the texture
|
||||
#define SURF_HINT 0x00000100 // make a primary bsp splitter
|
||||
#define SURF_SKIP 0x00000200 // completely ignore, allowing non-closed brushes
|
||||
|
||||
// xash 0.45 surfaces replacement table
|
||||
#define SURF_MIRROR 0x00010000 // mirror surface
|
||||
#define SURF_PORTAL 0x00020000 // portal surface
|
||||
|
||||
//
|
||||
// sprite_qc
|
||||
//
|
||||
typedef struct frame_s
|
||||
{
|
||||
char name[64]; // framename
|
||||
|
||||
int width; // lumpwidth
|
||||
int height; // lumpheight
|
||||
int origin[2]; // monster origin
|
||||
} frame_t;
|
||||
|
||||
typedef struct group_s
|
||||
{
|
||||
frame_t frame[64]; // max groupframes
|
||||
float interval[64]; // frame intervals
|
||||
int numframes; // num group frames;
|
||||
} group_t;
|
||||
|
||||
struct qcsprite_s
|
||||
{
|
||||
group_t group[8]; // 64 frames for each group
|
||||
frame_t frame[512]; // or 512 ungroupped frames
|
||||
|
||||
int type; // rendering type
|
||||
int texFormat; // half-life texture
|
||||
bool truecolor; // spr32
|
||||
byte palette[256][4]; // shared palette
|
||||
|
||||
int numgroup; // groups counter
|
||||
int totalframes; // including group frames
|
||||
} spr;
|
||||
|
||||
//
|
||||
// doom spritemodel_qc
|
||||
//
|
||||
typedef struct angled_s
|
||||
{
|
||||
char name[10]; // copy of skin name
|
||||
|
||||
int width; // lumpwidth
|
||||
int height; // lumpheight
|
||||
int origin[2]; // monster origin
|
||||
byte xmirrored; // swap left and right
|
||||
} angled_t;
|
||||
|
||||
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
|
||||
|
||||
char membername[8]; // current model name, four characsters
|
||||
char animation; // current animation number
|
||||
bool in_progress; // current state
|
||||
} flat;
|
||||
|
||||
_inline const char *SPR_RenderMode( void )
|
||||
{
|
||||
switch( spr.texFormat )
|
||||
{
|
||||
case SPR_ADDGLOW: return "glow";
|
||||
case SPR_ALPHTEST: return "alphatest";
|
||||
case SPR_INDEXALPHA: return "indexalpha";
|
||||
case SPR_ADDITIVE: return "additive";
|
||||
case SPR_NORMAL: return "solid";
|
||||
default: return "normal";
|
||||
}
|
||||
}
|
||||
|
||||
_inline const char *SPR_RenderType( void )
|
||||
{
|
||||
switch( spr.type )
|
||||
{
|
||||
case SPR_ORIENTED: return "oriented";
|
||||
case SPR_VP_PARALLEL: return "vp_parallel";
|
||||
case SPR_FACING_UPRIGHT: return "facing_upright";
|
||||
case SPR_VP_PARALLEL_UPRIGHT: return "vp_parallel_upright";
|
||||
case SPR_VP_PARALLEL_ORIENTED: return "vp_parallel_oriented";
|
||||
default: return "oriented";
|
||||
}
|
||||
}
|
||||
|
||||
void Skin_FinalizeScript( void );
|
||||
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 );
|
||||
bool Conv_CheckMap( const char *mapname );
|
||||
bool Conv_CheckWad( const char *wadname );
|
||||
|
||||
#endif//QC_GEN_H
|
|
@ -1,176 +0,0 @@
|
|||
# Microsoft Developer Studio Project File - Name="ripper" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=ripper - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ripper.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ripper.mak" CFG="ripper - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ripper - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "ripper - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ripper - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\temp\ripper\!release"
|
||||
# PROP Intermediate_Dir "..\temp\ripper\!release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLATFORM_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "./" /I "../public" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# 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 msvcrt.lib /nologo /dll /profile /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\ripper\!release
|
||||
InputPath=\Xash3D\src_main\temp\ripper\!release\ripper.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\ripper.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\ripper.dll "D:\Xash3D\bin\ripper.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ripper - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\temp\ripper\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\ripper\!debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLATFORM_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /I "./" /I "../public" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# 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 msvcrt.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /incremental:no /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\ripper\!debug
|
||||
InputPath=\Xash3D\src_main\temp\ripper\!debug\ripper.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\ripper.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\ripper.dll "D:\Xash3D\bin\ripper.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ripper - Win32 Release"
|
||||
# Name "ripper - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_bsplumps.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_jpgimage.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_main.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_pcximage.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_raw.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_shader.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_sound.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_sprite.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_sprite2.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_vtfimage.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_wadlumps.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\conv_wally.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\qc_gen.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ripper.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
53
todo.log
53
todo.log
|
@ -13,62 +13,29 @@ fopen
|
|||
|
||||
Отложенные задачи:
|
||||
1. Поддержка loop для ogg vorbis
|
||||
2. перенести ripper.dll в common.dll
|
||||
3. doom snd extractor (write PCM header 8bit 11kHz, dump data)
|
||||
|
||||
GLOBAL: Достигнуть уровня xash 0.45 к очередному релизу
|
||||
|
||||
0. Откат версии до 13 сентября OK
|
||||
1. Рефакторинг ImageLib OK
|
||||
2. Загрузка спрайтов\моделей при помощи ImageLib OK
|
||||
3. Софтверный загрузчик DDS OK
|
||||
4. Правильная растановка сторон для dds OK
|
||||
5. переместить PFDesc в launch.dll OK
|
||||
6. запрос для принудительной распаковки DXT
|
||||
7. поддержка vtf - файлов
|
||||
8. поддержка BGRA - форматов (VTF)
|
||||
9. Полная отладка ImageLib
|
||||
10. Отладка extragen
|
||||
11. дописать Image_SaveDDS
|
||||
12. избавится от непрямых путей в экстрагене
|
||||
|
||||
По умолчанию все картинки распаковываются в RGBA_32.
|
||||
Однако, если выставить флаг IL_DDS_HARDWARE, to DDS картинки разжиматься не будут, оставляя работу для
|
||||
рендера. Флаг IL_PALETTED_ONLY заставляет систему игнорировать все неиндексированные изображения.
|
||||
|
||||
|
||||
Логика работы:
|
||||
HOST_NORMAL - все картинки требуются в RGBA_32, но DDS предпочтительнее разжимать видеокартой
|
||||
! никогда не разжимать dds-кубемапы (поскольку они всегда имеют кратный размер), но всегда
|
||||
разжимать skybox
|
||||
HOST_BSPLIB - все картинки в PF_RGBA_32 всегда
|
||||
HOST_SPRITE, HOST_STUDIO, HOST_WADLIB, HOST_RIPPER - не распаковывать проиндексированные картинки, не трогать палитру
|
||||
|
||||
1. запрос для принудительной распаковки DXT
|
||||
2. упаковщик DXT1-3-5 для Image_Process
|
||||
3. Полная отладка ImageLib
|
||||
|
||||
операция "Имплементация рендера от q2e_068"
|
||||
0. имплементация backend
|
||||
|
||||
операция "Отладка: bsp 48
|
||||
0. отладка qbsp3
|
||||
1. починить подсчет строк для Com_GetToken OK
|
||||
2. подправить рендер с учетом новых констатнт
|
||||
2. подправить рендер с учетом новых констант
|
||||
3. переписать менеджер текстур на рендере
|
||||
4. переписать загрузчик текстур с учетом новой идеологии
|
||||
5. раз и навсегда пофиксить R_ImageFreeUnused
|
||||
6. создать Com_Assert в виде дефайна Sys_Break
|
||||
7. Заюзать матрицы 3x3 на сервере
|
||||
4. раз и навсегда пофиксить R_ImageFreeUnused
|
||||
5. создать Com_Assert в виде дефайна Sys_Break OK
|
||||
6. Заюзать матрицы 3x3 на сервере
|
||||
7. быстрые memset, memcpy, sqrt OK
|
||||
8. создать fast mathlib OK
|
||||
|
||||
Новый загрузчик текстур:
|
||||
0. сравнить скорость загрузки видеокартой\софтверным загрузчиком OK (видеокарта однозначно бырее)
|
||||
1. сравнить скорость загрузки софтверным загрузчиком из DDSlib OK (старый загрузчик немного бырее)
|
||||
2. все картинки при загрузке распаковываются в PF_RGB_24 (если нет альфы), либо в PF_RGBA_32 (если альфа есть)
|
||||
3. все кубемапы собираются в один большой архив из PF_RGB_24 * 6 (у кубемапов альфы никогда не бывает)
|
||||
4. доступ к стороне осуществляется при помощи функции FS_GetCubemapSide, после загрузки при помощи FS_LoadImage
|
||||
5. доступ осуществляется либо по номеру. либо по суффиксу (но по номеру, ИМХО удобнее)
|
||||
6. при некоторых инстанциях проиндексированные изображения не распаковываются в 32 и 24 битные, поскольку
|
||||
их необходимо сохранить в восьмибитном формате.
|
||||
7. DDS должен разжиматься весь в launch.dll по идее
|
||||
8. Расширение matrixlib - Matrix3x3
|
||||
1. Расширение matrixlib - Matrix3x3
|
||||
|
||||
1. r_backend.c:1335
|
||||
2. r_backend.c:1338
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <commctrl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
|
||||
#include "mxtk.h"
|
||||
|
|
|
@ -380,8 +380,7 @@ write advanced progdefs.h into disk
|
|||
word PR_WriteProgdefs( void )
|
||||
{
|
||||
char file[PROGDEFS_MAX_SIZE];
|
||||
char header_name[MAX_QPATH];
|
||||
char lwr_header[MAX_QPATH];
|
||||
string header_name, lwr_header;
|
||||
char lwr_prefix[8], upr_prefix[8];
|
||||
char array_size[8]; // g-cont: mega name!
|
||||
int f = 0, k = 1;
|
||||
|
@ -934,32 +933,32 @@ byte *PR_CreateProgsSRC( void )
|
|||
search_t *qc = FS_Search( "*", true );
|
||||
const char *datname = "unknown.dat\n"; // outname will be set by PR_WriteProgdefs
|
||||
byte *newprogs_src = NULL;
|
||||
char headers[2][MAX_QPATH]; // contains filename with struct description
|
||||
char searchmask[8][16];
|
||||
int i, k, j = 0;
|
||||
string headers[2]; // contains filename with struct description
|
||||
bool have_entvars = 0;
|
||||
bool have_globals = 0;
|
||||
int i, k, j = 0;
|
||||
|
||||
// hard-coded table! don't change!
|
||||
com.strcpy(searchmask[0], "qh" ); // quakec header
|
||||
com.strcpy(searchmask[1], "h" ); // c-style header
|
||||
com.strcpy(searchmask[2], "qc" ); // quakec sources
|
||||
com.strcpy(searchmask[3], "c" ); // c-style sources
|
||||
// hardcoded table! don't change!
|
||||
com.strcpy( searchmask[0], "qh" ); // quakec header
|
||||
com.strcpy( searchmask[1], "h" ); // c-style header
|
||||
com.strcpy( searchmask[2], "qc" ); // quakec sources
|
||||
com.strcpy( searchmask[3], "c" ); // c-style sources
|
||||
|
||||
if(!qc)
|
||||
{
|
||||
PR_ParseError(ERR_INTERNAL, "Couldn't open file progs.src" );
|
||||
return NULL;
|
||||
}
|
||||
memset(headers, '/0', 2 * MAX_QPATH);
|
||||
memset( headers, '/0', MAX_STRING * 2 );
|
||||
|
||||
for(i = 0; i < qc->numfilenames; i++)
|
||||
for( i = 0; i < qc->numfilenames; i++ )
|
||||
{
|
||||
// search by mask
|
||||
for( k = 0; k < 8; k++)
|
||||
{
|
||||
// skip blank mask
|
||||
if(!com.strlen(searchmask[k])) continue;
|
||||
if(!com.strlen( searchmask[k] )) continue;
|
||||
if(!com.stricmp(searchmask[k], FS_FileExtension(qc->filenames[i]))) // validate ext
|
||||
{
|
||||
if(Com_LoadScript( qc->filenames[i], NULL, 0 ))
|
||||
|
@ -970,15 +969,15 @@ byte *PR_CreateProgsSRC( void )
|
|||
if(!Com_GetToken( true )) break; //EOF
|
||||
if(Com_MatchToken( "end_sys_globals" ))
|
||||
{
|
||||
com.strncpy(headers[0], qc->filenames[i], MAX_QPATH );
|
||||
com.strncpy( headers[0], qc->filenames[i], MAX_STRING );
|
||||
have_globals = true;
|
||||
}
|
||||
else if(Com_MatchToken( "end_sys_fields" ))
|
||||
{
|
||||
com.strncpy(headers[1], qc->filenames[i], MAX_QPATH );
|
||||
com.strncpy( headers[1], qc->filenames[i], MAX_STRING );
|
||||
have_entvars = true;
|
||||
}
|
||||
if(have_globals && have_entvars)
|
||||
if( have_globals && have_entvars )
|
||||
goto buildnewlist; // end of parsing
|
||||
}
|
||||
}
|
||||
|
@ -987,12 +986,12 @@ byte *PR_CreateProgsSRC( void )
|
|||
}
|
||||
|
||||
// globals and locals not declared
|
||||
PR_ParseError(ERR_INTERNAL, "Couldn't open file progs.src" );
|
||||
PR_ParseError( ERR_INTERNAL, "Couldn't open file progs.src" );
|
||||
return NULL;
|
||||
buildnewlist:
|
||||
|
||||
newprogs_src = Qrealloc(newprogs_src, j + com.strlen(datname) + 1); // outfile name
|
||||
Mem_Copy(newprogs_src + j, (char *)datname, com.strlen(datname));
|
||||
newprogs_src = Qrealloc( newprogs_src, j + com.strlen( datname ) + 1 ); // outfile name
|
||||
Mem_Copy( newprogs_src + j, (char *)datname, com.strlen( datname ));
|
||||
j += com.strlen(datname) + 1; // null term
|
||||
|
||||
// file contains "sys_globals" and possible "sys_fields"
|
||||
|
@ -1000,16 +999,16 @@ buildnewlist:
|
|||
com.strncat(newprogs_src, va("%s\n", headers[0]), com.strlen(headers[0]) + 1);
|
||||
j += com.strlen(headers[0]) + 2; //null term
|
||||
|
||||
if(STRCMP(headers[0], headers[1] ))
|
||||
if(STRCMP( headers[0], headers[1] ))
|
||||
{
|
||||
// file contains sys_fields description
|
||||
newprogs_src = Qrealloc(newprogs_src, j + com.strlen(headers[1]) + 2); // second file (option)
|
||||
com.strncat(newprogs_src, va("%s\n", headers[1]), com.strlen(headers[1]) + 1);
|
||||
newprogs_src = Qrealloc( newprogs_src, j + com.strlen( headers[1] ) + 2 ); // second file (option)
|
||||
com.strncat( newprogs_src, va("%s\n", headers[1]), com.strlen(headers[1]) + 1);
|
||||
j += com.strlen(headers[1]) + 2; //null term
|
||||
}
|
||||
|
||||
// add headers
|
||||
for(i = 0; i < qc->numfilenames; i++)
|
||||
for( i = 0; i < qc->numfilenames; i++ )
|
||||
{
|
||||
for( k = 0; k < 2; k++)
|
||||
{
|
||||
|
@ -1044,7 +1043,7 @@ buildnewlist:
|
|||
}
|
||||
}
|
||||
Mem_Free( qc ); // free search
|
||||
FS_WriteFile("progs.src", newprogs_src, j );
|
||||
FS_WriteFile( "progs.src", newprogs_src, j );
|
||||
|
||||
return newprogs_src;
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
#define VPROGS_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
#include "pr_local.h"
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
#define SOUND_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <dsound.h>
|
||||
#include "basetypes.h"
|
||||
#include "launch_api.h"
|
||||
#include "ref_dllapi.h"
|
||||
#include "s_openal.h"
|
||||
|
||||
|
|
12
xash.dsw
12
xash.dsw
|
@ -75,18 +75,6 @@ Package=<4>
|
|||
|
||||
###############################################################################
|
||||
|
||||
Project: "ripper"=".\ripper\ripper.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "viewer"=".\viewer\viewer.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
|
|
Reference in New Issue