Exemplo n.º 1
0
        public static void tilemap_update(tilemap _tilemap)
        {
            if (_tilemap == ALL_TILEMAPS)
            {
                _tilemap = first_tilemap;
                while (_tilemap != null)
                {
                    tilemap_update(_tilemap);
                    _tilemap = _tilemap.next;
                }
            }
            else if (_tilemap.enable)
            {
                if (_tilemap.scrolled)
                {
                    tilemap_draw_delegate mark_visible = _tilemap.mark_visible;

                    int rows = _tilemap.scroll_rows;
                    int[] rowscroll = _tilemap.rowscroll;
                    int cols = _tilemap.scroll_cols;
                    int[] colscroll = _tilemap.colscroll;

                    int left = _tilemap.clip_left;
                    int right = _tilemap.clip_right;
                    int top = _tilemap.clip_top;
                    int bottom = _tilemap.clip_bottom;

                    blit.source_width = _tilemap.width;
                    blit.source_height = _tilemap.height;
                    blit.visible_row = _tilemap.visible_row;

                    //memset(_tilemap.visible, 0, _tilemap.num_tiles);
                    Array.Clear(_tilemap.visible, 0, _tilemap.num_tiles);
                    if (rows == 0 && cols == 0)
                    { /* no scrolling */
                        blit.clip_left = left;
                        blit.clip_top = top;
                        blit.clip_right = right;
                        blit.clip_bottom = bottom;

                        mark_visible(0, 0);
                    }
                    else if (rows == 0)
                    { /* scrolling columns */
                        int colwidth = blit.source_width / cols;

                        blit.clip_top = top;
                        blit.clip_bottom = bottom;

                        int col = 0;
                        while (col < cols)
                        {
                            /* count consecutive columns scrolled by the same amount */
                            int scroll = colscroll[col];
                            int cons = 1;
                            if (scroll != TILE_LINE_DISABLED)
                            {
                                while (col + cons < cols && colscroll[col + cons] == scroll) cons++;

                                if (scroll < 0) scroll = blit.source_height - (-scroll) % blit.source_height;
                                else scroll %= blit.source_height;

                                blit.clip_left = col * colwidth;
                                if (blit.clip_left < left) blit.clip_left = left;
                                blit.clip_right = (col + cons) * colwidth;
                                if (blit.clip_right > right) blit.clip_right = right;

                                mark_visible(0, scroll);
                                mark_visible(0, scroll - blit.source_height);
                            }
                            col += cons;
                        }
                    }
                    else if (cols == 0)
                    { /* scrolling rows */
                        int rowheight = blit.source_height / rows;

                        blit.clip_left = left;
                        blit.clip_right = right;

                        int row = 0;
                        while (row < rows)
                        {
                            /* count consecutive rows scrolled by the same amount */
                            int scroll = rowscroll[row];
                            int cons = 1;
                            if (scroll != TILE_LINE_DISABLED)
                            {
                                while (row + cons < rows && rowscroll[row + cons] == scroll) cons++;

                                if (scroll < 0) scroll = blit.source_width - (-scroll) % blit.source_width;
                                else scroll %= blit.source_width;

                                blit.clip_top = row * rowheight;
                                if (blit.clip_top < top) blit.clip_top = top;
                                blit.clip_bottom = (row + cons) * rowheight;
                                if (blit.clip_bottom > bottom) blit.clip_bottom = bottom;

                                mark_visible(scroll, 0);
                                mark_visible(scroll - blit.source_width, 0);
                            }
                            row += cons;
                        }
                    }
                    else if (rows == 1 && cols == 1)
                    { /* XY scrolling playfield */
                        int scrollx, scrolly;

                        if (rowscroll[0] < 0) scrollx = blit.source_width - (-rowscroll[0]) % blit.source_width;
                        else scrollx = rowscroll[0] % blit.source_width;

                        if (colscroll[0] < 0) scrolly = blit.source_height - (-colscroll[0]) % blit.source_height;
                        else scrolly = colscroll[0] % blit.source_height;

                        blit.clip_left = left;
                        blit.clip_top = top;
                        blit.clip_right = right;
                        blit.clip_bottom = bottom;

                        mark_visible(scrollx, scrolly);
                        mark_visible(scrollx, scrolly - blit.source_height);
                        mark_visible(scrollx - blit.source_width, scrolly);
                        mark_visible(scrollx - blit.source_width, scrolly - blit.source_height);
                    }
                    else if (rows == 1)
                    { /* scrolling columns + horizontal scroll */
                        int scrollx;

                        if (rowscroll[0] < 0) scrollx = blit.source_width - (-rowscroll[0]) % blit.source_width;
                        else scrollx = rowscroll[0] % blit.source_width;

                        int colwidth = blit.source_width / cols;

                        blit.clip_top = top;
                        blit.clip_bottom = bottom;

                        int col = 0;
                        while (col < cols)
                        {
                            /* count consecutive columns scrolled by the same amount */
                            int scroll = colscroll[col];
                            int cons = 1;
                            if (scroll != TILE_LINE_DISABLED)
                            {
                                while (col + cons < cols && colscroll[col + cons] == scroll) cons++;

                                if (scroll < 0) scroll = blit.source_height - (-scroll) % blit.source_height;
                                else scroll %= blit.source_height;

                                blit.clip_left = col * colwidth + scrollx;
                                if (blit.clip_left < left) blit.clip_left = left;
                                blit.clip_right = (col + cons) * colwidth + scrollx;
                                if (blit.clip_right > right) blit.clip_right = right;

                                mark_visible(scrollx, scroll);
                                mark_visible(scrollx, scroll - blit.source_height);

                                blit.clip_left = col * colwidth + scrollx - blit.source_width;
                                if (blit.clip_left < left) blit.clip_left = left;
                                blit.clip_right = (col + cons) * colwidth + scrollx - blit.source_width;
                                if (blit.clip_right > right) blit.clip_right = right;

                                mark_visible(scrollx - blit.source_width, scroll);
                                mark_visible(scrollx - blit.source_width, scroll - blit.source_height);
                            }
                            col += cons;
                        }
                    }
                    else if (cols == 1)
                    { /* scrolling rows + vertical scroll */
                        int scrolly;

                        if (colscroll[0] < 0) scrolly = blit.source_height - (-colscroll[0]) % blit.source_height;
                        else scrolly = colscroll[0] % blit.source_height;

                        int rowheight = blit.source_height / rows;

                        blit.clip_left = left;
                        blit.clip_right = right;

                        int row = 0;
                        while (row < rows)
                        {
                            /* count consecutive rows scrolled by the same amount */
                            int scroll = rowscroll[row];
                            int cons = 1;
                            if (scroll != TILE_LINE_DISABLED)
                            {
                                while (row + cons < rows && rowscroll[row + cons] == scroll) cons++;

                                if (scroll < 0) scroll = blit.source_width - (-scroll) % blit.source_width;
                                else scroll %= blit.source_width;

                                blit.clip_top = row * rowheight + scrolly;
                                if (blit.clip_top < top) blit.clip_top = top;
                                blit.clip_bottom = (row + cons) * rowheight + scrolly;
                                if (blit.clip_bottom > bottom) blit.clip_bottom = bottom;

                                mark_visible(scroll, scrolly);
                                mark_visible(scroll - blit.source_width, scrolly);

                                blit.clip_top = row * rowheight + scrolly - blit.source_height;
                                if (blit.clip_top < top) blit.clip_top = top;
                                blit.clip_bottom = (row + cons) * rowheight + scrolly - blit.source_height;
                                if (blit.clip_bottom > bottom) blit.clip_bottom = bottom;

                                mark_visible(scroll, scrolly - blit.source_height);
                                mark_visible(scroll - blit.source_width, scrolly - blit.source_height);
                            }
                            row += cons;
                        }
                    }

                    _tilemap.scrolled = false;
                }

                {
                    int num_pens = _tilemap.tile_width * _tilemap.tile_height; /* precalc - needed for >4bpp pen management handling */

                    byte[] visible = _tilemap.visible;
                    bool[] dirty_vram = _tilemap.dirty_vram;
                    bool[] dirty_pixels = _tilemap.dirty_pixels;

                    _BytePtr[] pendata = _tilemap.pendata;
                    _BytePtr[] maskdata = _tilemap.maskdata;
                    UShortSubArray[] paldata = _tilemap.paldata;
                    uint[] pen_usage = _tilemap.pen_usage;

                    int tile_flip = 0;
                    if ((_tilemap.attributes & TILEMAP_FLIPX) != 0) tile_flip |= TILE_FLIPX;
                    if ((_tilemap.attributes & TILEMAP_FLIPY) != 0) tile_flip |= TILE_FLIPY;
#if !PREROTATE_GFX
                    if ((Machine.orientation & ORIENTATION_SWAP_XY) != 0)
                    {
                        if ((Machine.orientation & ORIENTATION_FLIP_X) != 0) tile_flip ^= TILE_FLIPY;
                        if ((Machine.orientation & ORIENTATION_FLIP_Y) != 0) tile_flip ^= TILE_FLIPX;
                    }
                    else
                    {
                        if ((Machine.orientation & ORIENTATION_FLIP_X) != 0) tile_flip ^= TILE_FLIPX;
                        if ((Machine.orientation & ORIENTATION_FLIP_Y) != 0) tile_flip ^= TILE_FLIPY;
                    }
#endif

                    tile_info.flags = 0;
                    tile_info.priority = 0;

                    for (int tile_index = 0; tile_index < _tilemap.num_tiles; tile_index++)
                    {
                        if (visible[tile_index] != 0 && dirty_vram[tile_index])
                        {
                            int row = tile_index / _tilemap.num_cols;
                            int col = tile_index % _tilemap.num_cols;
                            int flags;

                            if ((_tilemap.orientation & ORIENTATION_FLIP_Y) != 0) row = _tilemap.num_rows - 1 - row;
                            if ((_tilemap.orientation & ORIENTATION_FLIP_X) != 0) col = _tilemap.num_cols - 1 - col;
                            if ((_tilemap.orientation & ORIENTATION_SWAP_XY) != 0) { var temp = col; col = row; row = temp; }// SWAP(col,row)

                            {
                                UShortSubArray the_color = paldata[tile_index];
                                if (the_color != null)
                                {
                                    uint old_pen_usage = pen_usage[tile_index];
                                    if (old_pen_usage != 0)
                                    {
                                        //palette_decrease_usage_count(the_color.offset - Machine.remapped_colortable.offset, old_pen_usage, PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                                        palette_decrease_usage_count(the_color.offset, old_pen_usage, PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                                    }
                                    else
                                    {
                                        //palette_decrease_usage_countx(the_color.offset - Machine.remapped_colortable.offset, num_pens, pendata[tile_index], PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                                        palette_decrease_usage_countx(the_color.offset, num_pens, pendata[tile_index], PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                                    }
                                }
                            }
                            _tilemap.tile_get_info(col, row);

                            flags = tile_info.flags ^ tile_flip;
                            if ((_tilemap.orientation & ORIENTATION_SWAP_XY) != 0)
                            {
                                flags =
                                    (flags & 0xfc) |
                                    ((flags & 1) << 1) | ((flags & 2) >> 1);
                            }

                            pen_usage[tile_index] = tile_info.pen_usage;
                            pendata[tile_index] = tile_info.pen_data;
                            paldata[tile_index] = tile_info.pal_data;
                            maskdata[tile_index] = tile_info.mask_data; // needed for _tilemap_BITMASK
                            _tilemap.flags[tile_index] = (byte)flags;
                            _tilemap.priority[tile_index] = tile_info.priority;


                            if (tile_info.pen_usage != 0)
                            {
                                //palette_increase_usage_count(tile_info.pal_data.offset - Machine.remapped_colortable.offset, tile_info.pen_usage, PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                                palette_increase_usage_count(tile_info.pal_data.offset, tile_info.pen_usage, PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                            }
                            else
                            {
                                //palette_increase_usage_countx(tile_info.pal_data.offset - Machine.remapped_colortable.offset, num_pens, tile_info.pen_data, PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                                palette_increase_usage_countx(tile_info.pal_data.offset, num_pens, tile_info.pen_data, PALETTE_COLOR_VISIBLE | PALETTE_COLOR_CACHED);
                            }

                            dirty_pixels[tile_index] = true;
                            dirty_vram[tile_index] = false;
                        }
                    }
                }
            }
        }