Skip to content

sega/sega_beena.cpp, sega_beena_cart.xml: Add software items and peripheral card reader support #13645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
841 changes: 820 additions & 21 deletions hash/sega_beena_cart.xml

Large diffs are not rendered by default.

100 changes: 50 additions & 50 deletions hash/tvochken.xml

Large diffs are not rendered by default.

195 changes: 130 additions & 65 deletions src/mame/layout/beena.lay
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
license:CC0-1.0
-->
<mamelayout version="2">
<element name="card" />

<element name="pencursor">
<image state="1">
<data><![CDATA[
Expand Down Expand Up @@ -51,77 +53,140 @@ license:CC0-1.0
</element>
</view>

<view name="Storyware and Card View">
<screen index="0">
<bounds x="0" y="0" width="4" height="3" />
</screen>

<element id="leftpage" ref="leftpage">
<bounds x="0" y="3.1" width="2" height="2.8" />
</element>
<element id="rightpage" ref="rightpage">
<bounds x="2" y="3.1" width="2" height="2.8" />
</element>

<element id="pencursor" ref="pencursor">
<!-- will be positioned by script -->
<bounds x="0" y="3.1" width="0.2" height="0.2" />
<color alpha="0.7" />
</element>

<element ref="card">
<bounds x="0" y="6" width="4" height="2.65" />
</element>
</view>

<script><![CDATA[
file:set_resolve_tags_callback(
function ()
-- get memory regions for page scans
local pages = { }
for i = 1, 12 do
local page = file.device:memregion(string.format('cartslot:page%u', i))
if page ~= nil then
pages[i] = page
else
break
end
end
local function init_storyware(view)
-- get memory regions for page scans
local pages = { }
for i = 1, 12 do
local page = file.device:memregion(string.format('cartslot:page%u', i))
if page ~= nil then
pages[i] = page
else
break
end
end

-- left/right page items are needed on-the-fly
local leftpage = file.views[view].items['leftpage']
local rightpage = file.views[view].items['rightpage']

-- recompute target pen cursor size and area when necessary
local curxoffs, curyoffs, curxscale, curyscale, curwidth, curheight
file.views[view]:set_recomputed_callback(
function ()
local lbounds = leftpage.bounds
local rbounds = rightpage.bounds
curwidth = lbounds.width / 10
curheight = lbounds.height / 14
curxoffs = lbounds.x0 - (curwidth * 0.5)
curyoffs = lbounds.y0 - (curheight * 0.5)
curxscale = (rbounds.x1 - lbounds.x0) / 255
curyscale = lbounds.height / 255
end)

-- make page display respond to page selection input
local pagectrl = file.device:ioport('PAGE')
local function get_page() return pagectrl:read() end
leftpage:set_element_state_callback(get_page)
rightpage:set_element_state_callback(get_page)

-- left/right page items are needed on-the-fly
local leftpage = file.views['Default View'].items['leftpage']
local rightpage = file.views['Default View'].items['rightpage']

-- recompute target pen cursor size and area when necessary
local curxoffs, curyoffs, curxscale, curyscale, curwidth, curheight
file.views['Default View']:set_recomputed_callback(
function ()
local lbounds = leftpage.bounds
local rbounds = rightpage.bounds
curwidth = lbounds.width / 10
curheight = lbounds.height / 14
curxoffs = lbounds.x0 - (curwidth * 0.5)
curyoffs = lbounds.y0 - (curheight * 0.5)
curxscale = (rbounds.x1 - lbounds.x0) / 255
curyscale = lbounds.height / 255
end)

-- make page display respond to page selection input
local pagectrl = file.device:ioport('PAGE')
local function get_page() return pagectrl:read() end
leftpage:set_element_state_callback(get_page)
rightpage:set_element_state_callback(get_page)

-- render even pages on the left, odd pages on the right
local function draw_page(n, dest)
local page = pages[n]
if page ~= nil then
-- render even pages on the left, odd pages on the right
local function draw_page(n, dest)
local page = pages[n]
if page ~= nil then
-- TODO: reduce temporary memory usage when I/O classes are exposed to Lua
local data = page:read(0, page.size)
local image = emu.bitmap_argb32.load(data)
image:resample(dest)
end
end
file.elements['leftpage']:set_draw_callback(
function (state, bitmap)
draw_page(state * 2, bitmap)
end)
file.elements['rightpage']:set_draw_callback(
function (state, bitmap)
draw_page((state * 2) + 1, bitmap)
end)

-- animate the position of the pen cursor
local penctrl = file.device:ioport('PEN_LEFT')
local penx = file.device:ioport('PENX')
local peny = file.device:ioport('PENY')
file.views[view].items['pencursor']:set_element_state_callback(
function ()
return (penctrl:read() & 2) >> 1
end)
file.views[view].items['pencursor']:set_bounds_callback(
function ()
local x = curxoffs + (penx:read() * curxscale)
local y = curyoffs + (peny:read() * curyscale)
return emu.render_bounds(x, y, x + curwidth, y + curheight)
end)
end

local sub -- keep this here to avoid it being garbage collected prematurely

local function init_card()
-- get card slot device and card display element
local card_device = emu.image_enumerator(file.device)['card']
local card_element = file.elements['card']

-- invalidate the card display on media change
local card_data = card_device.device:memregion('card')
sub = card_device:add_media_change_notifier(
function (event)
card_data = card_device.device:memregion('card')
card_element:invalidate()
end)

-- draw the card image
card_element:set_draw_callback(
function (state, bitmap)
if card_data ~= nil then
-- TODO: reduce temporary memory usage when I/O classes are exposed to Lua
local data = page:read(0, page.size)
local data = card_data:read(0, card_data.size)
local image = emu.bitmap_argb32.load(data)
image:resample(dest)
image:resample(bitmap)
end
end)
end

file:set_resolve_tags_callback(
function ()
local barcode_device = emu.device_enumerator(file.device, 3)[':card:rd']
if barcode_device == nil then
barcode_device = emu.device_enumerator(file.device, 3)[':card:rd2061']
end
if barcode_device == nil then
init_storyware('Default View')
else
init_storyware('Storyware and Card View')
init_card()
end
file.elements['leftpage']:set_draw_callback(
function (state, bitmap)
draw_page(state * 2, bitmap)
end)
file.elements['rightpage']:set_draw_callback(
function (state, bitmap)
draw_page((state * 2) + 1, bitmap)
end)

-- animate the position of the pen cursor
local penctrl = file.device:ioport('PEN_LEFT')
local penx = file.device:ioport('PENX')
local peny = file.device:ioport('PENY')
file.views['Default View'].items['pencursor']:set_element_state_callback(
function ()
return (penctrl:read() & 2) >> 1
end)
file.views['Default View'].items['pencursor']:set_bounds_callback(
function ()
local x = curxoffs + (penx:read() * curxscale)
local y = curyoffs + (peny:read() * curyscale)
return emu.render_bounds(x, y, x + curwidth, y + curheight)
end)
end)
]]></script>
</mamelayout>
32 changes: 20 additions & 12 deletions src/mame/sega/tvochken_card.cpp → src/mame/sega/9h0-0008_card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// copyright-holders:Vas Crabb
/******************************************************************************

tvochken_card.cpp
9h0-0008_card.cpp

Sega TV Ocha-ken barcode card loader
Sega Toys 9H0-0008 barcode card loader

TODO:
* Decode barcode from the scan so it doesn't need to be in a software
Expand All @@ -13,7 +13,8 @@
*******************************************************************************/

#include "emu.h"
#include "tvochken_card.h"

#include "9h0-0008_card.h"

#include "rendutil.h"
#include "softlist_dev.h"
Expand All @@ -24,27 +25,33 @@
#include <sstream>


DEFINE_DEVICE_TYPE(TVOCHKEN_CARD, tvochken_card_device, "tvochken_card", "Sega TV Ocha-Ken barcode card")
DEFINE_DEVICE_TYPE(SEGA_9H0_0008_CARD, sega_9h0_0008_card_device, "sega_9h0_0008_card", "Sega Toys 9H0-0008 barcode card")


tvochken_card_device::tvochken_card_device(
sega_9h0_0008_card_device::sega_9h0_0008_card_device(
machine_config const &mconfig,
char const *tag,
device_t *owner,
u32 clock)
: device_t(mconfig, TVOCHKEN_CARD, tag, owner, clock)
: sega_9h0_0008_card_device(mconfig, SEGA_9H0_0008_CARD, tag, owner, clock)
{
}


sega_9h0_0008_card_device::sega_9h0_0008_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: sega_9h0_0008_iox_slot_device(mconfig, type, tag, owner, clock)
, device_image_interface(mconfig, *this)
, m_barcode(0)
{
}


tvochken_card_device::~tvochken_card_device()
sega_9h0_0008_card_device::~sega_9h0_0008_card_device()
{
}


std::pair<std::error_condition, std::string> tvochken_card_device::call_load()
std::pair<std::error_condition, std::string> sega_9h0_0008_card_device::call_load()
{
memory_region *cardrgn;
if (loaded_through_softlist())
Expand Down Expand Up @@ -106,7 +113,7 @@ std::pair<std::error_condition, std::string> tvochken_card_device::call_load()
// TODO: support reading barcode from image
m_barcode = 0;
osd_printf_warning(
"%s: TV Ocha-Ken barcodes are only supported for software list items.\n",
"%s: Sega Toys 9H0-0008 barcodes are only supported for software list items.\n",
tag());
}

Expand Down Expand Up @@ -137,7 +144,7 @@ std::pair<std::error_condition, std::string> tvochken_card_device::call_load()
}


void tvochken_card_device::call_unload()
void sega_9h0_0008_card_device::call_unload()
{
memory_region *const cardrgn = memregion("card");
if (cardrgn)
Expand All @@ -147,11 +154,12 @@ void tvochken_card_device::call_unload()
}


void tvochken_card_device::device_start()
void sega_9h0_0008_card_device::device_start()
{
}

software_list_loader const &tvochken_card_device::get_software_list_loader() const

software_list_loader const &sega_9h0_0008_card_device::get_software_list_loader() const
{
return rom_software_list_loader::instance();
}
35 changes: 24 additions & 11 deletions src/mame/sega/tvochken_card.h → src/mame/sega/9h0-0008_card.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,37 @@
// copyright-holders:Vas Crabb
/******************************************************************************

tvochken_card.h
9h0-0008_card.h

Sega TV Ocha-ken barcode card loader
Sega Toys 9H0-0008 barcode card loader

*******************************************************************************/
#ifndef MAME_SEGA_TVOCHKEN_CARD_H
#define MAME_SEGA_TVOCHKEN_CARD_H
#ifndef MAME_SEGA_9H0_0008_CARD_H
#define MAME_SEGA_9H0_0008_CARD_H

#pragma once

#include <string>
#include <system_error>
#include <utility>

#include "9h0-0008_iox.h"

class tvochken_card_device : public device_t, public device_image_interface
class sega_9h0_0008_card_device : public sega_9h0_0008_iox_slot_device, public device_image_interface
{
public:
tvochken_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
virtual ~tvochken_card_device();
// construction/destruction
template <typename T>
sega_9h0_0008_card_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt, bool const fixed)
: sega_9h0_0008_card_device(mconfig, tag, owner, 0)
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(fixed);
}
sega_9h0_0008_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
virtual ~sega_9h0_0008_card_device();

// device_image_interface implementation
virtual std::pair<std::error_condition, std::string> call_load() override ATTR_COLD;
Expand All @@ -30,14 +41,16 @@ class tvochken_card_device : public device_t, public device_image_interface
virtual bool is_writeable() const noexcept override { return false; }
virtual bool is_creatable() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return false; }
virtual char const *image_interface() const noexcept override { return "tvochken_card"; }
virtual char const *image_interface() const noexcept override { return "sega_9h0_0008_card"; }
virtual char const *file_extensions() const noexcept override { return "png,jpg,bmp"; } // loose media not supported yet
virtual char const *image_type_name() const noexcept override { return "card"; }
virtual char const *image_brief_type_name() const noexcept override { return "crd"; }

u16 barcode() const noexcept { return m_barcode; }
virtual u16 data() const noexcept override { return m_barcode; }

protected:
sega_9h0_0008_card_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);

// device_t implementation
virtual void device_start() override ATTR_COLD;

Expand All @@ -49,6 +62,6 @@ class tvochken_card_device : public device_t, public device_image_interface
};


DECLARE_DEVICE_TYPE(TVOCHKEN_CARD, tvochken_card_device)
DECLARE_DEVICE_TYPE(SEGA_9H0_0008_CARD, sega_9h0_0008_card_device)

#endif // MAME_SEGA_TVOCHKEN_CARD_H
#endif // MAME_SEGA_9H0_0008_CARD_H
Loading
Loading