1 /*
2  * cfg_control.c - keyboard and joystick configuration data
3  *
4  * $Id: cfg_control.c,v 1.15 2006/03/28 11:41:19 fzago Exp $
5  *
6  * Program XBLAST
7  * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published
11  * by the Free Software Foundation; either version 2; or (at your option)
12  * any later version
13  *
14  * This program is distributed in the hope that it will be entertaining,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.
21  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #include "xblast.h"
25 
26 /*
27  * local macros
28  */
29 #define NUM_GAME_KEYS     (10+10)	//chat
30 #define NUM_XBLAST_KEYS    3
31 
32 /*
33  * local variables
34  */
35 static DBRoot *dbControl = NULL;
36 
37 /* conversion control to event type */
38 const XBEventCode keyEventType[NUM_KEYB_CONTROLS] = {
39 	XBE_KEYB_1, XBE_KEYB_2,
40 };
41 
42 /* menu key init table */
43 static CFGKeyTable menuKeyTable[] = {
44 	{"Tab", XBE_MENU, XBMK_NEXT},
45 	{"BackSpace", XBE_MENU, XBMK_PREV},
46 	{"Up", XBE_MENU, XBMK_UP},
47 	{"Down", XBE_MENU, XBMK_DOWN},
48 	{"Left", XBE_MENU, XBMK_LEFT},
49 	{"Right", XBE_MENU, XBMK_RIGHT},
50 	{"space", XBE_MENU, XBMK_SELECT},
51 	{"Return", XBE_MENU, XBMK_DEFAULT},
52 	{"Escape", XBE_MENU, XBMK_ABORT},
53 	/* end of data */
54 	{NULL, XBE_NONE, XBMK_NONE},
55 };
56 
57 /* game control keys */
58 static CFGKeyTable xblastKeyTable[] = {
59 	{"Escape", XBE_XBLAST, XBXK_EXIT},
60 	{NULL, XBE_NONE, XBXK_NONE},
61 };
62 
63 /* fixed chat control keys */
64 static CFGKeyTable chatKeyTable[] = {
65 	{"Escape", XBE_CHAT, XBCE_ESCAPE,},
66 	{"BackSpace", XBE_CHAT, XBCE_BACK},
67 	{"Return", XBE_CHAT, XBCE_ENTER},
68 	{NULL, XBE_NONE, XBCE_NONE},
69 };
70 
71 /*
72  * set default config keyboard config (left side)
73  */
74 static void
SetDefaultLeftKeyboard(CFGControlKeyboard * cfg)75 SetDefaultLeftKeyboard (CFGControlKeyboard * cfg)
76 {
77 	assert (NULL != cfg);
78 
79 	cfg->keyUp = GUI_StringToAtom ("T");
80 	cfg->keyLeft = GUI_StringToAtom ("F");
81 	cfg->keyDown = GUI_StringToAtom ("B");
82 	cfg->keyRight = GUI_StringToAtom ("H");
83 	cfg->keyStop = GUI_StringToAtom ("G");
84 	cfg->keyBomb = GUI_StringToAtom ("space");
85 	cfg->keySpecial = GUI_StringToAtom ("Tab");
86 	cfg->keyPause = GUI_StringToAtom ("P");
87 	cfg->keyAbort = GUI_StringToAtom ("A");
88 	cfg->keyAbortCancel = GUI_StringToAtom ("Z");
89 	/* Skywalker */
90 	cfg->keyLaola = GUI_StringToAtom ("1");
91 	cfg->keyLooser = GUI_StringToAtom ("2");
92 	cfg->keyBot = GUI_StringToAtom ("3");
93 	cfg->keyChatStart = GUI_StringToAtom ("4");
94 	cfg->keyChatSend = GUI_StringToAtom ("5");
95 	cfg->keyChatCancel = GUI_StringToAtom ("6");
96 	cfg->keyChatChangeReceiver = GUI_StringToAtom ("7");
97 	/* */
98 }								/* SetDefaultLeftKeyboard */
99 
100 /*
101  * set default config keyboard config (left side)
102  */
103 static void
SetDefaultRightKeyboard(CFGControlKeyboard * cfg)104 SetDefaultRightKeyboard (CFGControlKeyboard * cfg)
105 {
106 	assert (NULL != cfg);
107 
108 	cfg->keyUp = GUI_StringToAtom ("KP_8");
109 	cfg->keyLeft = GUI_StringToAtom ("KP_4");
110 	cfg->keyDown = GUI_StringToAtom ("KP_2");
111 	cfg->keyRight = GUI_StringToAtom ("KP_6");
112 	cfg->keyStop = GUI_StringToAtom ("KP_5");
113 	cfg->keyBomb = GUI_StringToAtom ("KP_0");
114 	cfg->keySpecial = GUI_StringToAtom ("Return");
115 	cfg->keyPause = GUI_StringToAtom ("KP_Subtract");
116 	cfg->keyAbort = GUI_StringToAtom ("KP_Multiply");
117 	cfg->keyAbortCancel = GUI_StringToAtom ("KP_Divide");
118 	/* Skywalker */
119 	cfg->keyLaola = GUI_StringToAtom ("F3");
120 	cfg->keyLooser = GUI_StringToAtom ("F4");
121 	cfg->keyBot = GUI_StringToAtom ("F5");
122 	cfg->keyChatStart = GUI_StringToAtom ("F6");
123 	cfg->keyChatSend = GUI_StringToAtom ("F7");
124 	cfg->keyChatCancel = GUI_StringToAtom ("F8");
125 	cfg->keyChatChangeReceiver = GUI_StringToAtom ("F9");
126 	/* */
127 }								/* SetDefaultLeftKeyboard */
128 
129 /*
130  * get atom for control type
131  */
132 static XBAtom
AtomType(XBEventCode type)133 AtomType (XBEventCode type)
134 {
135 	switch (type) {
136 	case XBE_KEYB_1:
137 		return atomRightKeyboard;
138 	case XBE_KEYB_2:
139 		return atomLeftKeyboard;
140 	default:
141 		return ATOM_INVALID;
142 	}
143 }								/* AtomType */
144 
145 /*
146  * store single key entry
147  */
148 static void
StoreEntry(DBSection * section,XBAtom atomEntry,XBAtom atomValue)149 StoreEntry (DBSection * section, XBAtom atomEntry, XBAtom atomValue)
150 {
151 	if (ATOM_INVALID != atomValue) {
152 		DB_CreateEntryString (section, atomEntry, GUI_AtomToString (atomValue));
153 	}
154 	else {
155 		DB_DeleteEntry (section, atomEntry);
156 	}
157 }								/* StoreEntry */
158 
159 /*
160  * store control config
161  */
162 void
StoreControlKeyboard(XBEventCode type,const CFGControlKeyboard * cfg)163 StoreControlKeyboard (XBEventCode type, const CFGControlKeyboard * cfg)
164 {
165 	XBAtom atom;
166 	DBSection *section;
167 
168 	/* determine section */
169 	atom = AtomType (type);
170 	if (ATOM_INVALID == atom) {
171 		return;
172 	}
173 	/* create section */
174 	section = DB_CreateSection (dbControl, atom);
175 	assert (section != NULL);
176 	/* store entries */
177 	StoreEntry (section, atomKeyUp, cfg->keyUp);
178 	StoreEntry (section, atomKeyLeft, cfg->keyLeft);
179 	StoreEntry (section, atomKeyDown, cfg->keyDown);
180 	StoreEntry (section, atomKeyRight, cfg->keyRight);
181 	StoreEntry (section, atomKeyStop, cfg->keyStop);
182 	StoreEntry (section, atomKeyBomb, cfg->keyBomb);
183 	StoreEntry (section, atomKeySpecial, cfg->keySpecial);
184 	StoreEntry (section, atomKeyPause, cfg->keyPause);
185 	StoreEntry (section, atomKeyAbort, cfg->keyAbort);
186 	StoreEntry (section, atomKeyAbortCancel, cfg->keyAbortCancel);
187 	/* Skywalker */
188 	StoreEntry (section, atomKeyLaola, cfg->keyLaola);
189 	StoreEntry (section, atomKeyLooser, cfg->keyLooser);
190 	StoreEntry (section, atomKeyBot, cfg->keyBot);
191 	StoreEntry (section, atomKeyChatSend, cfg->keyChatSend);
192 	StoreEntry (section, atomKeyChatStart, cfg->keyChatStart);
193 	StoreEntry (section, atomKeyChatCancel, cfg->keyChatCancel);
194 	StoreEntry (section, atomKeyChatChangeReceiver, cfg->keyChatChangeReceiver);
195 	/* */
196 }								/* StoreControlKeyboard */
197 
198 /*
199  * get single key entry
200  */
201 static void
RetrieveEntry(const DBSection * section,XBAtom atomEntry,XBAtom * atomValue)202 RetrieveEntry (const DBSection * section, XBAtom atomEntry, XBAtom * atomValue)
203 {
204 	const char *s;
205 
206 	assert (atomValue != NULL);
207 	if (DB_GetEntryString (section, atomEntry, &s)) {
208 		*atomValue = GUI_StringToAtom (s);
209 	}
210 	else {
211 		*atomValue = ATOM_INVALID;
212 	}
213 }								/* RetrieveEntry */
214 
215 /*
216  * get control config from database
217  */
218 XBBool
RetrieveControlKeyboard(XBEventCode type,CFGControlKeyboard * cfg)219 RetrieveControlKeyboard (XBEventCode type, CFGControlKeyboard * cfg)
220 {
221 	XBAtom atom;
222 	const DBSection *section;
223 
224 	/* determine section */
225 	atom = AtomType (type);
226 	if (ATOM_INVALID == atom) {
227 		return XBFalse;
228 	}
229 	/* get section */
230 	section = DB_GetSection (dbControl, atom);
231 	if (NULL == section) {
232 		return XBFalse;
233 	}
234 	/* get values */
235 	RetrieveEntry (section, atomKeyUp, &cfg->keyUp);
236 	RetrieveEntry (section, atomKeyLeft, &cfg->keyLeft);
237 	RetrieveEntry (section, atomKeyDown, &cfg->keyDown);
238 	RetrieveEntry (section, atomKeyRight, &cfg->keyRight);
239 	RetrieveEntry (section, atomKeyStop, &cfg->keyStop);
240 	RetrieveEntry (section, atomKeyBomb, &cfg->keyBomb);
241 	RetrieveEntry (section, atomKeySpecial, &cfg->keySpecial);
242 	RetrieveEntry (section, atomKeyPause, &cfg->keyPause);
243 	RetrieveEntry (section, atomKeyAbort, &cfg->keyAbort);
244 	RetrieveEntry (section, atomKeyAbortCancel, &cfg->keyAbortCancel);
245 	/* Skywalker */
246 	RetrieveEntry (section, atomKeyLaola, &cfg->keyLaola);
247 	RetrieveEntry (section, atomKeyLooser, &cfg->keyLooser);
248 	RetrieveEntry (section, atomKeyBot, &cfg->keyBot);
249 	RetrieveEntry (section, atomKeyChatSend, &cfg->keyChatSend);
250 	RetrieveEntry (section, atomKeyChatStart, &cfg->keyChatStart);
251 	RetrieveEntry (section, atomKeyChatCancel, &cfg->keyChatCancel);
252 	RetrieveEntry (section, atomKeyChatChangeReceiver, &cfg->keyChatChangeReceiver);
253 	/* */
254 	return XBTrue;
255 }								/* RetrieveControlKeyboard */
256 
257 /*
258  * int and load controls config
259  */
260 void
LoadControlConfig(void)261 LoadControlConfig (void)
262 {
263 	CFGControlKeyboard cfgKeyboard;
264 	/* create empty database */
265 	dbControl = DB_Create (DT_Config, atomControl);
266 	assert (dbControl != NULL);
267 	/* load from file */
268 	Dbg_Config ("loading control configs\n");
269 	if (DB_Load (dbControl)) {
270 		return;
271 	}
272 	Dbg_Config ("failed to load control configs, settting defaults\n");
273 	/* set default values */
274 	SetDefaultRightKeyboard (&cfgKeyboard);
275 	StoreControlKeyboard (XBE_KEYB_1, &cfgKeyboard);
276 	SetDefaultLeftKeyboard (&cfgKeyboard);
277 	StoreControlKeyboard (XBE_KEYB_2, &cfgKeyboard);
278 	/* store it */
279 	DB_Store (dbControl);
280 }								/* LoadControlConfig */
281 
282 /*
283  * save control config
284  */
285 void
SaveControlConfig(void)286 SaveControlConfig (void)
287 {
288 	assert (dbControl != NULL);
289 	if (DB_Changed (dbControl)) {
290 		Dbg_Config ("storing control configs\n");
291 		DB_Store (dbControl);
292 	}
293 }								/* SaveControlConfig  */
294 
295 /*
296  * finish control config
297  */
298 void
FinishControlConfig(void)299 FinishControlConfig (void)
300 {
301 	DB_Delete (dbControl);
302 	dbControl = NULL;
303 	Dbg_Config ("control config cleared\n");
304 }								/* FinishControlConfig  */
305 
306 /*
307  * put entry into key table
308  */
309 static int
PutEntry(CFGKeyTable * table,XBEventCode type,int key,const DBSection * section,XBAtom atom)310 PutEntry (CFGKeyTable * table, XBEventCode type, int key, const DBSection * section, XBAtom atom)
311 {
312 	const char *s;
313 
314 	assert (table != NULL);
315 	if (DB_GetEntryString (section, atom, &s)) {
316 		table->keysym = s;
317 		table->eventCode = type;
318 		table->eventData = key;
319 		return 1;
320 	}
321 	return 0;
322 }								/* PutEntry */
323 
324 /*
325  * get key control table for gui
326  */
327 const CFGKeyTable *
GetGameKeyPressTable(void)328 GetGameKeyPressTable (void)
329 {
330 	int i, num;
331 	XBEventCode type;
332 	const DBSection *section;
333 	static CFGKeyTable keyTable[2 * NUM_GAME_KEYS + NUM_XBLAST_KEYS + 1];
334 
335 	/* clear old table */
336 	memset (keyTable, 0, sizeof (keyTable));
337 	/* game control keys */
338 	num = 0;
339 	for (i = 0; i < NUM_KEYB_CONTROLS; i++) {
340 		type = keyEventType[i];
341 		section = DB_GetSection (dbControl, AtomType (type));
342 		if (NULL != section) {
343 			num += PutEntry (keyTable + num, type, XBGK_GO_UP, section, atomKeyUp);
344 			num += PutEntry (keyTable + num, type, XBGK_GO_LEFT, section, atomKeyLeft);
345 			num += PutEntry (keyTable + num, type, XBGK_GO_DOWN, section, atomKeyDown);
346 			num += PutEntry (keyTable + num, type, XBGK_GO_RIGHT, section, atomKeyRight);
347 			num += PutEntry (keyTable + num, type, XBGK_STOP_ALL, section, atomKeyStop);
348 			num += PutEntry (keyTable + num, type, XBGK_BOMB, section, atomKeyBomb);
349 			num += PutEntry (keyTable + num, type, XBGK_SPECIAL, section, atomKeySpecial);
350 			num += PutEntry (keyTable + num, type, XBGK_PAUSE, section, atomKeyPause);
351 			num += PutEntry (keyTable + num, type, XBGK_ABORT, section, atomKeyAbort);
352 			num += PutEntry (keyTable + num, type, XBGK_ABORT_CANCEL, section, atomKeyAbortCancel);
353 /* Skywalker */
354 			num += PutEntry (keyTable + num, type, XBGK_LAOLA, section, atomKeyLaola);
355 			num += PutEntry (keyTable + num, type, XBGK_LOOSER, section, atomKeyLooser);
356 			num += PutEntry (keyTable + num, type, XBGK_BOT, section, atomKeyBot);
357 			/* */
358 		}
359 	}
360 	/* game control keys */
361 	memcpy (keyTable + num, xblastKeyTable, sizeof (xblastKeyTable));
362 	/* that's all */
363 	return keyTable;
364 }								/* GetGameKeyPressTable */
365 
366 /*
367  * get key control table for chat
368  */
369 const CFGKeyTable *
GetChatKeyTable(void)370 GetChatKeyTable (void)
371 {
372 	int i, num;
373 	XBEventCode type;
374 	const DBSection *section;
375 	static CFGKeyTable keyTable[2 * NUM_GAME_KEYS + NUM_XBLAST_KEYS + 1];
376 
377 	/* clear old table */
378 	memset (keyTable, 0, sizeof (keyTable));
379 	/* game control keys */
380 	num = 0;
381 	for (i = 0; i < NUM_KEYB_CONTROLS; i++) {
382 		type = keyEventType[i];
383 		section = DB_GetSection (dbControl, AtomType (type));
384 		if (NULL != section) {
385 			num += PutEntry (keyTable + num, type, XBCE_SEND, section, atomKeyChatSend);
386 			num += PutEntry (keyTable + num, type, XBCE_START, section, atomKeyChatStart);
387 			num += PutEntry (keyTable + num, type, XBCE_CANCEL, section, atomKeyChatCancel);
388 			num += PutEntry (keyTable + num, type, XBCE_CHANGE, section, atomKeyChatChangeReceiver);
389 		}
390 	}
391 	/* fixed chat keys */
392 	memcpy (keyTable + num, chatKeyTable, sizeof (chatKeyTable));
393 	/* that's all */
394 	return keyTable;
395 }								/* GetGameKeyPressTable */
396 
397 /*
398  * get key control table for gui
399  */
400 const CFGKeyTable *
GetGameKeyReleaseTable(void)401 GetGameKeyReleaseTable (void)
402 {
403 	int i, num;
404 	XBEventCode type;
405 	const DBSection *section;
406 	static CFGKeyTable keyTable[2 * NUM_GAME_KEYS + 1];
407 
408 	/* clear old table */
409 	memset (keyTable, 0, sizeof (keyTable));
410 	/* build new one */
411 	num = 0;
412 	for (i = 0; i < NUM_KEYB_CONTROLS; i++) {
413 		type = keyEventType[i];
414 		section = DB_GetSection (dbControl, AtomType (type));
415 		if (NULL != section) {
416 			num += PutEntry (keyTable + num, type, XBGK_STOP_UP, section, atomKeyUp);
417 			num += PutEntry (keyTable + num, type, XBGK_STOP_LEFT, section, atomKeyLeft);
418 			num += PutEntry (keyTable + num, type, XBGK_STOP_DOWN, section, atomKeyDown);
419 			num += PutEntry (keyTable + num, type, XBGK_STOP_RIGHT, section, atomKeyRight);
420 		}
421 	}
422 	/* that's all */
423 	return keyTable;
424 }								/* GetGameKeyReleaseTable */
425 
426 /*
427  * get menu key table for gui
428  */
429 const CFGKeyTable *
GetMenuKeyTable(void)430 GetMenuKeyTable (void)
431 {
432 	return menuKeyTable;
433 }								/* GetMenuKeyTable */
434 
435 /*
436  * end cfg_control.c
437  */
438