1 #include "interface/controller.hpp"
2 #include "controller-parse.hpp"
9 #include "../src/emulation/bsnes-legacy/ports.inc"
11 const char* ports_json
= "{"
13 "\"B\":{\"type\":\"button\", \"name\":\"B\"},"
14 "\"Y\":{\"type\":\"button\", \"name\":\"Y\"},"
15 "\"select\":{\"type\":\"button\", \"name\":\"select\", \"symbol\":\"s\"},"
16 "\"start\":{\"type\":\"button\", \"name\":\"start\", \"symbol\":\"S\"},"
17 "\"up\":{\"type\":\"button\", \"name\":\"up\", \"symbol\":\"↑\", \"macro\":\"^\", \"movie\":\"u\"},"
18 "\"down\":{\"type\":\"button\", \"name\":\"down\", \"symbol\":\"↓\", \"macro\":\"v\", \"movie\":\"d\"},"
19 "\"left\":{\"type\":\"button\", \"name\":\"left\", \"symbol\":\"←\", \"macro\":\"<\", \"movie\":\"l\"},"
20 "\"right\":{\"type\":\"button\", \"name\":\"right\", \"symbol\":\"→\", \"macro\":\">\", \"movie\":\"r\"},"
21 "\"A\":{\"type\":\"button\", \"name\":\"A\"},"
22 "\"X\":{\"type\":\"button\", \"name\":\"X\"},"
23 "\"L\":{\"type\":\"button\", \"name\":\"L\"},"
24 "\"R\":{\"type\":\"button\", \"name\":\"R\"},"
25 "\"ext0\":{\"type\":\"button\", \"name\":\"ext0\", \"symbol\":\"0\", \"macro\":\"E0\"},"
26 "\"ext1\":{\"type\":\"button\", \"name\":\"ext1\", \"symbol\":\"1\", \"macro\":\"E1\"},"
27 "\"ext2\":{\"type\":\"button\", \"name\":\"ext2\", \"symbol\":\"2\", \"macro\":\"E2\"},"
28 "\"ext3\":{\"type\":\"button\", \"name\":\"ext3\", \"symbol\":\"3\", \"macro\":\"E3\"},"
29 "\"trigger\":{\"type\":\"button\", \"name\":\"trigger\", \"symbol\":\"T\"},"
30 "\"cursor\":{\"type\":\"button\", \"name\":\"cursor\", \"symbol\":\"C\"},"
31 "\"turbo\":{\"type\":\"button\", \"name\":\"turbo\", \"symbol\":\"U\"},"
32 "\"pause\":{\"type\":\"button\", \"name\":\"pause\", \"symbol\":\"P\"},"
33 "\"xaxis\":{\"type\":\"lightgun\", \"name\":\"xaxis\", \"min\":-16, \"max\":271},"
34 "\"yaxis\":{\"type\":\"lightgun\", \"name\":\"yaxis\", \"min\":-16, \"max\":255},"
35 "\"xmotion\":{\"type\":\"raxis\", \"name\":\"xaxis\", \"min\":-255, \"max\":255, \"centers\":true},"
36 "\"ymotion\":{\"type\":\"raxis\", \"name\":\"yaxis\", \"min\":-255, \"max\":255, \"centers\":true},"
37 "\"framesync\":{\"type\":\"button\", \"name\":\"framesync\", \"symbol\":\"F\", \"shadow\":true},"
38 "\"reset\":{\"type\":\"button\", \"name\":\"reset\", \"symbol\":\"R\", \"shadow\":true},"
39 "\"hard\":{\"type\":\"button\", \"name\":\"hard\", \"symbol\":\"H\", \"shadow\":true},"
40 "\"rhigh\":{\"type\":\"axis\", \"name\":\"rhigh\", \"shadow\":true},"
41 "\"rlow\":{\"type\":\"axis\", \"name\":\"rlow\", \"shadow\":true},"
42 "\"shadownull\":{\"type\":\"null\", \"shadow\":true}"
44 "\"gamepad\":{\"type\":\"gamepad\", \"class\":\"gamepad\", \"buttons\":["
45 "\"buttons/B\", \"buttons/Y\", \"buttons/select\", \"buttons/start\", \"buttons/up\", \"buttons/down\","
46 "\"buttons/left\", \"buttons/right\", \"buttons/A\", \"buttons/X\", \"buttons/L\", \"buttons/R\""
48 "\"gamepad16\":{\"type\":\"gamepad16\", \"class\":\"gamepad\", \"buttons\":["
49 "\"buttons/B\", \"buttons/Y\", \"buttons/select\", \"buttons/start\", \"buttons/up\", \"buttons/down\","
50 "\"buttons/left\", \"buttons/right\", \"buttons/A\", \"buttons/X\", \"buttons/L\", \"buttons/R\","
51 "\"buttons/ext0\", \"buttons/ext1\", \"buttons/ext2\", \"buttons/ext3\""
53 "\"justifier\":{\"type\":\"justifier\", \"class\":\"justifier\", \"buttons\":["
54 "\"buttons/xaxis\", \"buttons/yaxis\", \"buttons/trigger\", \"buttons/start\""
56 "\"mouse\":{\"type\":\"mouse\", \"class\":\"mouse\", \"buttons\":["
57 "\"buttons/xmotion\", \"buttons/ymotion\", \"buttons/L\", \"buttons/R\""
59 "\"superscope\":{\"type\":\"superscope\", \"class\":\"superscope\", \"buttons\":["
60 "\"buttons/xaxis\", \"buttons/yaxis\", \"buttons/trigger\", \"buttons/cursor\", \"buttons/turbo\","
63 "\"system\":{\"type\":\"(system)\", \"class\":\"(system)\", \"buttons\":["
64 "\"buttons/framesync\", \"buttons/reset\", \"buttons/rhigh\", \"buttons/rlow\""
66 "\"system_hreset\":{\"type\":\"(system)\", \"class\":\"(system)\", \"buttons\":["
67 "\"buttons/framesync\", \"buttons/reset\", \"buttons/rhigh\", \"buttons/rlow\", \"buttons/hard\""
69 "\"system_compact\":{\"type\":\"(system)\", \"class\":\"(system)\", \"buttons\":["
70 "\"buttons/framesync\", \"buttons/reset\", \"buttons/shadownull\", \"buttons/shadownull\","
74 "{\"symbol\":\"gamepad\", \"name\":\"gamepad\", \"hname\":\"gamepad\", \"controllers\":["
75 "\"controllers/gamepad\""
77 "{\"symbol\":\"gamepad16\", \"name\":\"gamepad16\", \"hname\":\"gamepad (16 buttons)\", \"controllers\":["
78 "\"controllers/gamepad16\""
80 "{\"symbol\":\"ygamepad16\", \"name\":\"ygamepad16\", \"hname\":\"Y-cabled gamepad (16 buttons)\", \"controllers\":["
81 "\"controllers/gamepad16\", \"controllers/gamepad16\""
83 "{\"symbol\":\"justifier\", \"name\":\"justifier\", \"hname\":\"Justifier\", \"controllers\":["
84 "\"controllers/justifier\""
86 "{\"symbol\":\"justifiers\", \"name\":\"justifiers\", \"hname\":\"2 Justifiers\", \"controllers\":["
87 "\"controllers/justifier\", \"controllers/justifier\""
89 "{\"symbol\":\"mouse\", \"name\":\"mouse\", \"hname\":\"Mouse\", \"controllers\":["
90 "\"controllers/mouse\""
91 "],\"legal\":[1, 2]},"
92 "{\"symbol\":\"multitap\", \"name\":\"multitap\", \"hname\":\"Multitap\", \"controllers\":["
93 "\"controllers/gamepad\", \"controllers/gamepad\", \"controllers/gamepad\", \"controllers/gamepad\""
94 "],\"legal\":[1, 2]},"
95 "{\"symbol\":\"multitap16\", \"name\":\"multitap16\", \"hname\":\"Multitap (16 buttons)\", \"controllers\":["
96 "\"controllers/gamepad16\", \"controllers/gamepad16\", \"controllers/gamepad16\","
97 "\"controllers/gamepad16\""
98 "],\"legal\":[1, 2]},"
99 "{\"symbol\":\"none\", \"name\":\"none\", \"hname\":\"None\", \"controllers\":[],\"legal\":[1, 2]},"
100 "{\"symbol\":\"superscope\", \"name\":\"superscope\", \"hname\":\"Super Scope\", \"controllers\":["
101 "\"controllers/superscope\""
103 "{\"symbol\":\"psystem\", \"name\":\"system\", \"hname\":\"system\", \"controllers\":["
104 "\"controllers/system\""
106 "{\"symbol\":\"psystem_hreset\", \"name\":\"system\", \"hname\":\"system\", \"controllers\":["
107 "\"controllers/system_hreset\""
109 "{\"symbol\":\"psystem_compact\", \"name\":\"system\", \"hname\":\"system\", \"controllers\":["
110 "\"controllers/system_compact\""
115 void show_data(unsigned char* buffer
, size_t bufsize
)
117 std::ostringstream s
;
118 for(unsigned i
= 0; i
< bufsize
; i
++)
119 s
<< std::hex
<< std::setfill('0') << std::setw(2) << (int)buffer
[i
] << " ";
120 std::cout
<< s
.str() << std::endl
;
123 void test_port(portctrl::type
* p
, unsigned bits
)
126 unsigned char buffer
[512];
127 unsigned char buffer2
[512];
128 unsigned char buffer3
[512];
129 memset(buffer
, 255, 512);
130 memset(buffer3
, 0, 512);
131 for(int i
= 0; i
< p
->storage_size
; i
++)
134 buffer
[bits
/ 8] &= ((1 << (bits
% 8)) - 1);
136 int x
= p
->serialize(p
, buffer
, out
);
140 //std::cout << p->name << ":\t" << out << std::endl;
142 if(out
[0] == '|') k
++;
143 int y
= p
->deserialize(p
, buffer2
, out
+ k
);
144 if(memcmp(buffer
, buffer2
, p
->storage_size
) || y
+ k
!= x
)
145 std::cerr
<< "Error! (" << out
<< ") [" << p
->hname
<< "]" << std::endl
;
147 if(p
->controller_info
->controllers
.size()) {
148 int pc
= rand() % p
->controller_info
->controllers
.size();
149 int pi
= rand() % p
->controller_info
->controllers
[pc
].buttons
.size();
151 if(p
->controller_info
->controllers
[pc
].buttons
[pi
].is_analog())
153 if(p
->controller_info
->controllers
[pc
].buttons
[pi
].type
== portctrl::button::TYPE_NULL
)
155 p
->write(p
, buffer3
, pc
, pi
, v
);
156 for(int i
= 0; i
< p
->controller_info
->controllers
.size(); i
++) {
157 for(int j
= 0; j
< p
->controller_info
->controllers
[pc
].buttons
.size(); j
++) {
158 int k2
= p
->read(p
, buffer3
, i
, j
);
159 if(k2
!= v
&& (i
== pc
&& j
== pi
)) {
160 std::cerr
<< "Error (" << i
<< "," << j
<< "," << k2
<< ")!=" << v
162 show_data(buffer3
, p
->storage_size
);
164 if(k2
!= 0 && (i
!= pc
|| j
!= pi
))
165 std::cerr
<< "Error (" << i
<< "," << j
<< "," << k2
<< ")!=0" << std::endl
;
175 gettimeofday(&tv
, NULL
);
176 return static_cast<uint64_t>(tv
.tv_sec
) * 1000000 + tv
.tv_usec
;
182 JSON::node
portsdata(ports_json
);
183 portctrl::type_generic
Sgamepad(portsdata
, "ports/0");
184 portctrl::type_generic
Sgamepad16(portsdata
, "ports/1");
185 portctrl::type_generic
Sygamepad16(portsdata
, "ports/2");
186 portctrl::type_generic
Sjustifier(portsdata
, "ports/3");
187 portctrl::type_generic
Sjustifiers(portsdata
, "ports/4");
188 portctrl::type_generic
Smouse(portsdata
, "ports/5");
189 portctrl::type_generic
Smultitap(portsdata
, "ports/6");
190 portctrl::type_generic
Smultitap16(portsdata
, "ports/7");
191 portctrl::type_generic
Snone(portsdata
, "ports/8");
192 portctrl::type_generic
Ssuperscope(portsdata
, "ports/9");
193 portctrl::type_generic
Spsystem(portsdata
, "ports/10");
194 portctrl::type_generic
Spsystem_hreset(portsdata
, "ports/11");
195 portctrl::type_generic
Spsystem_compact(portsdata
, "ports/12");
197 unsigned char buffer
[512];
200 s1
.ports
.push_back(&psystem
);
201 s1
.ports
.push_back(&multitap16
);
202 s1
.ports
.push_back(&multitap16
);
203 for(unsigned i
= 0; i
< 8; i
++)
204 s1
.logical_map
.push_back(std::make_pair(i
/ 4 + 1, i
% 4));
205 portctrl::type_set
& _fixed
= portctrl::type_set::make(s1
.ports
, s1
.portindex());
206 portctrl::frame
fixed(buffer
, _fixed
);
209 s2
.ports
.push_back(&Spsystem
);
210 s2
.ports
.push_back(&Smultitap16
);
211 s2
.ports
.push_back(&Smultitap16
);
212 for(unsigned i
= 0; i
< 8; i
++)
213 s2
.logical_map
.push_back(std::make_pair(i
/ 4 + 1, i
% 4));
214 portctrl::type_set
& _variable
= portctrl::type_set::make(s2
.ports
, s2
.portindex());
215 portctrl::frame
variable(buffer
, _variable
);
220 for(unsigned i
= 0; i
< 32; i
++)
224 uint64_t t1 = get_utime();
225 for(unsigned i = 0; i < 10000000; i++) {
226 fixed.serialize(out);
228 uint64_t d = get_utime() - t1;
229 std::cout << "Fixed Serialize: " << (double)d / 1000000 << std::endl;
232 for(unsigned i = 0; i < 10000000; i++) {
233 variable.serialize(out);
235 d = get_utime() - t1;
236 std::cout << "Variable Serialize: " << (double)d / 1000000 << std::endl;
239 for(unsigned i = 0; i < 10000000; i++) {
240 fixed.deserialize(out);
242 d = get_utime() - t1;
243 std::cout << "Fixed Unserialize: " << (double)d / 1000000 << std::endl;
246 for(unsigned i = 0; i < 10000000; i++) {
247 variable.deserialize(out);
249 d = get_utime() - t1;
250 std::cout << "Variable Unserialize: " << (double)d / 1000000 << std::endl;
255 std::cerr
<< "Running..." << std::endl
;
257 test_port(&Sgamepad
, 12);
258 test_port(&Sgamepad16
, 16);
259 test_port(&Sygamepad16
, 32);
260 test_port(&Sjustifier
, 2);
261 test_port(&Sjustifiers
, 4);
262 test_port(&Smouse
, 2);
263 test_port(&Smultitap
, 48);
264 test_port(&Smultitap16
, 64);
265 test_port(&Snone
, 0);
266 test_port(&Ssuperscope
, 4);
267 test_port(&Spsystem
, 2);
268 test_port(&Spsystem_hreset
, 3);
269 test_port(&Spsystem_compact
, 3);