Started adding support for scrolling reel displays, currently text

only, but should be pretty easy to get graphics in there and add
different direction scrolling - updating sc4 code to use these new types.  [David Haywood]

Stepper display output fix  [James Wallace]
This commit is contained in:
Scott Stone 2012-04-23 09:27:04 +00:00
parent 4f01aed69f
commit 03c6e6569e
4 changed files with 259 additions and 47 deletions

View File

@ -486,6 +486,10 @@ layout_element::layout_element(running_machine &machine, xml_data_node &elemnode
{
m_maxstate = xml_get_attribute_int_with_subst(machine, *compnode, "maxstate", 999);
}
if (newcomp.m_type == component::CTYPE_REEL)
{
m_maxstate = 65536;
}
}
// determine the scale/offset for normalization
@ -642,7 +646,31 @@ layout_element::component::component(running_machine &machine, xml_data_node &co
m_type = CTYPE_SIMPLECOUNTER;
m_digits = xml_get_attribute_int_with_subst(machine, compnode, "digits", 2);
}
// fruit machine reels
else if (strcmp(compnode.name, "reel") == 0)
{
m_type = CTYPE_REEL;
astring symbollist = xml_get_attribute_string_with_subst(machine, compnode, "symbollist", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
// split out position names from string and figure out our number of symbols
int location = -1;
m_numstops = 0;
location=symbollist.find(0,",");
while (location!=-1)
{
m_stopnames[m_numstops] = symbollist;
m_stopnames[m_numstops].substr(0, location);
symbollist.substr(location+1, symbollist.len()-(location-1));
m_numstops++;
location=symbollist.find(0,",");
}
m_stopnames[m_numstops++] = symbollist;
m_stateoffset = xml_get_attribute_int_with_subst(machine, compnode, "stateoffset", 0);
m_numsymbolsvisible = xml_get_attribute_int_with_subst(machine, compnode, "numsymbolsvisible", 3);
m_reelreversed = xml_get_attribute_int_with_subst(machine, compnode, "reelreversed", 0);
}
// led7seg nodes
else if (strcmp(compnode.name, "led7seg") == 0)
m_type = CTYPE_LED7SEG;
@ -744,6 +772,10 @@ void layout_element::component::draw(running_machine &machine, bitmap_argb32 &de
draw_simplecounter(machine, dest, bounds, state);
break;
case CTYPE_REEL:
draw_reel(machine, dest, bounds, state);
break;
default:
throw emu_fatalerror("Unknown component type requested draw()");
}
@ -940,6 +972,122 @@ void layout_element::component::draw_simplecounter(running_machine &machine, bit
draw_text(machine, dest, bounds);
}
/* state is a normalized value between 0 and 65536 so that we don't need to worry about how many motor steps here or in the .lay, only the number of symbols */
void layout_element::component::draw_reel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
{
const int max_state_used = 0x10000;
// shift the reels a bit based on this param, allows fine tuning
int use_state = (state + m_stateoffset) % max_state_used;
// compute premultiplied colors
UINT32 r = m_color.r * 255.0;
UINT32 g = m_color.g * 255.0;
UINT32 b = m_color.b * 255.0;
UINT32 a = m_color.a * 255.0;
// get the width of the string
render_font *font = machine.render().font_alloc("default");
float aspect = 1.0f;
INT32 width;
int curry = 0;
int num_shown = m_numsymbolsvisible;
int ourheight = bounds.height();
for (int fruit = 0;fruit<m_numstops;fruit++)
{
int basey;
if (m_reelreversed==1)
{
basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
}
else
{
basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
}
// wrap around...
if (basey < bounds.min_y)
basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
if (basey > bounds.max_y)
basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
int endpos = basey+ourheight/num_shown;
// only render the symbol / text if it's atually in view because the code is SLOW
if ((endpos >= bounds.min_y) && (basey <= bounds.max_y))
{
while (1)
{
width = font->string_width(ourheight/num_shown, aspect, m_stopnames[fruit]);
if (width < bounds.width())
break;
aspect *= 0.9f;
}
INT32 curx;
curx = bounds.min_x + (bounds.width() - width) / 2;
// allocate a temporary bitmap
bitmap_argb32 tempbitmap(dest.width(), dest.height());
// loop over characters
for (const char *s = m_stopnames[fruit]; *s != 0; s++)
{
// get the font bitmap
rectangle chbounds;
font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, *s, chbounds);
// copy the data into the target
for (int y = 0; y < chbounds.height(); y++)
{
int effy = basey + y;
if (effy >= bounds.min_y && effy <= bounds.max_y)
{
UINT32 *src = &tempbitmap.pix32(y);
UINT32 *d = &dest.pix32(effy);
for (int x = 0; x < chbounds.width(); x++)
{
int effx = curx + x + chbounds.min_x;
if (effx >= bounds.min_x && effx <= bounds.max_x)
{
UINT32 spix = RGB_ALPHA(src[x]);
if (spix != 0)
{
UINT32 dpix = d[effx];
UINT32 ta = (a * (spix + 1)) >> 8;
UINT32 tr = (r * ta + RGB_RED(dpix) * (0x100 - ta)) >> 8;
UINT32 tg = (g * ta + RGB_GREEN(dpix) * (0x100 - ta)) >> 8;
UINT32 tb = (b * ta + RGB_BLUE(dpix) * (0x100 - ta)) >> 8;
d[effx] = MAKE_ARGB(0xff, tr, tg, tb);
}
}
}
}
}
// advance in the X direction
curx += font->char_width(ourheight/num_shown, aspect, *s);
}
}
curry += ourheight/num_shown;
}
// free the temporary bitmap and font
machine.render().font_free(font);
}
//-------------------------------------------------
// load_bitmap - load a PNG file with artwork for

View File

@ -122,6 +122,7 @@ private:
CTYPE_LED16SEGSC,
CTYPE_DOTMATRIX,
CTYPE_SIMPLECOUNTER,
CTYPE_REEL,
CTYPE_MAX
};
@ -130,6 +131,7 @@ private:
void draw_disk(bitmap_argb32 &dest, const rectangle &bounds);
void draw_text(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds);
void draw_simplecounter(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state);
void draw_reel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state);
void load_bitmap();
void draw_led7seg(bitmap_argb32 &dest, const rectangle &bounds, int pattern);
void draw_led14seg(bitmap_argb32 &dest, const rectangle &bounds, int pattern);
@ -162,6 +164,15 @@ private:
astring m_imagefile; // name of the image file (for lazy loading)
astring m_alphafile; // name of the alpha file (for lazy loading)
bool m_hasalpha; // is there any alpha component present?
#define MAX_STOPS 256
// stuff for fruit machine reels
int m_numstops;
astring m_stopnames[MAX_STOPS];
int m_stateoffset;
int m_reelreversed;
int m_numsymbolsvisible;
};
// a texture encapsulates a texture for a given element in a given state

View File

@ -15,13 +15,58 @@
</rect>
</element>
<element name="Steppers" defstate="0">
<simplecounter maxstate="999" digits="2">
<simplecounter maxstate="999" digits="3">
<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0.1" width="1" height="1" />
<bounds x="0" y="0" width="1" height="1" />
</simplecounter>
</element>
<element name="vfd0">
<!-- a stateoffset of 682 will shift us by 1 step on a 96 step reel (0x10000/96) which seems a good default alignment for 96 step / 16 symbol reels -->
<element name="SteppersReel1" defstate="0">
<reel stateoffset="682" symbollist="Fruit1,Fruit2,Fruit3,Fruit4,Fruit5,Fruit6,Fruit7,Fruit8,Fruit9,Fruit10,Fruit11,Fruit12,Fruit13,Fruit14,Fruit15,Fruit16">
<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0" width="1" height="1" />
</reel>
</element>
<element name="SteppersReel2" defstate="0">
<reel stateoffset="682" symbollist="Fruit1,Fruit2,Fruit3,Fruit4,Fruit5,Fruit6,Fruit7,Fruit8,Fruit9,Fruit10,Fruit11,Fruit12,Fruit13,Fruit14,Fruit15,Fruit16">
"<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0" width="1" height="1" />
</reel>
</element>
<element name="SteppersReel3" defstate="0">
<reel stateoffset="682" symbollist="Fruit1,Fruit2,Fruit3,Fruit4,Fruit5,Fruit6,Fruit7,Fruit8,Fruit9,Fruit10,Fruit11,Fruit12,Fruit13,Fruit14,Fruit15,Fruit16">
<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0" width="1" height="1" />
</reel>
</element>
<element name="SteppersReel4" defstate="0">
<reel stateoffset="682" symbollist="Fruit1,Fruit2,Fruit3,Fruit4,Fruit5,Fruit6,Fruit7,Fruit8,Fruit9,Fruit10,Fruit11,Fruit12,Fruit13,Fruit14,Fruit15,Fruit16">
<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0" width="1" height="1" />
</reel>
</element>
<element name="SteppersReel5" defstate="0">
<reel symbollist="Example1,Example2,Example3,Example4,Example5,Example6,Example7,Example8,Example9,Example10,Example11,Example12">
<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0" width="1" height="1" />
</reel>
</element>
<element name="SteppersReel6" defstate="0">
<reel symbollist="Example1,Example2,Example3,Example4,Example5,Example6,Example7,Example8,Example9,Example10,Example11,Example12">
<color red="1.0" green="1.0" blue="1.0" />
<bounds x="0" y="0" width="1" height="1" />
</reel>
</element>
<element name="vfd0">
<led14segsc>
<color red="0" green="0.6" blue="1.0" />
</led14segsc>
@ -81,29 +126,53 @@
<backdrop name="vfd15" element="vfd0" state="0">
<bounds x="345" y="200" width="9" height="17"/>
</backdrop>
<backdrop name="reel1" element="Steppers" state="0">
<bounds x="210" y="300" width="50" height="50"/>
<backdrop name="reel1" element="Steppers" state="0">
<bounds x="250" y="350" width="10" height="5"/>
</backdrop>
<backdrop name="reel2" element="Steppers" state="0">
<bounds x="260" y="300" width="50" height="50"/>
<bounds x="300" y="350" width="10" height="5"/>
</backdrop>
<backdrop name="reel3" element="Steppers" state="0">
<bounds x="310" y="300" width="50" height="50"/>
<bounds x="350" y="350" width="10" height="5"/>
</backdrop>
<backdrop name="reel4" element="Steppers" state="0">
<bounds x="210" y="360" width="50" height="50"/>
<bounds x="250" y="410" width="10" height="5"/>
</backdrop>
<backdrop name="reel5" element="Steppers" state="0">
<bounds x="260" y="360" width="50" height="50"/>
<bounds x="300" y="410" width="10" height="5"/>
</backdrop>
<backdrop name="reel6" element="Steppers" state="0">
<bounds x="310" y="360" width="50" height="50"/>
<bounds x="350" y="410" width="10" height="5"/>
</backdrop>
<backdrop name="sreel1" element="SteppersReel1" state="0">
<bounds x="210" y="300" width="50" height="50"/>
</backdrop>
<backdrop name="sreel2" element="SteppersReel2" state="0">
<bounds x="260" y="300" width="50" height="50"/>
</backdrop>
<backdrop name="sreel3" element="SteppersReel3" state="0">
<bounds x="310" y="300" width="50" height="50"/>
</backdrop>
<backdrop name="sreel4" element="SteppersReel4" state="0">
<bounds x="210" y="360" width="50" height="50"/>
</backdrop>
<backdrop name="sreel5" element="SteppersReel5" state="0">
<bounds x="260" y="360" width="50" height="50"/>
</backdrop>
<backdrop name="sreel6" element="SteppersReel6" state="0">
<bounds x="310" y="360" width="50" height="50"/>
</backdrop>
<backdrop name="lamp0" element="matrixlamp" state="0">
<backdrop name="lamp0" element="matrixlamp" state="0">
<bounds x="0" y="0" width="7" height="7"/>
</backdrop>
<backdrop name="lamp1" element="matrixlamp" state="0">

View File

@ -1,32 +1,13 @@
/*************************************************************************************
AWP Hardware video simulation system
originally written for AGEMAME by J.Wallace
A.G.E Code Copyright J. Wallace and the AGEMAME Development Team.
Visit http://www.mameworld.net/agemame/ for more information.
M.A.M.E Core Copyright Nicola Salmoria and the MAME Team,
used under license from http://mamedev.org
**************************************************************************************
NOTE: Fading lamp system currently only recognises three lamp states:
0=off, 1, 2= fully on
Based on evidence, newer techs may need more states, but we can give them their own
handlers at some stage in the distant future.
Instructions:
In order to set up displays (dot matrices, etc) we normally set up the unique
displays first, and then add the remainder in order.
The priorities (in descending order) are:
Full video screens
Dot matrix displays
Other, as yet unknown devices
M.A.M.E Core Copyright Nicola Salmoria and the MAME Team.
This is a primitive handler for generating reels with multiple symbols visible
hanging off steppers.c .
**************************************************************************************/
#include "emu.h"
@ -93,27 +74,30 @@ void awp_draw_reel(int rno)
}
else
{
reelpos[rno] = stepper_get_position(rno)%(stepper_get_max(rno)-1);
reelpos[rno] = stepper_get_position(rno);
/* legacy symbol support */
for ( m = 0; m < (rsymbols-1); m++ )
{
{
sprintf(rga,"reel%da%d", x, m);
output_set_value(rga,(reelpos[rno] + rsteps * m)%stepper_get_max(rno));
output_set_value(rga,(reelpos[rno] + (rsteps * m) + stepper_get_max(rno)) % stepper_get_max(rno));
}
{
if ((reelpos[rno] - rsteps * m) < 0)
{
sprintf(rgb,"reel%db%d", x, m);
output_set_value(rgb,(reelpos[rno] - (rsteps * m - stepper_get_max(rno))));
}
else
{
sprintf(rgb,"reel%db%d", x, m);
output_set_value(rgb,(reelpos[rno] - rsteps * m));
}
sprintf(rgb,"reel%db%d", x, m);
output_set_value(rgb,(reelpos[rno] - (rsteps * m) + stepper_get_max(rno)) % stepper_get_max(rno));
}
}
output_set_value(rg,(reelpos[rno]));
sprintf(rg,"sreel%d", x); // out new scrolling reels are called 'sreel'
// normalize the value
int sreelpos = (reelpos[rno] * 0x10000) / stepper_get_max(rno);
output_set_value(rg,sreelpos);
}
}