From: ferreum Date: Wed, 16 Feb 2022 22:29:18 +0000 (+0100) Subject: rename input-demoseeking.cfg to demoseeking.cfg X-Git-Tag: xonotic-v0.8.5~141^2~3 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=fc4b02feeb4268813ccf03313cdc380c0ca869a3;p=xonotic%2Fxonotic-data.pk3dir.git rename input-demoseeking.cfg to demoseeking.cfg --- diff --git a/demoseeking.cfg b/demoseeking.cfg new file mode 100644 index 000000000..5ffad3a04 --- /dev/null +++ b/demoseeking.cfg @@ -0,0 +1,182 @@ +// Provides a seekdemo alias that allows fast-forwarding demo playback by a +// given time. +// +// Setup: +// +// Add "exec input-demoseeking.cfg" and the following cl_hook_gamestart_all +// hook to autoexec.cfg. If you already have a cl_hook_gamestart_all hook, add +// the quoted command to your hook, separated with a semicolon: +// +// exec input-demoseeking.cfg +// alias cl_hook_gamestart_all "demoseeking_game_started" +// +// Usage: +// - start a demo (ply/playdemo command or menu) +// - use ,. (comma and dot) keys to seek -5/+5 seconds +// - use m/ (m and slash) keys to seek -30/+30 seconds, - (minus) also +// works instead of slash +// - or use the "seekdemo " command directly +// +// Options (persisted): +// +// _demoseeking_min_speed +// Minimum seek speed. Default 1.5. +// _demoseeking_max_speed +// Maximum seek speed. Default 200. Reduce this if the client freezes too +// much while seeking. If the framerate is still high while seeking, you +// may increase this, but increasing this with low framerate is unlikely to +// improve seek performance. +// _demoseeking_bind_keys +// Whether to set default seekdemo bindings listed under "Usage" above. +// Default 1. Set to 0 to disable the bindings. +// +// Variables: +// +// _demo_is_playing +// Indicates whether a demo is currently playing. Set to 1 when playdemo +// starts a demo. +// Note: the setup above is needed to reset this reliably. +// _current_demo_name +// The name of the latest played demo. Same as the argument passed to the +// last playdemo command. If playdemo fails to start the demo (e.g. when +// the file does not exist) this variable is not updated. +// Note: the setup above is needed to reset this reliably. +// _demoseeking_is_seeking +// 1 while a seek is in progress, 0 otherwise. +// +// Extras: +// +// - The alias playdemo_hook is run when demo playback is started. +// - The alias seekdemo_hook_seek_end is run after a seek completed successfully. +// - The alias seekdemo_getseektime can be used by scripts to get the current +// playback time or seek target time. See its usage below. + +// state initialization +alias _demoseeking_init_vars "set _demoseeking_vars_loaded 1; set _demo_is_playing 0; set _current_demo_name \"\"; set _demoseeking_is_seeking 0; set _seekdemo_state idle; set _seekdemo_target 0; alias playdemo_hook \"\"; alias seekdemo_hook_seek_end" +alias _demoseeking_init_vars1 "" +_demoseeking_init_vars${_demoseeking_vars_loaded ?} + +// option initialization (persistent) +alias _demoseeking_init_options "seta _demoseeking_options_loaded 1; seta _demoseeking_min_speed 1.5; seta _demoseeking_max_speed 200; seta _demoseeking_bind_keys 1" +alias _demoseeking_init_options1 "" +_demoseeking_init_options${_demoseeking_options_loaded ?} + +// Hook into game start to reset seekdemo state. This prevents reloading the +// last demo when seekdemo is accidentally called during an actual game. +alias demoseeking_game_started "set _demo_is_playing 0; set _current_demo_name \"\"" + +// usage: seekdemo_getseektime +// Populates with the current seek target time, if seeking. If not +// seeking, populate it with the current playback time. +alias seekdemo_getseektime "_seekdemo_getseektime_get \"$1\" _seekdemo_getseektime_rpn_$_seekdemo_state" +alias _seekdemo_getseektime_get "cl_cmd rpn \"/$1\" ${$2} def" +set _seekdemo_getseektime_rpn_idle time +set _seekdemo_getseektime_rpn_starting _seekdemo_target +set _seekdemo_getseektime_rpn_seeking _seekdemo_target + +// Hook into "playdemo" command. This alias runs immediately after the actual +// "playdemo" command runs. Needed for seekdemo to restart the demo when +// seeking backwards. Runs the playdemo_hook alias when a demo file is being +// loaded. +// --- +// "cl_cmd rpn" fails while a map is loading, leaving the value of +// _demoseeking_playdemo_success untouched, which means the playdemo command +// succeeded. +alias playdemo "set _demoseeking_playdemo_success 1; cl_cmd rpn /_demoseeking_playdemo_success 0 def; _demoseeking_playdemo_check \"$1\"" +alias _demoseeking_playdemo_check "_demoseeking_playdemo_check_$_demoseeking_playdemo_success \"$1\"" +alias _demoseeking_playdemo_check_0 "echo \"playdemo failed\"" +alias _demoseeking_playdemo_check_1 "set _demo_is_playing 1; set _current_demo_name \"$1\"; playdemo_hook" + +// Hook into the "defer" command to restore state when "defer clear" is run +// while seeking. "defer clear" seems to be run by some csprogs. +// --- +// compare the first argument. when it's "clear", run _demoseeking_restore +alias defer "alias _demoseeking_deftmp_$1 \"\"; alias _demoseeking_deftmp_clear _demoseeking_restore; _demoseeking_deftmp_$1; unalias _demoseeking_deftmp_$1" +alias _demoseeking_restore "_demoseeking_restore_$_seekdemo_state" +// idle - no seek, no state to restore +alias _demoseeking_restore_idle "" +// startseek - special state where this script calls defer clear before +// starting the seek loop +alias _demoseeking_restore_startseek "" +// starting - unexpected defer clear before seek started. Restore state by +// running check for forward/backward seek. +alias _demoseeking_restore_starting "_seekdemo_start_seek" +// seeking - unexpected defer clear while seeking. Restart the loop. +alias _demoseeking_restore_seeking "_seekdemo_check_time" + +// usage: seekdemo +// Seek the playing demo by the number of seconds. May be a floating point +// number. The seek is asynchronous. When a seek is already in action, the +// target time is adjusted by the specified amount. +// When starting a seek backwards, the demo is restarted before forwarding to +// the earlier time. Does nothing when no demo is playing (_demo_is_playing). +// --- +// check if seek should start or if target time should be adjusted instead +alias seekdemo "_seekdemo_checkstate_$_seekdemo_state ${* q}" +// before starting seek, verify demo is playing first +alias _seekdemo_checkstate_idle "set _seekdemo_demo_is_playing 0; cl_cmd rpn /_seekdemo_demo_is_playing _demo_is_playing 0 != def; _seekdemo_checkstart ${* q}" +// when already seeking, only update the variable holding the target time +alias _seekdemo_checkstate_starting "_seekdemo_checkstate_seeking ${* q}" +alias _seekdemo_checkstate_seeking "rpn /_seekdemo_target _seekdemo_target \"$1\" add def" + +alias _seekdemo_checkstart "_seekdemo_checkstart_$_seekdemo_demo_is_playing ${* q}" +alias _seekdemo_checkstart_0 "echo \"no demo currently playing\"" +// start new seek +alias _seekdemo_checkstart_1 "cl_cmd rpn /_seekdemo_target time \"$1\" add def; set _demoseeking_is_seeking 1; set _seekdemo_state starting; _seekdemo_save_options; _seekdemo_start_seek" + +// check if seeking forwards or backwards +alias _seekdemo_start_seek "set _seekdemo_time_increasing err; cl_cmd rpn /_seekdemo_time_increasing _seekdemo_target time ge def; _seekdemo_check_increasing" +alias _seekdemo_check_increasing "_seekdemo_check_increasing_$_seekdemo_time_increasing" +// when seeking backwards, restart the demo and start the reload wait loop +alias _seekdemo_check_increasing_0 "playdemo \"$_current_demo_name\"; set _seekdemo_reload_success 1; cl_cmd rpn _seekdemo_reload_success 0 def; _seekdemo_check_reloading" +alias _seekdemo_check_increasing_1 "_seekdemo_check_time" +alias _seekdemo_check_increasing_err "_seekdemo_failed \"(demo not loaded?)\"" +alias _seekdemo_check_reloading "_seekdemo_check_reloading_$_seekdemo_reload_success" +alias _seekdemo_check_reloading_0 "_seekdemo_failed (playdemo)" +// launch the "defer 10" command as a fallback to stop waiting in case demo reload fails +alias _seekdemo_check_reloading_1 "defer 10 \"_seekdemo_failed (reload)\"; _seekdemo_wait_reload" + +// demo reload wait loop. "cl_cmd rpn" fails to execute until demo finished loading, leaving _demo_loaded 0 +alias _seekdemo_wait_reload "set _demo_loaded 0; cl_cmd rpn /_demo_loaded 1 def; _seekdemo_check_loaded" +alias _seekdemo_check_loaded "_seekdemo_check_loaded_$_demo_loaded" +alias _seekdemo_check_loaded_0 "defer 0.02 _seekdemo_wait_reload" +// defer clear kills the fallback "defer 10" above +alias _seekdemo_check_loaded_1 "set _seekdemo_state startseek; defer clear; set _seekdemo_state seeking; _seekdemo_check_time" + +// start of main seek loop, check if target time is reached +alias _seekdemo_check_time "set _seekdemo_seek_state failed; cl_cmd rpn _seekdemo_target time dup /_seekdemo_current_time exch def gt /_seekdemo_seek_state exch def; _seekdemo_check_continue" +alias _seekdemo_check_continue "_seekdemo_check_continue_$_seekdemo_seek_state" +alias _seekdemo_check_continue_0 "_seekdemo_leave_seek; seekdemo_hook_seek_end" +// Update options while seeking. +// - Adjust the playback speed by setting the slowmo cvar. The further the seek, the faster the playback speed. +// - Compare the speed to different speed levels to maximize performance for long seeks while reducing screen flashes for short ones. +// Then continue the loop with "defer 0", so the check is run on every rendered frame. +alias _seekdemo_check_continue_1 "set _seekdemo_speed_level failed; cl_cmd rpn _seekdemo_target time sub 10 mul _demoseeking_min_speed max _demoseeking_max_speed min dup /slowmo exch def dup 80 gt exch 2 gt add /_seekdemo_speed_level exch def; _seekdemo_set_options; defer 0 _seekdemo_check_time" +alias _seekdemo_check_continue_failed "_seekdemo_failed \"(demo ended?)\"" + +alias _seekdemo_failed "_seekdemo_leave_seek; echo SEEK FAILED ${1 ?}" + +// Update options while and after seeking and for different levels of seek speed. +// - Disable r_render only at high seek speed to maximize performance, but keep +// it enabled otherwise to avoid jarring black screens for short seeks. +// - snd_startnonloopingsounds disables all sounds that can safely be disabled, +// avoiding lots of sounds playing at the same time. +// - Other disabled options prevent side effects from fast seeking at low +// framerate, where particles and other effects accumulate and appear at the +// same time when the target has been reached. +alias _seekdemo_leave_seek "_seekdemo_restore_options; set _demoseeking_is_seeking 0; set _seekdemo_state idle; r_render 1; snd_startnonloopingsounds 1; slowmo \"$_seekdemo_sav_slowmo\"" +alias _seekdemo_set_options "_seekdemo_set_options_$_seekdemo_speed_level" +// speed level 0: below 2x playback speed, target almost reached, all options restored +alias _seekdemo_set_options_0 "r_render 1; snd_startnonloopingsounds 1; _seekdemo_restore_options" +// speed level 1: between 2x and 80x playback speed, sounds disabled, game rendered with reduced graphics +alias _seekdemo_set_options_1 "r_render 1; snd_startnonloopingsounds 0; _seekdemo_settemp_options" +// speed level 2: above 80x playback speed, sounds disabled, game not rendered to maximize performance +alias _seekdemo_set_options_2 "r_render 0; snd_startnonloopingsounds 0; _seekdemo_settemp_options" +// save/restore options for reduced settings +alias _seekdemo_save_options "set _seekdemo_sav_cl_decals \"$cl_decals\"; set _seekdemo_sav_cl_damagetext \"$cl_damagetext\"; set _seekdemo_sav_cl_particles \"$cl_particles\"; set _seekdemo_sav_cl_casings \"$cl_casings\"; set _seekdemo_sav_slowmo \"$slowmo\"" +alias _seekdemo_settemp_options "settemp cl_decals 0; settemp cl_damagetext 0; settemp cl_particles 0; settemp cl_casings 0" +alias _seekdemo_restore_options "settemp cl_decals \"$_seekdemo_sav_cl_decals\"; settemp cl_damagetext \"$_seekdemo_sav_cl_damagetext\"; settemp cl_particles \"$_seekdemo_sav_cl_particles\"; settemp cl_casings \"$_seekdemo_sav_cl_casings\"" + +alias _demoseeking_bind_keys_0 "" +alias _demoseeking_bind_keys_1 "bind , \"seekdemo -5\"; bind . \"seekdemo +5\"; bind m \"seekdemo -30\"; bind - \"seekdemo +30\"; bind / \"seekdemo +30\"" +_demoseeking_bind_keys_${_demoseeking_bind_keys ?} diff --git a/input-demoseeking.cfg b/input-demoseeking.cfg deleted file mode 100644 index 5ffad3a04..000000000 --- a/input-demoseeking.cfg +++ /dev/null @@ -1,182 +0,0 @@ -// Provides a seekdemo alias that allows fast-forwarding demo playback by a -// given time. -// -// Setup: -// -// Add "exec input-demoseeking.cfg" and the following cl_hook_gamestart_all -// hook to autoexec.cfg. If you already have a cl_hook_gamestart_all hook, add -// the quoted command to your hook, separated with a semicolon: -// -// exec input-demoseeking.cfg -// alias cl_hook_gamestart_all "demoseeking_game_started" -// -// Usage: -// - start a demo (ply/playdemo command or menu) -// - use ,. (comma and dot) keys to seek -5/+5 seconds -// - use m/ (m and slash) keys to seek -30/+30 seconds, - (minus) also -// works instead of slash -// - or use the "seekdemo " command directly -// -// Options (persisted): -// -// _demoseeking_min_speed -// Minimum seek speed. Default 1.5. -// _demoseeking_max_speed -// Maximum seek speed. Default 200. Reduce this if the client freezes too -// much while seeking. If the framerate is still high while seeking, you -// may increase this, but increasing this with low framerate is unlikely to -// improve seek performance. -// _demoseeking_bind_keys -// Whether to set default seekdemo bindings listed under "Usage" above. -// Default 1. Set to 0 to disable the bindings. -// -// Variables: -// -// _demo_is_playing -// Indicates whether a demo is currently playing. Set to 1 when playdemo -// starts a demo. -// Note: the setup above is needed to reset this reliably. -// _current_demo_name -// The name of the latest played demo. Same as the argument passed to the -// last playdemo command. If playdemo fails to start the demo (e.g. when -// the file does not exist) this variable is not updated. -// Note: the setup above is needed to reset this reliably. -// _demoseeking_is_seeking -// 1 while a seek is in progress, 0 otherwise. -// -// Extras: -// -// - The alias playdemo_hook is run when demo playback is started. -// - The alias seekdemo_hook_seek_end is run after a seek completed successfully. -// - The alias seekdemo_getseektime can be used by scripts to get the current -// playback time or seek target time. See its usage below. - -// state initialization -alias _demoseeking_init_vars "set _demoseeking_vars_loaded 1; set _demo_is_playing 0; set _current_demo_name \"\"; set _demoseeking_is_seeking 0; set _seekdemo_state idle; set _seekdemo_target 0; alias playdemo_hook \"\"; alias seekdemo_hook_seek_end" -alias _demoseeking_init_vars1 "" -_demoseeking_init_vars${_demoseeking_vars_loaded ?} - -// option initialization (persistent) -alias _demoseeking_init_options "seta _demoseeking_options_loaded 1; seta _demoseeking_min_speed 1.5; seta _demoseeking_max_speed 200; seta _demoseeking_bind_keys 1" -alias _demoseeking_init_options1 "" -_demoseeking_init_options${_demoseeking_options_loaded ?} - -// Hook into game start to reset seekdemo state. This prevents reloading the -// last demo when seekdemo is accidentally called during an actual game. -alias demoseeking_game_started "set _demo_is_playing 0; set _current_demo_name \"\"" - -// usage: seekdemo_getseektime -// Populates with the current seek target time, if seeking. If not -// seeking, populate it with the current playback time. -alias seekdemo_getseektime "_seekdemo_getseektime_get \"$1\" _seekdemo_getseektime_rpn_$_seekdemo_state" -alias _seekdemo_getseektime_get "cl_cmd rpn \"/$1\" ${$2} def" -set _seekdemo_getseektime_rpn_idle time -set _seekdemo_getseektime_rpn_starting _seekdemo_target -set _seekdemo_getseektime_rpn_seeking _seekdemo_target - -// Hook into "playdemo" command. This alias runs immediately after the actual -// "playdemo" command runs. Needed for seekdemo to restart the demo when -// seeking backwards. Runs the playdemo_hook alias when a demo file is being -// loaded. -// --- -// "cl_cmd rpn" fails while a map is loading, leaving the value of -// _demoseeking_playdemo_success untouched, which means the playdemo command -// succeeded. -alias playdemo "set _demoseeking_playdemo_success 1; cl_cmd rpn /_demoseeking_playdemo_success 0 def; _demoseeking_playdemo_check \"$1\"" -alias _demoseeking_playdemo_check "_demoseeking_playdemo_check_$_demoseeking_playdemo_success \"$1\"" -alias _demoseeking_playdemo_check_0 "echo \"playdemo failed\"" -alias _demoseeking_playdemo_check_1 "set _demo_is_playing 1; set _current_demo_name \"$1\"; playdemo_hook" - -// Hook into the "defer" command to restore state when "defer clear" is run -// while seeking. "defer clear" seems to be run by some csprogs. -// --- -// compare the first argument. when it's "clear", run _demoseeking_restore -alias defer "alias _demoseeking_deftmp_$1 \"\"; alias _demoseeking_deftmp_clear _demoseeking_restore; _demoseeking_deftmp_$1; unalias _demoseeking_deftmp_$1" -alias _demoseeking_restore "_demoseeking_restore_$_seekdemo_state" -// idle - no seek, no state to restore -alias _demoseeking_restore_idle "" -// startseek - special state where this script calls defer clear before -// starting the seek loop -alias _demoseeking_restore_startseek "" -// starting - unexpected defer clear before seek started. Restore state by -// running check for forward/backward seek. -alias _demoseeking_restore_starting "_seekdemo_start_seek" -// seeking - unexpected defer clear while seeking. Restart the loop. -alias _demoseeking_restore_seeking "_seekdemo_check_time" - -// usage: seekdemo -// Seek the playing demo by the number of seconds. May be a floating point -// number. The seek is asynchronous. When a seek is already in action, the -// target time is adjusted by the specified amount. -// When starting a seek backwards, the demo is restarted before forwarding to -// the earlier time. Does nothing when no demo is playing (_demo_is_playing). -// --- -// check if seek should start or if target time should be adjusted instead -alias seekdemo "_seekdemo_checkstate_$_seekdemo_state ${* q}" -// before starting seek, verify demo is playing first -alias _seekdemo_checkstate_idle "set _seekdemo_demo_is_playing 0; cl_cmd rpn /_seekdemo_demo_is_playing _demo_is_playing 0 != def; _seekdemo_checkstart ${* q}" -// when already seeking, only update the variable holding the target time -alias _seekdemo_checkstate_starting "_seekdemo_checkstate_seeking ${* q}" -alias _seekdemo_checkstate_seeking "rpn /_seekdemo_target _seekdemo_target \"$1\" add def" - -alias _seekdemo_checkstart "_seekdemo_checkstart_$_seekdemo_demo_is_playing ${* q}" -alias _seekdemo_checkstart_0 "echo \"no demo currently playing\"" -// start new seek -alias _seekdemo_checkstart_1 "cl_cmd rpn /_seekdemo_target time \"$1\" add def; set _demoseeking_is_seeking 1; set _seekdemo_state starting; _seekdemo_save_options; _seekdemo_start_seek" - -// check if seeking forwards or backwards -alias _seekdemo_start_seek "set _seekdemo_time_increasing err; cl_cmd rpn /_seekdemo_time_increasing _seekdemo_target time ge def; _seekdemo_check_increasing" -alias _seekdemo_check_increasing "_seekdemo_check_increasing_$_seekdemo_time_increasing" -// when seeking backwards, restart the demo and start the reload wait loop -alias _seekdemo_check_increasing_0 "playdemo \"$_current_demo_name\"; set _seekdemo_reload_success 1; cl_cmd rpn _seekdemo_reload_success 0 def; _seekdemo_check_reloading" -alias _seekdemo_check_increasing_1 "_seekdemo_check_time" -alias _seekdemo_check_increasing_err "_seekdemo_failed \"(demo not loaded?)\"" -alias _seekdemo_check_reloading "_seekdemo_check_reloading_$_seekdemo_reload_success" -alias _seekdemo_check_reloading_0 "_seekdemo_failed (playdemo)" -// launch the "defer 10" command as a fallback to stop waiting in case demo reload fails -alias _seekdemo_check_reloading_1 "defer 10 \"_seekdemo_failed (reload)\"; _seekdemo_wait_reload" - -// demo reload wait loop. "cl_cmd rpn" fails to execute until demo finished loading, leaving _demo_loaded 0 -alias _seekdemo_wait_reload "set _demo_loaded 0; cl_cmd rpn /_demo_loaded 1 def; _seekdemo_check_loaded" -alias _seekdemo_check_loaded "_seekdemo_check_loaded_$_demo_loaded" -alias _seekdemo_check_loaded_0 "defer 0.02 _seekdemo_wait_reload" -// defer clear kills the fallback "defer 10" above -alias _seekdemo_check_loaded_1 "set _seekdemo_state startseek; defer clear; set _seekdemo_state seeking; _seekdemo_check_time" - -// start of main seek loop, check if target time is reached -alias _seekdemo_check_time "set _seekdemo_seek_state failed; cl_cmd rpn _seekdemo_target time dup /_seekdemo_current_time exch def gt /_seekdemo_seek_state exch def; _seekdemo_check_continue" -alias _seekdemo_check_continue "_seekdemo_check_continue_$_seekdemo_seek_state" -alias _seekdemo_check_continue_0 "_seekdemo_leave_seek; seekdemo_hook_seek_end" -// Update options while seeking. -// - Adjust the playback speed by setting the slowmo cvar. The further the seek, the faster the playback speed. -// - Compare the speed to different speed levels to maximize performance for long seeks while reducing screen flashes for short ones. -// Then continue the loop with "defer 0", so the check is run on every rendered frame. -alias _seekdemo_check_continue_1 "set _seekdemo_speed_level failed; cl_cmd rpn _seekdemo_target time sub 10 mul _demoseeking_min_speed max _demoseeking_max_speed min dup /slowmo exch def dup 80 gt exch 2 gt add /_seekdemo_speed_level exch def; _seekdemo_set_options; defer 0 _seekdemo_check_time" -alias _seekdemo_check_continue_failed "_seekdemo_failed \"(demo ended?)\"" - -alias _seekdemo_failed "_seekdemo_leave_seek; echo SEEK FAILED ${1 ?}" - -// Update options while and after seeking and for different levels of seek speed. -// - Disable r_render only at high seek speed to maximize performance, but keep -// it enabled otherwise to avoid jarring black screens for short seeks. -// - snd_startnonloopingsounds disables all sounds that can safely be disabled, -// avoiding lots of sounds playing at the same time. -// - Other disabled options prevent side effects from fast seeking at low -// framerate, where particles and other effects accumulate and appear at the -// same time when the target has been reached. -alias _seekdemo_leave_seek "_seekdemo_restore_options; set _demoseeking_is_seeking 0; set _seekdemo_state idle; r_render 1; snd_startnonloopingsounds 1; slowmo \"$_seekdemo_sav_slowmo\"" -alias _seekdemo_set_options "_seekdemo_set_options_$_seekdemo_speed_level" -// speed level 0: below 2x playback speed, target almost reached, all options restored -alias _seekdemo_set_options_0 "r_render 1; snd_startnonloopingsounds 1; _seekdemo_restore_options" -// speed level 1: between 2x and 80x playback speed, sounds disabled, game rendered with reduced graphics -alias _seekdemo_set_options_1 "r_render 1; snd_startnonloopingsounds 0; _seekdemo_settemp_options" -// speed level 2: above 80x playback speed, sounds disabled, game not rendered to maximize performance -alias _seekdemo_set_options_2 "r_render 0; snd_startnonloopingsounds 0; _seekdemo_settemp_options" -// save/restore options for reduced settings -alias _seekdemo_save_options "set _seekdemo_sav_cl_decals \"$cl_decals\"; set _seekdemo_sav_cl_damagetext \"$cl_damagetext\"; set _seekdemo_sav_cl_particles \"$cl_particles\"; set _seekdemo_sav_cl_casings \"$cl_casings\"; set _seekdemo_sav_slowmo \"$slowmo\"" -alias _seekdemo_settemp_options "settemp cl_decals 0; settemp cl_damagetext 0; settemp cl_particles 0; settemp cl_casings 0" -alias _seekdemo_restore_options "settemp cl_decals \"$_seekdemo_sav_cl_decals\"; settemp cl_damagetext \"$_seekdemo_sav_cl_damagetext\"; settemp cl_particles \"$_seekdemo_sav_cl_particles\"; settemp cl_casings \"$_seekdemo_sav_cl_casings\"" - -alias _demoseeking_bind_keys_0 "" -alias _demoseeking_bind_keys_1 "bind , \"seekdemo -5\"; bind . \"seekdemo +5\"; bind m \"seekdemo -30\"; bind - \"seekdemo +30\"; bind / \"seekdemo +30\"" -_demoseeking_bind_keys_${_demoseeking_bind_keys ?}