627
644
m_type = CTYPE_TEXT;
628
645
m_string = xml_get_attribute_string_with_subst(machine, compnode, "string", "");
646
m_textalign = xml_get_attribute_int_with_subst(machine, compnode, "align", 0);
631
649
// dotmatrix nodes
632
650
else if (strcmp(compnode.name, "dotmatrix") == 0)
633
652
m_type = CTYPE_DOTMATRIX;
654
else if (strcmp(compnode.name, "dotmatrix5dot") == 0)
656
m_type = CTYPE_DOTMATRIX5DOT;
658
else if (strcmp(compnode.name, "dotmatrixdot") == 0)
660
m_type = CTYPE_DOTMATRIXDOT;
662
// simplecounter nodes
663
else if (strcmp(compnode.name, "simplecounter") == 0)
665
m_type = CTYPE_SIMPLECOUNTER;
666
m_digits = xml_get_attribute_int_with_subst(machine, compnode, "digits", 2);
668
// fruit machine reels
669
else if (strcmp(compnode.name, "reel") == 0)
673
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");
675
// split out position names from string and figure out our number of symbols
678
location=symbollist.find(0,",");
681
m_stopnames[m_numstops] = symbollist;
682
m_stopnames[m_numstops].substr(0, location);
683
symbollist.substr(location+1, symbollist.len()-(location-1));
685
location=symbollist.find(0,",");
687
m_stopnames[m_numstops++] = symbollist;
689
// careful, dirname is NULL if we're coming from internal layout, and our string assignment doesn't like that
693
for (int i=0;i<m_numstops;i++)
695
location=m_stopnames[i].find(0,":");
698
m_imagefile[i] = m_stopnames[i];
699
m_stopnames[i].substr(0, location);
700
m_imagefile[i].substr(location+1, m_imagefile[i].len()-(location-1));
703
m_file[i] = global_alloc(emu_file(machine.options().art_path(), OPEN_FLAG_READ));
707
//m_imagefile[i] = 0;
708
//m_alphafile[i] = 0;
713
m_stateoffset = xml_get_attribute_int_with_subst(machine, compnode, "stateoffset", 0);
714
m_numsymbolsvisible = xml_get_attribute_int_with_subst(machine, compnode, "numsymbolsvisible", 3);
715
m_reelreversed = xml_get_attribute_int_with_subst(machine, compnode, "reelreversed", 0);
636
718
else if (strcmp(compnode.name, "led7seg") == 0)
637
719
m_type = CTYPE_LED7SEG;
728
813
case CTYPE_DOTMATRIX:
729
draw_dotmatrix(dest, bounds, state);
814
draw_dotmatrix(8, dest, bounds, state);
817
case CTYPE_DOTMATRIX5DOT:
818
draw_dotmatrix(5, dest, bounds, state);
821
case CTYPE_DOTMATRIXDOT:
822
draw_dotmatrix(1, dest, bounds, state);
825
case CTYPE_SIMPLECOUNTER:
826
draw_simplecounter(machine, dest, bounds, state);
831
draw_reel(machine, dest, bounds, state);
895
1019
machine.render().font_free(font);
1022
void layout_element::component::draw_simplecounter(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
1025
sprintf(temp, "%0*d", m_digits, state);
1026
m_string = astring(temp);
1027
draw_text(machine, dest, bounds);
1030
/* 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 */
1031
void layout_element::component::draw_reel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
1035
const int max_state_used = 0x10000;
1037
// shift the reels a bit based on this param, allows fine tuning
1038
int use_state = (state + m_stateoffset) % max_state_used;
1040
// compute premultiplied colors
1041
UINT32 r = m_color.r * 255.0;
1042
UINT32 g = m_color.g * 255.0;
1043
UINT32 b = m_color.b * 255.0;
1044
UINT32 a = m_color.a * 255.0;
1046
// get the width of the string
1047
render_font *font = machine.render().font_alloc("default");
1048
float aspect = 1.0f;
1051
int num_shown = m_numsymbolsvisible;
1053
int ourheight = bounds.height();
1055
for (int fruit = 0;fruit<m_numstops;fruit++)
1061
if (m_reelreversed==1)
1063
basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
1067
basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
1071
if (basey < bounds.min_y)
1072
basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
1073
if (basey > bounds.max_y)
1074
basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
1076
int endpos = basey+ourheight/num_shown;
1078
// only render the symbol / text if it's atually in view because the code is SLOW
1079
if ((endpos >= bounds.min_y) && (basey <= bounds.max_y))
1084
width = font->string_width(ourheight/num_shown, aspect, m_stopnames[fruit]);
1085
if (width < bounds.width())
1091
curx = bounds.min_x + (bounds.width() - width) / 2;
1094
if (!m_bitmap[fruit].valid())
1095
load_reel_bitmap(fruit);
1097
if (m_file[fruit]) // render gfx
1099
bitmap_argb32 tempbitmap2(dest.width(), ourheight/num_shown);
1101
if (m_bitmap[fruit].valid())
1103
render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], m_color);
1105
for (int y = 0; y < ourheight/num_shown; y++)
1107
int effy = basey + y;
1109
if (effy >= bounds.min_y && effy <= bounds.max_y)
1111
UINT32 *src = &tempbitmap2.pix32(y);
1112
UINT32 *d = &dest.pix32(effy);
1113
for (int x = 0; x < dest.width(); x++)
1116
if (effx >= bounds.min_x && effx <= bounds.max_x)
1119
UINT32 spix = RGB_ALPHA(src[x]);
1131
else // render text (fallback)
1133
// allocate a temporary bitmap
1134
bitmap_argb32 tempbitmap(dest.width(), dest.height());
1136
// loop over characters
1137
for (const char *s = m_stopnames[fruit]; *s != 0; s++)
1139
// get the font bitmap
1141
font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, *s, chbounds);
1143
// copy the data into the target
1144
for (int y = 0; y < chbounds.height(); y++)
1146
int effy = basey + y;
1148
if (effy >= bounds.min_y && effy <= bounds.max_y)
1150
UINT32 *src = &tempbitmap.pix32(y);
1151
UINT32 *d = &dest.pix32(effy);
1152
for (int x = 0; x < chbounds.width(); x++)
1154
int effx = curx + x + chbounds.min_x;
1155
if (effx >= bounds.min_x && effx <= bounds.max_x)
1158
UINT32 spix = RGB_ALPHA(src[x]);
1161
UINT32 dpix = d[effx];
1162
UINT32 ta = (a * (spix + 1)) >> 8;
1163
UINT32 tr = (r * ta + RGB_RED(dpix) * (0x100 - ta)) >> 8;
1164
UINT32 tg = (g * ta + RGB_GREEN(dpix) * (0x100 - ta)) >> 8;
1165
UINT32 tb = (b * ta + RGB_BLUE(dpix) * (0x100 - ta)) >> 8;
1166
d[effx] = MAKE_ARGB(0xff, tr, tg, tb);
1173
// advance in the X direction
1174
curx += font->char_width(ourheight/num_shown, aspect, *s);
1181
curry += ourheight/num_shown;
1184
// free the temporary bitmap and font
1185
machine.render().font_free(font);
899
1191
//-------------------------------------------------
900
1192
// load_bitmap - load a PNG file with artwork for
904
1196
void layout_element::component::load_bitmap()
906
1198
// load the basic bitmap
907
assert(m_file != NULL);
908
m_hasalpha = render_load_png(m_bitmap, *m_file, m_dirname, m_imagefile);
1199
assert(m_file[0] != NULL);
1200
m_hasalpha[0] = render_load_png(m_bitmap[0], *m_file[0], m_dirname, m_imagefile[0]);
910
1202
// load the alpha bitmap if specified
911
if (m_bitmap.valid() && m_alphafile)
912
render_load_png(m_bitmap, *m_file, m_dirname, m_alphafile, true);
1203
if (m_bitmap[0].valid() && m_alphafile[0])
1204
render_load_png(m_bitmap[0], *m_file[0], m_dirname, m_alphafile[0], true);
914
1206
// if we can't load the bitmap, allocate a dummy one and report an error
915
if (!m_bitmap.valid())
1207
if (!m_bitmap[0].valid())
917
1209
// draw some stripes in the bitmap
918
m_bitmap.allocate(100, 100);
1210
m_bitmap[0].allocate(100, 100);
1211
m_bitmap[0].fill(0);
920
1212
for (int step = 0; step < 100; step += 25)
921
1213
for (int line = 0; line < 100; line++)
922
m_bitmap.pix32((step + line) % 100, line % 100) = MAKE_ARGB(0xff,0xff,0xff,0xff);
1214
m_bitmap[0].pix32((step + line) % 100, line % 100) = MAKE_ARGB(0xff,0xff,0xff,0xff);
926
mame_printf_warning("Unable to load component bitmap '%s'", m_imagefile.cstr());
1217
if (!m_alphafile[0])
1218
mame_printf_warning("Unable to load component bitmap '%s'", m_imagefile[0].cstr());
928
mame_printf_warning("Unable to load component bitmap '%s'/'%s'", m_imagefile.cstr(), m_alphafile.cstr());
1220
mame_printf_warning("Unable to load component bitmap '%s'/'%s'", m_imagefile[0].cstr(), m_alphafile[0].cstr());
1225
void layout_element::component::load_reel_bitmap(int number)
1228
// load the basic bitmap
1229
assert(m_file != NULL);
1230
/*m_hasalpha[number] = */ render_load_png(m_bitmap[number], *m_file[number], m_dirname, m_imagefile[number]);
1232
// load the alpha bitmap if specified
1233
//if (m_bitmap[number].valid() && m_alphafile[number])
1234
// render_load_png(m_bitmap[number], *m_file[number], m_dirname, m_alphafile[number], true);
1236
// if we can't load the bitmap just use text rendering
1237
if (!m_bitmap[number].valid())
1239
// fallback to text rendering
1240
global_free(m_file[number]);
1241
m_file[number] = NULL;
933
1248
//-------------------------------------------------
1428
1743
//-------------------------------------------------
1429
// draw_dotmatrix - draw a row of 8 dots for a
1744
// draw_dotmatrix - draw a row of dots for a
1431
1746
//-------------------------------------------------
1433
void layout_element::component::draw_dotmatrix(bitmap_argb32 &dest, const rectangle &bounds, int pattern)
1748
void layout_element::component::draw_dotmatrix(int dots, bitmap_argb32 &dest, const rectangle &bounds, int pattern)
1435
1750
const rgb_t onpen = MAKE_ARGB(0xff, 0xff, 0xff, 0xff);
1436
1751
const rgb_t offpen = MAKE_ARGB(0xff, 0x20, 0x20, 0x20);
1438
1753
// sizes for computation
1440
1754
int bmheight = 300;
1441
1755
int dotwidth = 250;
1443
1757
// allocate a temporary bitmap for drawing
1444
bitmap_argb32 tempbitmap(bmwidth, bmheight);
1758
bitmap_argb32 tempbitmap(dotwidth*dots, bmheight);
1445
1759
tempbitmap.fill(MAKE_ARGB(0xff, 0x00, 0x00, 0x00));
1447
for (int i = 0; i < 8; i++)
1761
for (int i = 0; i < dots; i++)
1448
1762
draw_segment_decimal(tempbitmap, ((dotwidth/2 )+ (i * dotwidth)), bmheight/2, dotwidth, (pattern & (1 << i))?onpen:offpen);
1450
1764
// resample to the target size