1 /*
2 Copyright (C) 2007, 2010 - Bit-Blot
3 
4 This file is part of Aquaria.
5 
6 Aquaria is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21 #include "ActionMapper.h"
22 #include "Core.h"
23 
24 //bool ActionMapper::isActing(const std::string &action)
25 //{
26 //	ButtonList::iterator i = actionMap[action].begin();
27 //	for (; i != actionMap[action].end(); i++)
28 //	{
29 //		if (keyDownMap[(*i)])
30 //			return true;
31 //	}
32 //	return false;
33 // //return keyDownMap[actionMap[action]];
34 //}
35 
36 //bool ActionMapper::isActing(int actionID)
37 //{
38 //	std::string action = "A";
39 //	action[0] = char(actionID);
40 //	ButtonList::iterator i = actionMap[action].begin();
41 //	for (; i != actionMap[action].end(); i++)
42 //	{
43 //		if (keyDownMap[(*i)])
44 //			return true;
45 //	}
46 //	return false;
47 // //return keyDownMap[actionMap[action]];
48 //}
49 
50 //void ActionMapper::addAction (const std::string &action, int k)
51 //{
52 //	actionMap[action].push_back(k);
53 //	keyDownMap[k] = core->getKeyState(k);
54 //}
55 //
56 //void ActionMapper::addAction (int actionID, int k)
57 //{
58 //	std::string action = "A";
59 //	action[0] = char(actionID);
60 //	actionMap[action].push_back(k);
61 //	keyDownMap[k] = core->getKeyState(k);
62 //}
63 
ActionMapper()64 ActionMapper::ActionMapper()
65 {
66 	cleared = false;
67 	inputEnabled = true;
68 	inUpdate = false;
69 }
70 
~ActionMapper()71 ActionMapper::~ActionMapper()
72 {
73 	clearCreatedEvents();
74 }
75 
getActionDataByID(int actionID)76 ActionData *ActionMapper::getActionDataByID(int actionID)
77 {
78 	for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); i++)
79 	{
80 		if ((*i).id == actionID)
81 			return &(*i);
82 	}
83 	return 0;
84 }
85 
isActing(int actionID)86 bool ActionMapper::isActing(int actionID)
87 {
88 	ActionData *ad = getActionDataByID(actionID);
89 	if (ad)
90 	{
91 		ButtonList::iterator i = ad->buttonList.begin();
92 		for (; i != ad->buttonList.end(); i++)
93 		{
94 			if (keyDownMap[(*i)])
95 				return true;
96 		}
97 	}
98 	return false;
99 }
100 
addAction(int actionID,int k)101 void ActionMapper::addAction (int actionID, int k)
102 {
103 	ActionData *ad = getActionDataByID(actionID);
104 
105 	if (ad)
106 	{
107 		/*
108 		std::ostringstream os;
109 		os << "Action ID [" << actionID << "] already exists!";
110 		debugLog(os.str());
111 		*/
112 	}
113 	else
114 	{
115 		ActionData data;
116 		data.id = actionID;
117 		actionData.push_back(data);
118 		ad = getActionDataByID(actionID);
119 		if (!ad)
120 		{
121 			std::ostringstream os;
122 			os << "Could not create action for Action ID [" << actionID << "]";
123 			errorLog(os.str());
124 			return;
125 		}
126 	}
127 
128 	if (ad)
129 	{
130 		if(std::find(ad->buttonList.begin(), ad->buttonList.end(), k) == ad->buttonList.end())
131 			ad->buttonList.push_back(k);
132 		keyDownMap[k] = core->getKeyState(k);
133 	}
134 }
135 
136 
137 
addAction(Event * event,int k,int state)138 void ActionMapper::addAction(Event *event, int k, int state)
139 {
140 	ActionData data;
141 	data.event = event;
142 	data.state = state;
143 	data.buttonList.push_back(k);
144 	actionData.push_back(data);
145 
146 	keyDownMap[k] = core->getKeyState(k);
147 }
148 
addCreatedEvent(Event * event)149 Event* ActionMapper::addCreatedEvent(Event *event)
150 {
151 	for (int i = 0; i < createdEvents.size(); i++)
152 	{
153 		if (createdEvents[i] == event)
154 			return event;
155 	}
156 	createdEvents.push_back(event);
157 	return event;
158 }
159 
clearCreatedEvents()160 void ActionMapper::clearCreatedEvents()
161 {
162 	for (int i = 0; i < createdEvents.size(); i++)
163 	{
164 		delete createdEvents[i];
165 	}
166 	createdEvents.clear();
167 }
168 
169 /*
170 void ActionMapper::addMouseButtonAction (const std::string &action, int b)
171 {
172 	actionMap[action].push_back (0-b);
173 	keyDownMap[0-b] = mouse_b & b;
174 }
175 
176 void ActionMapper::addJoystickButtonAction (const std::string &action, int b)
177 {
178 	if (num_joysticks)
179 	{
180 		actionMap[action].push_back (b+9000);
181 		keyDownMap[b+9000] = joy[0].button[b].b;
182 	}
183 }
184 
185 int ActionMapper::getDPad(int dir)
186 {
187 //	for (int = 0; i < joy[0].num_sticks; i++)
188 	//int s = 4;
189 	int s = 0;
190 	switch (dir)
191 	{
192 	case 0:
193 		return (joy[0].stick[s].axis[0].d1);
194 	break;
195 	case 1:
196 		return (joy[0].stick[s].axis[0].d2);
197 	break;
198 	case 2:
199 		return (joy[0].stick[s].axis[1].d1);
200 	break;
201 	case 3:
202 		return (joy[0].stick[s].axis[1].d2);
203 	break;
204 	}
205 	return 0;
206 }
207 
208 
209 void ActionMapper::addJoystickDPadAction (const std::string &action, int dir)
210 {
211 	if (num_joysticks)
212 	{
213 		actionMap[action].push_back (dir+8000);
214 		keyDownMap[dir+8000] = getDPad(dir);
215 	}
216 }
217 */
218 
enableInput()219 void ActionMapper::enableInput()
220 {
221 	inputEnabled = true;
222 }
223 
disableInput()224 void ActionMapper::disableInput()
225 {
226 	inputEnabled = false;
227 }
228 
removeAction(int actionID)229 void ActionMapper::removeAction(int actionID)
230 {
231 	ActionData *ad = getActionDataByID(actionID);
232 	if (ad)
233 	{
234 		ButtonList::iterator i = ad->buttonList.begin();
235 		for (; i != ad->buttonList.end(); i++)
236 		{
237 			int k = (*i);
238 			cleared = true; // it's a hack, but it works
239 			keyDownMap.erase(k);
240 		}
241 		for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end();)
242 		{
243 			if (i->id == actionID)
244 				i = actionData.erase(i);
245 			else
246 				i++;
247 		}
248 	}
249 }
250 
251 //int ActionMapper::getKeyForAction (std::string action)
252 //{
253 //	ButtonList b = actionMap[action];
254 //	if (!b.empty())
255 //	{
256 //		return b[0];
257 //	}
258 //	else
259 //	{
260 //		debugLog ("no action: " +action);
261 //		return -1;
262 //	}
263 //}
264 
pollAction(int actionID)265 bool ActionMapper::pollAction(int actionID)
266 {
267 	bool down = false;
268 
269 	ActionData *ad = getActionDataByID(actionID);
270 	if (ad)
271 	{
272 		ButtonList *blist = &ad->buttonList;
273 		ButtonList::iterator j;
274 		j = blist->begin();
275 
276 		for (; j != blist->end(); j++)
277 		{
278 			if (getKeyState((*j)))
279 			{
280 				down = true;
281 				break;
282 			}
283 		}
284 	}
285 
286 	return down;
287 }
288 
getKeyState(int k)289 bool ActionMapper::getKeyState(int k)
290 {
291 	bool keyState = false;
292 	if (k == KEY_ANYKEY)
293 	{
294 		keyState = false;
295 		for (int i = 0; i < KEY_MAXARRAY; i ++)
296 		{
297 			if (core->getKeyState(i))
298 			{
299 				keyState = true;
300 				break;
301 			}
302 		}
303 	}
304 	else if (k >= 0 && k < KEY_MAXARRAY)
305 	{
306 		keyState = (core->getKeyState(k));
307 	}
308 	else if (k == MOUSE_BUTTON_LEFT)
309 	{
310 		keyState = (core->mouse.buttons.left == DOWN);
311 	}
312 	else if (k == MOUSE_BUTTON_RIGHT)
313 	{
314 		keyState = (core->mouse.buttons.right == DOWN);
315 	}
316 	else if (k == MOUSE_BUTTON_MIDDLE)
317 	{
318 		keyState = (core->mouse.buttons.middle == DOWN);
319 	}
320 	else if (k >= JOY1_BUTTON_0 && k <= JOY1_BUTTON_16)
321 	{
322 		int v = k - JOY1_BUTTON_0;
323 
324 		if (core->joystickEnabled)
325 			keyState = core->joystick.buttons[v];
326 	}
327 	else if (k == JOY1_STICK_LEFT)
328 	{
329 		keyState = core->joystick.position.x < -0.6f;
330 	}
331 	else if (k == JOY1_STICK_RIGHT)
332 	{
333 		keyState = core->joystick.position.x > 0.6f;
334 	}
335 	else if (k == JOY1_STICK_UP)
336 	{
337 		keyState = core->joystick.position.y < -0.6f;
338 	}
339 	else if (k == JOY1_STICK_DOWN)
340 	{
341 		keyState = core->joystick.position.y > 0.6f;
342 	}
343 	else if (k == X360_BTN_START)
344 	{
345 		keyState = core->joystick.btnStart;
346 	}
347 	else if (k == X360_BTN_BACK)
348 	{
349 		keyState = core->joystick.btnSelect;
350 	}
351 	else if (k == JOY1_DPAD_LEFT)
352 	{
353 		keyState = core->joystick.dpadLeft;
354 	}
355 	else if (k == JOY1_DPAD_RIGHT)
356 	{
357 		keyState = core->joystick.dpadRight;
358 	}
359 	else if (k == JOY1_DPAD_UP)
360 	{
361 		keyState = core->joystick.dpadUp;
362 	}
363 	else if (k == JOY1_DPAD_DOWN)
364 	{
365 		keyState = core->joystick.dpadDown;
366 	}
367 
368 	return keyState;
369 }
370 
onUpdate(float dt)371 void ActionMapper::onUpdate (float dt)
372 {
373 	if (inUpdate) return;
374 	inUpdate = true;
375 	/*
376 	if (num_joysticks)
377 		poll_joystick();
378 	*/
379 	if (cleared) cleared = false;
380 	ActionDataSet::iterator i;
381 	KeyDownMap oldKeyDownMap = keyDownMap;
382 	for (i = actionData.begin(); i != actionData.end(); ++i)
383 	{
384 		ButtonList::iterator j;
385 		j = i->buttonList.begin();
386 		for (; j != i->buttonList.end(); j++)
387 		{
388 			int k = (*j);
389 			int keyState=false;
390 			//joystick
391 
392 			keyState = getKeyState(k);
393 
394 			if (keyState != oldKeyDownMap[k])
395 			{
396 				keyDownMap[k] = keyState;
397 				if (inputEnabled)
398 				{
399 					ActionData *ad = &(*i);
400 					if (ad->event)
401 					{
402 						if (ad->state==-1 || keyState == ad->state)
403 						{
404 							ad->event->act();
405 						}
406 					}
407 					else
408 					{
409 						action(ad->id, keyState);
410 					}
411 					if (core->loopDone) goto out;
412 				}
413 				if (cleared) { cleared = false; goto out; } // actionData has been cleared, stop iteration
414 			}
415 		}
416 	}
417 
418 out:
419 	inUpdate = false;
420 //		keyDownMap[k] = ;
421 }
422 
clearActions()423 void ActionMapper::clearActions()
424 {
425 	cleared = true;
426 	keyDownMap.clear();
427 	actionData.clear();
428 }
429 
removeAllActions()430 void ActionMapper::removeAllActions()
431 {
432 	std::vector <int> deleteList;
433 	ActionDataSet::iterator i;
434 	for (i = actionData.begin(); i != actionData.end(); i++)
435 	{
436 		deleteList.push_back(i->id);
437 	}
438 	for (int c = 0; c < deleteList.size(); c++)
439 	{
440 		removeAction (deleteList[c]);
441 	}
442 	actionData.clear();
443 }
444