mirror of
https://github.com/holub/mame
synced 2025-06-07 21:33:45 +03:00
pwm_display: add support for multi-state outputs per brightness level
This commit is contained in:
parent
d196d072ff
commit
fd45e9cfad
@ -15,8 +15,12 @@ or write_row to set them.
|
||||
|
||||
Display element states are sent to output tags "y.x" where y is the matrix row
|
||||
number, x is the row bit. It is also sent to "y.a" for all rows. The output state
|
||||
is 0 for off, and >0 for on, depending on brightness level. If segmask is defined,
|
||||
it is also sent to "digity", for use with multi-state elements, eg. 7seg leds.
|
||||
is 0 for off, and >0 for on, depending on brightness level.
|
||||
|
||||
If segmask is defined, it is also sent to "multiy.b" where b is brightness level,
|
||||
for use with multi-state elements. This usecase is not common though (one example
|
||||
is Coleco Quarterback where some digit segments are brighter). And when brightness
|
||||
level does not matter, it is also sent to "digity", for common 7seg leds.
|
||||
|
||||
If you use this device in a slot, or use multiple of them (or just don't want
|
||||
to use the default output tags), set a callback.
|
||||
@ -25,9 +29,9 @@ Brightness tresholds (0.0 to 1.0) indicate how long an element was powered on
|
||||
in the last frame, eg. 0.01 means a minimum on-time for 1%. Some games use two
|
||||
levels of brightness by strobing elements longer.
|
||||
|
||||
|
||||
TODO:
|
||||
- SVG screens and rendlay digit elements don't support multiple brightness levels
|
||||
- SVG screens and rendlay digit elements don't support multiple brightness levels,
|
||||
the latter can be worked around with by stacking digits on top of eachother
|
||||
|
||||
*/
|
||||
|
||||
@ -47,9 +51,11 @@ pwm_display_device::pwm_display_device(const machine_config &mconfig, const char
|
||||
device_t(mconfig, PWM_DISPLAY, tag, owner, clock),
|
||||
m_out_x(*this, "%u.%u", 0U, 0U),
|
||||
m_out_a(*this, "%u.a", 0U),
|
||||
m_out_multi(*this, "multi%u.%u", 0U, 0U),
|
||||
m_out_digit(*this, "digit%u", 0U),
|
||||
m_output_x_cb(*this),
|
||||
m_output_a_cb(*this),
|
||||
m_output_multi_cb(*this),
|
||||
m_output_digit_cb(*this)
|
||||
{
|
||||
// set defaults
|
||||
@ -70,15 +76,17 @@ pwm_display_device::pwm_display_device(const machine_config &mconfig, const char
|
||||
void pwm_display_device::device_start()
|
||||
{
|
||||
// resolve handlers
|
||||
m_external_output = !m_output_x_cb.isnull() || !m_output_a_cb.isnull() || !m_output_digit_cb.isnull();
|
||||
m_external_output = !m_output_x_cb.isnull() || !m_output_a_cb.isnull() || !m_output_multi_cb.isnull() || !m_output_digit_cb.isnull();
|
||||
m_output_x_cb.resolve_safe();
|
||||
m_output_a_cb.resolve_safe();
|
||||
m_output_multi_cb.resolve_safe();
|
||||
m_output_digit_cb.resolve_safe();
|
||||
|
||||
if (!m_external_output)
|
||||
{
|
||||
m_out_x.resolve();
|
||||
m_out_a.resolve();
|
||||
m_out_multi.resolve();
|
||||
m_out_digit.resolve();
|
||||
}
|
||||
|
||||
@ -191,13 +199,12 @@ TIMER_CALLBACK_MEMBER(pwm_display_device::frame_tick)
|
||||
const double factor1 = 1.0 - factor0;
|
||||
|
||||
// determine brightness cutoff
|
||||
u8 max_levels = 1;
|
||||
for (; m_levels[max_levels] < 1.0; max_levels++) { ; }
|
||||
double cutoff = m_level_max;
|
||||
|
||||
if (cutoff == 0.0)
|
||||
{
|
||||
u8 level;
|
||||
for (level = 1; m_levels[level] < 1.0; level++) { ; }
|
||||
cutoff = 4 * m_levels[level - 1];
|
||||
}
|
||||
cutoff = 4 * m_levels[max_levels - 1];
|
||||
if (cutoff > 1.0)
|
||||
cutoff = 1.0;
|
||||
|
||||
@ -205,7 +212,8 @@ TIMER_CALLBACK_MEMBER(pwm_display_device::frame_tick)
|
||||
|
||||
for (int y = 0; y < m_height; y++)
|
||||
{
|
||||
u64 row = 0;
|
||||
u64 multi_row[0x40];
|
||||
std::fill(std::begin(multi_row), std::end(multi_row), 0);
|
||||
|
||||
for (int x = 0; x <= m_width; x++)
|
||||
{
|
||||
@ -221,8 +229,7 @@ TIMER_CALLBACK_MEMBER(pwm_display_device::frame_tick)
|
||||
// output to y.x, or y.a when always-on
|
||||
if (x != m_width)
|
||||
{
|
||||
if (level > m_level_min)
|
||||
row |= (u64(1) << x);
|
||||
multi_row[level] |= (u64(1) << x);
|
||||
|
||||
if (m_external_output)
|
||||
m_output_x_cb(x << 6 | y, level);
|
||||
@ -238,15 +245,29 @@ TIMER_CALLBACK_MEMBER(pwm_display_device::frame_tick)
|
||||
}
|
||||
}
|
||||
|
||||
// output to digity (does not support multiple brightness levels)
|
||||
// multi-state outputs
|
||||
if (m_segmask[y] != 0)
|
||||
{
|
||||
row &= m_segmask[y];
|
||||
u64 digit_row = 0;
|
||||
|
||||
for (int b = 0; b <= max_levels; b++)
|
||||
{
|
||||
multi_row[b] &= m_segmask[y];
|
||||
if (b > m_level_min)
|
||||
digit_row |= multi_row[b];
|
||||
|
||||
// output to multiy.b
|
||||
if (m_external_output)
|
||||
m_output_multi_cb(b << 6 | y, digit_row);
|
||||
else
|
||||
m_out_multi[y][b] = multi_row[b];
|
||||
}
|
||||
|
||||
// output to digity (single brightness level)
|
||||
if (m_external_output)
|
||||
m_output_digit_cb(y, row);
|
||||
m_output_digit_cb(y, digit_row);
|
||||
else
|
||||
m_out_digit[y] = row;
|
||||
m_out_digit[y] = digit_row;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
// output callbacks when not using the default output tags
|
||||
auto output_x() { return m_output_x_cb.bind(); } // x = offset >> 6, y = offset & 0x3f
|
||||
auto output_a() { return m_output_a_cb.bind(); }
|
||||
auto output_multi() { return m_output_multi_cb.bind(); } // b = offset >> 6, y = offset & 0x3f
|
||||
auto output_digit() { return m_output_digit_cb.bind(); }
|
||||
|
||||
void reset_bri_levels() { std::fill(std::begin(m_levels), std::end(m_levels), 1.0); }
|
||||
@ -68,10 +69,12 @@ protected:
|
||||
private:
|
||||
output_finder<0x40, 0x40> m_out_x;
|
||||
output_finder<0x40> m_out_a;
|
||||
output_finder<0x40, 0x40> m_out_multi;
|
||||
output_finder<0x40> m_out_digit;
|
||||
|
||||
devcb_write8 m_output_x_cb;
|
||||
devcb_write8 m_output_a_cb;
|
||||
devcb_write64 m_output_multi_cb;
|
||||
devcb_write64 m_output_digit_cb;
|
||||
bool m_external_output;
|
||||
|
||||
|
@ -57,15 +57,15 @@ license:CC0
|
||||
</element>
|
||||
|
||||
<element name="digit" defstate="0">
|
||||
<led7seg><color red="1.0" green="0.25" blue="0.26" /></led7seg>
|
||||
<led7seg alpha="0.0833"><color red="1.0" green="0.25" blue="0.26" /></led7seg>
|
||||
</element>
|
||||
<element name="seg" defstate="0">
|
||||
<rect state="0"><color red="0.13" green="0.0325" blue="0.0338" /></rect>
|
||||
<rect state="1"><color red="0.5" green="0.125" blue="0.13" /></rect>
|
||||
<rect state="2"><color red="1.0" green="0.25" blue="0.26" /></rect>
|
||||
</element>
|
||||
<element name="mask" defstate="0">
|
||||
<disk state="1"><color red="0" green="0" blue="0" /></disk>
|
||||
<element name="mask">
|
||||
<rect><color red="0" green="0" blue="0" /></rect>
|
||||
</element>
|
||||
|
||||
|
||||
@ -141,62 +141,16 @@ license:CC0
|
||||
<element ref="static_white"><bounds x="344" y="56" width="4" height="1" /></element>
|
||||
|
||||
<!-- leds -->
|
||||
<element name="digit0" ref="digit"><bounds x="3" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="0.8" ref="seg"><bounds x="7" y="42.5" width="15" height="3" /></element>
|
||||
<element name="0.9" ref="seg"><bounds x="7" y="71.5" width="15" height="3" /></element>
|
||||
<repeat count="9">
|
||||
<param name="xd" start="3" increment="44" />
|
||||
<param name="xs" start="7" increment="44" />
|
||||
<param name="i" start="0" increment="1" />
|
||||
|
||||
<element name="digit1" ref="digit"><bounds x="47" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="1.8" ref="seg"><bounds x="51" y="42.5" width="15" height="3" /></element>
|
||||
<element name="1.9" ref="seg"><bounds x="51" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit2" ref="digit"><bounds x="91" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="2.8" ref="seg"><bounds x="95" y="42.5" width="15" height="3" /></element>
|
||||
<element name="2.9" ref="seg"><bounds x="95" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit3" ref="digit"><bounds x="135" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="3.8" ref="seg"><bounds x="139" y="42.5" width="15" height="3" /></element>
|
||||
<element name="3.9" ref="seg"><bounds x="139" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit4" ref="digit"><bounds x="179" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="4.8" ref="seg"><bounds x="183" y="42.5" width="15" height="3" /></element>
|
||||
<element name="4.9" ref="seg"><bounds x="183" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit5" ref="digit"><bounds x="223" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="5.8" ref="seg"><bounds x="227" y="42.5" width="15" height="3" /></element>
|
||||
<element name="5.9" ref="seg"><bounds x="227" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit6" ref="digit"><bounds x="267" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="6.8" ref="seg"><bounds x="271" y="42.5" width="15" height="3" /></element>
|
||||
<element name="6.9" ref="seg"><bounds x="271" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit7" ref="digit"><bounds x="311" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="7.8" ref="seg"><bounds x="315" y="42.5" width="15" height="3" /></element>
|
||||
<element name="7.9" ref="seg"><bounds x="315" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<element name="digit8" ref="digit"><bounds x="355" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="8.8" ref="seg"><bounds x="359" y="42.5" width="15" height="3" /></element>
|
||||
<element name="8.9" ref="seg"><bounds x="359" y="71.5" width="15" height="3" /></element>
|
||||
|
||||
<!-- digit masks -->
|
||||
<element name="0.0" ref="mask"><bounds x="8" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="1.0" ref="mask"><bounds x="52" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="2.0" ref="mask"><bounds x="96" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="3.0" ref="mask"><bounds x="140" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="4.0" ref="mask"><bounds x="184" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="5.0" ref="mask"><bounds x="228" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="6.0" ref="mask"><bounds x="272" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="7.0" ref="mask"><bounds x="316" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="8.0" ref="mask"><bounds x="360" y="-17" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
|
||||
<element name="0.3" ref="mask"><bounds x="5" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="1.3" ref="mask"><bounds x="49" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="2.3" ref="mask"><bounds x="93" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="3.3" ref="mask"><bounds x="137" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="4.3" ref="mask"><bounds x="181" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="5.3" ref="mask"><bounds x="225" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="6.3" ref="mask"><bounds x="269" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="7.3" ref="mask"><bounds x="313" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="8.3" ref="mask"><bounds x="357" y="12" width="17" height="6" /><color alpha="0.5" /></element>
|
||||
<element name="multi~i~.1" ref="digit"><bounds x="~xd~" y="-15.5" width="24" height="32" /><color alpha="0.5" /></element>
|
||||
<element name="multi~i~.2" ref="digit"><bounds x="~xd~" y="-15.5" width="24" height="32" /></element>
|
||||
<element name="~i~.8" ref="seg"><bounds x="~xs~" y="42.5" width="15" height="3" /></element>
|
||||
<element name="~i~.9" ref="seg"><bounds x="~xs~" y="71.5" width="15" height="3" /></element>
|
||||
</repeat>
|
||||
|
||||
</view>
|
||||
</mamelayout>
|
||||
|
Loading…
Reference in New Issue
Block a user