mode.tcl 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # TODO mode descriptions are not yet used in any way
  2. # TODO tab completion for the mode setting, so we can remove the hardcoded mentioning of the existing modes
  3. namespace eval mode {
  4. ## Mode switching infrastructure
  5. variable modes_info
  6. variable old_mode
  7. proc register {name enter_proc leave_proc description} {
  8. variable modes_info
  9. dict set modes_info $name [dict create enter_proc $enter_proc \
  10. leave_proc $leave_proc \
  11. description $description]
  12. }
  13. proc mode_changed {name1 name2 op} {
  14. variable modes_info
  15. variable old_mode
  16. set new_mode $::mode
  17. if {![dict exists $modes_info $new_mode]} {
  18. # New mode doesn't exist, restore variable and give an error
  19. set ::mode $old_mode
  20. error "No such mode: $new_mode. Possible values are: [dict keys $modes_info]"
  21. }
  22. # Leave old mode
  23. eval [dict get $modes_info $old_mode leave_proc]
  24. # Enter new mode
  25. eval [dict get $modes_info $new_mode enter_proc]
  26. set old_mode $new_mode
  27. }
  28. ## Define normal mode
  29. proc enter_normal_mode {} {}
  30. proc leave_normal_mode {} {}
  31. register "normal" [namespace code enter_normal_mode] \
  32. [namespace code leave_normal_mode] \
  33. "Mode that is most general purpose."
  34. ## Define tas mode
  35. variable old_inputdelay
  36. variable old_reversebar_fadeout_time
  37. proc enter_tas_mode {} {
  38. variable old_inputdelay
  39. variable old_reversebar_fadeout_time
  40. # in tas mode, set inputdelay to 0
  41. set old_inputdelay $::inputdelay
  42. set ::inputdelay 0
  43. # in tas mode, do not fadeout reverse bar
  44. set old_reversebar_fadeout_time $::reversebar_fadeout_time
  45. set ::reversebar_fadeout_time 0
  46. if {![osd exists framecount]} {
  47. toggle_frame_counter
  48. }
  49. if {![osd exists lag_counter]} {
  50. toggle_lag_counter
  51. }
  52. if {![osd exists cursors]} {
  53. toggle_cursors
  54. }
  55. if {![osd exists movielength]} {
  56. toggle_movie_length_display
  57. }
  58. reverse_widgets::enable_reversebar false
  59. # load/select/save reverse slot
  60. # Note: this hides the MSX keys 'SELECT' and 'STOP'
  61. bind_default F6 tas::load_replay_slot
  62. bind_default F7 tas::open_select_slot_menu
  63. bind_default F8 tas::save_replay_slot
  64. # Set up frame advance/reverse
  65. bind_default END -repeat next_frame
  66. bind_default SCROLLLOCK -repeat prev_frame
  67. }
  68. proc leave_tas_mode {} {
  69. variable old_inputdelay
  70. variable old_reversebar_fadeout_time
  71. # restore inputdelay
  72. set ::inputdelay $old_inputdelay
  73. # restore reversebar_fadeout_time
  74. set ::reversebar_fadeout_time $old_reversebar_fadeout_time
  75. if {[osd exists framecount]} {
  76. toggle_frame_counter
  77. }
  78. if {[osd exists lag_counter]} {
  79. toggle_lag_counter
  80. }
  81. if {[osd exists cursors]} {
  82. toggle_cursors
  83. }
  84. if {[osd exists movielength]} {
  85. toggle_movie_length_display
  86. }
  87. # Leave reverse enabled, including bar
  88. # Remove reverse slot stuff
  89. unbind_default F6
  90. unbind_default F7
  91. unbind_default F8
  92. # Remove frame advance/reverse
  93. unbind_default END
  94. unbind_default SCROLLLOCK
  95. }
  96. register "tas" [namespace code enter_tas_mode] \
  97. [namespace code leave_tas_mode] \
  98. "Mode for doing Tool Assisted Speedruns, with TAS widgets and easy ways to save replays."
  99. # Create setting (uses info from registered modes above)
  100. set help_text "This setting switches between different openMSX modes. A mode is a set of settings (mostly keybindings, but also OSD widgets that are activated) that are most suitable for a certain task. Currently these modes exist:"
  101. foreach name [lsort [dict keys $modes_info]] {
  102. append help_text "\n $name: [dict get $modes_info $name description]"
  103. }
  104. user_setting create string mode $help_text normal
  105. trace add variable ::mode write [namespace code mode_changed]
  106. ## Enter initial mode
  107. set old_mode $::mode
  108. after realtime 0 {eval [dict get $mode::modes_info $::mode enter_proc]}
  109. }