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; } } } } }