summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/sensorboard.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/sensorboard.h')
-rw-r--r--src/devices/machine/sensorboard.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/devices/machine/sensorboard.h b/src/devices/machine/sensorboard.h
new file mode 100644
index 00000000000..ae0384f922d
--- /dev/null
+++ b/src/devices/machine/sensorboard.h
@@ -0,0 +1,129 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ Generic sensorboard device
+
+*/
+
+#ifndef MAME_MACHINE_SENSORBOARD_H
+#define MAME_MACHINE_SENSORBOARD_H
+
+#pragma once
+
+class sensorboard_device : public device_t
+{
+public:
+ sensorboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+
+ enum
+ {
+ CHESS_BUTTONS = 0,
+ CHESS_MAGNETS,
+ CHESS_INDUCTIVE
+ };
+
+ // configuration helpers
+ sensorboard_device &set_preset(u8 preset) { init_preset(preset); return *this; } // device has presets for chess boards
+ sensorboard_device &set_size(u8 width, u8 height) { m_width = width; m_height = height; return *this; } // board dimensions, max 10 * 10
+ sensorboard_device &set_spawnpoints(u8 i) { m_maxspawn = i; m_maxid = i; return *this; } // number of piece spawnpoints, max 16
+ sensorboard_device &set_max_id(u8 i) { m_maxid = i; return *this; } // maximum piece id (if larger than set_spawnpoints)
+ sensorboard_device &set_sensordelay(attotime delay) { m_sensordelay = delay; return *this; } // delay when activating a sensor (like PORT_IMPULSE), set to attotime::never to disable
+ sensorboard_device &set_ui_enable(bool b) { if (!b) m_maxspawn = 0; m_ui_enabled = (b) ? 3 : 0; return *this; } // enable UI inputs
+ sensorboard_device &set_mod_enable(bool b) { if (b) m_ui_enabled |= 1; else m_ui_enabled &= 2; return *this; } // enable modifier keys
+
+ auto custom_init() { return m_custom_init_cb.bind(); }
+ auto custom_sensor() { return m_custom_sensor_cb.bind(); } // x = offset & 0xf, y = offset >> 4 & 0xf
+ auto custom_spawn() { return m_custom_spawn_cb.bind(); } // spawnpoint/piece = offset, retval = new piece id
+ auto custom_output() { return m_custom_output_cb.bind(); } // pos = offset(A8 for ui/board, A9 for count), id = data
+
+ // read sensors
+ u8 read_sensor(u8 x, u8 y);
+ u16 read_file(u8 x, bool reverse = false);
+ u16 read_rank(u8 y, bool reverse = false);
+
+ // handle board state
+ u8 read_piece(u8 x, u8 y) { return m_curstate[y * m_width + x]; }
+ void write_piece(u8 x, u8 y, u8 id) { m_curstate[y * m_width + x] = id; }
+ u8 read_init(u8 x, u8 y) { return m_inistate[y * m_width + x]; }
+ void write_init(u8 x, u8 y, u8 id) { m_inistate[y * m_width + x] = id; } // for setting initial board state
+
+ void refresh();
+
+ // handle pieces
+ void cancel_hand();
+ void remove_hand();
+ bool drop_piece(u8 x, u8 y);
+ bool pickup_piece(u8 x, u8 y);
+
+ // internal input handlers
+ DECLARE_INPUT_CHANGED_MEMBER(sensor);
+ DECLARE_INPUT_CHANGED_MEMBER(ui_spawn);
+ DECLARE_INPUT_CHANGED_MEMBER(ui_hand);
+ DECLARE_INPUT_CHANGED_MEMBER(ui_undo);
+ DECLARE_INPUT_CHANGED_MEMBER(ui_init);
+
+ DECLARE_CUSTOM_INPUT_MEMBER(check_bs_mask) { return m_bs_mask; }
+ DECLARE_CUSTOM_INPUT_MEMBER(check_ss_mask) { return m_ss_mask; }
+ DECLARE_CUSTOM_INPUT_MEMBER(check_ui_enabled) { return m_ui_enabled; }
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override { refresh(); }
+
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ output_finder<0x10, 0x10> m_out_piece;
+ output_finder<0x20+1> m_out_pui;
+ output_finder<2> m_out_count;
+ required_ioport_array<10> m_inp_rank;
+ required_ioport m_inp_ui;
+
+ devcb_read_line m_custom_init_cb;
+ devcb_read8 m_custom_sensor_cb;
+ devcb_read8 m_custom_spawn_cb;
+ devcb_write16 m_custom_output_cb;
+
+ u8 m_history[1000][0x100];
+ u8 m_curstate[0x100];
+ u8 m_inistate[0x100];
+ u8 m_spawnstate[0x20];
+
+ bool m_magnets;
+ bool m_inductive;
+ u8 m_width;
+ u8 m_height;
+ u32 m_bs_mask;
+ u32 m_ss_mask;
+ u8 m_maxspawn;
+ u8 m_maxid;
+ u8 m_hand;
+ int m_handpos;
+ int m_droppos;
+ int m_sensorpos;
+ u8 m_ui_enabled;
+
+ u8 m_uselect;
+ u32 m_upointer;
+ u32 m_ufirst;
+ u32 m_ulast;
+ u32 m_usize;
+
+ emu_timer *m_undotimer;
+ TIMER_CALLBACK_MEMBER(undo_tick);
+
+ attotime m_sensordelay;
+ emu_timer *m_sensortimer;
+ void cancel_sensor();
+ TIMER_CALLBACK_MEMBER(sensor_off) { cancel_sensor(); }
+
+ void init_preset(u8 preset);
+};
+
+
+DECLARE_DEVICE_TYPE(SENSORBOARD, sensorboard_device)
+
+#endif // MAME_MACHINE_SENSORBOARD_H