summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/machine/sensorboard.cpp12
-rw-r--r--src/devices/machine/sensorboard.h5
-rw-r--r--src/mame/saitek/ecbackg.cpp190
3 files changed, 200 insertions, 7 deletions
diff --git a/src/devices/machine/sensorboard.cpp b/src/devices/machine/sensorboard.cpp
index 14093ac0a00..4136831a6fd 100644
--- a/src/devices/machine/sensorboard.cpp
+++ b/src/devices/machine/sensorboard.cpp
@@ -78,6 +78,7 @@ sensorboard_device::sensorboard_device(const machine_config &mconfig, const char
m_inp_conf(*this, "CONF"),
m_clear_cb(*this),
m_init_cb(*this),
+ m_remove_cb(*this, 0),
m_sensor_cb(*this, 0),
m_spawn_cb(*this, 0),
m_output_cb(*this)
@@ -477,13 +478,15 @@ INPUT_CHANGED_MEMBER(sensorboard_device::sensor)
m_sensortimer->adjust(m_sensordelay);
}
+ bool drop = m_hand != 0;
+
// optional custom handling:
// return d0 = block drop piece
// return d1 = block pick up piece
u8 custom = m_sensor_cb(pos);
// drop piece
- if (m_hand != 0)
+ if (drop)
{
if (~custom & 1)
drop_piece(x, y);
@@ -519,7 +522,12 @@ INPUT_CHANGED_MEMBER(sensorboard_device::ui_hand)
return;
cancel_sensor();
- remove_hand();
+
+ // optional custom handling:
+ // return d0: block remove hand
+ if (~m_remove_cb() & 1)
+ remove_hand();
+
refresh();
}
diff --git a/src/devices/machine/sensorboard.h b/src/devices/machine/sensorboard.h
index bb095294cfa..dfd01c1e635 100644
--- a/src/devices/machine/sensorboard.h
+++ b/src/devices/machine/sensorboard.h
@@ -36,6 +36,7 @@ public:
auto clear_cb() { return m_clear_cb.bind(); } // 0 = internal clear, 1 = user presses clear
auto init_cb() { return m_init_cb.bind(); } // for setting pieces starting position
+ auto remove_cb() { return m_remove_cb.bind(); } // user removes piece from hand
auto sensor_cb() { return m_sensor_cb.bind(); } // x = offset & 0xf, y = offset >> 4 & 0xf
auto spawn_cb() { return m_spawn_cb.bind(); } // spawnpoint/piece = offset, retval = new piece id
auto output_cb() { return m_output_cb.bind(); } // pos = offset(A8 for ui/board, A9 for count), id = data
@@ -60,7 +61,10 @@ public:
// handle pieces
void cancel_hand();
void remove_hand();
+ u8 get_hand() { return m_hand; }
+ void set_hand(u8 hand) { m_hand = hand; }
int get_handpos() { return m_handpos; }
+ void set_handpos(int pos) { m_handpos = pos; }
bool drop_piece(u8 x, u8 y);
bool pickup_piece(u8 x, u8 y);
@@ -102,6 +106,7 @@ private:
devcb_write_line m_clear_cb;
devcb_write_line m_init_cb;
+ devcb_read8 m_remove_cb;
devcb_read8 m_sensor_cb;
devcb_read8 m_spawn_cb;
devcb_write16 m_output_cb;
diff --git a/src/mame/saitek/ecbackg.cpp b/src/mame/saitek/ecbackg.cpp
index 886cb0d42e3..f3d58b665f6 100644
--- a/src/mame/saitek/ecbackg.cpp
+++ b/src/mame/saitek/ecbackg.cpp
@@ -16,7 +16,7 @@ Hardware notes:
TODO:
- if/when MAME supports an exit callback, hook up power-off switch to that
-- finish sensorboard handling, internal artwork
+- finish internal artwork
*******************************************************************************/
@@ -51,6 +51,7 @@ public:
void ecbackg(machine_config &config);
+ DECLARE_INPUT_CHANGED_MEMBER(init_board);
DECLARE_INPUT_CHANGED_MEMBER(power_off) { if (newval) m_power = false; }
protected:
@@ -73,7 +74,13 @@ private:
u8 m_lcd_com = 0;
// I/O handlers
- void init_board(int state);
+ void init_backgammon();
+ void init_jacquet();
+ void init_plakoto();
+ void reset_board(int state);
+ u8 spawn_piece(offs_t offset);
+ u8 remove_piece();
+ u8 move_piece(offs_t offset);
u8 board_r(u8 row);
void standby(int state);
@@ -106,8 +113,172 @@ void ecbackg_state::machine_start()
Sensorboard
*******************************************************************************/
-void ecbackg_state::init_board(int state)
+void ecbackg_state::init_backgammon()
{
+ // initial position for Backgammon (default)
+ for (int i = 0; i < 5; i++)
+ {
+ m_board->write_piece(6, i, 1);
+ m_board->write_piece(0, i, 4);
+ m_board->write_piece(0, 9 - i, 1);
+ m_board->write_piece(6, 9 - i, 4);
+
+ if (i < 3)
+ {
+ m_board->write_piece(4, i, 1);
+ m_board->write_piece(4, 9 - i, 4);
+ }
+
+ if (i < 2)
+ {
+ m_board->write_piece(11, 9 - i, 1);
+ m_board->write_piece(11, i, 4);
+ }
+ }
+}
+
+void ecbackg_state::init_jacquet()
+{
+ // initial position for Jacquet / Trictrac / Moultezim
+ for (int i = 0; i < 5; i++)
+ {
+ m_board->write_piece(11, 9 - i, 3);
+ m_board->write_piece(0, i, 6);
+ }
+}
+
+void ecbackg_state::init_plakoto()
+{
+ // initial position for Plakoto
+ for (int i = 0; i < 5; i++)
+ {
+ m_board->write_piece(11, 9 - i, 3);
+ m_board->write_piece(11, i, 6);
+ }
+}
+
+INPUT_CHANGED_MEMBER(ecbackg_state::init_board)
+{
+ if (!newval)
+ return;
+
+ m_board->cancel_sensor();
+ m_board->cancel_hand();
+ m_board->clear_board();
+
+ // 3 possible initial board positions
+ switch (param)
+ {
+ case 0:
+ init_backgammon();
+ break;
+
+ case 1:
+ init_jacquet();
+ break;
+
+ case 2:
+ init_plakoto();
+ break;
+
+ default:
+ break;
+ }
+
+ m_board->refresh();
+}
+
+void ecbackg_state::reset_board(int state)
+{
+ if (!state)
+ init_backgammon();
+}
+
+u8 ecbackg_state::spawn_piece(offs_t offset)
+{
+ return (offset == 1) ? 1 : 4;
+}
+
+u8 ecbackg_state::remove_piece()
+{
+ int handpos = m_board->get_handpos();
+ u8 x = handpos & 0xf;
+ u8 y = handpos >> 4 & 0xf;
+
+ if (handpos == -1)
+ return 0;
+
+ u8 piece = m_board->read_piece(x, y);
+ m_board->remove_hand();
+
+ // decrement piece
+ if (piece != 1 && piece != 4)
+ m_board->write_piece(x, y, piece - 1);
+
+ // block default sensorboard handling
+ return 1;
+}
+
+u8 ecbackg_state::move_piece(offs_t offset)
+{
+ u8 x = offset & 0xf;
+ u8 y = offset >> 4 & 0xf;
+ u8 piece = m_board->read_piece(x, y);
+
+ u8 hand = m_board->get_hand();
+
+ // drop piece
+ if (hand != 0)
+ {
+ // drop piece on same spot
+ if (offset == m_board->get_handpos())
+ {
+ m_board->cancel_hand();
+ return 1;
+ }
+
+ if (piece != 0)
+ {
+ u8 piece_color = (piece < 4) ? 1 : 4;
+ u8 piece_index = piece - piece_color;
+
+ // invalid drop (overflow, or onto a stack of the opposite color)
+ if (piece_index == 2 || ((hand != piece_color) && piece_index == 1))
+ return 1;
+
+ remove_piece();
+
+ // swap piece (blot)
+ if ((hand != piece_color) && piece_index == 0)
+ {
+ m_board->write_piece(x, y, hand);
+ m_board->set_hand(piece_color);
+ }
+
+ // increment piece
+ else
+ m_board->write_piece(x, y, piece + 1);
+ }
+ else
+ {
+ // drop piece on empty spot
+ remove_piece();
+ m_board->write_piece(x, y, hand);
+ }
+ }
+
+ // pick up piece
+ else if (piece != 0)
+ {
+ // white or black piece
+ piece = (piece < 4) ? 1 : 4;
+
+ m_board->set_hand(piece);
+ m_board->set_handpos(offset);
+ }
+
+ // block default sensorboard handling
+ return 3;
}
u8 ecbackg_state::board_r(u8 row)
@@ -273,6 +444,11 @@ static INPUT_PORTS_START( ecbackg )
PORT_START("POWER") // needs to be triggered for nvram to work
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, ecbackg_state, power_off, 0) PORT_NAME("Stop")
+
+ PORT_START("BOARD")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CHANGED_MEMBER(DEVICE_SELF, ecbackg_state, init_board, 0) PORT_NAME("Board Reset Backgammon")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CHANGED_MEMBER(DEVICE_SELF, ecbackg_state, init_board, 1) PORT_NAME("Board Reset Jacquet")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CHANGED_MEMBER(DEVICE_SELF, ecbackg_state, init_board, 2) PORT_NAME("Board Reset Plakoto")
INPUT_PORTS_END
@@ -298,9 +474,13 @@ void ecbackg_state::ecbackg(machine_config &config)
m_maincpu->out_p7_cb().set(FUNC(ecbackg_state::lcd_com_w));
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
- m_board->init_cb().set(FUNC(ecbackg_state::init_board));
+ m_board->init_cb().set(FUNC(ecbackg_state::reset_board));
+ m_board->spawn_cb().set(FUNC(ecbackg_state::spawn_piece));
+ m_board->remove_cb().set(FUNC(ecbackg_state::remove_piece));
+ m_board->sensor_cb().set(FUNC(ecbackg_state::move_piece));
m_board->set_size(13, 10);
m_board->set_spawnpoints(2);
+ m_board->set_max_id(6);
m_board->set_delay(attotime::from_msec(150));
m_board->set_nvram_enable(true);
@@ -310,7 +490,7 @@ void ecbackg_state::ecbackg(machine_config &config)
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
screen.set_refresh_hz(60);
- screen.set_size(1920/3, 518/3);
+ screen.set_size(1920/5, 518/5);
screen.set_visarea_full();
PWM_DISPLAY(config, m_led_pwm).set_size(3, 8);