/** * @fn bitmap_t::bitmap_t(bitmap_format format, int bpp, bitmap_t &source, const rectangle &subrect) * * @brief Constructor. * * @param format Describes the format to use. * @param bpp The bits per pixel. * @param [in,out] source Source for the. * @param subrect The subrect. */ public bitmap_t(bitmap_format format, uint8_t bpp, bitmap_t source, rectangle subrect) { m_alloc = null; m_allocbytes = 0; m_base = source.raw_pixptr(subrect.top(), subrect.left()); //m_base(source.raw_pixptr(subrect.top(), subrect.left())) m_rowpixels = source.m_rowpixels; m_width = subrect.width(); m_height = subrect.height(); m_format = format; m_bpp = (uint8_t)bpp; m_palette = null; m_cliprect = new rectangle(0, subrect.width() - 1, 0, subrect.height() - 1); assert(format == source.m_format); assert(bpp == source.m_bpp); assert(source.cliprect().contains(subrect)); }
/** * @fn void bitmap_t::fill(UINT32 color, const rectangle &cliprect) * * @brief ------------------------------------------------- * fill -- fill a bitmap with a solid color * -------------------------------------------------. * * @param color The color. * @param bounds The bounds. */ public void fill(uint64_t color, rectangle bounds) { // if we have a cliprect, intersect with that rectangle fill = bounds; fill &= m_cliprect; if (!fill.empty()) { // based on the bpp go from there switch (m_bpp) { case 8: for (int32_t y = fill.top(); y <= fill.bottom(); y++) { std.fill_n(pixt <uint8_t, PixelType_operators_u8>(y, fill.left()), (size_t)fill.width(), (uint8_t)color); //std::fill_n(&pixt<uint8_t>(y, fill.left()), fill.width(), uint8_t(color)); } break; case 16: for (int32_t y = fill.top(); y <= fill.bottom(); ++y) { std.fill_n((PointerU16)pixt <uint16_t, PixelType_operators_u16>(y, fill.left()), (size_t)fill.width(), (uint16_t)color); //std::fill_n(&pixt<uint16_t>(y, fill.left()), fill.width(), uint16_t(color)); } break; case 32: for (int32_t y = fill.top(); y <= fill.bottom(); ++y) { std.fill_n((PointerU32)pixt <uint32_t, PixelType_operators_u32>(y, fill.left()), (size_t)fill.width(), (uint32_t)color); //std::fill_n(&pixt<uint32_t>(y, fill.left()), fill.width(), uint32_t(color)); } break; case 64: for (int32_t y = fill.top(); y <= fill.bottom(); ++y) { std.fill_n((PointerU64)pixt <uint64_t, PixelType_operators_u64>(y, fill.left()), (size_t)fill.width(), (uint64_t)color); //std::fill_n(&pixt<uint64_t>(y, fill.left()), fill.width(), uint64_t(color)); } break; } } }
// dirtying operations - partially intersecting tiles are dirtied void dirty(rectangle rect) { dirty(rect.left(), rect.right(), rect.top(), rect.bottom()); }
// subclass helpers void mark_dirty(rectangle rect) { mark_dirty(rect.left(), rect.right(), rect.top(), rect.bottom()); }
// cleaning operations - partially intersecting tiles are NOT cleaned public void clean(rectangle rect) { clean(rect.left(), rect.right(), rect.top(), rect.bottom()); }
//------------------------------------------------- // render_object: Internal processing callback // that renders to the backing bitmap and then // copies the result to the destination. //------------------------------------------------- void render_object(bitmap_ind16 bitmap, rectangle cliprect, Pointer <uint16_t> entry) //void atari_motion_objects_device::render_object(bitmap_ind16 &bitmap, const rectangle &cliprect, const uint16_t *entry) { // select the gfx element and save off key information int rawcode = (int)m_codemask.extract(entry); gfx_element gfx = m_gfxdecode.op0.gfx(m_gfxlookup[rawcode >> 8]); int save_granularity = gfx.granularity(); int save_colorbase = (int)gfx.colorbase(); int save_colors = (int)gfx.colors(); gfx.set_granularity(1); gfx.set_colorbase(0); gfx.set_colors(65536); // extract data from the various words int code = (int)m_codelookup[rawcode]; int color = m_colorlookup[m_colormask.extract(entry)]; int xpos = m_xposmask.extract(entry) + m_xoffset; int ypos = -m_yposmask.extract(entry); int hflip = m_hflipmask.extract(entry); int vflip = m_vflipmask.extract(entry); int width = m_widthmask.extract(entry) + 1; int height = m_heightmask.extract(entry) + 1; int priority = m_prioritymask.extract(entry); // compute the effective color, merging in priority color = (color * save_granularity) | (priority << PRIORITY_SHIFT); color += m_atari_motion_objects_config.m_palettebase; // add in the scroll positions if we're not in absolute coordinates if (m_absolutemask.extract(entry) == 0) { xpos -= (int)m_xscroll; ypos -= (int)m_yscroll; } // adjust for height ypos -= height << m_tileyshift; // handle previous hold bits if (m_next_xpos != 123456) { xpos = (int)m_next_xpos; } m_next_xpos = 123456; // check for the hold bit if (m_neighbormask.extract(entry) != 0) { if (!m_atari_motion_objects_config.m_nextneighbor) { xpos = (int)m_last_xpos + m_tilewidth; } else { m_next_xpos = (uint32_t)(xpos + m_tilewidth); } } m_last_xpos = (uint32_t)xpos; // adjust the final coordinates xpos &= m_bitmapxmask; ypos &= m_bitmapymask; if (xpos >= bitmap.width()) { xpos -= m_bitmapwidth; } if (ypos >= bitmap.height()) { ypos -= m_bitmapheight; } // is this one special? if (m_specialmask.mask() == 0 || m_specialmask.extract(entry) != m_atari_motion_objects_config.m_specialvalue) { // adjust for h flip int xadv = m_tilewidth; if (hflip != 0) { xpos += (width - 1) << m_tilexshift; xadv = -xadv; } // adjust for v flip int yadv = m_tileheight; if (vflip != 0) { ypos += (height - 1) << m_tileyshift; yadv = -yadv; } // standard order is: loop over Y first, then X if (!m_atari_motion_objects_config.m_swapxy) { // loop over the height for (int y = 0, sy = ypos; y < height; y++, sy += yadv) { // clip the Y coordinate if (sy <= cliprect.top() - m_tileheight) { code += width; continue; } else if (sy > cliprect.bottom()) { break; } // loop over the width for (int x = 0, sx = xpos; x < width; x++, sx += xadv, code++) { // clip the X coordinate if (sx <= -cliprect.left() - m_tilewidth || sx > cliprect.right()) { continue; } // draw the sprite gfx.transpen_raw(bitmap, cliprect, (u32)code, (u32)color, hflip, vflip, sx, sy, m_atari_motion_objects_config.m_transpen); mark_dirty(sx, sx + m_tilewidth - 1, sy, sy + m_tileheight - 1); } } } // alternative order is swapped else { // loop over the width for (int x = 0, sx = xpos; x < width; x++, sx += xadv) { // clip the X coordinate if (sx <= cliprect.left() - m_tilewidth) { code += height; continue; } else if (sx > cliprect.right()) { break; } // loop over the height for (int y = 0, sy = ypos; y < height; y++, sy += yadv, code++) { // clip the X coordinate if (sy <= -cliprect.top() - m_tileheight || sy > cliprect.bottom()) { continue; } // draw the sprite gfx.transpen_raw(bitmap, cliprect, (u32)code, (u32)color, hflip, vflip, sx, sy, m_atari_motion_objects_config.m_transpen); mark_dirty(sx, sx + m_tilewidth - 1, sy, sy + m_tileheight - 1); } } } } // restore original gfx information gfx.set_granularity((u16)save_granularity); gfx.set_colorbase((u16)save_colorbase); gfx.set_colors((u32)save_colors); }