void Host_InitVCR (quakeparms_t *parms) { int i, len, n; char *p; if (COM_CheckParm("-playback")) { if (com_argc != 2) Sys_Error("No other parameters allowed with -playback\n"); Sys_FileOpenRead("quake.vcr", &vcrFile); if (vcrFile == -1) Sys_Error("playback file not found\n"); Sys_FileRead (vcrFile, &i, sizeof(int)); if (i != VCR_SIGNATURE) Sys_Error("Invalid signature in vcr file\n"); Sys_FileRead (vcrFile, &com_argc, sizeof(int)); com_argv = malloc(com_argc * sizeof(char *)); com_argv[0] = parms->argv[0]; for (i = 0; i < com_argc; i++) { Sys_FileRead (vcrFile, &len, sizeof(int)); p = malloc(len); Sys_FileRead (vcrFile, p, len); com_argv[i+1] = p; } com_argc++; /* add one for arg[0] */ parms->argc = com_argc; parms->argv = com_argv; } if ( (n = COM_CheckParm("-record")) != 0) { vcrFile = Sys_FileOpenWrite("quake.vcr"); i = VCR_SIGNATURE; Sys_FileWrite(vcrFile, &i, sizeof(int)); i = com_argc - 1; Sys_FileWrite(vcrFile, &i, sizeof(int)); for (i = 1; i < com_argc; i++) { if (i == n) { len = 10; Sys_FileWrite(vcrFile, &len, sizeof(int)); Sys_FileWrite(vcrFile, "-playback", len); continue; } len = Q_strlen(com_argv[i]) + 1; Sys_FileWrite(vcrFile, &len, sizeof(int)); Sys_FileWrite(vcrFile, com_argv[i], len); } } }
/* ============ Image_WriteTGA -- writes RGB or RGBA data to a TGA file returns true if successful TODO: support BGRA and BGR formats (since opengl can return them, and we don't have to swap) ============ */ qboolean Image_WriteTGA (char *name, byte *data, int width, int height, int bpp, qboolean upsidedown) { int handle, i, temp, size, bytes; char pathname[MAX_OSPATH]; byte header[TARGAHEADERSIZE]; sprintf (pathname, "%s/%s", com_gamedir, name); handle = Sys_FileOpenWrite (pathname); if (handle == -1) return false; memset (&header, 0, TARGAHEADERSIZE); header[2] = 2; // uncompressed type header[12] = width&255; header[13] = width>>8; header[14] = height&255; header[15] = height>>8; header[16] = bpp; // pixel size if (upsidedown) header[17] = 0x20; // upside-down attribute bytes = bpp/8; size = width*height*bytes; // swap red and blue bytes for (i=0; i<size; i+=bytes) { temp = data[i]; data[i] = data[i+2]; data[i+2] = temp; } Sys_FileWrite (handle, &header, TARGAHEADERSIZE); Sys_FileWrite (handle, data, size); Sys_FileClose (handle); return true; }
/* ==================== CL_Record_f record <demoname> <map> [cd track] ==================== */ void CL_Record_f (void) { int c; char name[MAX_OSPATH]; int track; char forcetrack[16]; if (cmd_source != src_command) return; c = Cmd_Argc(); if (c != 2 && c != 3 && c != 4) { Con_Printf ("record <demoname> [<map> [cd track]]\n"); return; } if (strstr(Cmd_Argv(1), "..")) { Con_Printf ("Relative pathnames are not allowed.\n"); return; } if (c == 2 && cls.state == ca_connected) { Con_Printf("Can not record - already connected to server\nClient demo recording must be started before connecting\n"); return; } // write the forced cd track number, or -1 if (c == 4) { track = atoi(Cmd_Argv(3)); Con_Printf ("Forcing CD track to %i\n", cls.forcetrack); } else track = -1; sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); // // start the map up // if (c > 2) Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command); // // open the demo file // COM_DefaultExtension (name, ".dem"); Con_Printf ("recording to %s.\n", name); cls.demofile = Sys_FileOpenWrite(name); if (cls.demofile < 0) { Con_Printf ("ERROR: couldn't open demo for writing.\n"); return; } cls.forcetrack = track; sprintf(forcetrack, "%i\n", cls.forcetrack); Sys_FileWrite(cls.demofile, forcetrack, strlen(forcetrack)); cls.demorecording = true; }