Exemplo n.º 1
0
        ioport_charqueue_empty_delegate m_charqueue_empty;                       // character queue empty callback


        // construction/destruction
        //-------------------------------------------------
        //  natural_keyboard - constructor
        //-------------------------------------------------
        public natural_keyboard(running_machine machine)
        {
            m_machine         = machine;
            m_have_charkeys   = false;
            m_in_use          = false;
            m_bufbegin        = 0;
            m_bufend          = 0;
            m_current_code    = null;
            m_fieldnum        = 0;
            m_status_keydown  = false;
            m_last_cr         = false;
            m_timer           = null;
            m_current_rate    = attotime.zero;
            m_queue_chars     = null;
            m_accept_char     = null;
            m_charqueue_empty = null;


            // try building a list of keycodes; if none are available, don't bother
            build_codes();
            if (!m_keyboards.empty())
            {
                m_buffer.resize(KEY_BUFFER_SIZE);
                m_timer = machine.scheduler().timer_alloc(timer);
            }

            // retrieve option setting
            set_in_use(machine.options().natural_keyboard());
        }
Exemplo n.º 2
0
        //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]));
            }
        }
Exemplo n.º 3
0
        // 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());
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        // 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 = machine().ioport();

            // find all the devices with keyboard or keypad inputs
            foreach (var port in manager.ports())
            {
                var devinfo =
                    std.find_if(
                        m_keyboards,
                        (kbd_dev_info info) =>
                {
                    return(port.second().device() == info.device);
                });

                foreach (ioport_field field in port.second().fields())
                {
                    bool is_keyboard = field.type() == ioport_type.IPT_KEYBOARD;
                    if (is_keyboard || (field.type() == ioport_type.IPT_KEYPAD))
                    {
                        if (default == devinfo)
                        {
                            //devinfo = m_keyboards.emplace(devinfo, port.second->device());
                            devinfo = new kbd_dev_info(port.second().device());
                            m_keyboards.push_back(devinfo);
                        }

                        devinfo.keyfields.emplace_back(field);

                        if (is_keyboard)
                        {
                            devinfo.keyboard = true;
                        }
                        else
                        {
                            devinfo.keypad = true;
                        }
                    }
                }
            }

            std.sort(
                m_keyboards,
                (kbd_dev_info l, kbd_dev_info r) =>
            {
                return(std.strcmp(l.device.tag(), r.device.tag()));
            });

            // set up key mappings for each keyboard
            std.array <ioport_field, size_t_const_SHIFT_COUNT> shift = new std.array <ioport_field, size_t_const_SHIFT_COUNT>();
            unsigned mask;
            bool     have_keyboard = false;

            foreach (kbd_dev_info devinfo in m_keyboards)
            {
                if (LOG_NATURAL_KEYBOARD)
                {
                    machine().logerror("natural_keyboard: building codes for {0}... ({1} fields)\n", devinfo.device.tag(), devinfo.keyfields.size());
                }

                // enable all pure keypads and the first keyboard
                if (!devinfo.keyboard || !have_keyboard)
                {
                    devinfo.enabled = true;
                }
                have_keyboard = have_keyboard || devinfo.keyboard;

                // find all shift keys
                std.fill(shift, (ioport_field)null);  //std::fill(std::begin(shift), std::end(shift), nullptr);
                mask = 0;
                foreach (ioport_field field in devinfo.keyfields)
                {
                    if (field.type() == ioport_type.IPT_KEYBOARD)
                    {
                        std.vector <char32_t> codes = field.keyboard_codes(0);
                        foreach (char32_t code in codes)
                        {
                            if ((code >= UCHAR_SHIFT_BEGIN) && (code <= UCHAR_SHIFT_END))
                            {
                                mask |= 1U << (int)(code - UCHAR_SHIFT_BEGIN);
                                shift[code - UCHAR_SHIFT_BEGIN] = field;
                                if (LOG_NATURAL_KEYBOARD)
                                {
                                    machine().logerror("natural_keyboard: UCHAR_SHIFT_{0} found\n", code - UCHAR_SHIFT_BEGIN + 1);
                                }
                            }
                        }
                    }
                }

                // iterate over keyboard/keypad fields
                foreach (ioport_field field in devinfo.keyfields)
                {
                    field.live().lockout = !devinfo.enabled;
                    if (field.type() == ioport_type.IPT_KEYBOARD)
                    {
                        // iterate over all shift states
                        for (unsigned curshift = 0; curshift < SHIFT_STATES; ++curshift)
                        {
                            if ((curshift & ~mask) == 0)
                            {
                                // fetch the code, ignoring 0 and shifters
                                std.vector <char32_t> codes = field.keyboard_codes((int)curshift);
                                foreach (char32_t code in codes)
                                {
                                    if (((code < UCHAR_SHIFT_BEGIN) || (code > UCHAR_SHIFT_END)) && (code != 0))
                                    {
                                        m_have_charkeys = true;
                                        var found = devinfo.codemap.find(code);      //keycode_map::iterator const found(devinfo.codemap.find(code));
                                        keycode_map_entry newcode = new keycode_map_entry();
                                        std.fill(newcode.field, (ioport_field)null); //std::fill(std::begin(newcode.field), std::end(newcode.field), nullptr);
                                        newcode.shift     = curshift;
                                        newcode.condition = field.condition();

                                        unsigned fieldnum = 0;
                                        for (unsigned i = 0, bits = curshift; (i < SHIFT_COUNT) && (bits != 0); ++i, bits >>= 1)
                                        {
                                            if (BIT(bits, 0) != 0)
                                            {
                                                newcode.field[fieldnum++] = shift[i];
                                            }
                                        }

                                        newcode.field[fieldnum] = field;
                                        if (default == found)
                                        {
                                            natural_keyboard_keycode_map_entries entries = new natural_keyboard_keycode_map_entries();
                                            entries.emplace_back(newcode);
                                            devinfo.codemap.emplace(code, entries);
                                        }
                                        else
                                        {
                                            found.emplace_back(newcode);
                                        }

                                        if (LOG_NATURAL_KEYBOARD)
                                        {
                                            machine().logerror("natural_keyboard: code={0} ({1}) port={2} field.name='{3}'\n",
                                                               code, unicode_to_string(code), field.port(), field.name());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // sort mapping entries by shift state
                foreach (var mapping in devinfo.codemap)
                {
                    std.sort(
                        mapping.second(),
                        (keycode_map_entry x, keycode_map_entry y) => { return(x.shift.CompareTo(y.shift)); });     //[] (keycode_map_entry const &x, keycode_map_entry const &y) { return x.shift < y.shift; });
                }
            }