18 Dec 2007

This commit is contained in:
g-cont 2007-12-18 00:00:00 +03:00 committed by Alibek Omarov
parent 92396fe31f
commit 8142611b41
14 changed files with 761 additions and 62 deletions

View File

@ -36,6 +36,10 @@ scroll = visible_offset
1. Избавиться от short side в dface_t (перевести рендер в новый режим работы)
2. сжать entlump зипом
3. добавить LUMP_MAPINFO (для быстрого поиска имени карты)
4. переписать все свапы для лумпов
5. придумать как уменьшить размер карты
научить imagelib читать якобы поврежденные вады (gfx.wad, fonts.wad, cached.wad)
typedef struct
{
@ -48,9 +52,13 @@ typedef struct
} dmapinfo_t;
1. пофиксить чтение хл-текстур (для декалей)
2. исключить добавление одинаковых вадов
//==================================================
// то, что уже готово
//==================================================
+добавлена поддержка wad-файлов
+наконец-то добавлена аппаратная гамма
+добавлена загрузка мипмапов для всех типов текстур
+пофикшен баг с загрузкой мипмпов

View File

@ -33,7 +33,7 @@ void CalcTextureReflectivity (void)
// see if an earlier texinfo allready got the value
for (j = 0; j < i; j++)
{
if(!com.strcmp(GetStringFromTable(texinfo[i].texid), GetStringFromTable(texinfo[j].texid)))
if( texinfo[i].texid == texinfo[j].texid )
{
VectorCopy (texture_reflectivity[j], texture_reflectivity[i]);
break;

View File

@ -112,6 +112,7 @@ void RunPlatform ( void )
strcpy(searchmask[2], "*.wal" ); // quake2 textures
strcpy(searchmask[3], "*.lmp" ); // quake1 menu images
strcpy(searchmask[4], "*.mip" ); // quake1 textures
strcpy(searchmask[5], ".wad3" ); // half-life textures
Msg("Processing images ...\n\n");
break;
case BSPLIB:
@ -143,12 +144,14 @@ void RunPlatform ( void )
zonepool = Mem_AllocPool("compiler");
if(!FS_GetParmFromCmdLine("-file", filename ))
{
//search by mask
// search by mask
for( i = 0; i < 8; i++)
{
// skip blank mask
if(!strlen(searchmask[i])) continue;
search = FS_Search( searchmask[i], true );
if(com.stricmp(searchmask[i], ".wad3" ))
search = FS_Search( searchmask[i], true );
else search = FS_SearchLump( "*", true ); // hl-textures
if(!search) continue; // try next mask
for( j = 0; j < search->numfilenames; j++ )

View File

@ -611,5 +611,6 @@ void Cmd_Init( void )
Cmd_AddCommand ("wait", Cmd_Wait_f, "make script execution wait for some rendered frames" );
Cmd_AddCommand ("cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" );
Cmd_AddCommand ("stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in init.rc script)" );
}
Memory_Init_Commands(); // memlib stats
}

View File

@ -5,6 +5,7 @@
#include "launch.h"
#include "zip32.h"
#include "image.h"
#define ZIP_END_CDIR_SIZE 22
#define ZIP_CDIR_CHUNK_BASE_SIZE 46
@ -70,6 +71,14 @@ typedef struct pack_s
packfile_t *files;
} pack_t;
typedef struct wadfile_s
{
char name[64];
int numlumps;
file_t *file;
dlumpinfo_t *lumps;
} wadfile_t;
typedef struct searchpath_s
{
char filename[MAX_SYSPATH];
@ -86,6 +95,7 @@ typedef struct stringlist_s
} stringlist_t;
byte *fs_mempool;
byte *fs_searchwads = NULL;
searchpath_t *fs_searchpaths = NULL;
static void FS_InitMemory( void );
@ -698,7 +708,7 @@ pack_t *FS_LoadPackPAK(const char *packfile)
}
Mem_Free(info);
MsgDev(D_INFO, "Adding packfile %s (%i files)\n", packfile, numpackfiles);
MsgDev(D_INFO, "Adding packfile: %s (%i files)\n", packfile, numpackfiles);
return pack;
}
@ -959,6 +969,95 @@ void FS_AddGameDirectory (const char *dir)
fs_searchpaths = search;
}
/*
====================
FS_AddWad3File
====================
*/
static bool FS_AddWad3File( const char *filename )
{
dwadinfo_t header;
wadfile_t *w;
int infotableofs;
file_t *file;
int i, numlumps;
if(!fs_searchwads) // start from scratch
fs_searchwads = Mem_CreateArray( fs_mempool, sizeof(wadfile_t), 16 );
for (i = 0; i < Mem_ArraySize( fs_searchwads ); i++ )
{
w = Mem_GetElement( fs_searchwads, i );
if(w && !com_stricmp( filename, w->name ))
return false; // already loaded
}
file = FS_Open( filename, "rb" );
if(!file)
{
MsgDev(D_ERROR, "FS_AddWad3File: couldn't find %s\n", filename);
return false;
}
if( FS_Read(file, &header, sizeof(dwadinfo_t)) != sizeof(dwadinfo_t))
{
MsgDev(D_ERROR, "FS_AddWad3File: %s have corrupted header\n");
FS_Close( file );
return false;
}
if( header.ident != IDWAD3HEADER )
{
MsgDev(D_ERROR, "FS_AddWad3File: %s have invalid ident\n", filename );
FS_Close( file );
return false;
}
numlumps = LittleLong( header.numlumps );
if( numlumps > MAX_FILES_IN_PACK )
{
MsgDev(D_ERROR, "FS_AddWad3File: %s have too many lumps (%i)\n", numlumps);
FS_Close( file );
return false;
}
infotableofs = LittleLong( header.infotableofs );
if(FS_Seek (file, infotableofs, SEEK_SET))
{
MsgDev(D_ERROR, "FS_AddWad3File: unable to seek to lump table\n");
FS_Close( file );
return false;
}
w = Mem_AllocElement( fs_searchwads );
com_strncpy( w->name, filename, sizeof(w->name));
w->file = file;
w->numlumps = numlumps;
w->lumps = Mem_Alloc( fs_mempool, w->numlumps * sizeof(dlumpinfo_t));
if(FS_Read(file, w->lumps, sizeof(dlumpinfo_t) * w->numlumps) != (long)sizeof(dlumpinfo_t) * numlumps)
{
MsgDev(D_ERROR, "FS_AddWad3File: unable to read lump table\n");
FS_Close( w->file );
w->numlumps = 0;
Mem_Free( w->lumps );
w->lumps = NULL;
w->name[0] = 0;
return false;
}
// swap everthing
for (i = 0; i < numlumps; i++)
{
w->lumps[i].filepos = LittleLong(w->lumps[i].filepos);
w->lumps[i].disksize = LittleLong(w->lumps[i].disksize);
w->lumps[i].size = LittleLong(w->lumps[i].size);
com_strnlwr(w->lumps[i].name, w->lumps[i].name, sizeof(w->lumps[i].name));
}
// and leaves the file open
MsgDev(D_INFO, "Adding wadfile: %s (%i lumps)\n", filename, numlumps );
return true;
}
/*
================
@ -967,8 +1066,20 @@ FS_AddGameHierarchy
*/
void FS_AddGameHierarchy (const char *dir)
{
search_t *search;
int i, numWads = 0;
// Add the common game directory
if(dir || *dir)FS_AddGameDirectory (va("%s%s/", fs_basedir, dir));
if(dir || *dir)
{
FS_AddGameDirectory (va("%s%s/", fs_basedir, dir));
search = FS_Search( "*.wad", true );
if(!search) return;
for( i = 0; i < search->numfilenames; i++ )
FS_AddWad3File( search->filenames[i] );
Mem_Free( search );
}
}
@ -1037,6 +1148,9 @@ FS_ClearSearchPath
*/
void FS_ClearSearchPath (void)
{
uint i;
wadfile_t *w;
while (fs_searchpaths)
{
searchpath_t *search = fs_searchpaths;
@ -1049,6 +1163,20 @@ void FS_ClearSearchPath (void)
}
Mem_Free(search);
}
// close all wad files and free their lumps data
for (i = 0; i < Mem_ArraySize( fs_searchwads ); i++ )
{
w = Mem_GetElement( fs_searchwads, i );
if(!w) continue;
if(w->lumps) Mem_Free(w->lumps);
w->lumps = NULL;
if(w->file) FS_Close(w->file);
w->file = NULL;
w->name[0] = 0;
}
if( fs_searchwads ) Mem_RemoveArray( fs_searchwads );
fs_searchwads = NULL;
}
/*
@ -1206,7 +1334,10 @@ void FS_LoadGameInfo( const char *filename )
com_strcpy(GI.key, SC_GetToken( false ));
}
}
if(fs_modified) FS_Rescan(); // create new filesystem
if( fs_modified )
{
FS_Rescan(); // create new filesystem
}
}
/*
@ -1298,6 +1429,23 @@ FS_Shutdown
*/
void FS_Shutdown (void)
{
wadfile_t *w;
int i;
// close all wad files and free their lumps data
for (i = 0; i < Mem_ArraySize( fs_searchwads ); i++ )
{
w = Mem_GetElement( fs_searchwads, i );
if(!w) continue;
if(w->lumps) Mem_Free(w->lumps);
w->lumps = NULL;
if(w->file) FS_Close(w->file);
w->file = NULL;
w->name[0] = 0;
}
if( fs_searchwads ) Mem_RemoveArray( fs_searchwads );
fs_searchwads = NULL;
Mem_FreePool(&fs_mempool);
}
@ -1557,6 +1705,118 @@ file_t *FS_OpenReadFile (const char *filename, const char *mode, bool quiet, boo
return FS_OpenPackedFile (search->pack, pack_ind);
}
search_t *FS_SearchLump( const char *pattern, int caseinsensitive )
{
stringlist_t resultlist;
search_t *search = NULL;
int i, k, resultlistindex, numfiles, numchars;
wadfile_t *w;
// no wads loaded
if(!fs_searchwads) return NULL;
stringlistinit(&resultlist);
for( k = 0; k < Mem_ArraySize( fs_searchwads ); k++ )
{
// lookup all wads in list
w = (wadfile_t *)Mem_GetElement( fs_searchwads, k );
if( !w ) continue;
for(i = 0; i < (uint)w->numlumps; i++)
{
if(SC_FilterToken( (char *)pattern, w->lumps[i].name, !caseinsensitive ))
stringlistappend(&resultlist, w->lumps[i].name);
}
}
// sorting result
if (resultlist.numstrings)
{
stringlistsort(&resultlist);
numfiles = resultlist.numstrings;
numchars = 0;
for (resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++)
numchars += (int)com_strlen(resultlist.strings[resultlistindex]) + 1;
search = Malloc(sizeof(search_t) + numchars + numfiles * sizeof(char *));
search->filenames = (char **)((char *)search + sizeof(search_t));
search->filenamesbuffer = (char *)((char *)search + sizeof(search_t) + numfiles * sizeof(char *));
search->numfilenames = (int)numfiles;
numfiles = 0;
numchars = 0;
for (resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++)
{
size_t textlen;
search->filenames[numfiles] = search->filenamesbuffer + numchars;
textlen = com_strlen(resultlist.strings[resultlistindex]) + 1;
Mem_Copy(search->filenames[numfiles], resultlist.strings[resultlistindex], textlen);
numfiles++;
numchars += (int)textlen;
}
}
stringlistfreecontents(&resultlist);
return search;
}
/*
===========
FS_OpenWad3File
Look for a file in the loaded wadfiles and returns buffer with image lump
===========
*/
static byte *FS_OpenWad3File( const char *name, fs_offset_t *filesizeptr )
{
uint i, k;
mip_t *tex;
wadfile_t *w;
char basename[MAX_QPATH];
char texname[17];
// no wads loaded
if(!fs_searchwads) return NULL;
// note: wad images can't have real pathes
// so, extarct base name from path
FS_FileBase( (char *)name, basename );
if(filesizeptr) *filesizeptr = 0;
if(strlen(basename) >= WAD3_NAMELEN )
{
Msg("FS_OpenWad3File: %s too long name\n", basename );
return NULL;
}
com_strnlwr( basename, texname, WAD3_NAMELEN );
for( k = 0; k < Mem_ArraySize( fs_searchwads ); k++ )
{
w = (wadfile_t *)Mem_GetElement( fs_searchwads, k );
if( !w ) continue;
for(i = 0; i < (uint)w->numlumps; i++)
{
if(!com_strcmp(texname, w->lumps[i].name))
{
if(FS_Seek(w->file, w->lumps[i].filepos, SEEK_SET))
{
MsgDev(D_ERROR, "FS_OpenWad3File: corrupt WAD3 file\n");
return NULL;
}
tex = (mip_t *)Mem_Alloc( fs_mempool, w->lumps[i].disksize );
if( FS_Read(w->file, tex, w->lumps[i].size) < w->lumps[i].disksize )
{
MsgDev(D_ERROR, "FS_OpenWad3File: corrupt WAD3 file\n");
return NULL;
}
if(filesizeptr) *filesizeptr = w->lumps[i].disksize;
return (byte *)((mip_t *)tex);
}
}
}
return NULL;
}
/*
=============================================================================
@ -2072,9 +2332,10 @@ Always appends a 0 byte.
*/
byte *FS_LoadFile (const char *path, fs_offset_t *filesizeptr )
{
file_t *file;
byte *buf = NULL;
file_t *file;
byte *buf = NULL;
fs_offset_t filesize = 0;
const char *ext = FS_FileExtension( path );
file = _FS_Open (path, "rb", true, false);
if (file)
@ -2085,8 +2346,13 @@ byte *FS_LoadFile (const char *path, fs_offset_t *filesizeptr )
FS_Read (file, buf, filesize);
FS_Close (file);
}
if (filesizeptr) *filesizeptr = filesize;
else if(!com_stricmp("wad3", ext ))
{
// probably it's image from wad-file
buf = FS_OpenWad3File( path, &filesize );
}
if(filesizeptr) *filesizeptr = filesize;
return buf;
}
@ -2350,11 +2616,13 @@ void FS_Mem_FreeSearch(search_t *search)
void FS_InitMemory( void )
{
fs_mempool = Mem_AllocPool( "file management" );
fs_mempool = Mem_AllocPool( "Filesystem Pool" );
// add a path separator to the end of the basedir if it lacks one
if (fs_basedir[0] && fs_basedir[com_strlen(fs_basedir) - 1] != '/' && fs_basedir[com_strlen(fs_basedir) - 1] != '\\')
com_strncat(fs_basedir, "/", sizeof(fs_basedir));
if( !fs_searchwads ) fs_searchwads = Mem_CreateArray( fs_mempool, sizeof(wadfile_t), 16 );
}
/*

View File

@ -85,6 +85,17 @@ static byte palette_q2[768] =
159,91,83
};
extern int image_width, image_height;
extern byte image_num_layers; // num layers in
extern byte image_num_mips; // build mipmaps
extern uint image_type; // main type switcher
extern uint image_flags; // additional image flags
extern byte image_bits_count; // bits per RGBA
extern size_t image_size; // image rgba size
extern byte *image_palette; // palette pointer
extern byte *image_rgba; // image pointer (see image_type for details)
extern uint image_ptr; // common moveable pointer
// image lib utilites
extern uint *d_currentpal;
void Image_GetQ1Palette( void );

View File

@ -28,6 +28,10 @@ byte *image_cubemap; // cubemap pack
uint cubemap_image_type; // shared image type
char *suf[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
#define LUMP_NORMAL 0
#define LUMP_TRANSPARENT 1
#define LUMP_DECAL 2
uint d_8toD1table[256];
uint d_8toQ1table[256];
uint d_8toQ2table[256];
@ -36,10 +40,20 @@ uint *d_currentpal;
bool d1palette_init = false;
bool q1palette_init = false;
bool q2palette_init = false;
int d_rendermode = LUMP_NORMAL;
//=======================================================================
// IMGLIB COMMON TOOLS
//=======================================================================
void Image_Init( void )
{
Sys.imagepool = Mem_AllocPool( "ImageLib Pool" );
}
void Image_Shutdown( void )
{
Mem_FreePool( &Sys.imagepool );
}
bool Image_ValidSize( char *name )
{
@ -55,20 +69,47 @@ void Image_GetPalette( byte *pal, uint *d_table )
{
int i;
byte rgba[4];
// setup palette
for (i = 0; i < 256; i++)
switch( d_rendermode )
{
rgba[0] = 0xFF;
rgba[3] = pal[i*3+0];
rgba[2] = pal[i*3+1];
rgba[1] = pal[i*3+2];
d_table[i] = BuffBigLong( rgba );
case LUMP_DECAL:
for(i = 0; i < 256; i++)
{
rgba[3] = pal[765];
rgba[2] = pal[766];
rgba[1] = pal[767];
rgba[0] = i;
d_table[i] = BuffBigLong( rgba );
}
break;
case LUMP_TRANSPARENT:
for (i = 0; i < 256; i++)
{
rgba[3] = pal[i*3+0];
rgba[2] = pal[i*3+1];
rgba[1] = pal[i*3+2];
rgba[0] = pal[i] == 255 ? pal[i] : 0xFF;
d_table[i] = BuffBigLong( rgba );
}
break;
case LUMP_NORMAL:
for (i = 0; i < 256; i++)
{
rgba[3] = pal[i*3+0];
rgba[2] = pal[i*3+1];
rgba[1] = pal[i*3+2];
rgba[0] = 0xFF;
d_table[i] = BuffBigLong( rgba );
}
break;
}
}
void Image_GetD1Palette( void )
{
d_rendermode = LUMP_NORMAL;
if(!d1palette_init)
{
Image_GetPalette( palette_d1, d_8toD1table );
@ -80,6 +121,8 @@ void Image_GetD1Palette( void )
void Image_GetQ1Palette( void )
{
d_rendermode = LUMP_NORMAL;
if(!q1palette_init)
{
Image_GetPalette( palette_q1, d_8toQ1table );
@ -91,6 +134,8 @@ void Image_GetQ1Palette( void )
void Image_GetQ2Palette( void )
{
d_rendermode = LUMP_NORMAL;
if(!q2palette_init)
{
Image_GetPalette( palette_q2, d_8toQ2table );
@ -102,6 +147,8 @@ void Image_GetQ2Palette( void )
void Image_GetPalettePCX( byte *pal )
{
d_rendermode = LUMP_NORMAL;
if(pal)
{
Image_GetPalette( pal, d_8to24table );
@ -111,6 +158,19 @@ void Image_GetPalettePCX( byte *pal )
else Image_GetQ2Palette();
}
void Image_GetPaletteWAD( byte *pal, int rendermode )
{
d_rendermode = rendermode;
if(pal)
{
Image_GetPalette( pal, d_8to24table );
d_8to24table[255] &= LittleLong(0xffffff);
d_currentpal = d_8to24table;
}
else Image_GetQ1Palette();
}
/*
============
Image_Copy8bitRGBA
@ -242,7 +302,7 @@ bool Image_Processing( const char *name, rgbdata_t **pix )
byte *out;
char width[4], height[4];
//check for buffers
// check for buffers
if(!image || !image->buffer) return false;
w = image->width;
@ -276,8 +336,8 @@ LoadWAL
bool LoadWAL( char *name, char *buffer, int filesize )
{
wal_t wal;
int pixels, ofs[4], mipsize, nummips = 1;// FIXME, adding four mips ?
int w, h, i, flags, value, contents; // wal additional parms
int pixels, ofs[4], mipsize;// FIXME, adding four mips ?
int i, flags, value, contents; // wal additional parms
if (filesize < (int)sizeof(wal))
{
@ -289,16 +349,16 @@ bool LoadWAL( char *name, char *buffer, int filesize )
flags = LittleLong(wal.flags);
value = LittleLong(wal.value);
contents = LittleLong(wal.contents);
w = image_width = LittleLong(wal.width);
h = image_height = LittleLong(wal.height);
image_width = LittleLong(wal.width);
image_height = LittleLong(wal.height);
for(i = 0; i < 4; i++) ofs[i] = LittleLong(wal.offsets[i]);
if(!Image_ValidSize( name )) return false;
pixels = w * h;
pixels = image_width * image_height;
mipsize = (int)sizeof(wal) + ofs[0] + pixels;
if( pixels > 256 && filesize < mipsize )
{
// wal's width dimensions < 32 have invalid sizes.
// note: wal's with dimensions < 32 have invalid sizes.
MsgWarn("LoadWAL: file (%s) have invalid size\n", name );
return false;
}
@ -307,13 +367,7 @@ bool LoadWAL( char *name, char *buffer, int filesize )
image_type = PF_RGBA_32;
Image_GetQ2Palette(); // hardcoded
for(i = 0; i < nummips; i++ )
{
if(!FS_AddMipmapToPack( buffer + ofs[i], w, h ))
break; // there were errors
w = (w+1)>>1, h = (h+1)>>1; // calc size of next mip
}
return true;
return FS_AddMipmapToPack( buffer + ofs[0], image_width, image_height );
}
/*
@ -377,8 +431,7 @@ LoadMIP
bool LoadMIP( char *name, char *buffer, int filesize )
{
mip_t mip;
int i, w, h;
int ofs[4], mipsize, nummips = 1;// FIXME, adding four mips ?
int i, ofs[4], mipsize;
if (filesize < (int)sizeof(mip))
{
@ -387,9 +440,9 @@ bool LoadMIP( char *name, char *buffer, int filesize )
}
Mem_Copy(&mip, buffer, sizeof(mip));
w = image_width = LittleLong(mip.width);
h = image_height = LittleLong(mip.height);
for(i = 0; i < nummips; i++) ofs[i] = LittleLong(mip.offsets[i]);
image_width = LittleLong(mip.width);
image_height = LittleLong(mip.height);
for(i = 0; i < 4; i++) ofs[i] = LittleLong(mip.offsets[i]);
if(!Image_ValidSize( name )) return false;
mipsize = image_width * image_height;
@ -399,18 +452,65 @@ bool LoadMIP( char *name, char *buffer, int filesize )
MsgWarn("LoadMIP: file (%s) have invalid size\n", name );
return false;
}
image_num_layers = 1;
image_type = PF_RGBA_32;
Image_GetQ1Palette();// hardcoded
for(i = 0; i < nummips; i++ )
return FS_AddMipmapToPack( buffer + ofs[0], image_width, image_height );
}
/*
============
LoadWAD
============
*/
bool LoadWAD( char *name, char *buffer, int filesize )
{
mip_t mip;
byte *pal;
int ofs[4], i, rendermode;
if (filesize < (int)sizeof(mip))
{
if(!FS_AddMipmapToPack( buffer + ofs[i], w, h ))
break; // there were errors
w = (w+1)>>1, h = (h+1)>>1; // calc size of next mip
MsgWarn("LoadWAD_3: file (%s) have invalid size\n", name );
return false;
}
return true;
Mem_Copy(&mip, buffer, sizeof(mip));
image_width = LittleLong(mip.width);
image_height = LittleLong(mip.height);
for(i = 0; i < 4; i++) ofs[i] = LittleLong(mip.offsets[i]);
if(!Image_ValidSize( name )) return false;
pal = buffer + mip.offsets[0] + (((image_width * image_height) * 85)>>6);
pal += 2; // get palette
image_num_layers = 1;
image_type = PF_RGBA_32; // always exctracted to 32-bit buffer
// detect rendermode
if( name[0] == '{' )
{
if(pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255 && pal[255*3+3] == 0)
{
Msg("trans ");
rendermode = LUMP_TRANSPARENT;
}
else
{
Msg("decal ");
rendermode = LUMP_DECAL;
}
image_flags |= IMAGE_HAS_ALPHA;
}
else
{
Msg("normal ");
rendermode = LUMP_NORMAL;
}
Image_GetPaletteWAD( pal, rendermode );
return FS_AddMipmapToPack( buffer + mip.offsets[0], image_width, image_height );
}
/*
@ -1630,6 +1730,7 @@ loadformat_t load_formats[] =
{"textures/%s%s.%s", "dds", LoadDDS},
{"textures/%s%s.%s", "tga", LoadTGA},
{"textures/%s%s.%s", "jpg", LoadJPG},
{"textures/%s%s.%s", "wad3",LoadWAD},
{"textures/%s%s.%s", "pcx", LoadPCX},
{"textures/%s%s.%s", "wal", LoadWAL},
{"textures/%s%s.%s", "lmp", LoadLMP},
@ -1637,6 +1738,7 @@ loadformat_t load_formats[] =
{"%s%s.%s", "dds", LoadDDS},
{"%s%s.%s", "tga", LoadTGA},
{"%s%s.%s", "jpg", LoadJPG},
{"%s%s.%s", "wad3",LoadWAD},
{"%s%s.%s", "pcx", LoadPCX},
{"%s%s.%s", "wal", LoadWAL},
{"%s%s.%s", "lmp", LoadLMP},
@ -1733,7 +1835,6 @@ bool FS_AddMipmapToPack( const byte *in, int width, int height )
return true;
}
/*
================
FS_LoadImage

View File

@ -54,7 +54,26 @@ typedef struct mempool_s
uint sentinel2; // should always be MEMHEADER_SENTINEL1
} mempool_t;
mempool_t *poolchain = NULL;
typedef struct memarray_s
{
byte *data;
byte *allocflags;
size_t numflaggedrecords;
} memcluster_t;
typedef struct memarraypool_s
{
byte *mempool;
size_t recordsize;
size_t count;
size_t numarrays;
size_t maxarrays;
memcluster_t *arrays;
} memarray_t;
mempool_t *poolchain = NULL; // critical stuff
void _mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline)
{
@ -343,6 +362,166 @@ void _mem_emptypool(byte *poolptr, const char *filename, int fileline)
while (pool->chain) _mem_freeblock(pool->chain, filename, fileline);
}
bool _mem_allocated( mempool_t *pool, void *data )
{
memheader_t *header, *target;
if( pool )
{
// search only one pool
target = (memheader_t *)((byte *)data - sizeof(memheader_t));
for( header = pool->chain; header; header = header->next )
if( header == target ) return true;
}
else
{
// search all pools
for (pool = poolchain; pool; pool = pool->next)
if(_mem_allocated( pool, data ))
return true;
}
return false;
}
/*
========================
Check pointer for memory
allocated by memlib.c
========================
*/
bool _is_allocated( byte *poolptr, void *data )
{
mempool_t *pool = NULL;
if( poolptr ) pool = (mempool_t *)((byte *)poolptr);
return _mem_allocated( pool, data );
}
byte *_mem_alloc_array( byte *poolptr, size_t recordsize, int count, const char *filename, int fileline )
{
memarray_t *l = _mem_alloc( poolptr, sizeof(memarray_t), filename, fileline);
l->mempool = poolptr;
l->recordsize = recordsize;
l->count = count;
return (byte *)((memarray_t *)l);
}
void _mem_free_array( byte *arrayptr, const char *filename, int fileline )
{
memarray_t *l = (memarray_t *)((byte *)arrayptr);
size_t i;
if(l == NULL) Sys_Error("Mem_RemoveArray: array == NULL (called at %s:%i)", filename, fileline );
if (l->maxarrays)
{
for (i = 0; i != l->numarrays; i++)
_mem_free(l->arrays[i].data, filename, fileline );
_mem_free(l->arrays, filename, fileline );
}
_mem_free( l, filename, fileline); // himself
}
void *_mem_alloc_array_element( byte *arrayptr, const char *filename, int fileline )
{
memarray_t *l = (memarray_t *)((byte *)arrayptr);
size_t i, j;
if(l == NULL) Sys_Error("Mem_AllocElement: array == NULL (called at %s:%i)", filename, fileline );
for(i = 0; ; i++)
{
if(i == l->numarrays)
{
if (l->numarrays == l->maxarrays)
{
memcluster_t *oldarrays = l->arrays;
l->maxarrays = max(l->maxarrays * 2, 128);
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);
_mem_free(oldarrays, filename, fileline);
}
}
l->arrays[i].numflaggedrecords = 0;
l->arrays[i].data = _mem_alloc(l->mempool, (l->recordsize + 1) * l->count, filename, fileline);
l->arrays[i].allocflags = l->arrays[i].data + l->recordsize * l->count;
l->numarrays++;
}
if(l->arrays[i].numflaggedrecords < l->count)
{
for (j = 0; j < l->count; j++)
{
if(!l->arrays[i].allocflags[j])
{
l->arrays[i].allocflags[j] = true;
l->arrays[i].numflaggedrecords++;
return (void *)(l->arrays[i].data + l->recordsize * j);
}
}
}
}
}
void _mem_free_array_element( byte *arrayptr, void *element, const char *filename, int fileline )
{
size_t i, j;
byte *p = (byte *)element;
memarray_t *l = (memarray_t *)((byte *)arrayptr);
if(l == NULL) Sys_Error("Mem_FreeElement: array == NULL (called at %s:%i)", filename, fileline );
for (i = 0; i != l->numarrays; i++)
{
if(p >= l->arrays[i].data && p < (l->arrays[i].data + l->recordsize * l->count))
{
j = (p - l->arrays[i].data) / l->recordsize;
if (p != l->arrays[i].data + j * l->recordsize)
Sys_Error("Mem_FreeArrayElement: no such element %p\n", p);
if (!l->arrays[i].allocflags[j])
Sys_Error("Mem_FreeArrayElement: element %p is already free!\n", p);
l->arrays[i].allocflags[j] = false;
l->arrays[i].numflaggedrecords--;
return;
}
}
}
size_t _mem_array_size( byte *arrayptr )
{
size_t i, j, k;
memarray_t *l = (memarray_t *)((byte *)arrayptr);
if(l && l->numarrays)
{
i = l->numarrays - 1;
for (j = 0, k = 0; k < l->arrays[i].numflaggedrecords; j++)
if (l->arrays[i].allocflags[j]) k++;
return l->count * i + j;
}
return 0;
}
void *_mem_get_array_element( byte *arrayptr, size_t index )
{
size_t i, j;
memarray_t *l = (memarray_t *)((byte *)arrayptr);
if(!l) return NULL;
i = index / l->count;
j = index % l->count;
if (i >= l->numarrays || !l->arrays[i].allocflags[j])
return NULL;
return (void *)(l->arrays[i].data + j * l->recordsize);
}
void _mem_checkheadersentinels(void *data, const char *filename, int fileline)
{
memheader_t *mem;
@ -386,6 +565,58 @@ void _mem_check(const char *filename, int fileline)
_mem_checkclumpsentinels(clump, filename, fileline);
}
void _mem_printstats( void )
{
size_t count = 0, size = 0, realsize = 0;
mempool_t *pool;
Mem_Check();
for (pool = poolchain; pool; pool = pool->next)
{
count++;
size += pool->totalsize;
realsize += pool->realsize;
}
Msg("^3%lu^7 memory pools, totalling: ^1%s\n", (dword)count, Mem_Pretify( size ));
Msg("Total allocated size: ^1%s\n", Mem_Pretify( realsize ));
}
void _mem_printlist( size_t minallocationsize )
{
mempool_t *pool;
memheader_t *mem;
Mem_Check();
Msg("memory pool list:\n"" ^3size name\n");
for (pool = poolchain; pool; pool = pool->next)
{
Msg("%5luk (%5luk actual) %s (%+3li byte change)\n", (dword) ((pool->totalsize + 1023) / 1024), (dword)((pool->realsize + 1023) / 1024), pool->name, (long)pool->totalsize - pool->lastchecksize );
pool->lastchecksize = pool->totalsize;
for (mem = pool->chain; mem; mem = mem->next)
if (mem->size >= minallocationsize)
Msg("%10lu bytes allocated at %s:%i\n", (dword)mem->size, mem->filename, mem->fileline);
}
}
void MemList_f(void)
{
switch(Cmd_Argc())
{
case 1:
_mem_printlist(1<<30);
_mem_printstats();
break;
case 2:
_mem_printlist(atoi(Cmd_Argv(1)) * 1024);
_mem_printstats();
break;
default:
Msg("memlist: usage: memlist <all>\n");
break;
}
}
/*
========================
Memory_Init
@ -395,13 +626,16 @@ void Memory_Init( void )
{
poolchain = NULL; // init mem chain
Sys.basepool = Mem_AllocPool( "Main pool" );
Sys.imagepool = Mem_AllocPool( "ImageLib Pool" );
Sys.stringpool = Mem_AllocPool( "New string" );
}
void Memory_Shutdown( void )
{
Mem_FreePool( &Sys.basepool );
Mem_FreePool( &Sys.imagepool );
Mem_FreePool( &Sys.stringpool );
}
void Memory_Init_Commands( void )
{
Cmd_AddCommand("memlist", MemList_f, "prints memory pool information (or if used as memlist 5 lists individual allocations of 5K or larger, 0 lists all allocations)");
}

View File

@ -618,7 +618,6 @@ char *com_pretifymem( float value, int digitsafterdecimal )
return out;
}
/*
============
va

View File

@ -60,6 +60,12 @@ void Sys_GetStdAPI( void )
com.freepool = _mem_freepool;
com.clearpool = _mem_emptypool;
com.memcheck = _mem_check;
com.newarray = _mem_alloc_array;
com.delarray = _mem_free_array;
com.newelement = _mem_alloc_array_element;
com.delelement = _mem_free_array_element;
com.getelement = _mem_get_array_element;
com.arraysize = _mem_array_size;
// common functions
com.Com_InitRootDir = FS_InitRootDir; // init custom rootdir
@ -91,7 +97,8 @@ void Sys_GetStdAPI( void )
com.Com_ParseToken_Simple = SC_ParseToken_Simple; // basic parse (can't handle single characters)
com.Com_ParseToken = SC_ParseToken; // parse token from char buffer
com.Com_ParseWord = SC_ParseWord; // parse word from char buffer
com.Com_Search = FS_Search; // returned list of found files
com.Com_Search = FS_Search; // returned list of founded files
com.Com_SearchLump = FS_SearchLump; // returned list of founded images in wadfile
com.Com_Filter = SC_FilterToken; // compare keyword by mask with filter
com.com_token = token; // contains current token
@ -859,6 +866,7 @@ void Sys_Init( void )
Con_CreateConsole();
Sys_InitCPU();
Memory_Init();
Image_Init();
Cmd_Init();
Cvar_Init();
@ -881,6 +889,7 @@ void Sys_Exit ( void )
Sys_FreeLibrary( Sys.linked_dll );
FS_Shutdown();
Image_Shutdown();
Memory_Shutdown();
Con_DestroyConsole();

View File

@ -177,6 +177,7 @@ char *va(const char *format, ...);
//
void Memory_Init( void );
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);
@ -186,7 +187,14 @@ byte *_mem_allocpool(const char *name, const char *filename, int fileline);
void _mem_freepool(byte **poolptr, const char *filename, int fileline);
void _mem_emptypool(byte *poolptr, const char *filename, int fileline);
void _mem_free(void *data, const char *filename, int fileline);
byte *_mem_alloc_array( byte *poolptr, size_t recordsize, int count, const char *filename, int fileline );
void _mem_free_array( byte *arrayptr, const char *filename, int fileline );
void *_mem_alloc_array_element( byte *arrayptr, const char *filename, int fileline );
void _mem_free_array_element( byte *arrayptr, void *element, const char *filename, int fileline );
void *_mem_get_array_element( byte *arrayptr, size_t index );
size_t _mem_array_size( byte *arrayptr );
void _mem_check(const char *filename, int fileline);
bool _is_allocated( byte *poolptr, void *data );
#define Mem_Alloc(pool, size) _mem_alloc(pool, size, __FILE__, __LINE__)
#define Mem_Realloc(pool, ptr, size) _mem_realloc(pool, ptr, size, __FILE__, __LINE__)
@ -197,6 +205,13 @@ void _mem_check(const char *filename, int fileline);
#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, src, size ) _mem_set(dest, src, 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__)
#define Mem_FreeElement( array, el ) _mem_free_array_element( array, el, __FILE__, __LINE__ )
#define Mem_GetElement( array, idx ) _mem_get_array_element( array, idx )
#define Mem_ArraySize( array ) _mem_array_size( array )
#define Mem_IsAllocated( mem ) _is_allocated( NULL, mem )
#define Mem_Check() _mem_check(__FILE__, __LINE__)
#define Mem_Pretify( x ) com_pretifymem(x, 3)
#define Malloc( size ) Mem_Alloc( Sys.basepool, size )
@ -233,6 +248,7 @@ void FS_FreeImage( rgbdata_t *pack );
bool Image_Processing( const char *name, rgbdata_t **pix );
search_t *FS_Search(const char *pattern, int caseinsensitive );
search_t *FS_SearchDirs(const char *pattern, int caseinsensitive );
search_t *FS_SearchLump( const char *pattern, int caseinsensitive );
// files managment (like fopen, fread etc)
file_t *FS_Open (const char* filepath, const char* mode );
@ -344,4 +360,10 @@ char *SC_GetToken( bool newline );
char *SC_Token( void );
extern char token[];
//
// imglib.c
//
void Image_Init( void );
void Image_Shutdown( void );
#endif//LAUNCHER_H

View File

@ -53,6 +53,14 @@ typedef struct stdilib_api_s
void (*clearpool)(byte *poolptr, const char *file, int line);
void (*memcheck)(const char *file, int line); // check memory pools for consistensy
// xash memlib extension - memory arrays
byte *(*newarray)( byte *pool, size_t elementsize, int count, const char *file, int line );
void (*delarray)( byte *array, const char *file, int line );
void *(*newelement)( byte *array, const char *file, int line );
void (*delelement)( byte *array, void *element, const char *file, int line );
void *(*getelement)( byte *array, size_t index );
size_t (*arraysize)( byte *arrayptr );
// common functions
void (*Com_InitRootDir)( char *path ); // init custom rootdir
void (*Com_LoadGameInfo)( const char *filename ); // gate game info from script file
@ -84,6 +92,7 @@ typedef struct stdilib_api_s
char *(*Com_ParseToken)(const char **data ); // parse token from char buffer
char *(*Com_ParseWord)( const char **data ); // parse word from char buffer
search_t *(*Com_Search)(const char *pattern, int casecmp ); // returned list of found files
search_t *(*Com_SearchLump)(const char *pat, int casecmp ); // returned list of found lumps in wad files
bool (*Com_Filter)(char *filter, char *name, int casecmp ); // compare keyword by mask with filter
char *com_token; // contains current token
@ -207,6 +216,12 @@ typedef struct stdilib_api_s
#define Mem_Copy(dest, src, size ) com.memcpy(dest, src, size, __FILE__, __LINE__)
#define Mem_Set(dest, src, size ) com.memset(dest, src, 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__)
#define Mem_AllocElement( array ) com.newelement( array, __FILE__, __LINE__)
#define Mem_FreeElement( array, el ) com.delelement( array, el, __FILE__, __LINE__ )
#define Mem_GetElement( array, idx ) com.getelement( array, idx )
#define Mem_ArraySize( array ) com.arraysize( array )
/*
==========================================
@ -238,6 +253,7 @@ filesystem manager
#define FS_InitRootDir com.Com_InitRootDir
#define FS_LoadFile com.Com_LoadFile
#define FS_Search com.Com_Search
#define FS_SearchLump com.Com_SearchLump
#define FS_WriteFile com.Com_WriteFile
#define FS_Open( path, mode ) com.fopen( path, mode )
#define FS_Read( file, buffer, size ) com.fread( file, buffer, size )

View File

@ -790,7 +790,6 @@ typedef struct
typedef struct dsurfdesc_s
{
float vecs[2][4]; // [s/t][xyz offset] texture s\t
float lvecs[2][4]; // [s/t][xyz offset] lightmap texture s\t
int size[2]; // valid size for current s\t coords (used for replace texture)
int texid; // string table texture id number
int animid; // string table animchain id number
@ -1570,6 +1569,35 @@ typedef struct mip_s
/*
========================================================================
.WAD archive format (WhereAllData - WAD) Half-Life textures
========================================================================
*/
#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD3"
#define WAD3_NAMELEN 16
typedef struct
{
int ident; // should be WAD3
int numlumps;
int infotableofs;
} dwadinfo_t;
typedef struct
{
int filepos;
int disksize;
int size; // uncompressed
char type;
char compression; // probably not used
char pad1;
char pad2;
char name[WAD3_NAMELEN]; // must be null terminated
} dlumpinfo_t;
/*
========================================================================
.FLAT image format (Doom I\II textures)
========================================================================

View File

@ -24,18 +24,17 @@ static vec3_t modelorg; // relative to viewpoint
msurface_t *r_alpha_surfaces;
#define DYNAMIC_LIGHT_WIDTH 128
#define DYNAMIC_LIGHT_HEIGHT 128
#define LIGHTMAP_BYTES 4
#define BLOCK_WIDTH 128
#define BLOCK_HEIGHT 128
#define BLOCK_WIDTH 128
#define BLOCK_HEIGHT 128
#define DYNAMIC_LIGHT_WIDTH 128
#define DYNAMIC_LIGHT_HEIGHT 128
#define MAX_LIGHTMAPS 128
#define MAX_LIGHTMAPS 128
int c_visible_lightmaps;
int c_visible_textures;
int c_visible_lightmaps;
int c_visible_textures;
#define GL_LIGHTMAP_FORMAT GL_RGBA
@ -56,9 +55,9 @@ typedef struct
static gllightmapstate_t gl_lms;
static void LM_InitBlock( void );
static void LM_UploadBlock( bool dynamic );
static bool LM_AllocBlock (int w, int h, int *x, int *y);
static void LM_InitBlock( void );
static void LM_UploadBlock( bool dynamic );
static bool LM_AllocBlock (int w, int h, int *x, int *y);
extern void R_SetCacheState( msurface_t *surf );
extern void R_BuildLightMap (msurface_t *surf, byte *dest, int stride);