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