/*------------------------------------------------- * frame_update - looks through pressed * input as per events pushed our way and posts * corresponding IPT_UI_* events * -------------------------------------------------*/ void frame_update(running_machine machine) { /* update the state of all the UI keys */ for (ioport_type code = (ioport_type)(ioport_type.IPT_UI_FIRST + 1); code < ioport_type.IPT_UI_LAST; ++code) { bool pressed = machine.ioport().type_pressed(code); if (!pressed || m_seqpressed[(int)code] != SEQ_PRESSED_RESET) { m_seqpressed[(int)code] = pressed ? (byte)1 : (byte)0; } } // perform mouse hit testing ioport_field mouse_field = m_current_mouse_down ? find_mouse_field() : null; if (m_current_mouse_field != mouse_field) { // clear the old field if there was one if (m_current_mouse_field != null) { m_current_mouse_field.set_value(0); } // set the new field if it exists and isn't already being pressed if (mouse_field != null && !mouse_field.digital_value()) { mouse_field.set_value(1); } // update internal state m_current_mouse_field = mouse_field; } }
// construction/destruction //------------------------------------------------- // ui_input_manager - constructor //------------------------------------------------- public ui_input_manager(running_machine machine) { m_machine = machine; m_current_mouse_target = null; m_current_mouse_down = false; m_current_mouse_field = null; m_events_start = 0; m_events_end = 0; /* create the private data */ m_current_mouse_x = -1; m_current_mouse_y = -1; /* add a frame callback to poll inputs */ machine.add_notifier(machine_notification.MACHINE_NOTIFY_FRAME, frame_update); }
// construction/destruction //------------------------------------------------- // ui_input_manager - constructor //------------------------------------------------- public ui_input_manager(running_machine machine) { m_machine = machine; m_presses_enabled = true; m_current_mouse_target = null; m_current_mouse_x = -1; m_current_mouse_y = -1; m_current_mouse_down = false; m_current_mouse_field = null; m_events_start = 0; m_events_end = 0; std.fill(m_next_repeat, (osd_ticks_t)0); std.fill(m_seqpressed, (u8)0); // add a frame callback to poll inputs machine.add_notifier(machine_notification.MACHINE_NOTIFY_FRAME, frame_update); }
//void internal_post(char32_t ch); //------------------------------------------------- // timer - timer callback to keep things flowing // when posting a string of characters //------------------------------------------------- void timer(object ptr, int param) { if (m_queue_chars != null) { // the driver has a queue_chars handler while (!empty() && m_queue_chars(m_buffer, m_bufbegin, 1) != 0) { m_bufbegin = (m_bufbegin + 1) % (UInt32)m_buffer.size(); if (m_current_rate != attotime.zero) { break; } } } else { // the driver does not have a queue_chars handler // loop through this character's component codes keycode_map_entry code = find_code(m_buffer[(int)m_bufbegin]); bool advance; if (code != null) { do { assert(m_fieldnum < code.field.Length); ioport_field field = code.field[m_fieldnum]; if (field != null) { // special handling for toggle fields if (!field.live().toggle) { field.set_value(!m_status_keydown ? (UInt32)1 : 0); } else if (!m_status_keydown) { field.set_value(!field.digital_value() ? (UInt32)1 : 0); } } }while (code.field[m_fieldnum] != null && (++m_fieldnum < code.field.Length) && m_status_keydown); advance = (m_fieldnum >= code.field.Length) || code.field[m_fieldnum] == null; } else { advance = true; } if (advance) { m_fieldnum = 0; m_status_keydown = !m_status_keydown; // proceed to next character when keydown expires if (!m_status_keydown) { m_bufbegin = (m_bufbegin + 1) % (UInt32)m_buffer.size(); } } } // need to make sure timerproc is called again if buffer not empty if (!empty()) { m_timer.adjust(choose_delay(m_buffer[(int)m_bufbegin])); } }
// posting //void post(char32_t ch); //void post(const char32_t *text, size_t length = 0, const attotime &rate = attotime::zero); //void post_utf8(const char *text, size_t length = 0, const attotime &rate = attotime::zero); //void post_coded(const char *text, size_t length = 0, const attotime &rate = attotime::zero); // debugging //void dump(std::ostream &str) const; //std::string dump(); // internal helpers //------------------------------------------------- // build_codes - given an input port table, create // an input code table useful for mapping unicode // chars //------------------------------------------------- void build_codes(ioport_manager manager) { // find all shift keys UInt32 mask = 0; ioport_field [] shift = new ioport_field[SHIFT_COUNT]; for (int i = 0; i < shift.Length; i++) { shift[i] = null; //std::fill(std::begin(shift), std::end(shift), nullptr); } foreach (var port in manager.ports()) { foreach (ioport_field field in port.Value.fields()) { if (field.type() == ioport_type.IPT_KEYBOARD) { ListBase <char32_t> codes = field.keyboard_codes(0); foreach (char32_t code in codes) { if ((code >= ioport_global.UCHAR_SHIFT_BEGIN) && (code <= ioport_global.UCHAR_SHIFT_END)) { mask |= 1U << (int)(code - ioport_global.UCHAR_SHIFT_BEGIN); shift[code - ioport_global.UCHAR_SHIFT_BEGIN] = field; } } } } } // iterate over ports and fields foreach (var port in manager.ports()) { foreach (ioport_field field in port.Value.fields()) { if (field.type() == ioport_type.IPT_KEYBOARD) { // iterate over all shift states for (UInt32 curshift = 0; curshift < SHIFT_STATES; ++curshift) { if ((curshift & ~mask) == 0) { // fetch the code, ignoring 0 and shiters ListBase <char32_t> codes = field.keyboard_codes((int)curshift); foreach (char32_t code in codes) { if (((code < ioport_global.UCHAR_SHIFT_BEGIN) || (code > ioport_global.UCHAR_SHIFT_END)) && (code != 0)) { // prefer lowest shift state var found = m_keycode_map.find(code); if ((null == found) || (found.shift > curshift)) { keycode_map_entry newcode = new keycode_map_entry(); //std::fill(std::begin(newcode.field), std::end(newcode.field), nullptr); for (int i = 0; i < newcode.field.Length; i++) { newcode.field[i] = null; } newcode.shift = curshift; UInt32 fieldnum = 0; for (UInt32 i = 0, bits = curshift; (i < SHIFT_COUNT) && bits != 0; ++i, bits >>= 1) { if (BIT(bits, 0) != 0) { newcode.field[fieldnum++] = shift[i]; } } assert(fieldnum < newcode.field.Length); newcode.field[fieldnum] = field; if (null == found) { m_keycode_map.emplace(code, newcode); } else { found = newcode; } if (LOG_NATURAL_KEYBOARD) { machine().logerror("natural_keyboard: code={0} ({1}) port={2} field.name='{3}'\n", // code=%u (%s) port=%p field.name='%s'\n code, unicode_to_string(code), port, field.name()); } } } } } } } } } }
//NETDEV_ANALOG_CALLBACK_MEMBER(update_red); //NETDEV_ANALOG_CALLBACK_MEMBER(update_green); //NETDEV_ANALOG_CALLBACK_MEMBER(update_blue); //NETDEV_ANALOG_CALLBACK_MEMBER(update_sync); //INPUT_CHANGED_MEMBER(port_changed); public void port_changed(ioport_field field, u32 param, ioport_value oldval, ioport_value newval) { throw new emu_unimplemented(); }
//INPUT_CHANGED_MEMBER(mw8080bw_state::direct_coin_count) public void direct_coin_count(ioport_field field, u32 param, ioport_value oldval, ioport_value newval) { machine().bookkeeping().coin_counter_w(0, (int)newval); }