1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * Licensed under the BSD license, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2011 OpenBOR Team
7  */
8 
9 #include "kos.h"
10 #include "control.h"
11 
12 int dcpad_rumblepower[4];
13 
14 static int usejoy;
15 static int lastkey[4];
16 
17 #define	PAD_START 1
18 #define	PAD_END   (18*4)
19 
20 static const char *padnames[PAD_END+1+1] = {
21 	"...",
22 #define CONTROLNAMES(x) \
23 	x" Up",         \
24 	x" Right",      \
25 	x" Down",       \
26 	x" Left",       \
27 	x" A",          \
28 	x" B",          \
29 	x" X",          \
30 	x" Y",          \
31 	x" L-Trigger",  \
32 	x" R-Trigger",  \
33 	x" Start",      \
34 	x" C",          \
35 	x" D",          \
36 	x" Z",          \
37 	x" Up 2",       \
38 	x" Down 2",     \
39 	x" Left 2",     \
40 	x" Right 2",
41 	CONTROLNAMES("P1")
42 	CONTROLNAMES("P2")
43 	CONTROLNAMES("P3")
44 	CONTROLNAMES("P4")
45 	"Undefined"
46 };
47 
flag_to_index(unsigned long flag)48 static int flag_to_index(unsigned long flag)
49 {
50 	int index = 0;
51 	unsigned long bit = 1;
52 	while(!((bit<<index)&flag) && index<31) ++index;
53 	return index;
54 }
55 
control_exit()56 void control_exit()
57 {
58 	usejoy = 0;
59 }
60 
control_init(int joy_enable)61 void control_init(int joy_enable)
62 {
63 	usejoy = joy_enable;
64 }
65 
control_usejoy(int enable)66 int control_usejoy(int enable)
67 {
68 	usejoy = enable;
69 	return 0;
70 }
71 
control_getjoyenabled()72 int control_getjoyenabled()
73 {
74 	return usejoy;
75 }
76 
keyboard_getlastkey()77 int keyboard_getlastkey()
78 {
79 	int i, ret[4];
80 	for(i=0; i<4; i++)
81 	{
82 		ret[i] = lastkey[i];
83 		lastkey[i] = 0;
84 	}
85 	return (ret[0] | ret[1] | ret[2] | ret[3]);
86 }
87 
control_setkey(s_playercontrols * pcontrols,unsigned int flag,int key)88 void control_setkey(s_playercontrols * pcontrols, unsigned int flag, int key)
89 {
90 	if(!pcontrols) return;
91 	pcontrols->settings[flag_to_index(flag)] = key;
92 	pcontrols->keyflags = pcontrols->newkeyflags = 0;
93 }
94 
95 // Scan input for newly-pressed keys.
96 // Return value:
97 // 0  = no key was pressed
98 // >0 = key code for pressed key
99 // <0 = error
control_scankey()100 int control_scankey()
101 {
102 	static unsigned ready = 0;
103 	unsigned k=0;
104 	unsigned port0=lastkey[0];
105 	unsigned port1=lastkey[1];
106 	unsigned port2=lastkey[2];
107 	unsigned port3=lastkey[3];
108 
109 	     if(port0) k = 1 + 0*18 + flag_to_index(port0);
110 	else if(port1) k = 1 + 1*18 + flag_to_index(port1);
111 	else if(port2) k = 1 + 2*18 + flag_to_index(port2);
112 	else if(port3) k = 1 + 3*18 + flag_to_index(port3);
113 
114 	if(ready && k)
115 	{
116 		ready = 0;
117 		return k;
118 	}
119 	ready = (!k);
120 	return 0;
121 }
122 
control_getkeyname(unsigned keycode)123 char * control_getkeyname(unsigned keycode)
124 {
125 	if(keycode >= PAD_START && keycode <= PAD_END) return (char*)padnames[keycode];
126 	return "...";
127 }
128 
control_update(s_playercontrols ** playercontrols,int numplayers)129 void control_update(s_playercontrols ** playercontrols, int numplayers)
130 {
131 	unsigned long k;
132 	unsigned long i;
133 	int player;
134 	int t;
135 	s_playercontrols * pcontrols;
136 	unsigned port[4];
137 	for(i=0; i<4; i++) port[i] = getPad(i);
138 	for(player=0; player<numplayers; player++)
139 	{
140 		pcontrols = playercontrols[player];
141 		k = 0;
142 		for(i=0; i<32; i++){
143 			t = pcontrols->settings[i];
144 			if(t >= PAD_START && t <= PAD_END)
145 			{
146 				int portnum = (t-1) / 18;
147 				int shiftby = (t-1) % 18;
148 				if(portnum >= 0 && portnum <= 3)
149 				{
150 					if((port[portnum] >> shiftby) & 1) k |= (1<<i);
151 				}
152 			}
153 		}
154 		pcontrols->kb_break = 0;
155 		pcontrols->newkeyflags = k & (~pcontrols->keyflags);
156 		pcontrols->keyflags = k;
157 	}
158 }
159 
control_rumble(int port,int msec)160 void control_rumble(int port, int msec)
161 {
162 	dcpad_rumblepower[port] = msec;
163 }
164 
getPad(int port)165 unsigned long getPad(int port)
166 {
167 	unsigned long btns=0;
168 	maple_device_t *caddr;
169 	cont_state_t *cont;
170 	if((caddr = maple_enum_type(port, MAPLE_FUNC_CONTROLLER)) == NULL) goto DONE;
171 	if((cont = maple_dev_status(caddr)) == NULL) goto DONE;
172 	if(cont->buttons & CONT_DPAD_UP)	 btns |= DC_DPAD_UP;
173 	if(cont->buttons & CONT_DPAD_RIGHT)  btns |= DC_DPAD_RIGHT;
174 	if(cont->buttons & CONT_DPAD_DOWN)   btns |= DC_DPAD_DOWN;
175 	if(cont->buttons & CONT_DPAD_LEFT)   btns |= DC_DPAD_LEFT;
176 	if(cont->buttons & CONT_DPAD2_UP)	 btns |= DC_DPAD2_UP;
177 	if(cont->buttons & CONT_DPAD2_RIGHT) btns |= DC_DPAD2_RIGHT;
178 	if(cont->buttons & CONT_DPAD2_DOWN)  btns |= DC_DPAD2_DOWN;
179 	if(cont->buttons & CONT_DPAD2_LEFT)  btns |= DC_DPAD2_LEFT;
180 	if(cont->buttons & CONT_START)       btns |= DC_START;
181 	if(cont->buttons & CONT_A)           btns |= DC_A;
182 	if(cont->buttons & CONT_B)           btns |= DC_B;
183 	if(cont->buttons & CONT_C)           btns |= DC_C;
184 	if(cont->buttons & CONT_D)           btns |= DC_D;
185 	if(cont->buttons & CONT_X)           btns |= DC_X;
186 	if(cont->buttons & CONT_Y)           btns |= DC_Y;
187 	if(cont->buttons & CONT_Z)           btns |= DC_Z;
188 	if(cont->joyy < -40)                 btns |= DC_DPAD_UP;
189 	if(cont->joyx > 40)                  btns |= DC_DPAD_RIGHT;
190 	if(cont->joyy > 40)	                 btns |= DC_DPAD_DOWN;
191 	if(cont->joyx < -40)                 btns |= DC_DPAD_LEFT;
192 	if(cont->joy2y < -40)                btns |= DC_DPAD2_UP;
193 	if(cont->joy2x > 40)                 btns |= DC_DPAD2_RIGHT;
194 	if(cont->joy2y > 40)	             btns |= DC_DPAD2_DOWN;
195 	if(cont->joy2x < -40)                btns |= DC_DPAD2_LEFT;
196 	if(cont->ltrig > 20)                 btns |= DC_LEFT_TRIGGER;
197 	if(cont->rtrig > 20)                 btns |= DC_RIGHT_TRIGGER;
198 
199 DONE:
200   	return lastkey[port] = btns;
201 }
202