28 Oct 2008

This commit is contained in:
g-cont 2008-10-28 00:00:00 +03:00 committed by Alibek Omarov
parent 64cdd0a43b
commit 15dbaeb3aa
87 changed files with 4241 additions and 4074 deletions

View File

@ -17,7 +17,6 @@ baserc\
viewer\
physic\
render\
ripper\
vprogs\
vsound\
common\

View File

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

View File

@ -5,6 +5,7 @@
#ifndef BSPLIB_H
#define BSPLIB_H
#include <stdio.h>
#include "platform.h"
#include "utils.h"
#include "mathlib.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

702
common/ripper/conv_doom.c Normal file
View File

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

163
common/ripper/conv_image.c Normal file
View File

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

View File

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

View File

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

451
common/ripper/conv_sprite.c Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1187
launch/amd3dx.h Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

24
public/baserc_api.h Normal file
View File

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

View File

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

View File

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

View File

@ -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__ );
/*
===========================================

View File

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

View File

@ -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;
/*
==============================================================================

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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