UINT32 laserdisc_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { // handle the overlay if present screen_bitmap &overbitmap = m_overbitmap[m_overindex]; if (overbitmap.valid() && (!m_overupdate_ind16.isnull() || !m_overupdate_rgb32.isnull())) { // scale the cliprect to the overlay size rectangle clip(m_overclip); clip.min_y = cliprect.min_y * overbitmap.height() / bitmap.height(); if (cliprect.min_y == screen.visible_area().min_y) clip.min_y = MIN(clip.min_y, m_overclip.min_y); clip.max_y = (cliprect.max_y + 1) * overbitmap.height() / bitmap.height() - 1; // call the update callback if (!m_overupdate_ind16.isnull()) m_overupdate_ind16(screen, overbitmap.as_ind16(), clip); else m_overupdate_rgb32(screen, overbitmap.as_rgb32(), clip); } // if this is the last update, do the rendering if (cliprect.max_y == screen.visible_area().max_y) { // update the texture with the overlay contents if (overbitmap.valid()) m_overtex->set_bitmap(overbitmap, m_overclip, overbitmap.texformat()); // get the laserdisc video bitmap_yuy16 &vidbitmap = get_video(); m_videotex->set_bitmap(vidbitmap, vidbitmap.cliprect(), TEXFORMAT_YUY16); // reset the screen contents screen.container().empty(); // add the video texture if (m_videoenable) screen.container().add_quad(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0xff,0xff,0xff), m_videotex, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); // add the overlay if (m_overenable && overbitmap.valid()) { float x0 = 0.5f - 0.5f * m_overscalex + m_overposx; float y0 = 0.5f - 0.5f * m_overscaley + m_overposy; float x1 = x0 + m_overscalex; float y1 = y0 + m_overscaley; screen.container().add_quad(x0, y0, x1, y1, rgb_t(0xff,0xff,0xff,0xff), m_overtex, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1)); } // swap to the next bitmap m_overindex = (m_overindex + 1) % ARRAY_LENGTH(m_overbitmap); } return 0; }
UINT32 toaplan2_state::screen_update_batrider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { screen_update_toaplan2(screen, bitmap, cliprect); int line; rectangle clip; const rectangle &visarea = screen.visible_area(); clip = visarea; /* used for 'for use in' and '8ing' screen on bbakraid, raizing on batrider */ for (line = 0; line < 256;line++) { if (m_tx_flip) { clip.min_y = clip.max_y = 256 - line; m_tx_tilemap->set_scrolly(0, 256 - line + m_txvideoram16_offs[256 - line]); } else { clip.min_y = clip.max_y = line; m_tx_tilemap->set_scrolly(0, - line + m_txvideoram16_offs[ line]); } m_tx_tilemap->draw(screen, bitmap, clip, 0, 0); } return 0; }
int tc0100scn_device::tilemap_draw( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, uint32_t priority ) { int disable = m_ctrl[6] & 0xf7; rectangle clip = cliprect; clip &= screen.visible_area(); #if 0 if (disable != 0 && disable != 3 && disable != 7) popmessage("layer disable = %x",disable); #endif switch (layer) { case 0: if (disable & 0x01) return 1; m_tilemap[0][m_dblwidth]->draw(screen, bitmap, clip, flags, priority); break; case 1: if (disable & 0x02) return 1; tilemap_draw_fg(screen, bitmap, clip, m_tilemap[1][m_dblwidth], flags, priority); break; case 2: if (disable & 0x04) return 1; m_tilemap[2][m_dblwidth]->draw(screen, bitmap, clip, flags, priority); break; } return 0; }
UINT32 angelkds_state::screen_update_angelkds(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { const rectangle &visarea = screen.visible_area(); rectangle clip; bitmap.fill(0x3f, cliprect); /* is there a register controling the colour?, we currently use the last colour of the tx palette */ /* draw top of screen */ clip.set(8*0, 8*16-1, visarea.min_y, visarea.max_y); if ((m_layer_ctrl & 0x80) == 0x00) m_bgtop_tilemap->draw(screen, bitmap, clip, 0, 0); draw_sprites(bitmap, clip, 0x80); if ((m_layer_ctrl & 0x20) == 0x00) m_tx_tilemap->draw(screen, bitmap, clip, 0, 0); /* draw bottom of screen */ clip.set(8*16, 8*32-1, visarea.min_y, visarea.max_y); if ((m_layer_ctrl & 0x40) == 0x00) m_bgbot_tilemap->draw(screen, bitmap, clip, 0, 0); draw_sprites(bitmap, clip, 0x40); if ((m_layer_ctrl & 0x20) == 0x00) m_tx_tilemap->draw(screen, bitmap, clip, 0, 0); return 0; }
UINT32 m20_state::screen_update_m20(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { int x,y,i; UINT8 pen; UINT32 count; bitmap.fill(get_black_pen(machine()), cliprect); count = (0); for(y=0; y<256; y++) { for(x=0; x<512; x+=16) { for (i = 0; i < 16; i++) { pen = (m_p_videoram[count]) >> (15 - i) & 1; if (screen.visible_area().contains(x + i, y)) bitmap.pix32(y, x + i) = machine().pens[pen]; } count++; } } return 0; }
UINT32 multi16_state::screen_update_multi16(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int x,y; int count; int xi; count = 0; for(y=0;y<mc6845_v_display*8;y++) { for(x=0;x<(mc6845_h_display*8)/16;x++) { for(xi=0;xi<16;xi++) { int dot = (BITSWAP16(m_p_vram[count],7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8) >> (15-xi)) & 0x1; if(screen.visible_area().contains(x*16+xi, y)) bitmap.pix16(y, x*16+xi) = machine().pens[dot]; } count++; } } return 0; }
UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { UINT32 flags = PRIMFLAG_ANTIALIAS(machine().options().antialias() ? 1 : 0) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD) | PRIMFLAG_VECTOR(1); const rectangle &visarea = screen.visible_area(); float xscale = 1.0f / (65536 * visarea.width()); float yscale = 1.0f / (65536 * visarea.height()); float xoffs = (float)visarea.min_x; float yoffs = (float)visarea.min_y; point *curpoint; int lastx = 0; int lasty = 0; curpoint = m_vector_list.get(); screen.container().empty(); screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTORBUF(1)); for (int i = 0; i < m_vector_index; i++) { render_bounds coords; float intensity = (float)curpoint->intensity / 255.0f; float intensity_weight = normalized_sigmoid(intensity, vector_options::s_beam_intensity_weight); // check for static intensity float beam_width = m_min_intensity == m_max_intensity ? vector_options::s_beam_width_min : vector_options::s_beam_width_min + intensity_weight * (vector_options::s_beam_width_max - vector_options::s_beam_width_min); // normalize width beam_width *= 1.0f / (float)VECTOR_WIDTH_DENOM; coords.x0 = ((float)lastx - xoffs) * xscale; coords.y0 = ((float)lasty - yoffs) * yscale; coords.x1 = ((float)curpoint->x - xoffs) * xscale; coords.y1 = ((float)curpoint->y - yoffs) * yscale; if (curpoint->intensity != 0) { screen.container().add_line( coords.x0, coords.y0, coords.x1, coords.y1, beam_width, (curpoint->intensity << 24) | (curpoint->col & 0xffffff), flags); } lastx = curpoint->x; lasty = curpoint->y; curpoint++; } return 0; }
static int get_lightgun_pos(screen_device &screen, int player, int *x, int *y) { const rectangle &visarea = screen.visible_area(); int xpos = screen.ioport((player == 0) ? "GUN1X" : "GUN2X")->read_safe(0xffffffff); int ypos = screen.ioport((player == 0) ? "GUN1Y" : "GUN2Y")->read_safe(0xffffffff); if (xpos == -1 || ypos == -1) return FALSE; *x = visarea.min_x + xpos * visarea.width() / 255; *y = visarea.min_y + ypos * visarea.height() / 255; return TRUE; }
uint32_t nwktr_state::screen_update_rscreen(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { bitmap.fill(m_palette->pen(0), cliprect); m_voodoo[1]->voodoo_update(bitmap, cliprect); const rectangle &visarea = screen.visible_area(); const rectangle tilemap_rect(visarea.min_x, visarea.max_x, visarea.min_y + 16, visarea.max_y); m_k001604->draw_front_layer(screen, bitmap, tilemap_rect); draw_7segment_led(bitmap, 3, 3, m_led_reg0); draw_7segment_led(bitmap, 9, 3, m_led_reg1); return 0; }
UINT32 jackie_state::screen_update_jackie(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int i,j; int startclipmin = 0; const rectangle &visarea = screen.visible_area(); bitmap.fill(get_black_pen(machine()), cliprect); for (i=0;i < 0x40;i++) { m_reel1_tilemap->set_scrolly(i, m_bg_scroll[i+0x000]); m_reel2_tilemap->set_scrolly(i, m_bg_scroll[i+0x040]); m_reel3_tilemap->set_scrolly(i, m_bg_scroll[i+0x080]); } for (j=0; j < 0x100-1; j++) { rectangle clip; int rowenable = m_bg_scroll2[j]; /* draw top of screen */ clip.set(visarea.min_x, visarea.max_x, startclipmin, startclipmin+1); if (rowenable==0) { m_reel1_tilemap->draw(bitmap, clip, 0,0); } else if (rowenable==1) { m_reel2_tilemap->draw(bitmap, clip, 0,0); } else if (rowenable==2) { m_reel3_tilemap->draw(bitmap, clip, 0,0); } else if (rowenable==3) { } startclipmin+=1; } m_fg_tilemap->draw(bitmap, cliprect, 0, 0); return 0; }
UINT32 nwktr_state::screen_update_nwktr(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { device_t *voodoo = machine().device("voodoo"); bitmap.fill(machine().pens[0], cliprect); voodoo_update(voodoo, bitmap, cliprect); const rectangle &visarea = screen.visible_area(); const rectangle tilemap_rect(visarea.min_x, visarea.max_x, visarea.min_y+16, visarea.max_y); k001604_draw_front_layer(m_k001604, bitmap, tilemap_rect); draw_7segment_led(bitmap, 3, 3, m_led_reg0); draw_7segment_led(bitmap, 9, 3, m_led_reg1); return 0; }
UINT32 nwktr_state::screen_update_nwktr(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { voodoo_device *voodoo = (voodoo_device*)machine().device("voodoo0"); bitmap.fill(m_palette->pen(0), cliprect); voodoo->voodoo_update(bitmap, cliprect); const rectangle &visarea = screen.visible_area(); const rectangle tilemap_rect(visarea.min_x, visarea.max_x, visarea.min_y+16, visarea.max_y); m_k001604->draw_front_layer(screen, bitmap, tilemap_rect); draw_7segment_led(bitmap, 3, 3, m_led_reg0); draw_7segment_led(bitmap, 9, 3, m_led_reg1); return 0; }
UINT32 mogura_state::screen_update_mogura(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { const rectangle &visarea = screen.visible_area(); /* tilemap layout is a bit strange ... */ rectangle clip = visarea; clip.max_x = 256 - 1; m_tilemap->set_scrollx(0, 256); m_tilemap->draw(screen, bitmap, clip, 0, 0); clip.min_x = 256; clip.max_x = 512 - 1; m_tilemap->set_scrollx(0, -128); m_tilemap->draw(screen, bitmap, clip, 0, 0); return 0; }
UINT32 flkatck_state::screen_update_flkatck(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { rectangle clip[2]; const rectangle &visarea = screen.visible_area(); address_space &space = machine().driver_data()->generic_space(); if (m_flipscreen) { clip[0] = visarea; clip[0].max_x -= 40; clip[1] = visarea; clip[1].min_x = clip[1].max_x - 40; m_k007121_tilemap[0]->set_scrollx(0, k007121_ctrlram_r(m_k007121, space, 0) - 56 ); m_k007121_tilemap[0]->set_scrolly(0, k007121_ctrlram_r(m_k007121, space, 2)); m_k007121_tilemap[1]->set_scrollx(0, -16); } else { clip[0] = visarea; clip[0].min_x += 40; clip[1] = visarea; clip[1].max_x = 39; clip[1].min_x = 0; m_k007121_tilemap[0]->set_scrollx(0, k007121_ctrlram_r(m_k007121, space, 0) - 40 ); m_k007121_tilemap[0]->set_scrolly(0, k007121_ctrlram_r(m_k007121, space, 2)); m_k007121_tilemap[1]->set_scrollx(0, 0); } /* compute clipping */ clip[0] &= cliprect; clip[1] &= cliprect; /* draw the graphics */ m_k007121_tilemap[0]->draw(bitmap, clip[0], 0, 0); k007121_sprites_draw(m_k007121, bitmap, cliprect, machine().gfx[0], NULL, &m_k007121_ram[0x1000], 0, 40, 0, (UINT32)-1); m_k007121_tilemap[1]->draw(bitmap, clip[1], 0, 0); return 0; }
uint32_t flkatck_state::screen_update_flkatck(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { rectangle clip[2]; const rectangle &visarea = screen.visible_area(); address_space &space = machine().dummy_space(); if (m_flipscreen) { clip[0] = visarea; clip[0].max_x -= 40; clip[1] = visarea; clip[1].min_x = clip[1].max_x - 40; m_k007121_tilemap[0]->set_scrollx(0, m_k007121->ctrlram_r(space, 0) - 56 ); m_k007121_tilemap[0]->set_scrolly(0, m_k007121->ctrlram_r(space, 2)); m_k007121_tilemap[1]->set_scrollx(0, -16); } else { clip[0] = visarea; clip[0].min_x += 40; clip[1] = visarea; clip[1].max_x = 39; clip[1].min_x = 0; m_k007121_tilemap[0]->set_scrollx(0, m_k007121->ctrlram_r(space, 0) - 40 ); m_k007121_tilemap[0]->set_scrolly(0, m_k007121->ctrlram_r(space, 2)); m_k007121_tilemap[1]->set_scrollx(0, 0); } /* compute clipping */ clip[0] &= cliprect; clip[1] &= cliprect; /* draw the graphics */ m_k007121_tilemap[0]->draw(screen, bitmap, clip[0], 0, 0); m_k007121->sprites_draw(bitmap, cliprect, m_gfxdecode->gfx(0), m_gfxdecode->palette(), &m_k007121_ram[0x1000], 0, 40, 0, screen.priority(), (uint32_t)-1, true); m_k007121_tilemap[1]->draw(screen, bitmap, clip[1], 0, 0); return 0; }
void lethalj_scanline_update(screen_device &screen, bitmap_t *bitmap, int scanline, const tms34010_display_params *params) { UINT16 *src = &screenram[(vispage << 17) | ((params->rowaddr << 9) & 0x3fe00)]; UINT16 *dest = BITMAP_ADDR16(bitmap, scanline, 0); int coladdr = params->coladdr << 1; int x; /* blank palette: fill with white */ if (blank_palette) { for (x = params->heblnk; x < params->hsblnk; x++) dest[x] = 0x7fff; if (scanline == screen.visible_area().max_y) blank_palette = 0; return; } /* copy the non-blanked portions of this scanline */ for (x = params->heblnk; x < params->hsblnk; x++) dest[x] = src[coladdr++ & 0x1ff] & 0x7fff; }
UINT32 kingdrby_state::screen_update_kingdrby(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { const rectangle &visarea = screen.visible_area(); rectangle clip; m_sc0_tilemap->set_scrollx(0, m_vram[0x342]); m_sc0_tilemap->set_scrolly(0, m_vram[0x341]); m_sc1_tilemap->set_scrollx(0, m_vram[0x342]); m_sc1_tilemap->set_scrolly(0, m_vram[0x341]); m_sc0w_tilemap->set_scrolly(0, 32); /* maybe it needs two window tilemaps? (one at the top, the other at the bottom)*/ clip.set(visarea.min_x, 256, 192, visarea.max_y); /*TILEMAP_DRAW_CATEGORY + TILEMAP_DRAW_OPAQUE doesn't suit well?*/ m_sc0_tilemap->draw(bitmap, cliprect, 0,0); draw_sprites(machine(),bitmap,cliprect); m_sc1_tilemap->draw(bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1),0); m_sc0w_tilemap->draw(bitmap, clip, 0,0); return 0; }
UINT32 williams_state::screen_update_blaster(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { rgb_t pens[16]; int x, y; /* precompute the palette */ for (x = 0; x < 16; x++) pens[x] = m_palette_lookup[m_generic_paletteram_8[x]]; /* if we're blitting from the top, start with a 0 for color 0 */ if (cliprect.min_y == screen.visible_area().min_y || !(m_blaster_video_control & 1)) m_blaster_color0 = m_palette_lookup[m_blaster_palette_0[0] ^ 0xff]; /* loop over rows */ for (y = cliprect.min_y; y <= cliprect.max_y; y++) { int erase_behind = m_blaster_video_control & m_blaster_scanline_control[y] & 2; UINT8 *source = &m_videoram[y]; UINT32 *dest = &bitmap.pix32(y); /* latch a new color0 pen? */ if (m_blaster_video_control & m_blaster_scanline_control[y] & 1) m_blaster_color0 = m_palette_lookup[m_blaster_palette_0[y] ^ 0xff]; /* loop over columns */ for (x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2) { int pix = source[(x/2) * 256]; /* clear behind us if requested */ if (erase_behind) source[(x/2) * 256] = 0; /* now draw */ dest[x+0] = (pix & 0xf0) ? pens[pix >> 4] : m_blaster_color0 | pens[0]; dest[x+1] = (pix & 0x0f) ? pens[pix & 0x0f] : m_blaster_color0 | pens[0]; } } return 0; }
void lethalj_scanline_update(screen_device &screen, bitmap_ind16 &bitmap, int scanline, const tms34010_display_params *params) { lethalj_state *state = screen.machine().driver_data<lethalj_state>(); UINT16 *src = &state->m_screenram[(state->m_vispage << 17) | ((params->rowaddr << 9) & 0x3fe00)]; UINT16 *dest = &bitmap.pix16(scanline); int coladdr = params->coladdr << 1; int x; /* blank palette: fill with white */ if (state->m_blank_palette) { for (x = params->heblnk; x < params->hsblnk; x++) dest[x] = 0x7fff; if (scanline == screen.visible_area().max_y) state->m_blank_palette = 0; return; } /* copy the non-blanked portions of this scanline */ for (x = params->heblnk; x < params->hsblnk; x++) dest[x] = src[coladdr++ & 0x1ff] & 0x7fff; }
void vindictr_state::scanline_update(screen_device &screen, int scanline) { int x; /* keep in range */ int offset = ((scanline - 8) / 8) * 64 + 42; if (offset < 0) offset += 0x7c0; else if (offset >= 0x7c0) return; /* update the current parameters */ for (x = 42; x < 64; x++) { uint16_t data = m_alpha_tilemap->basemem_read(offset++); switch ((data >> 9) & 7) { case 2: /* /PFB */ if (m_playfield_tile_bank != (data & 7)) { screen.update_partial(scanline - 1); m_playfield_tile_bank = data & 7; m_playfield_tilemap->mark_all_dirty(); } break; case 3: /* /PFHSLD */ if (m_playfield_xscroll != (data & 0x1ff)) { screen.update_partial(scanline - 1); m_playfield_tilemap->set_scrollx(0, data); m_playfield_xscroll = data & 0x1ff; } break; case 4: /* /MOHS */ if (m_mob->xscroll() != (data & 0x1ff)) { screen.update_partial(scanline - 1); m_mob->set_xscroll(data & 0x1ff); } break; case 5: /* /PFSPC */ break; case 6: /* /VIRQ */ scanline_int_write_line(1); break; case 7: /* /PFVS */ { /* a new vscroll latches the offset into a counter; we must adjust for this */ int offset = scanline; const rectangle &visible_area = screen.visible_area(); if (offset > visible_area.bottom()) offset -= visible_area.bottom() + 1; if (m_playfield_yscroll != ((data - offset) & 0x1ff)) { screen.update_partial(scanline - 1); m_playfield_tilemap->set_scrolly(0, data - offset); m_mob->set_yscroll((data - offset) & 0x1ff); } break; } } } }
UINT32 zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { // Wait until configuration is completed before transfering anything if (m_zeusbase[0x30] == 0) return 0; int x, y; poly->wait(); if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x10 : 1; popmessage("Zbase = %f", (double)zbase); } if (machine().input().code_pressed(KEYCODE_UP)) { zbase -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x10 : 1; popmessage("Zbase = %f", (double)zbase); } /* normal update case */ if (!machine().input().code_pressed(KEYCODE_W)) { int xoffs = screen.visible_area().min_x; for (y = cliprect.min_y; y <= cliprect.max_y; y++) { UINT32 *colorptr = &m_frameColor[frame_addr_from_xy(0, y, false)]; UINT32 *dest = &bitmap.pix32(y); for (x = cliprect.min_x; x <= cliprect.max_x; x++) { UINT32 bufX = x - xoffs; //dest[x] = WAVERAM_READPIX(base, y, x - xoffs); dest[x] = colorptr[bufX]; } } } /* waveram drawing case */ else { const void *base; if (machine().input().code_pressed(KEYCODE_DOWN)) yoffs += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x1000 : 40; if (machine().input().code_pressed(KEYCODE_UP)) yoffs -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x1000 : 40; if (machine().input().code_pressed(KEYCODE_LEFT) && texel_width > 4) { texel_width >>= 1; while (machine().input().code_pressed(KEYCODE_LEFT)) ; } if (machine().input().code_pressed(KEYCODE_RIGHT) && texel_width < 512) { texel_width <<= 1; while (machine().input().code_pressed(KEYCODE_RIGHT)) ; } if (yoffs < 0) yoffs = 0; if (1) { //base = waveram0_ptr_from_expanded_addr(yoffs << 8); //base = waveram0_ptr_from_expanded_addr(yoffs); base = WAVERAM_BLOCK0(yoffs); } else base = (void *)&m_frameColor[yoffs << 6]; int xoffs = screen.visible_area().min_x; for (y = cliprect.min_y; y <= cliprect.max_y; y++) { UINT32 *dest = &bitmap.pix32(y); for (x = cliprect.min_x; x <= cliprect.max_x; x++) { if (1) { UINT8 tex = get_texel_8bit((UINT64 *)base, y, x, texel_width); dest[x] = (tex << 16) | (tex << 8) | tex; } else { dest[x] = ((UINT32 *)(base))[((y * WAVERAM1_WIDTH)) + x - xoffs]; } } } popmessage("offs = %06X base = %08X", yoffs, base); }
void vindictr_state::scanline_update(screen_device &screen, int scanline) { UINT16 *base = &m_alpha[((scanline - 8) / 8) * 64 + 42]; int x; /* keep in range */ if (base < m_alpha) base += 0x7c0; else if (base >= &m_alpha[0x7c0]) return; /* update the current parameters */ for (x = 42; x < 64; x++) { UINT16 data = *base++; switch ((data >> 9) & 7) { case 2: /* /PFB */ if (m_playfield_tile_bank != (data & 7)) { screen.update_partial(scanline - 1); m_playfield_tile_bank = data & 7; m_playfield_tilemap->mark_all_dirty(); } break; case 3: /* /PFHSLD */ if (m_playfield_xscroll != (data & 0x1ff)) { screen.update_partial(scanline - 1); m_playfield_tilemap->set_scrollx(0, data); m_playfield_xscroll = data & 0x1ff; } break; case 4: /* /MOHS */ if (atarimo_get_xscroll(0) != (data & 0x1ff)) { screen.update_partial(scanline - 1); atarimo_set_xscroll(0, data & 0x1ff); } break; case 5: /* /PFSPC */ break; case 6: /* /VIRQ */ scanline_int_gen(*subdevice("maincpu")); break; case 7: /* /PFVS */ { /* a new vscroll latches the offset into a counter; we must adjust for this */ int offset = scanline; const rectangle &visible_area = screen.visible_area(); if (offset > visible_area.max_y) offset -= visible_area.max_y + 1; if (m_playfield_yscroll != ((data - offset) & 0x1ff)) { screen.update_partial(scanline - 1); m_playfield_tilemap->set_scrolly(0, data - offset); atarimo_set_yscroll(0, (data - offset) & 0x1ff); } break; } } } }
void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 *pixel_data) { // initialise the blink timer if (m_blink_start > screen.frame_number()) m_blink_start = screen.frame_number(); // compute the blink state according to the programmed duty cycle const bool blink_state = ((screen.frame_number() - m_blink_start) & ( (m_command_0 & CR0302) == CR0302_1616 ? 0x10 : (m_command_0 & CR0302) == CR0302_3232 ? 0x20 : (m_command_0 & CR0302) == CR0302_6464 ? 0x40 : 0x30)) == 0; // compute the pixel mask from the pixel read mask and blink mask/state const u8 pixel_mask = m_pixel_read_mask & (blink_state ? 0xffU : ~m_pixel_blink_mask); // draw visible pixel data switch (m_command_0 & CR0100) { case CR0100_1BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8) { u8 data = *pixel_data++; bitmap.pix(y, x + 7) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 6) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 5) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 4) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 3) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 2) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 1) = get_rgb(data & 0x1, pixel_mask); data >>= 1; bitmap.pix(y, x + 0) = get_rgb(data & 0x1, pixel_mask); } break; case CR0100_2BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4) { u8 data = *pixel_data++; bitmap.pix(y, x + 3) = get_rgb(data & 0x3, pixel_mask); data >>= 2; bitmap.pix(y, x + 2) = get_rgb(data & 0x3, pixel_mask); data >>= 2; bitmap.pix(y, x + 1) = get_rgb(data & 0x3, pixel_mask); data >>= 2; bitmap.pix(y, x + 0) = get_rgb(data & 0x3, pixel_mask); } break; case CR0100_4BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 2) { u8 data = *pixel_data++; bitmap.pix(y, x + 1) = get_rgb(data & 0x7, pixel_mask); data >>= 4; bitmap.pix(y, x + 0) = get_rgb(data & 0x7, pixel_mask); } break; case CR0100_8BPP: for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) bitmap.pix(y, x) = get_rgb(*pixel_data++, pixel_mask); break; } // draw cursors when visible and not blinked off if ((m_cursor_command & (CR47 | CR46 | CR45 | CR44)) && ((m_cursor_command & CR40) == 0 || blink_state)) { // get 64x64 bitmap and cross hair cursor plane enable const u8 bm_cursor_enable = (m_cursor_command & (CR47 | CR46)) >> 6; const u8 ch_cursor_enable = (m_cursor_command & (CR45 | CR44)) >> 4; // get cross hair cursor half thickness const int ch_thickness = (m_cursor_command & CR4241) >> 1; /* * The cursor (x) value to be written is calculated as follows: * * Cx = desired display screen (x) position + H - P * * where * * P = 37 if 1:1 input multiplexing, 52 if 4:1 input multiplexing, * 57 if 5:1 input multiplexing * H = number of pixels between the first rising edge of LD* * following the falling edge of HSYNC* to active video * * The cursor (y) value to be written is calculated as follows: * * Cy = desired display screen (y) position + V - 32 * * where * * V = number of scan lines from the second sync pulse during * vertical blanking to active video * * Values from $0FC0 (-64) to $0FBF (+4031) may be loaded into the * cursor (y) register. The negative values ($0FC0 to $0FFF) are used * in situations where V < 32, and the cursor must be moved off the * top of the screen. */ const int cursor_x = m_cursor_x + ( (m_command_0 & CR0706) == CR0706_11MPX ? 37 : (m_command_0 & CR0706) == CR0706_41MPX ? 52 : (m_command_0 & CR0706) == CR0706_51MPX ? 57 : 0); const int cursor_y = (m_cursor_y < 0xfc0 ? m_cursor_y : m_cursor_y - 0x1000) + 32; // 64x64 bitmap cursor if (bm_cursor_enable) { // compute target 64x64 rectangle rectangle cursor(cursor_x - 31, cursor_x + 32, cursor_y - 31, cursor_y + 32); // intersect with screen bitmap cursor &= bitmap.cliprect(); // draw if any portion is visible if (!cursor.empty()) { for (int y = 0; y < 64; y++) { // get screen y pixel coordinate const int ypos = cursor_y - 31 + y; for (int x = 0; x < 64; x++) { // get screen x pixel coordinate const int xpos = cursor_x - 31 + x; // check if pixel is visible if (cursor.contains(xpos, ypos)) { // retrieve 2 bits of 64x64 bitmap cursor data u8 data = (m_cursor_ram[y * 16 + (x >> 2)] >> ((3 - (x & 3)) << 1)) & bm_cursor_enable; // check for dual-cursor mode and combine with cross-hair data if (ch_cursor_enable) if (((x >= 31 - ch_thickness) && (x <= 31 + ch_thickness)) || ((y >= 31 - ch_thickness) && (y <= 31 + ch_thickness))) data = (m_cursor_command & CR43) ? data | ch_cursor_enable : data ^ ch_cursor_enable; // write cursor data to screen (normal or X Window mode) if (data && !((m_command_2 & CR21) && data == 1)) bitmap.pix(ypos, xpos) = m_cursor_color[data - 1]; } } } } } // cross hair cursor if (ch_cursor_enable) { // get the cross hair cursor color const rgb_t ch_color = m_cursor_color[ch_cursor_enable - 1]; /* * The window (x) value to be written is calculated as follows: * * Wx = desired display screen (x) position + H - P * * where * * P = 5 if 1:1 input multiplexing, 20 if 4:1 input multiplexing, * 25 if 5:1 input multiplexing * H = number of pixels between the first rising edge of LD* * following the falling edge of HSYNC* to active video * * The window (y) value to be written is calculated as follows: * * Wy = desired display screen (y) position + V * * where * * V = number of scan lines from the second sync pulse during * vertical blanking to active video * * Values from $0000 to $0FFF may be written to the window (x) and * (y) registers. A full-screen cross hair is implemented by * loading the window (x,y) registers with $0000, and the window * width and height registers with $0FFF. */ const bool full_screen = (m_window_x == 0 && m_window_y == 0 && m_window_w == 0x0fff && m_window_h == 0x0fff); const int window_x = full_screen ? screen.visible_area().min_x : m_window_x + ( (m_command_0 & CR0706) == CR0706_11MPX ? 5 : (m_command_0 & CR0706) == CR0706_41MPX ? 20 : (m_command_0 & CR0706) == CR0706_51MPX ? 25 : 0); const int window_y = full_screen ? screen.visible_area().min_y : m_window_y; /* * The actual window width is 2, 8 or 10 pixels more than the * value specified by the window width register, depending on * whether 1:1, 4:1 or 5:1 input multiplexing is specified. The * actual window height is 2 pixels more than the value specified * by the window height register. Therefore, the minimum window * width is 2, 8 or 10 pixels for 1:1, 4:1 and 5:1 multiplexing, * respectively. The minimum window height is 2 pixels. * * Values from $0000 to $0FFF may be written to the window width * and height registers. * * Note: testing indicates the cross-hair cursor should be drawn * strictly inside the window, although this is not 100% clear from * the documentation. */ const int window_w = full_screen ? screen.visible_area().width() : m_window_w + ( (m_command_0 & CR0706) == CR0706_11MPX ? 2 : (m_command_0 & CR0706) == CR0706_41MPX ? 8 : (m_command_0 & CR0706) == CR0706_51MPX ? 10 : 0); const int window_h = full_screen ? screen.visible_area().height() : m_window_h + 2; // check for dual-cursor mode if (bm_cursor_enable) { // draw the cross hair cursor as vertical and horizontal filled rectangles broken by the 64x64 cursor area rectangle v1(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, cursor_y - 32); rectangle v2(cursor_x - ch_thickness, cursor_x + ch_thickness, cursor_y + 33, window_y + window_h); rectangle h1(window_x + 1, cursor_x - 32, cursor_y - ch_thickness, cursor_y + ch_thickness); rectangle h2(cursor_x + 33, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness); v1 &= bitmap.cliprect(); v2 &= bitmap.cliprect(); h1 &= bitmap.cliprect(); h2 &= bitmap.cliprect(); if (!v1.empty()) bitmap.fill(ch_color, v1); if (!v2.empty()) bitmap.fill(ch_color, v2); if (!h1.empty()) bitmap.fill(ch_color, h1); if (!h2.empty()) bitmap.fill(ch_color, h2); } else { // draw the cross hair cursor as unbroken vertical and horizontal filled rectangles rectangle v(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, window_y + window_h); rectangle h(window_x + 1, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness); v &= bitmap.cliprect(); h &= bitmap.cliprect(); if (!v.empty()) bitmap.fill(ch_color, v); if (!h.empty()) bitmap.fill(ch_color, h); } } }
void batman_scanline_update(screen_device &screen, int scanline) { batman_state *state = screen.machine().driver_data<batman_state>(); /* update the scanline parameters */ if (scanline <= screen.visible_area().max_y && state->m_atarivc_state.rowscroll_enable) { UINT16 *base = &state->m_alpha[scanline / 8 * 64 + 48]; int scan, i; for (scan = 0; scan < 8; scan++, scanline++) for (i = 0; i < 2; i++) { int data = *base++; switch (data & 15) { case 9: if (scanline > 0) screen.update_partial(scanline - 1); state->m_atarivc_state.mo_xscroll = (data >> 7) & 0x1ff; atarimo_set_xscroll(0, state->m_atarivc_state.mo_xscroll); break; case 10: if (scanline > 0) screen.update_partial(scanline - 1); state->m_atarivc_state.pf1_xscroll_raw = (data >> 7) & 0x1ff; atarivc_update_pf_xscrolls(state); tilemap_set_scrollx(state->m_playfield_tilemap, 0, state->m_atarivc_state.pf0_xscroll); tilemap_set_scrollx(state->m_playfield2_tilemap, 0, state->m_atarivc_state.pf1_xscroll); break; case 11: if (scanline > 0) screen.update_partial(scanline - 1); state->m_atarivc_state.pf0_xscroll_raw = (data >> 7) & 0x1ff; atarivc_update_pf_xscrolls(state); tilemap_set_scrollx(state->m_playfield_tilemap, 0, state->m_atarivc_state.pf0_xscroll); break; case 13: if (scanline > 0) screen.update_partial(scanline - 1); state->m_atarivc_state.mo_yscroll = (data >> 7) & 0x1ff; atarimo_set_yscroll(0, state->m_atarivc_state.mo_yscroll); break; case 14: if (scanline > 0) screen.update_partial(scanline - 1); state->m_atarivc_state.pf1_yscroll = (data >> 7) & 0x1ff; tilemap_set_scrolly(state->m_playfield2_tilemap, 0, state->m_atarivc_state.pf1_yscroll); break; case 15: if (scanline > 0) screen.update_partial(scanline - 1); state->m_atarivc_state.pf0_yscroll = (data >> 7) & 0x1ff; tilemap_set_scrolly(state->m_playfield_tilemap, 0, state->m_atarivc_state.pf0_yscroll); break; } } }
UINT32 luckgrln_state::screen_update_luckgrln(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int y,x; int count = 0; const rectangle &visarea = screen.visible_area(); int i; rectangle clip = visarea; bitmap.fill(0, cliprect); for (i= 0;i < 64;i++) { m_reel1_tilemap->set_scrolly(i, m_reel1_scroll[i]); m_reel2_tilemap->set_scrolly(i, m_reel2_scroll[i]); m_reel3_tilemap->set_scrolly(i, m_reel3_scroll[i]); m_reel4_tilemap->set_scrolly(i, m_reel4_scroll[i]); } for (y=0;y<32;y++) { clip.min_y = y*8; clip.max_y = y*8+8; if (clip.min_y<visarea.min_y) clip.min_y = visarea.min_y; if (clip.max_y>visarea.max_y) clip.max_y = visarea.max_y; for (x=0;x<64;x++) { UINT16 tile = (m_luck_vram1[count] & 0xff); UINT16 tile_high = (m_luck_vram2[count]); UINT16 tileattr = (m_luck_vram3[count]); UINT8 col = 0; UINT8 region = 0; UINT8 bgenable; clip.min_x = x*8; clip.max_x = x*8+8; if (clip.min_x<visarea.min_x) clip.min_x = visarea.min_x; if (clip.max_x>visarea.max_x) clip.max_x = visarea.max_x; /* m_luck_vram1 tttt tttt (t = low tile bits) m_luck_vram2 tttt ppp? (t = high tile bits) (p = pal select)? */ tile |= (tile_high & 0xf0) << 4; if (tileattr & 0x02) tile |= 0x1000; // ?? low bit is used too col = tile_high&0xf; // --ss fbt- m_luck_vram3 // - = unused? // s = reel layer select for this 8x8 region // f = fg enabled for this 8x8 region (or priority?) // b = reel enabled for this 8x8 region (not set on startup screens) // t = tile bank bgenable = (tileattr &0x30)>>4; #if 0 // treat bit as fg enable if (tileattr&0x04) { if (bgenable==0) m_reel1_tilemap->draw(screen, bitmap, clip, 0, 0); if (bgenable==1) m_reel2_tilemap->draw(screen, bitmap, clip, 0, 0); if (bgenable==2) m_reel3_tilemap->draw(screen, bitmap, clip, 0, 0); if (bgenable==3) m_reel4_tilemap->draw(screen, bitmap, clip, 0, 0); } if (tileattr&0x08) m_gfxdecode->gfx(region)->transpen(bitmap,clip,tile,col,0,0,x*8,y*8, 0); #else // treat it as priority flag instead (looks better in non-adult title screen - needs verifying) if (!(tileattr&0x08)) m_gfxdecode->gfx(region)->transpen(bitmap,clip,tile,col,0,0,x*8,y*8, 0); if (tileattr&0x04) { if (bgenable==0) m_reel1_tilemap->draw(screen, bitmap, clip, 0, 0); if (bgenable==1) m_reel2_tilemap->draw(screen, bitmap, clip, 0, 0); if (bgenable==2) m_reel3_tilemap->draw(screen, bitmap, clip, 0, 0); if (bgenable==3) m_reel4_tilemap->draw(screen, bitmap, clip, 0, 0); } if ((tileattr&0x08)) m_gfxdecode->gfx(region)->transpen(bitmap,clip,tile,col,0,0,x*8,y*8, 0); #endif count++; } } return 0; }
UINT32 igs009_state::screen_update_jingbell(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int layers_ctrl = m_video_enable ? -1 : 0; #ifdef MAME_DEBUG if (machine().input().code_pressed(KEYCODE_Z)) { int mask = 0; if (machine().input().code_pressed(KEYCODE_Q)) mask |= 1; if (machine().input().code_pressed(KEYCODE_W)) mask |= 2; if (machine().input().code_pressed(KEYCODE_A)) mask |= 4; if (mask != 0) layers_ctrl &= mask; } #endif if (layers_ctrl & 1) { int zz,i; int startclipmin = 0; const rectangle &visarea = screen.visible_area(); for (i= 0;i < 0x80;i++) { m_gp98_reel1_tilemap->set_scrolly(i, m_bg_scroll[i]*2); m_gp98_reel2_tilemap->set_scrolly(i, m_bg_scroll[i+0x80]*2); m_gp98_reel3_tilemap->set_scrolly(i, m_bg_scroll[i+0x100]*2); m_gp98_reel4_tilemap->set_scrolly(i, m_bg_scroll[i+0x180]*2); } for (zz=0;zz<0x80-8;zz++) // -8 because of visible area (2*8 = 16) { rectangle clip; int rowenable = m_bg_scroll2[zz]; /* draw top of screen */ clip.set(visarea.min_x, visarea.max_x, startclipmin, startclipmin+2); bitmap.fill(m_palette->pen(rowenable), clip); if (rowenable==0) { // 0 and 1 are the same? or is there a global switchoff? m_gp98_reel1_tilemap->draw(screen, bitmap, clip, 0,0); } else if (rowenable==1) { m_gp98_reel2_tilemap->draw(screen, bitmap, clip, 0,0); } else if (rowenable==2) { m_gp98_reel3_tilemap->draw(screen, bitmap, clip, 0,0); } else if (rowenable==3) { m_gp98_reel4_tilemap->draw(screen, bitmap, clip, 0,0); } startclipmin+=2; } } else bitmap.fill(m_palette->black_pen(), cliprect); if (layers_ctrl & 2) m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; }
UINT32 tc0091lvc_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { UINT32 count; int x,y; UINT8 global_flip; bitmap.fill(m_palette->black_pen(), cliprect); if((m_vregs[4] & 0x20) == 0) return 0; global_flip = m_vregs[4] & 0x10; if((m_vregs[4] & 0x7) == 7) // 8bpp bitmap enabled { count = 0; for (y=0;y<256;y++) { for (x=0;x<512;x++) { int res_x, res_y; res_x = (global_flip) ? 320-x : x; res_y = (global_flip) ? 256-y : y; if(screen.visible_area().contains(res_x, res_y)) bitmap.pix16(res_y, res_x) = m_palette->pen(m_bitmap_ram[count]); count++; } } } else { int dx, dy; machine().tilemap().set_flip_all(global_flip ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); dx = m_bg0_scroll[0] | (m_bg0_scroll[1] << 8); if (global_flip) { dx = ((dx & 0xfffc) | ((dx - 3) & 0x0003)) ^ 0xf; dx += 192; } dy = m_bg0_scroll[2]; bg0_tilemap->set_scrollx(0, -dx); bg0_tilemap->set_scrolly(0, -dy); dx = m_bg1_scroll[0] | (m_bg1_scroll[1] << 8); if (global_flip) { dx = ((dx & 0xfffc) | ((dx - 3) & 0x0003)) ^ 0xf; dx += 192; } dy = m_bg1_scroll[2]; bg1_tilemap->set_scrollx(0, -dx); bg1_tilemap->set_scrolly(0, -dy); tx_tilemap->set_scrollx(0, (global_flip) ? -192 : 0); screen.priority().fill(0, cliprect); bg1_tilemap->draw(screen, bitmap, cliprect, 0,0); bg0_tilemap->draw(screen, bitmap, cliprect, 0,(m_vregs[4] & 0x8) ? 0 : 1); draw_sprites(screen, bitmap, cliprect, global_flip); tx_tilemap->draw(screen, bitmap, cliprect, 0,0); } return 0; }
void draw_virtual_tilemap(screen_device &screen, struct tilemap_info *info, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16 pages, UINT16 xscroll, UINT16 yscroll, UINT32 flags, UINT32 priority) { int leftmin = -1, leftmax = -1, rightmin = -1, rightmax = -1; int topmin = -1, topmax = -1, bottommin = -1, bottommax = -1; rectangle pageclip; int page; if (info->flip) { pages = BITSWAP16(pages, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 ); } int width = screen.visible_area().max_x+1; int height = screen.visible_area().max_y+1; /* which half/halves of the virtual tilemap do we intersect in the X direction? */ if (xscroll < 64*8 - width) { leftmin = 0; leftmax = width - 1; rightmin = -1; } else if (xscroll < 64*8) { leftmin = 0; leftmax = 64*8 - xscroll - 1; rightmin = leftmax + 1; rightmax = width - 1; } else if (xscroll < 128*8 - width) { rightmin = 0; rightmax = width - 1; leftmin = -1; } else { rightmin = 0; rightmax = 128*8 - xscroll - 1; leftmin = rightmax + 1; leftmax = width - 1; } /* which half/halves of the virtual tilemap do we intersect in the Y direction? */ if (yscroll < 32*8 - height) { topmin = 0; topmax = height - 1; bottommin = -1; } else if (yscroll < 32*8) { topmin = 0; topmax = 32*8 - yscroll - 1; bottommin = topmax + 1; bottommax = height - 1; } else if (yscroll < 64*8 - height) { bottommin = 0; bottommax = height - 1; topmin = -1; } else { bottommin = 0; bottommax = 64*8 - yscroll - 1; topmin = bottommax + 1; topmax = height - 1; } // adjust split positions to compensate for flipping if (info->flip) { int temp; if (bottommin != -1) bottommin = height - 1 - bottommin; if (bottommax != -1) bottommax = height - 1 - bottommax; if (topmin != -1) topmin = height - 1 - topmin; if (topmax != -1) topmax = height - 1 - topmax; temp = bottommin; bottommin = topmax; topmax = temp; temp = bottommax; bottommax = topmin; topmin = temp; if (leftmin != -1) leftmin = width - 1 - leftmin; if (leftmax != -1) leftmax = width - 1 - leftmax; if (rightmin != -1) rightmin = width - 1 - rightmin; if (rightmax != -1) rightmax = width - 1 - rightmax; temp = leftmin; leftmin = rightmax; rightmax = temp; temp = leftmax; leftmax = rightmin; rightmin = temp; } /* draw the upper-left chunk */ if (leftmin != -1 && topmin != -1) { pageclip.min_x = (leftmin < cliprect.min_x) ? cliprect.min_x : leftmin; pageclip.max_x = (leftmax > cliprect.max_x) ? cliprect.max_x : leftmax; pageclip.min_y = (topmin < cliprect.min_y) ? cliprect.min_y : topmin; pageclip.max_y = (topmax > cliprect.max_y) ? cliprect.max_y : topmax; if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y) { page = (pages >> 0) & 0xf; info->tilemaps[page]->set_scrollx(0, xscroll); info->tilemaps[page]->set_scrolly(0, yscroll); info->tilemaps[page]->draw(screen, bitmap, pageclip, flags, priority); }