summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/sensorboard.h
blob: 424db04c558ceb3ed727ce2ab5b5481fee3dca6a (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                                                           
                    
         

                              

                         


                                
                                                                  
                                                                                                                                                

                                                                                                                                       
                                                                                                                                                                                       


                                                                                                                                              
                                                                                                  



                                                                                                                        
                                                                         








                                                                                 
                                                                               

                       
                             






                                      
                         





                                               
                                                                                              
















                                                                              
                                    

                                 
                                          



                                         
                         













                         
                             

                                  










                                         
                                                              





                                                    
// 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 12 * 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_nosensors;
	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