예제 #1
0
        /*************************************
        *
        *  Main refresh
        *
        *************************************/
        uint32_t screen_update_atarisy2(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect)
        {
            // start drawing
            m_mob.op0.draw_async(cliprect);

            // reset priorities
            bitmap_ind8 priority_bitmap = screen.priority();

            priority_bitmap.fill(0, cliprect);

            // draw the playfield
            m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 0, 0);
            m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 1, 1);
            m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 2, 2);
            m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 3, 3);

            // draw and merge the MO
            bitmap_ind16 mobitmap = m_mob.op0.bitmap();

            for (sparse_dirty_rect rect = m_mob.op0.first_dirty_rect(cliprect); rect != null; rect = rect.next())
            {
                for (int y = rect.m_rect.top(); y <= rect.m_rect.bottom(); y++)
                {
                    PointerU16 mo  = mobitmap.pix(y);        //uint16_t const *const mo = &mobitmap.pix(y);
                    PointerU16 pf  = bitmap.pix(y);          //uint16_t *const pf = &bitmap.pix(y);
                    PointerU8  pri = priority_bitmap.pix(y); //uint8_t const *const pri = &priority_bitmap.pix(y);
                    for (int x = rect.m_rect.left(); x <= rect.m_rect.right(); x++)
                    {
                        if (mo[x] != 0xffff)
                        {
                            int mopriority = mo[x] >> atari_motion_objects_device.PRIORITY_SHIFT;

                            // high priority PF?
                            if (((mopriority + pri[x]) & 2) != 0)
                            {
                                // only gets priority if PF pen is less than 8
                                if ((pf[x] & 0x08) == 0)
                                {
                                    pf[x] = (uint16_t)(mo[x] & atari_motion_objects_device.DATA_MASK);
                                }
                            }

                            // low priority
                            else
                            {
                                pf[x] = (uint16_t)(mo[x] & atari_motion_objects_device.DATA_MASK);
                            }
                        }
                    }
                }
            }

            // add the alpha on top
            m_alpha_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 0, 0);
            return(0);
        }
예제 #2
0
        //-------------------------------------------------
        //  first_dirty_rect -- return the first dirty
        //  rectangle in the list
        //-------------------------------------------------
        public sparse_dirty_rect first_dirty_rect(rectangle cliprect)
        {
            // if what we have is valid, just return it again
            if (m_rect_list_bounds == cliprect)
            {
                return(m_rect_list.empty() ? null : m_rect_list.first());
            }

            // reclaim the dirty list and start over
            m_rect_allocator.reclaim_all(m_rect_list);

            // compute dirty space rectangle coordinates
            int sx       = cliprect.min_x >> m_granularity;
            int ex       = cliprect.max_x >> m_granularity;
            int sy       = cliprect.min_y >> m_granularity;
            int ey       = cliprect.max_y >> m_granularity;
            int tilesize = 1 << m_granularity;

            // loop over all grid rows that intersect our cliprect
            for (int y = sy; y <= ey; y++)
            {
                PointerU8         dirtybase = m_bitmap.pix(y); //uint8_t *dirtybase = &m_bitmap.pix(y);
                sparse_dirty_rect currect   = null;

                // loop over all grid columns that intersect our cliprect
                for (int x = sx; x <= ex; x++)
                {
                    // if this tile is not dirty, end our current run and continue
                    if (dirtybase[x] == 0)
                    {
                        if (currect != null)
                        {
                            currect.m_rect &= cliprect;  //*currect &= cliprect;
                        }
                        currect = null;
                        continue;
                    }

                    // if we can't add to an existing rect, create a new one
                    if (currect == null)
                    {
                        // allocate a new rect and add it to the list
                        currect = m_rect_list.append(m_rect_allocator.alloc());

                        // make a rect describing this grid square
                        currect.m_rect.min_x = x << m_granularity;
                        currect.m_rect.max_x = currect.m_rect.min_x + tilesize - 1;
                        currect.m_rect.min_y = y << m_granularity;
                        currect.m_rect.max_y = currect.m_rect.min_y + tilesize - 1;
                    }

                    // if we can add to the previous rect, just expand its width
                    else
                    {
                        currect.m_rect.max_x += tilesize;
                    }
                }

                // clip the last rect to the cliprect
                if (currect != null)
                {
                    currect.m_rect &= cliprect;
                }
            }

            // mark the list as valid
            m_rect_list_bounds = cliprect;
            return(m_rect_list.empty() ? null : m_rect_list.first());
        }