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
|
// 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 sb_type
{
NOSENSORS = 0,
BUTTONS,
MAGNETS,
INDUCTIVE
};
// configuration helpers
sensorboard_device &set_type(sb_type type); // sensor type
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_delay(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 init_cb() { return m_custom_init_cb.bind(); } // for setting pieces starting position
auto sensor_cb() { return m_custom_sensor_cb.bind(); } // x = offset & 0xf, y = offset >> 4 & 0xf
auto spawn_cb() { return m_custom_spawn_cb.bind(); } // spawnpoint/piece = offset, retval = new piece id
auto output_cb() { return m_custom_output_cb.bind(); } // pos = offset(A8 for ui/board, A9 for count), id = data
void preset_chess(int state); // init_cb() preset for chessboards
// 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; }
void clear_board() { memset(m_curstate, 0, ARRAY_LENGTH(m_curstate)); }
void refresh();
void cancel_sensor();
// handle pieces
void cancel_hand();
void remove_hand();
bool drop_piece(u8 x, u8 y);
bool pickup_piece(u8 x, u8 y);
// 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_sensor_busy) { return (m_sensorpos == -1) ? 0 : 1; }
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_spawn;
required_ioport m_inp_ui;
devcb_write_line m_custom_init_cb;
devcb_read8 m_custom_sensor_cb;
devcb_read8 m_custom_spawn_cb;
devcb_write16 m_custom_output_cb;
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_curstate[0x100];
u8 m_history[1000][0x100];
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;
TIMER_CALLBACK_MEMBER(sensor_off) { cancel_sensor(); }
};
DECLARE_DEVICE_TYPE(SENSORBOARD, sensorboard_device)
#endif // MAME_MACHINE_SENSORBOARD_H
|