1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EP_INPUT_BUTTONS_H
19 #define EP_INPUT_BUTTONS_H
20 
21 // Headers
22 #include <vector>
23 #include <array>
24 #include <cassert>
25 #include <initializer_list>
26 #include <algorithm>
27 #include <ostream>
28 
29 #include <lcf/enum_tags.h>
30 #include "flat_map.h"
31 #include "keys.h"
32 
33 /**
34  * Input namespace.
35  */
36 namespace Input {
37 	/** Input buttons list. */
38 	enum InputButton : uint8_t {
39 		UP,
40 		DOWN,
41 		LEFT,
42 		RIGHT,
43 		DECISION,
44 		CANCEL,
45 		SHIFT,
46 		N0,
47 		N1,
48 		N2,
49 		N3,
50 		N4,
51 		N5,
52 		N6,
53 		N7,
54 		N8,
55 		N9,
56 		PLUS,
57 		MINUS,
58 		MULTIPLY,
59 		DIVIDE,
60 		PERIOD,
61 		DEBUG_MENU,
62 		DEBUG_THROUGH,
63 		DEBUG_SAVE,
64 		DEBUG_ABORT_EVENT,
65 		SETTINGS_MENU,
66 		TOGGLE_FPS,
67 		TAKE_SCREENSHOT,
68 		SHOW_LOG,
69 		RESET,
70 		PAGE_UP,
71 		PAGE_DOWN,
72 		SCROLL_UP,
73 		SCROLL_DOWN,
74 		FAST_FORWARD,
75 		FAST_FORWARD_PLUS,
76 		TOGGLE_FULLSCREEN,
77 		TOGGLE_ZOOM,
78 		BUTTON_COUNT
79 	};
80 
81 	constexpr auto kButtonNames = lcf::makeEnumTags<InputButton>(
82 		"UP",
83 		"DOWN",
84 		"LEFT",
85 		"RIGHT",
86 		"DECISION",
87 		"CANCEL",
88 		"SHIFT",
89 		"N0",
90 		"N1",
91 		"N2",
92 		"N3",
93 		"N4",
94 		"N5",
95 		"N6",
96 		"N7",
97 		"N8",
98 		"N9",
99 		"PLUS",
100 		"MINUS",
101 		"MULTIPLY",
102 		"DIVIDE",
103 		"PERIOD",
104 		"DEBUG_MENU",
105 		"DEBUG_THROUGH",
106 		"DEBUG_SAVE",
107 		"DEBUG_ABORT_EVENT",
108 		"SETTINGS_MENU",
109 		"TOGGLE_FPS",
110 		"TAKE_SCREENSHOT",
111 		"SHOW_LOG",
112 		"RESET",
113 		"PAGE_UP",
114 		"PAGE_DOWN",
115 		"SCROLL_UP",
116 		"SCROLL_DOWN",
117 		"FAST_FORWARD",
118 		"FAST_FORWARD_PLUS",
119 		"TOGGLE_FULLSCREEN",
120 		"TOGGLE_ZOOM",
121 		"BUTTON_COUNT");
122 
123 	constexpr auto kButtonHelp = lcf::makeEnumTags<InputButton>(
124 		"Up Direction",
125 		"Down Direction",
126 		"Left Direction",
127 		"Right Direction",
128 		"Decision Key",
129 		"Cancel Key",
130 		"Shift Key",
131 		"Number 0",
132 		"Number 1",
133 		"Number 2",
134 		"Number 3",
135 		"Number 4",
136 		"Number 5",
137 		"Number 6",
138 		"Number 7",
139 		"Number 8",
140 		"Number 9",
141 		"Plus Key",
142 		"Minus Key",
143 		"Multiply Key",
144 		"Divide Key",
145 		"Period Key",
146 		"(Test Play) Open the debug menu",
147 		"(Test Play) Walk through walls",
148 		"(Test Play) Open the save menu",
149 		"(Test Play) Aborts current active event",
150 		"Open the settings menu",
151 		"Toggle the FPS display",
152 		"Take a screenshot",
153 		"Show the console log on the screen",
154 		"Reset to the title screen",
155 		"Page up key",
156 		"Page down key",
157 		"Scroll up key",
158 		"Scroll down key",
159 		"Fast forward key",
160 		"Fast forward plus key",
161 		"Toggle Fullscreen mode",
162 		"Toggle Window Zoom level",
163 		"Total Button Count");
164 
165 	/**
166 	 * Return true if the given button is a system button.
167 	 * System buttons are refreshed on every physical frame
168 	 * and do not affect the game logic.
169 	 */
IsSystemButton(InputButton b)170 	constexpr bool IsSystemButton(InputButton b) {
171 		switch (b) {
172 			case TOGGLE_FPS:
173 			case TAKE_SCREENSHOT:
174 			case SHOW_LOG:
175 			case TOGGLE_ZOOM:
176 			case FAST_FORWARD:
177 			case FAST_FORWARD_PLUS:
178 				return true;
179 			default:
180 				return false;
181 		}
182 	}
183 
184 	namespace Direction {
185 		enum InputDirection : uint8_t {
186 			NONE = 0,
187 			DOWNLEFT = 1,
188 			DOWN = 2,
189 			DOWNRIGHT = 3,
190 			LEFT = 4,
191 			CENTER = 5,
192 			RIGHT = 6,
193 			UPLEFT = 7,
194 			UP = 8,
195 			UPRIGHT = 9,
196 			NUM_DIRECTIONS = 10,
197 		};
198 
199 		static constexpr auto kNames = lcf::makeEnumTags<InputDirection>(
200 			"NONE",
201 			"DOWNLEFT",
202 			"DOWN",
203 			"DOWNRIGHT",
204 			"LEFT",
205 			"CENTER",
206 			"RIGHT",
207 			"UPLEFT",
208 			"UP",
209 			"UPRIGHT",
210 			"NUM_DIRECTIONS");
211 	};
212 
213 	using ButtonMappingArray = FlatUniqueMultiMap<InputButton,Keys::InputKey>;
214 
215 	/** A mapping for a button to a input key */
216 	using ButtonMapping = ButtonMappingArray::pair_type;
217 
218 	inline std::ostream& operator<<(std::ostream& os, ButtonMapping bm) {
219 		os << "{ " << kButtonNames.tag(bm.first) << ", " << Keys::kNames.tag(bm.second) << " }";
220 		return os;
221 	}
222 
223 	using DirectionMappingArray = FlatUniqueMultiMap<Direction::InputDirection, InputButton>;
224 
225 	/** A mapping for a single direction to a button */
226 	using DirectionMapping = DirectionMappingArray::pair_type;
227 
228 	inline std::ostream& operator<<(std::ostream& os, DirectionMapping dm) {
229 		os << "{ " << Direction::kNames.tag(dm.first) << ", " << kButtonNames.tag(dm.second) << " }";
230 		return os;
231 	}
232 
233 	/** Returns default button mappings */
234 	ButtonMappingArray GetDefaultButtonMappings();
235 
236 	/** Returns default direction mappings */
237 	DirectionMappingArray GetDefaultDirectionMappings();
238 }
239 
240 #endif
241