From 40713ea5e484b22ec32fb8d232b44e9673cdcb0f Mon Sep 17 00:00:00 2001 From: g-cont Date: Sat, 16 Aug 2008 00:00:00 +0400 Subject: [PATCH] 16 Aug 2008 --- common/wadlib.c | 155 +++------------ engine/client/client.h | 12 -- engine/common.h | 7 +- engine/server/server.h | 4 +- engine/server/sv_progs.c | 393 +++++++++++++++------------------------ launch/cmd.c | 2 +- launch/cvar.c | 5 +- launch/filesystem.c | 105 ++++++++--- launch/filesystem.h | 55 +++++- launch/launch.dsp | 8 +- launch/launch.h | 16 +- launch/memlib.c | 7 +- launch/random.c | 106 ----------- launch/system.c | 10 + launch/utils.c | 253 +++++++++++++++++++++++++ public/const.h | 50 +++-- public/ref_dfiles.h | 103 ++-------- public/ref_dllapi.h | 42 +++-- ripper/conv_bsplumps.c | 12 +- todo.log | 15 +- vprogs/pr_edict.c | 231 ++++++++++++----------- vprogs/pr_local.h | 7 - vprogs/pr_main.c | 27 +-- vprogs/pr_utils.c | 1 + vprogs/vprogs.h | 9 +- 25 files changed, 836 insertions(+), 799 deletions(-) delete mode 100644 launch/random.c create mode 100644 launch/utils.c diff --git a/common/wadlib.c b/common/wadlib.c index 9e71f466..ee79dda7 100644 --- a/common/wadlib.c +++ b/common/wadlib.c @@ -6,21 +6,19 @@ #include "platform.h" #include "byteorder.h" #include "mathlib.h" +#include "const.h" #include "utils.h" char wadoutname[MAX_SYSPATH]; -static dlumpinfo_t wadlumps[MAX_FILES_IN_WAD]; -static char lumpname[MAX_SYSPATH]; -dwadinfo_t wadfile; // main header +wfile_t *handle = NULL; +string lumpname; byte *wadpool; -int wadheader; -int numlumps = 0; + float linearpalette[256][3]; int color_used[256]; float maxdistortion; int colors_used; byte pixdata[256]; -file_t *handle = NULL; rgbdata_t *image = NULL; vec3_t d_color; @@ -102,14 +100,12 @@ byte Mip_AveragePixels( int count ) VectorClear( d_color ); // no distortion yet return pix; // perfect match } - bestdistortion = distortion; bestcolor = pix; } } } - if( bestdistortion > 0.001 && colors_used < 255 ) { bestcolor = Pal_AddColor( r, g, b ); @@ -133,12 +129,8 @@ byte Mip_AveragePixels( int count ) void Wad3_NewWad( void ) { - handle = FS_Open( wadoutname, "wb" ); - - if(!handle) Sys_Break("Wad3_NewWad: can't create %s\n", wadoutname ); - FS_Write( handle, &wadfile, sizeof(wadfile)); - memset( wadlumps, 0, sizeof(wadlumps)); - numlumps = 0; + handle = WAD_Open( wadoutname, "wb" ); + if( !handle ) Sys_Break("Wad3_NewWad: can't create %s\n", wadoutname ); } /* @@ -148,74 +140,12 @@ AddLump */ void Wad3_AddLump( const byte *buffer, size_t lumpsize, int lump_type, bool compress ) { - dlumpinfo_t *info; - int ofs; + int result; + if( !handle ) Wad3_NewWad(); // create wad file + result = WAD_Write( handle, lumpname, buffer, lumpsize, lump_type, ( compress ? CMP_ZLIB : CMP_NONE )); - if( numlumps >= MAX_FILES_IN_WAD ) - { - MsgDev( D_ERROR, "Wad3_AddLump: max files limit execeeds\n" ); - return; - } - - // we can load file from another wad - if( !buffer || !lumpsize ) - { - MsgDev( D_ERROR, "Wad3_AddLump: file %s not found\n", lumpname ); - return; - } - - // create wad file - if( !handle ) Wad3_NewWad(); - - info = &wadlumps[numlumps]; - - // lumpname must be prepared with Wad3_CleanupName first! - com.strncpy( info->name, lumpname, WAD3_NAMELEN ); - ofs = FS_Tell( handle ); - info->filepos = LittleLong( ofs ); - info->type = (char)lump_type; - numlumps++; // increase lump number - - if( compress ) - { - vfile_t *h = VFS_Open( handle, "wz" ); - info->compression = CMP_ZLIB; - info->size = lumpsize; // realsize - VFS_Write( h, buffer, lumpsize ); - handle = VFS_Close( h ); // go back to real filesystem - ofs = FS_Tell( handle ); // ofs - info->filepos returns compressed size - info->disksize = LittleLong( ofs - info->filepos ); - } - else - { - info->compression = CMP_NONE; - info->size = info->disksize = LittleLong( lumpsize ); - FS_Write( handle, buffer, lumpsize ); // just write file - } - Msg( "AddLump: %s, size %d\n", info->name, info->disksize ); -} - -void Wad3_CleanupName( string name, bool havealpha ) -{ - string tempname; - - lumpname[0] = '\0'; - FS_FileBase( name, tempname ); - if(com.strlen( tempname ) > WAD3_NAMELEN ) - { - // windows style cutoff long names - tempname[14] = '~'; - tempname[15] = '1'; - } - - // half-life designers probably forget to clear alpha in some "non-alpha" textures :) - // rendermode == SOLID it's a greatest hack to avoid transparency for +0BUTTONSUIT, +0C3A1_NRC1 etc - - com.strcat( lumpname, tempname ); - tempname[16] = '\0'; // cutoff all other - - // and turn big letters - com.strupr( lumpname, lumpname ); + if( result == -1 ) MsgDev( D_ERROR, "Wad3_AddLump: can't write lump %s\n", lumpname ); + else Msg("Add %s\t#%i\n", lumpname, result ); //FIXME: align message } /* @@ -234,24 +164,21 @@ void Cmd_GrabMip( void ) int xx, yy, count; int linedelta; size_t plump_size; - string mipname; byte *lump; mip_t *mip; Com_GetToken( false ); - com.strncpy( mipname, com_token, MAX_STRING ); + com.strncpy( lumpname, com_token, MAX_STRING ); // load mip image or replaced with error.bmp - image = FS_LoadImage( mipname, error_bmp, error_bmp_size ); + image = FS_LoadImage( lumpname, error_bmp, error_bmp_size ); if( !image ) { // no fatal error, just ignore this image for adding into wad-archive - MsgDev( D_ERROR, "Cmd_LoadMip: unable to loading %s\n", mipname ); + MsgDev( D_ERROR, "Cmd_LoadMip: unable to loading %s\n", lumpname ); return; } - Wad3_CleanupName( mipname, (image->flags & IMAGE_HAS_ALPHA )); - Image_ConvertPalette( image ); // turn into 24-bit mode if(Com_TryToken()) { @@ -288,7 +215,7 @@ void Cmd_GrabMip( void ) mip = (mip_t *)plump; mip->width = LittleLong( w ); mip->height = LittleLong( h ); - com.strncpy( mip->name, lumpname, WAD3_NAMELEN ); + com.strncpy( mip->name, lumpname, sizeof(mip->name)); plump = (byte *)&mip->offsets[4]; screen_p = image->buffer + yl * image->width + xl; @@ -404,18 +331,17 @@ void Cmd_GrabPic( void ) int x, y, xl, yl, xh, yh; byte *plump, *lump; size_t plump_size; - string picname; lmp_t *pic; Com_GetToken( false ); - com.strncpy( picname, com_token, MAX_STRING ); + com.strncpy( lumpname, com_token, MAX_STRING ); // load mip image or replaced with error.bmp - image = FS_LoadImage( picname, error_bmp, error_bmp_size ); + image = FS_LoadImage( lumpname, error_bmp, error_bmp_size ); if( !image ) { // no fatal error, just ignore this image for adding into wad-archive - MsgDev( D_ERROR, "Cmd_LoadPic: unable to loading %s\n", picname ); + MsgDev( D_ERROR, "Cmd_LoadPic: unable to loading %s\n", lumpname ); return; } @@ -435,8 +361,6 @@ void Cmd_GrabPic( void ) yh = image->height; } - Wad3_CleanupName( picname, false ); // don't add { symbol to the final name - if( xh < xl || yh < yl || xl < 0 || yl < 0 ) { xl = yl = 0; @@ -479,21 +403,19 @@ void Cmd_GrabScript( void ) { byte *lump; size_t plump_size; - string textname; Com_GetToken( false ); - com.strncpy( textname, com_token, MAX_STRING ); + com.strncpy( lumpname, com_token, MAX_STRING ); // load mip image or replaced with error.bmp - lump = FS_LoadFile( textname, &plump_size ); + lump = FS_LoadFile( lumpname, &plump_size ); if( !lump || !plump_size ) { // no fatal error, just ignore this image for adding into wad-archive - MsgDev( D_ERROR, "Cmd_LoadScript: unable to loading %s\n", textname ); + MsgDev( D_ERROR, "Cmd_LoadScript: unable to loading %s\n", lumpname ); return; } - Wad3_CleanupName( textname, false ); // don't add { symbol to the final name // write out and release intermediate buffers Wad3_AddLump( lump, plump_size, TYPE_SCRIPT, true ); // always compress text files @@ -511,19 +433,18 @@ void Cmd_GrabProgs( void ) { byte *lump; size_t plump_size; - string datname; dprograms_t *hdr; Com_GetToken( false ); - com.strncpy( datname, com_token, MAX_STRING ); + com.strncpy( lumpname, com_token, MAX_STRING ); // load mip image or replaced with error.bmp - lump = FS_LoadFile( datname, &plump_size ); + lump = FS_LoadFile( lumpname, &plump_size ); if( !lump || !plump_size || plump_size < sizeof(dprograms_t)) { // no fatal error, just ignore this image for adding into wad-archive - MsgDev( D_ERROR, "Cmd_LoadProgs: unable to loading %s\n", datname ); + MsgDev( D_ERROR, "Cmd_LoadProgs: unable to loading %s\n", lumpname ); return; } // validate progs @@ -532,11 +453,10 @@ void Cmd_GrabProgs( void ) if( hdr->ident != VPROGSHEADER32 || hdr->version != VPROGS_VERSION ) { // no fatal error, just ignore this image for adding into wad-archive - MsgDev( D_ERROR, "Cmd_LoadProgs: %s invalid progs version, ignore\n", datname ); + MsgDev( D_ERROR, "Cmd_LoadProgs: %s invalid progs version, ignore\n", lumpname ); Mem_Free( lump ); return; } - Wad3_CleanupName( datname, false ); // don't add { symbol to the final name // write out and release intermediate buffers Wad3_AddLump( lump, plump_size, TYPE_VPROGS, !hdr->flags ); // release progs may be already packed @@ -567,10 +487,6 @@ void ResetWADInfo( void ) { FS_FileBase( gs_filename, wadoutname ); // kill path and ext FS_DefaultExtension( wadoutname, ".wad" ); // set new ext - - memset( &wadheader, 0, sizeof(wadheader)); - wadheader = IDWAD3HEADER; - numlumps = 0; handle = NULL; } @@ -600,23 +516,8 @@ bool ParseWADfileScript( void ) bool WriteWADFile( void ) { - int ofs; - - if(!handle) return false; - - // write the lumpingo - ofs = FS_Tell( handle ); - FS_Write( handle, wadlumps, numlumps * sizeof(dlumpinfo_t)); - - // write the header - wadfile.ident = wadheader; - wadfile.numlumps = LittleLong( numlumps ); - wadfile.infotableofs = LittleLong( ofs ); - - FS_Seek( handle, 0, SEEK_SET ); - FS_Write( handle, &wadfile, sizeof(wadfile)); - FS_Close( handle ); - + if( !handle ) return false; + WAD_Close( handle ); return true; } @@ -628,7 +529,7 @@ bool BuildCurrentWAD( const char *name ) FS_DefaultExtension( gs_filename, ".qc" ); load = Com_LoadScript( gs_filename, NULL, 0 ); - if(load) + if( load ) { if(!ParseWADfileScript()) return false; diff --git a/engine/client/client.h b/engine/client/client.h index af543b9b..6b01f6a8 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -465,18 +465,6 @@ void CL_FreeEdicts( void ); void CL_VM_Begin( void ); void CL_VM_End( void ); -_inline edict_t *CLVM_EDICT_NUM( int entnum ) -{ - edict_t *ent; - - while( entnum >= prog->max_edicts ) PRVM_MEM_IncreaseEdicts(); - ent = PRVM_EDICT_NUM( entnum ); - memset(ent->progs.cl, 0, prog->progs->entityfields * 4); - ent->priv.cl->free = false; - - return ent; -} - // // cl_sound.c // diff --git a/engine/common.h b/engine/common.h index a7571906..fbd94213 100644 --- a/engine/common.h +++ b/engine/common.h @@ -184,8 +184,6 @@ void VM_Cmd_Reset( void ); #define PRVM_GetString vm->GetString #define PRVM_SetEngineString vm->SetEngineString #define PRVM_SetTempString vm->SetTempString -#define PRVM_AllocString vm->AllocString -#define PRVM_FreeString vm->FreeString #define VM_Frame vm->Update #define PRVM_SetProg vm->SetProg @@ -194,14 +192,13 @@ void VM_Cmd_Reset( void ); #define PRVM_LoadProgs vm->LoadProgs #define PRVM_ProgLoaded vm->ProgLoaded #define PRVM_ED_LoadFromFile vm->LoadFromFile -#define PRVM_ED_ParseGlobals vm->ParseGlobals +#define PRVM_ED_ReadGlobals vm->ReadGlobals #define PRVM_ED_WriteGlobals vm->WriteGlobals #define PRVM_ED_Print vm->PrintEdict #define PRVM_ED_Write vm->WriteEdict -#define PRVM_ED_ParseEdict vm->ParseEdict +#define PRVM_ED_Read vm->ReadEdict #define PRVM_ED_Alloc vm->AllocEdict #define PRVM_ED_Free vm->FreeEdict -#define PRVM_MEM_IncreaseEdicts vm->IncreaseEdicts #define PRVM_ExecuteProgram( func, name ) vm->ExecuteProgram( func, name, __FILE__, __LINE__ ) #define PRVM_StackTrace vm->StackTrace diff --git a/engine/server/server.h b/engine/server/server.h index 2c329f40..ce879f40 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -390,8 +390,8 @@ void SV_TouchTriggers (edict_t *ent); // // sv_save.c // -void SV_WriteSaveFile( char *name ); -void SV_ReadSaveFile( char *name ); +void SV_WriteSaveFile( const char *name ); +void SV_ReadSaveFile( const char *name ); void SV_ReadLevelFile( const char *name ); //============================================================ diff --git a/engine/server/sv_progs.c b/engine/server/sv_progs.c index 9f5c861f..31ed977e 100644 --- a/engine/server/sv_progs.c +++ b/engine/server/sv_progs.c @@ -6,8 +6,7 @@ #include "common.h" #include "server.h" #include "byteorder.h" - -byte *sav_base; +#include "const.h" /* ============ @@ -234,8 +233,8 @@ bool SV_EntitiesIn( bool mode, vec3_t v1, vec3_t v2 ) leafnum = pe->PointLeafnum (v1); cluster = pe->LeafCluster (leafnum); area1 = pe->LeafArea (leafnum); - if( mode == DVIS_PHS ) mask = pe->ClusterPHS (cluster); - else if( mode == DVIS_PVS ) mask = pe->ClusterPVS (cluster); + if( mode == DVIS_PHS ) mask = pe->ClusterPHS( cluster ); + else if( mode == DVIS_PVS ) mask = pe->ClusterPVS( cluster ); else Host_Error( "SV_EntitiesIn: unsupported mode\n" ); leafnum = pe->PointLeafnum (v2); @@ -256,95 +255,72 @@ Save\Load gamestate savefile operations ============ */ -void SV_AddSaveLump( dsavehdr_t *hdr, file_t *f, int lumpnum, void *data, int len ) -{ - lump_t *lump; +static int s_table; - lump = &hdr->lumps[lumpnum]; - lump->fileofs = LittleLong( FS_Tell(f)); - lump->filelen = LittleLong(len); - FS_Write(f, data, (len + 3) & ~3 ); // align +void SV_AddSaveLump( wfile_t *f, const char *lumpname, void *data, size_t len, bool compress ) +{ + WAD_Write( f, lumpname, data, len, TYPE_BINDATA, ( compress ? CMP_ZLIB : CMP_NONE )); } -static void Cvar_AddToBuffer( const char *name, const char *string, const char *buffer, int *bufsize ) +static void SV_SetPair( const char *name, const char *value, dkeyvalue_t *cvars, int *numpairs ) { - if( com.strlen(name) >= 64 || com.strlen(string) >= 64 ) - { - MsgDev(D_NOTE, "cvar too long: %s = %s\n", name, string); - return; - } - *bufsize = com.strpack((char *)buffer, *bufsize, (char *)name, com.strlen(name)); - *bufsize = com.strpack((char *)buffer, *bufsize, (char *)string, com.strlen(string)); + if( !name || !value ) return; // SetString can't register null strings + cvars[*numpairs].epair[DENT_KEY] = StringTable_SetString( s_table, name ); + cvars[*numpairs].epair[DENT_VAL] = StringTable_SetString( s_table, value); + (*numpairs)++; // increase epairs } -void SV_AddCvarLump( dsavehdr_t *hdr, file_t *f ) +void SV_AddCvarLump( wfile_t *f ) { - int bufsize = 1; // null terminator - char *cvbuffer = Z_Malloc( MAX_MSGLEN ); - - Cvar_LookupVars( CVAR_LATCH, cvbuffer, &bufsize, Cvar_AddToBuffer ); - SV_AddSaveLump( hdr, f, LUMP_GAMECVARS, cvbuffer, bufsize ); - - Mem_Free( cvbuffer ); // free buffer + dkeyvalue_t cvbuffer[MAX_FIELDS]; + int numpairs = 0; + + Cvar_LookupVars( CVAR_LATCH, cvbuffer, &numpairs, SV_SetPair ); + SV_AddSaveLump( f, "latched_cvars", cvbuffer, numpairs * sizeof(dkeyvalue_t), true ); } -void SV_AddCStrLump( dsavehdr_t *hdr, file_t *f ) +void SV_AddCStrLump( wfile_t *f ) { - int i, stringsize, bufsize = 1; // null terminator - char *csbuffer = Z_Malloc( MAX_CONFIGSTRINGS * MAX_QPATH ); + string_t csbuffer[MAX_CONFIGSTRINGS]; + int i; // pack the cfg string data for(i = 0; i < MAX_CONFIGSTRINGS; i++) - { - stringsize = bound(0, com.strlen(sv.configstrings[i]), MAX_QPATH); - bufsize = com.strpack(csbuffer, bufsize, sv.configstrings[i], stringsize ); - } - SV_AddSaveLump( hdr, f, LUMP_CFGSTRING, csbuffer, bufsize ); - Mem_Free( csbuffer ); // free memory + csbuffer[i] = StringTable_SetString( s_table, sv.configstrings[i] ); + SV_AddSaveLump( f, "config_strings", &csbuffer, sizeof(csbuffer), true ); } -void SV_WriteGlobal( dsavehdr_t *hdr, file_t *f ) +void SV_WriteGlobal( wfile_t *f ) { - vfile_t *h = VFS_Open( f, "wz" ); // zip-compression - lump_t *lump; - int len, pos; - - lump = &hdr->lumps[LUMP_GAMESTATE]; - lump->fileofs = LittleLong( FS_Tell(f)); + dkeyvalue_t globals[MAX_FIELDS]; + int numpairs = 0; SV_VM_Begin(); - PRVM_ED_WriteGlobals( h ); + PRVM_ED_WriteGlobals( &globals, &numpairs, SV_SetPair ); SV_VM_End(); - pos = VFS_Tell( h ); - FS_Write(f, &pos, sizeof(int)); // first four bytes is real filelength - f = VFS_Close( h ); - - len = LittleLong(FS_Tell(f)); - lump->filelen = LittleLong( len - lump->fileofs ); // store compressed file length + SV_AddSaveLump( f, "globals", &globals, numpairs * sizeof(dkeyvalue_t), true ); } -void SV_WriteLocals( dsavehdr_t *hdr, file_t *f ) +void SV_WriteLocals( wfile_t *f ) { - vfile_t *h = VFS_Open( f, "wz" ); // zip-compression - lump_t *lump; - int i, len, pos; - - lump = &hdr->lumps[LUMP_GAMEENTS]; - lump->fileofs = LittleLong( FS_Tell(f)); + dkeyvalue_t fields[MAX_FIELDS]; + vfile_t *h = VFS_Open( NULL, "wb" ); + int i, numpairs = 0; SV_VM_Begin(); - for(i = 0; i < prog->num_edicts; i++) + for( i = 0; i < prog->num_edicts; i++ ) { - PRVM_ED_Write(h, PRVM_EDICT_NUM(i)); + numpairs = 0; // reset fields info + PRVM_ED_Write( PRVM_EDICT_NUM( i ), &fields, &numpairs, SV_SetPair ); + VFS_Write( h, &numpairs, sizeof( int )); // numfields + VFS_Write( h, &fields, numpairs * sizeof( dkeyvalue_t )); // fields } SV_VM_End(); - pos = VFS_Tell( h ); - - FS_Write(f, &pos, sizeof(int)); // first four bytes is real filelength - f = VFS_Close(h); - len = LittleLong(FS_Tell(f)); - lump->filelen = LittleLong( len - lump->fileofs ); // store compressed file length + + // all allocated memory will be freed at end of SV_WriteSaveFile + SV_AddSaveLump( f, "entities", VFS_GetBuffer( h ), VFS_Tell( h ), true ); + VFS_Close( h ); // release virtual file } /* @@ -352,13 +328,12 @@ void SV_WriteLocals( dsavehdr_t *hdr, file_t *f ) SV_WriteSaveFile ============= */ -void SV_WriteSaveFile( char *name ) +void SV_WriteSaveFile( const char *name ) { - char path[MAX_SYSPATH]; string comment; - dsavehdr_t *header; - file_t *savfile; + wfile_t *savfile; bool autosave = false; + char path[MAX_SYSPATH]; byte *portalopen = Z_Malloc( MAX_MAP_AREAPORTALS ); int portalsize; @@ -377,174 +352,124 @@ void SV_WriteSaveFile( char *name ) } if(!com.strcmp(name, "save0.bin")) autosave = true; - com.sprintf (path, "save/%s", name ); - savfile = FS_Open( path, "wb"); + com.sprintf( path, "save/%s", name ); + savfile = WAD_Open( path, "wb" ); - if(!savfile) + if( !savfile ) { MsgDev(D_ERROR, "SV_WriteSaveFile: failed to open %s\n", path ); return; } MsgDev (D_INFO, "Saving game..." ); - com.sprintf (comment, "%s - %s", sv.configstrings[CS_NAME], timestamp(TIME_FULL)); - - header = (dsavehdr_t *)Z_Malloc( sizeof(dsavehdr_t)); - header->ident = LittleLong (IDSAVEHEADER); - header->version = LittleLong (SAVE_VERSION); - FS_Write( savfile, header, sizeof(dsavehdr_t)); + com.sprintf (comment, "%s - %s", sv.configstrings[CS_NAME], timestamp( TIME_FULL )); + s_table = StringTable_Create( name, MAX_MAP_NUMSTRINGS ); // write lumps pe->GetAreaPortals( &portalopen, &portalsize ); - SV_AddSaveLump( header, savfile, LUMP_COMMENTS, comment, sizeof(comment)); - SV_AddCStrLump( header, savfile ); - SV_AddSaveLump( header, savfile, LUMP_AREASTATE, portalopen, portalsize ); - SV_WriteGlobal( header, savfile ); - SV_AddSaveLump( header, savfile, LUMP_MAPNAME, svs.mapcmd, sizeof(svs.mapcmd)); - SV_AddCvarLump( header, savfile ); - SV_WriteLocals( header, savfile ); - - // merge header - FS_Seek( savfile, 0, SEEK_SET ); - FS_Write( savfile, header, sizeof(dsavehdr_t)); - FS_Close( savfile ); - Mem_Free( portalopen); - Mem_Free( header ); - MsgDev(D_INFO, "done.\n"); + SV_AddSaveLump( savfile, "map_comment", comment, sizeof(comment), false ); + SV_AddCStrLump( savfile ); + SV_AddSaveLump( savfile, "areaportals", portalopen, portalsize, true ); + SV_WriteGlobal( savfile ); + SV_AddSaveLump( savfile, "map_name", svs.mapcmd, sizeof(svs.mapcmd), false ); + SV_AddCvarLump( savfile ); + SV_WriteLocals( savfile ); + StringTable_Save( s_table, savfile ); // now system released + Mem_Free( portalopen ); // release portalinfo + WAD_Close( savfile ); + + MsgDev( D_INFO, "done.\n" ); } -void Sav_LoadComment( lump_t *l ) +void Sav_LoadComment( wfile_t *l ) { byte *in; int size; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadComment: funny lump size\n" ); - - size = l->filelen / sizeof(*in); + in = WAD_Read( l, "map_comment", &size, TYPE_BINDATA ); com.strncpy( svs.comment, in, size ); } -void Sav_LoadCvars( lump_t *l ) +void Sav_LoadCvars( wfile_t *l ) { - char name[64], string[64]; - int size, pos = 0; - byte *in; + dkeyvalue_t *in; + int i, numpairs; + const char *name, *value; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadCvars: funny lump size\n" ); - size = l->filelen / sizeof(*in); + in = (dkeyvalue_t *)WAD_Read( l, "latched_cvars", &numpairs, TYPE_BINDATA ); + if( numpairs % sizeof(*in)) Host_Error( "Sav_LoadCvars: funny lump size\n" ); + numpairs /= sizeof( dkeyvalue_t ); - while(pos < size) + for( i = 0; i < numpairs; i++ ) { - pos = com.strunpack( in, pos, name ); - pos = com.strunpack( in, pos, string ); - Cvar_SetLatched( name, string ); + name = StringTable_GetString( s_table, in[i].epair[DENT_KEY] ); + value = StringTable_GetString( s_table, in[i].epair[DENT_VAL] ); + Cvar_SetLatched( name, value ); } } -void Sav_LoadMapCmds( lump_t *l ) +void Sav_LoadMapCmds( wfile_t *l ) { byte *in; int size; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadMapCmds: funny lump size\n" ); - - size = l->filelen / sizeof(*in); - com.strncpy(svs.mapcmd, in, size ); + in = WAD_Read( l, "map_name", &size, TYPE_BINDATA ); + com.strncpy( svs.mapcmd, in, size ); } -void Sav_LoadCfgString( lump_t *l ) +void Sav_LoadCfgString( wfile_t *l ) { - char *in; - int i, pos = 0; + string_t *in; + int i, numstrings; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadCfgString: funny lump size\n" ); + in = (string_t *)WAD_Read( l, "config_strings", &numstrings, TYPE_BINDATA ); + if( numstrings % sizeof(*in)) Host_Error( "Sav_LoadCfgString: funny lump size\n" ); + numstrings /= sizeof( string_t ); // because old saves can contain last values of MAX_CONFIGSTRINGS // unpack the cfg string data - for(i = 0; i < MAX_CONFIGSTRINGS; i++) - { - pos = com.strunpack( in, pos, sv.configstrings[i] ); - } + for( i = 0; i < numstrings; i++ ) + com.strncpy( sv.configstrings[i], StringTable_GetString( s_table, in[i] ), MAX_QPATH ); } -void Sav_LoadAreaPortals( lump_t *l ) +void Sav_LoadAreaPortals( wfile_t *l ) { byte *in; int size; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadAreaPortals: funny lump size\n" ); - - size = l->filelen / sizeof(*in); + in = WAD_Read( l, "areaportals", &size, TYPE_BINDATA ); pe->SetAreaPortals( in, size ); // CM_ReadPortalState } -void Sav_LoadGlobal( lump_t *l ) +void Sav_LoadGlobal( wfile_t *l ) { - byte *in, *globals, *ptr; - int size, realsize; + dkeyvalue_t *globals; + int numpairs; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadGlobal: funny lump size\n" ); - size = l->filelen / sizeof(*in); - realsize = LittleLong(((int *)in)[0]); - - ptr = globals = Z_Malloc( realsize ); - VFS_Unpack( in+4, size, &globals, realsize ); - PRVM_ED_ParseGlobals( globals ); - Mem_Free( ptr ); // free globals + globals = (dkeyvalue_t *)WAD_Read( l, "globals", &numpairs, TYPE_BINDATA ); + if( numpairs % sizeof(*globals)) Host_Error( "Sav_LoadGlobal: funny lump size\n" ); + numpairs /= sizeof( dkeyvalue_t ); + PRVM_ED_ReadGlobals( s_table, globals, numpairs ); } -void Sav_LoadLocals( lump_t *l ) +void Sav_LoadLocals( wfile_t *l ) { - byte *in, *ents, *ptr; - int size, realsize, entnum = 0; + dkeyvalue_t fields[MAX_FIELDS]; + int numpairs, entnum = 0; + byte *buff; + size_t size; + vfile_t *h; - in = (void *)(sav_base + l->fileofs); - if (l->filelen % sizeof(*in)) Host_Error("Sav_LoadLocals: funny lump size\n" ); - size = l->filelen / sizeof(*in); - realsize = LittleLong(((int *)in)[0]); + buff = WAD_Read( l, "entities", &size, TYPE_BINDATA ); + h = VFS_Create( buff, size ); - ptr = ents = Z_Malloc( realsize ); - VFS_Unpack( in + sizeof(int), size, &ents, realsize ); - - while(Com_SimpleGetToken(&ents)) + while(!VFS_Eof( h )) { - edict_t *ent; - - if( com_token[0] == '{' ) - { - if( entnum >= host.max_edicts ) - Host_Error("Sav_LoadLocals: too many edicts in save file\n" ); - while(entnum >= prog->max_edicts) PRVM_MEM_IncreaseEdicts(); - ent = PRVM_EDICT_NUM( entnum ); - memset(ent->progs.sv, 0, prog->progs->entityfields * 4); - ent->priv.sv->free = false; - - // parse an edict - PRVM_ED_ParseEdict( ents, ent ); - ent->priv.sv->serialnumber = entnum++; // increase serialnumber - - // link it into the bsp tree - if(!ent->priv.sv->free) - { - SV_LinkEdict( ent ); - SV_CreatePhysBody( ent ); - SV_SetPhysForce( ent ); // restore forces ... - SV_SetMassCentre( ent ); // and mass force - } - if( ent->progs.sv->loopsound ) - { - ent->priv.sv->s.soundindex = SV_SoundIndex(PRVM_GetString(ent->progs.sv->loopsound)); - } - } + VFS_Read( h, &numpairs, sizeof( int )); + VFS_Read( h, &fields, numpairs * sizeof( dkeyvalue_t )); + PRVM_ED_Read( s_table, entnum, fields, numpairs ); + entnum++; } - prog->num_edicts = entnum; - Mem_Free( ptr ); // free ents } /* @@ -552,37 +477,29 @@ void Sav_LoadLocals( lump_t *l ) SV_ReadSaveFile ============= */ -void SV_ReadSaveFile( char *name ) +void SV_ReadSaveFile( const char *name ) { char path[MAX_SYSPATH]; - dsavehdr_t *header; - byte *savfile; - int i, id, size; + wfile_t *savfile; + int s_table; com.sprintf(path, "save/%s", name ); - savfile = FS_LoadFile(path, &size ); + savfile = WAD_Open( path, "rb" ); - if(!savfile) + if( !savfile ) { MsgDev(D_ERROR, "SV_ReadSaveFile: can't open %s\n", path ); return; } - header = (dsavehdr_t *)savfile; - i = LittleLong (header->version); - id = LittleLong (header->ident); - - if(id != IDSAVEHEADER) Host_Error("SV_ReadSaveFile: file %s is corrupted\n", path ); - if(i != SAVE_VERSION ) Host_Error("file %s from an older save version\n", path ); - - sav_base = (byte *)header; - - Sav_LoadComment(&header->lumps[LUMP_COMMENTS]); - Sav_LoadCvars(&header->lumps[LUMP_GAMECVARS]); + s_table = StringTable_Load( savfile, name ); + Sav_LoadComment( savfile ); + Sav_LoadCvars( savfile ); + StringTable_Delete( s_table ); SV_InitGame(); // start a new game fresh with new cvars - Sav_LoadMapCmds(&header->lumps[LUMP_MAPNAME]); - Mem_Free( savfile ); + Sav_LoadMapCmds( savfile ); + WAD_Close( savfile ); CL_Drop(); } @@ -594,68 +511,55 @@ SV_ReadLevelFile void SV_ReadLevelFile( const char *name ) { char path[MAX_SYSPATH]; - dsavehdr_t *header; - byte *savfile; - int i, id, size; + wfile_t *savfile; + int s_table; com.sprintf (path, "save/%s", name ); - savfile = FS_LoadFile(path, &size ); + savfile = WAD_Open( path, "rb" ); - if(!savfile) + if( !savfile ) { - MsgDev(D_ERROR, "SV_ReadLevelFile: can't open %s\n", path ); + MsgDev( D_ERROR, "SV_ReadLevelFile: can't open %s\n", path ); return; } - header = (dsavehdr_t *)savfile; - i = LittleLong (header->version); - id = LittleLong (header->ident); - - if(id != IDSAVEHEADER) Host_Error("SV_ReadSaveFile: file %s is corrupted\n", path ); - if (i != SAVE_VERSION) Host_Error("file %s from an older save version\n", path ); - - sav_base = (byte *)header; - Sav_LoadCfgString(&header->lumps[LUMP_CFGSTRING]); - Sav_LoadAreaPortals(&header->lumps[LUMP_AREASTATE]); - Sav_LoadGlobal(&header->lumps[LUMP_GAMESTATE]); - Sav_LoadLocals(&header->lumps[LUMP_GAMEENTS]); - Mem_Free( savfile ); + s_table = StringTable_Load( savfile, name ); + Sav_LoadCfgString( savfile ); + Sav_LoadAreaPortals( savfile ); + Sav_LoadGlobal( savfile ); + Sav_LoadLocals( savfile ); + StringTable_Delete( s_table ); + WAD_Close( savfile ); } bool SV_ReadComment( char *comment, int savenum ) { - dsavehdr_t *header; - byte *savfile; - int i, id, size; + wfile_t *savfile; + int result; - if(!comment) return false; - savfile = FS_LoadFile(va("save/save%i.bin", savenum), &size ); + if( !comment ) return false; + result = WAD_Check( va( "save/save%i.bin", savenum )); - if(!savfile) + switch( result ) { + case 0: com.strncpy( comment, "", MAX_STRING ); return false; - } - - header = (dsavehdr_t *)savfile; - i = LittleLong (header->version); - id = LittleLong (header->ident); - - if(id != IDSAVEHEADER || i != SAVE_VERSION) - { + case 1: break; + default: com.strncpy( comment, "", MAX_STRING ); return false; } - sav_base = (byte *)header; - Sav_LoadComment(&header->lumps[LUMP_COMMENTS]); + savfile = WAD_Open( va("save/save%i.bin", savenum), "rb" ); + Sav_LoadComment( savfile ); com.strncpy( comment, svs.comment, MAX_STRING ); - Mem_Free( savfile ); + WAD_Close( savfile ); return true; } -void SV_BeginIncreaseEdicts(void) +void SV_BeginIncreaseEdicts( void ) { int i; edict_t *ent; @@ -766,6 +670,18 @@ bool SV_LoadEdict( edict_t *ent ) return true; } +void SV_RestoreEdict( edict_t *ent ) +{ + // link it into the bsp tree + SV_LinkEdict( ent ); + SV_CreatePhysBody( ent ); + SV_SetPhysForce( ent ); // restore forces ... + SV_SetMassCentre( ent ); // and mass force + + if( ent->progs.sv->loopsound ) // restore loopsound + ent->priv.sv->s.soundindex = SV_SoundIndex(PRVM_GetString(ent->progs.sv->loopsound)); +} + void SV_VM_Begin( void ) { PRVM_Begin; @@ -2605,6 +2521,7 @@ void SV_InitServerProgs( void ) prog->free_edict = SV_FreeEdict; prog->count_edicts = SV_CountEdicts; prog->load_edict = SV_LoadEdict; + prog->restore_edict = SV_RestoreEdict; prog->filecrc = PROG_CRC_SERVER; // using default builtins diff --git a/launch/cmd.c b/launch/cmd.c index 3b4f8f3f..1aa77770 100644 --- a/launch/cmd.c +++ b/launch/cmd.c @@ -522,7 +522,7 @@ void Cmd_RemoveCommand (const char *cmd_name) Cmd_LookupCmds ============ */ -void Cmd_LookupCmds( char *buffer, void *ptr, cvarcmd_t callback ) +void Cmd_LookupCmds( char *buffer, void *ptr, setpair_t callback ) { cmd_function_t *cmd; diff --git a/launch/cvar.c b/launch/cvar.c index 99f41ed0..df33b823 100644 --- a/launch/cvar.c +++ b/launch/cvar.c @@ -114,10 +114,13 @@ char *Cvar_VariableString (const char *var_name) Cvar_LookupVars ============ */ -void Cvar_LookupVars( int checkbit, char *buffer, void *ptr, cvarcmd_t callback ) +void Cvar_LookupVars( int checkbit, void *buffer, void *ptr, setpair_t callback ) { cvar_t *cvar; + // nothing to process ? + if( !callback ) return; + // force checkbit to 0 for lookup all cvars for( cvar = cvar_vars; cvar; cvar = cvar->next ) { diff --git a/launch/filesystem.c b/launch/filesystem.c index 59284875..4f0d3783 100644 --- a/launch/filesystem.c +++ b/launch/filesystem.c @@ -74,6 +74,7 @@ typedef struct wfile_s { char filename [MAX_SYSPATH]; int infotableofs; + byte *mempool; // W_ReadLump temp buffers int numlumps; int mode; file_t *file; @@ -2942,6 +2943,12 @@ fs_offset_t VFS_Write( vfile_t *file, const void *buf, size_t size ) return file->length; } +byte *VFS_GetBuffer( vfile_t *file ) +{ + if( !file ) return NULL; + return file->buff; +} + /* ==================== VFS_Print @@ -3116,7 +3123,8 @@ file_t *VFS_Close( vfile_t *file ) FS_Write( file->handle, out, sizeof(out) - strm.avail_out ); deflateEnd( &strm ); } - else FS_Write(file->handle, file->buff, (file->length + 3) & ~3); // align + else if( file->handle ) + FS_Write(file->handle, file->buff, (file->length + 3) & ~3); // align } handle = file->handle; // keep real handle @@ -3146,6 +3154,8 @@ wadtype_t wad_types[] = {"lmp", TYPE_QPIC }, // quake1, hl pic {"mip", TYPE_MIPTEX2}, // hl texture {"mip", TYPE_MIPTEX }, // quake1 mip + {"bin", TYPE_BINDATA}, // xash binary data + {"str", TYPE_STRDATA}, // xash string data {"raw", TYPE_RAW }, // signed raw data {"txt", TYPE_SCRIPT }, // xash script file {"lst", TYPE_SCRIPT }, // xash script file @@ -3225,9 +3235,8 @@ static void W_CleanupName( const char *dirtyname, char *cleanname ) tempname[14] = '~'; tempname[15] = '1'; } - - com_strcat( cleanname, tempname ); tempname[16] = '\0'; // cutoff all other ... + com_strncpy( cleanname, tempname, 16 ); // .. and turn big letters com.strupr( cleanname, cleanname ); @@ -3246,7 +3255,7 @@ static bool W_ConvertIWADLumps( wfile_t *wad ) if( !wad ) return false; lat_size = wad->numlumps * sizeof( dlumpfile_t ); - doomlumps = (dlumpfile_t *)Mem_Alloc( fs_mempool, lat_size ); + doomlumps = (dlumpfile_t *)Mem_Alloc( wad->mempool, lat_size ); if( FS_Read( wad->file, doomlumps, lat_size ) != lat_size ) { @@ -3375,7 +3384,7 @@ byte *W_ReadLump( wfile_t *wad, dlumpinfo_t *lump, size_t *lumpsizeptr ) switch( lump->compression ) { case CMP_NONE: - buf = (byte *)Mem_Alloc( fs_mempool, lump->disksize ); + buf = (byte *)Mem_Alloc( wad->mempool, lump->disksize ); size = FS_Read( wad->file, buf, lump->disksize ); if( size < lump->disksize ) { @@ -3389,9 +3398,9 @@ byte *W_ReadLump( wfile_t *wad, dlumpinfo_t *lump, size_t *lumpsizeptr ) MsgDev(D_WARN, "W_ReadLump: lump %s have unsupported compression type\n", lump->name ); return NULL; case CMP_ZLIB: - cbuf = (byte *)Mem_Alloc( fs_mempool, lump->disksize ); + cbuf = (byte *)Mem_Alloc( wad->mempool, lump->disksize ); size = FS_Read( wad->file, cbuf, lump->disksize ); - buf = (byte *)Mem_Alloc( fs_mempool, lump->size ); + buf = (byte *)Mem_Alloc( wad->mempool, lump->size ); if(!VFS_Unpack( cbuf, size, &buf, lump->size )) { MsgDev( D_WARN, "W_ReadLump: %s is probably corrupted\n", lump->name ); @@ -3412,9 +3421,12 @@ bool W_WriteLump( wfile_t *wad, dlumpinfo_t *lump, const void* data, size_t data size_t ofs; vfile_t *h; - if( !wad || !lump || !data || !datasize ) + if( !wad || !lump ) return false; + if( !data || !datasize ) + { + MsgDev( D_WARN, "W_WriteLump: ignore blank lump %s - nothing to save\n", lump->name ); return false; - + } switch(( int )cmp) { case CMP_LZSS: @@ -3443,13 +3455,59 @@ WADSYSTEM PUBLIC BASE FUNCTIONS ============================================================================= */ +int W_Check( const char *filename ) +{ + file_t *testwad; + dwadinfo_t header; + int numlumps; + int infotableofs; + + testwad = FS_Open( filename, "rb" ); + if( !testwad ) return 0; // just not exist + + if( FS_Read( testwad, &header, sizeof(dwadinfo_t)) != sizeof(dwadinfo_t)) + { + // corrupted or not wad + FS_Close( testwad ); + return -1; // too small file + } + + switch( header.ident ) + { + case IDIWADHEADER: + case IDPWADHEADER: + case IDWAD2HEADER: + case IDWAD3HEADER: break; + default: + FS_Close( testwad ); + return -2; // invalid id + } + + numlumps = LittleLong( header.numlumps ); + if( numlumps < 0 || numlumps > MAX_FILES_IN_WAD ) + { + // invalid lump number + FS_Close( testwad ); + return -3; // invalid lumpcount + } + infotableofs = LittleLong( header.infotableofs ); + if( FS_Seek( testwad, infotableofs, SEEK_SET )) + { + // corrupted or not wad + FS_Close( testwad ); + return -4; // invalid lumptable + } + + // all check is done + FS_Close( testwad ); + return 1; // valid +} + wfile_t *W_Open( const char *filename, const char *mode ) { dwadinfo_t header; wfile_t *wad = (wfile_t *)Mem_Alloc( fs_mempool, sizeof( wfile_t )); - // copy wad name - com_strncpy( wad->filename, filename, sizeof( wad->filename )); wad->file = FS_Open( filename, mode ); if( !wad->file ) { @@ -3458,6 +3516,10 @@ wfile_t *W_Open( const char *filename, const char *mode ) return NULL; } + // copy wad name + com_strncpy( wad->filename, filename, sizeof( wad->filename )); + wad->mempool = Mem_AllocPool( filename ); + // if the file is opened in "write", "append", or "read/write" mode if( mode[0] == 'w' ) { @@ -3521,7 +3583,7 @@ wfile_t *W_Open( const char *filename, const char *mode ) return NULL; } // NOTE: lumps table can be reallocated for O_APPEND mode - wad->lumps = Mem_Alloc( fs_mempool, wad->numlumps * sizeof( dlumpinfo_t )); + wad->lumps = Mem_Alloc( wad->mempool, wad->numlumps * sizeof( dlumpinfo_t )); // setup lump allocation table switch( header.ident ) @@ -3568,7 +3630,7 @@ void W_Close( wfile_t *wad ) FS_Write( wad->file, &hdr, sizeof( hdr )); } - if( wad->lumps ) Mem_Free( wad->lumps ); + Mem_FreePool( &wad->mempool ); if( wad->file ) FS_Close( wad->file ); Mem_Free( wad ); // free himself } @@ -3578,7 +3640,12 @@ fs_offset_t W_SaveLump( wfile_t *wad, const char *lump, const void* data, size_t size_t lat_size; dlumpinfo_t *info; - if( !wad || !lump || !data || !datasize ) return -1; + if( !wad || !lump ) return -1; + if( !data || !datasize ) + { + MsgDev( D_WARN, "W_SaveLump: ignore blank lump %s - nothing to save\n", lump ); + return -1; + } if( wad->mode == O_RDONLY ) { MsgDev( D_ERROR, "W_SaveLump: %s opened in readonly mode\n", wad->filename ); @@ -3591,11 +3658,10 @@ fs_offset_t W_SaveLump( wfile_t *wad, const char *lump, const void* data, size_t return -1; } - wad->numlumps++; - lat_size = wad->numlumps * sizeof( dlumpinfo_t ); + lat_size = sizeof( dlumpinfo_t ) * (wad->numlumps + 1); // reallocate lumptable - wad->lumps = Mem_Realloc( fs_mempool, wad->lumps, lat_size ); + wad->lumps = Mem_Realloc( wad->mempool, wad->lumps, lat_size ); info = wad->lumps + wad->numlumps; // if we are in append mode - we need started from infotableofs poisition @@ -3609,13 +3675,10 @@ fs_offset_t W_SaveLump( wfile_t *wad, const char *lump, const void* data, size_t info->type = type; if(!W_WriteLump( wad, info, data, datasize, cmp )) - { - wad->numlumps--; return -1; - } MsgDev( D_NOTE, "W_SaveLump: %s, size %d\n", info->name, info->disksize ); - return wad->numlumps; + return wad->numlumps++; } byte *W_LoadLump( wfile_t *wad, const char *lumpname, size_t *lumpsizeptr, const char type ) diff --git a/launch/filesystem.h b/launch/filesystem.h index 5aae6209..06fa8a96 100644 --- a/launch/filesystem.h +++ b/launch/filesystem.h @@ -303,15 +303,48 @@ typedef struct word comment_size; } dpak3file_t; +/* +======================================================================== +.WAD archive format (WhereAllData - WAD) + +List of compressed files, that can be identify only by TYPE_* + + +header: dwadinfo_t[dwadinfo_t] +file_1: byte[dwadinfo_t[num]->disksize] +file_2: byte[dwadinfo_t[num]->disksize] +file_3: byte[dwadinfo_t[num]->disksize] +... +file_n: byte[dwadinfo_t[num]->disksize] +infotable dlumpinfo_t[dwadinfo_t->numlumps] +======================================================================== +*/ #define IDIWADHEADER (('D'<<24)+('A'<<16)+('W'<<8)+'I') // little-endian "IWAD" doom1 game wad #define IDPWADHEADER (('D'<<24)+('A'<<16)+('W'<<8)+'P') // little-endian "PWAD" doom1 game wad #define IDWAD2HEADER (('2'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD2" quake1 gfx.wad +#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD3" half-life wads -#define TYPE_FLMP 59 // doom1 hud picture (doom1 mapped lump) -#define TYPE_SND 60 // doom1 wav sound (doom1 mapped lump) -#define TYPE_MUS 61 // doom1 music file (doom1 mapped lump) -#define TYPE_SKIN 62 // doom1 sprite model (doom1 mapped lump) -#define TYPE_FLAT 63 // doom1 wall texture (doom1 mapped lump) +#define WAD3_NAMELEN 16 +#define MAX_FILES_IN_WAD 8192 + +// hidden virtual lump types +#define TYPE_ANY -1 // any type can be accepted +#define TYPE_NONE 0 // unknown lump type +#define TYPE_FLMP 1 // doom1 hud picture (doom1 mapped lump) +#define TYPE_SND 2 // doom1 wav sound (doom1 mapped lump) +#define TYPE_MUS 3 // doom1 music file (doom1 mapped lump) +#define TYPE_SKIN 4 // doom1 sprite model (doom1 mapped lump) +#define TYPE_FLAT 5 // doom1 wall texture (doom1 mapped lump) +#define TYPE_MAXHIDDEN 63 // after this number started typeing letters ( 'a', 'b' etc ) + +#include "const.h" + +typedef struct +{ + int ident; // should be IWAD, WAD2 or WAD3 + int numlumps; // num files + int infotableofs; +} dwadinfo_t; // doom1 and doom2 lump header typedef struct @@ -321,6 +354,18 @@ typedef struct char name[8]; // null not included } dlumpfile_t; +typedef struct +{ + int filepos; + int disksize; + int size; // uncompressed + char type; + char compression; // probably not used + char pad1; + char pad2; + char name[16]; // must be null terminated +} dlumpinfo_t; + #define ZLIB_VERSION "1.2.3" #define MAX_WBITS 15 diff --git a/launch/launch.dsp b/launch/launch.dsp index 8d2b1c20..b8589352 100644 --- a/launch/launch.dsp +++ b/launch/launch.dsp @@ -188,16 +188,16 @@ SOURCE=.\parselib.c # End Source File # Begin Source File -SOURCE=.\random.c -# End Source File -# Begin Source File - SOURCE=.\stdlib.c # End Source File # Begin Source File SOURCE=.\system.c # End Source File +# Begin Source File + +SOURCE=.\utils.c +# End Source File # End Group # Begin Group "Header Files" diff --git a/launch/launch.h b/launch/launch.h index 5b6aaff4..81906724 100644 --- a/launch/launch.h +++ b/launch/launch.h @@ -301,6 +301,7 @@ extern int fs_argc; wfile_t *W_Open( const char *filename, const char *mode ); byte *W_LoadLump( wfile_t *wad, const char *lumpname, size_t *lumpsizeptr, const char type ); fs_offset_t W_SaveLump( wfile_t *wad, const char *lump, const void* data, size_t datasize, char type, char cmp ); +int W_Check( const char *filename ); void W_Close( wfile_t *wad ); // simply files managment interface @@ -344,7 +345,7 @@ cvar_t *Cvar_FindVar (const char *var_name); cvar_t *Cvar_Get (const char *var_name, const char *value, int flags, const char *description); void Cvar_Set( const char *var_name, const char *value); cvar_t *Cvar_Set2( const char *var_name, const char *value, bool force ); -void Cvar_LookupVars( int checkbit, char *buffer, void *ptr, cvarcmd_t callback ); +void Cvar_LookupVars( int checkbit, void *buffer, void *ptr, setpair_t callback ); void Cvar_FullSet (char *var_name, char *value, int flags); void Cvar_SetLatched( const char *var_name, const char *value); void Cvar_SetValue( const char *var_name, float value); @@ -378,7 +379,7 @@ void Cmd_Init( void ); void Cmd_AddCommand(const char *cmd_name, xcommand_t function, const char *cmd_desc); void Cmd_RemoveCommand(const char *cmd_name); bool Cmd_Exists (const char *cmd_name); -void Cmd_LookupCmds( char *buffer, void *ptr, cvarcmd_t callback ); +void Cmd_LookupCmds( char *buffer, void *ptr, setpair_t callback ); bool Cmd_GetMapList( const char *s, char *completedname, int length ); bool Cmd_GetDemoList( const char *s, char *completedname, int length ); bool Cmd_GetMovieList (const char *s, char *completedname, int length ); @@ -396,6 +397,7 @@ int VFS_Printf(vfile_t* file, const char* format, ...); int VFS_Seek( vfile_t *file, fs_offset_t offset, int whence ); int VFS_Gets(vfile_t* file, byte *string, size_t bufsize ); bool VFS_Unpack( void* compbuf, size_t compsize, void **buf, size_t size ); +byte *VFS_GetBuffer( vfile_t *file ); fs_offset_t VFS_Tell (vfile_t* file); file_t *VFS_Close( vfile_t *file ); bool VFS_Eof( vfile_t* file); @@ -436,4 +438,14 @@ extern char token[]; void Image_Init( void ); void Image_Shutdown( void ); +// +// stringtable.c +// +int StringTable_CreateNewSystem( const char *name, size_t max_strings ); +string_t StringTable_SetString( int handle, const char *string ); +const char *StringTable_GetString( int handle, string_t index ); +int StringTable_LoadSystem( wfile_t *wad, const char *name ); +bool StringTable_SaveSystem( int h, wfile_t *wad ); +void StringTable_DeleteSystem( int handle ); + #endif//LAUNCHER_H \ No newline at end of file diff --git a/launch/memlib.c b/launch/memlib.c index 41c7b113..1ae63fa9 100644 --- a/launch/memlib.c +++ b/launch/memlib.c @@ -246,14 +246,17 @@ void *_mem_realloc(byte *poolptr, void *memptr, size_t size, const char *filenam char *nb; memheader_t *memhdr; - if (size <= 0) return memptr; // no need to reallocate + if( size <= 0 ) return memptr; // no need to reallocate nb = _mem_alloc(poolptr, size, filename, fileline); if( memptr ) // first allocate? { + size_t newsize; + // get size of old block memhdr = (memheader_t *)((byte *)memptr - sizeof(memheader_t)); - _mem_copy( nb, memptr, memhdr->size, filename, fileline ); + newsize = memhdr->size < size ? memhdr->size : size; // upper data can be trucnated! + _mem_copy( nb, memptr, newsize, filename, fileline ); _mem_free( memptr, filename, fileline); // free unused old block } diff --git a/launch/random.c b/launch/random.c deleted file mode 100644 index c0e36025..00000000 --- a/launch/random.c +++ /dev/null @@ -1,106 +0,0 @@ -//======================================================================= -// Copyright XashXT Group 2007 © -// stdlib.c - std lib portable utils -//======================================================================= - -#include "launch.h" -#include "mathlib.h" - -static long idum = 0; - -#define MAX_RANDOM_RANGE 0x7FFFFFFFUL -#define IA 16807 -#define IM 2147483647 -#define IQ 127773 -#define IR 2836 -#define NTAB 32 -#define NDIV (1+(IM-1)/NTAB) -#define AM (1.0/IM) -#define EPS 1.2e-7 -#define RNMX (1.0 - EPS) - -void SeedRandomNumberGenerator( long lSeed ) -{ - if( lSeed ) idum = lSeed; - else idum = -time( NULL ); - - if( 1000 < idum ) idum = -idum; - else if( -1000 < idum ) idum -= 22261048; -} - -long lran1( void ) -{ - int j; - long k; - - static long iy = 0; - static long iv[NTAB]; - - if( idum <= 0 || !iy ) - { - if(-(idum) < 1) idum=1; - else idum = -(idum); - - for( j = NTAB + 7; j >= 0; j-- ) - { - k = (idum) / IQ; - idum = IA * (idum - k * IQ) - IR * k; - if( idum < 0 ) idum += IM; - if( j < NTAB ) iv[j] = idum; - } - iy = iv[0]; - } - k = (idum)/IQ; - idum = IA * (idum - k * IQ) - IR * k; - if( idum < 0 ) idum += IM; - j = iy / NDIV; - iy = iv[j]; - iv[j] = idum; - - return iy; -} - -// fran1 -- return a random floating-point number on the interval [0,1) -float fran1( void ) -{ - float temp = (float)AM * lran1(); - if( temp > RNMX ) return (float)RNMX; - else return temp; -} - -float Com_RandomFloat( float flLow, float flHigh ) -{ - float fl; - - if( idum == 0 ) SeedRandomNumberGenerator(0); - - fl = fran1(); // float in [0, 1) - return (fl * (flHigh - flLow)) + flLow; // float in [low, high) -} - -long Com_RandomLong( long lLow, long lHigh ) -{ - dword maxAcceptable; - dword n, x = lHigh-lLow + 1; - - if( idum == 0 ) SeedRandomNumberGenerator(0); - - if( x <= 0 || MAX_RANDOM_RANGE < x-1 ) - return lLow; - - // The following maps a uniform distribution on the interval [0, MAX_RANDOM_RANGE] - // to a smaller, client-specified range of [0,x-1] in a way that doesn't bias - // the uniform distribution unfavorably. Even for a worst case x, the loop is - // guaranteed to be taken no more than half the time, so for that worst case x, - // the average number of times through the loop is 2. For cases where x is - // much smaller than MAX_RANDOM_RANGE, the average number of times through the - // loop is very close to 1. - // - maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE+1) % x ); - do - { - n = lran1(); - } while( n > maxAcceptable ); - - return lLow + (n % x); -} \ No newline at end of file diff --git a/launch/system.c b/launch/system.c index 77a10a3a..f1c32859 100644 --- a/launch/system.c +++ b/launch/system.c @@ -165,10 +165,12 @@ void Sys_GetStdAPI( void ) com.vfprintf = VFS_Printf; // write formatted message com.vfseek = VFS_Seek; // fseek, can seek in packfiles too com.vfunpack = VFS_Unpack; // inflate zipped buffer + com.vfbuffer = VFS_GetBuffer; // get pointer at start vfile buffer com.vftell = VFS_Tell; // like a ftell com.vfeof = VFS_Eof; // like a feof // wadstorag filesystem + com.wfcheck = W_Check; // validate container com.wfopen = W_Open; // open wad file or create new com.wfclose = W_Close; // close wadfile com.wfwrite = W_SaveLump; // dump lump into disk @@ -231,6 +233,14 @@ void Sys_GetStdAPI( void ) com.snprintf = com_snprintf; com.timestamp = com_timestamp; + // stringtable.c system + com.st_create = StringTable_CreateNewSystem; + com.st_getstring = StringTable_GetString; + com.st_setstring = StringTable_SetString; + com.st_load = StringTable_LoadSystem; + com.st_save = StringTable_SaveSystem; + com.st_remove = StringTable_DeleteSystem; + com.GameInfo = &GI; } diff --git a/launch/utils.c b/launch/utils.c new file mode 100644 index 00000000..8f000a0f --- /dev/null +++ b/launch/utils.c @@ -0,0 +1,253 @@ +//======================================================================= +// Copyright XashXT Group 2007 © +// utils.c - global system utils +//======================================================================= + +#include "launch.h" +#include "mathlib.h" +#include "const.h" + +static long idum = 0; + +#define MAX_RANDOM_RANGE 0x7FFFFFFFUL +#define IA 16807 +#define IM 2147483647 +#define IQ 127773 +#define IR 2836 +#define NTAB 32 +#define NDIV (1+(IM-1)/NTAB) +#define AM (1.0/IM) +#define EPS 1.2e-7 +#define RNMX (1.0 - EPS) + +void SeedRandomNumberGenerator( long lSeed ) +{ + if( lSeed ) idum = lSeed; + else idum = -time( NULL ); + + if( 1000 < idum ) idum = -idum; + else if( -1000 < idum ) idum -= 22261048; +} + +long lran1( void ) +{ + int j; + long k; + + static long iy = 0; + static long iv[NTAB]; + + if( idum <= 0 || !iy ) + { + if(-(idum) < 1) idum=1; + else idum = -(idum); + + for( j = NTAB + 7; j >= 0; j-- ) + { + k = (idum) / IQ; + idum = IA * (idum - k * IQ) - IR * k; + if( idum < 0 ) idum += IM; + if( j < NTAB ) iv[j] = idum; + } + iy = iv[0]; + } + k = (idum)/IQ; + idum = IA * (idum - k * IQ) - IR * k; + if( idum < 0 ) idum += IM; + j = iy / NDIV; + iy = iv[j]; + iv[j] = idum; + + return iy; +} + +// fran1 -- return a random floating-point number on the interval [0,1) +float fran1( void ) +{ + float temp = (float)AM * lran1(); + if( temp > RNMX ) return (float)RNMX; + else return temp; +} + +float Com_RandomFloat( float flLow, float flHigh ) +{ + float fl; + + if( idum == 0 ) SeedRandomNumberGenerator(0); + + fl = fran1(); // float in [0, 1) + return (fl * (flHigh - flLow)) + flLow; // float in [low, high) +} + +long Com_RandomLong( long lLow, long lHigh ) +{ + dword maxAcceptable; + dword n, x = lHigh-lLow + 1; + + if( idum == 0 ) SeedRandomNumberGenerator(0); + + if( x <= 0 || MAX_RANDOM_RANGE < x-1 ) + return lLow; + + // The following maps a uniform distribution on the interval [0, MAX_RANDOM_RANGE] + // to a smaller, client-specified range of [0,x-1] in a way that doesn't bias + // the uniform distribution unfavorably. Even for a worst case x, the loop is + // guaranteed to be taken no more than half the time, so for that worst case x, + // the average number of times through the loop is 2. For cases where x is + // much smaller than MAX_RANDOM_RANGE, the average number of times through the + // loop is very close to 1. + maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE+1) % x ); + do + { + n = lran1(); + } while( n > maxAcceptable ); + + return lLow + (n % x); +} + +#define MAX_STRINGTABLE_SYSTEMS 8 // separately stringsystems + +typedef struct stringtable_s +{ + string name; // system name (for debug targets) + char *data; // buffer with strings + size_t datasize; // current buffsize + size_t maxdatasize; // dynamically resized + + int *table; // indexes at begining string + size_t numstrings; // current strings count + size_t maxstrings; // current system limit +} stringtable_t; + +stringtable_t *dstring[MAX_STRINGTABLE_SYSTEMS]; + +bool StringTable_CheckHandle( int handle ) +{ + if( handle < 0 || handle > MAX_STRINGTABLE_SYSTEMS ) + { + MsgDev( D_ERROR, "StringTable_CheckHandle: invalid system handle %d\n", handle ); + return false; + } + if( !dstring[handle] ) + { + MsgDev( D_ERROR, "StringTable_CheckHandle: system with handle %d inactive\n", handle ); + return false; + } + return true; +} + +bool StringTable_CheckString( int handle, string_t str ) +{ + if(!StringTable_CheckHandle( handle )) + return false; + + if( str < 0 || str > dstring[handle]->numstrings ) + { + MsgDev( D_ERROR, "StringTable_CheckString: invalid string index %i\n", str ); + return false; + } + return true; +} + +int StringTable_CreateNewSystem( const char *name, size_t max_strings ) +{ + int i; + + // fisrt, find free stringtable system + for( i = 0; i < MAX_STRINGTABLE_SYSTEMS; i++ ) + { + if( !dstring[i] ) + { + // found free slot + dstring[i] = Mem_Alloc( Sys.stringpool, sizeof(stringtable_t)); + com_strncpy( dstring[i]->name, name, MAX_STRING ); + dstring[i]->maxstrings = max_strings; + return i; + } + } + + MsgDev( D_ERROR, "StringTable_CreateNewSystem: no free string systems\n" ); + return -1; +} + +void StringTable_DeleteSystem( int handle ) +{ + if(!StringTable_CheckHandle( handle )) + return; + + // now free stringtable + Mem_Free( dstring[handle]->data ); // free strings + Mem_Free( dstring[handle]->table); // free indices + Mem_Free( dstring[handle] ); // free himself + memset( &dstring[handle], 0, sizeof(stringtable_t)); +} + +const char *StringTable_GetString( int handle, string_t index ) +{ + if(!StringTable_CheckString( handle, index )) + return ""; + return &dstring[handle]->data[dstring[handle]->table[index]]; +} + +string_t StringTable_SetString( int handle, const char *string ) +{ + int i, len, table_size, data_size; + + if(!StringTable_CheckHandle( handle )) + return -1; + + for( i = 0; i < dstring[handle]->numstrings; i++ ) + { + if(!com.stricmp( string, StringTable_GetString( handle, i ))) + return i; // already existing + } + + // register new string + len = com.strlen( string ); + table_size = sizeof(string_t) * (dstring[handle]->numstrings + 1); + data_size = dstring[handle]->datasize + len + 1; + + if( table_size >= dstring[handle]->maxstrings ) + { + MsgDev( D_ERROR, "StringTable_SetString: string table %s limit exeeded\n", dstring[handle]->name ); + return -1; + } + + dstring[handle]->table = Mem_Realloc( Sys.stringpool, dstring[handle]->table, table_size ); + dstring[handle]->data = Mem_Realloc( Sys.stringpool, dstring[handle]->data, data_size ); + + com.strcpy( &dstring[handle]->data[dstring[handle]->datasize], string ); + dstring[handle]->table[dstring[handle]->numstrings] = dstring[handle]->datasize; + dstring[handle]->datasize += len + 1; // null terminator + dstring[handle]->numstrings++; + + return dstring[handle]->numstrings - 1; // current index +} + +bool StringTable_SaveSystem( int h, wfile_t *wad ) +{ + int table_size; + + if(!StringTable_CheckHandle( h )) + return false; + if(!W_SaveLump( wad, "stringdata", dstring[h]->data, dstring[h]->datasize, TYPE_STRDATA, CMP_ZLIB )) + return false; + table_size = dstring[h]->numstrings * sizeof(string_t); + if(!W_SaveLump( wad, "stringtable", dstring[h]->table, table_size, TYPE_STRDATA, CMP_ZLIB )) + return false; + + StringTable_DeleteSystem( h ); // strings dumped, now we can free it + return true; +} + +int StringTable_LoadSystem( wfile_t *wad, const char *name ) +{ + int h = StringTable_CreateNewSystem( name, MAX_MAP_NUMSTRINGS ); + int datasize, numstrings; + + dstring[h]->data = W_LoadLump( wad, "stringdata", &datasize, TYPE_STRDATA ); + dstring[h]->table = (int *)W_LoadLump( wad, "stringtable", &numstrings, TYPE_STRDATA ); + dstring[h]->datasize = datasize; + dstring[h]->numstrings = numstrings / sizeof(int); + return h; +} \ No newline at end of file diff --git a/public/const.h b/public/const.h index 9fcde1e2..561b0c97 100644 --- a/public/const.h +++ b/public/const.h @@ -5,26 +5,44 @@ #ifndef CONST_H #define CONST_H +// dlumpinfo_t->compression +#define CMP_NONE 0 // compression none +#define CMP_LZSS 1 // currently not used +#define CMP_ZLIB 2 // zip-archive compression + +// dlumpinfo_t->type +#define TYPE_QPAL 64 // quake palette +#define TYPE_QTEX 65 // probably was never used +#define TYPE_QPIC 66 // quake1 and hl pic (lmp_t) +#define TYPE_MIPTEX2 67 // half-life (mip_t) previous was TYP_SOUND but never used in quake1 +#define TYPE_MIPTEX 68 // quake1 (mip_t) +#define TYPE_BINDATA 69 // engine internal data +#define TYPE_STRDATA 70 // big unterminated string (stringtable marked as TYPE_BINARYDATA) + +#define TYPE_RAW 71 // unrecognized raw data +#define TYPE_SCRIPT 72 // .txt scrips (xash ext) +#define TYPE_VPROGS 73 // .dat progs (xash ext) + // entity_state_t->renderfx -#define RF_MINLIGHT (1<<0) // allways have some light (viewmodel) -#define RF_PLAYERMODEL (1<<1) // don't draw through eyes, only mirrors -#define RF_VIEWMODEL (1<<2) // it's a viewmodel -#define RF_FULLBRIGHT (1<<3) // allways draw full intensity -#define RF_DEPTHHACK (1<<4) // for view weapon Z crunching +#define RF_MINLIGHT (1<<0) // allways have some light (viewmodel) +#define RF_PLAYERMODEL (1<<1) // don't draw through eyes, only mirrors +#define RF_VIEWMODEL (1<<2) // it's a viewmodel +#define RF_FULLBRIGHT (1<<3) // allways draw full intensity +#define RF_DEPTHHACK (1<<4) // for view weapon Z crunching #define RF_TRANSLUCENT (1<<5) -#define RF_IR_VISIBLE (1<<6) // skin is an index in image_precache +#define RF_IR_VISIBLE (1<<6) // skin is an index in image_precache #define RF_HOLOGRAMM (1<<7) // entity_state_t->effects -#define EF_BRIGHTFIELD (1<<0) // swirling cloud of particles -#define EF_MUZZLEFLASH (1<<1) // single frame ELIGHT on entity attachment 0 -#define EF_BRIGHTLIGHT (1<<2) // DLIGHT centered at entity origin -#define EF_DIMLIGHT (1<<3) // player flashlight -#define EF_INVLIGHT (1<<4) // get lighting from ceiling -#define EF_NOINTERP (1<<5) // don't interpolate the next frame -#define EF_LIGHT (1<<6) // rocket flare glow sprite -#define EF_NODRAW (1<<7) // don't draw entity -#define EF_TELEPORT (1<<8) // create teleport splash -#define EF_ROTATE (1<<9) // rotate bonus item +#define EF_BRIGHTFIELD (1<<0) // swirling cloud of particles +#define EF_MUZZLEFLASH (1<<1) // single frame ELIGHT on entity attachment 0 +#define EF_BRIGHTLIGHT (1<<2) // DLIGHT centered at entity origin +#define EF_DIMLIGHT (1<<3) // player flashlight +#define EF_INVLIGHT (1<<4) // get lighting from ceiling +#define EF_NOINTERP (1<<5) // don't interpolate the next frame +#define EF_LIGHT (1<<6) // rocket flare glow sprite +#define EF_NODRAW (1<<7) // don't draw entity +#define EF_TELEPORT (1<<8) // create teleport splash +#define EF_ROTATE (1<<9) // rotate bonus item #endif//CONST_H \ No newline at end of file diff --git a/public/ref_dfiles.h b/public/ref_dfiles.h index 7d8996d9..ec87cb7f 100644 --- a/public/ref_dfiles.h +++ b/public/ref_dfiles.h @@ -90,61 +90,6 @@ typedef struct frametype_t type; } dframetype_t; -/* -======================================================================== -.WAD archive format (WhereAllData - WAD) - -List of compressed files, that can be identify only by TYPE_* - - -header: dwadinfo_t[dwadinfo_t] -file_1: byte[dwadinfo_t[num]->disksize] -file_2: byte[dwadinfo_t[num]->disksize] -file_3: byte[dwadinfo_t[num]->disksize] -... -file_n: byte[dwadinfo_t[num]->disksize] -infotable dlumpinfo_t[dwadinfo_t->numlumps] -======================================================================== -*/ -#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD3" half-life wads - -#define WAD3_NAMELEN 16 -#define MAX_FILES_IN_WAD 8192 - -#define CMP_NONE 0 // compression none -#define CMP_LZSS 1 // RLE compression ? -#define CMP_ZLIB 2 // zip-archive compression - -#define TYPE_ANY -1 // any type can be accepted -#define TYPE_NONE 0 // blank lump -#define TYPE_QPAL 64 // quake palette -#define TYPE_QTEX 65 // probably was never used -#define TYPE_QPIC 66 // quake1 and hl pic (lmp_t) -#define TYPE_MIPTEX2 67 // half-life (mip_t) previous was TYP_SOUND but never used in quake1 -#define TYPE_MIPTEX 68 // quake1 (mip_t) -#define TYPE_RAW 69 // unrecognized raw data -#define TYPE_SCRIPT 70 // .txt scrips (xash ext) -#define TYPE_VPROGS 71 // .dat progs (xash ext) - -typedef struct -{ - int ident; // should be IWAD, WAD2 or WAD3 - int numlumps; // num files - 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[16]; // must be null terminated -} dlumpinfo_t; - /* ======================================================================== @@ -255,7 +200,7 @@ BRUSH MODELS #define DVIS_PHS 1 #define DENT_KEY 0 -#define DENT_VALUE 1 +#define DENT_VAL 1 //other limits #define MAXLIGHTMAPS 4 @@ -286,7 +231,7 @@ typedef struct typedef struct { string_t epair[2]; // 0 - key, 1 - value (indexes from stringtable) -} dentity_t; +} dkeyvalue_t; typedef struct { @@ -373,7 +318,7 @@ typedef struct typedef struct { string_t s_name; // string system index - string_t s_next; // anim chain texture + int s_next; // number of next texture in animchain int size[2]; // valid size for current s\t coords (used for replace texture) } dmiptex_t; @@ -401,6 +346,15 @@ a internal virtual machine like as QuakeC, but it has more extensions #define VPROGS_VERSION 8 // xash progs version #define VPROGSHEADER32 (('2'<<24)+('3'<<16)+('M'<<8)+'V') // little-endian "VM32" +// prvm limits +#define MAX_REGS 65536 +#define MAX_STRINGS 1000000 +#define MAX_STATEMENTS 0x80000 +#define MAX_GLOBALS 32768 +#define MAX_FUNCTIONS 16384 +#define MAX_FIELDS 2048 +#define MAX_CONSTANTS 2048 + // global ofsets #define OFS_NULL 0 #define OFS_RETURN 1 @@ -827,37 +781,4 @@ typedef struct int normindex; // normal vec3_t } mstudiomesh_t; -/* -============================================================================== -SAVE FILE - -included global, and both (client & server) pent list -============================================================================== -*/ -#define SAVE_VERSION 3 -#define IDSAVEHEADER (('E'<<24)+('V'<<16)+('A'<<8)+'S') // little-endian "SAVE" - -#define LUMP_COMMENTS 0 // map comments (name, savetime) -#define LUMP_CFGSTRING 1 // client info strings -#define LUMP_AREASTATE 2 // area portals state -#define LUMP_GAMESTATE 3 // progs global state (compressed) -#define LUMP_MAPNAME 4 // map name -#define LUMP_GAMECVARS 5 // contain game comment and all cvar state -#define LUMP_GAMEENTS 6 // ents state (compressed) -#define LUMP_SNAPSHOT 7 // rgb32 image snapshot (128x128) -#define SAVE_NUMLUMPS 8 // header size - -typedef struct -{ - int ident; - int version; - lump_t lumps[SAVE_NUMLUMPS]; -} dsavehdr_t; - -typedef struct -{ - char name[MAX_QPATH]; - char value[MAX_QPATH]; -} dsavecvar_t; - #endif//REF_DFILES_H \ No newline at end of file diff --git a/public/ref_dllapi.h b/public/ref_dllapi.h index 32eb30a2..c521666d 100644 --- a/public/ref_dllapi.h +++ b/public/ref_dllapi.h @@ -45,7 +45,7 @@ typedef enum { mod_bad, mod_world, mod_brush, mod_studio, mod_sprite } modtype_t typedef void (*cmsave_t) (void* handle, const void* buffer, size_t size); typedef void (*cmdraw_t)( int color, int numpoints, const float *points ); typedef struct { int numfilenames; char **filenames; char *filenamesbuffer; } search_t; -typedef void (*cvarcmd_t)(const char *s, const char *m, const char *d, void *ptr ); +typedef void (*setpair_t)(const char *key, const char *value, void *buffer, void *numpairs ); typedef struct { @@ -502,7 +502,7 @@ typedef struct stdilib_api_s // console variables cvar_t *(*Cvar_Get)(const char *name, const char *value, int flags, const char *desc); - void (*Cvar_LookupVars)( int checkbit, char *buffer, void *ptr, cvarcmd_t callback ); + void (*Cvar_LookupVars)( int checkbit, void *buffer, void *ptr, setpair_t callback ); void (*Cvar_SetString)( const char *name, const char *value ); void (*Cvar_SetLatched)( const char *name, const char *value); void (*Cvar_FullSet)( char *name, char *value, int flags ); @@ -517,7 +517,7 @@ typedef struct stdilib_api_s uint (*Cmd_Argc)( void ); char *(*Cmd_Args)( void ); char *(*Cmd_Argv)( uint arg ); - void (*Cmd_LookupCmds)( char *buffer, void *ptr, cvarcmd_t callback ); + void (*Cmd_LookupCmds)( char *buffer, void *ptr, setpair_t callback ); void (*Cmd_AddCommand)(const char *name, xcommand_t function, const char *desc); void (*Cmd_TokenizeString)(const char *text_in); void (*Cmd_DelCommand)(const char *name); @@ -544,10 +544,12 @@ typedef struct stdilib_api_s int (*vfprintf)(vfile_t* file, const char* format, ...); // write formatted message int (*vfseek)(vfile_t* file, fs_offset_t offset, int whence); // fseek, can seek in packfiles too bool (*vfunpack)( void* comp, size_t size1, void **buf, size_t size2);// deflate zipped buffer + byte *(*vfbuffer)( vfile_t *file ); // get pointer to virtual filebuff long (*vftell)(vfile_t* file); // like a ftell bool (*vfeof)( vfile_t* file); // like a feof // wadstorage filesystem + int (*wfcheck)( const char *filename ); // validate container wfile_t *(*wfopen)( const char *filename, const char *mode ); // open wad file or create new void (*wfclose)( wfile_t *wad ); // close wadfile long (*wfwrite)( wfile_t *wad, const char *lump, const void* data, size_t datasize, char type, char cmp ); @@ -610,6 +612,14 @@ typedef struct stdilib_api_s int (*vsnprintf)(char *buf, size_t size, const char *fmt, va_list args); // format message int (*snprintf)(char *buffer, size_t buffersize, const char *format, ...); // print into buffer const char* (*timestamp)( int format ); // returns current time stamp + + // stringtable system + int (*st_create)( const char *name, size_t max_strings ); + const char *(*st_getstring)( int handle, string_t index ); + string_t (*st_setstring)( int handle, const char *string ); + int (*st_load)( wfile_t *wad, const char *name ); + bool (*st_save)( int h, wfile_t *wad ); + void (*st_remove)( int handle ); // misc utils gameinfo_t *GameInfo; // user game info (filled by engine) @@ -782,6 +792,7 @@ virtual filesystem manager =========================================== */ #define VFS_Create com.vfcreate +#define VFS_GetBuffer com.vfbuffer #define VFS_Open com.vfopen #define VFS_Write com.vfwrite #define VFS_Read com.vfread @@ -800,6 +811,7 @@ wadstorage filesystem manager =========================================== */ #define WAD_Open com.wfopen +#define WAD_Check com.wfcheck #define WAD_Close com.wfclose #define WAD_Write com.wfwrite #define WAD_Read com.wfread @@ -856,6 +868,12 @@ misc utils #define RunThreadsOnIndividual com.Com_CreateThread #define Com_RandomLong com.Com_RandomLong #define Com_RandomFloat com.Com_RandomFloat +#define StringTable_Create com.st_create +#define StringTable_Delete com.st_remove +#define StringTable_GetString com.st_getstring +#define StringTable_SetString com.st_setstring +#define StringTable_Load com.st_load +#define StringTable_Save com.st_save /* =========================================== @@ -1531,7 +1549,8 @@ typedef struct prvm_prog_s void (*init_edict)(edict_t *edict); void (*free_edict)(edict_t *ed); void (*count_edicts)(void); - bool (*load_edict)(edict_t *ent); + bool (*load_edict)(edict_t *ent); // initialize edict for first loading + void (*restore_edict)(edict_t *ent); // restore edict from savegame or changelevel void (*init_cmd)(void); void (*reset_cmd)(void); void (*error_cmd)(const char *format, ...); @@ -1552,14 +1571,15 @@ typedef struct vprogs_exp_s void ( *Update )( dword time ); // refreshing compile, exec some programs e.t.c // edict operations - void (*WriteGlobals)( vfile_t *f ); - void (*ParseGlobals)( const char *data ); - void (*PrintEdict)( edict_t *ed ); - void (*WriteEdict)( vfile_t *f, edict_t *ed ); - const char *(*ParseEdict)( const char *data, edict_t *ed ); edict_t *(*AllocEdict)( void ); void (*FreeEdict)( edict_t *ed ); - void (*IncreaseEdicts)( void ); + void (*PrintEdict)( edict_t *ed ); + + // savegame stuff + void (*WriteGlobals)( void *buffer, void *ptr, setpair_t callback ); + void (*ReadGlobals)( int s_table, dkeyvalue_t *globals, int count ); + void (*WriteEdict)( edict_t *ed, void *buffer, void *ptr, setpair_t callback ); + void (*ReadEdict)( int s_table, int ednum, dkeyvalue_t *fields, int numpairs ); // load ents description void (*LoadFromFile)( const char *data ); @@ -1568,8 +1588,6 @@ typedef struct vprogs_exp_s const char *(*GetString)( int num ); int (*SetEngineString)( const char *s ); int (*SetTempString)( const char *s ); - int (*AllocString)( size_t bufferlength, char **pointer ); - void (*FreeString)( int num ); void (*InitProg)( int prognr ); void (*SetProg)( int prognr ); diff --git a/ripper/conv_bsplumps.c b/ripper/conv_bsplumps.c index e73605ba..0967d8b4 100644 --- a/ripper/conv_bsplumps.c +++ b/ripper/conv_bsplumps.c @@ -9,6 +9,14 @@ #define IDIWADHEADER (('D'<<24)+('A'<<16)+('W'<<8)+'I') // little-endian "IWAD" doom1 game wad #define IDPWADHEADER (('D'<<24)+('A'<<16)+('W'<<8)+'P') // little-endian "PWAD" doom1 game wad #define IDWAD2HEADER (('2'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD2" quake1 gfx.wad +#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W') // little-endian "WAD3" half-life wads + +typedef struct +{ + int ident; // should be IWAD, WAD2 or WAD3 + int numlumps; // num files + int infotableofs; +} dwadheader_t; typedef struct { @@ -161,11 +169,11 @@ bool Conv_CheckMap( const char *mapname ) bool Conv_CheckWad( const char *wadname ) { file_t *f = FS_Open( wadname, "rb" ); - dwadinfo_t hdr; // generic header + dwadheader_t hdr; // generic header if( !f ) return false; - if(FS_Read( f, &hdr, sizeof(dwadinfo_t)) != sizeof(dwadinfo_t)) + if(FS_Read( f, &hdr, sizeof(dwadheader_t)) != sizeof(dwadheader_t)) { FS_Close( f ); // very strange file with size smaller than 12 bytes and ext .wad return false; diff --git a/todo.log b/todo.log index 6fe4681e..9e4342ea 100644 --- a/todo.log +++ b/todo.log @@ -27,24 +27,11 @@ TODO LIST Упорядочить EF_, RF_ ed_type проверки Анимация (разобраться с pev->animtime) - +Смена формата карты!!!!!!!!! выбросить лишние ресурсы забэкапить результат -#define DENTITY_KEY 0 -#define DENTITY_VALUE 1 - -typedef struct -{ - string_t epair[2]; [variable sized][2] -} dentity_t; - -// only once bsp file can be opened -bool FS_OpenBSP( const char *name, const char *mode ); -bool FS_ReadLump( const char *name, char type, int version, size_t *lmpsize, byte *data ); -bool FS_SaveLump( const char *name, char type, int version, size_t lumpsize, byte *data ); -bool FS_CloseBSP( void ); Список доступных рендереров: Что в них интересного 0. Q3Fusion (Mirrors, Portals) diff --git a/vprogs/pr_edict.c b/vprogs/pr_edict.c index 26d05da0..41cac402 100644 --- a/vprogs/pr_edict.c +++ b/vprogs/pr_edict.c @@ -440,27 +440,26 @@ char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val) // Parse the string a bit to turn special characters // (like newline, specifically) into escape codes, // this fixes saving games from various mods - s = PRVM_GetString (val->string); - for (i = 0;i < (int)sizeof(line) - 2 && *s;) + s = PRVM_GetString ( val->string ); + for( i = 0;i < (int)sizeof(line) - 2 && *s; ) { - if (*s == '\n') + if( *s == '\n' ) { line[i++] = '\\'; line[i++] = 'n'; } - else if (*s == '\r') + else if( *s == '\r' ) { line[i++] = '\\'; line[i++] = 'r'; } - else - line[i++] = *s; + else line[i++] = *s; s++; } line[i] = '\0'; break; case ev_entity: - com.sprintf (line, "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict))); + com.sprintf( line, "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict))); break; case ev_function: f = vm.prog->functions + val->function; @@ -622,42 +621,85 @@ PRVM_ED_Write For savegames ============= */ -void PRVM_ED_Write(vfile_t *f, edict_t *ed) +void PRVM_ED_Write( edict_t *ed, void *buffer, void *numpairs, setpair_t callback ) { ddef_t *d; int *v; int i, j; - const char *name; + const char *name, *value; int type; - VFS_Print(f, "{\n"); - - if (ed->priv.ed->free) + if( !callback ) return; + if( ed->priv.ed->free ) { - VFS_Print(f, "}\n"); + // freed entity too has serialnumber! + callback( NULL, NULL, buffer, numpairs ); return; } - for (i = 1; i < vm.prog->progs->numfielddefs; i++) + for( i = 1; i < vm.prog->progs->numfielddefs; i++ ) { d = &vm.prog->fielddefs[i]; - name = PRVM_GetString(d->s_name); - if (name[com.strlen(name)-2] == '_') + name = PRVM_GetString( d->s_name ); + if(name[com.strlen(name) - 2] == '_') continue; // skip _x, _y, _z vars - v = (int *)((char *)ed->progs.vp + d->ofs*4); - + v = (int *)((char *)ed->progs.vp + d->ofs * 4); // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; - for (j = 0; j < prvm_type_size[type]; j++) - if(v[j]) break; - if (j == prvm_type_size[type]) - continue; + for( j = 0; j < prvm_type_size[type]; j++ ) + if( v[j] ) break; + if( j == prvm_type_size[type] ) continue; - VFS_Printf(f,"\"%s\" ",name); - VFS_Printf(f,"\"%s\"\n", PRVM_UglyValueString((etype_t)d->type, (prvm_eval_t *)v)); + value = PRVM_UglyValueString((etype_t)d->type, (prvm_eval_t *)v); + callback( name, value, buffer, numpairs ); } - VFS_Print(f, "}\n"); +} + +/* +============= +PRVM_ED_Read + +For savegames +============= +*/ +void PRVM_ED_Read( int s_table, int entnum, dkeyvalue_t *fields, int numpairs ) +{ + const char *keyname, *value; + ddef_t *key; + edict_t *ent; + int i; + + if( entnum >= vm.prog->limit_edicts ) Host_Error( "PRVM_ED_Read: too many edicts in save file\n" ); + while( entnum >= vm.prog->max_edicts) PRVM_MEM_IncreaseEdicts(); // increase edict numbers + ent = PRVM_EDICT_NUM( entnum ); + PRVM_ED_ClearEdict( ent ); + + if( !numpairs ) + { + // freed edict + ent->priv.ed->free = true; + return; + } + + // go through all the dictionary pairs + for( i = 0; i < numpairs; i++ ) + { + keyname = StringTable_GetString( s_table, fields[i].epair[DENT_KEY] ); + value = StringTable_GetString( s_table, fields[i].epair[DENT_VAL] ); + + key = PRVM_ED_FindField( keyname ); + if( !key ) + { + MsgDev( D_WARN, "%s: unknown field '%s'\n", PRVM_NAME, keyname); + continue; + } + // simple huh ? + if(!PRVM_ED_ParseEpair( ent, key, value )) PRVM_ERROR( "PRVM_ED_ParseEdict: parse error" ); + } + + // all done, restore physics interaction links or somelike + PRVM_GCALL(restore_edict)(ent); } void PRVM_ED_PrintNum (int ent) @@ -700,28 +742,27 @@ PRVM_ED_PrintEdict_f For debugging, prints a single edict ============= */ -void PRVM_ED_PrintEdict_f (void) +void PRVM_ED_PrintEdict_f( void ) { int i; - if(Cmd_Argc() != 3) + if( Cmd_Argc() != 3 ) { Msg("prvm_edict \n"); return; } - - if(!PRVM_SetProgFromString(Cmd_Argv(1))) return; + if(!PRVM_SetProgFromString(Cmd_Argv( 1 ))) return; i = com.atoi (Cmd_Argv(2)); - if (i >= vm.prog->num_edicts) + if( i >= vm.prog->num_edicts ) { - Msg("Bad edict number\n"); + Msg( "bad edict number\n" ); vm.prog = NULL; return; } - PRVM_ED_PrintNum (i); + PRVM_ED_PrintNum( i ); vm.prog = NULL; } @@ -732,9 +773,7 @@ PRVM_ED_Count For debugging ============= */ -// 2 possibilities : 1. just displaying the active edict count -// 2. making a function pointer [x] -void PRVM_ED_Count_f (void) +void PRVM_ED_Count_f( void ) { int i; edict_t *ent; @@ -742,40 +781,35 @@ void PRVM_ED_Count_f (void) if(Cmd_Argc() != 2) { - Msg("prvm_count \n"); + Msg( "prvm_count \n" ); return; } - if(!PRVM_SetProgFromString(Cmd_Argv(1))) + if(!PRVM_SetProgFromString(Cmd_Argv( 1 ))) return; - if(vm.prog->count_edicts) - vm.prog->count_edicts(); + if( vm.prog->count_edicts ) vm.prog->count_edicts(); else { active = 0; - for (i=0 ; inum_edicts ; i++) + for( i = 0; i < vm.prog->num_edicts; i++ ) { - ent = PRVM_EDICT_NUM(i); - if (ent->priv.ed->free) + ent = PRVM_EDICT_NUM( i ); + if( ent->priv.ed->free ) continue; active++; } - Msg("num_edicts:%3i\n", vm.prog->num_edicts); - Msg("active :%3i\n", active); + Msg( "num_edicts:%3i\n", vm.prog->num_edicts ); + Msg( "active :%3i\n", active ); } - vm.prog = NULL; } /* ============================================================================== - - ARCHIVING GLOBALS - -FIXME: need to tag constants, doesn't really work + ARCHIVING GLOBALS ============================================================================== */ /* @@ -783,14 +817,17 @@ FIXME: need to tag constants, doesn't really work PRVM_ED_WriteGlobals ============= */ -void PRVM_ED_WriteGlobals( vfile_t *f ) +void PRVM_ED_WriteGlobals( void *buffer, void *numpairs, setpair_t callback ) { ddef_t *def; const char *name; + const char *value; int i, type; - VFS_Print(f,"{\n"); - for (i = 0; i < vm.prog->progs->numglobaldefs; i++) + // nothing to process ? + if( !callback ) return; + + for( i = 0; i < vm.prog->progs->numglobaldefs; i++ ) { def = &vm.prog->globaldefs[i]; type = def->type; @@ -798,51 +835,39 @@ void PRVM_ED_WriteGlobals( vfile_t *f ) continue; type &= ~DEF_SAVEGLOBAL; - if (type != ev_string && type != ev_float && type != ev_entity) + if( type != ev_string && type != ev_float && type != ev_entity ) continue; name = PRVM_GetString(def->s_name); - VFS_Printf(f,"\"%s\" ", name); - VFS_Printf(f,"\"%s\"\n", PRVM_UglyValueString((etype_t)type, (prvm_eval_t *)&vm.prog->globals.gp[def->ofs])); + value = PRVM_UglyValueString((etype_t)type, (prvm_eval_t *)&vm.prog->globals.gp[def->ofs]); + callback( name, value, buffer, numpairs ); } - VFS_Print(f,"}\n"); } /* ============= -PRVM_ED_ParseGlobals +PRVM_ED_ReadGlobals ============= */ -void PRVM_ED_ParseGlobals (const char *data) +void PRVM_ED_ReadGlobals( int s_table, dkeyvalue_t *globals, int numpairs ) { - char keyname[MAX_MSGLEN]; - ddef_t *key; + const char *keyname; + const char *value; + ddef_t *key; + int i; - while (1) + for( i = 0; i < numpairs; i++ ) { - // parse key - if (!Com_SimpleGetToken(&data)) - PRVM_ERROR ("PRVM_ED_ParseGlobals: EOF without closing brace\n"); - if (com_token[0] == '}') break; - if (com_token[0] == '{') continue; - com.strncpy (keyname, com_token, sizeof(keyname)); + keyname = StringTable_GetString( s_table, globals[i].epair[DENT_KEY] ); + value = StringTable_GetString( s_table, globals[i].epair[DENT_VAL]); - // parse value - if (!Com_SimpleGetToken(&data)) - PRVM_ERROR ("PRVM_ED_ParseGlobals: EOF without closing brace\n"); - - if (com_token[0] == '}') - PRVM_ERROR ("PRVM_ED_ParseGlobals: closing brace without data\n"); - - key = PRVM_ED_FindGlobal (keyname); - if (!key) + key = PRVM_ED_FindGlobal( keyname ); + if( !key ) { - MsgDev(D_INFO, "'%s' is not a global on %s\n", keyname, PRVM_NAME); + MsgDev( D_INFO, "'%s' is not a global on %s\n", keyname, PRVM_NAME ); continue; } - - if (!PRVM_ED_ParseEpair(NULL, key, com_token)) - PRVM_ERROR ("PRVM_ED_ParseGlobals: parse error\n"); + if( !PRVM_ED_ParseEpair( NULL, key, value )) PRVM_ERROR( "PRVM_ED_ReadGlobals: parse error\n" ); } } @@ -857,13 +882,13 @@ Can parse either fields or globals returns false if error ============= */ -bool PRVM_ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s) +bool PRVM_ED_ParseEpair( edict_t *ent, ddef_t *key, const char *s ) { - int i, l; - char *new_p; - ddef_t *def; - prvm_eval_t *val; - mfunction_t *func; + int i, l; + char *new_p; + ddef_t *def; + prvm_eval_t *val; + mfunction_t *func; if( ent ) val = (prvm_eval_t *)((int *)ent->progs.vp + key->ofs); else val = (prvm_eval_t *)((int *)vm.prog->globals.gp + key->ofs); @@ -891,36 +916,34 @@ bool PRVM_ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s) break; case ev_float: while(*s && *s <= ' ') s++; - val->_float = com.atof(s); + val->_float = com.atof( s ); break; case ev_vector: - for (i = 0; i < 3; i++) + for( i = 0; i < 3; i++ ) { - while (*s && *s <= ' ') s++; - if (!*s) break; - val->vector[i] = com.atof(s); - while (*s > ' ') s++; + while(*s && *s <= ' ') s++; + if( !*s ) break; + val->vector[i] = com.atof( s ); + while( *s > ' ' ) s++; if (!*s) break; } break; case ev_entity: - while (*s && *s <= ' ') - s++; - i = com.atoi(s); + while( *s && *s <= ' ' ) s++; + i = com.atoi( s ); if (i >= vm.prog->limit_edicts) - MsgDev(D_WARN, "PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= limit_edicts %u) on %s\n", (uint)i, (uint)vm.prog->limit_edicts, PRVM_NAME); - while (i >= vm.prog->max_edicts) - PRVM_MEM_IncreaseEdicts(); + MsgDev( D_WARN, "PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= limit_edicts %u) on %s\n", (uint)i, (uint)vm.prog->limit_edicts, PRVM_NAME); + while( i >= vm.prog->max_edicts ) PRVM_MEM_IncreaseEdicts(); // if IncreaseEdicts was called the base pointer needs to be updated - if (ent) val = (prvm_eval_t *)((int *)ent->progs.vp + key->ofs); + if( ent ) val = (prvm_eval_t *)((int *)ent->progs.vp + key->ofs); val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM((int)i)); break; case ev_field: def = PRVM_ED_FindField(s); - if (!def) + if( !def ) { - MsgDev(D_WARN, "PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME); + MsgDev( D_WARN, "PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME ); return false; } val->_int = def->ofs; @@ -928,16 +951,16 @@ bool PRVM_ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s) case ev_function: func = PRVM_ED_FindFunction(s); - if (!func) + if( !func ) { - MsgDev(D_WARN, "PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME); + MsgDev( D_WARN, "PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME ); return false; } val->function = func - vm.prog->functions; break; default: - MsgDev(D_WARN, "PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(key->s_name), PRVM_NAME); + MsgDev( D_WARN, "PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(key->s_name), PRVM_NAME ); return false; } return true; diff --git a/vprogs/pr_local.h b/vprogs/pr_local.h index b4b1dd83..d263ab62 100644 --- a/vprogs/pr_local.h +++ b/vprogs/pr_local.h @@ -494,14 +494,7 @@ typedef enum { extern pr_info_t pr; extern byte *qccpool; extern file_t *asmfile; -extern uint MAX_REGS; extern int MAX_ERRORS; -extern int MAX_STRINGS; -extern int MAX_GLOBALS; -extern int MAX_FIELDS; -extern int MAX_STATEMENTS; -extern int MAX_FUNCTIONS; -extern int MAX_CONSTANTS; extern char *compilingfile; extern char progsoutname[MAX_SYSPATH]; extern char sourcedir[MAX_SYSPATH]; diff --git a/vprogs/pr_main.c b/vprogs/pr_main.c index e4679ee9..37c77223 100644 --- a/vprogs/pr_main.c +++ b/vprogs/pr_main.c @@ -10,14 +10,7 @@ byte *qccpool; int com_argc = 0; char **com_argv; char v_copyright[1024]; -uint MAX_REGS; int MAX_ERRORS; -int MAX_STRINGS; -int MAX_GLOBALS; -int MAX_FIELDS; -int MAX_STATEMENTS; -int MAX_FUNCTIONS; -int MAX_CONSTANTS; int numtemps; bool compileactive = false; char progsoutname[MAX_SYSPATH]; @@ -155,17 +148,8 @@ void PR_InitCompile( const char *name ) com.strncat(v_copyright,"This file was created with Xash3D QuakeC compiler,\n", sizeof(v_copyright)); com.strncat(v_copyright,"who based on original code of ForeThought's QuakeC compiler.\n",sizeof(v_copyright)); com.strncat(v_copyright,"Thanks to ID Software at all.", sizeof(v_copyright)); - - // tune limits - MAX_REGS = 65536; - MAX_ERRORS = 10; // per one file - MAX_STRINGS = 1000000; - MAX_GLOBALS = 32768; - MAX_FIELDS = 2048; - MAX_STATEMENTS = 0x80000; - MAX_FUNCTIONS = 16384; - maxtypeinfos = 16384; - MAX_CONSTANTS = 2048; + MAX_ERRORS = 10; // per one file + maxtypeinfos = 16384; PR_SetDefaultProperties(); @@ -382,20 +366,17 @@ vprogs_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, void *unused ) vm.Update = PRVM_Frame; vm.WriteGlobals = PRVM_ED_WriteGlobals; - vm.ParseGlobals = PRVM_ED_ParseGlobals; + vm.ReadGlobals = PRVM_ED_ReadGlobals; vm.PrintEdict = PRVM_ED_Print; vm.WriteEdict = PRVM_ED_Write; - vm.ParseEdict = PRVM_ED_ParseEdict; + vm.ReadEdict = PRVM_ED_Read; vm.AllocEdict = PRVM_ED_Alloc; vm.FreeEdict = PRVM_ED_Free; - vm.IncreaseEdicts = PRVM_MEM_IncreaseEdicts; vm.LoadFromFile = PRVM_ED_LoadFromFile; vm.GetString = PRVM_GetString; vm.SetEngineString = PRVM_SetEngineString; vm.SetTempString = PRVM_SetTempString; - vm.AllocString = PRVM_AllocString; - vm.FreeString = PRVM_FreeString; vm.InitProg = PRVM_InitProg; vm.SetProg = PRVM_SetProg; diff --git a/vprogs/pr_utils.c b/vprogs/pr_utils.c index 2baa628b..203eef16 100644 --- a/vprogs/pr_utils.c +++ b/vprogs/pr_utils.c @@ -4,6 +4,7 @@ //======================================================================= #include "vprogs.h" +#include "const.h" void Hash_InitTable(hashtable_t *table, int numbucks) { diff --git a/vprogs/vprogs.h b/vprogs/vprogs.h index cf828f45..fd2ec271 100644 --- a/vprogs/vprogs.h +++ b/vprogs/vprogs.h @@ -359,13 +359,14 @@ void PRVM_ED_ClearEdict (edict_t *e); ddef_t *PRVM_ED_GlobalAtOfs( int ofs ); void PRVM_PrintFunctionStatements (const char *name); void PRVM_ED_Print(edict_t *ed); -void PRVM_ED_Write (vfile_t *f, edict_t *ed); +void PRVM_ED_Write( edict_t *ed, void *buffer, void *ptr, setpair_t callback ); +void PRVM_ED_Read( int s_table, int ednum, dkeyvalue_t *fields, int numpairs ); const char *PRVM_ED_ParseEdict (const char *data, edict_t *ent); char *PRVM_ValueString( etype_t type, prvm_eval_t *val ); -void PRVM_ED_WriteGlobals (vfile_t *f); -void PRVM_ED_ParseGlobals (const char *data); +void PRVM_ED_WriteGlobals( void *buffer, void *ptr, setpair_t callback ); +void PRVM_ED_ReadGlobals( int s_table, dkeyvalue_t *globals, int numpairs ); -void PRVM_ED_LoadFromFile (const char *data); +void PRVM_ED_LoadFromFile( const char *data ); edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline); #define PRVM_EDICT_NUM(n) (((n) >= 0 && (n) < vm.prog->max_edicts) ? vm.prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__))