Ejemplo n.º 1
0
        /**
         * @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;
                }
            }
        }
Ejemplo n.º 2
0
        /**
         * @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));
        }
Ejemplo n.º 3
0
 // dirtying operations - partially intersecting tiles are dirtied
 void dirty(rectangle rect)
 {
     dirty(rect.left(), rect.right(), rect.top(), rect.bottom());
 }
Ejemplo n.º 4
0
 // subclass helpers
 void mark_dirty(rectangle rect)
 {
     mark_dirty(rect.left(), rect.right(), rect.top(), rect.bottom());
 }
Ejemplo n.º 5
0
        // cleaning operations - partially intersecting tiles are NOT cleaned

        public void clean(rectangle rect)
        {
            clean(rect.left(), rect.right(), rect.top(), rect.bottom());
        }
Ejemplo n.º 6
0
        //-------------------------------------------------
        //  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);
        }
Ejemplo n.º 7
0
        }                                                                                                //void set_config(const atari_motion_objects_config &config) { static_cast<atari_motion_objects_config &>(*this) = config; }

        //void set_xoffset(int xoffset) { m_xoffset = xoffset; }


        // getters
        //int bank() const { return m_bank; }
        //int xscroll() const { return m_xscroll; }
        //int yscroll() const { return m_yscroll; }
        //std::vector<uint32_t> &code_lookup() { return m_codelookup; }
        //std::vector<uint8_t> &color_lookup() { return m_colorlookup; }
        //std::vector<uint8_t> &gfx_lookup() { return m_gfxlookup; }

        // setters
        //void set_bank(int bank) { m_bank = bank; }
        //void set_xscroll(int xscroll) { m_xscroll = xscroll & m_bitmapxmask; }
        //void set_yscroll(int yscroll) { m_yscroll = yscroll & m_bitmapymask; }
        //void set_scroll(int xscroll, int yscroll) { set_xscroll(xscroll); set_yscroll(yscroll); }
        //void set_slipram(uint16_t *ram) { m_slipram = ram; }


        // rendering
        //-------------------------------------------------
        //  draw: Render the motion objects to the
        //  destination bitmap.
        //-------------------------------------------------
        protected override void draw(bitmap_ind16 bitmap, rectangle cliprect)
        {
            // compute start/stop bands
            int startband = ((cliprect.top() + (int)m_yscroll - m_atari_motion_objects_config.m_slipoffset) & m_bitmapymask) >> m_slipshift;
            int stopband  = ((cliprect.bottom() + (int)m_yscroll - m_atari_motion_objects_config.m_slipoffset) & m_bitmapymask) >> m_slipshift;

            if (startband > stopband)
            {
                startband -= m_bitmapheight >> m_slipshift;
            }
            if (m_slipshift == 0)
            {
                stopband = startband;
            }

            // loop over SLIP bands
            for (int band = startband; band <= stopband; band++)
            {
                // compute the starting link and clip for the current band
                rectangle bandclip = cliprect;
                int       link     = 0;
                if (m_slipshift != 0)
                {
                    // extract the link from the SLIP RAM
                    link = (m_slipram[band & m_sliprammask] >> m_linkmask.shift()) & m_linkmask.mask();

                    // compute minimum Y and wrap around if necessary
                    bandclip.min_y = ((band << m_slipshift) - (int)m_yscroll + m_atari_motion_objects_config.m_slipoffset) & m_bitmapymask;
                    if (bandclip.min_y >= bitmap.height())
                    {
                        bandclip.min_y -= m_bitmapheight;
                    }

                    // maximum Y is based on the minimum
                    bandclip.set_height(1 << m_slipshift);

                    // keep within the cliprect
                    bandclip &= cliprect;
                }

                // if this matches the last link, we don't need to re-process the list
                build_active_list(link);

                // initialize the parameters
                m_next_xpos = 123456;

                // safety check
                if (m_activelist == m_activelast.Buffer && m_activelast.Offset == 0)  //if (m_activelist == m_activelast)
                {
                    continue;
                }

                // set the start and end points
                Pointer <uint16_t> first;  //uint16_t *first, *last;
                Pointer <uint16_t> last;
                int step;
                if (m_atari_motion_objects_config.m_reverse)
                {
                    first = m_activelast - 4;
                    last  = new Pointer <uint16_t>(m_activelist);
                    step  = -4;
                }
                else
                {
                    first = new Pointer <uint16_t>(m_activelist);
                    last  = m_activelast - 4;
                    step  = 4;
                }

                // render the mos
                for (Pointer <uint16_t> current = new Pointer <uint16_t>(first); ; current += step)  //for (uint16_t *current = first; ; current += step)
                {
                    render_object(bitmap, bandclip, current);
                    if (current.Buffer == last.Buffer && current.Offset == last.Offset)  //if (current == last)
                    {
                        break;
                    }
                }
            }
        }