OXYGENHUB
◆ main openmsx / share / scripts / mode.tcl
3.3 KiB · Tcl · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 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
4
namespace eval mode {
5
6
## Mode switching infrastructure
7
8
variable modes_info
9
variable old_mode
10
11
proc register {name enter_proc leave_proc description} {
12
	variable modes_info
13
	dict set modes_info $name [dict create enter_proc $enter_proc \
14
	                                       leave_proc $leave_proc \
15
	                                       description $description]
16
}
17
18
proc mode_changed {name1 name2 op} {
19
	variable modes_info
20
	variable old_mode
21
22
	set new_mode $::mode
23
	if {![dict exists $modes_info $new_mode]} {
24
		# New mode doesn't exist, restore variable and give an error
25
		set ::mode $old_mode
26
		error "No such mode: $new_mode. Possible values are: [dict keys $modes_info]"
27
	}
28
29
	# Leave old mode
30
	eval [dict get $modes_info $old_mode leave_proc]
31
32
	# Enter new mode
33
	eval [dict get $modes_info $new_mode enter_proc]
34
35
	set old_mode $new_mode
36
}
37
38
39
40
## Define normal mode
41
42
proc enter_normal_mode {} {}
43
proc leave_normal_mode {} {}
44
45
register "normal" [namespace code enter_normal_mode] \
46
                  [namespace code leave_normal_mode] \
47
         "Mode that is most general purpose."
48
49
50
51
## Define tas mode
52
53
variable old_inputdelay
54
55
proc enter_tas_mode {} {
56
57
	variable old_inputdelay
58
59
	# in tas mode, set inputdelay to 0
60
	set old_inputdelay $::inputdelay
61
	set ::inputdelay 0
62
63
	if {![osd exists framecount]} {
64
		toggle_frame_counter
65
	}
66
	if {![osd exists lag_counter]} {
67
		toggle_lag_counter
68
	}
69
	if {![osd exists cursors]} {
70
		toggle_cursors
71
	}
72
	if {![osd exists movielength]} {
73
		toggle_movie_length_display
74
	}
75
76
	# load/select/save reverse slot
77
	# Note: this hides the MSX keys 'SELECT' and 'STOP'
78
	bind_default F6 tas::load_replay_slot
79
	bind_default F7 tas::open_select_slot_menu
80
	bind_default F8 tas::save_replay_slot
81
82
	# Set up frame advance/reverse
83
	bind_default END -repeat next_frame
84
	bind_default SCROLLLOCK -repeat prev_frame
85
}
86
87
proc leave_tas_mode {} {
88
89
	variable old_inputdelay
90
91
	# restore inputdelay
92
	set ::inputdelay $old_inputdelay
93
94
	if {[osd exists framecount]} {
95
		toggle_frame_counter
96
	}
97
	if {[osd exists lag_counter]} {
98
		toggle_lag_counter
99
	}
100
	if {[osd exists cursors]} {
101
		toggle_cursors
102
	}
103
	if {[osd exists movielength]} {
104
		toggle_movie_length_display
105
	}
106
107
	# Remove reverse slot stuff
108
	unbind_default F6
109
	unbind_default F7
110
	unbind_default F8
111
112
	# Remove frame advance/reverse
113
	unbind_default END
114
	unbind_default SCROLLLOCK
115
}
116
117
register "tas" [namespace code enter_tas_mode] \
118
               [namespace code leave_tas_mode] \
119
         "Mode for doing Tool Assisted Speedruns, with TAS widgets and easy ways to save replays."
120
121
122
123
# Create setting (uses info from registered modes above)
124
125
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:"
126
foreach name [lsort [dict keys $modes_info]] {
127
	append help_text "\n  $name: [dict get $modes_info $name description]"
128
}
129
130
user_setting create string mode $help_text normal
131
132
trace add variable ::mode write [namespace code mode_changed]
133
134
135
## Enter initial mode
136
137
set old_mode $::mode
138
after realtime 0 {eval [dict get $mode::modes_info $::mode enter_proc]}
139
140
}