qbism wrote:'Demo rewind' , 'record demo any time' , host_timescale, and video capture start/stop work together for a video package that can save a lot of production time. (I need to go back and look at pause_demo also!) I tried capture_start in the middle of demo playback, and the video matched the rewinds and host_timescale frame rate changes made during playback.
Racing ghosts would be fun ...
Racing ghosts is the idea of a fake player appearing that you can race against. Like let's say you want to improve on beating a level. This should work with just about any mod (I'm not going to think about cutscenes ... at least I don't think I am? Although if I am right those are cl.intermission = 3 or something).
[Who knows, this might also be useful in single player as some sort of "I'm stuck and don't know what to do".]
I peeked at the engine and I am rather confident I can make this happen and hopefully fast.
1. Will need to be able to create a ghost file from a demo. timedemo is the best candidate to copy because it tries to run through everything fast. So we will create a ghostdemo function that essentially is a timedemo except that it won't render or make sound. It will record everything to a fix-sized record with a time stamp if the player moves or the player angles change. We will do this in CL_RelinkEntities.
2. The file created will be kind of like this:
No file header or identifying data because the intent is that this will be made FROM a demo.
Map change: Type bit (0) ... MAX_QPATH (64) --- err lets use 31 instead --- of newmap. [32 chars] // Occurs at beginning of file and upon map change. If map name exceeds 31 chars, that's just too bad (how many map names are 27 or more characters long? I know of none. 26 = "maps/whatever" so we don't count "maps/" 5 chars).
Location data: Type bit (1) ... frame number (2 bytes) ... AND as unsigned int (x 100) --->cl.time, player x, y, z, pitch, yaw, roll [32 bytes] (this could be improved by adding the model index, but, eyes.mdl are hard to see and I don't want to break 32 bytes and this doesn't need to be perfect the first time).
Location data checks against player x, y, z and angles from previous frame. If no change, doesn't bother to write any data. Consider the idea of limiting writes to, say, 5 times per second. [You have no way of knowing what FPS a demo was recorded at, someone doing 600 fps ... well, the file could get needlessly large].
Not going to worry about effects or skins or other stuff. Since this file doesn't need to be compatible with anything, that can just be changed in the future if need be the case
3. Play back. We are supporting multimap demos here. Scan through the ghost file and locate the current map. The time read will be "1" (Quake time starts at 1) [we will store the offset time]. Read another record every time cl.time exceeds the current ghost time [if end of file or the map changed in the ghost file, the ghost will forever remain stationary]. Maybe interpolate the location and angles of the ghost.
4. Drawing the ghost ... Probably right before R_DrawViewModel. Maybe make a memcpy of the player entity and overwrite the origin, angles, frame and do R_DrawAliasModel.
In theory ...