void handle_event(XEvent &xevent) override { for (int i = 0; i < devicelist()->size(); i++) { downcast<x11_input_device*>(devicelist()->at(i))->queue_events(&xevent, 1); } }
bool handle_input_event(input_event eventid, void* eventdata) override { // Only handle raw input data if (!input_enabled() || eventid != INPUT_EVENT_RAWINPUT) return FALSE; HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT*>(eventdata); BYTE small_buffer[4096]; std::unique_ptr<BYTE[]> larger_buffer; LPBYTE data = small_buffer; BOOL result; UINT size; // ignore if not enabled if (!input_enabled()) return FALSE; // determine the size of databuffer we need if ((*get_rawinput_data)(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0) return FALSE; // if necessary, allocate a temporary buffer and fetch the data if (size > sizeof(small_buffer)) { larger_buffer = std::make_unique<BYTE[]>(size); data = larger_buffer.get(); if (data == nullptr) return FALSE; } // fetch the data and process the appropriate message types result = (*get_rawinput_data)(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)); if (result) { std::lock_guard<std::mutex> scope_lock(m_module_lock); rawinput_device *devinfo; // find the device in the list and update for (int i = 0; i < devicelist()->size(); i++) { devinfo = dynamic_cast<rawinput_device*>(devicelist()->at(i)); if (devinfo) { RAWINPUT *input = reinterpret_cast<RAWINPUT*>(data); if (input->header.hDevice == devinfo->device_handle()) { devinfo->queue_events(input, 1); result = TRUE; } } } } return result; }
bool handle_input_event(input_event eventid, void* eventdata) override { // Only handle raw input data if (!input_enabled() || eventid != INPUT_EVENT_RAWINPUT) return false; HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT*>(eventdata); BYTE small_buffer[4096]; std::unique_ptr<BYTE[]> larger_buffer; LPBYTE data = small_buffer; UINT size; // ignore if not enabled if (!input_enabled()) return false; // determine the size of databuffer we need if ((*get_rawinput_data)(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0) return false; // if necessary, allocate a temporary buffer and fetch the data if (size > sizeof(small_buffer)) { larger_buffer = std::make_unique<BYTE[]>(size); data = larger_buffer.get(); if (data == nullptr) return false; } // fetch the data and process the appropriate message types bool result = (*get_rawinput_data)(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)); if (result) { std::lock_guard<std::mutex> scope_lock(m_module_lock); RAWINPUT *input = reinterpret_cast<RAWINPUT*>(data); // find the device in the list and update auto target_device = std::find_if(devicelist()->begin(), devicelist()->end(), [input](auto &device) { auto devinfo = dynamic_cast<rawinput_device*>(device.get()); return devinfo != nullptr && input->header.hDevice == devinfo->device_handle(); }); if (target_device != devicelist()->end()) { static_cast<rawinput_device*>((*target_device).get())->queue_events(input, 1); return true; } } return false; }
TDevice* create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice) { TDevice* devinfo = nullptr; INT name_length = 0; // determine the length of the device name, allocate it, and fetch it if not nameless if (get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, NULL, &name_length) != 0) return nullptr; std::unique_ptr<TCHAR[]> tname = std::make_unique<TCHAR[]>(name_length + 1); if (name_length > 1 && get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1) return nullptr; // if this is an RDP name, skip it if (_tcsstr(tname.get(), TEXT("Root#RDP_")) != NULL) return nullptr; // improve the name and then allocate a device tname = std::unique_ptr<TCHAR[]>(rawinput_device_improve_name(tname.release())); // convert name to utf8 auto osd_deleter = [](void *ptr) { osd_free(ptr); }; auto utf8_name = std::unique_ptr<char, decltype(osd_deleter)>(utf8_from_tstring(tname.get()), osd_deleter); devinfo = devicelist()->create_device<TDevice>(machine, utf8_name.get(), *this); // Add the handle devinfo->set_handle(rawinputdevice->hDevice); return devinfo; }
TDevice* create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice) { TDevice* devinfo; UINT name_length = 0; // determine the length of the device name, allocate it, and fetch it if not nameless if ((*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0) return nullptr; std::unique_ptr<TCHAR[]> tname = std::make_unique<TCHAR[]>(name_length + 1); if (name_length > 1 && (*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1) return nullptr; // if this is an RDP name, skip it if (_tcsstr(tname.get(), TEXT("Root#RDP_")) != nullptr) return nullptr; // improve the name and then allocate a device std::wstring name = rawinput_device_improve_name(tname.get()); // convert name to utf8 std::string utf8_name = osd::text::from_wstring(name.c_str()); // set device id to raw input name std::string utf8_id = osd::text::from_wstring(tname.get()); devinfo = devicelist()->create_device<TDevice>(machine, utf8_name.c_str(), utf8_id.c_str(), *this); // Add the handle devinfo->set_handle(rawinputdevice->hDevice); return devinfo; }
bool handle_input_event(input_event eventid, void *eventdata) override { if (!input_enabled()) return false; KeyPressEventArgs *args; switch (eventid) { case INPUT_EVENT_KEYDOWN: case INPUT_EVENT_KEYUP: args = static_cast<KeyPressEventArgs*>(eventdata); devicelist()->for_each_device([args](auto device) { auto keyboard = dynamic_cast<win32_keyboard_device*>(device); if (keyboard != nullptr) keyboard->queue_events(args, 1); }); return true; default: return false; } }
virtual void input_init(running_machine &machine) override { win32_mouse_device *devinfo; int axisnum, butnum; if (!input_enabled() || !mouse_enabled()) return; // allocate a device devinfo = devicelist()->create_device<win32_mouse_device>(machine, "Win32 Mouse 1", *this); if (devinfo == nullptr) return; // populate the axes for (axisnum = 0; axisnum < 2; axisnum++) { devinfo->device()->add_item( default_axis_name[axisnum], static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum), generic_axis_get_state<LONG>, &devinfo->mouse.lX + axisnum); } // populate the buttons for (butnum = 0; butnum < 2; butnum++) { devinfo->device()->add_item( default_button_name(butnum), static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum), generic_button_get_state<BYTE>, &devinfo->mouse.rgbButtons[butnum]); } }
machine_config::machine_config(const game_driver &gamedrv, emu_options &options) : m_minimum_quantum(attotime::zero), m_perfect_cpu_quantum(NULL), m_watchdog_vblank_count(0), m_watchdog_time(attotime::zero), m_nvram_handler(NULL), m_memcard_handler(NULL), m_video_attributes(0), m_gfxdecodeinfo(NULL), m_total_colors(0), m_default_layout(NULL), m_gamedrv(gamedrv), m_options(options) { // construct the config (*gamedrv.machine_config)(*this, NULL); // intialize slot devices - make sure that any required devices have been allocated device_slot_interface *slot = NULL; for (bool gotone = m_devicelist.first(slot); gotone; gotone = slot->next(slot)) { const slot_interface *intf = slot->get_slot_interfaces(); if (intf != NULL) { device_t &owner = slot->device(); const char *selval = options.value(owner.tag()); if (!options.exists(owner.tag())) selval = slot->get_default_card(devicelist(), options); if (selval != NULL && strlen(selval)!=0) { bool found = false; for (int i = 0; intf[i].name != NULL; i++) { if (strcmp(selval, intf[i].name) == 0) { device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, 0); found = true; if (!options.exists(owner.tag())) device_t::static_set_input_default(*new_dev, slot->input_ports_defaults()); } } if (!found) throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()); } } } // when finished, set the game driver device_t *root = m_devicelist.find("root"); if (root == NULL) throw emu_fatalerror("Machine configuration missing driver_device"); driver_device::static_set_game(*root, gamedrv); // then notify all devices that their configuration is complete for (device_t *device = m_devicelist.first(); device != NULL; device = device->next()) if (!device->configured()) device->config_complete(); }
device_t &running_machine::add_dynamic_device(device_t &owner, device_type type, const char *tag, UINT32 clock) { // allocate and append this device astring fulltag; owner.subtag(fulltag, tag); device_t &device = const_cast<device_list &>(devicelist()).append(fulltag, *type(m_config, fulltag, &owner, clock)); // append any machine config additions from new devices for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next()) if (!curdevice->configured()) { machine_config_constructor machconfig = curdevice->machine_config_additions(); if (machconfig != NULL) (*machconfig)(const_cast<machine_config &>(m_config), curdevice); } // notify any new devices that their configurations are complete for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next()) if (!curdevice->configured()) curdevice->config_complete(); return device; }
x11_lightgun_device* create_lightgun_device(running_machine &machine, int index) { x11_lightgun_device *devinfo = nullptr; char tempname[20]; if (m_lightgun_map.map[index].name.length() == 0) { if (m_lightgun_map.initialized) { snprintf(tempname, ARRAY_LENGTH(tempname), "NC%d", index); devinfo = devicelist()->create_device<x11_lightgun_device>(machine, tempname, *this); } return nullptr; } else { devinfo = devicelist()->create_device<x11_lightgun_device>(machine, m_lightgun_map.map[index].name.c_str(), *this); } return devinfo; }
bool handle_input_event(input_event eventid, void* eventdata) override { if (!input_enabled() || !lightgun_enabled() || eventid != INPUT_EVENT_MOUSE_BUTTON) return false; auto args = static_cast<MouseButtonEventArgs*>(eventdata); devicelist()->for_each_device([args](auto device) { auto lightgun = dynamic_cast<win32_lightgun_device*>(device); if (lightgun != nullptr) lightgun->queue_events(args, 1); }); return true; }
virtual void input_init(running_machine &machine) override { // Add a single win32 keyboard device that we'll monitor using Win32 win32_keyboard_device *devinfo = devicelist()->create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", *this); keyboard_trans_table &table = keyboard_trans_table::instance(); // populate it for (int keynum = 0; keynum < MAX_KEYS; keynum++) { input_item_id itemid = table.map_di_scancode_to_itemid(keynum); char name[20]; // generate/fetch the name _snprintf(name, ARRAY_LENGTH(name), "Scan%03d", keynum); // add the item to the device devinfo->device()->add_item(name, itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]); } }
void input_init(running_machine &machine) override { // get the number of devices, allocate a device list, and fetch it int device_count = 0; if (get_rawinput_device_list(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0) return; if (device_count == 0) return; auto rawinput_devices = std::make_unique<RAWINPUTDEVICELIST[]>(device_count); if (get_rawinput_device_list(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) return; // iterate backwards through devices; new devices are added at the head for (int devnum = device_count - 1; devnum >= 0; devnum--) { RAWINPUTDEVICELIST *device = &rawinput_devices[devnum]; add_rawinput_device(machine, device); } // don't enable global inputs when debugging if (!machine.options().debug()) { m_global_inputs_enabled = downcast<windows_options &>(machine.options()).global_inputs(); } // If we added no devices, no need to register for notifications if (devicelist()->size() == 0) return; // finally, register to receive raw input WM_INPUT messages if we found devices RAWINPUTDEVICE registration; registration.usUsagePage = usagepage(); registration.usUsage = usage(); registration.dwFlags = m_global_inputs_enabled ? 0x00000100 : 0; registration.hwndTarget = win_window_list->m_hwnd; // register the device register_rawinput_devices(®istration, 1, sizeof(registration)); }
virtual void input_init(running_machine &machine) override { int max_guns = downcast<windows_options&>(machine.options()).dual_lightgun() ? 2 : 1; // allocate the lightgun devices for (int gunnum = 0; gunnum < max_guns; gunnum++) { static const char *const gun_names[] = { "Win32 Gun 1", "Win32 Gun 2" }; win32_lightgun_device *devinfo; int axisnum, butnum; // allocate a device devinfo = devicelist()->create_device<win32_lightgun_device>(machine, gun_names[gunnum], *this); if (devinfo == nullptr) break; // populate the axes for (axisnum = 0; axisnum < 2; axisnum++) { devinfo->device()->add_item( default_axis_name[axisnum], static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum), generic_axis_get_state<LONG>, &devinfo->mouse.lX + axisnum); } // populate the buttons for (butnum = 0; butnum < 2; butnum++) { devinfo->device()->add_item( default_button_name(butnum), static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum), generic_button_get_state<BYTE>, &devinfo->mouse.rgbButtons[butnum]); } } }
void running_machine::start() { // initialize basic can't-fail systems here config_init(*this); m_input = auto_alloc(*this, input_manager(*this)); output_init(*this); palette_init(*this); m_render = auto_alloc(*this, render_manager(*this)); generic_machine_init(*this); generic_sound_init(*this); // allocate a soft_reset timer m_soft_reset_timer = m_scheduler.timer_alloc(timer_expired_delegate(FUNC(running_machine::soft_reset), this)); // init the osd layer m_osd.init(*this); // create the video manager m_video = auto_alloc(*this, video_manager(*this)); ui_init(*this); // initialize the base time (needed for doing record/playback) ::time(&m_base_time); // initialize the input system and input ports for the game // this must be done before memory_init in order to allow specifying // callbacks based on input port tags time_t newbase = input_port_init(*this); if (newbase != 0) m_base_time = newbase; // intialize UI input ui_input_init(*this); // initialize the streams engine before the sound devices start m_sound = auto_alloc(*this, sound_manager(*this)); // first load ROMs, then populate memory, and finally initialize CPUs // these operations must proceed in this order rom_init(*this); memory_init(*this); watchdog_init(*this); // must happen after memory_init because this relies on generic.spriteram generic_video_init(*this); // allocate the gfx elements prior to device initialization gfx_init(*this); // initialize natural keyboard support inputx_init(*this); // initialize image devices image_init(*this); tilemap_init(*this); crosshair_init(*this); // initialize the debugger if ((debug_flags & DEBUG_FLAG_ENABLED) != 0) debugger_init(*this); // call the game driver's init function // this is where decryption is done and memory maps are altered // so this location in the init order is important ui_set_startup_text(*this, "Initializing...", true); // start up the devices const_cast<device_list &>(devicelist()).start_all(); // if we're coming in with a savegame request, process it now const char *savegame = options().state(); if (savegame[0] != 0) schedule_load(savegame); // if we're in autosave mode, schedule a load else if (options().autosave() && (m_system.flags & GAME_SUPPORTS_SAVE) != 0) schedule_load("auto"); // set up the cheat engine m_cheat = auto_alloc(*this, cheat_manager(*this)); // disallow save state registrations starting here m_save.allow_registration(false); }
running_machine::running_machine(const machine_config &_config, osd_interface &osd, bool exit_to_game_select) : firstcpu(NULL), primary_screen(NULL), palette(NULL), pens(NULL), colortable(NULL), shadow_table(NULL), priority_bitmap(NULL), debug_flags(0), memory_data(NULL), palette_data(NULL), tilemap_data(NULL), romload_data(NULL), input_data(NULL), input_port_data(NULL), ui_input_data(NULL), debugcpu_data(NULL), generic_machine_data(NULL), generic_video_data(NULL), generic_audio_data(NULL), m_config(_config), m_system(_config.gamedrv()), m_osd(osd), m_regionlist(m_respool), m_save(*this), m_scheduler(*this), m_cheat(NULL), m_render(NULL), m_input(NULL), m_sound(NULL), m_video(NULL), m_debug_view(NULL), m_driver_device(NULL), m_current_phase(MACHINE_PHASE_PREINIT), m_paused(false), m_hard_reset_pending(false), m_exit_pending(false), m_exit_to_game_select(exit_to_game_select), m_new_driver_pending(NULL), m_soft_reset_timer(NULL), m_rand_seed(0x9d14abd7), m_ui_active(false), m_basename(_config.gamedrv().name), m_sample_rate(_config.options().sample_rate()), m_logfile(NULL), m_saveload_schedule(SLS_NONE), m_saveload_schedule_time(attotime::zero), m_saveload_searchpath(NULL), m_logerror_list(m_respool) { memset(gfx, 0, sizeof(gfx)); memset(&generic, 0, sizeof(generic)); memset(&m_base_time, 0, sizeof(m_base_time)); // set the machine on all devices const_cast<device_list &>(devicelist()).set_machine_all(*this); // find the driver device config and tell it which game m_driver_device = device<driver_device>("root"); if (m_driver_device == NULL) throw emu_fatalerror("Machine configuration missing driver_device"); // find devices primary_screen = downcast<screen_device *>(devicelist().first(SCREEN)); for (device_t *device = devicelist().first(); device != NULL; device = device->next()) if (dynamic_cast<cpu_device *>(device) != NULL) { firstcpu = downcast<cpu_device *>(device); break; } // fetch core options if (options().debug()) debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (options().debug_internal() ? 0 : DEBUG_FLAG_OSD_ENABLED); }