summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/cop400/cop410ds.c
blob: 638653151d09be3fbcba1f0da6e34a5827019306 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/***************************************************************************

    cop410ds.c

    National Semiconductor COP410 Emulator.

***************************************************************************/

#include "emu.h"

CPU_DISASSEMBLE( cop410 )
{
	UINT8 opcode = oprom[0];
	UINT8 next_opcode = oprom[1];
	UINT16 address;
	UINT32 flags = 0;
	int bytes = 1;

	if ((opcode >= 0x80 && opcode <= 0xBE) || (opcode >= 0xC0 && opcode <= 0xFE))
	{
		if ((pc & 0x3E0) >= 0x80 && (pc & 0x3E0) < 0x100) //JP pages 2,3
		{
			address = (UINT16)((pc & 0x380) | (opcode & 0x7F));
			sprintf(buffer, "JP %x", address);
		}
		else
		{
			if ((opcode & 0xC0) == 0xC0) //JP other pages
			{
				address = (UINT16)((pc & 0x3C0) | (opcode & 0x3F));
				sprintf(buffer, "JP %x", address);
			}
			else                    //JSRP
			{
				address = (UINT16)(0x80 | (opcode & 0x3F));
				sprintf(buffer, "JSRP %x", address);
				flags = DASMFLAG_STEP_OVER;
			}
		}
	}
	else if (opcode >= 0x08 && opcode <= 0x0F)
	{
		sprintf(buffer, "LBI 0,%u", ((opcode & 0xF) + 1) & 0xF);
	}
	else if (opcode >= 0x18 && opcode <= 0x1F)
	{
		sprintf(buffer, "LBI 1,%u", ((opcode & 0xF) + 1) & 0xF);
	}
	else if (opcode >= 0x28 && opcode <= 0x2F)
	{
		sprintf(buffer, "LBI 2,%u", ((opcode & 0xF) + 1) & 0xF);
	}
	else if (opcode >= 0x38 && opcode <= 0x3F)
	{
		sprintf(buffer, "LBI 3,%u", ((opcode & 0xF) + 1) & 0xF);
	}
	else if (opcode >= 0x51 && opcode <= 0x5F)
	{
		sprintf(buffer, "AISC %u", opcode & 0xF);
	}
	else if (opcode >= 0x60 && opcode <= 0x61)
	{
		address = ((opcode & 0x01) << 8) | next_opcode;
		sprintf(buffer, "JMP %x", address);
		bytes = 2;
	}
	else if (opcode >= 0x68 && opcode <= 0x69)
	{
		address = ((opcode & 0x01) << 8) | next_opcode;
		sprintf(buffer, "JSR %x", address);
		flags = DASMFLAG_STEP_OVER;
		bytes = 2;
	}
	else if (opcode >= 0x70 && opcode <= 0x7F)
	{
		sprintf(buffer, "STII %u", opcode & 0xF);
	}
	else
	{
		switch (opcode)
		{
		case 0:
			sprintf(buffer, "CLRA");
			break;

		case 1:
			sprintf(buffer, "SKMBZ 0");
			break;

		case 2:
			sprintf(buffer, "XOR");
			break;

		case 3:
			sprintf(buffer, "SKMBZ 2");
			break;

		case 4:
			sprintf(buffer, "XIS 0");
			break;

		case 5:
			sprintf(buffer, "LD 0");
			break;

		case 6:
			sprintf(buffer, "X 0");
			break;

		case 7:
			sprintf(buffer, "XDS 0");
			break;

		case 0x11:
			sprintf(buffer, "SKMBZ 1");
			break;

		case 0x13:
			sprintf(buffer, "SKMBZ 3");
			break;

		case 0x14:
			sprintf(buffer, "XIS 1");
			break;

		case 0x15:
			sprintf(buffer, "LD 1");
			break;

		case 0x16:
			sprintf(buffer, "X 1");
			break;

		case 0x17:
			sprintf(buffer, "XDS 1");
			break;

		case 0x20:
			sprintf(buffer, "SKC");
			break;

		case 0x21:
			sprintf(buffer, "SKE");
			break;

		case 0x22:
			sprintf(buffer, "SC");
			break;

		case 0x23:
			bytes = 2;

			if (next_opcode >= 0x80 && next_opcode <= 0xbf)
			{
				address = (UINT16)(next_opcode & 0x3F);
				sprintf(buffer, "XAD %x,%x", ((address & 0x30) >> 4),address & 0x0F);
			}
			else
			{
				sprintf(buffer, "Invalid");
			}
			break;

		case 0x24:
			sprintf(buffer, "XIS 2");
			break;

		case 0x25:
			sprintf(buffer, "LD 2");
			break;

		case 0x26:
			sprintf(buffer, "X 2");
			break;

		case 0x27:
			sprintf(buffer, "XDS 2");
			break;

		case 0x30:
			sprintf(buffer, "ASC");
			break;

		case 0x31:
			sprintf(buffer, "ADD");
			break;

		case 0x32:
			sprintf(buffer, "RC");
			break;

		case 0x33:
			bytes = 2;

			if (next_opcode >= 0x60 && next_opcode <= 0x6F)
			{
				sprintf(buffer, "LEI %x", next_opcode & 0xF);
			}
			else
			{
				switch (next_opcode)
				{
				case 0x01:
					sprintf(buffer, "SKGBZ 0");
					break;

				case 0x03:
					sprintf(buffer, "SKGBZ 2");
					break;

				case 0x11:
					sprintf(buffer, "SKGBZ 1");
					break;

				case 0x13:
					sprintf(buffer, "SKGBZ 3");
					break;

				case 0x21:
					sprintf(buffer, "SKGZ");
					break;

				case 0x2A:
					sprintf(buffer, "ING");
					break;

				case 0x2E:
					sprintf(buffer, "INL");
					break;

				case 0x38:
					sprintf(buffer, "HALT");
					break;

				case 0x3A:
					sprintf(buffer, "OMG");
					break;

				case 0x3C:
					sprintf(buffer, "CAMQ");
					break;

				case 0x3E:
					sprintf(buffer, "OBD");
					break;

				default:
					sprintf(buffer, "Invalid");
					break;
				}
				break;
			}

		case 0x34:
			sprintf(buffer, "XIS 3");
			break;

		case 0x35:
			sprintf(buffer, "LD 3");
			break;

		case 0x36:
			sprintf(buffer, "X 3");
			break;

		case 0x37:
			sprintf(buffer, "XDS 3");
			break;

		case 0x40:
			sprintf(buffer, "COMP");
			break;

		case 0x42:
			sprintf(buffer, "RMB 2");
			break;

		case 0x43:
			sprintf(buffer, "RMB 3");
			break;

		case 0x44:
			sprintf(buffer, "NOP");
			break;

		case 0x45:
			sprintf(buffer, "RMB 1");
			break;

		case 0x46:
			sprintf(buffer, "SMB 2");
			break;

		case 0x47:
			sprintf(buffer, "SMB 1");
			break;

		case 0x48:
			sprintf(buffer, "RET");
			flags = DASMFLAG_STEP_OUT;
			break;

		case 0x49:
			sprintf(buffer, "RETSK");
			flags = DASMFLAG_STEP_OUT;
			break;

		case 0x4B:
			sprintf(buffer, "SMB 3");
			break;

		case 0x4C:
			sprintf(buffer, "RMB 0");
			break;

		case 0x4D:
			sprintf(buffer, "SMB 0");
			break;

		case 0x4E:
			sprintf(buffer, "CBA");
			break;

		case 0x4F:
			sprintf(buffer, "XAS");
			break;

		case 0x50:
			sprintf(buffer, "CAB");
			break;

		case 0xBF:
			sprintf(buffer, "LQID");
			break;

		case 0xFF:
			sprintf(buffer, "JID");
			break;

		default:
			sprintf(buffer, "Invalid");
			break;
		}
	}

	return bytes | flags | DASMFLAG_SUPPORTED;
}
} }; //============================================================ // sdl_mouse_device //============================================================ class sdl_mouse_device : public sdl_device { public: mouse_state mouse; sdl_mouse_device(running_machine &machine, const char* name, input_module &module) : sdl_device(machine, name, DEVICE_CLASS_MOUSE, module), mouse({0}) { } void reset() override { memset(&mouse, 0, sizeof(mouse)); } void poll() override { mouse.lX = 0; mouse.lY = 0; sdl_device::poll(); } virtual void process_event(SDL_Event &sdlevent) override { switch (sdlevent.type) { case SDL_MOUSEMOTION: mouse.lX += sdlevent.motion.xrel * INPUT_RELATIVE_PER_PIXEL; mouse.lY += sdlevent.motion.yrel * INPUT_RELATIVE_PER_PIXEL; { int cx = -1, cy = -1; auto window = GET_FOCUS_WINDOW(&sdlevent.motion); if (window != nullptr && window->xy_to_render_target(sdlevent.motion.x, sdlevent.motion.y, &cx, &cy)) machine().ui_input().push_mouse_move_event(window->target(), cx, cy); } break; case SDL_MOUSEBUTTONDOWN: mouse.buttons[sdlevent.button.button - 1] = 0x80; //printf("But down %d %d %d %d %s\n", event.button.which, event.button.button, event.button.x, event.button.y, devinfo->name.c_str()); if (sdlevent.button.button == 1) { // FIXME Move static declaration static osd_ticks_t last_click = 0; static int last_x = 0; static int last_y = 0; int cx, cy; osd_ticks_t click = osd_ticks() * 1000 / osd_ticks_per_second(); auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != nullptr && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { machine().ui_input().push_mouse_down_event(window->target(), cx, cy); // FIXME Parameter ? if ((click - last_click < 250) && (cx >= last_x - 4 && cx <= last_x + 4) && (cy >= last_y - 4 && cy <= last_y + 4)) { last_click = 0; machine().ui_input().push_mouse_double_click_event(window->target(), cx, cy); } else { last_click = click; last_x = cx; last_y = cy; } } } else if (sdlevent.button.button == 3) { int cx, cy; auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != nullptr && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { machine().ui_input().push_mouse_rdown_event(window->target(), cx, cy); } } break; case SDL_MOUSEBUTTONUP: mouse.buttons[sdlevent.button.button - 1] = 0; //printf("But up %d %d %d %d\n", event.button.which, event.button.button, event.button.x, event.button.y); if (sdlevent.button.button == 1) { int cx, cy; auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != nullptr && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { machine().ui_input().push_mouse_up_event(window->target(), cx, cy); } } else if (sdlevent.button.button == 3) { int cx, cy; auto window = GET_FOCUS_WINDOW(&sdlevent.button); if (window != nullptr && window->xy_to_render_target(sdlevent.button.x, sdlevent.button.y, &cx, &cy)) { machine().ui_input().push_mouse_rup_event(window->target(), cx, cy); } } break; case SDL_MOUSEWHEEL: auto window = GET_FOCUS_WINDOW(&sdlevent.wheel); if (window != nullptr) machine().ui_input().push_mouse_wheel_event(window->target(), 0, 0, sdlevent.wheel.y, 3); break; } } }; //============================================================ // sdl_joystick_device //============================================================ // state information for a joystick struct sdl_joystick_state { INT32 axes[MAX_AXES]; INT32 buttons[MAX_BUTTONS]; INT32 hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS]; INT32 balls[MAX_AXES]; }; struct sdl_api_state { SDL_Joystick *device; SDL_JoystickID joystick_id; }; class sdl_joystick_device : public sdl_device { public: sdl_joystick_state joystick; sdl_api_state sdl_state; sdl_joystick_device(running_machine &machine, const char *name, input_module &module) : sdl_device(machine, name, DEVICE_CLASS_JOYSTICK, module), joystick({{0}}), sdl_state({ nullptr }) { } ~sdl_joystick_device() { if (sdl_state.device != nullptr) { SDL_JoystickClose(sdl_state.device); sdl_state.device = nullptr; } } void reset() override { memset(&joystick, 0, sizeof(joystick)); } void process_event(SDL_Event &sdlevent) override { switch (sdlevent.type) { case SDL_JOYAXISMOTION: joystick.axes[sdlevent.jaxis.axis] = (sdlevent.jaxis.value * 2); break; case SDL_JOYBALLMOTION: //printf("Ball %d %d\n", sdlevent.jball.xrel, sdlevent.jball.yrel); joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * INPUT_RELATIVE_PER_PIXEL; joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * INPUT_RELATIVE_PER_PIXEL; break; case SDL_JOYHATMOTION: if (sdlevent.jhat.value & SDL_HAT_UP) { joystick.hatsU[sdlevent.jhat.hat] = 0x80; } else { joystick.hatsU[sdlevent.jhat.hat] = 0; } if (sdlevent.jhat.value & SDL_HAT_DOWN) { joystick.hatsD[sdlevent.jhat.hat] = 0x80; } else { joystick.hatsD[sdlevent.jhat.hat] = 0; } if (sdlevent.jhat.value & SDL_HAT_LEFT) { joystick.hatsL[sdlevent.jhat.hat] = 0x80; } else { joystick.hatsL[sdlevent.jhat.hat] = 0; } if (sdlevent.jhat.value & SDL_HAT_RIGHT) { joystick.hatsR[sdlevent.jhat.hat] = 0x80; } else { joystick.hatsR[sdlevent.jhat.hat] = 0; } break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: joystick.buttons[sdlevent.jbutton.button] = (sdlevent.jbutton.state == SDL_PRESSED) ? 0x80 : 0; break; } } }; class sdl_sixaxis_joystick_device : public sdl_joystick_device { public: sdl_sixaxis_joystick_device(running_machine &machine, const char *name, input_module &module) : sdl_joystick_device(machine, name, module) { } void process_event(SDL_Event &sdlevent) override { switch (sdlevent.type) { case SDL_JOYAXISMOTION: { int axis = sdlevent.jaxis.axis; if (axis <= 3) { joystick.axes[sdlevent.jaxis.axis] = (sdlevent.jaxis.value * 2); } else { int magic = (sdlevent.jaxis.value / 2) + 16384; joystick.axes[sdlevent.jaxis.axis] = magic; } } break; default: // Call the base for other events sdl_joystick_device::process_event(sdlevent); break; } } }; //============================================================ // sdl_input_module //============================================================ class sdl_input_module : public input_module_base, public sdl_event_subscriber { public: sdl_input_module(const char *type) : input_module_base(type, "sdl") { } void input_init(running_machine &machine) override { if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED) { osd_printf_warning("Debug Build: Disabling input grab for -debug\n"); set_mouse_enabled(false); } } void exit() override { // unsubscribe for events sdl_event_manager::instance().unsubscribe(this); input_module_base::exit(); } void before_poll(running_machine& machine) override { // Tell the event manager to process events and push them to the devices sdl_event_manager::instance().process_events(machine); } bool should_poll_devices(running_machine& machine) override { return sdl_event_manager::instance().has_focus() && input_enabled(); } virtual void handle_event(SDL_Event &sdlevent) override { // By default dispatch event to every device for (int i = 0; i < devicelist()->size(); i++) downcast<sdl_device*>(devicelist()->at(i))->queue_events(&sdlevent, 1); } }; //============================================================ // sdl_keyboard_module //============================================================ class sdl_keyboard_module : public sdl_input_module { keyboard_trans_table * m_key_trans_table; public: sdl_keyboard_module() : sdl_input_module(OSD_KEYBOARDINPUT_PROVIDER), m_key_trans_table(nullptr) { } void input_init(running_machine &machine) override { sdl_input_module::input_init(machine); static int event_types[] = { static_cast<int>(SDL_KEYDOWN), static_cast<int>(SDL_KEYUP), static_cast<int>(SDL_TEXTINPUT) }; sdl_event_manager::instance().subscribe(event_types, ARRAY_LENGTH(event_types), this); sdl_keyboard_device *devinfo; // Read our keymap and store a pointer to our table m_key_trans_table = sdlinput_read_keymap(machine); keyboard_trans_table& local_table = *m_key_trans_table; osd_printf_verbose("Keyboard: Start initialization\n"); // SDL only has 1 keyboard add it now devinfo = devicelist()->create_device<sdl_keyboard_device>(machine, "System keyboard", *this); // populate it for (int keynum = 0; local_table[keynum].mame_key != ITEM_ID_INVALID; keynum++) { input_item_id itemid = local_table[keynum].mame_key; // generate the default / modified name char defname[20]; snprintf(defname, sizeof(defname) - 1, "%s", local_table[keynum].ui_name); devinfo->device()->add_item(defname, itemid, generic_button_get_state<std::int32_t>, &devinfo->keyboard.state[local_table[keynum].sdl_scancode]); } osd_printf_verbose("Keyboard: Registered %s\n", devinfo->name()); osd_printf_verbose("Keyboard: End initialization\n"); } private: static keyboard_trans_table* sdlinput_read_keymap(running_machine &machine) { char *keymap_filename; FILE *keymap_file; int line = 1; int index, i, sk, vk, ak; char buf[256]; char mks[41]; char sks[41]; char kns[41]; int sdl2section = 0; keyboard_trans_table &default_table = keyboard_trans_table::instance(); if (!machine.options().bool_value(SDLOPTION_KEYMAP)) return &default_table; keymap_filename = (char *)downcast<sdl_options &>(machine.options()).keymap_file(); osd_printf_verbose("Keymap: Start reading keymap_file %s\n", keymap_filename); keymap_file = fopen(keymap_filename, "r"); if (keymap_file == nullptr) { osd_printf_warning("Keymap: Unable to open keymap %s, using default\n", keymap_filename); return &default_table; } // Allocate a block of translation entries big enough to hold what's in the default table auto key_trans_entries = std::make_unique<key_trans_entry[]>(default_table.size()); // copy the elements from the default table for (int i = 0; i < default_table.size(); i++) key_trans_entries[i] = default_table[i]; // Allocate the trans table to be associated with the machine so we don't have to free it keyboard_trans_table *custom_table = auto_alloc(machine, keyboard_trans_table(std::move(key_trans_entries), default_table.size())); while (!feof(keymap_file)) { char *ret = fgets(buf, 255, keymap_file); if (ret && buf[0] != '\n' && buf[0] != '#') { buf[255] = 0; i = strlen(buf); if (i && buf[i - 1] == '\n') buf[i - 1] = 0; if (strncmp(buf, "[SDL2]", 6) == 0) { sdl2section = 1; } else if (((SDLMAME_SDL2) ^ sdl2section) == 0) { mks[0] = 0; sks[0] = 0; memset(kns, 0, ARRAY_LENGTH(kns)); sscanf(buf, "%40s %40s %x %x %40c\n", mks, sks, &vk, &ak, kns); index = default_table.lookup_mame_index(mks); sk = lookup_sdl_code(sks); if (sk >= 0 && index >= 0) { key_trans_entry &entry = (*custom_table)[index]; entry.sdl_key = sk; // vk and ak are not really needed //key_trans_table[index][VIRTUAL_KEY] = vk; //key_trans_table[index][ASCII_KEY] = ak; entry.ui_name = auto_alloc_array(machine, char, strlen(kns) + 1); strcpy(entry.ui_name, kns); osd_printf_verbose("Keymap: Mapped <%s> to <%s> with ui-text <%s>\n", sks, mks, kns); } else osd_printf_warning("Keymap: Error on line %d - %s key not found: %s\n", line, (sk<0) ? "sdl" : "mame", buf); } } line++; } fclose(keymap_file); osd_printf_verbose("Keymap: Processed %d lines\n", line); return custom_table; } }; //============================================================ // sdl_mouse_module //============================================================ class sdl_mouse_module : public sdl_input_module { public: sdl_mouse_module() : sdl_input_module(OSD_MOUSEINPUT_PROVIDER) { } virtual void input_init(running_machine &machine) override { sdl_input_module::input_init(machine); static int event_types[] = { static_cast<int>(SDL_MOUSEMOTION), static_cast<int>(SDL_MOUSEBUTTONDOWN), static_cast<int>(SDL_MOUSEBUTTONUP), static_cast<int>(SDL_MOUSEWHEEL) }; sdl_event_manager::instance().subscribe(event_types, ARRAY_LENGTH(event_types), this); sdl_mouse_device *devinfo; char defname[20]; int button; osd_printf_verbose("Mouse: Start initialization\n"); // SDL currently only supports one mouse devinfo = devicelist()->create_device<sdl_mouse_device>(machine, "System mouse", *this); // add the axes devinfo->device()->add_item("X", ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo->mouse.lX); devinfo->device()->add_item("Y", ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &devinfo->mouse.lY); for (button = 0; button < 4; button++) { input_item_id itemid = (input_item_id)(ITEM_ID_BUTTON1 + button); snprintf(defname, sizeof(defname), "B%d", button + 1); devinfo->device()->add_item(defname, itemid, generic_button_get_state<std::int32_t>, &devinfo->mouse.buttons[button]); } osd_printf_verbose("Mouse: Registered %s\n", devinfo->name()); osd_printf_verbose("Mouse: End initialization\n"); } }; static void devmap_register(device_map_t *devmap, int physical_idx, const std::string &name) { int found = 0; int stick, i; for (i = 0; i < MAX_DEVMAP_ENTRIES; i++) { if (strcmp(name.c_str(), devmap->map[i].name.c_str()) == 0 && devmap->map[i].physical < 0) { devmap->map[i].physical = physical_idx; found = 1; devmap->logical[physical_idx] = i; } } if (found == 0) { stick = devmap_leastfree(devmap); devmap->map[stick].physical = physical_idx; devmap->map[stick].name = name; devmap->logical[physical_idx] = stick; } } //============================================================ // sdl_joystick_module //============================================================ class sdl_joystick_module : public sdl_input_module { private: device_map_t m_joy_map; bool m_sixaxis_mode; public: sdl_joystick_module() : sdl_input_module(OSD_JOYSTICKINPUT_PROVIDER), m_sixaxis_mode(false) { } virtual void exit() override { sdl_input_module::exit(); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } virtual void input_init(running_machine &machine) override { SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { osd_printf_error("Could not initialize SDL Joystick: %s.\n", SDL_GetError()); return; } sdl_input_module::input_init(machine); char tempname[512]; m_sixaxis_mode = downcast<const sdl_options*>(options())->sixaxis(); devmap_init(machine, &m_joy_map, SDLOPTION_JOYINDEX, 8, "Joystick mapping"); osd_printf_verbose("Joystick: Start initialization\n"); int physical_stick; for (physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++) { std::string joy_name = remove_spaces(SDL_JoystickNameForIndex(physical_stick)); devmap_register(&m_joy_map, physical_stick, joy_name.c_str()); } for (int stick = 0; stick < MAX_DEVMAP_ENTRIES; stick++) { sdl_joystick_device *devinfo = create_joystick_device(machine, &m_joy_map, stick, DEVICE_CLASS_JOYSTICK); if (devinfo == nullptr) continue; physical_stick = m_joy_map.map[stick].physical; SDL_Joystick *joy = SDL_JoystickOpen(physical_stick); devinfo->sdl_state.device = joy; devinfo->sdl_state.joystick_id = SDL_JoystickInstanceID(joy); osd_printf_verbose("Joystick: %s\n", SDL_JoystickNameForIndex(physical_stick)); osd_printf_verbose("Joystick: ... %d axes, %d buttons %d hats %d balls\n", SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumHats(joy), SDL_JoystickNumBalls(joy)); osd_printf_verbose("Joystick: ... Physical id %d mapped to logical id %d\n", physical_stick, stick + 1); // loop over all axes for (int axis = 0; axis < SDL_JoystickNumAxes(joy); axis++) { input_item_id itemid; if (axis < INPUT_MAX_AXIS) itemid = (input_item_id)(ITEM_ID_XAXIS + axis); else if (axis < INPUT_MAX_AXIS + INPUT_MAX_ADD_ABSOLUTE) itemid = (input_item_id)(ITEM_ID_ADD_ABSOLUTE1 - INPUT_MAX_AXIS + axis); else itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE; snprintf(tempname, sizeof(tempname), "A%d %s", axis, devinfo->name()); devinfo->device()->add_item(tempname, itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.axes[axis]); } // loop over all buttons for (int button = 0; button < SDL_JoystickNumButtons(joy); button++) { input_item_id itemid; devinfo->joystick.buttons[button] = 0; if (button < INPUT_MAX_BUTTONS) itemid = (input_item_id)(ITEM_ID_BUTTON1 + button); else if (button < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH) itemid = (input_item_id)(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + button); else itemid = ITEM_ID_OTHER_SWITCH; snprintf(tempname, sizeof(tempname), "button %d", button); devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.buttons[button]); } // loop over all hats for (int hat = 0; hat < SDL_JoystickNumHats(joy); hat++) { input_item_id itemid; snprintf(tempname, sizeof(tempname), "hat %d Up", hat); itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + 4 * hat : ITEM_ID_OTHER_SWITCH); devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsU[hat]); snprintf(tempname, sizeof(tempname), "hat %d Down", hat); itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + 4 * hat : ITEM_ID_OTHER_SWITCH); devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsD[hat]); snprintf(tempname, sizeof(tempname), "hat %d Left", hat); itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + 4 * hat : ITEM_ID_OTHER_SWITCH); devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsL[hat]); snprintf(tempname, sizeof(tempname), "hat %d Right", hat); itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + 4 * hat : ITEM_ID_OTHER_SWITCH); devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsR[hat]); } // loop over all (track)balls for (int ball = 0; ball < SDL_JoystickNumBalls(joy); ball++) { int itemid; if (ball * 2 < INPUT_MAX_ADD_RELATIVE) itemid = ITEM_ID_ADD_RELATIVE1 + ball * 2; else itemid = ITEM_ID_OTHER_AXIS_RELATIVE; snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2, devinfo->name()); devinfo->device()->add_item(tempname, (input_item_id)itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2]); snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2 + 1, devinfo->name()); devinfo->device()->add_item(tempname, (input_item_id)(itemid + 1), generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2 + 1]); } } static int event_types[] = { static_cast<int>(SDL_JOYAXISMOTION), static_cast<int>(SDL_JOYBALLMOTION), static_cast<int>(SDL_JOYHATMOTION), static_cast<int>(SDL_JOYBUTTONDOWN), static_cast<int>(SDL_JOYBUTTONUP) }; sdl_event_manager::instance().subscribe(event_types, ARRAY_LENGTH(event_types), this); osd_printf_verbose("Joystick: End initialization\n"); } virtual void handle_event(SDL_Event &sdlevent) override { // Figure out which joystick this event id destined for for (int i = 0; i < devicelist()->size(); i++) { auto joy = downcast<sdl_joystick_device*>(devicelist()->at(i)); // If we find a matching joystick, dispatch the event to the joystick if (joy->sdl_state.joystick_id == sdlevent.jdevice.which) joy->queue_events(&sdlevent, 1); } } private: sdl_joystick_device* create_joystick_device(running_machine &machine, device_map_t *devmap, int index, input_device_class devclass) { sdl_joystick_device *devinfo = nullptr; char tempname[20]; if (devmap->map[index].name.length() == 0) { /* only map place holders if there were mappings specified is enabled */ if (devmap->initialized) { snprintf(tempname, ARRAY_LENGTH(tempname), "NC%d", index); devinfo = m_sixaxis_mode ? devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, tempname, *this) : devicelist()->create_device<sdl_joystick_device>(machine, tempname, *this); } return nullptr; } else { devinfo = m_sixaxis_mode ? devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, devmap->map[index].name.c_str(), *this) : devicelist()->create_device<sdl_joystick_device>(machine, devmap->map[index].name.c_str(), *this); } return devinfo; } }; #else MODULE_NOT_SUPPORTED(sdl_keyboard_module, OSD_KEYBOARDINPUT_PROVIDER, "sdl") MODULE_NOT_SUPPORTED(sdl_mouse_module, OSD_MOUSEINPUT_PROVIDER, "sdl") MODULE_NOT_SUPPORTED(sdl_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "sdl") #endif MODULE_DEFINITION(KEYBOARDINPUT_SDL, sdl_keyboard_module) MODULE_DEFINITION(MOUSEINPUT_SDL, sdl_mouse_module) MODULE_DEFINITION(JOYSTICKINPUT_SDL, sdl_joystick_module)