UINT32 scv_state::screen_update_scv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int x, y; UINT8 fg = m_videoram[0x1403] >> 4; UINT8 bg = m_videoram[0x1403] & 0x0f; UINT8 gr_fg = m_videoram[0x1401] >> 4; UINT8 gr_bg = m_videoram[0x1401] & 0x0f; int clip_x = ( m_videoram[0x1402] & 0x0f ) * 2; int clip_y = m_videoram[0x1402] >> 4; /* Clear the screen */ bitmap.fill(gr_bg , cliprect); /* Draw background */ for ( y = 0; y < 16; y++ ) { int text_y = 0; if ( y < clip_y ) { text_y = ( m_videoram[0x1400] & 0x80 ) ? 0 : 1; } else { text_y = ( m_videoram[0x1400] & 0x80 ) ? 1 : 0; } for ( x = 0; x < 32; x++ ) { int text_x = 0; UINT8 d = m_videoram[ 0x1000 + y * 32 + x ]; if ( x < clip_x ) { text_x = ( m_videoram[0x1400] & 0x40 ) ? 0 : 1; } else { text_x = ( m_videoram[0x1400] & 0x40 ) ? 1 : 0; } if ( text_x && text_y ) { /* Text mode */ UINT8 *char_data = m_charrom->base() + ( d & 0x7f ) * 8; draw_text( bitmap, x * 8, y * 16, char_data, fg, bg ); } else { switch ( m_videoram[0x1400] & 0x03 ) { case 0x01: /* Semi graphics mode */ draw_semi_graph( bitmap, x * 8 , y * 16 , d & 0x80, gr_fg ); draw_semi_graph( bitmap, x * 8 + 4, y * 16 , d & 0x40, gr_fg ); draw_semi_graph( bitmap, x * 8 , y * 16 + 4, d & 0x20, gr_fg ); draw_semi_graph( bitmap, x * 8 + 4, y * 16 + 4, d & 0x10, gr_fg ); draw_semi_graph( bitmap, x * 8 , y * 16 + 8, d & 0x08, gr_fg ); draw_semi_graph( bitmap, x * 8 + 4, y * 16 + 8, d & 0x04, gr_fg ); draw_semi_graph( bitmap, x * 8 , y * 16 + 12, d & 0x02, gr_fg ); draw_semi_graph( bitmap, x * 8 + 4, y * 16 + 12, d & 0x01, gr_fg ); break; case 0x03: /* Block graphics mode */ draw_block_graph( bitmap, x * 8, y * 16 , d >> 4 ); draw_block_graph( bitmap, x * 8, y * 16 + 8, d & 0x0f ); break; default: /* Otherwise draw nothing? */ break; } } } } /* Draw sprites if enabled */ if ( m_videoram[0x1400] & 0x10 ) { UINT8 screen_start_sprite_line = ( ( ( m_videoram[0x1400] & 0xf7 ) == 0x17 ) && ( ( m_videoram[0x1402] & 0xef ) == 0x4f ) ) ? 21 + 32 : 0 ; int i; for ( i = 0; i < 128; i++ ) { UINT8 spr_y = m_videoram[ 0x1200 + i * 4 ] & 0xfe; UINT8 y_32 = m_videoram[ 0x1200 + i * 4 ] & 0x01; /* Xx32 sprite */ UINT8 clip = m_videoram[ 0x1201 + i * 4 ] >> 4; UINT8 col = m_videoram[ 0x1201 + i * 4 ] & 0x0f; UINT8 spr_x = m_videoram[ 0x1202 + i * 4 ] & 0xfe; UINT8 x_32 = m_videoram[ 0x1202 + i * 4 ] & 0x01; /* 32xX sprite */ UINT8 tile_idx = m_videoram[ 0x1203 + i * 4 ] & 0x7f; UINT8 half = m_videoram[ 0x1203 + i * 4] & 0x80; UINT8 left = 1; UINT8 right = 1; UINT8 top = 1; UINT8 bottom = 1; if ( !col ) { continue; } if ( !spr_y ) { continue; } if ( half ) { if ( tile_idx & 0x40 ) { if ( y_32 ) { spr_y -= 8; top = 0; bottom = 1; y_32 = 0; } else { top = 1; bottom = 0; } } if ( x_32 ) { spr_x -= 8; left = 0; right = 1; x_32 = 0; } else { left = 1; right = 0; } } /* Check if 2 color sprites are enabled */ if ( ( m_videoram[0x1400] & 0x20 ) && ( i & 0x20 ) ) { /* 2 color sprite handling */ draw_sprite( bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line ); if ( x_32 || y_32 ) { static const UINT8 spr_2col_lut0[16] = { 0, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 1, 1 }; static const UINT8 spr_2col_lut1[16] = { 0, 1, 8, 11, 2, 3, 10, 9, 4, 5, 12, 13, 6, 7, 14, 15 }; draw_sprite( bitmap, spr_x, spr_y, tile_idx ^ ( 8 * x_32 + y_32 ), ( i & 0x40 ) ? spr_2col_lut1[col] : spr_2col_lut0[col], left, right, top, bottom, clip, screen_start_sprite_line ); } } else { /* regular sprite handling */ draw_sprite( bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line ); if ( x_32 ) { draw_sprite( bitmap, spr_x + 16, spr_y, tile_idx | 8, col, 1, 1, top, bottom, clip, screen_start_sprite_line ); } if ( y_32 ) { clip = ( clip & 0x08 ) ? ( clip & 0x07 ) : 0; draw_sprite( bitmap, spr_x, spr_y + 16, tile_idx | 1, col, left, right, 1, 1, clip, screen_start_sprite_line ); if ( x_32 ) { draw_sprite( bitmap, spr_x + 16, spr_y + 16, tile_idx | 9, col, 1, 1, 1, 1, clip, screen_start_sprite_line ); } } } } }
UINT32 albazc_state::screen_update_hanaroku(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { bitmap.fill(0x1f0, cliprect); // ??? draw_sprites(bitmap, cliprect); return 0; }
uint32_t destroyr_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int i, j; bitmap.fill(0, cliprect); /* draw major objects */ for (i = 0; i < 16; i++) { int attr = m_major_obj_ram[2 * i + 0] ^ 0xff; int horz = m_major_obj_ram[2 * i + 1]; int num = attr & 3; int scan = attr & 4; int flipx = attr & 8; if (scan == 0) { if (horz >= 192) horz -= 256; } else { if (horz < 192) continue; } m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, num, 0, flipx, 0, horz, 16 * i, 0); } /* draw alpha numerics */ for (i = 0; i < 8; i++) { for (j = 0; j < 32; j++) { int num = m_alpha_num_ram[32 * i + j]; m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, num, 0, 0, 0, 8 * j, 8 * i, 0); } } /* draw minor objects */ for (i = 0; i < 2; i++) { int num = i << 4 | (m_minor_obj_ram[i + 0] & 0xf); int horz = 256 - m_minor_obj_ram[i + 2]; int vert = 256 - m_minor_obj_ram[i + 4]; m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, num, 0, 0, 0, horz, vert, 0); } /* draw waves */ for (i = 0; i < 4; i++) { m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, m_wavemod ? 1 : 0, 0, 0, 0, 64 * i, 0x4e, 0); } /* draw cursor */ for (i = 0; i < 256; i++) { if (i & 4) bitmap.pix16(m_cursor ^ 0xff, i) = 7; } return 0; }
void buggychl_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) { int offs; const UINT8 *gfx; g_profiler.start(PROFILER_USER1); gfx = memregion("gfx2")->base(); for (offs = 0; offs < m_spriteram.bytes(); offs += 4) { int sx, sy, flipy, zoom, ch, x, px, y; const UINT8 *lookup; const UINT8 *zoomx_rom, *zoomy_rom; sx = m_spriteram[offs + 3] - ((m_spriteram[offs + 2] & 0x80) << 1); sy = 256 - 64 - m_spriteram[offs] + ((m_spriteram[offs + 1] & 0x80) << 1); flipy = m_spriteram[offs + 1] & 0x40; zoom = m_spriteram[offs + 1] & 0x3f; zoomy_rom = gfx + (zoom << 6); zoomx_rom = gfx + 0x2000 + (zoom << 3); lookup = m_sprite_lookup + ((m_spriteram[offs + 2] & 0x7f) << 6); for (y = 0; y < 64; y++) { int dy = flip_screen_y() ? (255 - sy - y) : (sy + y); if ((dy & ~0xff) == 0) { int charline, base_pos; charline = zoomy_rom[y] & 0x07; base_pos = zoomy_rom[y] & 0x38; if (flipy) base_pos ^= 0x38; px = 0; for (ch = 0; ch < 4; ch++) { int pos, code, realflipy; const UINT8 *pendata; pos = base_pos + 2 * ch; code = 8 * (lookup[pos] | ((lookup[pos + 1] & 0x07) << 8)); realflipy = (lookup[pos + 1] & 0x80) ? !flipy : flipy; code += (realflipy ? (charline ^ 7) : charline); pendata = m_gfxdecode->gfx(1)->get_data(code); for (x = 0; x < 16; x++) { int col = pendata[x]; if (col) { int dx = flip_screen_x() ? (255 - sx - px) : (sx + px); if ((dx & ~0xff) == 0) bitmap.pix16(dy, dx) = m_sprite_color_base + col; } /* the following line is almost certainly wrong */ if (zoomx_rom[7 - (2 * ch + x / 8)] & (1 << (x & 7))) px++; } } } } } g_profiler.stop(); }
inline void apple2_state::apple2_plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, UINT32 code, const UINT8 *textgfx_data, UINT32 textgfx_datalen, UINT32 my_a2) { int x, y, i; int fg = m_fgcolor; int bg = m_bgcolor; const UINT8 *chardata; UINT16 color; if (m_sysconfig != nullptr) { switch (m_sysconfig->read() & 0x03) { case 0: break; // leave alone case 1: if ((m_machinetype == APPLE_II) || (m_machinetype == LABA2P) || (m_machinetype == SPACE84)) { bg = WHITE; } else { fg = WHITE; } break; case 2: if ((m_machinetype == APPLE_II) || (m_machinetype == LABA2P) || (m_machinetype == SPACE84)) { bg = GREEN; } else { fg = GREEN; } break; case 3: if ((m_machinetype == APPLE_II) || (m_machinetype == LABA2P) || (m_machinetype == SPACE84)) { bg = ORANGE; } else { fg = ORANGE; } break; } } if (my_a2 & VAR_ALTCHARSET) { /* we're using an alternate charset */ code |= m_alt_charset_value; } else if (m_flash && (code >= 0x40) && (code <= 0x7f)) { /* we're flashing; swap */ i = fg; fg = bg; bg = i; } /* look up the character data */ chardata = &textgfx_data[(code * 8) % textgfx_datalen]; /* and finally, plot the character itself */ if ((m_machinetype == SPACE84) || (m_machinetype == LABA2P)) { for (y = 0; y < 8; y++) { for (x = 0; x < 7; x++) { color = (chardata[y] & (1 << (6-x))) ? bg : fg; for (i = 0; i < xscale; i++) { bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color; } } } } else { for (y = 0; y < 8; y++) { for (x = 0; x < 7; x++) { color = (chardata[y] & (1 << x)) ? bg : fg; for (i = 0; i < xscale; i++) { bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color; } } } } }
/* write a single char on screen */ void pdp1_state::pdp1_draw_char(bitmap_ind16 &bitmap, char character, int x, int y, int color) { m_gfxdecode->gfx(0)->transpen(bitmap,bitmap.cliprect(), character-32, color, 0, 0, x+1, y, 0); }
void rastersp_state::video_start() { m_update_bitmap.allocate(320, 240); }
static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int sprite_priority) { tceptor_state *state = machine.driver_data<tceptor_state>(); UINT16 *mem1 = &state->m_sprite_ram_buffered[0x000/2]; UINT16 *mem2 = &state->m_sprite_ram_buffered[0x100/2]; int need_mask = 0; int i; for (i = 0; i < 0x100; i += 2) { int scalex = (mem1[1 + i] & 0xfc00) << 1; int scaley = (mem1[0 + i] & 0xfc00) << 1; int pri = 7 - ((mem1[1 + i] & 0x3c0) >> 6); if (pri == sprite_priority && scalex && scaley) { int x = mem2[1 + i] & 0x3ff; int y = 512 - (mem2[0 + i] & 0x3ff); int flipx = mem2[0 + i] & 0x4000; int flipy = mem2[0 + i] & 0x8000; int color = mem1[1 + i] & 0x3f; int gfx; int code; if (mem2[0 + i] & 0x2000) { gfx = state->m_sprite32; code = mem1[0 + i] & 0x3ff; } else { gfx = state->m_sprite16; code = mem1[0 + i] & 0x1ff; scaley *= 2; } if (state->m_is_mask_spr[color]) { if (!need_mask) // backup previous bitmap copybitmap(state->m_temp_bitmap, bitmap, 0, 0, 0, 0, cliprect); need_mask = 1; } // round off scalex += 0x800; scaley += 0x800; x -= 64; y -= 78; drawgfxzoom_transmask(bitmap, cliprect, machine.gfx[gfx], code, color, flipx, flipy, x, y, scalex, scaley, colortable_get_transpen_mask(machine.colortable, machine.gfx[gfx], color, SPR_TRANS_COLOR)); } } /* if SPR_MASK_COLOR pen is used, restore pixels from previous bitmap */ if (need_mask) { int x, y; for (x = cliprect.min_x; x <= cliprect.max_x; x++) for (y = cliprect.min_y; y <= cliprect.max_y; y++) if (colortable_entry_get_value(machine.colortable, bitmap.pix16(y, x)) == SPR_MASK_COLOR) // restore pixel bitmap.pix16(y, x) = state->m_temp_bitmap.pix16(y, x); } }
UINT32 darkmist_state::screen_update_darkmist(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { UINT8 *spriteram = m_spriteram; #define DM_GETSCROLL(n) (((m_scroll[(n)]<<1)&0xff) + ((m_scroll[(n)]&0x80)?1:0) +( ((m_scroll[(n)-1]<<4) | (m_scroll[(n)-1]<<12) )&0xff00)) set_pens(machine()); m_bgtilemap->set_scrollx(0, DM_GETSCROLL(0x2)); m_bgtilemap->set_scrolly(0, DM_GETSCROLL(0x6)); m_fgtilemap->set_scrollx(0, DM_GETSCROLL(0xa)); m_fgtilemap->set_scrolly(0, DM_GETSCROLL(0xe)); bitmap.fill(get_black_pen(machine()), cliprect); if(m_hw & DISPLAY_BG) m_bgtilemap->draw(bitmap, cliprect, 0,0); if(m_hw & DISPLAY_FG) m_fgtilemap->draw(bitmap, cliprect, 0,0); if(m_hw & DISPLAY_SPR) { /* Sprites 76543210 0 - TTTT TTTT - tile 1 - xyBP PPP? - palette (P), flips (x,y), B - use spritebank, ? - unknown, according to gamecode top bit of one of coords(y/x) 2 - YYYY YYYY - y coord 3 - XXXX XXXX - x coord */ int i,fx,fy,tile,palette; for(i=0; i<m_spriteram.bytes(); i+=32) { fy=spriteram[i+1]&0x40; fx=spriteram[i+1]&0x80; tile=spriteram[i+0]; if(spriteram[i+1]&0x20) tile += (*m_spritebank << 8); palette=((spriteram[i+1])>>1)&0xf; if(spriteram[i+1]&0x1) palette=machine().rand()&15; palette+=32; drawgfx_transpen( bitmap,cliprect, machine().gfx[2], tile, palette, fx,fy, spriteram[i+3],spriteram[i+2],0 ); } }
UINT32 fuuki16_state::screen_update_fuuki16(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { UINT16 layer0_scrollx, layer0_scrolly; UINT16 layer1_scrollx, layer1_scrolly; UINT16 layer2_scrollx, layer2_scrolly; UINT16 scrollx_offs, scrolly_offs; /* It's not independent bits causing layers to switch, that wouldn't make sense with 3 bits. See fuukifg3 for more justification */ static const int pri_table[6][3] = { { 0, 1, 2 }, { 0, 2, 1 }, { 1, 0, 2 }, { 1, 2, 0 }, { 2, 0, 1 }, { 2, 1, 0 }}; int tm_front = pri_table[m_priority[0] & 0x0f][0]; int tm_middle = pri_table[m_priority[0] & 0x0f][1]; int tm_back = pri_table[m_priority[0] & 0x0f][2]; flip_screen_set(m_vregs[0x1e / 2] & 1); /* Layers scrolling */ scrolly_offs = m_vregs[0xc / 2] - (flip_screen() ? 0x103 : 0x1f3); scrollx_offs = m_vregs[0xe / 2] - (flip_screen() ? 0x2a7 : 0x3f6); layer0_scrolly = m_vregs[0x0 / 2] + scrolly_offs; layer0_scrollx = m_vregs[0x2 / 2] + scrollx_offs; layer1_scrolly = m_vregs[0x4 / 2] + scrolly_offs; layer1_scrollx = m_vregs[0x6 / 2] + scrollx_offs; layer2_scrolly = m_vregs[0x8 / 2]; layer2_scrollx = m_vregs[0xa / 2]; m_tilemap[0]->set_scrollx(0, layer0_scrollx); m_tilemap[0]->set_scrolly(0, layer0_scrolly); m_tilemap[1]->set_scrollx(0, layer1_scrollx); m_tilemap[1]->set_scrolly(0, layer1_scrolly); m_tilemap[2]->set_scrollx(0, layer2_scrollx + 0x10); m_tilemap[2]->set_scrolly(0, layer2_scrolly /*+ 0x02*/); m_tilemap[3]->set_scrollx(0, layer2_scrollx + 0x10); m_tilemap[3]->set_scrolly(0, layer2_scrolly /*+ 0x02*/); /* The backmost tilemap decides the background color(s) but sprites can go below the opaque pixels of that tilemap. We thus need to mark the transparent pixels of this layer with a different priority value */ // fuuki16_draw_layer(machine(), bitmap, cliprect, tm_back, TILEMAP_DRAW_OPAQUE, 0); /* Actually, bg colour is simply the last pen i.e. 0x1fff -pjp */ bitmap.fill((0x800 * 4) - 1, cliprect); screen.priority().fill(0, cliprect); fuuki16_draw_layer(screen, bitmap, cliprect, tm_back, 0, 1); fuuki16_draw_layer(screen, bitmap, cliprect, tm_middle, 0, 2); fuuki16_draw_layer(screen, bitmap, cliprect, tm_front, 0, 4); m_fuukivid->draw_sprites(screen, bitmap, cliprect, flip_screen(), 0); return 0; }
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_t groundfx_state::screen_update_groundfx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { address_space &space = machine().dummy_space(); uint8_t layer[5]; uint8_t scclayer[3]; uint16_t priority; m_tc0100scn->tilemap_update(); m_tc0480scp->tilemap_update(); priority = m_tc0480scp->get_bg_priority(); layer[0] = (priority & 0xf000) >> 12; /* tells us which bg layer is bottom */ layer[1] = (priority & 0x0f00) >> 8; layer[2] = (priority & 0x00f0) >> 4; layer[3] = (priority & 0x000f) >> 0; /* tells us which is top */ layer[4] = 4; /* text layer always over bg layers */ scclayer[0] = m_tc0100scn->bottomlayer(); scclayer[1] = scclayer[0]^1; scclayer[2] = 2; screen.priority().fill(0, cliprect); bitmap.fill(0, cliprect); /* wrong color? */ m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, scclayer[0], TILEMAP_DRAW_OPAQUE, 0); m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, scclayer[1], 0, 0); /* BIG HACK! The rear view mirror is a big priority trick - the text layer of TC0100SCN is used as a stencil to display the bottom layer of TC0480SCP and a particular sprite priority. These never appear outside of the stencil. I'm not sure how the game turns this effect on/off (the 480 layer is used normally in the frontend of the game). I haven't implemented it properly yet, instead I'm doing a hacky cliprect around the rearview and drawing it's contents the usual way. */ if (m_tc0100scn->long_r(space, 0x4090 / 4, 0xffffffff) || m_tc0480scp->long_r(space, 0x20 / 4, 0xffffffff) == 0x240866) /* Anything in text layer - really stupid hack */ { m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8); //m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, 0, scclayer[2], 0, 0); if (m_tc0480scp->long_r(space, 0x20 / 4, 0xffffffff) != 0x240866) /* Stupid hack for start of race */ m_tc0480scp->tilemap_draw(screen, bitmap, m_hack_cliprect, layer[0], 0, 0); draw_sprites(screen, bitmap, cliprect, 1, 44, -574); } else { m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 1); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4); m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8); m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, scclayer[2], 0, 0); draw_sprites(screen, bitmap, cliprect, 0, 44, -574); } m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); /* TC0480SCP text layer */ return 0; }
static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect) { zac2650_state *state = machine.driver_data<zac2650_state>(); int offs; const rectangle &visarea = machine.primary_screen->visible_area(); /* -------------------------------------------------------------- */ /* There seems to be a strange setup with this board, in that it */ /* appears that the S2636 runs from a different clock than the */ /* background generator, When the program maps sprite position to */ /* character position it only has 6 pixels of sprite for 8 pixels */ /* of character. */ /* -------------------------------------------------------------- */ /* n.b. The original has several graphic glitches as well, so it */ /* does not seem to be a fault of the emulation! */ /* -------------------------------------------------------------- */ state->m_CollisionBackground = 0; /* Read from 0x1e80 bit 7 */ // for collision detection checking copybitmap(state->m_bitmap,bitmap,0,0,0,0,visarea); for(offs=0;offs<0x50;offs+=0x10) { if((state->m_s2636_0_ram[offs+10]<0xF0) && (offs!=0x30)) { int spriteno = (offs / 8); int expand = ((state->m_s2636_0_ram[0xc0] & (spriteno*2))!=0) ? 2 : 1; int bx = (state->m_s2636_0_ram[offs+10] * 4) - 22; int by = (state->m_s2636_0_ram[offs+12] * 3) + 3; int x,y; /* Sprite->Background collision detection */ drawgfx_transpen(bitmap,cliprect, machine.gfx[expand], spriteno, 1, 0,0, bx,by, 0); for (x = bx; x < bx + machine.gfx[expand]->width(); x++) { for (y = by; y < by + machine.gfx[expand]->height(); y++) { if (visarea.contains(x, y)) if (bitmap.pix16(y, x) != state->m_bitmap.pix16(y, x)) { state->m_CollisionBackground = 0x80; break; } } } drawgfx_transpen(bitmap,cliprect, machine.gfx[expand], spriteno, 0, 0,0, bx,by, 0); } } /* Sprite->Sprite collision detection */ state->m_CollisionSprite = 0; // if(SpriteCollision(machine, 0,1)) state->m_CollisionSprite |= 0x20; /* Not Used */ if(SpriteCollision(machine, 0,2)) state->m_CollisionSprite |= 0x10; if(SpriteCollision(machine, 0,4)) state->m_CollisionSprite |= 0x08; if(SpriteCollision(machine, 1,2)) state->m_CollisionSprite |= 0x04; if(SpriteCollision(machine, 1,4)) state->m_CollisionSprite |= 0x02; // if(SpriteCollision(machine, 2,4)) state->m_CollisionSprite |= 0x01; /* Not Used */ }
void buggychl_state::draw_sky( bitmap_ind16 &bitmap, const rectangle &cliprect ) { for (int y = 0; y < 256; y++) for (int x = 0; x < 256; x++) bitmap.pix16(y, x) = 128 + x / 2; }
UINT32 segas16a_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // if no drawing is happening, fill with black and get out if (!m_segaic16vid->segaic16_display_enable) { bitmap.fill(m_palette->black_pen(), cliprect); return 0; } // start the sprites drawing m_sprites->draw_async(cliprect); // reset priorities screen.priority().fill(0, cliprect); // draw background opaquely first, not setting any priorities m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_BACKGROUND, 0 | TILEMAP_DRAW_OPAQUE, 0x00); m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_BACKGROUND, 1 | TILEMAP_DRAW_OPAQUE, 0x00); // draw background again, just to set the priorities on non-transparent pixels bitmap_ind16 dummy_bitmap; m_segaic16vid->segaic16_tilemap_draw(screen, dummy_bitmap, cliprect, 0, SEGAIC16_TILEMAP_BACKGROUND, 0, 0x01); m_segaic16vid->segaic16_tilemap_draw(screen, dummy_bitmap, cliprect, 0, SEGAIC16_TILEMAP_BACKGROUND, 1, 0x02); // draw foreground m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_FOREGROUND, 0, 0x02); m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_FOREGROUND, 1, 0x04); // text layer m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_TEXT, 0, 0x04); m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_TEXT, 1, 0x08); // mix in sprites bitmap_ind16 &sprites = m_sprites->bitmap(); for (const sparse_dirty_rect *rect = m_sprites->first_dirty_rect(cliprect); rect != NULL; rect = rect->next()) for (int y = rect->min_y; y <= rect->max_y; y++) { UINT16 *dest = &bitmap.pix(y); UINT16 *src = &sprites.pix(y); UINT8 *pri = &screen.priority().pix(y); for (int x = rect->min_x; x <= rect->max_x; x++) { // only process written pixels UINT16 pix = src[x]; if (pix != 0xffff) { // compare sprite priority against tilemap priority int priority = pix >> 10; if ((1 << priority) > pri[x]) { // if color bits are all 1, this triggers shadow/hilight if ((pix & 0x3f0) == 0x3f0) dest[x] += (m_paletteram[dest[x]] & 0x8000) ? m_palette_entries*2 : m_palette_entries; // otherwise, just add in sprite palette base else dest[x] = 0x400 | (pix & 0x3ff); } } } }
UINT32 batman_state::screen_update_batman(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // start drawing m_vad->mob()->draw_async(cliprect); /* draw the playfield */ bitmap_ind8 &priority_bitmap = screen.priority(); priority_bitmap.fill(0, cliprect); m_vad->playfield()->draw(screen, bitmap, cliprect, 0, 0x00); m_vad->playfield()->draw(screen, bitmap, cliprect, 1, 0x01); m_vad->playfield()->draw(screen, bitmap, cliprect, 2, 0x02); m_vad->playfield()->draw(screen, bitmap, cliprect, 3, 0x03); m_vad->playfield2()->draw(screen, bitmap, cliprect, 0, 0x80); m_vad->playfield2()->draw(screen, bitmap, cliprect, 1, 0x84); m_vad->playfield2()->draw(screen, bitmap, cliprect, 2, 0x88); m_vad->playfield2()->draw(screen, bitmap, cliprect, 3, 0x8c); // draw and merge the MO bitmap_ind16 &mobitmap = m_vad->mob()->bitmap(); for (const sparse_dirty_rect *rect = m_vad->mob()->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next()) for (int y = rect->min_y; y <= rect->max_y; y++) { UINT16 *mo = &mobitmap.pix16(y); UINT16 *pf = &bitmap.pix16(y); UINT8 *pri = &priority_bitmap.pix8(y); for (int x = rect->min_x; x <= rect->max_x; x++) if (mo[x] != 0xffff) { /* verified on real hardware: for all MO colors, MO priority 0: obscured by low fg playfield pens priority 1-3 obscured by high fg playfield pens priority 3 only obscured by bg playfield priority 3 only for all MO colors, MO priority 1: obscured by low fg playfield pens priority 2-3 obscured by high fg playfield pens priority 3 only obscured by bg playfield priority 3 only for all MO colors, MO priority 2-3: obscured by low fg playfield pens priority 3 only obscured by high fg playfield pens priority 3 only obscured by bg playfield priority 3 only */ int mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT; /* upper bit of MO priority signals special rendering and doesn't draw anything */ if (mopriority & 4) continue; /* foreground playfield case */ if (pri[x] & 0x80) { int pfpriority = (pri[x] >> 2) & 3; /* playfield priority 3 always wins */ if (pfpriority == 3) ; /* priority is consistent for upper pens in playfield */ else if (pf[x] & 0x08) pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; /* otherwise, we need to compare */ else if (mopriority >= pfpriority) pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK; } /* background playfield case */ else {
void hd66421_device::plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color) { bitmap.pix16(y, x) = (UINT16)color; }
INLINE void K053936GP_copyroz32clip( running_machine &machine, bitmap_rgb32 &dst_bitmap, bitmap_ind16 &src_bitmap, const rectangle &dst_cliprect, const rectangle &src_cliprect, UINT32 _startx,UINT32 _starty,int _incxx,int _incxy,int _incyx,int _incyy, int tilebpp, int blend, int alpha, int clip, int pixeldouble_output, palette_device *palette ) { static const int colormask[8]={1,3,7,0xf,0x1f,0x3f,0x7f,0xff}; int cy, cx; int ecx; int src_pitch, incxy, incxx; int src_minx, src_maxx, src_miny, src_maxy, cmask; UINT16 *src_base; size_t src_size; const pen_t *pal_base; int dst_ptr; int dst_size; int dst_base2; int tx, dst_pitch; UINT32 *dst_base; int starty, incyy, startx, incyx, ty, sx, sy; incxy = _incxy; incxx = _incxx; incyy = _incyy; incyx = _incyx; starty = _starty; startx = _startx; if (clip) // set source clip range to some extreme values when disabled { src_minx = src_cliprect.min_x; src_maxx = src_cliprect.max_x; src_miny = src_cliprect.min_y; src_maxy = src_cliprect.max_y; } // this simply isn't safe to do! else { src_minx = src_miny = -0x10000; src_maxx = src_maxy = 0x10000; } // set target clip range sx = dst_cliprect.min_x; tx = dst_cliprect.max_x - sx + 1; sy = dst_cliprect.min_y; ty = dst_cliprect.max_y - sy + 1; startx += sx * incxx + sy * incyx; starty += sx * incxy + sy * incyy; // adjust entry points and other loop constants dst_pitch = dst_bitmap.rowpixels(); dst_base = &dst_bitmap.pix32(0); dst_base2 = sy * dst_pitch + sx + tx; ecx = tx = -tx; tilebpp = (tilebpp-1) & 7; pal_base = palette->pens(); cmask = colormask[tilebpp]; src_pitch = src_bitmap.rowpixels(); src_base = &src_bitmap.pix16(0); src_size = src_bitmap.width() * src_bitmap.height(); dst_size = dst_bitmap.width() * dst_bitmap.height(); dst_ptr = 0;//dst_base; cy = starty; cx = startx; if (blend > 0) { dst_base += dst_pitch; // draw blended starty += incyy; startx += incyx; do { do { int srcx = (cx >> 16) & 0x1fff; int srcy = (cy >> 16) & 0x1fff; int pixel; UINT32 offs; offs = srcy * src_pitch + srcx; cx += incxx; cy += incxy; if (offs>=src_size) continue; if (srcx < src_minx || srcx > src_maxx || srcy < src_miny || srcy > src_maxy) continue; pixel = src_base[offs]; if (!(pixel & cmask)) continue; if ((dst_ptr+ecx+dst_base2)<dst_size) dst_base[dst_ptr+ecx+dst_base2] = alpha_blend_r32(pal_base[pixel], dst_base[dst_ptr+ecx+dst_base2], alpha); if (pixeldouble_output) { ecx++; if ((dst_ptr+ecx+dst_base2)<dst_size) dst_base[dst_ptr+ecx+dst_base2] = alpha_blend_r32(pal_base[pixel], dst_base[dst_ptr+ecx+dst_base2], alpha); } } while (++ecx < 0); ecx = tx; dst_ptr += dst_pitch; cy = starty; starty += incyy; cx = startx; startx += incyx; } while (--ty); }
inline void pdp1_state::pdp1_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color) { bitmap.pix16(y, x) = color; }
void apple2_state::apple2_hires_draw(bitmap_ind16 &bitmap, const rectangle &cliprect, int page, int beginrow, int endrow) { const UINT8 *vram, *vaux; int row, col, b; int offset; int columns; UINT8 vram_row[82]; UINT16 v; UINT16 *p; UINT32 w; UINT16 *artifact_map_ptr; int mon_type = 0; if (m_sysconfig != nullptr) { mon_type = m_sysconfig->read() & 0x03; } /* sanity checks */ if (beginrow < cliprect.min_y) beginrow = cliprect.min_y; if (endrow > cliprect.max_y) endrow = cliprect.max_y; if (endrow < beginrow) return; if (m_machinetype == TK2000) { vram = m_a2_videoram + (page ? 0xa000 : 0x2000); vaux = m_a2_videoaux + (page ? 0xa000 : 0x2000); } else { vram = m_a2_videoram + (page ? 0x4000 : 0x2000); vaux = m_a2_videoaux + (page ? 0x4000 : 0x2000); } columns = ((effective_a2() & (VAR_DHIRES|VAR_80COL)) == (VAR_DHIRES|VAR_80COL)) ? 80 : 40; vram_row[0] = 0; vram_row[columns + 1] = 0; for (row = beginrow; row <= endrow; row++) { for (col = 0; col < 40; col++) { offset = compute_video_address(col, row / 8) | ((row & 7) << 10); switch(columns) { case 40: vram_row[1+col] = vram[offset]; break; case 80: vram_row[1+(col*2)+0] = vaux[offset]; vram_row[1+(col*2)+1] = vram[offset]; break; default: fatalerror("Invalid column count\n"); } } p = &bitmap.pix16(row); for (col = 0; col < columns; col++) { w = (((UINT32) vram_row[col+0] & 0x7f) << 0) | (((UINT32) vram_row[col+1] & 0x7f) << 7) | (((UINT32) vram_row[col+2] & 0x7f) << 14); switch(columns) { case 40: switch (mon_type) { case 0: artifact_map_ptr = &m_hires_artifact_map[((vram_row[col+1] & 0x80) >> 7) * 16]; for (b = 0; b < 7; b++) { v = artifact_map_ptr[((w >> (b + 7-1)) & 0x07) | (((b ^ col) & 0x01) << 3)]; *(p++) = v; *(p++) = v; } break; case 1: w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? WHITE : BLACK; *(p++) = v ? WHITE : BLACK; } break; case 2: w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? GREEN : BLACK; *(p++) = v ? GREEN : BLACK; } break; case 3: w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? ORANGE : BLACK; *(p++) = v ? ORANGE : BLACK; } break; } break; case 80: if (m_monochrome_dhr) { w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? WHITE : BLACK; } } else { switch (mon_type) { case 0: for (b = 0; b < 7; b++) { v = m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F]; *(p++) = v; } break; case 1: w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? WHITE : BLACK; } break; case 2: w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? GREEN : BLACK; } break; case 3: w >>= 7; for (b = 0; b < 7; b++) { v = (w & 1); w >>= 1; *(p++) = v ? ORANGE : BLACK; } break; } } break; default: fatalerror("Invalid column count\n"); } } }
INLINE void tx0_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color) { bitmap.pix16(y, x) = color; }
UINT32 segahang_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { // if no drawing is happening, fill with black and get out if (!m_segaic16vid->segaic16_display_enable) { bitmap.fill(get_black_pen(machine()), cliprect); return 0; } // start the sprites drawing m_sprites->draw_async(cliprect); // reset priorities screen.priority().fill(0, cliprect); // draw the low priority road layer m_segaic16road->segaic16_road_draw(0, bitmap, cliprect, SEGAIC16_ROAD_BACKGROUND); // draw background m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_BACKGROUND, 0, 0x01); m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_BACKGROUND, 1, 0x02); // draw foreground m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_FOREGROUND, 0, 0x02); m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_FOREGROUND, 1, 0x04); // draw the high priority road m_segaic16road->segaic16_road_draw(0, bitmap, cliprect, SEGAIC16_ROAD_FOREGROUND); // text layer // note that we inflate the priority of the text layer to prevent sprites // from drawing over the high scores m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_TEXT, 0, 0x08); m_segaic16vid->segaic16_tilemap_draw(screen, bitmap, cliprect, 0, SEGAIC16_TILEMAP_TEXT, 1, 0x08); // mix in sprites bitmap_ind16 &sprites = m_sprites->bitmap(); for (const sparse_dirty_rect *rect = m_sprites->first_dirty_rect(cliprect); rect != NULL; rect = rect->next()) for (int y = rect->min_y; y <= rect->max_y; y++) { UINT16 *dest = &bitmap.pix(y); UINT16 *src = &sprites.pix(y); UINT8 *pri = &screen.priority().pix(y); // hangon mixing if (!m_sharrier_video) { for (int x = rect->min_x; x <= rect->max_x; x++) { // only process written pixels UINT16 pix = src[x]; if (pix != 0xffff) { // compare sprite priority against tilemap priority int priority = pix >> 10; if ((1 << priority) > pri[x]) { // if color bits are all 1, this triggers shadow/hilight if ((pix & 0x3f0) == 0x3f0) dest[x] += m_shadow ? m_palette_entries*2 : m_palette_entries; // otherwise, just add in sprite palette base else dest[x] = 0x400 | (pix & 0x3ff); } } } } // sharrier mixing else { for (int x = rect->min_x; x <= rect->max_x; x++)