1 /*
2  *  tracker/sdl/SDL_KeyTranslation.cpp
3  *
4  *  Copyright 2009 Peter Barth, Christopher O'Neill, Dale Whinham
5  *
6  *  This file is part of Milkytracker.
7  *
8  *  Milkytracker is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  Milkytracker is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with Milkytracker.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 /*
24  *  KeyTranslation.cpp
25  *  MilkyTracker
26  *
27  *  Created by Peter Barth on 19.11.05.
28  *
29  *  12/5/14 - Dale Whinham
30  *    - Port to SDL2
31  *    - Many new SDL2 scancodes added - keyboard shortcuts need thorough testing
32  *    - OSX: Command now acts as CTRL (e.g. more native-style Command-C, Command-V copy and paste in MilkyTracker edit mode)
33  *    - Attempted to fix mapping of RAlt/RCtrl (RCommand on OSX) for the FTII-style song play/pattern play shortcuts
34  *    - CapsLock now acts as noteoff-insert as per MilkyTracker manual
35  *
36  *  14/8/06 - Christopher O'Neill
37  *    - PC specific code added to toSC - allows none qwerty layouts to work
38  *    - Small fix in toSC
39  *    - Various keys added to toVK - rewritten to use array instead of select
40  */
41 
42 #include "SDL_KeyTranslation.h"
43 
toVK(const SDL_Keysym & keysym)44 pp_uint16 toVK(const SDL_Keysym& keysym)
45 {
46 	switch (keysym.sym)
47 	{
48 		// Letters
49 		case SDLK_a:	return 'A';
50 		case SDLK_b:	return 'B';
51 		case SDLK_c:	return 'C';
52 		case SDLK_d:	return 'D';
53 		case SDLK_e:	return 'E';
54 		case SDLK_f:	return 'F';
55 		case SDLK_g:	return 'G';
56 		case SDLK_h:	return 'H';
57 		case SDLK_i:	return 'I';
58 		case SDLK_j:	return 'J';
59 		case SDLK_k:	return 'K';
60 		case SDLK_l:	return 'L';
61 		case SDLK_m:	return 'M';
62 		case SDLK_n:	return 'N';
63 		case SDLK_o:	return 'O';
64 		case SDLK_p:	return 'P';
65 		case SDLK_q:	return 'Q';
66 		case SDLK_r:	return 'R';
67 		case SDLK_s:	return 'S';
68 		case SDLK_t:	return 'T';
69 		case SDLK_u:	return 'U';
70 		case SDLK_v:	return 'V';
71 		case SDLK_w:	return 'W';
72 		case SDLK_x:	return 'X';
73 		case SDLK_y:	return 'Y';
74 		case SDLK_z:	return 'Z';
75 
76 		// Numbers
77 		case SDLK_0:	return '0';
78 		case SDLK_1:	return '1';
79 		case SDLK_2:	return '2';
80 		case SDLK_3:	return '3';
81 		case SDLK_4:	return '4';
82 		case SDLK_5:	return '5';
83 		case SDLK_6:	return '6';
84 		case SDLK_7:	return '7';
85 		case SDLK_8:	return '8';
86 		case SDLK_9:	return '9';
87 
88 		// Numeric keypad
89 		case SDLK_KP_0:			return VK_NUMPAD0;
90 		case SDLK_KP_1:			return VK_NUMPAD1;
91 		case SDLK_KP_2:			return VK_NUMPAD2;
92 		case SDLK_KP_3:			return VK_NUMPAD3;
93 		case SDLK_KP_4:			return VK_NUMPAD4;
94 		case SDLK_KP_5:			return VK_NUMPAD5;
95 		case SDLK_KP_6:			return VK_NUMPAD6;
96 		case SDLK_KP_7:			return VK_NUMPAD7;
97 		case SDLK_KP_8:			return VK_NUMPAD8;
98 		case SDLK_KP_9:			return VK_NUMPAD9;
99 		case SDLK_KP_DIVIDE:	return VK_DIVIDE;
100 		case SDLK_KP_MULTIPLY:	return VK_MULTIPLY;
101 		case SDLK_KP_MINUS:		return VK_SUBTRACT;
102 		case SDLK_KP_PLUS:		return VK_ADD;
103 		case SDLK_KP_ENTER:		return VK_SEPARATOR;
104 		case SDLK_KP_PERIOD:	return VK_DECIMAL;
105 
106 		// Modifier keys
107 		case SDLK_LALT:		return VK_ALT;
108 		case SDLK_RALT:		return VK_RMENU;	// RAlt for 'play current pattern from beginning' in FastTracker II mode
109 		case SDLK_LSHIFT:	return VK_SHIFT;
110 		case SDLK_RSHIFT:	return VK_SHIFT;
111 #ifdef __APPLE__
112 		case SDLK_LGUI:		return VK_LCONTROL;	// OSX: LCommand = LCtrl for native-style Cut/Copy/Paste etc in MilkyTracker edit mode
113 		case SDLK_RGUI:		return VK_RCONTROL;	// OSX: RCommand = RCtrl for 'play song from current order' in FastTracker II edit mode
114 #else
115 		case SDLK_LCTRL:	return VK_LCONTROL;
116 		case SDLK_RCTRL:	return VK_RCONTROL;
117 #endif
118 		case SDLK_MODE:		return VK_RMENU;
119 		case SDLK_CAPSLOCK:	return VK_CAPITAL;
120 
121 		// Other non-character keys
122 		case SDLK_RETURN:		return VK_RETURN;
123 		case SDLK_TAB:			return VK_TAB;
124 		case SDLK_SPACE:		return VK_SPACE;
125 		case SDLK_ESCAPE:		return VK_ESCAPE;
126 		case SDLK_INSERT:		return VK_INSERT;
127 		case SDLK_DELETE:		return VK_DELETE;
128 		case SDLK_BACKSPACE:	return VK_BACK;
129 
130 		case SDLK_LEFT:			return VK_LEFT;
131 		case SDLK_RIGHT:		return VK_RIGHT;
132 		case SDLK_DOWN:			return VK_DOWN;
133 		case SDLK_UP:			return VK_UP;
134 
135 		case SDLK_PAGEUP:		return VK_PRIOR;
136 		case SDLK_PAGEDOWN:		return VK_NEXT;
137 		case SDLK_HOME:			return VK_HOME;
138 		case SDLK_END:			return VK_END;
139 
140 		// Function keys
141 		case SDLK_F1:	return VK_F1;
142 		case SDLK_F2:	return VK_F2;
143 		case SDLK_F3:	return VK_F3;
144 		case SDLK_F4:	return VK_F4;
145 		case SDLK_F5:	return VK_F5;
146 		case SDLK_F6:	return VK_F6;
147 		case SDLK_F7:	return VK_F7;
148 		case SDLK_F8:	return VK_F8;
149 		case SDLK_F9:	return VK_F9;
150 		case SDLK_F10:	return VK_F10;
151 		case SDLK_F11:	return VK_F11;
152 		case SDLK_F12:	return VK_F12;
153 
154 		// TODO: Check if the following are required and remove if unused
155 		case SDLK_CARET:	return 0xC0;
156 		case SDLK_PLUS:		return 0xDD;
157 		case SDLK_HASH:		return 0xDC;
158 		case SDLK_COMMA:	return 0xBC;
159 		case SDLK_PERIOD:	return 0xBF;
160 		case SDLK_MINUS:	return 0xBE;
161 		case SDLK_LESS:		return 0xE2;
162 
163 		default:			return 0;
164 	}
165 }
166 
toSC(const SDL_Keysym & keysym)167 pp_uint16 toSC(const SDL_Keysym& keysym)
168 {
169 	switch (keysym.scancode)
170 	{
171 		// Letters
172 		case SDL_SCANCODE_A:	return SC_A;
173 		case SDL_SCANCODE_B:	return SC_B;
174 		case SDL_SCANCODE_C:	return SC_C;
175 		case SDL_SCANCODE_D:	return SC_D;
176 		case SDL_SCANCODE_E:	return SC_E;
177 		case SDL_SCANCODE_F:	return SC_F;
178 		case SDL_SCANCODE_G:	return SC_G;
179 		case SDL_SCANCODE_H:	return SC_H;
180 		case SDL_SCANCODE_I:	return SC_I;
181 		case SDL_SCANCODE_J:	return SC_J;
182 		case SDL_SCANCODE_K:	return SC_K;
183 		case SDL_SCANCODE_L:	return SC_L;
184 		case SDL_SCANCODE_M:	return SC_M;
185 		case SDL_SCANCODE_N:	return SC_N;
186 		case SDL_SCANCODE_O:	return SC_O;
187 		case SDL_SCANCODE_P:	return SC_P;
188 		case SDL_SCANCODE_Q:	return SC_Q;
189 		case SDL_SCANCODE_R:	return SC_R;
190 		case SDL_SCANCODE_S:	return SC_S;
191 		case SDL_SCANCODE_T:	return SC_T;
192 		case SDL_SCANCODE_U:	return SC_U;
193 		case SDL_SCANCODE_V:	return SC_V;
194 		case SDL_SCANCODE_W:	return SC_W;
195 		case SDL_SCANCODE_X:	return SC_X;
196 		case SDL_SCANCODE_Y:	return SC_Z; // MilkyTracker scancodes are based on German
197 		case SDL_SCANCODE_Z:	return SC_Y; // keyboard layout; so Y <-> Z swap is correct here.
198 
199 		// Numbers
200 		case SDL_SCANCODE_0:	return SC_0;
201 		case SDL_SCANCODE_1:	return SC_1;
202 		case SDL_SCANCODE_2:	return SC_2;
203 		case SDL_SCANCODE_3:	return SC_3;
204 		case SDL_SCANCODE_4:	return SC_4;
205 		case SDL_SCANCODE_5:	return SC_5;
206 		case SDL_SCANCODE_6:	return SC_6;
207 		case SDL_SCANCODE_7:	return SC_7;
208 		case SDL_SCANCODE_8:	return SC_8;
209 		case SDL_SCANCODE_9:	return SC_9;
210 
211 		// Special characters
212 		case SDL_SCANCODE_MINUS:			return SC_SS;
213 		case SDL_SCANCODE_EQUALS:			return SC_TICK;
214 		case SDL_SCANCODE_LEFTBRACKET:		return SC_UE;
215 		case SDL_SCANCODE_RIGHTBRACKET:		return SC_PLUS;
216 
217 		case SDL_SCANCODE_SEMICOLON:		return SC_OE;
218 		case SDL_SCANCODE_APOSTROPHE:		return SC_AE;
219 		case SDL_SCANCODE_BACKSLASH:		return SC_SHARP;
220 
221 		case SDL_SCANCODE_NONUSBACKSLASH:	return SC_SMALLERGREATER;
222 		case SDL_SCANCODE_COMMA:			return SC_COMMA;
223 		case SDL_SCANCODE_PERIOD:			return SC_PERIOD;
224 		case SDL_SCANCODE_SLASH:			return SC_MINUS;
225 		case SDL_SCANCODE_GRAVE:			return SC_WTF;	// WTF is actually a Section sign
226 
227 		// Modifiers
228 		case SDL_SCANCODE_CAPSLOCK:			return SC_CAPSLOCK;
229 
230 		default:							return 0;
231 	}
232 }
233