diff --git a/engine/Makefile b/engine/Makefile index ba15d2ad1..937795c8e 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -66,7 +66,15 @@ ifeq ($(USEASM),true) DO_AS=$(CC) $(BASE_CFLAGS) $(WCFLAGS) -x assembler-with-cpp -DELF -o $@ -c $< $(CFLAGS) endif endif -BASELDFLAGS=-lm + +ifeq ($(FTE_TARGET),win32) + BASELDFLAGS=-lm +endif +ifeq ($(FTE_TARGET),cygwin) + BASELDFLAGS=-lm +endif +BASELDFLAGS ?= -lm -ldl + #BASELDFLAGS=-lm -lz GLXLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lpng -ljpeg GLSLDFLAGS=-L/usr/X11R6/lib -lMesaGL -lglide -lvga diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 72510f009..f9f2bea10 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -27,6 +27,9 @@ float demtime; int cls_lastto; int cls_lasttype; +void CL_PlayDemo(char *demoname); +char lastdemoname[256]; + /* ============================================================================== @@ -54,7 +57,7 @@ void CL_StopPlayback (void) Media_CaptureDemoEnd(); - fclose (cls.demofile); + VFS_CLOSE (cls.demofile); cls.demofile = NULL; cls.state = ca_disconnected; cls.demoplayback = DPB_NONE; @@ -84,10 +87,10 @@ void CL_WriteDemoCmd (usercmd_t *pcmd) //Con_Printf("write: %ld bytes, %4.4f\n", msg->cursize, realtime); fl = LittleFloat((float)realtime); - fwrite (&fl, sizeof(fl), 1, cls.demofile); + VFS_WRITE (cls.demofile, &fl, sizeof(fl)); c = dem_cmd; - fwrite (&c, sizeof(c), 1, cls.demofile); + VFS_WRITE (cls.demofile, &c, sizeof(c)); // correct for byte order, bytes don't matter @@ -102,15 +105,15 @@ void CL_WriteDemoCmd (usercmd_t *pcmd) cmd.sidemove = LittleShort(pcmd->sidemove); cmd.upmove = LittleShort(pcmd->upmove); - fwrite(&cmd, sizeof(cmd), 1, cls.demofile); + VFS_WRITE (cls.demofile, &cmd, sizeof(cmd)); for (i=0 ; i<3 ; i++) { fl = LittleFloat (cl.viewangles[0][i]); - fwrite (&fl, 4, 1, cls.demofile); + VFS_WRITE (cls.demofile, &fl, 4); } - fflush (cls.demofile); + VFS_FLUSH (cls.demofile); } /* @@ -132,16 +135,16 @@ void CL_WriteDemoMessage (sizebuf_t *msg) return; fl = LittleFloat((float)realtime); - fwrite (&fl, sizeof(fl), 1, cls.demofile); + VFS_WRITE (cls.demofile, &fl, sizeof(fl)); c = dem_read; - fwrite (&c, sizeof(c), 1, cls.demofile); + VFS_WRITE (cls.demofile, &c, sizeof(c)); len = LittleLong (msg->cursize); - fwrite (&len, 4, 1, cls.demofile); - fwrite (msg->data, msg->cursize, 1, cls.demofile); + VFS_WRITE (cls.demofile, &len, 4); + VFS_WRITE (cls.demofile, msg->data, msg->cursize); - fflush (cls.demofile); + VFS_FLUSH (cls.demofile); } int unreaddata; @@ -160,13 +163,71 @@ int readdemobytes(void *data, int len) return len; } - i = fread(data, 1, len, cls.demofile); + i = VFS_READ(cls.demofile, data, len); memcpy(&unreaddata, data, 4); return i; } +void CL_ProgressDemoTime(void) +{ + extern cvar_t cl_demospeed; + + if (cl.parsecount && Media_PausedDemo()) + { //console visible whilst democapturing +#undef realtime + cls.netchan.last_received = realtime; +#define realtime demtime + return; + } + if (cl_demospeed.value>0) + realtime += host_frametime*cl_demospeed.value; + else + realtime += host_frametime; +} + +void CL_DemoJump_f(void) +{ + float newtime; + char *s = Cmd_Argv(1); + char *colon = strchr(s, ':'); + + if (*s == '+') + { + if (colon) + { + colon++; + realtime += atoi(colon); + + realtime += atoi(s)*60; + } + else + realtime += atoi(s); + } + else + { + if (colon) + { + colon++; + newtime = atoi(colon); + newtime += atoi(s)*60; + } + else + newtime = atoi(s); + + if (newtime >= realtime) + realtime = newtime; + else + { + Con_Printf("Rewinding demo\n"); + CL_PlayDemo(lastdemoname); + + realtime = newtime; + } + } +} + /* ==================== CL_GetDemoMessage @@ -186,8 +247,6 @@ qboolean CL_GetDemoMessage (void) usercmd_t *pcmd; q1usercmd_t q1cmd; - realtime += host_frametime *0.1; - #ifdef NQPROT if (cls.demoplayback == DPB_NETQUAKE || cls.demoplayback == DPB_QUAKE2) { //read the nq demo @@ -353,7 +412,7 @@ readnext: Host_Error ("CL_GetDemoMessage: cls.state != ca_active"); // get the msg type - fread (&c, sizeof(c), 1, cls.demofile); + VFS_READ (cls.demofile, &c, sizeof(c)); switch (c&7) { @@ -513,7 +572,7 @@ void CL_Stop_f (void) CL_WriteDemoMessage (&net_message); // finish up - fclose (cls.demofile); + VFS_CLOSE (cls.demofile); cls.demofile = NULL; cls.demorecording = false; Con_Printf ("Completed demo\n"); @@ -540,21 +599,21 @@ void CL_WriteRecordDemoMessage (sizebuf_t *msg, int seq) return; fl = LittleFloat((float)realtime); - fwrite (&fl, sizeof(fl), 1, cls.demofile); + VFS_WRITE (cls.demofile, &fl, sizeof(fl)); c = dem_read; - fwrite (&c, sizeof(c), 1, cls.demofile); + VFS_WRITE (cls.demofile, &c, sizeof(c)); len = LittleLong (msg->cursize + 8); - fwrite (&len, 4, 1, cls.demofile); + VFS_WRITE (cls.demofile, &len, 4); i = LittleLong(seq); - fwrite (&i, 4, 1, cls.demofile); - fwrite (&i, 4, 1, cls.demofile); + VFS_WRITE (cls.demofile, &i, 4); + VFS_WRITE (cls.demofile, &i, 4); - fwrite (msg->data, msg->cursize, 1, cls.demofile); + VFS_WRITE (cls.demofile, msg->data, msg->cursize); - fflush (cls.demofile); + VFS_FLUSH (cls.demofile); } @@ -570,17 +629,17 @@ void CL_WriteSetDemoMessage (void) return; fl = LittleFloat((float)realtime); - fwrite (&fl, sizeof(fl), 1, cls.demofile); + VFS_WRITE (cls.demofile, &fl, sizeof(fl)); c = dem_set; - fwrite (&c, sizeof(c), 1, cls.demofile); + VFS_WRITE (cls.demofile, &c, sizeof(c)); len = LittleLong(cls.netchan.outgoing_sequence); - fwrite (&len, 4, 1, cls.demofile); + VFS_WRITE (cls.demofile, &len, 4); len = LittleLong(cls.netchan.incoming_sequence); - fwrite (&len, 4, 1, cls.demofile); + VFS_WRITE (cls.demofile, &len, 4); - fflush (cls.demofile); + VFS_FLUSH (cls.demofile); } @@ -720,7 +779,7 @@ void CL_Record_f (void) // // open the demo file // - cls.demofile = fopen (name, "wb"); + cls.demofile = FS_OpenVFS (name, "wb", FS_GAME); if (!cls.demofile) { Con_Printf ("ERROR: couldn't open.\n"); @@ -1039,7 +1098,7 @@ void CL_ReRecord_f (void) // COM_DefaultExtension (name, ".qwd"); - cls.demofile = fopen (name, "wb"); + cls.demofile = FS_OpenVFS (name, "wb", FS_GAME); if (!cls.demofile) { Con_Printf ("ERROR: couldn't open.\n"); @@ -1072,13 +1131,6 @@ play [demoname] */ void CL_PlayDemo_f (void) { - char name[256]; - int ft, c, neg; - int len; - char type; - int protocol; - int start; - if (Cmd_Argc() != 2) { Con_Printf ("playdemo : plays a demo\n"); @@ -1094,6 +1146,18 @@ void CL_PlayDemo_f (void) } #endif + CL_PlayDemo(Cmd_Argv(1)); +} + +void CL_PlayDemo(char *demoname) +{ + char name[256]; + int ft, c, neg; + int len; + char type; + int protocol; + int start; + // // disconnect from server // @@ -1103,20 +1167,20 @@ void CL_PlayDemo_f (void) // // open the demo file // - strcpy (name, Cmd_Argv(1)); + Q_strncpyz (name, demoname, sizeof(name)); COM_DefaultExtension (name, ".qwd"); - COM_FOpenFile (name, &cls.demofile); + cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); if (!cls.demofile) { - strcpy (name, Cmd_Argv(1)); + Q_strncpyz (name, demoname, sizeof(name)); COM_DefaultExtension (name, ".dem"); - COM_FOpenFile (name, &cls.demofile); + cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); } if (!cls.demofile) { - strcpy (name, Cmd_Argv(1)); + Q_strncpyz (name, demoname, sizeof(name)); COM_DefaultExtension (name, ".mvd"); - COM_FOpenFile (name, &cls.demofile); + cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); } if (!cls.demofile) { @@ -1124,6 +1188,7 @@ void CL_PlayDemo_f (void) cls.demonum = -1; // stop demo loop return; } + Q_strncpyz (lastdemoname, demoname, sizeof(lastdemoname)); Con_Printf ("Playing demo from %s.\n", name); if (!Q_strcasecmp(name + strlen(name) - 3, "mvd")) @@ -1133,6 +1198,7 @@ void CL_PlayDemo_f (void) } else cls.demoplayback = DPB_QUAKEWORLD; + cls.state = ca_demostart; net_message.packing = SZ_RAWBYTES; Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, 0); @@ -1143,11 +1209,11 @@ void CL_PlayDemo_f (void) cls.netchan.last_received=0; - start = ftell(cls.demofile); - fread(&len, sizeof(len), 1, cls.demofile); - fread(&type, sizeof(type), 1, cls.demofile); - fread(&protocol, sizeof(protocol), 1, cls.demofile); - fseek(cls.demofile, start, SEEK_SET); + start = VFS_TELL(cls.demofile); + VFS_READ(cls.demofile, &len, sizeof(len)); + VFS_READ(cls.demofile, &type, sizeof(type)); + VFS_READ(cls.demofile, &protocol, sizeof(protocol)); + VFS_SEEK(cls.demofile, start); if (len > 5 && type == svcq2_serverdata && protocol == PROTOCOL_VERSION_Q2) { #ifdef Q2CLIENT @@ -1164,7 +1230,7 @@ void CL_PlayDemo_f (void) cls.protocol = CP_QUAKEWORLD; ft = 0; //work out if the first line is a int for the track number. - while ((c = getc(cls.demofile)) != '\n') + while ((VFS_READ(cls.demofile, &c, 1)==1) && (c != '\n')) { if (c == '-') neg = true; @@ -1185,7 +1251,7 @@ void CL_PlayDemo_f (void) #endif } else - fseek(cls.demofile, start, SEEK_SET); //quakeworld demo, so go back to start. + VFS_SEEK(cls.demofile, start); //quakeworld demo, so go back to start. } } diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 06930e16d..1f3d72373 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -3341,6 +3341,7 @@ void MVD_Interpolate(void) entity_state_t *oldents; struct predicted_player *pplayer; static float old; + extern float demtime; self = &cl.frames[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[0]]; oldself = &cl.frames[(cls.netchan.outgoing_sequence - 1) & UPDATE_MASK].playerstate[cl.playernum[0]]; @@ -3371,7 +3372,7 @@ void MVD_Interpolate(void) oldframe = &cl.frames[cl.oldparsecount & UPDATE_MASK]; oldents = oldframe->packet_entities.entities; - f = (realtime - olddemotime) / (nextdemotime - olddemotime); + f = (demtime - olddemotime) / (nextdemotime - olddemotime); if (f < 0) f = 0; if (f > 1) diff --git a/engine/client/cl_ignore.c b/engine/client/cl_ignore.c index 771020da3..7bba50404 100644 --- a/engine/client/cl_ignore.c +++ b/engine/client/cl_ignore.c @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "cl_ignore.h" +#include + #define MAX_TEAMIGNORELIST 4 #define FLOODLIST_SIZE 10 diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 3736ff79e..520ac1f16 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -813,7 +813,7 @@ float CL_FilterTime (double time, float wantfps) //now returns the extra time no if (cls.timedemo || cls.protocol == CP_QUAKE3) return -1; - if (cls.demoplayback != DPB_NONE) + if (cls.demoplayback != DPB_NONE || cls.protocol != CP_QUAKEWORLD) { if (!wantfps) return -1; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index e35fc3687..7d8d5167a 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -56,7 +56,7 @@ cvar_t cl_splitscreen = {"cl_splitscreen", "0"}; cvar_t lookspring = {"lookspring","0", NULL, CVAR_ARCHIVE}; cvar_t lookstrafe = {"lookstrafe","0", NULL, CVAR_ARCHIVE}; -cvar_t sensitivity = {"sensitivity","3", NULL, CVAR_ARCHIVE}; +cvar_t sensitivity = {"sensitivity","10", NULL, CVAR_ARCHIVE}; cvar_t cl_staticsounds = {"cl_staticsounds", "1"}; @@ -1545,10 +1545,10 @@ void CL_SetInfo_f (void) } } -void CL_SaveInfo(FILE *f) +void CL_SaveInfo(vfsfile_t *f) { - fwrite("\n", 1, 1, f); - fwrite("setinfo * \"\"\n", 13, 1, f); + VFS_WRITE(f, "\n", 1); + VFS_WRITE(f, "setinfo * \"\"\n", 13); Info_WriteToFile(f, cls.userinfo, "setinfo", CVAR_USERINFO); } @@ -2309,7 +2309,10 @@ void CL_ReadPackets (void) #endif case CP_QUAKEWORLD: if (cls.demoplayback == DPB_MVD) + { MSG_BeginReading(); + cls.netchan.last_received = realtime; + } else if (!Netchan_Process(&cls.netchan)) continue; // wasn't accepted for some reason CL_ParseServerMessage (); @@ -2629,6 +2632,7 @@ void CL_Init (void) Cmd_AddCommand ("rerecord", CL_ReRecord_f); Cmd_AddCommand ("stop", CL_Stop_f); Cmd_AddCommand ("playdemo", CL_PlayDemo_f); + Cmd_AddCommand ("demo_jump", CL_DemoJump_f); Cmd_AddCommand ("timedemo", CL_TimeDemo_f); Cmd_AddCommand ("showpic", SCR_ShowPic_Script_f); @@ -2775,7 +2779,7 @@ Writes key bindings and archived cvars to config.cfg */ void Host_WriteConfiguration (void) { - FILE *f; + vfsfile_t *f; if (host_initialized && cfg_save_name.string && *cfg_save_name.string) { @@ -2785,7 +2789,7 @@ void Host_WriteConfiguration (void) return; } - f = fopen (va("%s/%s.cfg",com_gamedir, cfg_save_name.string), "w"); + f = FS_OpenVFS(va("%s.cfg",cfg_save_name.string), "w", FS_GAMEONLY); if (!f) { Con_TPrintf (TLC_CONFIGCFG_WRITEFAILED); @@ -2795,7 +2799,7 @@ void Host_WriteConfiguration (void) Key_WriteBindings (f); Cvar_WriteVariables (f, false); - fclose (f); + VFS_CLOSE (f); } } @@ -2868,8 +2872,8 @@ void Host_Frame (double time) } #endif - if (cls.demoplayback && cl_demospeed.value>0) - realframetime *= cl_demospeed.value; // this probably screws up other timings +// if (cls.demoplayback && cl_demospeed.value>0) +// realframetime *= cl_demospeed.value; // this probably screws up other timings #ifndef CLIENTONLY RSpeedRemark(); @@ -2901,7 +2905,6 @@ void Host_Frame (double time) cl.gametimemark += time; - #ifdef VOICECHAT CLVC_Poll(); #endif @@ -2925,7 +2928,7 @@ void Host_Frame (double time) else { realtime += spare/1000; //don't use it all! - spare = CL_FilterTime((realtime - oldrealtime)*1000, cl_maxfps.value>0?cl_maxfps.value:cl_netfps.value); + spare = CL_FilterTime((realtime - oldrealtime)*1000, (cl_maxfps.value>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:cl_netfps.value); if (!spare) return; if (spare < 0 || cls.state < ca_onserver) @@ -2939,6 +2942,8 @@ void Host_Frame (double time) host_frametime = (realtime - oldrealtime)*cl.gamespeed; oldrealtime = realtime; + CL_ProgressDemoTime(); + #if defined(Q2CLIENT) if (cls.protocol == CP_QUAKE2) diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 30d85bb24..a9d014e5b 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -545,7 +545,7 @@ static void CL_LerpMove (int pnum, float msgtime) int i; int from, to; - if (cl_nolerp.value) + if (cl_nolerp.value || cls.demoplayback == DPB_MVD) return; if (cls.netchan.outgoing_sequence < lastsequence) { @@ -757,7 +757,7 @@ void CL_PredictMovePNum (int pnum) vel = vec3_origin; goto fixedorg; } - Con_Printf("Not lerped\n"); + /* entity_state_t *CL_FindOldPacketEntity(int num); entity_state_t *CL_FindPacketEntity(int num); entity_state_t *state; @@ -814,7 +814,7 @@ fixedorg: to = &cl.frames[cl.validsequence & UPDATE_MASK]; - if (Cam_TrackNum(pnum)>=0 && !cl_nolerp.value) + if (Cam_TrackNum(pnum)>=0 && !cl_nolerp.value && cls.demoplayback != DPB_MVD) { float f; diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 83eae2496..bcc82c281 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1556,6 +1556,7 @@ void SCR_ScreenShot_f (void) char pcxname[80]; char checkname[MAX_OSPATH]; int i; + vfsfile_t *vfs; if (!VID_GetRGBInfo) { @@ -1587,8 +1588,9 @@ void SCR_ScreenShot_f (void) pcxname[18] = (i%100)/10 + '0'; pcxname[19] = (i%10) + '0'; sprintf (checkname, "%s/%s", com_gamedir, pcxname); - if (Sys_FileTime(checkname) == -1) + if (!(vfs = FS_OpenVFS(pcxname, "r", FS_GAMEONLY))) break; // file doesn't exist + VFS_CLOSE(vfs); } if (i==100000) { diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 1b0c03034..10b821404 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -462,9 +462,9 @@ int VMQ3_GetFileList(char *path, char *ext, char *output, int buffersize) vms.found=0; if (*(char *)path == '$') { - extern char *com_basedir; vms.skip=0; - Sys_EnumerateFiles(com_basedir, "*", VMEnumMods, &vms); + Sys_EnumerateFiles(com_quakedir, "*", VMEnumMods, &vms); + Sys_EnumerateFiles(com_homedir, "*", VMEnumMods, &vms); } else if (*(char *)ext == '.' || *(char *)ext == '/') COM_EnumerateFiles(va("%s/*%s", path, ext), VMEnum, &vms); @@ -707,7 +707,7 @@ void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font) _snprintf(name, sizeof(name), "fonts/fontImage_%i.dat",pointSize); - in.i = COM_LoadTempFile(name); + in.c = COM_LoadTempFile(name); if (com_filesize == sizeof(fontInfo_t)) { for(i=0; i sizeof(compressed) || size < 1) Host_Error ("Bad compressed frame size"); - fread (compressed, 1, size, cin.cinematic_file); + VFS_READ (cin.cinematic_file, compressed, size); // read sound start = cin.cinematicframe*cin.s_rate/14; end = (cin.cinematicframe+1)*cin.s_rate/14; count = end - start; - fread (samples, 1, count*cin.s_width*cin.s_channels, cin.cinematic_file); + VFS_READ (cin.cinematic_file, samples, count*cin.s_width*cin.s_channels); S_RawAudio (0, samples, cin.s_rate, count, cin.s_channels, cin.s_width); @@ -485,11 +485,11 @@ qboolean CIN_PlayCinematic (char *arg) cin.cinematicframe = 0; - COM_FOpenFile (arg, &cin.cinematic_file); + cin.cinematic_file = FS_OpenVFS(arg, "rb", FS_GAME); if (!cin.cinematic_file) { _snprintf (name, sizeof(name), "video/%s", arg); - COM_FOpenFile (name, &cin.cinematic_file); + cin.cinematic_file = FS_OpenVFS(name, "rb", FS_GAME); } if (!cin.cinematic_file) { @@ -501,16 +501,16 @@ qboolean CIN_PlayCinematic (char *arg) SCR_EndLoadingPlaque (); - fread (&width, 1, 4, cin.cinematic_file); - fread (&height, 1, 4, cin.cinematic_file); + VFS_READ (cin.cinematic_file, &width, 4); + VFS_READ (cin.cinematic_file, &height, 4); cin.width = LittleLong(width); cin.height = LittleLong(height); - fread (&cin.s_rate, 1, 4, cin.cinematic_file); + VFS_READ (cin.cinematic_file, &cin.s_rate, 4); cin.s_rate = LittleLong(cin.s_rate); - fread (&cin.s_width, 1, 4, cin.cinematic_file); + VFS_READ (cin.cinematic_file, &cin.s_width, 4); cin.s_width = LittleLong(cin.s_width); - fread (&cin.s_channels, 1, 4, cin.cinematic_file); + VFS_READ (cin.cinematic_file, &cin.s_channels, 4); cin.s_channels = LittleLong(cin.s_channels); Huff1TableInit (); diff --git a/engine/client/image.c b/engine/client/image.c index 12e462193..33bd34b0e 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -964,38 +964,98 @@ qbyte *ReadJPEGFile(qbyte *infile, int length, int *width, int *height) } - +#define OUTPUT_BUF_SIZE 4096 typedef struct { struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; } jpeg_error_mgr_wrapper; +typedef struct { + struct jpeg_destination_mgr pub; + + vfsfile_t *vfs; + + + JOCTET buffer[OUTPUT_BUF_SIZE]; /* start of buffer */ +} my_destination_mgr; + +METHODDEF(void) init_destination (j_compress_ptr cinfo) +{ + my_destination_mgr *dest = (my_destination_mgr*) cinfo->dest; + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} +METHODDEF(boolean) empty_output_buffer (j_compress_ptr cinfo) +{ + my_destination_mgr *dest = (my_destination_mgr*) cinfo->dest; + + VFS_WRITE(dest->vfs, dest->buffer, OUTPUT_BUF_SIZE); + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} +METHODDEF(void) term_destination (j_compress_ptr cinfo) +{ + my_destination_mgr *dest = (my_destination_mgr*) cinfo->dest; + + VFS_WRITE(dest->vfs, dest->buffer, OUTPUT_BUF_SIZE - dest->pub.free_in_buffer); + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + +void jpeg_mem_dest (j_compress_ptr cinfo, vfsfile_t *vfs) +{ + my_destination_mgr *dest; + + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_destination_mgr)); + dest = (my_destination_mgr*) cinfo->dest; +// dest->buffer = (JOCTET *) +// (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, +// OUTPUT_BUF_SIZE * sizeof(JOCTET)); + } + + dest = (my_destination_mgr*) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->pub.free_in_buffer = 0; /* forces fill_input_buffer on first read */ + dest->pub.next_output_byte = NULL; /* until buffer loaded */ + dest->vfs = vfs; +} + + + METHODDEF(void) jpeg_error_exit (j_common_ptr cinfo) { longjmp(((jpeg_error_mgr_wrapper *) cinfo->err)->setjmp_buffer, 1); } -extern char *com_basedir; void screenshotJPEG(char *filename, qbyte *screendata, int screenwidth, int screenheight) //input is rgb NOT rgba { - char name[MAX_OSPATH]; qbyte *buffer; - FILE *outfile; + vfsfile_t *outfile; jpeg_error_mgr_wrapper jerr; struct jpeg_compress_struct cinfo; JSAMPROW row_pointer[1]; - sprintf (name, "%s/%s", com_gamedir, filename); - if (!(outfile = fopen (name, "wb"))) { - COM_CreatePath (name); - if (!(outfile = fopen (name, "wb"))) + if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY))) + { + FS_CreatePath (filename, FS_GAME); + if (!(outfile = FS_OpenVFS(filename, "w", FS_GAMEONLY))) Sys_Error ("Error opening %s", filename); } cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpeg_error_exit; - if (setjmp(jerr.setjmp_buffer)) { + if (setjmp(jerr.setjmp_buffer)) + { jpeg_destroy_compress(&cinfo); - fclose(outfile); - unlink(name); + VFS_CLOSE(outfile); + FS_Remove(filename, FS_GAME); Con_Printf("Failed to create jpeg\n"); return; } @@ -1003,7 +1063,7 @@ void screenshotJPEG(char *filename, qbyte *screendata, int screenwidth, int scre buffer = screendata; - jpeg_stdio_dest(&cinfo, outfile); + jpeg_mem_dest(&cinfo, outfile); cinfo.image_width = screenwidth; cinfo.image_height = screenheight; cinfo.input_components = 3; @@ -1012,13 +1072,14 @@ void screenshotJPEG(char *filename, qbyte *screendata, int screenwidth, int scre jpeg_set_quality (&cinfo, 75/*bound(0, (int) gl_image_jpeg_quality_level.value, 100)*/, true); jpeg_start_compress(&cinfo, true); - while (cinfo.next_scanline < cinfo.image_height) { + while (cinfo.next_scanline < cinfo.image_height) + { *row_pointer = &buffer[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); - fclose(outfile); + VFS_CLOSE(outfile); jpeg_destroy_compress(&cinfo); } diff --git a/engine/client/keys.c b/engine/client/keys.c index 5e150de67..e2f9960a5 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -967,8 +967,9 @@ Key_WriteBindings Writes lines containing "bind key value" ============ */ -void Key_WriteBindings (FILE *f) +void Key_WriteBindings (vfsfile_t *f) { + char *s; int i, m; char *binding, *base; @@ -997,21 +998,22 @@ void Key_WriteBindings (FILE *f) if (bindcmdlevel[i][m] != bindcmdlevel[i][0]) { if (i == ';') - fprintf (f, "bindlevel \"%s%s\" %i \"%s\"\n", prefix, Key_KeynumToString(i), bindcmdlevel[i][m], keybindings[i][m]); + s = va("bindlevel \"%s%s\" %i \"%s\"\n", prefix, Key_KeynumToString(i), bindcmdlevel[i][m], keybindings[i][m]); else if (i == '\"') - fprintf (f, "bindlevel \"%s%s\" %i \"%s\"\n", prefix, "\"\"", bindcmdlevel[i][m], keybindings[i][m]); + s = va("bindlevel \"%s%s\" %i \"%s\"\n", prefix, "\"\"", bindcmdlevel[i][m], keybindings[i][m]); else - fprintf (f, "bindlevel %s%s %i \"%s\"\n", prefix, Key_KeynumToString(i), bindcmdlevel[i][m], keybindings[i][m]); + s = va("bindlevel %s%s %i \"%s\"\n", prefix, Key_KeynumToString(i), bindcmdlevel[i][m], keybindings[i][m]); } else { if (i == ';') - fprintf (f, "bind \"%s%s\" \"%s\"\n", prefix, Key_KeynumToString(i), keybindings[i][m]); + s = va("bind \"%s%s\" \"%s\"\n", prefix, Key_KeynumToString(i), keybindings[i][m]); else if (i == '\"') - fprintf (f, "bind \"%s%s\" \"%s\"\n", prefix, "\"\"", keybindings[i][m]); + s = va("bind \"%s%s\" \"%s\"\n", prefix, "\"\"", keybindings[i][m]); else - fprintf (f, "bind %s%s \"%s\"\n", prefix, Key_KeynumToString(i), keybindings[i][m]); + s = va("bind %s%s \"%s\"\n", prefix, Key_KeynumToString(i), keybindings[i][m]); } + VFS_WRITE(f, s, strlen(s)); } } } diff --git a/engine/client/keys.h b/engine/client/keys.h index 38e360990..ec3fd18e2 100644 --- a/engine/client/keys.h +++ b/engine/client/keys.h @@ -170,7 +170,7 @@ extern qboolean chat_team; void Key_Event (int key, qboolean down); void Key_Init (void); -void Key_WriteBindings (FILE *f); +void Key_WriteBindings (vfsfile_t *f); void Key_SetBinding (int keynum, int modifier, char *binding, int cmdlevel); void Key_ClearStates (void); diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 67746c5b2..c6cbd0256 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -964,6 +964,7 @@ qboolean Media_PlayFilm(char *name) media_filmtype = MFT_CIN; return true; } + if ((roqfilm = roq_open(name))) { Con_ClearNotify(); @@ -1318,6 +1319,17 @@ enum { CT_SCREENSHOT } capturetype; char capturefilenameprefix[MAX_QPATH]; + +qboolean Media_PausedDemo (void) +{ + //capturedemo doesn't record any frames when the console is visible + //but that's okay, as we don't load any demo frames either. + if (recordingdemo) + if (scr_con_current > 0 || !cl.validsequence) + return true; + + return false; +} void Media_RecordFrame (void) { HRESULT hr; @@ -1328,13 +1340,11 @@ void Media_RecordFrame (void) if (!capturetype) return; - if (recordingdemo) - if (scr_con_current > 0 || !cl.validsequence) - { - scr_con_current=0; - key_dest = key_game; - return; - } + if (Media_PausedDemo()) + return; + + if (cls.findtrack) + return; //skip until we're tracking the right player. //overlay this on the screen, so it appears in the film if (*capturemessage.string) @@ -1660,6 +1670,7 @@ void Media_RecordDemo_f(void) void Media_CaptureDemoEnd(void){} void Media_RecordAudioFrame (short *sample_buffer, int samples){} void Media_RecordFrame (void) {} +void Media_PausedDemo (void) {return false;} #endif void Media_Init(void) { @@ -1708,6 +1719,7 @@ void Media_StopRecordFilm_f (void) {} void Media_RecordFilm_f (void){} void M_Menu_Media_f (void) {} char *Media_NextTrack(void) {return NULL;} +qboolean Media_PausedDemo(void) {return false;} int filmtexture; media_filmtype_t media_filmtype; diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 1fd66889c..b937f9ce6 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -547,7 +547,7 @@ void Master_AddMasterHTTP (char *address, int servertype, char *description) qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth) { extern char *com_basedir; - FILE *f; + vfsfile_t *f; char line[1024]; char file[1024]; char *name, *next; @@ -557,11 +557,11 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth) return false; depth--; - f = fopen(va("%s/%s", com_basedir, filename), "rb"); + f = NULL;//FS_OpenVFS(filename, "rb", FS_BASE); if (!f) return false; - while(fgets(line, sizeof(line)-1, f)) + while(VFS_GETS(f, line, sizeof(line)-1)) { if (*line == '#') //comment continue; @@ -663,7 +663,7 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth) else Master_AddMaster(line, servertype, name); } - fclose(f); + VFS_CLOSE(f); return true; } @@ -1184,7 +1184,7 @@ void MasterInfo_Begin(void) Master_AddMaster("master.edome.net", MT_MASTERQW, "edome master server."); Master_AddMaster("qwmaster.barrysworld.com", MT_MASTERQW, "barrysworld master server."); - Master_AddMaster("qwmaster.ocrana.de", MT_MASTERQW, "Ocrana2 master server."); + Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server."); Master_AddMaster("213.221.174.165:27000", MT_MASTERQW, "unknown1 master server."); Master_AddMaster("195.74.0.8", MT_MASTERQW, "unknown2 master server."); Master_AddMaster("192.246.40.37", MT_MASTERQW, "unknown3 master server."); diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 894d1d234..b0b90e03c 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -1073,7 +1073,7 @@ void P_SelectableTrail(model_t *model, cvar_t *selection, int mdleffect, int mdl model->particletrail = P_AllocateParticleType("t_zomgib"); model->traildefaultindex = 70; break; - case 6: // Scrag tracer + case 6: // Scrag tracer model->particletrail = P_AllocateParticleType("t_tracer"); model->traildefaultindex = 60; break; @@ -1559,16 +1559,18 @@ void P_NewServer(void) void P_ReadPointFile_f (void) { - FILE *f; + vfsfile_t *f; vec3_t org; int r; int c; char name[MAX_OSPATH]; + char line[1024]; + char *s; COM_StripExtension(cl.worldmodel->name, name); strcat(name, ".pts"); - COM_FOpenFile (name, &f); + f = FS_OpenVFS(name, "rb", FS_GAME); if (!f) { Con_Printf ("couldn't open %s\n", name); @@ -1581,9 +1583,23 @@ void P_ReadPointFile_f (void) c = 0; for ( ;; ) { - r = fscanf (f,"%f %f %f\n", &org[0], &org[1], &org[2]); - if (r != 3) - break; + VFS_GETS(f, line, sizeof(line)); + + s = COM_Parse(line); + org[0] = atof(com_token); + + s = COM_Parse(s); + if (!s) + continue; + org[1] = atof(com_token); + + s = COM_Parse(s); + if (!s) + continue; + org[2] = atof(com_token); + if (COM_Parse(s)) + continue; + c++; if (c%8) @@ -1597,7 +1613,7 @@ void P_ReadPointFile_f (void) P_RunParticleEffectType(org, NULL, 1, pt_pointfile); } - fclose (f); + VFS_CLOSE (f); Con_Printf ("%i points read\n", c); } @@ -2880,7 +2896,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype else VectorCopy(ptype->rgb, p->rgb); - + // use org temporarily for rgbsync p->org[2] = frandom(); diff --git a/engine/client/roq.h b/engine/client/roq.h index 8bc813aa2..b3d8f8c31 100644 --- a/engine/client/roq.h +++ b/engine/client/roq.h @@ -21,7 +21,7 @@ typedef struct { } roq_qcell; typedef struct { - FILE *fp; + vfsfile_t *fp; unsigned int maxpos; //addition for pack files. all seeks add this, all tells subtract this. int buf_size; unsigned char *buf; diff --git a/engine/client/roq_read.c b/engine/client/roq_read.c index 4c54c5cb3..884071b16 100644 --- a/engine/client/roq_read.c +++ b/engine/client/roq_read.c @@ -24,6 +24,14 @@ #ifndef NOMEDIA + +static int VFS_GETC(vfsfile_t *fp) +{ + unsigned char c; + VFS_READ(fp, &c, 1); + return c; +} + //#include //#include //#include @@ -34,31 +42,31 @@ #define FAST /* -------------------------------------------------------------------------- */ -static unsigned int get_word(FILE *fp) +static unsigned int get_word(vfsfile_t *fp) { unsigned int ret; - ret = ((fgetc(fp)) & 0xff); - ret |= ((fgetc(fp)) & 0xff) << 8; + ret = ((VFS_GETC(fp)) & 0xff); + ret |= ((VFS_GETC(fp)) & 0xff) << 8; return(ret); } /* -------------------------------------------------------------------------- */ -static unsigned long get_long(FILE *fp) +static unsigned long get_long(vfsfile_t *fp) { unsigned long ret; - ret = ((fgetc(fp)) & 0xff); - ret |= ((fgetc(fp)) & 0xff) << 8; - ret |= ((fgetc(fp)) & 0xff) << 16; - ret |= ((fgetc(fp)) & 0xff) << 24; + ret = ((VFS_GETC(fp)) & 0xff); + ret |= ((VFS_GETC(fp)) & 0xff) << 8; + ret |= ((VFS_GETC(fp)) & 0xff) << 16; + ret |= ((VFS_GETC(fp)) & 0xff) << 24; return(ret); } /* -------------------------------------------------------------------------- */ -static int roq_parse_file(FILE *fp, roq_info *ri) +static int roq_parse_file(vfsfile_t *fp, roq_info *ri) { unsigned int head1, head3, chunk_id, chunk_arg; long head2, chunk_size; @@ -67,7 +75,7 @@ long fpos; int max_frame; #endif -#define rfeof(f) (ftell(f)>= ri->maxpos) +#define rfeof(f) (VFS_TELL(f)>= ri->maxpos) #ifndef FAST ri->num_audio_bytes = ri->num_frames = max_frame = 0; @@ -79,32 +87,34 @@ int max_frame; head2 = get_long(fp); head3 = get_word(fp); if(head1 != 0x1084 && head2 != 0xffffffff && head3 != 0x1e) - { + { Con_Printf("Not an RoQ file.\n"); return 1; - } + } - ri->roq_start = ftell(fp); + ri->roq_start = VFS_TELL(fp); while(!rfeof(fp)) - { + { #if DBUG > 20 Con_Printf("---------------------------------------------------------------------------\n"); #endif - fpos = ftell(fp); + fpos = VFS_TELL(fp); chunk_id = get_word(fp); chunk_size = get_long(fp); chunk_arg = get_word(fp); if (chunk_size == -1) //FIXME: THIS SHOULD NOT HAPPEN break; - if(chunk_size > ri->buf_size) ri->buf_size = chunk_size; - if(rfeof(fp)) break; + if(chunk_size > ri->buf_size) + ri->buf_size = chunk_size; + if(rfeof(fp)) + break; #if DBUG > 20 Con_Printf("%03d 0x%06lx: chunk: 0x%02x size: %ld cells: 2x2=%d,4x4=%d\n", i, fpos, chunk_id, chunk_size, v1>>8,v1&0xff); #endif if(chunk_id == RoQ_INFO) /* video info */ - { + { ri->width = get_word(fp); ri->height = get_word(fp); get_word(fp); @@ -112,32 +122,35 @@ int max_frame; #ifdef FAST return 0; //we have all the data we need now. We always find a sound chunk first, or none at all. #endif - } + } else - { + { #ifndef FAST if(chunk_id == RoQ_QUAD_VQ) - { + { ri->num_frames++; if(ri->num_frames > max_frame) - { + { max_frame += 5000; - if((ri->frame_offset = BZ_Realloc(ri->frame_offset, sizeof(long) * max_frame)) == NULL) return 1; - } - ri->frame_offset[ri->num_frames] = fpos; + if((ri->frame_offset = BZ_Realloc(ri->frame_offset, sizeof(long) * max_frame)) == NULL) + return 1; } + ri->frame_offset[ri->num_frames] = fpos; + } #endif if(chunk_id == RoQ_SOUND_MONO || chunk_id == RoQ_SOUND_STEREO) - { - if(chunk_id == RoQ_SOUND_MONO) ri->audio_channels = 1; - else ri->audio_channels = 2; + { + if(chunk_id == RoQ_SOUND_MONO) + ri->audio_channels = 1; + else + ri->audio_channels = 2; #ifndef FAST ri->num_audio_bytes += chunk_size; #endif - } - fseek(fp, chunk_size, SEEK_CUR); } + VFS_SEEK(fp, VFS_TELL(fp) + chunk_size); } + } return 0; } @@ -211,34 +224,34 @@ unsigned char *pa, *pb; pa = ri->y[0] + (y * ri->width) + x; pb = ri->y[1] + (my * ri->width) + mx; for(i = 0; i < 4; i++) - { + { pa[0] = pb[0]; pa[1] = pb[1]; pa[2] = pb[2]; pa[3] = pb[3]; pa += ri->width; pb += ri->width; - } + } pa = ri->u[0] + (y/2) * (ri->width/2) + x/2; pb = ri->u[1] + (my/2) * (ri->width/2) + (mx + 1)/2; for(i = 0; i < 2; i++) - { + { pa[0] = pb[0]; pa[1] = pb[1]; pa += ri->width/2; pb += ri->width/2; - } + } pa = ri->v[0] + (y/2) * (ri->width/2) + x/2; pb = ri->v[1] + (my/2) * (ri->width/2) + (mx + 1)/2; for(i = 0; i < 2; i++) - { + { pa[0] = pb[0]; pa[1] = pb[1]; pa += ri->width/2; pb += ri->width/2; - } + } } @@ -254,7 +267,7 @@ unsigned char *pa, *pb; pa = ri->y[0] + (y * ri->width) + x; pb = ri->y[1] + (my * ri->width) + mx; for(i = 0; i < 8; i++) - { + { pa[0] = pb[0]; pa[1] = pb[1]; pa[2] = pb[2]; @@ -265,86 +278,88 @@ unsigned char *pa, *pb; pa[7] = pb[7]; pa += ri->width; pb += ri->width; - } + } pa = ri->u[0] + (y/2) * (ri->width/2) + x/2; pb = ri->u[1] + (my/2) * (ri->width/2) + (mx + 1)/2; for(i = 0; i < 4; i++) - { + { pa[0] = pb[0]; pa[1] = pb[1]; pa[2] = pb[2]; pa[3] = pb[3]; pa += ri->width/2; pb += ri->width/2; - } + } pa = ri->v[0] + (y/2) * (ri->width/2) + x/2; pb = ri->v[1] + (my/2) * (ri->width/2) + (mx + 1)/2; for(i = 0; i < 4; i++) - { + { pa[0] = pb[0]; pa[1] = pb[1]; pa[2] = pb[2]; pa[3] = pb[3]; pa += ri->width/2; pb += ri->width/2; - } + } } /* -------------------------------------------------------------------------- */ roq_info *roq_open(char *fname) { -FILE *fp; +vfsfile_t *fp; roq_info *ri; int i; - if (COM_FOpenFile(fname, &fp)==-1) -// if((fp = fopen(fname, "rb")) == NULL) - { - +// if (COM_FOpenFile(fname, &fp)==-1) + if((fp = FS_OpenVFS(fname, "rb", FS_GAME)) == NULL) + { return NULL; - } + } if((ri = BZF_Malloc(sizeof(roq_info))) == NULL) - { + { Con_Printf("Error allocating memory.\n"); return NULL; - } + } memset(ri, 0, sizeof(roq_info)); - ri->maxpos = ftell(fp)+com_filesize;//no adds/subracts for fileoffset here + com_filesize = VFS_GETLEN(fp); + + ri->maxpos = VFS_TELL(fp)+com_filesize;//no adds/subracts for fileoffset here ri->fp = fp; - if(roq_parse_file(fp, ri)) return NULL; + if(roq_parse_file(fp, ri)) + return NULL; #ifndef FAST ri->stream_length = (ri->num_frames * 1000)/30; #endif for(i = 0; i < 128; i++) - { + { ri->snd_sqr_arr[i] = i * i; ri->snd_sqr_arr[i + 128] = -(i * i); - } + } for(i = 0; i < 2; i++) - { + { if((ri->y[i] = BZF_Malloc(ri->width * ri->height)) == NULL || (ri->u[i] = BZF_Malloc((ri->width * ri->height)/4)) == NULL || (ri->v[i] = BZF_Malloc((ri->width * ri->height)/4)) == NULL) - { + { Con_Printf("Memory allocation error.\n"); return NULL; - } } + } ri->buf_size *= 2; if((ri->buf = BZF_Malloc(ri->buf_size)) == NULL) - { + { Con_Printf("Memory allocation error.\n"); return NULL; - } + } ri->audio_buf_size = 0; ri->audio = NULL; @@ -360,15 +375,20 @@ void roq_close(roq_info *ri) { int i; - if(ri == NULL) return; - fclose(ri->fp); + if(ri == NULL) + return; + VFS_CLOSE(ri->fp); for(i = 0; i < 2; i++) - { - if(ri->y[i] != NULL) BZ_Free(ri->y[i]); - if(ri->u[i] != NULL) BZ_Free(ri->u[i]); - if(ri->v[i] != NULL) BZ_Free(ri->v[i]); - } - if(ri->buf != NULL) BZ_Free(ri->buf); + { + if(ri->y[i] != NULL) + BZ_Free(ri->y[i]); + if(ri->u[i] != NULL) + BZ_Free(ri->u[i]); + if(ri->v[i] != NULL) + BZ_Free(ri->v[i]); + } + if(ri->buf != NULL) + BZ_Free(ri->buf); BZ_Free(ri); } @@ -376,7 +396,7 @@ int i; /* -------------------------------------------------------------------------- */ int roq_read_frame(roq_info *ri) { -FILE *fp = ri->fp; +vfsfile_t *fp = ri->fp; unsigned int chunk_id = 0, chunk_arg = 0; unsigned long chunk_size = 0; int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1, vqid, bpos, xpos, ypos, xp, yp, x, y; @@ -384,75 +404,72 @@ unsigned char *tp, *buf; int frame_stats[2][4] = {{0},{0}}; roq_qcell *qcell; - fseek(fp, ri->vid_pos, SEEK_SET); + VFS_SEEK(fp, ri->vid_pos); while(!rfeof(fp)) - { + { chunk_id = get_word(fp); chunk_size = get_long(fp); chunk_arg = get_word(fp); if (chunk_size == 0xffffffff) return -1; - if(rfeof(fp)) break; - if(chunk_id == RoQ_QUAD_VQ) break; + if(rfeof(fp)) + break; + if(chunk_id == RoQ_QUAD_VQ) + break; if(chunk_id == RoQ_QUAD_CODEBOOK) - { - if((nv1 = chunk_arg >> 8) == 0) nv1 = 256; - if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) nv2 = 256; - for(i = 0; i < nv1; i++) - { - ri->cells[i].y0 = fgetc(fp); - ri->cells[i].y1 = fgetc(fp); - ri->cells[i].y2 = fgetc(fp); - ri->cells[i].y3 = fgetc(fp); - ri->cells[i].u = fgetc(fp); - ri->cells[i].v = fgetc(fp); - } + { + if((nv1 = chunk_arg >> 8) == 0) + nv1 = 256; + if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) + nv2 = 256; + VFS_READ(fp, ri->cells, nv1 * sizeof(roq_cell)); for(i = 0; i < nv2; i++) - for(j = 0; j < 4; j++) ri->qcells[i].idx[j] = fgetc(fp); - } - else fseek(fp, chunk_size, SEEK_CUR); + for(j = 0; j < 4; j++) ri->qcells[i].idx[j] = VFS_GETC(fp); } + else + VFS_SEEK(fp, VFS_TELL(fp)+chunk_size); + } if(chunk_id != RoQ_QUAD_VQ) - { - ri->vid_pos = ftell(fp); + { + ri->vid_pos = VFS_TELL(fp); return 0; - } + } ri->frame_num++; if(ri->buf_size < chunk_size) - { + { ri->buf_size *= 2; if (ri->buf_size < chunk_size) //double wasn't enough ri->buf_size = chunk_size; BZ_Free(ri->buf); if((ri->buf = BZ_Malloc(ri->buf_size)) == NULL) - { + { Con_Printf("Memory allocation error.\n"); return -1; - } } - fread(ri->buf, chunk_size, 1, fp); + } + VFS_READ(fp, ri->buf, chunk_size); buf = ri->buf; bpos = xpos = ypos = 0; while(bpos < chunk_size) - { + { for(yp = ypos; yp < ypos + 16; yp += 8) for(xp = xpos; xp < xpos + 16; xp += 8) - { + { if(vqflg_pos < 0) - { + { vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); vqflg_pos = 7; - } + } vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; frame_stats[0][vqid]++; vqflg_pos--; switch(vqid) - { + { case RoQ_ID_MOT: break; case RoQ_ID_FCC: apply_motion_8x8(ri, xp, yp, buf[bpos++], (char)(chunk_arg >> 8), (char)(chunk_arg & 0xff)); @@ -466,21 +483,21 @@ roq_qcell *qcell; break; case RoQ_ID_CCC: for(k = 0; k < 4; k++) - { + { x = xp; y = yp; if(k & 0x01) x += 4; if(k & 0x02) y += 4; if(vqflg_pos < 0) - { + { vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); vqflg_pos = 7; - } + } vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; frame_stats[1][vqid]++; vqflg_pos--; switch(vqid) - { + { case RoQ_ID_MOT: break; case RoQ_ID_FCC: apply_motion_4x4(ri, x, y, buf[bpos++], (char)(chunk_arg >> 8), (char)(chunk_arg & 0xff)); @@ -499,22 +516,22 @@ roq_qcell *qcell; apply_vector_2x2(ri, x+2, y+2, ri->cells + buf[bpos+3]); bpos += 4; break; - } } + } break; default: Con_Printf("Unknown vq code: %d\n", vqid); - } } + } xpos += 16; if(xpos >= ri->width) - { + { xpos -= ri->width; ypos += 16; - } - if(ypos >= ri->height) break; } + if(ypos >= ri->height) break; + } #if 0 frame_stats[0][3] = 0; @@ -523,20 +540,28 @@ roq_qcell *qcell; Con_Printf("for 04x04 CCC = %d, FCC = %d, MOT = %d, SLD = %d, PAT = 0\n", frame_stats[1][3], frame_stats[1][1], frame_stats[1][0], frame_stats[1][2]); #endif - ri->vid_pos = ftell(fp); + ri->vid_pos = VFS_TELL(fp); if(ri->frame_num == 1) - { + { memcpy(ri->y[1], ri->y[0], ri->width * ri->height); memcpy(ri->u[1], ri->u[0], (ri->width * ri->height)/4); memcpy(ri->v[1], ri->v[0], (ri->width * ri->height)/4); - } + } else - { - tp = ri->y[0]; ri->y[0] = ri->y[1]; ri->y[1] = tp; - tp = ri->u[0]; ri->u[0] = ri->u[1]; ri->u[1] = tp; - tp = ri->v[0]; ri->v[0] = ri->v[1]; ri->v[1] = tp; - } + { + tp = ri->y[0]; + ri->y[0] = ri->y[1]; + ri->y[1] = tp; + + tp = ri->u[0]; + ri->u[0] = ri->u[1]; + ri->u[1] = tp; + + tp = ri->v[0]; + ri->v[0] = ri->v[1]; + ri->v[1] = tp; + } return 1; } @@ -545,16 +570,16 @@ roq_qcell *qcell; /* -------------------------------------------------------------------------- */ int roq_read_audio(roq_info *ri) { -FILE *fp = ri->fp; +vfsfile_t *fp = ri->fp; unsigned int chunk_id = 0, chunk_arg = 0; unsigned long chunk_size = 0; int i, snd_left, snd_right; - fseek(fp, ri->aud_pos, SEEK_SET); + VFS_SEEK(fp, ri->aud_pos); ri->audio_size = 0; for(;;) - { + { if(rfeof(fp)) return -1; chunk_id = get_word(fp); @@ -566,51 +591,51 @@ int i, snd_left, snd_right; return -1; if (chunk_id == RoQ_SOUND_MONO || chunk_id == RoQ_SOUND_STEREO) break; - fseek(fp, chunk_size, SEEK_CUR); - } + VFS_SEEK(fp, VFS_TELL(fp)+chunk_size); + } if(ri->audio_buf_size < chunk_size*2) - { + { if(ri->audio != NULL) BZ_Free(ri->audio); ri->audio=NULL; ri->audio_buf_size = chunk_size * 3; if (ri->audio_buf_size <= 0) return -1; if((ri->audio = BZ_Malloc(ri->audio_buf_size)) == NULL) return -1; - } + } if (ri->audio_buf_size < 0) return -1; if(chunk_id == RoQ_SOUND_MONO) - { + { ri->audio_size = chunk_size; snd_left = chunk_arg; for(i = 0; i < chunk_size; i++) - { - snd_left += (int)ri->snd_sqr_arr[(unsigned)fgetc(fp)]; + { + snd_left += (int)ri->snd_sqr_arr[(unsigned)VFS_GETC(fp)]; *(short *)&ri->audio[i * 2] = snd_left; - } - ri->aud_pos = ftell(fp); - return chunk_size; } + ri->aud_pos = VFS_TELL(fp); + return chunk_size; + } if(chunk_id == RoQ_SOUND_STEREO) - { + { ri->audio_size = chunk_size; snd_left = (chunk_arg & 0xFF00); snd_right = (chunk_arg & 0xFF) << 8; for(i = 0; i < chunk_size; i += 2) - { - snd_left += (int)ri->snd_sqr_arr[(unsigned)fgetc(fp)]; - snd_right += (int)ri->snd_sqr_arr[(unsigned)fgetc(fp)]; + { + snd_left += (int)ri->snd_sqr_arr[(unsigned)VFS_GETC(fp)]; + snd_right += (int)ri->snd_sqr_arr[(unsigned)VFS_GETC(fp)]; *(short *)&ri->audio[i * 2] = snd_left; *(short *)&ri->audio[i * 2 + 2] = snd_right; - } - ri->aud_pos = ftell(fp); - return chunk_size; } + ri->aud_pos = VFS_TELL(fp); + return chunk_size; + } - ri->aud_pos = ftell(fp); + ri->aud_pos = VFS_TELL(fp); return 0; } #undef rfeof diff --git a/engine/client/snd_mem.c b/engine/client/snd_mem.c index 69a120abb..44288f0a3 100644 --- a/engine/client/snd_mem.c +++ b/engine/client/snd_mem.c @@ -213,9 +213,6 @@ qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc) S_LoadSound ============== */ -#ifdef AVAIL_MP3 -sfxcache_t *S_LoadMP3Sound (sfx_t *s); -#endif sfxcache_t *S_LoadSound (sfx_t *s) { @@ -235,13 +232,6 @@ sfxcache_t *S_LoadSound (sfx_t *s) s->decoder = NULL; -#ifdef AVAIL_MP3 - //mp3 support. The only bit actual code outside snd_mp3.c (excluding def for the function call) - sc = S_LoadMP3Sound(s); // try and load a replacement mp3 instead. - if (sc) - return sc; -#endif - if (name[1] == ':' && name[2] == '\\') diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 7ec3c38aa..5dd22e419 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -72,6 +72,13 @@ int viewportx; int viewporty; +static int VFS_GETC(vfsfile_t *fp) +{ + unsigned char c; + VFS_READ(fp, &c, 1); + return c; +} + //newsize = number of chars, EXCLUDING terminator. void MakeNewSize(fileblock_t *block, int newsize) //this is used to resize a block. It allocates a new one, copys the data frees the old one and links it into the right place //it is called when the user is typing @@ -132,7 +139,7 @@ void SetCursorpos(void) if (ts < 1) ts = 4; for (cursorx=0,s=cursorblock->data;cursorx < positionacross && *s;s++,a++) - { + { if (*s == '\t') { cursorx += ts; @@ -227,7 +234,7 @@ qboolean EditorSaveFile(char *s) //returns true if succesful void EditorNewFile() { - GETBLOCK(64, firstblock); + GETBLOCK(64, firstblock); GETBLOCK(64, firstblock->next); firstblock->next->prev = firstblock; cursorblock = firstblock; @@ -239,7 +246,7 @@ void EditorNewFile() madechanges = true; executionlinenum = -1; - key_dest = key_editor; + key_dest = key_editor; editoractive = true; } @@ -248,33 +255,29 @@ void EditorOpenFile(char *name) int i; char line[8192]; int len, flen, pos=0; - FILE *F; - fileblock_t *b; + vfsfile_t *F; + fileblock_t *b; - CloseEditor(); + CloseEditor(); strcpy(OpenEditorFile, name); - if ((flen=COM_FOpenFile(OpenEditorFile, &F)) == -1) + if (!(F = FS_OpenVFS(OpenEditorFile, "rb", FS_GAME))) { sprintf(OpenEditorFile, "src/%s", name); - if ((flen=COM_FOpenFile(OpenEditorFile, &F)) == -1) + if (!(F = FS_OpenVFS(OpenEditorFile, "rb", FS_GAME))) { - F = fopen(OpenEditorFile, "rb"); - if (F) - flen = COM_filelength(F); - else - { - Con_Printf("Couldn't open file \"%s\"\nA new file will be created\n", name); - strcpy(OpenEditorFile, name); - key_dest = key_console; - EditorNewFile(); - return; - } + Con_Printf("Couldn't open file \"%s\"\nA new file will be created\n", name); + strcpy(OpenEditorFile, name); + key_dest = key_console; + EditorNewFile(); + return; } } i=1; - + + flen = VFS_GETLEN(F); + while(pos < flen) { len = 0; @@ -282,7 +285,7 @@ void EditorOpenFile(char *name) { if (pos+len >= flen) break; - line[len] = fgetc(F); + line[len] = VFS_GETC(F); if (line[len] == '\n') break; @@ -311,7 +314,7 @@ void EditorOpenFile(char *name) { if (editprogfuncs->ToggleBreak(editprogfuncs, OpenEditorFile+strlen(com_gamedir)+1, i, 3)) { - firstblock->flags |= FB_BREAK; + firstblock->flags |= FB_BREAK; } } else @@ -320,7 +323,7 @@ void EditorOpenFile(char *name) { if (svprogfuncs->ToggleBreak(svprogfuncs, OpenEditorFile+strlen(com_gamedir)+1, i, 3)) { - firstblock->flags |= FB_BREAK; + firstblock->flags |= FB_BREAK; } } } @@ -329,11 +332,11 @@ void EditorOpenFile(char *name) } if (firstblock == NULL) { - GETBLOCK(10, firstblock); - } + GETBLOCK(10, firstblock); + } else for (; firstblock->prev; firstblock=firstblock->prev); - fclose(F); + VFS_CLOSE(F); cursorblock = firstblock; cursorx = 0; @@ -343,7 +346,7 @@ void EditorOpenFile(char *name) madechanges = false; executionlinenum = -1; - key_dest = key_editor; + key_dest = key_editor; editoractive = true; } @@ -378,7 +381,7 @@ void Editor_Key(int key) break; case 'N': - case 'n': + case 'n': (*CmdAfterSave)(); CmdAfterSave = NULL; break; @@ -447,7 +450,7 @@ void Editor_Key(int key) cursorblock = cursorblock->prev; cursorlinenum--; } - } + } } SetCursorpos(); break; @@ -484,7 +487,7 @@ void Editor_Key(int key) { *s = '\0'; break; - } + } s++; } if (*file) @@ -497,14 +500,14 @@ void Editor_Key(int key) case K_F4: EditorSaveFile(OpenEditorFile); break; - case K_F5: + case K_F5: editormodal = false; if (editprogfuncs) *editprogfuncs->pr_trace = false; break; case K_F6: if (editprogfuncs) - PR_StackTrace(editprogfuncs); + PR_StackTrace(editprogfuncs); break; case K_F7: EditorSaveFile(OpenEditorFile); @@ -624,7 +627,7 @@ void Editor_Key(int key) // cursorblock->next->prev = cursorblock->prev; E_Free(b); -// cursorblock = b; +// cursorblock = b; break; } @@ -637,12 +640,12 @@ void Editor_Key(int key) madechanges = true; //FIXME: does this work right? if (!cursorblock->datalength && cursorblock->next && cursorblock->prev) //blank line - { + { b = cursorblock; - if (b->next) + if (b->next) b->next->prev = b->prev; if (b->prev) - b->prev->next = b->next; + b->prev->next = b->next; if (cursorblock->next) cursorblock = cursorblock->next; @@ -663,7 +666,7 @@ void Editor_Key(int key) } break; - case K_ENTER: + case K_ENTER: { fileblock_t *b = cursorblock; @@ -671,7 +674,7 @@ void Editor_Key(int key) madechanges = true; - GETBLOCK(strlen(b->data+cursorx), cursorblock); + GETBLOCK(strlen(b->data+cursorx), cursorblock); cursorblock->next = b->next; cursorblock->prev = b; b->next = cursorblock; @@ -710,12 +713,12 @@ void Editor_Key(int key) } cursorx++; cursorblock->datalength++; - *(s+1) = key; + *(s+1) = key; } else //over write a char - { + { MakeNewSize(cursorblock, cursorblock->datalength+5); //not really needed - + cursorblock->data[cursorx] = key; cursorx++; } @@ -738,7 +741,7 @@ void Draw_CursorLine(int ox, int y, fileblock_t *b) ts*=8; if (b->flags & (FB_BREAK)) - colour = COLOR_RED; //red + colour = COLOR_RED; //red if (executionblock == b) { @@ -757,7 +760,7 @@ void Draw_CursorLine(int ox, int y, fileblock_t *b) if (*d == '\t') { if (a == cx) - Draw_ColouredCharacter (x+ox, y, 11|M_COLOR_WHITE); + Draw_ColouredCharacter (x+ox, y, 11|M_COLOR_WHITE); x+=ts; x-=x%ts; d++; @@ -793,7 +796,7 @@ void Draw_NonCursorLine(int x, int y, fileblock_t *b) ts*=8; if (b->flags & (FB_BREAK)) - colour = COLOR_RED; //red + colour = COLOR_RED; //red if (executionblock == b) { @@ -809,14 +812,14 @@ void Draw_NonCursorLine(int x, int y, fileblock_t *b) { nx+=ts; nx-=nx%ts; - d++; - continue; + d++; + continue; } if (x+nx < vid.width) Draw_ColouredCharacter (x+nx, y, (int)*d | (colour<<8)); d++; - nx += 8; - } + nx += 8; + } } fileblock_t *firstline(void) @@ -859,7 +862,7 @@ void Editor_Draw(void) cursorlinenum++; if (b == cursorblock) break; - } + } } if (!viewportystartblock) //look for the cursor line num @@ -870,7 +873,7 @@ void Editor_Draw(void) y++; if (y == viewporty) break; - } + } } x=0; @@ -889,7 +892,7 @@ void Editor_Draw(void) x=-x + vid.width/2; if (x > 0) x = 0; - + if (madechanges) Draw_Character (vid.width - 8, 0, '!'|128); if (!insertkeyhit) @@ -914,14 +917,14 @@ void Editor_Draw(void) { if (b == cursorblock) Draw_CursorLine(x, y, b); - else + else Draw_NonCursorLine(x, y, b); y+=8; if (y > vid.height) break; } - + /* if (CmdAfterSave) { if (madechanges) @@ -955,23 +958,23 @@ int QCLibEditor(progfuncs_t *prfncs, char *filename, int line, int nump, char ** int i; char buffer[8192]; char *r; - FILE *f; + vfsfile_t *f; if (line == -1) return -1; - COM_FOpenFile(filename, &f); + f = FS_OpenVFS(filename, "rb", FS_GAME); if (!f) Con_Printf("%s - %i\n", filename, line); else { for (i = 0; i < line; i++) { - fgets(buffer, sizeof(buffer), f); + VFS_GETS(f, buffer, sizeof(buffer)); } if ((r = strchr(buffer, '\r'))) { r[0] = '\n';r[1]='\0';} Con_Printf("%s", buffer); - fclose(f); + VFS_CLOSE(f); } //PF_break(NULL); return line; @@ -1043,7 +1046,7 @@ void Editor_f(void) void Editor_Init(void) { Cmd_AddCommand("edit", Editor_f); - + Cvar_Register(&alloweditor, "Text editor"); Cvar_Register(&editstripcr, "Text editor"); Cvar_Register(&editaddcr, "Text editor"); diff --git a/engine/client/wad.c b/engine/client/wad.c index 4462e9847..f5866074d 100644 --- a/engine/client/wad.c +++ b/engine/client/wad.c @@ -235,7 +235,7 @@ void SwapPic (qpic_t *pic) typedef struct { char name[16]; - FILE *file; + vfsfile_t *file; int position; int size; } texwadlump_t; @@ -275,7 +275,7 @@ void W_LoadTextureWadFile (char *filename, int complain) wadinfo_t header; int i, j; int infotableofs; - FILE *file; + vfsfile_t *file; int numlumps; wadfile_t *wf = openwadfiles; @@ -287,9 +287,9 @@ void W_LoadTextureWadFile (char *filename, int complain) wf = wf->next; } - COM_FOpenFile (filename, &file); + file = FS_OpenVFS(filename, "rb", FS_GAME); if (!file) - COM_FOpenFile (va("textures/halflife/%s", filename), &file); + file = FS_OpenVFS(va("textures/halflife/%s", filename), "rb", FS_GAME); if (!file) { if (complain) @@ -297,7 +297,7 @@ void W_LoadTextureWadFile (char *filename, int complain) return; } - if (fread(&header, 1, sizeof(wadinfo_t), file) != sizeof(wadinfo_t)) + if (VFS_READ(file, &header, sizeof(wadinfo_t)) != sizeof(wadinfo_t)) {Con_Printf ("W_LoadTextureWadFile: unable to read wad header");return;} if(memcmp(header.identification, "WAD3", 4)) @@ -307,12 +307,12 @@ void W_LoadTextureWadFile (char *filename, int complain) if (numlumps < 1 || numlumps > TEXWAD_MAXIMAGES) {Con_Printf ("W_LoadTextureWadFile: invalid number of lumps (%i)\n", numlumps);return;} infotableofs = LittleLong(header.infotableofs); - if (fseek(file, infotableofs, SEEK_SET)) + if (VFS_SEEK(file, infotableofs)) {Con_Printf ("W_LoadTextureWadFile: unable to seek to lump table");return;} if (!((lumps = Hunk_TempAlloc(sizeof(lumpinfo_t)*numlumps)))) {Con_Printf ("W_LoadTextureWadFile: unable to allocate temporary memory for lump table");return;} - if (fread(lumps, 1, sizeof(lumpinfo_t)*numlumps, file) != (int)sizeof(lumpinfo_t) * numlumps) + if (VFS_READ(file, lumps, sizeof(lumpinfo_t)*numlumps) != (int)sizeof(lumpinfo_t) * numlumps) {Con_Printf ("W_LoadTextureWadFile: unable to read lump table");return;} for (i=0, lump_p = lumps ; iwidth = LittleLong(tex->width); diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index 6c4ee0a2b..318a17f26 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -2962,7 +2962,6 @@ qbool TP_CheckSoundTrigger (char *str) int i, j; int start, length; char soundname[MAX_OSPATH]; - FILE *f; if (!*str) return false; @@ -3008,10 +3007,8 @@ qbool TP_CheckSoundTrigger (char *str) COM_DefaultExtension (soundname, ".wav"); // make sure we have it on disk (FIXME) - COM_FOpenFile (va("sound/%s", soundname), &f); - if (!f) + if (!FS_FLocateFile (va("sound/%s", soundname), FSLFRT_IFFOUND, NULL)) return false; - fclose (f); // now play the sound S_LocalSound (soundname); diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 478368ccc..e2f9f531f 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -42,8 +42,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define AVAIL_JPEGLIB #define AVAIL_ZLIB -// #define AVAIL_MP3 - #define AVAIL_OGGVORBIS #endif #define AVAIL_MASM @@ -58,9 +56,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef NO_ZLIB #undef AVAIL_ZLIB #endif -#ifdef NO_MAD - #undef AVAIL_MP3 -#endif #ifdef NO_OGG #undef AVAIL_OGGVORBIS #endif @@ -84,7 +79,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef MINIMAL #define CL_MASTER //this is useful - #undef AVAIL_MP3 //no mp3 support #undef AVAIL_JPEGLIB //no jpeg support #undef AVAIL_PNGLIB //no png support #undef USE_MADLIB //no internal mp3 playing @@ -120,8 +114,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect') #define FISH //sw rendering only #define ZLIB //zip/pk3 support - #define WEBSERVER //http/ftp servers - #define WEBCLIENT //http/ftp clients. +// #define WEBSERVER //http/ftp servers +// #define WEBCLIENT //http/ftp clients. #define RUNTIMELIGHTING //calculate lit/lux files the first time the map is loaded and doesn't have a loadable lit. // #define QTERM //qterm... adds a console command that allows running programs from within quake - bit like xterm. #define CL_MASTER //query master servers and stuff for a dynamic server listing. @@ -156,10 +150,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef AVAIL_ZLIB #endif -#ifdef USE_MADLIB //global option. Specify on compiler command line. - #define AVAIL_MP3 //suposedly anti-gpl. don't use in a distributed binary -#endif - #ifndef _WIN32 #undef QTERM #endif diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 8158f5be5..020858382 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -883,8 +883,9 @@ void Cmd_AliasList_f (void) Con_Printf("\n"); } -void Alias_WriteAliases (FILE *f) +void Alias_WriteAliases (vfsfile_t *f) { + char *s; cmdalias_t *cmd; int num=0; for (cmd=cmd_alias ; cmd ; cmd=cmd->next) @@ -894,12 +895,22 @@ void Alias_WriteAliases (FILE *f) if (cmd->flags & ALIAS_FROMSERVER) continue; if (!num) - fprintf(f, "\n//////////////////\n//Aliases\n"); - fprintf(f, "alias %s \"%s\"\n", cmd->name, cmd->value); + { + s = va("\n//////////////////\n//Aliases\n"); + VFS_WRITE(f, s, strlen(s)); + } + s = va("alias %s \"%s\"\n", cmd->name, cmd->value); + VFS_WRITE(f, s, strlen(s)); if (cmd->restriction != 1) //1 is default - fprintf(f, "restrict %s %i\n", cmd->name, cmd->restriction); + { + s = va("restrict %s %i\n", cmd->name, cmd->restriction); + VFS_WRITE(f, s, strlen(s)); + } if (cmd->execlevel != 0) //0 is default (runs at user's level) - fprintf(f, "aliaslevel %s %i\n", cmd->name, cmd->execlevel); + { + s = va("aliaslevel %s %i\n", cmd->name, cmd->execlevel); + VFS_WRITE(f, s, strlen(s)); + } num++; } } @@ -2686,24 +2697,13 @@ qboolean Cmd_FilterMessage (char *message, qboolean sameteam) //returns true if */ void Cmd_WriteConfig_f(void) { - FILE *f; + vfsfile_t *f; char *filename; filename = Cmd_Argv(1); if (!*filename) filename = "fte"; - if (!strncmp(filename, "../", 3)) - { - filename+=3; - if (strstr(filename, "..")) - { - Con_Printf ("Couldn't write config %s\n",filename); - return; - } - filename = va("%s/fte/%s.cfg",com_basedir, filename); - } - else { if (strstr(filename, "..")) { @@ -2711,31 +2711,31 @@ void Cmd_WriteConfig_f(void) return; } - filename = va("%s/fte/configs/%s.cfg",com_basedir, filename); + filename = va("configs/%s.cfg",filename); } COM_DefaultExtension(filename, ".cfg"); - COM_CreatePath(filename); - f = fopen (filename, "wb"); + FS_CreatePath(filename, FS_CONFIGONLY); + f = FS_OpenVFS(filename, "wb", FS_CONFIGONLY); if (!f) { Con_Printf ("Couldn't write config %s\n",filename); return; } - fprintf(f, "// FTE config file\n\n"); + VFS_WRITE(f, "// FTE config file\n\n", 20); #ifndef SERVERONLY Key_WriteBindings (f); CL_SaveInfo(f); #else - fprintf(f, "// Dedicated Server config\n\n"); + VFS_WRITE(f, "// Dedicated Server config\n\n", 28); #endif #ifdef CLIENTONLY - fprintf(f, "// no local/server infos\n\n"); + VFS_WRITE(f, "// no local/server infos\n\n", 26); #else SV_SaveInfos(f); #endif Alias_WriteAliases (f); Cvar_WriteVariables (f, true); - fclose(f); + VFS_CLOSE(f); FS_FlushFSHash(); } @@ -2819,6 +2819,7 @@ void Cmd_Init (void) Cmd_AddCommand ("cfg_save",Cmd_WriteConfig_f); Cmd_AddCommand ("cfg_load",Cmd_Exec_f); + //Cmd_AddCommand ("cfg_reset",Cmd_Reset_f); Cmd_AddCommand ("exec",Cmd_Exec_f); Cmd_AddCommand ("echo",Cmd_Echo_f); diff --git a/engine/common/common.c b/engine/common/common.c index 72297794d..07462a646 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -2131,11 +2131,11 @@ being registered. */ void COM_CheckRegistered (void) { - FILE *h; + vfsfile_t *h; unsigned short check[128]; int i; - COM_FOpenFile("gfx/pop.lmp", &h); + h = FS_OpenVFS("gfx/pop.lmp", "r", FS_GAME); static_registered = false; if (!h) @@ -2149,8 +2149,8 @@ void COM_CheckRegistered (void) return; } - fread (check, 1, sizeof(check), h); - fclose (h); + VFS_READ(h, check, sizeof(check)); + VFS_CLOSE(h); for (i=0 ; i<128 ; i++) if (pop[i] != (unsigned short)BigShort (check[i])) @@ -2743,7 +2743,7 @@ void Info_Print (char *s) } } -void Info_WriteToFile(FILE *f, char *info, char *commandname, int cvarflags) +void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags) { char *command; char *value; @@ -2764,12 +2764,12 @@ void Info_WriteToFile(FILE *f, char *info, char *commandname, int cvarflags) if (var && var->flags & cvarflags) continue; //this is saved via a cvar. - fwrite(commandname, strlen(commandname), 1, f); - fwrite(" ", 1, 1, f); - fwrite(command, value-command, 1, f); - fwrite(" ", 1, 1, f); - fwrite(value+1, info-(value+1), 1, f); - fwrite("\n", 1, 1, f); + VFS_WRITE(f, commandname, strlen(commandname)); + VFS_WRITE(f, " ", 1); + VFS_WRITE(f, command, value-command); + VFS_WRITE(f, " ", 1); + VFS_WRITE(f, value+1, info-(value+1)); + VFS_WRITE(f, "\n", 1); } } diff --git a/engine/common/common.h b/engine/common/common.h index 36a93ec81..d82b2611b 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -266,7 +266,10 @@ extern int com_filesize; struct cache_user_s; extern char com_gamedir[MAX_OSPATH]; -extern char *com_basedir; +extern char com_quakedir[MAX_OSPATH]; +extern char com_homedir[MAX_OSPATH]; +extern char com_configdir[MAX_OSPATH]; //dir to put cfg_save configs in +//extern char *com_basedir; void COM_WriteFile (char *filename, void *data, int len); FILE *COM_WriteFileOpen (char *filename); @@ -279,7 +282,7 @@ typedef struct { int len; } flocation_t; -typedef enum {FSLFRT_LENGTH, FSLFRT_DEPTH_OSONLY, FSLFRT_DEPTH_ANYPATH} FSLF_ReturnType_e; +typedef enum {FSLFRT_IFFOUND, FSLFRT_LENGTH, FSLFRT_DEPTH_OSONLY, FSLFRT_DEPTH_ANYPATH} FSLF_ReturnType_e; //if loc is valid, loc->search is always filled in, the others are filled on success. //returns -1 if couldn't find. int FS_FLocateFile(char *filename, FSLF_ReturnType_e returntype, flocation_t *loc); @@ -296,6 +299,36 @@ void COM_CloseFile (FILE *h); #define COM_FDepthFile(filename,ignorepacks) FS_FLocateFile(filename,ignorepacks?FSLFRT_DEPTH_OSONLY:FSLFRT_DEPTH_ANYPATH, NULL) #define COM_FCheckExists(filename) (FS_FLocateFile(filename,FSLFRT_LENGTH, NULL)>0) + +typedef struct vfsfile_s { + int (*ReadBytes) (struct vfsfile_s *file, void *buffer, int bytestoread); + int (*WriteBytes) (struct vfsfile_s *file, void *buffer, int bytestoread); + qboolean (*Seek) (struct vfsfile_s *file, unsigned long pos); //returns false for error + unsigned long (*Tell) (struct vfsfile_s *file); + unsigned long (*GetLen) (struct vfsfile_s *file); //could give some lag + void (*Close) (struct vfsfile_s *file); +} vfsfile_t; + +#define VFS_CLOSE(vf) (vf->Close(vf)) +#define VFS_TELL(vf) (vf->Tell(vf)) +#define VFS_GETLEN(vf) (vf->GetLen(vf)) +#define VFS_SEEK(vf,pos) (vf->Seek(vf,pos)) +#define VFS_READ(vf,buffer,buflen) (vf->ReadBytes(vf,buffer,buflen)) +#define VFS_WRITE(vf,buffer,buflen) (vf->WriteBytes(vf,buffer,buflen)) +#define VFS_FLUSH(vf) +#define VFS_GETS(vf,buffer,buflen) Sys_Error("VFS_GETS not implemented"),false //:( + +void FS_Remove(char *fname, int relativeto); +vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto); +enum { + FS_GAME, + FS_BASE, + FS_GAMEONLY, + FS_CONFIGONLY, + FS_SKINS +}; + + int COM_filelength (FILE *f); qbyte *COM_LoadStackFile (char *path, void *buffer, int bufsize); qbyte *COM_LoadTempFile (char *path); @@ -328,7 +361,7 @@ void Info_RemoveNonStarKeys (char *start); void Info_SetValueForKey (char *s, const char *key, const char *value, int maxsize); void Info_SetValueForStarKey (char *s, const char *key, const char *value, int maxsize); void Info_Print (char *s); -void Info_WriteToFile(FILE *f, char *info, char *commandname, int cvarflags); +void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags); unsigned int Com_BlockChecksum (void *buffer, int length); void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf); diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 65fe92598..b63931b18 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -840,7 +840,7 @@ Cvar_RegisterVariable Adds a freestanding variable to the variable list. ============ */ -void Cvar_Register (cvar_t *variable, const char *groupname) +qboolean Cvar_Register (cvar_t *variable, const char *groupname) { cvar_t *old; cvar_group_t *group; @@ -878,18 +878,18 @@ void Cvar_Register (cvar_t *variable, const char *groupname) Cvar_SetCore (variable, old->string, true); Cvar_Free(old); - return; + return false; } Con_Printf ("Can't register variable %s, already defined\n", variable->name); - return; + return false; } // check for overlap with a command if (Cmd_Exists (variable->name)) { Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name); - return; + return false; } group = Cvar_GetGroup(groupname); @@ -905,6 +905,8 @@ void Cvar_Register (cvar_t *variable, const char *groupname) // set it through the function to be consistant Cvar_SetCore (variable, value, true); + + return true; } /* void Cvar_RegisterVariable (cvar_t *variable) @@ -931,7 +933,8 @@ cvar_t *Cvar_Get(const char *name, const char *defaultvalue, int flags, const ch var->string = (char*)defaultvalue; var->flags = flags|CVAR_POINTER|CVAR_USERCREATED; - Cvar_Register(var, group); + if (!Cvar_Register(var, group)) + return NULL; return var; } @@ -1054,12 +1057,13 @@ Writes lines containing "set variable value" for all variables with the archive flag set to true. ============ */ -void Cvar_WriteVariables (FILE *f, qboolean all) +void Cvar_WriteVariables (vfsfile_t *f, qboolean all) { qboolean writtengroupheader; cvar_group_t *grp; cvar_t *var; char *val; + char *s; for (grp=cvar_groups ; grp ; grp=grp->next) { @@ -1070,7 +1074,8 @@ void Cvar_WriteVariables (FILE *f, qboolean all) if (!writtengroupheader) { writtengroupheader = true; - fprintf(f, "\n// %s\n", grp->name); + s = va("\n// %s\n", grp->name); + VFS_WRITE(f, s, strlen(s)); } val = var->string; //latched vars should act differently. @@ -1080,12 +1085,13 @@ void Cvar_WriteVariables (FILE *f, qboolean all) if (var->flags & CVAR_USERCREATED) { if (var->flags & CVAR_ARCHIVE) - fprintf (f, "seta %s \"%s\"\n", var->name, val); + s = va("seta %s \"%s\"\n", var->name, val); else - fprintf (f, "set %s \"%s\"\n", var->name, val); + s = va("set %s \"%s\"\n", var->name, val); } else - fprintf (f, "%s \"%s\"\n", var->name, val); + s = va("%s \"%s\"\n", var->name, val); + VFS_WRITE(f, s, strlen(s)); } } } diff --git a/engine/common/cvar.h b/engine/common/cvar.h index 0156d8b8b..e323c7b3d 100644 --- a/engine/common/cvar.h +++ b/engine/common/cvar.h @@ -104,7 +104,7 @@ cvar_t *Cvar_Get (const char *var_name, const char *value, int flags, const char void Cvar_LockFromServer(cvar_t *var, const char *str); -void Cvar_Register (cvar_t *variable, const char *cvargroup); +qboolean Cvar_Register (cvar_t *variable, const char *cvargroup); // registers a cvar that already has the name, string, and optionally the // archive elements set. @@ -135,7 +135,7 @@ qboolean Cvar_Command (int level); // command. Returns true if the command was a variable reference that // was handled. (print or change) -void Cvar_WriteVariables (FILE *f, qboolean all); +void Cvar_WriteVariables (vfsfile_t *f, qboolean all); // Writes lines containing "set variable value" for all variables // with the archive flag set to true. diff --git a/engine/common/fs.c b/engine/common/fs.c index 7e24bace0..75e7746a5 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -1,5 +1,7 @@ #include "quakedef.h" +//#define com_gamedir com__gamedir + #include @@ -13,8 +15,25 @@ int active_fs_cachetype; +typedef struct { + void (*PrintPath)(void *handle); + void (*ClosePath)(void *handle); + void (*BuildHash)(void *handle); + qboolean (*FindFile)(void *handle, flocation_t *loc, char *name, void *hashedresult); //true if found (hashedresult can be NULL) + //note that if rawfile and offset are set, many Com_FileOpens will read the raw file + //otherwise ReadFile will be called instead. + void (*ReadFile)(void *handle, flocation_t *loc, char *buffer); //reads the entire file + int (*EnumerateFiles)(void *handle, char *match, int (*func)(char *, int, void *), void *parm); + + void *(*OpenNew)(vfsfile_t *file, char *desc); //returns a handle to a new pak/path + + int (*GeneratePureCRC) (void *handle, int seed, int usepure); + + vfsfile_t *(*OpenVFS)(void *handle, flocation_t *loc, char *mode); +} searchpathfuncs_t; +vfsfile_t *FS_OpenVFSLoc(flocation_t *loc, char *mode); @@ -43,10 +62,12 @@ typedef struct typedef struct pack_s { - char filename[MAX_OSPATH]; - FILE *handle; + char descname[MAX_OSPATH]; + vfsfile_t *handle; + unsigned int filepos; //the pos the subfiles left it at (to optimize calls to vfs_seek) int numfiles; packfile_t *files; + int references; //seeing as all vfiles from a pak file use the parent's vfsfile, we need to keep the parent open until all subfiles are closed. } pack_t; // @@ -80,36 +101,19 @@ typedef struct #define MAX_FILES_IN_PACK 2048 -char com_gamedir[MAX_OSPATH]; -char *com_basedir; +char com_gamedir[MAX_OSPATH]; //the os path where we write files +//char *com_basedir; //obsolete char com_quakedir[MAX_OSPATH]; char com_homedir[MAX_OSPATH]; +char com_configdir[MAX_OSPATH]; //homedir/fte/configs + int fs_hash_dups; int fs_hash_files; -typedef struct { - void (*PrintPath)(void *handle); - void (*ClosePath)(void *handle); - void (*BuildHash)(void *handle); - qboolean (*FindFile)(void *handle, flocation_t *loc, char *name, void *hashedresult); //true if found (hashedresult can be NULL) - //note that if rawfile and offset are set, many Com_FileOpens will read the raw file - //otherwise ReadFile will be called instead. - void (*ReadFile)(void *handle, flocation_t *loc, char *buffer); //reads the entire file - int (*EnumerateFiles)(void *handle, char *match, int (*func)(char *, int, void *), void *parm); - - void *(*OpenNew)(char *name); - - int (*GeneratePureCRC) (void *handle, int seed, int usepure); -} searchpathfuncs_t; - - - - - @@ -118,9 +122,7 @@ int COM_FileOpenRead (char *path, FILE **hndl); - - - +#define ENFORCEFOPENMODE(mode) {if (strcmp(mode, "r") && strcmp(mode, "w")/* && strcmp(mode, "rw")*/)Sys_Error("fs mode %s is not permitted here\n");} @@ -131,6 +133,92 @@ int COM_FileOpenRead (char *path, FILE **hndl); //====================================================================================================== //STDIO files (OS) +typedef struct { + vfsfile_t funcs; + FILE *handle; +} vfsosfile_t; +int VFSOS_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread) +{ + vfsosfile_t *intfile = (vfsosfile_t*)file; + return fread(buffer, 1, bytestoread, intfile->handle); +} +int VFSOS_WriteBytes (struct vfsfile_s *file, void *buffer, int bytestoread) +{ + vfsosfile_t *intfile = (vfsosfile_t*)file; + return fwrite(buffer, 1, bytestoread, intfile->handle); +} +qboolean VFSOS_Seek (struct vfsfile_s *file, unsigned long pos) +{ + vfsosfile_t *intfile = (vfsosfile_t*)file; + return fseek(intfile->handle, pos, SEEK_SET) == 0; +} +unsigned long VFSOS_Tell (struct vfsfile_s *file) +{ + vfsosfile_t *intfile = (vfsosfile_t*)file; + return ftell(intfile->handle); +} +unsigned long VFSOS_GetSize (struct vfsfile_s *file) +{ + vfsosfile_t *intfile = (vfsosfile_t*)file; + + unsigned int curpos; + unsigned int maxlen; + curpos = ftell(intfile->handle); + fseek(intfile->handle, 0, SEEK_END); + maxlen = ftell(intfile->handle); + fseek(intfile->handle, curpos, SEEK_SET); + + return maxlen; +} +void VFSOS_Close(vfsfile_t *file) +{ + vfsosfile_t *intfile = (vfsosfile_t*)file; + fclose(intfile->handle); +} +vfsfile_t *VFSOS_Open(char *osname, char *mode) +{ + FILE *f; + vfsosfile_t *file; + qboolean read = !!strchr(mode, 'r'); + qboolean write = !!strchr(mode, 'w'); + qboolean text = !!strchr(mode, 't'); + char newmode[3]; + int modec = 0; + + if (read) + newmode[modec++] = 'r'; + if (write) + newmode[modec++] = 'w'; + if (text) + newmode[modec++] = 't'; + else + newmode[modec++] = 'b'; + newmode[modec++] = '\0'; + + f = fopen(osname, newmode); + if (!f) + return NULL; + + file = Z_Malloc(sizeof(vfsosfile_t)); + file->funcs.ReadBytes = strchr(mode, 'r')?VFSOS_ReadBytes:NULL; + file->funcs.WriteBytes = strchr(mode, 'w')?VFSOS_WriteBytes:NULL; + file->funcs.Seek = VFSOS_Seek; + file->funcs.Tell = VFSOS_Tell; + file->funcs.GetLen = VFSOS_GetSize; + file->funcs.Close = VFSOS_Close; + file->handle = f; + + return (vfsfile_t*)file; +} + +vfsfile_t *FSOS_OpenVFS(void *handle, flocation_t *loc, char *mode) +{ + char diskname[MAX_OSPATH]; + _snprintf(diskname, sizeof(diskname), "%s/%s", handle, loc->rawname); + + return VFSOS_Open(diskname, mode); +} + void FSOS_PrintPath(void *handle) { Con_Printf("%s\n", handle); @@ -176,7 +264,7 @@ qboolean FSOS_FLocate(void *handle, flocation_t *loc, char *filename, void *hash if (hashedresult && (void *)hashedresult != handle) - return -1; + return false; /* if (!static_registered) @@ -191,7 +279,7 @@ qboolean FSOS_FLocate(void *handle, flocation_t *loc, char *filename, void *hash f = fopen(netpath, "rb"); if (!f) - return -1; + return false; fseek(f, 0, SEEK_END); len = ftell(f); @@ -201,10 +289,10 @@ qboolean FSOS_FLocate(void *handle, flocation_t *loc, char *filename, void *hash loc->len = len; loc->offset = 0; loc->index = 0; - Q_strncpyz(loc->rawname, netpath, sizeof(loc->rawname)); + Q_strncpyz(loc->rawname, filename, sizeof(loc->rawname)); } - return len; + return true; } void FSOS_ReadFile(void *handle, flocation_t *loc, char *buffer) { @@ -222,7 +310,10 @@ searchpathfuncs_t osfilefuncs = { FSOS_BuildHash, FSOS_FLocate, FSOS_ReadFile, - Sys_EnumerateFiles + Sys_EnumerateFiles, + NULL, + NULL, + FSOS_OpenVFS }; @@ -233,12 +324,21 @@ void FSPAK_PrintPath(void *handle) { pack_t *pak = handle; - Con_Printf("%s\n", pak->filename); + if (pak->references != 1) + Con_Printf("%s (%i)\n", pak->descname, pak->references-1); + else + Con_Printf("%s\n", pak->descname); } void FSPAK_ClosePath(void *handle) { pack_t *pak = handle; - fclose (pak->handle); + + pak->references--; + if (pak->references > 0) + return; //not free yet + + + VFS_CLOSE (pak->handle); if (pak->files) Z_Free(pak->files); Z_Free(pak); @@ -270,7 +370,7 @@ qboolean FSPAK_FLocate(void *handle, flocation_t *loc, char *filename, void *has if (pf) { //is this a pointer to a file in this pak? if (pf < pak->files || pf > pak->files + pak->numfiles) - return -1; //was found in a different path + return false; //was found in a different path } else { @@ -290,13 +390,13 @@ qboolean FSPAK_FLocate(void *handle, flocation_t *loc, char *filename, void *has if (loc) { loc->index = pf - pak->files; - strcpy(loc->rawname, pak->filename); + _snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", pak->descname, filename); loc->offset = pf->filepos; loc->len = pf->filelen; } - return len; + return true; } - return -1; + return false; } int FSPAK_EnumerateFiles (void *handle, char *match, int (*func)(char *, int, void *), void *parm) { @@ -324,7 +424,7 @@ Loads the header and directory, adding the files at the beginning of the list so they override previous pack files. ================= */ -void *FSPAK_LoadPackFile (char *packfile) +void *FSPAK_LoadPackFile (vfsfile_t *file, char *desc) { dpackheader_t header; int i; @@ -332,14 +432,16 @@ void *FSPAK_LoadPackFile (char *packfile) packfile_t *newfiles; int numpackfiles; pack_t *pack; - FILE *packhandle; + vfsfile_t *packhandle; dpackfile_t info; + int read; // unsigned short crc; - if (COM_FileOpenRead (packfile, &packhandle) == -1) + packhandle = file; + if (packhandle == NULL) return NULL; - fread (&header, 1, sizeof(header), packhandle); + VFS_READ(packhandle, &header, sizeof(header)); if (header.id[0] != 'P' || header.id[1] != 'A' || header.id[2] != 'C' || header.id[3] != 'K') { @@ -359,7 +461,7 @@ void *FSPAK_LoadPackFile (char *packfile) newfiles = (packfile_t*)Z_Malloc (numpackfiles * sizeof(packfile_t)); - fseek (packhandle, header.dirofs, SEEK_SET); + VFS_SEEK(packhandle, header.dirofs); // fread (&info, 1, header.dirlen, packhandle); // crc the directory to check for modifications @@ -372,7 +474,8 @@ void *FSPAK_LoadPackFile (char *packfile) // parse the directory for (i=0 ; ifilename, packfile); + strcpy (pack->descname, desc); pack->handle = packhandle; pack->numfiles = numpackfiles; pack->files = newfiles; + pack->filepos = 0; + VFS_SEEK(packhandle, pack->filepos); - Con_TPrintf (TL_ADDEDPACKFILE, packfile, numpackfiles); + pack->references++; + + Con_TPrintf (TL_ADDEDPACKFILE, desc, numpackfiles); return pack; } + + +typedef struct { + vfsfile_t funcs; + pack_t *parentpak; + unsigned long startpos; + unsigned long length; + unsigned long currentpos; +} vfspack_t; +int VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread) +{ + vfspack_t *vfsp = (vfspack_t*)vfs; + int read; + + if (vfsp->currentpos - vfsp->startpos + bytestoread > vfsp->length) + bytestoread = vfsp->length - (vfsp->currentpos - vfsp->startpos + bytestoread); + if (bytestoread <= 0) + return -1; + + if (vfsp->parentpak->filepos != vfsp->currentpos) + VFS_SEEK(vfsp->parentpak->handle, vfsp->currentpos); + read = VFS_READ(vfsp->parentpak->handle, buffer, bytestoread); + vfsp->currentpos += read; + vfsp->parentpak->filepos = vfsp->currentpos; + + return read; +} +int VFSPAK_WriteBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread) +{ //not supported. + Sys_Error("Cannot write to pak files\n"); + return 0; +} +qboolean VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos) +{ + vfspack_t *vfsp = (vfspack_t*)vfs; + if (pos < 0 || pos > vfsp->length) + return false; + vfsp->currentpos = pos + vfsp->startpos; + + return true; +} +unsigned long VFSPAK_Tell (struct vfsfile_s *vfs) +{ + vfspack_t *vfsp = (vfspack_t*)vfs; + return vfsp->currentpos - vfsp->startpos; +} +unsigned long VFSPAK_GetLen (struct vfsfile_s *vfs) +{ + vfspack_t *vfsp = (vfspack_t*)vfs; + return vfsp->length; +} +void VFSPAK_Close(vfsfile_t *vfs) +{ + vfspack_t *vfsp = (vfspack_t*)vfs; + FSPAK_ClosePath(vfsp->parentpak); //tell the parent that we don't need it open any more (reference counts) + Z_Free(vfsp); //free ourselves. +} +vfsfile_t *FSPAK_OpenVFS(void *handle, flocation_t *loc, char *mode) +{ + pack_t *pack = (pack_t*)handle; + vfspack_t *vfs = Z_Malloc(sizeof(vfspack_t)); + + vfs->parentpak = ((pack_t*)handle); + vfs->parentpak->references++; + + vfs->startpos = loc->offset; + vfs->length = loc->len; + vfs->currentpos = vfs->startpos; + + vfs->funcs.Close = VFSPAK_Close; + vfs->funcs.GetLen = VFSPAK_GetLen; + vfs->funcs.ReadBytes = VFSPAK_ReadBytes; + vfs->funcs.Seek = VFSPAK_Seek; + vfs->funcs.Tell = VFSPAK_Tell; + vfs->funcs.WriteBytes = VFSPAK_WriteBytes; //not supported + + return (vfsfile_t *)vfs; +} + searchpathfuncs_t packfilefuncs = { FSPAK_PrintPath, FSPAK_ClosePath, @@ -401,7 +587,9 @@ searchpathfuncs_t packfilefuncs = { FSPAK_FLocate, FSOS_ReadFile, FSPAK_EnumerateFiles, - FSPAK_LoadPackFile + FSPAK_LoadPackFile, + NULL, + FSPAK_OpenVFS }; //====================================================================================================== @@ -432,6 +620,12 @@ typedef struct zipfile_s #ifdef HASH_FILESYSTEM hashtable_t hash; #endif + + vfsfile_t *raw; + vfsfile_t *currentfile; //our unzip.c can only handle one active file at any one time + //so we have to keep closing and switching. + //slow, but it works. most of the time we'll only have a single file open anyway. + int references; //and a reference count } zipfile_t; @@ -439,11 +633,18 @@ static void FSZIP_PrintPath(void *handle) { zipfile_t *zip = handle; - Con_Printf("%s\n", zip->filename); + if (zip->references != 1) + Con_Printf("%s (%i)\n", zip->filename, zip->references-1); + else + Con_Printf("%s\n", zip->filename); } static void FSZIP_ClosePath(void *handle) { zipfile_t *zip = handle; + + if (--zip->references > 0) + return; //not yet time + unzClose(zip->handle); if (zip->files) Z_Free(zip->files); @@ -476,7 +677,7 @@ static qboolean FSZIP_FLocate(void *handle, flocation_t *loc, char *filename, vo if (pf) { //is this a pointer to a file in this pak? if (pf < zip->files || pf >= zip->files + zip->numfiles) - return -1; //was found in a different path + return false; //was found in a different path } else { @@ -502,15 +703,15 @@ static qboolean FSZIP_FLocate(void *handle, flocation_t *loc, char *filename, vo unzLocateFileMy (zip->handle, loc->index, zip->files[loc->index].filepos); loc->offset = unzGetCurrentFileUncompressedPos(zip->handle); - if (loc->offset<0) - { //file not found, or is compressed. - *loc->rawname = '\0'; - loc->offset=0; - } +// if (loc->offset<0) +// { //file not found, or is compressed. +// *loc->rawname = '\0'; +// loc->offset=0; +// } } - return len; + return true; } - return -1; + return false; } static void FSZIP_ReadFile(void *handle, flocation_t *loc, char *buffer) @@ -559,7 +760,7 @@ Loads the header and directory, adding the files at the beginning of the list so they override previous pack files. ================= */ -static void *FSZIP_LoadZipFile (char *filename) +static void *FSZIP_LoadZipFile (vfsfile_t *packhandle, char *desc) { int i; @@ -569,17 +770,14 @@ static void *FSZIP_LoadZipFile (char *filename) unz_global_info globalinf; unz_file_info file_info; - FILE *packhandle; - if (COM_FileOpenRead (filename, &packhandle) == -1) - return NULL; - fclose(packhandle); zip = Z_Malloc(sizeof(zipfile_t)); - Q_strncpyz(zip->filename, filename, sizeof(zip->filename)); - zip->handle = unzOpen (filename); + Q_strncpyz(zip->filename, desc, sizeof(zip->filename)); + zip->handle = unzOpen ((zip->raw = packhandle)); if (!zip->handle) { - Con_TPrintf (TL_COULDNTOPENZIP, filename); + Z_Free(zip); + Con_TPrintf (TL_COULDNTOPENZIP, desc); return NULL; } @@ -597,8 +795,10 @@ static void *FSZIP_LoadZipFile (char *filename) unzGoToNextFile (zip->handle); } + zip->references = 1; + zip->currentfile = NULL; - Con_TPrintf (TL_ADDEDZIPFILE, filename, zip->numfiles); + Con_TPrintf (TL_ADDEDZIPFILE, desc, zip->numfiles); return zip; } @@ -631,6 +831,148 @@ int FSZIP_GeneratePureCRC(void *handle, int seed, int crctype) return Com_BlockChecksum(filecrcs+1, (numcrcs-1)*sizeof(int)); } +typedef struct { + vfsfile_t funcs; + + //in case we're forced away. + zipfile_t *parent; + qboolean iscompressed; + int pos; + int length; //try and optimise some things + int index; + int startpos; +} vfszip_t; +void VFSZIP_MakeActive(vfszip_t *vfsz) +{ + int i; + char buffer[8192]; //must be power of two + + if ((vfszip_t*)vfsz->parent->currentfile == vfsz) + return; //already us + if (vfsz->parent->currentfile) + unzCloseCurrentFile(vfsz->parent->handle); + + unzLocateFileMy(vfsz->parent->handle, vfsz->index, vfsz->startpos); + unzOpenCurrentFile(vfsz->parent->handle); + + + if (vfsz->pos > 0) + { + Con_DPrintf("VFSZIP_MakeActive: Shockingly inefficient\n"); + + //now we need to seek up to where we had previously gotten to. + for (i = 0; i < vfsz->pos-sizeof(buffer); i++) + unzReadCurrentFile(vfsz->parent->handle, buffer, sizeof(buffer)); + unzReadCurrentFile(vfsz->parent->handle, buffer, vfsz->pos - i); + } + + vfsz->parent->currentfile = (vfsfile_t*)vfsz; +} + +int VFSZIP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread) +{ + int read; + vfszip_t *vfsz = (vfszip_t*)file; + + if (vfsz->iscompressed) + { + VFSZIP_MakeActive(vfsz); + read = unzReadCurrentFile(vfsz->parent->handle, buffer, bytestoread); + } + else + { + if (vfsz->parent->currentfile != file) + { + unzCloseCurrentFile(vfsz->parent->handle); + VFS_SEEK(vfsz->parent->raw, vfsz->pos+vfsz->startpos); + vfsz->parent->currentfile = file; + } + read = VFS_READ(vfsz->parent->raw, buffer, bytestoread); + } + + vfsz->pos += read; + return read; +} +int VFSZIP_WriteBytes (struct vfsfile_s *file, void *buffer, int bytestoread) +{ + Sys_Error("VFSZIP_WriteBytes: Not supported\n"); + return 0; +} +qboolean VFSZIP_Seek (struct vfsfile_s *file, unsigned long pos) +{ + vfszip_t *vfsz = (vfszip_t*)file; + + //This is *really* inefficient + if (vfsz->parent->currentfile == file) + { + unzCloseCurrentFile(vfsz->parent->handle); + vfsz->parent->currentfile = NULL; //make it not us + } + + + + if (pos < 0 || pos > vfsz->length) + return false; + vfsz->pos = pos; + + return true; +} +unsigned long VFSZIP_Tell (struct vfsfile_s *file) +{ + vfszip_t *vfsz = (vfszip_t*)file; + return vfsz->pos; +} +unsigned long VFSZIP_GetLen (struct vfsfile_s *file) +{ + vfszip_t *vfsz = (vfszip_t*)file; + return vfsz->length; +} +void VFSZIP_Close (struct vfsfile_s *file) +{ + vfszip_t *vfsz = (vfszip_t*)file; + + if (vfsz->parent->currentfile == file) + vfsz->parent->currentfile = NULL; //make it not us + + FSZIP_ClosePath(vfsz->parent); + Z_Free(vfsz); +} + +vfsfile_t *FSZIP_OpenVFS(void *handle, flocation_t *loc, char *mode) +{ + int rawofs; + zipfile_t *zip = handle; + vfszip_t *vfsz; + if (strchr(mode, 'w')) + return NULL; + vfsz = Z_Malloc(sizeof(vfszip_t)); + + vfsz->parent = zip; + vfsz->index = loc->index; + vfsz->startpos = zip->files[loc->index].filepos; + vfsz->length = loc->len; + + vfsz->funcs.Close = VFSZIP_Close; + vfsz->funcs.GetLen = VFSZIP_GetLen; + vfsz->funcs.ReadBytes = VFSZIP_ReadBytes; + vfsz->funcs.Seek = VFSZIP_Seek; + vfsz->funcs.Tell = VFSZIP_Tell; + vfsz->funcs.WriteBytes = NULL; + + unzLocateFileMy(vfsz->parent->handle, vfsz->index, vfsz->startpos); + rawofs = unzGetCurrentFileUncompressedPos(zip->handle); + vfsz->iscompressed = rawofs<0; + if (!vfsz->iscompressed) + { + vfsz->startpos = rawofs; + VFS_SEEK(zip->raw, vfsz->startpos); + } + vfsz->parent->currentfile = (vfsfile_t*)vfsz; + + zip->references++; + return (vfsfile_t*)vfsz; +} + searchpathfuncs_t zipfilefuncs = { FSZIP_PrintPath, FSZIP_ClosePath, @@ -639,7 +981,8 @@ searchpathfuncs_t zipfilefuncs = { FSZIP_ReadFile, FSZIP_EnumerateFiles, FSZIP_LoadZipFile, - FSZIP_GeneratePureCRC + FSZIP_GeneratePureCRC, + FSZIP_OpenVFS }; #endif @@ -669,8 +1012,9 @@ searchpath_t *com_searchpaths; searchpath_t *com_purepaths; searchpath_t *com_base_searchpaths; // without gamedirs +static void COM_AddDataFiles(char *pathto, searchpath_t *search, char *extension, searchpathfuncs_t *funcs); -void COM_AddPathHandle(searchpathfuncs_t *funcs, void *handle, qboolean copyprotect, qboolean istemporary) +searchpath_t *COM_AddPathHandle(char *probablepath, searchpathfuncs_t *funcs, void *handle, qboolean copyprotect, qboolean istemporary) { searchpath_t *search; @@ -684,6 +1028,21 @@ void COM_AddPathHandle(searchpathfuncs_t *funcs, void *handle, qboolean copyprot com_searchpaths = search; com_fschanged = true; + + + //add any data files too +// if (loadstuff & 2) + COM_AddDataFiles(probablepath, search, "pak", &packfilefuncs);//q1/hl/h2/q2 + //pk2s never existed. +#ifdef AVAIL_ZLIB +// if (loadstuff & 4) + COM_AddDataFiles(probablepath, search, "pk3", &zipfilefuncs); //q3 + offspring +// if (loadstuff & 8) + COM_AddDataFiles(probablepath, search, "pk4", &zipfilefuncs); //q4 + //we could easily add zip, but it's friendlier not to +#endif + + return search; } /* @@ -721,11 +1080,8 @@ int COM_FileOpenRead (char *path, FILE **hndl) int COM_FileSize(char *path) { int len; - FILE *h; - len = COM_FOpenFile(path, &h); - if (len>=0) - fclose(h); - + flocation_t loc; + len = FS_FLocateFile(path, FSLFRT_LENGTH, &loc); return len; } @@ -1016,11 +1372,15 @@ int FS_FLocateFile(char *filename, FSLF_ReturnType_e returntype, flocation_t *lo { for (search = com_purepaths ; search ; search = search->nextpure) { - len = search->funcs->FindFile(search->handle, loc, filename, pf); - if (len>=0) + if (search->funcs->FindFile(search->handle, loc, filename, pf)) { if (loc) + { loc->search = search; + len = loc->len; + } + else + len = 0; goto out; } depth += (search->funcs != &osfilefuncs || returntype == FSLFRT_DEPTH_ANYPATH); @@ -1032,11 +1392,15 @@ int FS_FLocateFile(char *filename, FSLF_ReturnType_e returntype, flocation_t *lo // for (search = com_searchpaths ; search ; search = search->next) { - len = search->funcs->FindFile(search->handle, loc, filename, pf); - if (len>=0) + if (search->funcs->FindFile(search->handle, loc, filename, pf)) { if (loc) + { loc->search = search; + len = loc->len; + } + else + len = 1; goto out; } depth += (search->funcs != &osfilefuncs || returntype == FSLFRT_DEPTH_ANYPATH); @@ -1062,6 +1426,7 @@ out: else return depth; } +#if 0 int COM_FOpenLocationFILE(flocation_t *loc, FILE **file) { if (!*loc->rawname) @@ -1100,6 +1465,7 @@ int COM_FOpenLocationFILE(flocation_t *loc, FILE **file) int COM_FOpenFile(char *filename, FILE **file) { flocation_t loc; + Con_Printf("^1COM_FOpenFile is obsolete\n"); FS_FLocateFile(filename, FSLFRT_LENGTH, &loc); com_filesize = -1; @@ -1112,14 +1478,135 @@ int COM_FOpenFile(char *filename, FILE **file) *file = NULL; return com_filesize; } +/* int COM_FOpenWriteFile(char *filename, FILE **file) { COM_CreatePath(filename); *file = fopen(filename, "wb"); return !!*file; } +*/ +#endif //int COM_FOpenFile (char *filename, FILE **file) {file_from_pak=0;return COM_FOpenFile2 (filename, file, false);} //FIXME: TEMPORARY +//true if protection kicks in +qboolean Sys_PathProtection(char *pattern) +{ + if (strchr(pattern, '\\')) + { + char *s; + while(s = strchr(pattern, '\\')) + *s = '/'; + Con_Printf("Warning: \\ charactures in filename %s\n", pattern); + } + + if (strstr(pattern, "..")) + Con_Printf("Error: '..' charactures in filename %s\n", pattern); + else if (pattern[0] == '/') + Con_Printf("Error: absolute path in filename %s\n", pattern); + else if (strstr(pattern, ":")) //win32 drive seperator (or mac path seperator, but / works there and they're used to it) + Con_Printf("Error: absolute path in filename %s\n", pattern); + else + return false; + return true; +} + +vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto) +{ + char fullname[MAX_OSPATH]; + flocation_t loc; + vfsfile_t *vfs; + + //eventually, this function will be the *ONLY* way to get at files + + //blanket-bans + + if (Sys_PathProtection(filename)) + return NULL; + + switch (relativeto) + { + case FS_GAMEONLY: //OS access only, no paks + if (*com_homedir) + { + _snprintf(fullname, sizeof(fullname), "%s/%s/%s", com_homedir, gamedirfile, filename); + vfs = VFSOS_Open(fullname, mode); + if (vfs) + return vfs; + } + _snprintf(fullname, sizeof(fullname), "%s/%s/%s", com_quakedir, gamedirfile, filename); + return VFSOS_Open(fullname, mode); + case FS_GAME: + if (*com_homedir) + _snprintf(fullname, sizeof(fullname), "%s/%s/%s", com_homedir, gamedirfile, filename); + else + _snprintf(fullname, sizeof(fullname), "%s/%s/%s", com_quakedir, gamedirfile, filename); + break; + case FS_BASE: + if (*com_homedir) + { + _snprintf(fullname, sizeof(fullname), "%s/%s", com_homedir, filename); + vfs = VFSOS_Open(fullname, mode); + if (vfs) + return vfs; + } + _snprintf(fullname, sizeof(fullname), "%s/%s", com_quakedir, filename); + return VFSOS_Open(fullname, mode); + case FS_CONFIGONLY: + if (*com_homedir) + { + _snprintf(fullname, sizeof(fullname), "%s/fte/%s", com_homedir, filename); + vfs = VFSOS_Open(fullname, mode); + if (vfs) + return vfs; + } + _snprintf(fullname, sizeof(fullname), "%s/fte/%s", com_quakedir, filename); + return VFSOS_Open(fullname, mode); + default: + Sys_Error("FS_CreatePath: Bad relative path"); + break; + } + + FS_FLocateFile(filename, FSLFRT_IFFOUND, &loc); + + if (loc.search) + { + com_file_copyprotected = loc.search->copyprotected; + return loc.search->funcs->OpenVFS(loc.search->handle, &loc, mode); + } + + return NULL; +} + +void FS_Rename(char *oldf, char *newf, int relativeto) +{ + rename(oldf, newf); +} +void FS_Remove(char *fname, int relativeto) +{ + unlink (fname); +} +void FS_CreatePath(char *pname, int relativeto) +{ + char fullname[MAX_OSPATH]; + switch (relativeto) + { + case FS_GAMEONLY: + case FS_GAME: + _snprintf(fullname, sizeof(fullname), "%s/%s", com_gamedir, pname); + break; + case FS_BASE: + _snprintf(fullname, sizeof(fullname), "%s/%s", com_homedir, pname); + break; + case FS_CONFIGONLY: + _snprintf(fullname, sizeof(fullname), "%s/fte/%s", com_homedir, pname); + break; + default: + Sys_Error("FS_CreatePath: Bad relative path"); + break; + } + COM_CreatePath(fullname); +} static cache_user_t *loadcache; static qbyte *loadbuf; @@ -1135,8 +1622,8 @@ Always appends a 0 qbyte to the loaded data. */ qbyte *COM_LoadFile (char *path, int usehunk) { + vfsfile_t *f; qbyte *buf; - FILE *f; int len; char base[32]; flocation_t loc; @@ -1145,18 +1632,12 @@ qbyte *COM_LoadFile (char *path, int usehunk) if (!loc.search) return NULL; //wasn't found - if (*loc.rawname) - { -// Con_Printf("Opening %s\n", loc.rawname); - f = fopen(loc.rawname, "rb"); - if (!f) - return NULL; - fseek(f, loc.offset, SEEK_SET); - } - else - f = NULL; - com_filesize = len = loc.len; + f = loc.search->funcs->OpenVFS(loc.search->handle, &loc, "r"); + if (!f) + return NULL; + + com_filesize = len = VFS_GETLEN(f); // extract the filename base name for hunk tag COM_FileBase (path, base); @@ -1195,20 +1676,8 @@ qbyte *COM_LoadFile (char *path, int usehunk) Draw_BeginDisc (); #endif - if (f) - { - fread (buf, 1, len, f); - fclose (f); - } - else - { - if (loc.search->funcs->ReadFile) - { - loc.search->funcs->ReadFile(loc.search->handle, &loc, buf); - } - else - return NULL; - } + VFS_READ(f, buf, len); + VFS_CLOSE(f); #ifndef SERVERONLY if (qrenderer) @@ -1285,6 +1754,8 @@ void COM_FlushTempoaryPacks(void) qboolean COM_LoadMapPackFile (char *filename, int ofs) { + return false; +/* dpackheader_t header; int i; packfile_t *newfiles; @@ -1360,6 +1831,7 @@ qboolean COM_LoadMapPackFile (char *filename, int ofs) COM_AddPathHandle(&packfilefuncs, pack, true, true); return true; +*/ } #ifdef DOOMWADS @@ -1585,14 +2057,23 @@ static int COM_AddWad (char *descriptor) } #endif -static int COM_AddWildDataFiles (char *descriptor, int size, void *param) +typedef struct { + searchpathfuncs_t *funcs; + searchpath_t *parentpath; + char *parentdesc; +} wildpaks_t; + +static int COM_AddWildDataFiles (char *descriptor, int size, void *vparam) { - searchpathfuncs_t *funcs = param; + wildpaks_t *param = vparam; + vfsfile_t *vfs; + searchpathfuncs_t *funcs = param->funcs; searchpath_t *search; pack_t *pak; char pakfile[MAX_OSPATH]; + flocation_t loc; - sprintf (pakfile, "%s/%s", com_gamedir, descriptor); + sprintf (pakfile, "%s%s", param->parentdesc, descriptor); for (search = com_searchpaths; search; search = search->next) { @@ -1602,31 +2083,54 @@ static int COM_AddWildDataFiles (char *descriptor, int size, void *param) return true; //already loaded (base paths?) } - pak = funcs->OpenNew (pakfile); + search = param->parentpath; + + if (!search->funcs->FindFile(search->handle, &loc, descriptor, NULL)) + return true; //not found.. + vfs = search->funcs->OpenVFS(search->handle, &loc, "r"); + pak = funcs->OpenNew (vfs, pakfile); if (!pak) return true; - COM_AddPathHandle(funcs, pak, true, false); + + sprintf (pakfile, "%s%s/", param->parentdesc, descriptor); + COM_AddPathHandle(pakfile, funcs, pak, true, false); return true; } -static void COM_AddDataFiles(char *extension, searchpathfuncs_t *funcs) + +static void COM_AddDataFiles(char *pathto, searchpath_t *search, char *extension, searchpathfuncs_t *funcs) { + //search is the parent int i; - void *handle; + void *handle; char pakfile[MAX_OSPATH]; + vfsfile_t *vfs; + flocation_t loc; + wildpaks_t wp; for (i=0 ; ; i++) { - sprintf (pakfile, "%s/pak%i.%s", com_gamedir, i, extension); - handle = funcs->OpenNew (pakfile); + _snprintf (pakfile, sizeof(pakfile), "pak%i.%s", i, extension); + if (!search->funcs->FindFile(search->handle, &loc, pakfile, NULL)) + break; //not found.. + _snprintf (pakfile, sizeof(pakfile), "%spak%i.%s", pathto, i, extension); + vfs = search->funcs->OpenVFS(search->handle, &loc, "r"); + if (!vfs) + break; + Con_Printf("Opened %s\n", pakfile); + handle = funcs->OpenNew (vfs, pakfile); if (!handle) break; - COM_AddPathHandle(funcs, handle, true, false); + _snprintf (pakfile, sizeof(pakfile), "%spak%i.%s/", pathto, i, extension); + COM_AddPathHandle(pakfile, funcs, handle, true, false); } sprintf (pakfile, "*.%s", extension); - Sys_EnumerateFiles(com_gamedir, pakfile, COM_AddWildDataFiles, funcs); + wp.funcs = funcs; + wp.parentdesc = pathto; + wp.parentpath = search; + search->funcs->EnumerateFiles(search->handle, pakfile, COM_AddWildDataFiles, &wp); } void COM_RefreshFSCache_f(void) @@ -1671,24 +2175,9 @@ void COM_AddGameDirectory (char *dir, unsigned int loadstuff) // add the directory to the search path // - if (loadstuff & 1) - { - p = Z_Malloc(strlen(dir)+1); - strcpy(p, dir); - COM_AddPathHandle(&osfilefuncs, p, false, false); - } - -//add any data files too - if (loadstuff & 2) - COM_AddDataFiles("pak", &packfilefuncs);//q1/hl/h2/q2 - //pk2s never existed. -#ifdef AVAIL_ZLIB - if (loadstuff & 4) - COM_AddDataFiles("pk3", &zipfilefuncs); //q3 + offspring - if (loadstuff & 8) - COM_AddDataFiles("pk4", &zipfilefuncs); //q4 - //we could easily add zip, but it's friendlier not to -#endif + p = Z_Malloc(strlen(dir)+1); + strcpy(p, dir); + COM_AddPathHandle(va("%s/", dir), &osfilefuncs, p, false, false); } char *COM_NextPath (char *prevpath) @@ -2168,11 +2657,6 @@ void COM_InitFilesystem (void) Con_Printf("Using home directory \"%s\"\n", com_homedir); strcat(com_homedir, "/.fte"); - com_basedir = com_homedir; - } - else - { - com_basedir = com_quakedir; } // diff --git a/engine/common/log.c b/engine/common/log.c index 2c54cb7ae..5f516bfb9 100644 --- a/engine/common/log.c +++ b/engine/common/log.c @@ -16,7 +16,6 @@ cvar_t log_dosformat = {"log_dosformat", "0", NULL, CVAR_NOTFROMSERVER}; // externals int COM_FileSize(char *path); extern char gamedirfile[]; -extern char *com_basedir; // table of readable characters, same as ezquake char readable[256] = @@ -150,19 +149,19 @@ void Con_Log (char *s) *t = 0; - f = va("%s/%s/%s.log",com_basedir,d,f); // temp string in va() + f = va("%s/%s.log",d,f); // temp string in va() // file rotation if (log_rotate_size.value >= 4096 && log_rotate_files.value >= 1) { int x; - FILE *fi; + vfsfile_t *fi; // check file size, use x as temp - if ((fi = fopen(f, "rb"))) + if ((fi = FS_OpenVFS(f, "rb", FS_BASE))) { - x = COM_filelength(fi); - fclose(fi); + x = VFS_GETLEN(fi); + VFS_CLOSE(fi); } else x = 0; @@ -176,7 +175,7 @@ void Con_Log (char *s) // unlink file at the top of the chain _snprintf(oldf, sizeof(oldf)-1, "%s.%i", f, i); - unlink(oldf); + FS_Remove(oldf, FS_BASE); // rename files through chain for (x = i-1; x > 0; x--) @@ -185,12 +184,12 @@ void Con_Log (char *s) _snprintf(oldf, sizeof(oldf)-1, "%s.%i", f, x); // check if file exists, otherwise skip - if ((fi = fopen(oldf, "rb"))) - fclose(fi); + if ((fi = FS_OpenVFS(f, "rb", FS_BASE))) + VFS_CLOSE(fi); else continue; // skip nonexistant files - if (rename(oldf, newf)) + if (FS_Rename(oldf, newf, FS_BASE)) { // rename failed, disable log and bug out Cvar_ForceSet(&log_enable, "0"); diff --git a/engine/common/plugin.c b/engine/common/plugin.c index c857bb2a4..81b0454d3 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -104,11 +104,10 @@ cvar_t plug_loaddefault = {"plug_loaddefault", "1"}; //custom plugin builtins. typedef int (VARGS *Plug_Builtin_t)(void *offset, unsigned int mask, const long *arg); +void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags); #define PLUG_BIF_DLLONLY 1 #define PLUG_BIF_QVMONLY 2 -void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags); - #include "netinc.h" typedef struct plugin_s { diff --git a/engine/common/protocol.h b/engine/common/protocol.h index b418d5068..54afa632b 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -54,7 +54,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PEXT_SHOWPIC 0x04000000 #define PEXT_SETATTACHMENT 0x08000000 //md3 tags (needs networking, they need to lerp). //#define PEXT_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs) -//There's still a bug I need to resolve #define PEXT_CHUNKEDDOWNLOADS 0x20000000 //alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings. +#define PEXT_CHUNKEDDOWNLOADS 0x20000000 //alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings. #ifdef CSQC_DAT #define PEXT_CSQC 0x40000000 //csqc additions diff --git a/engine/common/unzip.c b/engine/common/unzip.c index 846baa5c7..0fe4d188e 100644 --- a/engine/common/unzip.c +++ b/engine/common/unzip.c @@ -94,7 +94,7 @@ typedef struct { unsigned long crc32_wait; /* crc32 we must obtain after decompress all */ unsigned long rest_read_compressed; /* number of byte to be decompressed */ unsigned long rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - FILE* file; /* io structore of the zipfile */ + vfsfile_t* file; /* io structore of the zipfile */ unsigned long compression_method; /* compression method (0==store) */ unsigned long byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ } file_in_zip_read_info_s; @@ -103,7 +103,7 @@ typedef struct { /* unz_s contain internal information about the zipfile */ typedef struct { - FILE* file; /* io structore of the zipfile */ + vfsfile_t* file; /* io structore of the zipfile */ unz_global_info gi; /* public global information */ unsigned long byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ unsigned long num_file; /* number of the current file in the zipfile*/ @@ -129,26 +129,26 @@ typedef struct { */ -local int unzlocal_getShort(FILE *fin,unsigned long *pi) { +local int unzlocal_getShort(vfsfile_t *fin,unsigned long *pi) { unsigned short c; - int err = fread(&c, 2, 1, fin); - if (err==1) { + int err = VFS_READ(fin, &c, 2); + if (err==2) { *pi = LittleShort(c); return UNZ_OK; } else { - if (ferror(fin)) return UNZ_ERRNO; + if (VFS_TELL(fin) != VFS_GETLEN(fin)) return UNZ_ERRNO; else return UNZ_EOF; } } -local int unzlocal_getLong(FILE *fin,unsigned long *pi) { +local int unzlocal_getLong(vfsfile_t *fin,unsigned long *pi) { unsigned long c; - int err = fread(&c, 4, 1, fin); - if (err==1) { + int err = VFS_READ(fin, &c, 4); + if (err==4) { *pi = LittleLong(c); return UNZ_OK; } else { - if (ferror(fin)) return UNZ_ERRNO; + if (VFS_TELL(fin) != VFS_GETLEN(fin)) return UNZ_ERRNO; else return UNZ_EOF; } } @@ -160,16 +160,14 @@ local int unzlocal_getLong(FILE *fin,unsigned long *pi) { Locate the Central directory of a zipfile (at the end, just before the global comment) */ -local unsigned long unzlocal_SearchCentralDir(FILE *fin) { +local unsigned long unzlocal_SearchCentralDir(vfsfile_t *fin) { unsigned char* buf; unsigned long uSizeFile; unsigned long uBackRead; unsigned long uMaxBack=0xffff; /* maximum size of global comment */ unsigned long uPosFound=0; - if (fseek(fin,0,SEEK_END) != 0) return 0; - - uSizeFile = ftell( fin ); + uSizeFile = VFS_GETLEN(fin); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; @@ -186,9 +184,11 @@ local unsigned long unzlocal_SearchCentralDir(FILE *fin) { uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (fseek(fin,uReadPos,SEEK_SET)!=0) break; - if (fread(buf,(unsigned int)uReadSize,1,fin)!=1) break; + if (!VFS_SEEK(fin, uReadPos)) + break; + + if (VFS_READ(fin,buf,(unsigned int)uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && @@ -212,11 +212,10 @@ local unsigned long unzlocal_SearchCentralDir(FILE *fin) { Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ -extern unzFile ZEXPORT unzOpen (const char *path) { +extern unzFile ZEXPORT unzOpen (vfsfile_t *fin) { unz_s us; unz_s *s; unsigned long central_pos,uL; - FILE * fin ; unsigned long number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ @@ -228,13 +227,13 @@ extern unzFile ZEXPORT unzOpen (const char *path) { int err=UNZ_OK; - fin=fopen(path,"rb"); + if (!fin) return NULL; central_pos = unzlocal_SearchCentralDir(fin); if (!central_pos) err=UNZ_ERRNO; - if (fseek(fin,central_pos,SEEK_SET)!=0) err=UNZ_ERRNO; + if (!VFS_SEEK(fin,central_pos)) err=UNZ_ERRNO; /* the signature, already checked */ if (unzlocal_getLong(fin,&uL)!=UNZ_OK) err=UNZ_ERRNO; @@ -266,7 +265,7 @@ extern unzFile ZEXPORT unzOpen (const char *path) { if ((central_pospfile_in_zip_read) unzCloseCurrentFile(file); - fclose(s->file); + VFS_CLOSE(s->file); TRYFREE(s); return UNZ_OK; } @@ -343,7 +342,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, if (!file) return UNZ_PARAMERROR; s=(unz_s*)file; - if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) err=UNZ_ERRNO; + if (!VFS_SEEK(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile)) err=UNZ_ERRNO; /* we check the magic */ @@ -353,7 +352,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, else if (uMagic!=0x02014b50) err=UNZ_BADZIPFILE; } - fread(&file_info, sizeof(file_info)-2*4, 1, s->file); // 2*4 is the size of 2 my vars + VFS_READ(s->file, &file_info, sizeof(file_info)-2*4); // 2*4 is the size of 2 my vars file_info.version = LittleShort(file_info.version); file_info.version_needed = LittleShort(file_info.version_needed); file_info.flag = LittleShort(file_info.flag); @@ -386,7 +385,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, else uSizeRead = fileNameBufferSize; if ((file_info.size_filename>0) && (fileNameBufferSize>0)) - if (fread(szFileName,(unsigned int)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; + if (VFS_READ(s->file, szFileName,(unsigned int)uSizeRead)!=uSizeRead) err=UNZ_ERRNO; lSeek -= uSizeRead; } @@ -399,11 +398,11 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, if (lSeek!=0) { - if (fseek(s->file,lSeek,SEEK_CUR)==0) lSeek=0; + if (VFS_SEEK(s->file, VFS_TELL(s->file)+lSeek)) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (fread(extraField,(unsigned int)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; + if (VFS_READ(s->file, extraField,(unsigned int)uSizeRead)!=uSizeRead) err=UNZ_ERRNO; lSeek += file_info.size_file_extra - uSizeRead; } else lSeek+=file_info.size_file_extra; @@ -419,11 +418,11 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, if (lSeek!=0) { - if (fseek(s->file,lSeek,SEEK_CUR)==0) lSeek=0; + if (VFS_SEEK(s->file, VFS_TELL(s->file)+lSeek)) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (fread(szComment,(unsigned int)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; + if (VFS_READ(s->file, szComment,(unsigned int)uSizeRead)!=uSizeRead) err=UNZ_ERRNO; lSeek+=file_info.size_file_comment - uSizeRead; } else lSeek+=file_info.size_file_comment; @@ -525,7 +524,7 @@ local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s *s, unsigned int *piSi *poffset_local_extrafield = 0; *psize_local_extrafield = 0; - if (fseek(s->file,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; + if (!VFS_SEEK(s->file,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile)) return UNZ_ERRNO; if (err==UNZ_OK) @@ -755,10 +754,10 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) { unsigned int uReadThis = UNZ_BUFSIZE; if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; if (!uReadThis) return UNZ_EOF; - if (fseek(pfile_in_zip_read_info->file, + if (!VFS_SEEK(pfile_in_zip_read_info->file, pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; - if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; + pfile_in_zip_read_info->byte_before_the_zipfile)) return UNZ_ERRNO; + if (VFS_READ(pfile_in_zip_read_info->file, pfile_in_zip_read_info->read_buffer,uReadThis)!=uReadThis) return UNZ_ERRNO; pfile_in_zip_read_info->pos_in_zipfile += uReadThis; pfile_in_zip_read_info->rest_read_compressed-=uReadThis; @@ -881,11 +880,11 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file,voidp buf,unsigned len) { if (!read_now) return 0; - if (fseek(pfile_in_zip_read_info->file, + if (!VFS_SEEK(pfile_in_zip_read_info->file, pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) return UNZ_ERRNO; + pfile_in_zip_read_info->pos_local_extrafield)) return UNZ_ERRNO; - if (fread(buf,(unsigned int)size_to_read,1,pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; + if (VFS_READ(pfile_in_zip_read_info->file, buf,(unsigned int)size_to_read)!=size_to_read) return UNZ_ERRNO; return (int)read_now; } @@ -939,11 +938,11 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char *szComment, unsigned uReadThis = uSizeBuf; if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; - if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) return UNZ_ERRNO; + if (!VFS_SEEK(s->file,s->central_pos+22)) return UNZ_ERRNO; if (uReadThis>0) { *szComment='\0'; - if (fread(szComment,(unsigned int)uReadThis,1,s->file)!=1) return UNZ_ERRNO; + if (VFS_READ(s->file, szComment,(unsigned int)uReadThis)!=uReadThis) return UNZ_ERRNO; } if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) *(szComment+s->gi.size_comment)='\0'; diff --git a/engine/common/unzip.h b/engine/common/unzip.h index ea80b6ba2..d3bb38083 100644 --- a/engine/common/unzip.h +++ b/engine/common/unzip.h @@ -126,7 +126,7 @@ extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, */ -extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen OF((vfsfile_t *fin)); /* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index 89949be8d..7844c285a 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -2516,47 +2516,6 @@ SOURCE=..\client\snd_mix.c # End Source File # Begin Source File -SOURCE=..\client\snd_mp3.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - SOURCE=..\client\snd_ov.c !IF "$(CFG)" == "ftequake - Win32 Release" @@ -5629,6 +5588,10 @@ SOURCE=..\sw\vid_win2.c # PROP Default_Filter "" # Begin Source File +SOURCE=..\client\cl_plugin.inc +# End Source File +# Begin Source File + SOURCE=..\common\cmd.c # End Source File # Begin Source File diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index f63666710..e5d434928 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -156,7 +156,6 @@ inline void PPL_EnableVertexArrays(void) qglDisableClientState(GL_COLOR_ARRAY); qglEnableClientState(GL_VERTEX_ARRAY); qglVertexPointer(3, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->xyz); - qglDisableClientState( GL_COLOR_ARRAY ); } inline void PPL_FlushArrays(void) { diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index f14239d06..3e97a93ab 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -143,10 +143,10 @@ qboolean GLX_InitLibrary(char *driver) gllibrary = dlopen(driver, RTLD_LAZY); else gllibrary = NULL; - if (!gllibrary) - gllibrary = dlopen("libGL.so", RTLD_LAZY); if (!gllibrary) //I hate this. gllibrary = dlopen("libGL.so.1", RTLD_LAZY); + if (!gllibrary) + gllibrary = dlopen("libGL.so", RTLD_LAZY); if (!gllibrary) return false; diff --git a/engine/http/ftpclient.c b/engine/http/ftpclient.c index 2df9acc2c..f857d5038 100644 --- a/engine/http/ftpclient.c +++ b/engine/http/ftpclient.c @@ -24,7 +24,7 @@ typedef struct FTPclientconn_s{ enum {ftp_control, ftp_listing, ftp_getting, ftp_putting} type; int stage; - IWEBFILE *f; + vfsfile_t *f; struct FTPclientconn_s *next; @@ -402,7 +402,7 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con sprintf(tempbuff, "STOR %s\r\n", con->file); con->stage = 6; con->transfered = 0; - con->transfersize = con->f->length; + con->transfersize = VFS_GETLEN(con->f); } else { diff --git a/engine/http/httpserver.c b/engine/http/httpserver.c index 07c13cb77..b308dfce2 100644 --- a/engine/http/httpserver.c +++ b/engine/http/httpserver.c @@ -73,7 +73,7 @@ void HTTP_ServerShutdown(void) typedef struct HTTP_active_connections_s { int datasock; - IWEBFILE *file; + vfsfile_t *file; struct HTTP_active_connections_s *next; http_mode_t mode; diff --git a/engine/http/iweb.h b/engine/http/iweb.h index 3f74c4385..a5fcd4dde 100644 --- a/engine/http/iweb.h +++ b/engine/http/iweb.h @@ -94,25 +94,6 @@ typedef struct { int len; } IWeb_FileGen_t; -typedef struct { -//one or the other - FILE *f; - int pos; - - IWeb_FileGen_t *bufferdata; - - int start; - int length; - int end; -} IWEBFILE; -IWEBFILE *IWebFOpenRead(char *name); //fread(name, "rb"); -IWEBFILE *IWebFOpenWrite(char *name, int append); //fopen(name, append?"ab":"wb"); -int IWebFWrite(void *data, int s1, int s2, IWEBFILE *); //fwrite -int IWebFRead(void *data, int s1, int s2, IWEBFILE *); //fwrite -void IWebFClose(IWEBFILE *); -void IWebFSeek(IWEBFILE *file, long pos, int type); -int IWebFTell(IWEBFILE *file); - #ifndef WEBSVONLY void *IWebMalloc(int size); void *IWebRealloc(void *old, int size); @@ -123,7 +104,7 @@ void IWebFree(void *mem); int IWebAuthorize(char *name, char *password); iwboolean IWebAllowUpLoad(char *fname, char *uname); -IWEBFILE *IWebGenerateFile(char *name, char *content, int contentlength); +vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength); diff --git a/engine/http/iwebiface.c b/engine/http/iwebiface.c index e5e7618bf..60347d475 100644 --- a/engine/http/iwebiface.c +++ b/engine/http/iwebiface.c @@ -375,152 +375,7 @@ void IWebRun(void) void IWebShutdown(void) { } - -IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb"); -{ - IWEBFILE *gf; - FILE *f; - - if (*name == '/') - name++; - - if (strstr(name, "..")) - return NULL; - - if ((com_filesize=COM_FOpenFile(name, &f)) >= 0) - { - IWEBFILE *ret = IWebMalloc(sizeof(IWEBFILE)); - if (!ret) - { - fclose(f); - return NULL; - } - ret->f = f; - ret->length = com_filesize; - ret->start = ftell(f); - ret->end = ret->start+ret->length; - return ret; - } - - if (com_file_copyprotected) - { - char *buffer; - IWEBFILE *ret; - - return NULL; //reject - we don't want to have this hanging over us - //big files take a LOT of memory. - - buffer = COM_LoadMallocFile(name); - if (buffer) - { - ret = IWebMalloc(sizeof(IWEBFILE) + sizeof(IWeb_FileGen_t)); - ret->bufferdata = (IWeb_FileGen_t *)(ret+1); - ret->length = ret->bufferdata->len = com_filesize; - ret->bufferdata->data = buffer; - ret->bufferdata->references=-1000; - ret->start = 0; - ret->pos = 0; - ret->end = com_filesize; - - return ret; - } - } - -#ifndef CLIENTONLY - gf = IWebGenerateFile(name, NULL, 0); - if (gf) - return gf; #endif - return NULL; -} -#endif -IWEBFILE *IWebFOpenWrite(char *name, int append) //fopen(name, append?"ab":"wb"); -{ - FILE *f; - char name2[512]; - if (strstr(name, "..")) - return NULL; - if (*name == '/') - sprintf(name2, "%s%s", com_gamedir, name); - else - sprintf(name2, "%s/%s", com_gamedir, name); - COM_CreatePath(name2); - f = fopen(name2, append?"ab":"wb"); - if (f) - { - IWEBFILE *ret = IWebMalloc(sizeof(IWEBFILE)); - if (!ret) - { - fclose(f); - return NULL; - } - ret->f = f; - ret->length = 0; - ret->start = 0; - ret->end = ret->start+ret->length; - return ret; - } - return NULL; -} -int IWebFWrite(void *data, int s1, int s2, IWEBFILE *file) //fwrite -{ - return fwrite(data, s1, s2, file->f); -} -int IWebFRead(void *data, int s1, int s2, IWEBFILE *file) //fread -{ -#ifdef PARANOID - if (s1 != 1) - Sys_Error("IWebFRead: s1 must be 1"); //should never happen. It's a debugging thing. -#endif - if (!file->f) - { - int readable; - readable = s2; - if (s1*readable + file->pos >= file->bufferdata->len) - readable = (file->length - file->pos)/s1; - memcpy(data, file->bufferdata->data+file->pos, readable*s1); - file->pos += readable*s1; - return readable; - } - - if (s2 + ftell(file->f) > file->end) //cut down the ammount readable. - s2 = file->end - ftell(file->f); - return fread(data, s1, s2, file->f); -} -void IWebFClose(IWEBFILE *file) -{ - if (file->f) - fclose(file->f); - else - { - if (file->bufferdata->references == -1000) //temp condition where buffer->data is malloc, and the buffer header is part of the file info - IWebFree(file->bufferdata->data); - else - { - file->bufferdata->references--; - } - } - IWebFree(file); -} - -void IWebFSeek(IWEBFILE *file, long pos, int type) -{ - if (!file->f) - { - file->pos = pos; - return; - } - if (type == SEEK_SET) - fseek(file->f, pos + file->start, SEEK_SET); - else - Sys_Error("IWebFSeek: Bad seek type\n"); -} -int IWebFTell(IWEBFILE *file) -{ - if (!file->f) - return file->pos; - return ftell(file->f) - file->start; -} #ifndef WEBSVONLY //replacement for Z_Malloc. It simply allocates up to a reserve ammount. diff --git a/engine/http/webgen.c b/engine/http/webgen.c index 36bc83d9a..478714bd7 100644 --- a/engine/http/webgen.c +++ b/engine/http/webgen.c @@ -324,7 +324,18 @@ IWebFile_t IWebFiles[] = { {"admin.html", IWeb_GenerateAdminFile} }; -IWEBFILE *IWebGenerateFile(char *name, char *content, int contentlength) +typedef struct { + vfsfile_t funcs; + char *buffer; + int length; + int pos; +} vfsmemory_t; + +vfsfile_t *VFSMEM_FromZMalloc(char *buffer, int length) +{ +} + +vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength) { int fnum; char *parms; @@ -381,7 +392,8 @@ IWEBFILE *IWebGenerateFile(char *name, char *content, int contentlength) IWebFiles[fnum].lastgenerationtime = -10; } - ret = IWebMalloc(sizeof(IWEBFILE)); + ret = VFSMEM_FromZMalloc + ret = IWebMalloc(sizeof(vfsfile_t)); if (!ret) { BZ_Free(IWeb_GenerationBuffer); diff --git a/engine/qclib/pr_multi.c b/engine/qclib/pr_multi.c index b7a652444..dad370405 100644 --- a/engine/qclib/pr_multi.c +++ b/engine/qclib/pr_multi.c @@ -385,7 +385,7 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable) //oh well, must be a parameter. if (*(int *)&pr_globals[pr_globaldefs16[num].ofs]) - Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs16[num].s_name, *(int *)&pr_globals[pr_globaldefs16[num].ofs]); + Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs16[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs16[num].ofs]); return; case 32: for (i=1 ; inumfielddefs; i++) diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index f5101f68c..cb50d3ba8 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -413,6 +413,7 @@ typedef struct char params[MAXCONSTANTPARAMS][MAXCONSTANTPARAMLENGTH]; int numparams; pbool used; + pbool inside; int namelen; } CompilerConstant_t; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 5bd577105..82589c216 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -1954,7 +1954,7 @@ int QCC_PR_CheakCompConst(void) // printf("%s\n", pr_token); c = pHash_Get(&compconstantstable, pr_token); - if (c) + if (c && !c->inside) { pr_file_p = oldpr_file_p+strlen(c->name); while(*pr_file_p == ' ' || *pr_file_p == '\t') @@ -2084,7 +2084,9 @@ int QCC_PR_CheakCompConst(void) else QCC_PR_IncludeChunk(c->value, false, NULL); + c->inside++; QCC_PR_Lex(); + c->inside--; return true; } diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index bcbbf3ebd..cc0dc56f1 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -3202,6 +3202,8 @@ void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals) val = PR_GetStringOfs(prinst, OFS_PARM1); var = Cvar_Get(var_name, val, 0, "QC variables"); + if (!var) + return; Cvar_Set (var, val); } @@ -5097,9 +5099,10 @@ void PF_logfrag (progfuncs_t *prinst, struct globalvars_s *pr_globals) s = va("\\%s\\%s\\\n",svs.clients[e1-1].name, svs.clients[e2-1].name); SZ_Print (&svs.log[svs.logsequence&1], s); - if (sv_fraglogfile) { - fprintf (sv_fraglogfile, s); - fflush (sv_fraglogfile); + if (sv_fraglogfile) + { + VFS_WRITE(sv_fraglogfile, s, strlen(s)); + VFS_FLUSH (sv_fraglogfile); } } @@ -5270,9 +5273,10 @@ void PF_logstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) s = PF_VarString(prinst, 0, pr_globals); - if (sv_fraglogfile) { - fprintf (sv_fraglogfile, s); - fflush (sv_fraglogfile); + if (sv_fraglogfile) + { + VFS_WRITE(sv_fraglogfile, s, strlen(s)); + VFS_FLUSH(sv_fraglogfile); } } #define PRSTR 0xa6ffb3d7 diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 899fc78aa..9518a3e77 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -457,9 +457,9 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) eval_t *eval, *e2; char name[MAX_OSPATH]; - FILE *f; + vfsfile_t *f; char mapname[MAX_QPATH]; - float time, tfloat; + float time; char str[32768]; int i,j; edict_t *ent; @@ -519,41 +519,43 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) // been used. The menu calls it before stuffing loadgame command // SCR_BeginLoadingPlaque (); - COM_FOpenFile(name, &f); + f = FS_OpenVFS(name, "rt", FS_GAME); if (!f) { Con_TPrintf (STL_ERRORCOULDNTOPEN); return false; } - fscanf (f, "%i\n", &version); + VFS_GETS(f, str, sizeof(str)); + version = atoi(str); if (version != CACHEGAME_VERSION) { - fclose (f); + VFS_CLOSE (f); Con_TPrintf (STL_BADSAVEVERSION, version, CACHEGAME_VERSION); return false; } - fscanf (f, "%s\n", str); + VFS_GETS(f, str, sizeof(str)); //comment SV_SendMessagesToAll(); - fscanf (f, "%f\n", &tfloat); - pt = tfloat; + VFS_GETS(f, str, sizeof(str)); + pt = atof(str); // this silliness is so we can load 1.06 save files, which have float skill values - fscanf (f, "%f\n", &tfloat); - current_skill = (int)(tfloat + 0.1); + VFS_GETS(f, str, sizeof(str)); + current_skill = (int)(atof(str) + 0.1); Cvar_Set (&skill, va("%i", current_skill)); - fscanf (f, "%f\n", &tfloat); - Cvar_SetValue (&deathmatch, tfloat); - fscanf (f, "%f\n", &tfloat); - Cvar_SetValue (&coop, tfloat); - fscanf (f, "%f\n", &tfloat); - Cvar_SetValue (&teamplay, tfloat); + VFS_GETS(f, str, sizeof(str)); + Cvar_SetValue (&deathmatch, atof(str)); + VFS_GETS(f, str, sizeof(str)); + Cvar_SetValue (&coop, atof(str)); + VFS_GETS(f, str, sizeof(str)); + Cvar_SetValue (&teamplay, atof(str)); - fscanf (f, "%s\n",mapname); - fscanf (f, "%f\n",&time); + VFS_GETS(f, mapname, sizeof(mapname)); + VFS_GETS(f, str, sizeof(str)); + time = atof(str); SV_SpawnServer (mapname, startspot, false, false); if (svs.gametype != gametype) @@ -563,7 +565,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) } if (sv.state != ss_active) { - fclose (f); + VFS_CLOSE (f); Con_TPrintf (STL_LOADFAILED); return false; } @@ -575,7 +577,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) for (i=0 ; iload_ents(svprogfuncs, file, 0); BZ_Free(file); @@ -645,7 +645,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) pr_global_struct->time = sv.time = time; - fclose (f); + VFS_CLOSE(f); SV_ClearWorld (); diff --git a/engine/server/server.h b/engine/server/server.h index 627605797..775282176 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -109,16 +109,16 @@ typedef struct double starttime; float physicstime; //nq clients do so much better with times sent with physics than real. int framenum; - - int lastcheck; // used by PF_checkclient - double lastchecktime; // for monster ai - qboolean paused; // are we paused? + int lastcheck; // used by PF_checkclient + double lastchecktime; // for monster ai + + qboolean paused; // are we paused? //check player/eyes models for hacks unsigned model_player_checksum; unsigned eyes_player_checksum; - + char name[64]; // file map name char mapname[256]; char modelname[MAX_QPATH]; // maps/.bsp, for model_precache[0] @@ -157,7 +157,7 @@ typedef struct sizebuf_t reliable_datagram; qbyte reliable_datagram_buf[MAX_QWMSGLEN]; - // the multicast buffer is used to send a message to a set of clients + // the multicast buffer is used to send a message to a set of clients sizebuf_t multicast; qbyte multicast_buf[MAX_NQMSGLEN]; @@ -188,7 +188,7 @@ typedef struct // the signon buffer will be sent to each client as they connect // includes the entity baselines, the static entities, etc - // large levels will have >MAX_DATAGRAM sized signons, so + // large levels will have >MAX_DATAGRAM sized signons, so // multiple signon messages are kept sizebuf_t signon; int num_signon_buffers; @@ -210,7 +210,7 @@ typedef struct qboolean mvdplayback; float realtime; - FILE *demofile; //also signifies playing the thing. + vfsfile_t *demofile; //also signifies playing the thing. int lasttype; int lastto; @@ -277,7 +277,7 @@ typedef enum cs_free, // can be reused for a new connection cs_zombie, // client has been disconnected, but don't reuse // connection for a couple seconds - cs_connected, // has been assigned to a client_t, but not in game yet + cs_connected, // has been assigned to a client_t, but not in game yet cs_spawned // client is fully in game } client_conn_state_t; @@ -359,7 +359,7 @@ typedef struct client_s float entgravity; // localized ent gravity int viewent; //fake the entity positioning. - + edict_t *edict; // EDICT_NUM(clientnum+1) #ifdef Q2SERVER q2edict_t *q2edict; // EDICT_NUM(clientnum+1) @@ -394,9 +394,9 @@ typedef struct client_s float spawninfotime; float nextservertimeupdate; -// client known data for deltas +// client known data for deltas int old_frags; - + int stats[MAX_CL_STATS]; union{ //save space @@ -408,7 +408,7 @@ typedef struct client_s q3client_frame_t *q3frames; #endif }; - FILE *download; // file being downloaded + vfsfile_t *download; // file being downloaded int downloadsize; // total bytes int downloadcount; // bytes sent @@ -442,11 +442,11 @@ typedef struct client_s qboolean upgradewarn; // did we warn him? - FILE *upload; + vfsfile_t *upload; char uploadfn[MAX_QPATH]; netadr_t snap_from; qboolean remote_snap; - + //===== NETWORK ============ int chokecount; int delta_sequence; // -1 = no compression @@ -497,7 +497,7 @@ typedef struct client_s int trustlevel; qboolean wasrecorded; //this client shouldn't get any net messages sent to them - + vec3_t specorigin; //mvds need to use a different origin from the one QC has. vec3_t specvelocity; @@ -694,7 +694,7 @@ typedef struct client_t clients[MAX_CLIENTS]; int serverflags; // episode completion information - + double last_heartbeat; int heartbeat_sequence; svstats_t stats; @@ -860,7 +860,7 @@ extern char localmodels[MAX_MODELS][5]; // inline model names for precache extern char localinfo[MAX_LOCALINFO_STRING+1]; extern int host_hunklevel; -extern FILE *sv_fraglogfile; +extern vfsfile_t *sv_fraglogfile; //=========================================================== @@ -902,7 +902,7 @@ void SV_InitOperatorCommands (void); void SV_SendServerinfo (client_t *client); void SV_ExtractFromUserinfo (client_t *cl); -void SV_SaveInfos(FILE *f); +void SV_SaveInfos(vfsfile_t *f); void Master_Heartbeat (void); @@ -1053,7 +1053,7 @@ void ClientReliableWrite_SZ(client_t *cl, void *data, int len); #define RANK_CUFFED 4 #define RANK_CRIPPLED 8 //ha ha... get speed cheaters with this!... :o) -typedef struct { //stats info +typedef struct { //stats info int kills; int deaths; float parm[NUM_SPAWN_PARMS]; @@ -1074,7 +1074,7 @@ typedef struct { //name, identity and order. typedef struct { rankheader_t h; - rankstats_t s; + rankstats_t s; } rankinfo_t; int Rank_GetPlayerID(char *name, int pwd, qboolean allowcreate, qboolean requirepasswordtobeset); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index 3253d7fa4..2df3b1135 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -21,6 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef CLIENTONLY +#ifndef INVALID_SOCKET +#define INVALID_SOCKET -1 +#endif + + + qboolean sv_allow_cheats; int fp_messages=4, fp_persecond=4, fp_secondsdead=10; @@ -187,7 +193,6 @@ void SV_Logfile_f (void) { extern cvar_t log_enable, log_dir, log_name; extern char gamedirfile[]; - extern char *com_basedir; if (log_enable.value) { @@ -206,7 +211,7 @@ void SV_Logfile_f (void) if (log_name.string[0]) f = log_name.string; - Con_Printf(va("Logging to %s/%s/%s.log.\n", com_basedir, d, f)); + Con_Printf(va("Logging to %s/%s.log.\n", d, f)); Cvar_SetValue(&log_enable, 1); } @@ -225,7 +230,7 @@ void SV_Fraglogfile_f (void) if (sv_fraglogfile) { Con_TPrintf (STL_FLOGGINGOFF); - fclose (sv_fraglogfile); + VFS_CLOSE (sv_fraglogfile); sv_fraglogfile = NULL; return; } @@ -233,16 +238,16 @@ void SV_Fraglogfile_f (void) // find an unused name for (i=0 ; i<1000 ; i++) { - sprintf (name, "%s/frag_%i.log", com_gamedir, i); - sv_fraglogfile = fopen (name, "r"); + sprintf (name, "frag_%i.log", i); + sv_fraglogfile = FS_OpenVFS(name, "r", FS_GAME); if (!sv_fraglogfile) { // can't read it, so create this one - sv_fraglogfile = fopen (name, "w"); + sv_fraglogfile = FS_OpenVFS (name, "w", FS_GAME); if (!sv_fraglogfile) i=1000; // give error break; } - fclose (sv_fraglogfile); + VFS_CLOSE (sv_fraglogfile); } if (i==1000) { @@ -1282,13 +1287,13 @@ void SV_Localinfo_f (void) Con_DPrintf("Localinfo %s changed (%s -> %s)\n", Cmd_Argv(1), old, Cmd_Argv(2)); } -void SV_SaveInfos(FILE *f) +void SV_SaveInfos(vfsfile_t *f) { - fwrite("\n", 1, 1, f); - fwrite("serverinfo * \"\"\n", 16, 1, f); + VFS_WRITE(f, "\n", 1); + VFS_WRITE(f, "serverinfo * \"\"\n", 16); Info_WriteToFile(f, svs.info, "serverinfo", CVAR_SERVERINFO); - fwrite("\n", 1, 1, f); - fwrite("localinfo * \"\"\n", 15, 1, f); + VFS_WRITE(f, "\n", 1); + VFS_WRITE(f, "localinfo * \"\"\n", 15); Info_WriteToFile(f, localinfo, "localinfo", 0); } diff --git a/engine/server/sv_demo.c b/engine/server/sv_demo.c index 03436144a..49c2cab03 100644 --- a/engine/server/sv_demo.c +++ b/engine/server/sv_demo.c @@ -16,10 +16,10 @@ void SV_WriteDemoMessage (sizebuf_t *msg) if (!svs.demorecording) return; time = LittleFloat(sv.time); - fwrite(&time, 1, sizeof(time), svdemofile); + fwrite(&time, 1, sizeof(time), svdemofile); len = LittleShort((short)msg->cursize); fwrite(&len, 1, sizeof(len), svdemofile); - fwrite(msg->data, 1, msg->cursize, svdemofile); + fwrite(msg->data, 1, msg->cursize, svdemofile); } qboolean SV_GetDemoMessage (void) @@ -68,7 +68,7 @@ qboolean SV_GetPacket (void) return false; SV_WriteDemoMessage (&net_message); - + return true; } @@ -107,7 +107,7 @@ void SV_RecordDemo_f (void) svs.demorecording = true; i = predictablerandgetseed(); - fwrite(&i, 1, sizeof(i), svdemofile); + fwrite(&i, 1, sizeof(i), svdemofile); SV_SpawnServer(mapname, NULL, false, false); } @@ -162,7 +162,7 @@ void SV_PlayDemo_f(void) fread(&i, 1, sizeof(i), svdemofile); predictablesrand(i); - + fread(&time, 1, sizeof(time), svdemofile); svdemotime = LittleFloat(time); @@ -225,9 +225,9 @@ void SV_LoadClientDemo_f (void) if (svd.demofile) { Con_Printf ("Ending old demo\n"); - fclose(svd.demofile); + VFS_CLOSE(svd.demofile); svd.demofile = NULL; - + SV_ReadMVD(); } @@ -240,10 +240,10 @@ void SV_LoadClientDemo_f (void) } demoname = Cmd_Argv(1); - com_filesize = COM_FOpenFile(demoname, &svd.demofile); - + svd.demofile = FS_OpenVFS(demoname, "rb", FS_GAME); if (!svd.demofile) //try with a different path - com_filesize = COM_FOpenFile(va("demos/%s", demoname), &svd.demofile); + svd.demofile = FS_OpenVFS(va("demos/%s", demoname), "rb", FS_GAME); + com_filesize = VFS_GETLEN(svd.demofile); if (!svd.demofile) { @@ -253,7 +253,7 @@ void SV_LoadClientDemo_f (void) if (com_filesize <= 0) { Con_Printf("Failed to open %s\n", demoname); - fclose(svd.demofile); + VFS_CLOSE(svd.demofile); svd.demofile = NULL; return; } @@ -306,7 +306,7 @@ void SV_LoadClientDemo_f (void) { svs.spawncount++; SV_BroadcastCommand ("changing\n"); //but this arrives BEFORE the serverdata - + ohc = host_client; for (i=0, host_client = svs.clients ; i svd.realtime) { - fseek(svd.demofile, ftell(svd.demofile) - sizeof(newtime), SEEK_SET); + VFS_SEEK(svd.demofile, VFS_TELL(svd.demofile) - sizeof(newtime)); return false; } else if (nextdemotime + 0.1 < svd.realtime) @@ -351,13 +351,13 @@ readnext: } else { - fread(&demotime, sizeof(demotime), 1, svd.demofile); + VFS_READ(svd.demofile, &demotime, sizeof(demotime)); demotime = LittleFloat(demotime); if (!nextdemotime) svd.realtime = nextdemotime = demotime; } -// decide if it is time to grab the next message +// decide if it is time to grab the next message if (!sv.paused) { // always grab until fully connected if (!svd.mvdplayback) { @@ -365,11 +365,11 @@ readnext: // too far back svd.realtime = demotime - 1.0; // rewind back to time - fseek(svd.demofile, ftell(svd.demofile) - sizeof(demotime), SEEK_SET); + VFS_SEEK(svd.demofile, VFS_TELL(svd.demofile) - sizeof(demotime)); return false; } else if (nextdemotime < demotime) { // rewind back to time - fseek(svd.demofile, ftell(svd.demofile) - sizeof(demotime), SEEK_SET); + VFS_SEEK(svd.demofile, VFS_TELL(svd.demofile) - sizeof(demotime)); return false; // don't need another message yet } } @@ -380,20 +380,20 @@ readnext: olddemotime = demotime; // get the msg type - if ((r = fread (&c, sizeof(c), 1, svd.demofile)) != 1) + if ((r = VFS_READ(svd.demofile, &c, sizeof(c))) != sizeof(c)) { Con_Printf ("Unexpected end of demo\n"); - fclose(svd.demofile); + VFS_CLOSE(svd.demofile); svd.demofile = NULL; return false; // SV_Error ("Unexpected end of demo"); } - + switch (c & 7) { case dem_cmd : Con_Printf ("dem_cmd not supported\n"); - fclose(svd.demofile); + VFS_CLOSE(svd.demofile); svd.demofile = NULL; return false; @@ -418,32 +418,32 @@ readnext: // fread (&emptycmd, 12, 1, svd.demofile); /* for (j = 0; j < 3; j++) cl.viewangles[i] = LittleFloat (cl.viewangles[i]); - if (cl.spectator) - Cam_TryLock (); + if (cl.spectator) + Cam_TryLock (); */ goto readnext; case dem_read: readit: // get the next message - fread (&net_message.cursize, 4, 1, svd.demofile); + VFS_READ (svd.demofile, &net_message.cursize, 4); net_message.cursize = LittleLong (net_message.cursize); - + if (!svd.mvdplayback && net_message.cursize > MAX_QWMSGLEN + 8) SV_Error ("Demo message > MAX_MSGLEN + 8"); else if (svd.mvdplayback && net_message.cursize > net_message.maxsize) SV_Error ("Demo message > MAX_UDP_PACKET"); - if ((r = fread (net_message.data, net_message.cursize, 1, svd.demofile)) != 1) + if ((r = VFS_READ(svd.demofile, net_message.data, net_message.cursize)) != net_message.cursize) SV_Error ("Corrupted demo"); /* if (svd.mvdplayback) { tracknum = Cam_TrackNum(); - + if (svd.lasttype == dem_multiple) { if (tracknum == -1) goto readnext; - + if (!(svd.lastto & (1 << (tracknum)))) goto readnext; } else if (svd.lasttype == dem_single) { @@ -455,12 +455,12 @@ readit: return true; case dem_set: - fread (&i, 4, 1, svd.demofile); - fread (&i, 4, 1, svd.demofile); + VFS_READ(svd.demofile, &i, 4); + VFS_READ(svd.demofile, &i, 4); goto readnext; case dem_multiple: - if ((r = fread (&i, 4, 1, svd.demofile)) != 1) + if ((r = VFS_READ(svd.demofile, &i, 4)) != 1) SV_Error ("Corrupted demo"); svd.lastto = LittleLong(i); @@ -579,7 +579,7 @@ qboolean SV_ReadMVD (void) if (oldsc != svs.spawncount) { - fclose(svd.demofile); + VFS_CLOSE(svd.demofile); svd.demofile = NULL; for (i=0, host_client = svs.clients ; i #ifndef CLIENTONLY #define Q2EDICT_NUM(i) (q2edict_t*)((char *)ge->edicts+i*ge->edict_size) @@ -103,6 +103,7 @@ cvar_t allow_download_root = {"allow_download_root", "0"}; cvar_t allow_download_textures = {"allow_download_textures", "1"}; cvar_t allow_download_pk3s = {"allow_download_pk3s", "1"}; cvar_t allow_download_wads = {"allow_download_wads", "1"}; +cvar_t allow_download_configs = {"allow_download_configs", "0"}; cvar_t sv_public = {"sv_public", "0"}; cvar_t sv_listen = {"sv_listen", "1"}; @@ -172,7 +173,7 @@ char cvargroup_serverinfo[] = "serverinfo variables"; char cvargroup_serverphysics[] = "server physics variables"; char cvargroup_servercontrol[] = "server control variables"; -FILE *sv_fraglogfile; +vfsfile_t *sv_fraglogfile; void SV_FixupName(char *in, char *out); void SV_AcceptClient (netadr_t adr, int userid, char *userinfo); @@ -197,7 +198,7 @@ void SV_Shutdown (void) Master_Shutdown (); if (sv_fraglogfile) { - fclose (sv_fraglogfile); + VFS_CLOSE (sv_fraglogfile); sv_fraglogfile = NULL; } @@ -435,12 +436,12 @@ void SV_DropClient (client_t *drop) if (drop->download) { - fclose (drop->download); + VFS_CLOSE (drop->download); drop->download = NULL; } if (drop->upload) { - fclose (drop->upload); + VFS_CLOSE (drop->upload); drop->upload = NULL; } *drop->uploadfn = 0; @@ -2498,16 +2499,17 @@ SV_WriteIP_f */ void SV_WriteIP_f (void) { - FILE *f; + vfsfile_t *f; char name[MAX_OSPATH]; qbyte b[4]; int i; + char *s; - sprintf (name, "%s/listip.cfg", com_gamedir); + sprintf (name, "listip.cfg"); Con_Printf ("Writing %s.\n", name); - COM_FOpenWriteFile(name, &f); + f = FS_OpenVFS(name, "wt", FS_GAME); if (!f) { Con_Printf ("Couldn't open %s\n", name); @@ -2517,10 +2519,11 @@ void SV_WriteIP_f (void) for (i=0 ; i +#include #include #include #include #include -cvar_t sys_nostdout = {"sys_nostdout","0"}; -cvar_t sys_extrasleep = {"sys_extrasleep","0"}; -cvar_t sys_maxtic = {"sys_maxtic", "100"}; +cvar_t sys_nostdout = {"sys_nostdout","0"}; +cvar_t sys_extrasleep = {"sys_extrasleep","0"}; +cvar_t sys_maxtic = {"sys_maxtic", "100"}; +cvar_t sys_colorconsole = {"sys_colorconsole", "0"}; +cvar_t sys_linebuffer = {"sys_linebuffer", "1"}; qboolean stdin_ready; + + + +struct termios orig, changes; + /* =============================================================================== @@ -172,10 +180,216 @@ void Sys_Error (const char *error, ...) va_end (argptr); printf ("Fatal error: %s\n",string); + tcsetattr(STDIN_FILENO, TCSADRAIN, &orig); + *(int*)-3 = 0; exit (1); } + + + + + + + + + + + + + +void ApplyColour(unsigned int chr) +{ + static int oldchar = 7*256; + chr = chr&~255; + + if (oldchar == chr) + return; + oldchar = chr; + switch(chr&CON_COLOURMASK) + { +//to get around wierd defaults (like a white background) we have these special hacks for colours 0 and 7 + case 0*256: + printf("\e[0;7%sm", (chr&CON_BLINKTEXT)?";5":""); + break; + case 7*256: + printf("\e[0%sm", (chr&CON_BLINKTEXT)?";5":""); + break; + default: + printf("\e[0;%i%sm", 30+((chr&CON_COLOURMASK)>>8), (chr&CON_BLINKTEXT)?";5":""); + break; + } +} + +#define putch(c) putc(c, stdout); +void Sys_PrintColouredChar(unsigned int chr) +{ + ApplyColour(chr); + + putch(chr&255); +} + +/* +================ +Sys_Printf +================ +*/ +#define MAXPRINTMSG 4096 +char coninput_text[256]; +int coninput_len; +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + + if (sys_nostdout.value) + return; + + if (1) + { + char msg[MAXPRINTMSG]; + unsigned char *t; + + va_start (argptr,fmt); + vsnprintf (msg,sizeof(msg)-1, fmt,argptr); + va_end (argptr); + + if (!sys_linebuffer.value) + { + int i; + + for (i = 0; i < coninput_len; i++) + putch('\b'); + putch('\b'); + for (i = 0; i < coninput_len; i++) + putch(' '); + putch(' '); + for (i = 0; i < coninput_len; i++) + putch('\b'); + putch('\b'); + } + + + for (t = (unsigned char*)msg; *t; t++) + { + if (*t >= 146 && *t < 156) + *t = *t - 146 + '0'; + if (*t >= 0x12 && *t <= 0x1b) + *t = *t - 0x12 + '0'; + if (*t == 143) + *t = '.'; + if (*t == 157 || *t == 158 || *t == 159) + *t = '-'; + if (*t >= 128) + *t -= 128; + if (*t == 16) + *t = '['; + if (*t == 17) + *t = ']'; + if (*t == 0x1c) + *t = 249; + } + + if (sys_colorconsole.value) + { + int ext = COLOR_WHITE<<8; + int extstack[4]; + int extstackdepth = 0; + unsigned char *str = (unsigned char*)msg; + + + while(*str) + { + if (*str == '^') + { + str++; + if (*str >= '0' && *str <= '7') + { + ext = (*str++-'0')*256 + (ext&~CON_COLOURMASK); //change colour only. + continue; + } + else if (*str == 'a') + { + str++; + ext = (ext & ~CON_2NDCHARSETTEXT) + (CON_2NDCHARSETTEXT - (ext & CON_2NDCHARSETTEXT)); + continue; + } + else if (*str == 'b') + { + str++; + ext = (ext & ~CON_BLINKTEXT) + (CON_BLINKTEXT - (ext & CON_BLINKTEXT)); + continue; + } + else if (*str == 's') //store on stack (it's great for names) + { + str++; + if (extstackdepth < sizeof(extstack)/sizeof(extstack[0])) + { + extstack[extstackdepth] = ext; + extstackdepth++; + } + continue; + } + else if (*str == 'r') //restore from stack (it's great for names) + { + str++; + if (extstackdepth) + { + extstackdepth--; + ext = extstack[extstackdepth]; + } + continue; + } + else if (*str == '^') + { + Sys_PrintColouredChar('^' + ext); + str++; + } + else + { + Sys_PrintColouredChar('^' + ext); + Sys_PrintColouredChar ((*str++) + ext); + } + continue; + } + Sys_PrintColouredChar ((*str++) + ext); + } + + ApplyColour(7*256); + } + else + { + for (t = msg; *t; t++) + { + *t &= 0x7f; + if ((*t > 128 || *t < 32) && *t != 10 && *t != 13 && *t != 9) + printf("[%02x]", *t); + else + putc(*t, stdout); + } + } + + if (!sys_linebuffer.value) + { + if (coninput_len) + printf("]%s", coninput_text); + else + putch(']'); + } + } + else + { + va_start (argptr,fmt); + vprintf (fmt,argptr); + va_end (argptr); + } + + fflush(stdout); +} + + + +#if 0 /* ================ Sys_Printf @@ -207,6 +421,7 @@ void Sys_Printf (char *fmt, ...) fflush(stdout); } +#endif /* ================ @@ -215,11 +430,70 @@ Sys_Quit */ void Sys_Quit (void) { + tcsetattr(STDIN_FILENO, TCSADRAIN, &orig); exit (0); // appkit isn't running } static int do_stdin = 1; +#if 1 +char *Sys_LineInputChar(char *line) +{ +char c; + while(*line) +{ +c = *line++; + if (c == '\r' || c == '\n') + { + coninput_text[coninput_len] = 0; + putch ('\n'); + putch (']'); + coninput_len = 0; + fflush(stdout); + return coninput_text; + } + if (c == 8) + { + if (coninput_len) + { + putch (c); + putch (' '); + putch (c); + coninput_len--; + coninput_text[coninput_len] = 0; + } + continue; + } + if (c == '\t') + { + int i; + char *s = Cmd_CompleteCommand(coninput_text, true, true, 0); + if(s) + { + for (i = 0; i < coninput_len; i++) + putch('\b'); + for (i = 0; i < coninput_len; i++) + putch(' '); + for (i = 0; i < coninput_len; i++) + putch('\b'); + + strcpy(coninput_text, s); + coninput_len = strlen(coninput_text); + printf("%s", coninput_text); + } + continue; + } + putch (c); + coninput_text[coninput_len] = c; + coninput_len++; + coninput_text[coninput_len] = 0; + if (coninput_len == sizeof(coninput_text)) + coninput_len = 0; +} + fflush(stdout); +return NULL; +} +#endif /* ================ Sys_ConsoleInput @@ -230,24 +504,51 @@ it to the host command processor */ char *Sys_ConsoleInput (void) { - static char text[256]; - int len; + char text[256]; + int len; + + if (sys_linebuffer.modified) + { + sys_linebuffer.modified = false; + changes = orig; + if (sys_linebuffer.value) + { + changes.c_lflag |= (ICANON|ECHO); + } + else + { + changes.c_lflag &= ~(ICANON|ECHO); + changes.c_cc[VTIME] = 0; + changes.c_cc[VMIN] = 1; + } + tcsetattr(STDIN_FILENO, TCSADRAIN, &changes); + } if (!stdin_ready || !do_stdin) return NULL; // the select didn't say it was ready stdin_ready = false; - len = read (0, text, sizeof(text)); - if (len == 0) { - // end of file - do_stdin = 0; - return NULL; + if (sys_linebuffer.value == 0) + { + text[0] = getc(stdin); + text[1] = 0; + len = 1; + return Sys_LineInputChar(text); } - if (len < 1) - return NULL; - text[len-1] = 0; // rip off the /n and terminate + else + { + len = read (0, text, sizeof(text)-1); + if (len == 0) { + // end of file + do_stdin = 0; + return NULL; + } + if (len < 1) + return NULL; + text[len-1] = 0; // rip off the /n and terminate - return text; + return text; + } } /* @@ -263,6 +564,9 @@ void Sys_Init (void) Cvar_Register (&sys_nostdout, "System configuration"); Cvar_Register (&sys_extrasleep, "System configuration"); Cvar_Register (&sys_maxtic, "System configuration"); + + Cvar_Register (&sys_colorconsole, "System configuration"); + Cvar_Register (&sys_linebuffer, "System configuration"); } /* @@ -277,6 +581,9 @@ int main(int argc, char *argv[]) // extern int net_socket; int j; + tcgetattr(STDIN_FILENO, &orig); + changes = orig; + memset (&parms, 0, sizeof(parms)); COM_InitArgv (argc, argv); @@ -294,12 +601,6 @@ int main(int argc, char *argv[]) parms.basedir = "."; -/* - if (Sys_FileTime ("id1/pak0.pak") != -1) - else - parms.basedir = "/raid/quake/v2"; -*/ - SV_Init (&parms); // run one frame immediately for first heartbeat diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 5a9b4ef13..93060917f 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -428,6 +428,7 @@ void ApplyColour(unsigned int chr) return; oldchar = chr; +#if 1 if (hconsoleout) { int val; @@ -462,7 +463,7 @@ void ApplyColour(unsigned int chr) SetConsoleTextAttribute(hconsoleout, val); } -#if 0 +#else //does ansi work? //no? //windows sucks. diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 7d3afcef9..721920fbc 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -1402,8 +1402,8 @@ void SV_NextChunkedDownload(int chunknum) char buffer[1024]; if (host_client->datagram.cursize + CHUNKSIZE+5+50 > host_client->datagram.maxsize) return; //choked! - fseek (host_client->download, chunknum*CHUNKSIZE, SEEK_SET); - fread (buffer, 1, CHUNKSIZE, host_client->download); + VFS_SEEK (host_client->download, chunknum*CHUNKSIZE); + VFS_READ (host_client->download, buffer, CHUNKSIZE); MSG_WriteByte(&host_client->datagram, svc_download); MSG_WriteLong(&host_client->datagram, chunknum); @@ -1446,7 +1446,7 @@ void SV_NextDownload_f (void) */ if (r > 768) r = 768; - r = fread (buffer, 1, r, host_client->download); + r = VFS_READ (host_client->download, buffer, r); ClientReliableWrite_Begin (host_client, ISQ2CLIENT(host_client)?svcq2_download:svc_download, 6+r); ClientReliableWrite_Short (host_client, r); @@ -1472,7 +1472,7 @@ void SV_NextDownload_f (void) if (host_client->downloadcount != host_client->downloadsize) return; - fclose (host_client->download); + VFS_CLOSE (host_client->download); host_client->download = NULL; } @@ -1521,7 +1521,7 @@ void SV_NextUpload (void) if (!host_client->upload) { - host_client->upload = fopen(host_client->uploadfn, "wb"); + host_client->upload = FS_OpenVFS(host_client->uploadfn, "wb", FS_GAME); if (!host_client->upload) { Sys_Printf("Can't create %s\n", host_client->uploadfn); @@ -1535,11 +1535,9 @@ void SV_NextUpload (void) OutofBandPrintf(host_client->snap_from, "Server receiving %s from %d...\n", host_client->uploadfn, host_client->userid); } - fwrite (net_message.data + msg_readcount, 1, size, host_client->upload); + VFS_WRITE (host_client->upload, net_message.data + msg_readcount, size); msg_readcount += size; -Con_DPrintf ("UPLOAD: %d received\n", size); - if (percent != 100) { ClientReliableWrite_Begin (host_client, svc_stufftext, 8); @@ -1547,7 +1545,7 @@ Con_DPrintf ("UPLOAD: %d received\n", size); } else { - fclose (host_client->upload); + VFS_CLOSE (host_client->upload); host_client->upload = NULL; Con_Printf("%s upload completed.\n", host_client->uploadfn); @@ -1582,6 +1580,7 @@ qboolean SV_AllowDownload (char *name) extern cvar_t allow_download_pk3s; extern cvar_t allow_download_wads; extern cvar_t allow_download_root; + extern cvar_t allow_download_configs; //allowed at all? if (!allow_download.value) @@ -1625,10 +1624,13 @@ qboolean SV_AllowDownload (char *name) return !!allow_download_wads.value; //pk3s. - if (!strcmp(".pk3", COM_FileExtension(name))) + if (!strcmp(".pk3", COM_FileExtension(name)) || !strcmp(".pak", COM_FileExtension(name))) if (strnicmp(name, "pak", 3)) //don't give out q3 pk3 files. return !!allow_download_pk3s.value; + if (!strcmp(".cfg", COM_FileExtension(name))) + return !!allow_download_configs.value; + //root of gamedir if (!strchr(name, '/') && !allow_download_root.value) { @@ -1678,7 +1680,7 @@ void SV_BeginDownload_f(void) if (host_client->download) { - fclose (host_client->download); + VFS_CLOSE (host_client->download); host_client->download = NULL; } @@ -1690,7 +1692,7 @@ void SV_BeginDownload_f(void) *p = (char)tolower(*p); } - host_client->downloadsize = COM_FOpenFile (name, &host_client->download); + host_client->download = FS_OpenVFS(name, "rb", FS_GAME); host_client->downloadcount = 0; if (!host_client->download @@ -1700,7 +1702,7 @@ void SV_BeginDownload_f(void) { if (host_client->download) { - fclose(host_client->download); + VFS_CLOSE(host_client->download); host_client->download = NULL; } @@ -1723,6 +1725,8 @@ void SV_BeginDownload_f(void) return; } + host_client->downloadsize = VFS_GETLEN(host_client->download); + #ifdef PEXT_CHUNKEDDOWNLOADS if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) { diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index 1be76bb9d..6d349ceda 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -29,9 +29,10 @@ #pragma comment (lib, "botlib.lib") #define FTE_GetBotLibAPI GetBotLibAPI #else + #include botlib_export_t *FTE_GetBotLibAPI( int apiVersion, botlib_import_t *import ) { - botlib_export_t *(*QDECL pGetBotLibAPI)( int apiVersion, botlib_import_t *import ); + botlib_export_t *(QDECL *pGetBotLibAPI)( int apiVersion, botlib_import_t *import ); static HINSTANCE hmod; if (!hmod)