mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
a2gameio: Add support for the Softape Bright Pen (#12721)
* a2gameio: Add Softape Bright Pen support for the Apple ][/][+
This commit is contained in:
parent
bebfd944ae
commit
1174af0fe8
6 changed files with 179 additions and 2 deletions
|
@ -3141,6 +3141,8 @@ end
|
|||
|
||||
if (BUSES["A2GAMEIO"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/a2gameio/brightpen.cpp",
|
||||
MAME_DIR .. "src/devices/bus/a2gameio/brightpen.h",
|
||||
MAME_DIR .. "src/devices/bus/a2gameio/computereyes.cpp",
|
||||
MAME_DIR .. "src/devices/bus/a2gameio/computereyes.h",
|
||||
MAME_DIR .. "src/devices/bus/a2gameio/gameio.cpp",
|
||||
|
|
140
src/devices/bus/a2gameio/brightpen.cpp
Normal file
140
src/devices/bus/a2gameio/brightpen.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
// license:BSD-3-Clause
|
||||
// copyright-holders:kmg
|
||||
/*********************************************************************
|
||||
|
||||
Apple II Softape Bright Pen interface for the Apple ][/][+
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "bus/a2gameio/brightpen.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
#define BRIGHTPEN_POINT "BRIGHTPEN_POINT"
|
||||
#define BRIGHTPEN_X "BRIGHTPEN_X"
|
||||
#define BRIGHTPEN_Y "BRIGHTPEN_Y"
|
||||
|
||||
// ======================> apple2_brightpen_device
|
||||
|
||||
class apple2_brightpen_device : public device_t, public device_a2gameio_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
apple2_brightpen_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, APPLE2_BRIGHTPEN, tag, owner, clock)
|
||||
, device_a2gameio_interface(mconfig, *this)
|
||||
, m_brightpen_point(*this, BRIGHTPEN_POINT)
|
||||
, m_brightpen_x(*this, BRIGHTPEN_X)
|
||||
, m_brightpen_y(*this, BRIGHTPEN_Y)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// device_t implementation
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_start() override;
|
||||
|
||||
// device_a2gameio_interface implementation
|
||||
virtual int sw0_r() override;
|
||||
|
||||
private:
|
||||
// input ports
|
||||
required_ioport m_brightpen_point;
|
||||
required_ioport m_brightpen_x;
|
||||
required_ioport m_brightpen_y;
|
||||
|
||||
// radius of circle picked up by the bright pen
|
||||
static constexpr int PEN_X_RADIUS = 2;
|
||||
static constexpr int PEN_Y_RADIUS = 1;
|
||||
// brightness threshold
|
||||
static constexpr int BRIGHTNESS_THRESHOLD = 0x20;
|
||||
// # of CRT scanlines that sustain brightness
|
||||
static constexpr int SUSTAIN = 22;
|
||||
};
|
||||
|
||||
//**************************************************************************
|
||||
// INPUT PORTS
|
||||
//**************************************************************************
|
||||
|
||||
static INPUT_PORTS_START( apple2_brightpen )
|
||||
PORT_START(BRIGHTPEN_X)
|
||||
PORT_BIT( 0x3ff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15) PORT_MINMAX(0, 559) PORT_NAME("Bright Pen X")
|
||||
PORT_START(BRIGHTPEN_Y)
|
||||
PORT_BIT( 0x3ff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15) PORT_MINMAX(0, 191) PORT_NAME("Bright Pen Y")
|
||||
PORT_START(BRIGHTPEN_POINT)
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Bright Pen pointed at screen")
|
||||
PORT_BIT( 0xfe, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor apple2_brightpen_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(apple2_brightpen);
|
||||
}
|
||||
|
||||
void apple2_brightpen_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
// light detection logic based on zapper_sensor.cpp nes_zapper_sensor_device::detect_light
|
||||
|
||||
int apple2_brightpen_device::sw0_r()
|
||||
{
|
||||
if (!BIT(m_brightpen_point->read(), 0)) return 0;
|
||||
|
||||
int pen_x_pos = m_brightpen_x->read();
|
||||
int pen_y_pos = m_brightpen_y->read();
|
||||
int beam_vpos = m_screen->vpos();
|
||||
int beam_hpos = m_screen->hpos();
|
||||
|
||||
// update the screen if the beam position is within the radius of the pen
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (!m_screen->vblank())
|
||||
{
|
||||
if (beam_vpos > pen_y_pos - PEN_Y_RADIUS || (beam_vpos == pen_y_pos - PEN_Y_RADIUS && beam_hpos >= pen_x_pos - PEN_X_RADIUS))
|
||||
{
|
||||
m_screen->update_now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int brightness_sum = 0;
|
||||
int pixels_scanned = 0;
|
||||
|
||||
// sum brightness of pixels nearby the pen position
|
||||
for (int i = pen_x_pos - PEN_X_RADIUS; i <= pen_x_pos + PEN_X_RADIUS; i++)
|
||||
{
|
||||
for (int j = pen_y_pos - PEN_Y_RADIUS; j <= pen_y_pos + PEN_Y_RADIUS; j++)
|
||||
{
|
||||
// look at pixels within circular sensor
|
||||
if ((pen_x_pos - i) * (pen_x_pos - i) + (pen_y_pos - j) * (pen_y_pos - j) <= PEN_X_RADIUS * PEN_Y_RADIUS)
|
||||
{
|
||||
rgb_t pix = m_screen->pixel(i, j);
|
||||
|
||||
// only detect light if pen position is near, and behind,
|
||||
// where the video generator is drawing on the CRT,
|
||||
if (j <= beam_vpos && j > beam_vpos - SUSTAIN && (j != beam_vpos || i <= beam_hpos))
|
||||
{
|
||||
brightness_sum += pix.r() + pix.g() + pix.b();
|
||||
}
|
||||
pixels_scanned++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// light detected if average brightness is above threshold
|
||||
return (brightness_sum >= BRIGHTNESS_THRESHOLD * pixels_scanned);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(APPLE2_BRIGHTPEN, device_a2gameio_interface, apple2_brightpen_device, "a2brightpen", "Softape Bright Pen")
|
18
src/devices/bus/a2gameio/brightpen.h
Normal file
18
src/devices/bus/a2gameio/brightpen.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
// license:BSD-3-Clause
|
||||
/*********************************************************************
|
||||
|
||||
Apple II Softape Bright Pen interface for a lightpen
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_A2GAMEIO_BRIGHTPEN_H
|
||||
#define MAME_BUS_A2GAMEIO_BRIGHTPEN_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bus/a2gameio/gameio.h"
|
||||
|
||||
// device type declaration
|
||||
DECLARE_DEVICE_TYPE(APPLE2_BRIGHTPEN, device_a2gameio_interface)
|
||||
|
||||
#endif // MAME_BUS_A2GAMEIO_BRIGHTPEN_H
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
#include "emu.h"
|
||||
#include "bus/a2gameio/gameio.h"
|
||||
#include "bus/a2gameio/brightpen.h"
|
||||
#include "bus/a2gameio/joystick.h"
|
||||
#include "bus/a2gameio/joyport.h"
|
||||
#include "bus/a2gameio/joyport_paddles.h"
|
||||
|
@ -68,6 +69,7 @@ DEFINE_DEVICE_TYPE(APPLE2_GAMEIO, apple2_gameio_device, "a2gameio", "Apple II Ga
|
|||
apple2_gameio_device::apple2_gameio_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, APPLE2_GAMEIO, tag, owner, clock)
|
||||
, device_single_card_slot_interface<device_a2gameio_interface>(mconfig, *this)
|
||||
, m_screen(*this, finder_base::DUMMY_TAG)
|
||||
, m_intf(nullptr)
|
||||
, m_sw_pullups(false)
|
||||
{
|
||||
|
@ -82,6 +84,7 @@ void apple2_gameio_device::iiandplus_options(device_slot_interface &slot)
|
|||
slot.option_add("gizmo", APPLE2_GIZMO);
|
||||
slot.option_add("compeyes", APPLE2_COMPUTEREYES);
|
||||
slot.option_add("wicojoy", APPLE2_WICO_JOYSTICK);
|
||||
slot.option_add("brightpen", APPLE2_BRIGHTPEN);
|
||||
}
|
||||
|
||||
void apple2_gameio_device::default_options(device_slot_interface &slot)
|
||||
|
@ -105,8 +108,10 @@ void apple2_gameio_device::device_config_complete()
|
|||
|
||||
void apple2_gameio_device::device_resolve_objects()
|
||||
{
|
||||
if (m_intf)
|
||||
if (m_intf) {
|
||||
m_intf->m_connector = this;
|
||||
m_intf->set_screen(m_screen);
|
||||
}
|
||||
}
|
||||
|
||||
void apple2_gameio_device::device_start()
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
|
@ -37,6 +38,13 @@ public:
|
|||
set_fixed(false);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
apple2_gameio_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&screen_tag, U &&opts, const char *dflt)
|
||||
: apple2_gameio_device(mconfig, tag, owner, opts, dflt)
|
||||
{
|
||||
m_screen.set_tag(std::forward<T>(screen_tag));
|
||||
}
|
||||
|
||||
// configuration
|
||||
void set_sw_pullups(bool enabled) { m_sw_pullups = enabled; }
|
||||
bool has_sw_pullups() const { return m_sw_pullups; }
|
||||
|
@ -77,6 +85,8 @@ protected:
|
|||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
|
||||
optional_device<screen_device> m_screen;
|
||||
|
||||
private:
|
||||
// selected device
|
||||
device_a2gameio_interface *m_intf;
|
||||
|
@ -115,6 +125,8 @@ protected:
|
|||
virtual void an4_w(int state) { }
|
||||
virtual void strobe_w(int state) { }
|
||||
|
||||
void set_screen(screen_device *screen) { m_screen = screen; }
|
||||
screen_device *m_screen;
|
||||
private:
|
||||
apple2_gameio_device *m_connector;
|
||||
};
|
||||
|
|
|
@ -1155,7 +1155,7 @@ void apple2_state::apple2_common(machine_config &config)
|
|||
m_softlatch->q_out_cb<6>().append(m_video, FUNC(a2_video_device::an2_w));
|
||||
m_softlatch->q_out_cb<7>().set(m_gameio, FUNC(apple2_gameio_device::an3_w));
|
||||
|
||||
APPLE2_GAMEIO(config, m_gameio, apple2_gameio_device::iiandplus_options, nullptr);
|
||||
APPLE2_GAMEIO(config, m_gameio, m_screen, apple2_gameio_device::iiandplus_options, nullptr);
|
||||
|
||||
/* keyboard controller */
|
||||
AY3600(config, m_ay3600, 0);
|
||||
|
|
Loading…
Reference in a new issue