1 /*
2  * OpenBOR - http://www.chronocrash.com
3  * -----------------------------------------------------------------------
4  * Licensed under a BSD-style license, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2017 OpenBOR Team
7  */
8 
9 #include <string.h>
10 #include <psp2/ctrl.h>
11 #include "vitaport.h"
12 #include "control.h"
13 
14 #define	PAD_START			1
15 #define	MAX_PADS			4
16 #define	PAD_END				(18*MAX_PADS)
17 
18 static int usejoy;
19 static int lastkey[MAX_PADS];
20 
21 static const char *padnames[PAD_END+1+1] = {
22 	"...",
23 #define CONTROLNAMES(x) \
24 	x" Up",             \
25 	x" Right",          \
26 	x" Down",           \
27 	x" Left",           \
28 	x" X",              \
29 	x" O",              \
30 	x" []",             \
31 	x" /\\",            \
32 	x" L",              \
33 	x" R",              \
34 	x" Start",          \
35 	x" Select",         \
36 	x" L2",             \
37 	x" R2",             \
38 	x" L3",             \
39 	x" R3",
40 	CONTROLNAMES("Vita 1")
41 	CONTROLNAMES("Vita 2")
42 	CONTROLNAMES("Vita 3")
43 	CONTROLNAMES("Vita 4")
44 	"undefined"
45 };
46 
47 static unsigned int getPad(int port);
48 
flag_to_index(unsigned int flag)49 static int flag_to_index(unsigned int flag)
50 {
51 	int index = 0;
52 	unsigned int bit = 1;
53 	while (!((bit<<index)&flag) && index<31) ++index;
54 	return index;
55 }
56 
control_exit()57 void control_exit()
58 {
59 	usejoy = 0;
60 }
61 
control_init(int joy_enable)62 void control_init(int joy_enable)
63 {
64 	usejoy = joy_enable;
65 }
66 
control_usejoy(int enable)67 int control_usejoy(int enable)
68 {
69 	usejoy = enable;
70 	return 0;
71 }
72 
control_getjoyenabled()73 int control_getjoyenabled()
74 {
75 	return usejoy;
76 }
77 
keyboard_getlastkey(void)78 int keyboard_getlastkey(void)
79 {
80 	int i, ret=0;
81 	for (i=0; i<MAX_PADS; i++)
82 	{
83 		ret |= lastkey[i];
84 		lastkey[i] = 0;
85 	}
86 	return ret;
87 }
88 
control_setkey(s_playercontrols * pcontrols,unsigned int flag,int key)89 void control_setkey(s_playercontrols * pcontrols, unsigned int flag, int key)
90 {
91 	if (!pcontrols) return;
92 	pcontrols->settings[flag_to_index(flag)] = key;
93 	pcontrols->keyflags = pcontrols->newkeyflags = 0;
94 }
95 
96 // Scan input for newly-pressed keys.
97 // Return value:
98 // 0  = no key was pressed
99 // >0 = key code for pressed key
100 // <0 = error
control_scankey()101 int control_scankey()
102 {
103 	static unsigned ready = 0;
104 	unsigned i, k=0;
105 
106 	for (i=0; i<MAX_PADS; i++)
107 	{
108 		if (lastkey[i])
109 		{
110 			k = 1 + i*18 + flag_to_index(lastkey[i]);
111 			break;
112 		}
113 	}
114 
115 	if (ready && k)
116 	{
117 		ready = 0;
118 		return k;
119 	}
120 	ready = (!k);
121 	return 0;
122 }
123 
control_getkeyname(unsigned keycode)124 char * control_getkeyname(unsigned keycode)
125 {
126 	if (keycode >= PAD_START && keycode <= PAD_END) return (char*)padnames[keycode];
127 	return "...";
128 }
129 
control_update(s_playercontrols ** playercontrols,int numplayers)130 void control_update(s_playercontrols ** playercontrols, int numplayers)
131 {
132 	unsigned int k;
133 	unsigned int i;
134 	int player;
135 	int t;
136 	s_playercontrols * pcontrols;
137 	unsigned port[MAX_PADS];
138 	for (i=0; i<MAX_PADS; i++) port[i] = getPad(i);
139 	for (player=0; player<numplayers; player++)
140 	{
141 		pcontrols = playercontrols[player];
142 		k = 0;
143 		for (i=0; i<32; i++)
144 		{
145 			t = pcontrols->settings[i];
146 			if (t >= PAD_START && t <= PAD_END)
147 			{
148 				int portnum = (t-1) / 18;
149 				int shiftby = (t-1) % 18;
150 				if (portnum >= 0 && portnum <= 3)
151 				{
152 					if ((port[portnum] >> shiftby) & 1) k |= (1<<i);
153 				}
154 			}
155 		}
156 		pcontrols->kb_break = 0;
157 		pcontrols->newkeyflags = k & (~pcontrols->keyflags);
158 		pcontrols->keyflags = k;
159 	}
160 }
161 
control_rumble(int port,int ratio,int msec)162 void control_rumble(int port, int ratio, int msec)
163 {
164 }
165 
getPad(int port)166 static unsigned int getPad(int port)
167 {
168 	unsigned int btns = 0;
169 	SceCtrlData pad;
170 	memset(&pad, 0, sizeof(pad));
171 	sceCtrlPeekBufferPositive(0, &pad, 1);
172 
173 	if (port != 0) return lastkey[port] = 0;
174 
175 	if (control_getjoyenabled())
176 	{
177 		if (pad.ly >= 0xC0)              btns |= VITA_DPAD_DOWN;
178 		if (pad.ly <= 0x30)              btns |= VITA_DPAD_UP;
179 		if (pad.lx <= 0x30)              btns |= VITA_DPAD_LEFT;
180 		if (pad.lx >= 0xC0)              btns |= VITA_DPAD_RIGHT;
181 	}
182 
183 	if (pad.buttons & SCE_CTRL_SELECT)   btns |= VITA_SELECT;
184 	if (pad.buttons & SCE_CTRL_START)    btns |= VITA_START;
185 	if (pad.buttons & SCE_CTRL_UP)	     btns |= VITA_DPAD_UP;
186 	if (pad.buttons & SCE_CTRL_RIGHT)    btns |= VITA_DPAD_RIGHT;
187 	if (pad.buttons & SCE_CTRL_DOWN)     btns |= VITA_DPAD_DOWN;
188 	if (pad.buttons & SCE_CTRL_LEFT)     btns |= VITA_DPAD_LEFT;
189 	if (pad.buttons & SCE_CTRL_LTRIGGER) btns |= VITA_LEFT_TRIGGER;
190 	if (pad.buttons & SCE_CTRL_RTRIGGER) btns |= VITA_RIGHT_TRIGGER;
191 	if (pad.buttons & SCE_CTRL_TRIANGLE) btns |= VITA_TRIANGLE;
192 	if (pad.buttons & SCE_CTRL_CIRCLE)   btns |= VITA_CIRCLE;
193 	if (pad.buttons & SCE_CTRL_CROSS)	 btns |= VITA_CROSS;
194 	if (pad.buttons & SCE_CTRL_SQUARE)   btns |= VITA_SQUARE;
195 	if (pad.buttons & SCE_CTRL_L1)       btns |= VITA_L1;
196 	if (pad.buttons & SCE_CTRL_R1)       btns |= VITA_R1;
197 	if (pad.buttons & SCE_CTRL_L3)       btns |= VITA_L3;
198 	if (pad.buttons & SCE_CTRL_R3)       btns |= VITA_R3;
199 
200 	return lastkey[port] = btns;
201 }
202