void palette_device::configure_tilemap_groups(tilemap_t &tmap, gfx_element &gfx, int transcolor) { int color; assert(gfx.colors() <= TILEMAP_NUM_GROUPS); // iterate over all colors in the tilemap for (color = 0; color < gfx.colors(); color++) tmap.set_transmask(color, transpen_mask(gfx, color, transcolor), 0); }
UINT32 palette_device::transpen_mask(gfx_element &gfx, int color, int transcolor) { UINT32 entry = gfx.colorbase() + (color % gfx.colors()) * gfx.granularity(); // make sure we are in range assert(entry < m_indirect_pens.size()); assert(gfx.depth() <= 32); // either gfx->color_depth entries or as many as we can get up until the end int count = MIN(gfx.depth(), m_indirect_pens.size() - entry); // set a bit anywhere the transcolor matches UINT32 mask = 0; for (int bit = 0; bit < count; bit++) if (m_indirect_pens[entry++] == transcolor) mask |= 1 << bit; // return the final mask return mask; }
static void gfxset_draw_item(running_machine &machine, gfx_element &gfx, int index, bitmap_rgb32 &bitmap, int dstx, int dsty, int color, int rotate, device_palette_interface *dpalette) { int width = (rotate & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width(); int height = (rotate & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height(); const rgb_t *palette = dpalette->palette()->entry_list_raw() + gfx.colorbase() + color * gfx.granularity(); int x, y; // loop over rows in the cell for (y = 0; y < height; y++) { uint32_t *dest = &bitmap.pix32(dsty + y, dstx); const uint8_t *src = gfx.get_data(index); // loop over columns in the cell for (x = 0; x < width; x++) { int effx = x, effy = y; const uint8_t *s; // compute effective x,y values after rotation if (!(rotate & ORIENTATION_SWAP_XY)) { if (rotate & ORIENTATION_FLIP_X) effx = gfx.width() - 1 - effx; if (rotate & ORIENTATION_FLIP_Y) effy = gfx.height() - 1 - effy; } else { if (rotate & ORIENTATION_FLIP_X) effx = gfx.height() - 1 - effx; if (rotate & ORIENTATION_FLIP_Y) effy = gfx.width() - 1 - effy; std::swap(effx, effy); } // get a pointer to the start of this source row s = src + effy * gfx.rowbytes(); // extract the pixel *dest++ = 0xff000000 | palette[s[effx]]; } } }
static void gfxset_update_bitmap(running_machine &machine, ui_gfx_state &state, int xcells, int ycells, gfx_element &gfx) { int dev = state.gfxset.devindex; int set = state.gfxset.set; ui_gfx_info &info = state.gfxdev[dev]; int cellxpix, cellypix; int x, y; // compute the number of source pixels in a cell cellxpix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width()); cellypix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height()); // realloc the bitmap if it is too small if (state.bitmap == nullptr || state.texture == nullptr || state.bitmap->bpp() != 32 || state.bitmap->width() != cellxpix * xcells || state.bitmap->height() != cellypix * ycells) { // free the old stuff machine.render().texture_free(state.texture); global_free(state.bitmap); // allocate new stuff state.bitmap = global_alloc(bitmap_rgb32(cellxpix * xcells, cellypix * ycells)); state.texture = machine.render().texture_alloc(); state.texture->set_bitmap(*state.bitmap, state.bitmap->cliprect(), TEXFORMAT_ARGB32); // force a redraw state.bitmap_dirty = true; } // handle the redraw if (state.bitmap_dirty) { // loop over rows for (y = 0; y < ycells; y++) { rectangle cellbounds; // make a rect that covers this row cellbounds.set(0, state.bitmap->width() - 1, y * cellypix, (y + 1) * cellypix - 1); // only display if there is data to show if (info.offset[set] + y * xcells < gfx.elements()) { // draw the individual cells for (x = 0; x < xcells; x++) { int index = info.offset[set] + y * xcells + x; // update the bounds for this cell cellbounds.min_x = x * cellxpix; cellbounds.max_x = (x + 1) * cellxpix - 1; // only render if there is data if (index < gfx.elements()) gfxset_draw_item(machine, gfx, index, *state.bitmap, cellbounds.min_x, cellbounds.min_y, info.color[set], info.rotate[set], info.palette[set]); // otherwise, fill with transparency else state.bitmap->fill(0, cellbounds); } } // otherwise, fill with transparency else state.bitmap->fill(0, cellbounds); } // reset the texture to force an update state.texture->set_bitmap(*state.bitmap, state.bitmap->cliprect(), TEXFORMAT_ARGB32); state.bitmap_dirty = false; } }