Use virtual methods instead of pointers for core stuff
[lsnes.git] / src / emulation / make-ports.lua
blobed7a04ccd4bf5e570358f7135bf1ff6381d616e9
1 nextsym = 0;
3 stripcomma = function(y)
4 if #y > 0 and string.sub(y, #y - 1) == "," then
5 return string.sub(y, 0, #y - 1);
6 end
7 return y;
8 end
10 makesymbol = function()
11 nextsym = nextsym + 1;
12 return "X"..nextsym;
13 end
15 button="BUTTON";
16 axis="AXIS";
17 raxis="RAXIS";
18 taxis="TAXIS";
19 shadow="SHADOW";
20 shadow_axis="SHADOW_AXIS";
21 null="NULL";
23 if not arg[1] then
24 error("Expected input file");
25 end
26 dofile(arg[1]);
28 buttonsymbols = {};
30 for i = 1,#ports do
31 local port = ports[i];
32 print("namespace portdefs {");
33 local bits = 0;
34 local ints = 0;
35 local csyms = {};
36 local psym = makesymbol();
37 local psym2 = makesymbol();
38 for j = 1,#(port.controllers) do
39 local controller = port.controllers[j];
40 local csym = makesymbol();
41 local csym2 = makesymbol();
42 table.insert(csyms, csym2);
43 local bsyms={};
44 for k = 1,#(controller.buttons) do
45 local xbutton = controller.buttons[k];
46 local bsym = makesymbol();
47 if xbutton[1] == button then
48 table.insert(bsyms, bsym);
49 buttonsymbols[bsym] = "{port_controller_button::TYPE_BUTTON, U'" .. xbutton[2] ..
50 "', \"" .. xbutton[3] .. "\", false, 0, 0, false, \"" ..
51 (xbutton[5] or xbutton[2]) .. "\"}";
52 bits = bits + 1;
53 end
54 if xbutton[1] == axis then
55 table.insert(bsyms, bsym);
56 buttonsymbols[bsym] = "{port_controller_button::TYPE_AXIS, U'\\0',\"" .. xbutton[2]
57 .. "\", false, ".. xbutton[3] .. ", ".. xbutton[4] .. "," ..
58 (xbutton[5] and "true" or "false") .. ", NULL}";
59 ints = ints + 1;
60 end
61 if xbutton[1] == raxis then
62 table.insert(bsyms, bsym);
63 buttonsymbols[bsym] = "{port_controller_button::TYPE_RAXIS, U'\\0',\"" .. xbutton[2]
64 .. "\", false, ".. xbutton[3] .. ", ".. xbutton[4] .. "," ..
65 (xbutton[5] and "true" or "false") .. ", NULL}";
66 ints = ints + 1;
67 end
68 if xbutton[1] == taxis then
69 table.insert(bsyms, bsym);
70 buttonsymbols[bsym] = "{port_controller_button::TYPE_TAXIS, U'\\0',\"" .. xbutton[2]
71 .. "\", false, ".. xbutton[3] .. ", ".. xbutton[4] .. "," ..
72 (xbutton[5] and "true" or "false") .. ", NULL}";
73 ints = ints + 1;
74 end
75 if xbutton[1] == shadow then
76 table.insert(bsyms, bsym);
77 buttonsymbols[bsym] = "{port_controller_button::TYPE_BUTTON, U'" .. xbutton[2] ..
78 "', \"" .. xbutton[3] .. "\", true, 0, 0, false, NULL}";
79 bits = bits + 1;
80 end
81 if xbutton[1] == shadow_axis then
82 table.insert(bsyms, bsym);
83 buttonsymbols[bsym] = "{port_controller_button::TYPE_AXIS, U'\\0', \"" .. xbutton[2]
84 .. "\", true, 0, 0, false, NULL}";
85 ints = ints + 1;
86 end
87 if xbutton[1] == null then
88 table.insert(bsyms, bsym);
89 buttonsymbols[bsym] = "{port_controller_button::TYPE_NULL, U'\0', NULL, false, 0, 0,"
90 .. "false, NULL}";
91 end
92 end
93 print("\tport_controller "..csym2.." = {\""..controller.class.."\", \""..controller.name.."\", {");
94 for k = 1,#bsyms do
95 print("\t\t" .. buttonsymbols[bsyms[k]] .. ",");
96 end
97 print("\t}};");
98 end
99 local s = "{";
100 local f = true;
101 for j = 1,#csyms do
102 if not f then
103 s = s .. ",";
105 f = false;
106 s = s .."&"..csyms[j];
108 s = s .. "}"
109 print("\tport_controller_set "..psym2.." = {"..s.."};");
110 print("}");
111 print("struct _"..port.symbol.." : public port_type");
112 print("{");
113 print("\t_"..port.symbol.."() : port_type(\""..port.iname.."\", \""..port.hname.."\", "..i..","..
114 (math.floor((bits + 7) / 8) + 2 * ints)..")");
115 print("\t{");
116 print("\t\twrite = [](unsigned char* buffer, unsigned idx, unsigned ctrl, short x) -> void {");
117 print("\t\t\tswitch(idx) {");
118 local bit_l = 0;
119 local int_l = math.floor((bits + 7) / 8);
120 for j = 1,#(port.controllers) do
121 local controller = port.controllers[j];
122 print("\t\t\tcase "..(j-1)..":");
123 print("\t\t\t\tswitch(ctrl) {");
124 for k = 1,#(controller.buttons) do
125 local xbutton = controller.buttons[k];
126 local bt = xbutton[1];
127 print("\t\t\t\tcase "..(k-1)..":");
128 if (bt == button) or (bt == shadow) then
129 local bidx = math.floor(bit_l / 8);
130 local bmask = math.pow(2, bit_l % 8);
131 print("\t\t\t\t\tif(x) buffer["..bidx.."] |= "..bmask.."; else "..
132 "buffer["..bidx.."] &= ~"..bmask..";");
133 bit_l = bit_l + 1;
135 if (bt == axis) or (bt == raxis) or (bt == taxis) or (bt == shadow_axis) then
136 print("\t\t\t\t\tbuffer["..int_l.."] = (unsigned short)x;");
137 print("\t\t\t\t\tbuffer["..(int_l + 1).."] = ((unsigned short)x >> 8);");
138 int_l = int_l + 2;
140 print("\t\t\t\t\tbreak;");
142 print("\t\t\t\t};");
143 print("\t\t\t\tbreak;");
145 print("\t\t\t};");
146 print("\t\t};");
147 print("\t\tread = [](const unsigned char* buffer, unsigned idx, unsigned ctrl) -> short {");
148 local bit_l = 0;
149 local int_l = math.floor((bits + 7) / 8);
150 print("\t\t\tswitch(idx) {");
151 for j = 1,#(port.controllers) do
152 local controller = port.controllers[j];
153 print("\t\t\tcase "..(j-1)..":");
154 print("\t\t\t\tswitch(ctrl) {");
155 for k = 1,#(controller.buttons) do
156 local xbutton = controller.buttons[k];
157 local bt = xbutton[1];
158 print("\t\t\t\tcase "..(k-1)..":");
159 if (bt == button) or (bt == shadow) then
160 local bidx = math.floor(bit_l / 8);
161 local bmask = math.pow(2, bit_l % 8);
162 print("\t\t\t\t\treturn (buffer["..bidx.."] & "..bmask..") ? 1 : 0;");
163 bit_l = bit_l + 1;
165 if (bt == axis) or (bt == raxis) or (bt == taxis) or (bt == shadow_axis) then
166 print("\t\t\t\t\treturn (short)((unsigned short)buffer["..int_l.."] + ("..
167 "(unsigned short)buffer["..(int_l+1).."] << 8));");
168 int_l = int_l + 2;
171 print("\t\t\t\t};");
172 print("\t\t\t\tbreak;");
174 print("\t\t\t};");
175 print("\t\t\treturn 0;");
176 print("\t\t};");
177 print("\t\tserialize = [](const unsigned char* buffer, char* textbuf) -> size_t {");
178 local bit_l = 0;
179 local int_l = math.floor((bits + 7) / 8);
180 print("\t\t\tsize_t ptr = 0;");
181 print("\t\t\tshort tmp;");
182 for j = 1,#(port.controllers) do
183 local controller = port.controllers[j];
184 if j > 1 or port.legal[1] ~= 0 then
185 print("\t\t\ttextbuf[ptr++] = '|';");
187 for k = 1,#(controller.buttons) do
188 local xbutton = controller.buttons[k];
189 local bt = xbutton[1];
190 if (bt == button) or (bt == shadow) then
191 local bidx = math.floor(bit_l / 8);
192 local bmask = math.pow(2, bit_l % 8);
193 print("\t\t\ttextbuf[ptr++] = (buffer["..bidx.."] & "..bmask..") ? '"..
194 (xbutton[4] or xbutton[2]).."' : '.';");
195 bit_l = bit_l + 1;
198 for k = 1,#(controller.buttons) do
199 local xbutton = controller.buttons[k];
200 local bt = xbutton[1];
201 if (bt == axis) or (bt == raxis) or (bt == taxis) or (bt == shadow_axis) then
202 print("\t\t\t\ttmp = (short)((unsigned short)buffer["..int_l.."] + ("..
203 "(unsigned short)buffer["..(int_l+1).."] << 8));");
204 print("\t\t\t\tptr += sprintf(textbuf + ptr, \" %i\", tmp);");
205 int_l = int_l + 2;
209 print("\t\t\ttextbuf[ptr] = '\\0';");
210 print("\t\t\treturn ptr;");
211 print("\t\t};");
212 print("\t\tdeserialize = [](unsigned char* buffer, const char* textbuf) -> size_t {");
213 local bit_l = 0;
214 local int_l = math.floor((bits + 7) / 8);
215 if #(port.controllers) == 0 then
216 print("\t\t\treturn DESERIALIZE_SPECIAL_BLANK;");
217 else
218 print("\t\t\tmemset(buffer, 0, "..(math.floor((bits + 7) / 8) + 2 * ints)..");");
219 print("\t\t\tsize_t ptr = 0;");
220 print("\t\t\tshort tmp;");
221 for j = 1,#(port.controllers) do
222 local controller = port.controllers[j];
223 for k = 1,#(controller.buttons) do
224 local xbutton = controller.buttons[k];
225 local bt = xbutton[1];
226 if (bt == button) or (bt == shadow) then
227 local bidx = math.floor(bit_l / 8);
228 local bmask = math.pow(2, bit_l % 8);
229 print("\t\t\tif(read_button_value(textbuf, ptr))");
230 print("\t\t\t\tbuffer["..bidx.."] |= "..bmask..";");
231 bit_l = bit_l + 1;
234 for k = 1,#(controller.buttons) do
235 local xbutton = controller.buttons[k];
236 local bt = xbutton[1];
237 if (bt == axis) or (bt == raxis) or (bt == taxis) or (bt == shadow_axis) then
238 print("\t\t\ttmp = read_axis_value(textbuf, ptr);");
239 print("\t\t\tbuffer["..int_l.."] = (unsigned short)tmp;");
240 print("\t\t\tbuffer["..(int_l + 1).."] = ((unsigned short)tmp >> 8);");
241 int_l = int_l + 2;
244 print("\t\t\tskip_rest_of_field(textbuf, ptr, "..((j < #(port.controllers)) and 'true' or
245 'false')..");");
247 print("\t\t\treturn ptr;");
249 print("\t\t};");
250 print("\t\tlegal = [](unsigned c) -> int {");
251 for j = 1,#(port.legal) do
252 print("\t\t\tif(c == "..port.legal[j]..") return true;");
254 print("\t\t\treturn false;");
255 print("\t\t};");
256 print("\t\tused_indices = [](unsigned c) -> unsigned {");
257 for j = 1,#(port.controllers) do
258 print("\t\t\tif(c == "..(j-1)..") return "..#(port.controllers[j].buttons)..";");
260 print("\t\t\treturn 0;");
261 print("\t\t};");
262 print("\t\tcontroller_info = &portdefs::"..psym2..";");
263 print("\t}");
264 print("} "..port.symbol..";");
266 local s = "std::vector<port_type*> _port_types{ ";
267 for i = 1,#ports do
268 s = s .."&"..ports[i].symbol..", ";
270 s = stripcomma(s);
271 s = s .. "};";
272 print(s);