Actually call on_reset callback
[lsnes.git] / src / test / gptest.cpp
blob4012cac25a12d6f0d1ddfff1d8d5467707be3be3
1 #include "interface/controller.hpp"
2 #include "controller-parse.hpp"
3 #include <iostream>
4 #include <sstream>
5 #include <iomanip>
6 #include <cstdlib>
7 #include <sys/time.h>
9 #include "../src/emulation/bsnes-legacy/ports.inc"
11 const char* ports_json = "{"
12 "\"buttons\":{"
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}"
43 "},\"controllers\":{"
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\""
47 "]},"
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\""
52 "]},"
53 "\"justifier\":{\"type\":\"justifier\", \"class\":\"justifier\", \"buttons\":["
54 "\"buttons/xaxis\", \"buttons/yaxis\", \"buttons/trigger\", \"buttons/start\""
55 "]},"
56 "\"mouse\":{\"type\":\"mouse\", \"class\":\"mouse\", \"buttons\":["
57 "\"buttons/xmotion\", \"buttons/ymotion\", \"buttons/L\", \"buttons/R\""
58 "]},"
59 "\"superscope\":{\"type\":\"superscope\", \"class\":\"superscope\", \"buttons\":["
60 "\"buttons/xaxis\", \"buttons/yaxis\", \"buttons/trigger\", \"buttons/cursor\", \"buttons/turbo\","
61 "\"buttons/pause\""
62 "]},"
63 "\"system\":{\"type\":\"(system)\", \"class\":\"(system)\", \"buttons\":["
64 "\"buttons/framesync\", \"buttons/reset\", \"buttons/rhigh\", \"buttons/rlow\""
65 "]},"
66 "\"system_hreset\":{\"type\":\"(system)\", \"class\":\"(system)\", \"buttons\":["
67 "\"buttons/framesync\", \"buttons/reset\", \"buttons/rhigh\", \"buttons/rlow\", \"buttons/hard\""
68 "]},"
69 "\"system_compact\":{\"type\":\"(system)\", \"class\":\"(system)\", \"buttons\":["
70 "\"buttons/framesync\", \"buttons/reset\", \"buttons/shadownull\", \"buttons/shadownull\","
71 "\"buttons/hard\""
72 "]}"
73 "},\"ports\":["
74 "{\"symbol\":\"gamepad\", \"name\":\"gamepad\", \"hname\":\"gamepad\", \"controllers\":["
75 "\"controllers/gamepad\""
76 "],\"legal\":[1,2]},"
77 "{\"symbol\":\"gamepad16\", \"name\":\"gamepad16\", \"hname\":\"gamepad (16 buttons)\", \"controllers\":["
78 "\"controllers/gamepad16\""
79 "],\"legal\":[1,2]},"
80 "{\"symbol\":\"ygamepad16\", \"name\":\"ygamepad16\", \"hname\":\"Y-cabled gamepad (16 buttons)\", \"controllers\":["
81 "\"controllers/gamepad16\", \"controllers/gamepad16\""
82 "],\"legal\":[1,2]},"
83 "{\"symbol\":\"justifier\", \"name\":\"justifier\", \"hname\":\"Justifier\", \"controllers\":["
84 "\"controllers/justifier\""
85 "],\"legal\":[2]},"
86 "{\"symbol\":\"justifiers\", \"name\":\"justifiers\", \"hname\":\"2 Justifiers\", \"controllers\":["
87 "\"controllers/justifier\", \"controllers/justifier\""
88 "],\"legal\":[2]},"
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\""
102 "],\"legal\":[2]},"
103 "{\"symbol\":\"psystem\", \"name\":\"system\", \"hname\":\"system\", \"controllers\":["
104 "\"controllers/system\""
105 "],\"legal\":[0]},"
106 "{\"symbol\":\"psystem_hreset\", \"name\":\"system\", \"hname\":\"system\", \"controllers\":["
107 "\"controllers/system_hreset\""
108 "],\"legal\":[0]},"
109 "{\"symbol\":\"psystem_compact\", \"name\":\"system\", \"hname\":\"system\", \"controllers\":["
110 "\"controllers/system_compact\""
111 "],\"legal\":[0]}"
113 "}";
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)
125 char out[512];
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++)
132 buffer[i] = rand();
133 if(bits % 8) {
134 buffer[bits / 8] &= ((1 << (bits % 8)) - 1);
136 int x = p->serialize(p, buffer, out);
137 out[x] = '|';
138 out[x+1] = 'X';
139 out[x+2] = '\0';
140 //std::cout << p->name << ":\t" << out << std::endl;
141 int k = 0;
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();
150 short v = 1;
151 if(p->controller_info->controllers[pc].buttons[pi].is_analog())
152 v = rand();
153 if(p->controller_info->controllers[pc].buttons[pi].type == portctrl::button::TYPE_NULL)
154 v = 0;
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
161 << std::endl;
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;
172 uint64_t get_utime()
174 struct timeval tv;
175 gettimeofday(&tv, NULL);
176 return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
179 int main()
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];
199 controller_set s1;
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);
208 controller_set s2;
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);
217 char out[512];
218 srand(time(NULL));
220 for(unsigned i = 0; i < 32; i++)
221 buffer[i] = rand();
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;
231 t1 = get_utime();
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;
238 t1 = get_utime();
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;
245 t1 = get_utime();
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;
251 return 0;
254 srand(time(NULL));
255 std::cerr << "Running..." << std::endl;
256 while(true) {
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);
271 return 0;