/************************************* * * Video update * *************************************/ public u32 screen_update_centiped(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { ListBytesPointer spriteram = m_spriteram.target; //uint8_t *spriteram = m_spriteram; rectangle spriteclip = cliprect; int offs; /* draw the background */ m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); /* apply the sprite clip */ if (m_flipscreen != 0) { spriteclip.min_x += 8; } else { spriteclip.max_x -= 8; } /* draw the sprites */ for (offs = 0; offs < 0x10; offs++) { int code = ((spriteram[offs] & 0x3e) >> 1) | ((spriteram[offs] & 0x01) << 6); int color = spriteram[offs + 0x30]; int flipx = (spriteram[offs] >> 6) & 1; int flipy = (spriteram[offs] >> 7) & 1; int x = spriteram[offs + 0x20]; int y = 240 - spriteram[offs + 0x10]; m_gfxdecode.target.digfx.gfx(1).transmask(bitmap, spriteclip, (UInt32)code, (UInt32)color, flipx, flipy, x, y, m_penmask[color & 0x3f]); } return(0); }
public uint32_t screen_update(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); draw_sprites(bitmap, cliprect); m_fg_tilemap.draw(screen, bitmap, cliprect, 0, 0); return(0); }
/************************************* * * Video update * *************************************/ u32 screen_update_centiped(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { rectangle spriteclip = cliprect; /* draw the background */ m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); /* apply the sprite clip */ if (m_flipscreen != 0) { spriteclip.min_x += 8; } else { spriteclip.max_x -= 8; } /* draw the sprites */ for (int offs = 0; offs < 0x10; offs++) { int code = ((m_spriteram[offs].op & 0x3e) >> 1) | ((m_spriteram[offs].op & 0x01) << 6); int color = m_spriteram[offs + 0x30].op; int flipx = (m_spriteram[offs].op >> 6) & 1; int flipy = (m_spriteram[offs].op >> 7) & 1; int x = m_spriteram[offs + 0x20].op; int y = 240 - m_spriteram[offs + 0x10].op; m_gfxdecode.op0.gfx(1).transmask(bitmap, spriteclip, (u32)code, (u32)color, flipx, flipy, x, y, m_penmask[color & 0x3f]); } return(0); }
uint32_t screen_update_dkong(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { machine().tilemap().set_flip_all(m_flip != 0 ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0); switch (m_hardware_type) { case HARDWARE_TKG02: case HARDWARE_TKG04: check_palette(); m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); draw_sprites(bitmap, cliprect, 0x40, 1); break; case HARDWARE_TRS01: case HARDWARE_TRS02: m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); draw_sprites(bitmap, cliprect, 0x40, 1); radarscp_draw_background(bitmap, cliprect); break; default: fatalerror("Invalid hardware type in dkong_video_update\n"); break; } return(0); }
u32 screen_update_galaga(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { bitmap.fill(m_palette.op0.black_pen(), cliprect); m_starfield.op0.draw_starfield(bitmap, cliprect, 0); draw_sprites(bitmap, cliprect); m_fg_tilemap.draw(screen, bitmap, cliprect); return(0); }
u32 screen_update_digdug(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); m_fg_tilemap.draw(screen, bitmap, cliprect, 0, 0); draw_sprites(bitmap, cliprect); return(0); }
public UInt32 screen_update_galaga(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { bitmap.fill(m_palette.target.palette_interface.black_pen(), cliprect); draw_stars(bitmap, cliprect); draw_sprites(bitmap, cliprect); m_fg_tilemap.draw(screen, bitmap, cliprect, 0, 0); return(0); }
protected override void draw_sprites(bitmap_ind16 bitmap, rectangle cliprect) { Pointer <uint8_t> spriteram = new Pointer <uint8_t>(m_digdug_objram.op, 0x380); //uint8_t *spriteram = m_digdug_objram + 0x380; Pointer <uint8_t> spriteram_2 = new Pointer <uint8_t>(m_digdug_posram.op, 0x380); //uint8_t *spriteram_2 = m_digdug_posram + 0x380; Pointer <uint8_t> spriteram_3 = new Pointer <uint8_t>(m_digdug_flpram.op, 0x380); //uint8_t *spriteram_3 = m_digdug_flpram + 0x380; int offs; // mask upper and lower columns rectangle visarea = cliprect; visarea.min_x = 2 * 8; visarea.max_x = 34 * 8 - 1; for (offs = 0; offs < 0x80; offs += 2) { int sprite = spriteram[offs]; int color = spriteram[offs + 1] & 0x3f; int sx = spriteram_2[offs + 1] - 40 + 1; int sy = 256 - spriteram_2[offs] + 1; // sprites are buffered and delayed by one scanline int flipx = (spriteram_3[offs] & 0x01); int flipy = (spriteram_3[offs] & 0x02) >> 1; int size = (sprite & 0x80) >> 7; int x, y; if (size != 0) { sprite = (sprite & 0xc0) | ((sprite & ~0xc0) << 2); } sy -= 16 * size; sy = (sy & 0xff) - 32; // fix wraparound if (flip_screen() != 0) { flipx ^= 1; flipy ^= 1; } for (y = 0; y <= size; y++) { for (x = 0; x <= size; x++) { uint32_t transmask = m_palette.op0.transpen_mask(m_gfxdecode.op0.gfx(1), (u32)color, 0x1f); m_gfxdecode.op0.gfx(1).transmask(bitmap, visarea, (u32)(sprite + gfx_offs[y ^ (size * flipy), x ^ (size * flipx)]), (u32)color, flipx, flipy, ((sx + 16 * x) & 0xff), sy + 16 * y, transmask); /* wraparound */ m_gfxdecode.op0.gfx(1).transmask(bitmap, visarea, (u32)(sprite + gfx_offs[y ^ (size * flipy), x ^ (size * flipx)]), (u32)color, flipx, flipy, ((sx + 16 * x) & 0xff) + 0x100, sy + 16 * y, transmask); } } } }
void copy_layer(bitmap_ind16 bitmap, rectangle cliprect, int which, int [] sprites_on, rectangle [] sprite_areas) { int [] fudge1 = new int [3] { 3, 1, -1 }; int [] fudge2 = new int [3] { 8, 10, 12 }; if ((m_video_mode.op0 & layer_enable_mask[which]) != 0) { int i; int scrollx; int [] scrolly = new int [32]; scrollx = m_scroll.op[2 * which]; if (GLOBAL_FLIP_X) { scrollx = (scrollx & 0xf8) + ((scrollx + fudge1[which]) & 7) + fudge2[which]; } else { scrollx = -(scrollx & 0xf8) + ((scrollx + fudge1[which]) & 7) + fudge2[which]; } if (GLOBAL_FLIP_Y) { for (i = 0; i < 32; i++) { scrolly[31 - i] = m_colscrolly.op[32 * which + i] + m_scroll.op[2 * which + 1]; } } else { for (i = 0; i < 32; i++) { scrolly[i] = -m_colscrolly.op[32 * which + i] - m_scroll.op[2 * which + 1]; } } copyscrollbitmap_trans(bitmap, m_layer_bitmap[which], 1, new int [] { scrollx }, 32, scrolly, cliprect, TRANSPARENT_PEN); // store parts covered with sprites for sprites/layers collision detection for (i = 0; i < 0x20; i++) { if ((i >= 0x10) && (i <= 0x17)) { continue; // no sprites here } if (sprites_on[i] != 0) { copyscrollbitmap(m_sprite_layer_collbitmap2[which], m_layer_bitmap[which], 1, new int [] { scrollx }, 32, scrolly, sprite_areas[i]); } } } }
/************************************* * * Main refresh * *************************************/ uint32_t screen_update_atarisy2(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { // start drawing m_mob.op0.draw_async(cliprect); // reset priorities bitmap_ind8 priority_bitmap = screen.priority(); priority_bitmap.fill(0, cliprect); // draw the playfield m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 0, 0); m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 1, 1); m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 2, 2); m_playfield_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 3, 3); // draw and merge the MO bitmap_ind16 mobitmap = m_mob.op0.bitmap(); for (sparse_dirty_rect rect = m_mob.op0.first_dirty_rect(cliprect); rect != null; rect = rect.next()) { for (int y = rect.m_rect.top(); y <= rect.m_rect.bottom(); y++) { PointerU16 mo = mobitmap.pix(y); //uint16_t const *const mo = &mobitmap.pix(y); PointerU16 pf = bitmap.pix(y); //uint16_t *const pf = &bitmap.pix(y); PointerU8 pri = priority_bitmap.pix(y); //uint8_t const *const pri = &priority_bitmap.pix(y); for (int x = rect.m_rect.left(); x <= rect.m_rect.right(); x++) { if (mo[x] != 0xffff) { int mopriority = mo[x] >> atari_motion_objects_device.PRIORITY_SHIFT; // high priority PF? if (((mopriority + pri[x]) & 2) != 0) { // only gets priority if PF pen is less than 8 if ((pf[x] & 0x08) == 0) { pf[x] = (uint16_t)(mo[x] & atari_motion_objects_device.DATA_MASK); } } // low priority else { pf[x] = (uint16_t)(mo[x] & atari_motion_objects_device.DATA_MASK); } } } } } // add the alpha on top m_alpha_tilemap.op0.tilemap.draw(screen, bitmap, cliprect, 0, 0); return(0); }
void draw_sprites(bitmap_ind16 bitmap) { /* * sprite visibility area is missing 4 pixels from the sides, surely to reduce * wraparound side effects. This was verified on a real Elevator Action. * Note that the clipping is asymmetrical. This matches the real thing. * I'm not sure of what should happen when the screen is flipped, though. */ rectangle spritevisiblearea = new rectangle(0 * 8 + 3, 32 * 8 - 1 - 1, 2 * 8, 30 * 8 - 1); rectangle spritevisibleareaflip = new rectangle(0 * 8 + 1, 32 * 8 - 3 - 1, 2 * 8, 30 * 8 - 1); if (SPRITES_ON) { // drawing order is a bit strange. The last sprite has to be moved at the start of the list. for (int sprite = 0x1f; sprite >= 0; sprite--) { uint8_t sx; uint8_t sy; int which = (sprite - 1) & 0x1f; // move last sprite at the head of the list offs_t offs = (offs_t)(which * 4); if ((which >= 0x10) && (which <= 0x17)) { continue; // no sprites here } if (get_sprite_xy((uint8_t)which, out sx, out sy)) { int code = m_spriteram.op[SPRITE_RAM_PAGE_OFFSET + (int)offs + 3] & 0x3f; int color = 2 * ((m_colorbank.op[1] >> 4) & 0x03) + ((m_spriteram.op[SPRITE_RAM_PAGE_OFFSET + (int)offs + 2] >> 2) & 0x01); int flip_x = m_spriteram.op[SPRITE_RAM_PAGE_OFFSET + (int)offs + 2] & 0x01; int flip_y = m_spriteram.op[SPRITE_RAM_PAGE_OFFSET + (int)offs + 2] & 0x02; if (GLOBAL_FLIP_X) { sx = (uint8_t)(238 - sx); flip_x = flip_x == 0 ? 1 : 0; } if (GLOBAL_FLIP_Y) { sy = (uint8_t)(242 - sy); flip_y = flip_y == 0 ? 1 : 0; } get_sprite_gfx_element((uint8_t)which).transpen(bitmap, GLOBAL_FLIP_X ? spritevisibleareaflip : spritevisiblearea, (u32)code, (u32)color, flip_x, flip_y, sx, sy, 0); // draw with wrap around. The horizontal games (eg. sfposeid) need this get_sprite_gfx_element((uint8_t)which).transpen(bitmap, GLOBAL_FLIP_X ? spritevisibleareaflip : spritevisiblearea, (u32)code, (u32)color, flip_x, flip_y, sx - 0x100, sy, 0); } } } }
void copy_layer(bitmap_ind16 bitmap, rectangle cliprect, copy_layer_func_t copy_layer_func, int which, int [] sprites_on, rectangle [] sprite_areas) { if (which == 0) { draw_sprites(bitmap); } else { copy_layer_func(bitmap, cliprect, which - 1, sprites_on, sprite_areas); } }
// ----- core graphics drawing ----- // specific drawgfx implementations for each transparency type /*------------------------------------------------- * opaque - render a gfx element with * no transparency * -------------------------------------------------*/ void opaque(bitmap_ind16 dest, rectangle cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty) { color = colorbase() + granularity() * (color % colors()); code %= elements(); //DECLARE_NO_PRIORITY; bitmap_t priority = drawgfxm_global.drawgfx_dummy_priority_bitmap; //DRAWGFX_CORE(u16, PIXEL_OP_REBASE_OPAQUE, NO_PRIORITY); drawgfxm_global.DRAWGFX_CORE <u16, drawgfxm_global.NO_PRIORITY>(drawgfxm_global.PIXEL_OP_REBASE_OPAQUE, cliprect, destx, desty, width(), height(), flipx, flipy, rowbytes(), get_data, code, dest, priority, color, 0, null, 2); }
void copy_layers(bitmap_ind16 bitmap, rectangle cliprect, copy_layer_func_t copy_layer_func, int [] sprites_on, rectangle [] sprite_areas) { // fill the screen with the background color bitmap.fill((uint32_t)(8 * (m_colorbank.op[1] & 0x07)), cliprect); for (int i = 0; i < 4; i++) { int which = m_draw_order[m_video_priority.op0 & 0x1f, i]; copy_layer(bitmap, cliprect, copy_layer_func, which, sprites_on, sprite_areas); } }
int video_update_common(bitmap_ind16 bitmap, rectangle cliprect, copy_layer_func_t copy_layer_func) { int [] sprites_on = new int[0x20]; // 1 if sprite is active rectangle [] sprite_areas = new rectangle[0x20]; // areas on bitmap (sprite locations) set_pens(); draw_layers(); calculate_sprite_areas(sprites_on, sprite_areas); copy_layers(bitmap, cliprect, copy_layer_func, sprites_on, sprite_areas); //check_sprite_layer_collision() uses drawn bitmaps, so it must me called _AFTER_ draw_layers() check_collision(sprites_on, sprite_areas); return(0); }
/*************************************************************************** * * Display refresh * ***************************************************************************/ protected virtual void draw_sprites(bitmap_ind16 bitmap, rectangle cliprect) { int offs; for (offs = (int)m_spriteram.bytes() - 4; offs >= 0; offs -= 4) { int i; int code; int col; int sx; int sy; int dir; code = (m_spriteram[offs] & 0x7f) + 4 * (m_spriteram[offs + 1] & 0x20) + 2 * (m_spriteram[offs] & 0x80); col = m_spriteram[offs + 1] & 0x0f; sx = m_spriteram[offs + 3] - 0x10 * (m_spriteram[offs + 1] & 0x10); sy = m_spriteram[offs + 2]; dir = 1; if (flip_screen() != 0) { sx = 240 - sx; sy = 240 - sy; dir = -1; } /* handle double / quadruple height */ i = (m_spriteram[offs + 1] & 0xc0) >> 6; if (i == 2) { i = 3; } do { m_gfxdecode.target.digfx.gfx(2).transpen(bitmap, cliprect, (u32)(code + i), (u32)col, (int)flip_screen(), (int)flip_screen(), sx, sy + 16 * i * dir, 15); i--; } while (i >= 0); } }
protected virtual void draw_sprites(bitmap_ind16 bitmap, rectangle cliprect) { ListBytesPointer spriteram = new ListBytesPointer(m_galaga_ram1.target, 0x380); //uint8_t *spriteram = m_galaga_ram1 + 0x380; ListBytesPointer spriteram_2 = new ListBytesPointer(m_galaga_ram2.target, 0x380); //uint8_t *spriteram_2 = m_galaga_ram2 + 0x380; ListBytesPointer spriteram_3 = new ListBytesPointer(m_galaga_ram3.target, 0x380); //uint8_t *spriteram_3 = m_galaga_ram3 + 0x380; int offs; for (offs = 0; offs < 0x80; offs += 2) { int sprite = spriteram[offs] & 0x7f; int color = spriteram[offs + 1] & 0x3f; int sx = spriteram_2[offs + 1] - 40 + 0x100 * (spriteram_3[offs + 1] & 3); int sy = 256 - spriteram_2[offs] + 1; // sprites are buffered and delayed by one scanline int flipx = (spriteram_3[offs] & 0x01); int flipy = (spriteram_3[offs] & 0x02) >> 1; int sizex = (spriteram_3[offs] & 0x04) >> 2; int sizey = (spriteram_3[offs] & 0x08) >> 3; int x, y; sy -= 16 * sizey; sy = (sy & 0xff) - 32; // fix wraparound if (flip_screen() != 0) { flipx ^= 1; flipy ^= 1; } for (y = 0; y <= sizey; y++) { for (x = 0; x <= sizex; x++) { m_gfxdecode.target.digfx.gfx(1).transmask(bitmap, cliprect, (UInt32)(sprite + gfx_offs[y ^ (sizey * flipy), x ^ (sizex * flipx)]), (UInt32)color, flipx, flipy, sx + 16 * x, sy + 16 * y, m_palette.target.palette_interface.transpen_mask(m_gfxdecode.target.digfx.gfx(1), (UInt32)color, 0x0f)); } } } }
protected virtual void draw_sprites(bitmap_ind16 bitmap, rectangle cliprect) { Pointer <uint8_t> spriteram = new Pointer <uint8_t>(m_galaga_ram1.op, 0x380); //uint8_t *spriteram = &m_galaga_ram1[0x380]; Pointer <uint8_t> spriteram_2 = new Pointer <uint8_t>(m_galaga_ram2.op, 0x380); //uint8_t *spriteram_2 = &m_galaga_ram2[0x380]; Pointer <uint8_t> spriteram_3 = new Pointer <uint8_t>(m_galaga_ram3.op, 0x380); //uint8_t *spriteram_3 = &m_galaga_ram3[0x380]; for (int offs = 0; offs < 0x80; offs += 2) { int sprite = spriteram[offs] & 0x7f; int color = spriteram[offs + 1] & 0x3f; int sx = spriteram_2[offs + 1] - 40 + 0x100 * (spriteram_3[offs + 1] & 3); int sy = 256 - spriteram_2[offs] + 1; // sprites are buffered and delayed by one scanline int flipx = (spriteram_3[offs] & 0x01); int flipy = (spriteram_3[offs] & 0x02) >> 1; int sizex = (spriteram_3[offs] & 0x04) >> 2; int sizey = (spriteram_3[offs] & 0x08) >> 3; sy -= 16 * sizey; sy = (sy & 0xff) - 32; // fix wraparound if (flip_screen() != 0) { flipx ^= 1; flipy ^= 1; } for (int y = 0; y <= sizey; y++) { for (int x = 0; x <= sizex; x++) { m_gfxdecode.op0.gfx(1).transmask(bitmap, cliprect, (u32)(sprite + gfx_offs[y ^ (sizey * flipy), x ^ (sizex * flipx)]), (u32)color, flipx, flipy, sx + 16 * x, sy + 16 * y, m_palette.op0.transpen_mask(m_gfxdecode.op0.gfx(1), (u32)color, 0x0f)); } } } }
protected override void video_start() { m_sprite_layer_collbitmap1.allocate(16, 16); for (int i = 0; i < 3; i++) { m_layer_bitmap[i] = new bitmap_ind16(); m_screen.op0.register_screen_bitmap(m_layer_bitmap[i]); m_sprite_layer_collbitmap2[i] = new bitmap_ind16(); m_screen.op0.register_screen_bitmap(m_sprite_layer_collbitmap2[i]); } m_sprite_sprite_collbitmap1.allocate(32, 32); m_sprite_sprite_collbitmap2.allocate(32, 32); m_gfxdecode.op0.gfx(0).set_source(new Pointer <uint8_t>(m_characterram.op)); m_gfxdecode.op0.gfx(1).set_source(new Pointer <uint8_t>(m_characterram.op)); m_gfxdecode.op0.gfx(2).set_source(new Pointer <uint8_t>(m_characterram.op, 0x1800)); m_gfxdecode.op0.gfx(3).set_source(new Pointer <uint8_t>(m_characterram.op, 0x1800)); compute_draw_order(); }
//void transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, UINT32 transpen); //void transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, UINT32 transpen); /*------------------------------------------------- * transmask - render a gfx element * with a multiple transparent pens provided as * a mask * -------------------------------------------------*/ public void transmask(bitmap_ind16 dest, rectangle cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 trans_mask) { // special case 0 mask to opaque if (trans_mask == 0) { opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); return; } // use pen usage to optimize code %= elements(); if (has_pen_usage()) { // fully transparent; do nothing UInt32 usage = pen_usage(code); if ((usage & ~trans_mask) == 0) { return; } // fully opaque; draw as such if ((usage & trans_mask) == 0) { opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); return; } } // render color = colorbase() + granularity() * (color % colors()); //DECLARE_NO_PRIORITY; bitmap_t priority = drawgfxm_global.drawgfx_dummy_priority_bitmap; //DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSMASK, NO_PRIORITY); drawgfxm_global.DRAWGFX_CORE <UInt16, drawgfxm_global.NO_PRIORITY>(drawgfxm_global.PIXEL_OP_REBASE_TRANSMASK, cliprect, destx, desty, width(), height(), flipx, flipy, rowbytes(), get_data, code, dest, priority, color, trans_mask, null, 2); }
void draw_stars(bitmap_ind16 bitmap, rectangle cliprect) { /* draw the stars */ /* $a005 controls the stars ON/OFF */ if (m_videolatch.target.q5_r() == 1) { int star_cntr; int set_a, set_b; /* two sets of stars controlled by these bits */ set_a = m_videolatch.target.q3_r(); set_b = m_videolatch.target.q4_r() | 2; for (star_cntr = 0; star_cntr < MAX_STARS; star_cntr++) { int x; int y; if ((set_a == s_star_seed_tab[star_cntr].set) || (set_b == s_star_seed_tab[star_cntr].set)) { x = (int)((s_star_seed_tab[star_cntr].x + m_stars_scrollx) % 256 + 16); y = (int)((112 + s_star_seed_tab[star_cntr].y + m_stars_scrolly) % 256); /* 112 is a tweak to get alignment about perfect */ if (cliprect.contains(x, y)) { //bitmap.pix16(y, x) = STARS_COLOR_BASE + m_star_seed_tab[ star_cntr ].col; RawBuffer bitmapBuffer; UInt32 bitmapBufferOffset = bitmap.pix16(out bitmapBuffer, y, x); bitmapBuffer.set_uint16((int)bitmapBufferOffset, (UInt16)(STARS_COLOR_BASE + s_star_seed_tab[star_cntr].col)); } } } } }
public static u32 screen_update____empty(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { bitmap.fill(rgb_t.black(), cliprect); return(0); }
//------------------------------------------------- // render_object: Internal processing callback // that renders to the backing bitmap and then // copies the result to the destination. //------------------------------------------------- void render_object(bitmap_ind16 bitmap, rectangle cliprect, Pointer <uint16_t> entry) //void atari_motion_objects_device::render_object(bitmap_ind16 &bitmap, const rectangle &cliprect, const uint16_t *entry) { // select the gfx element and save off key information int rawcode = (int)m_codemask.extract(entry); gfx_element gfx = m_gfxdecode.op0.gfx(m_gfxlookup[rawcode >> 8]); int save_granularity = gfx.granularity(); int save_colorbase = (int)gfx.colorbase(); int save_colors = (int)gfx.colors(); gfx.set_granularity(1); gfx.set_colorbase(0); gfx.set_colors(65536); // extract data from the various words int code = (int)m_codelookup[rawcode]; int color = m_colorlookup[m_colormask.extract(entry)]; int xpos = m_xposmask.extract(entry) + m_xoffset; int ypos = -m_yposmask.extract(entry); int hflip = m_hflipmask.extract(entry); int vflip = m_vflipmask.extract(entry); int width = m_widthmask.extract(entry) + 1; int height = m_heightmask.extract(entry) + 1; int priority = m_prioritymask.extract(entry); // compute the effective color, merging in priority color = (color * save_granularity) | (priority << PRIORITY_SHIFT); color += m_atari_motion_objects_config.m_palettebase; // add in the scroll positions if we're not in absolute coordinates if (m_absolutemask.extract(entry) == 0) { xpos -= (int)m_xscroll; ypos -= (int)m_yscroll; } // adjust for height ypos -= height << m_tileyshift; // handle previous hold bits if (m_next_xpos != 123456) { xpos = (int)m_next_xpos; } m_next_xpos = 123456; // check for the hold bit if (m_neighbormask.extract(entry) != 0) { if (!m_atari_motion_objects_config.m_nextneighbor) { xpos = (int)m_last_xpos + m_tilewidth; } else { m_next_xpos = (uint32_t)(xpos + m_tilewidth); } } m_last_xpos = (uint32_t)xpos; // adjust the final coordinates xpos &= m_bitmapxmask; ypos &= m_bitmapymask; if (xpos >= bitmap.width()) { xpos -= m_bitmapwidth; } if (ypos >= bitmap.height()) { ypos -= m_bitmapheight; } // is this one special? if (m_specialmask.mask() == 0 || m_specialmask.extract(entry) != m_atari_motion_objects_config.m_specialvalue) { // adjust for h flip int xadv = m_tilewidth; if (hflip != 0) { xpos += (width - 1) << m_tilexshift; xadv = -xadv; } // adjust for v flip int yadv = m_tileheight; if (vflip != 0) { ypos += (height - 1) << m_tileyshift; yadv = -yadv; } // standard order is: loop over Y first, then X if (!m_atari_motion_objects_config.m_swapxy) { // loop over the height for (int y = 0, sy = ypos; y < height; y++, sy += yadv) { // clip the Y coordinate if (sy <= cliprect.top() - m_tileheight) { code += width; continue; } else if (sy > cliprect.bottom()) { break; } // loop over the width for (int x = 0, sx = xpos; x < width; x++, sx += xadv, code++) { // clip the X coordinate if (sx <= -cliprect.left() - m_tilewidth || sx > cliprect.right()) { continue; } // draw the sprite gfx.transpen_raw(bitmap, cliprect, (u32)code, (u32)color, hflip, vflip, sx, sy, m_atari_motion_objects_config.m_transpen); mark_dirty(sx, sx + m_tilewidth - 1, sy, sy + m_tileheight - 1); } } } // alternative order is swapped else { // loop over the width for (int x = 0, sx = xpos; x < width; x++, sx += xadv) { // clip the X coordinate if (sx <= cliprect.left() - m_tilewidth) { code += height; continue; } else if (sx > cliprect.right()) { break; } // loop over the height for (int y = 0, sy = ypos; y < height; y++, sy += yadv, code++) { // clip the X coordinate if (sy <= -cliprect.top() - m_tileheight || sy > cliprect.bottom()) { continue; } // draw the sprite gfx.transpen_raw(bitmap, cliprect, (u32)code, (u32)color, hflip, vflip, sx, sy, m_atari_motion_objects_config.m_transpen); mark_dirty(sx, sx + m_tilewidth - 1, sy, sy + m_tileheight - 1); } } } } // restore original gfx information gfx.set_granularity((u16)save_granularity); gfx.set_colorbase((u16)save_colorbase); gfx.set_colors((u32)save_colors); }
void radarscp_draw_background(bitmap_ind16 bitmap, rectangle cliprect) { throw new emu_unimplemented(); }
/*************************************************************************** * Draw the game screen in the given bitmap_ind16. ***************************************************************************/ void draw_sprites(bitmap_ind16 bitmap, rectangle cliprect, uint32_t mask_bank, uint32_t shift_bits) { int offs; int scanline_vf; /* buffering scanline including flip */ int scanline_vfc; /* line buffering scanline including flip - this is the cached scanline_vf */ int scanline; /* current scanline */ int add_y; int add_x; int num_sprt; /* Draw the sprites. There are two pecularities which have been mentioned by * a Donkey Kong II author at CAX 2008: * 1) On real hardware, sprites wrap around from the right to the left instead * of clipping. * 2) On real hardware, there is a limit of 16 sprites per scanline. * Sprites after the 16th (starting from the left) simply don't show. * * 2) is in line with the real hardware which buffers the sprite data * for one scanline. The ram is 64x9 and a sprite takes 4 bytes. * ==> 16 sprites per scanline. * * TODO: 9th bit is not understood right now. * * 1) is due to limitation of signals to 8 bit. * * This is quite different from galaxian. The dkong hardware updates sprites * only once every frame by dma. The number of sprites can not be processed * directly, Thus the preselection. The buffering takes place during the * active phase of the video signal. The scanline is than rendered into the linebuffer * during HBLANK. * * A sprite will be drawn: * a) FlipQ = 1 : (sprite_y + 0xF9 + scanline) & 0xF0 == 0xF0 * b) FlipQ = 0 : (sprite_y + 0xF7 + (scanline ^ 0xFF)) & 0xF0 == 0xF0 * * FlipQ = 1 ("Normal Play"): * * sprite_y = 0x20 * * scanline * 0x10, 0xEF, 0x208, 0x00 * 0x18, 0xE7, 0x200, 0x00 * 0x19, 0xE6, 0x1FF, 0xF0 * 0x20, 0xDF, 0x1F8, 0xF0 * */ scanline_vf = (cliprect.max_y - 1) & 0xFF; scanline_vfc = (cliprect.max_y - 1) & 0xFF; scanline = cliprect.max_y & 0xFF; if (m_flip != 0) { scanline_vf ^= 0xFF; scanline_vfc ^= 0xFF; add_y = 0xF7; add_x = 0xF7; } else { add_y = 0xF9; add_x = 0xF7; } for (offs = m_sprite_bank << 9, num_sprt = 0; (num_sprt < 16) && (offs < (m_sprite_bank << 9) + 0x200) /* sprite_ram_size */; offs += 4) { int y = m_sprite_ram[offs]; int do_draw = (((y + add_y + 1 + scanline_vf) & 0xF0) == 0xF0) ? 1 : 0; if (do_draw != 0) { /* sprite_ram[offs + 2] & 0x40 is used by Donkey Kong 3 only */ /* sprite_ram[offs + 2] & 0x30 don't seem to be used (they are */ /* probably not part of the color code, since Mario Bros, which */ /* has similar hardware, uses a memory mapped port to change */ /* palette bank, so it's limited to 16 color codes) */ int code = (int)((m_sprite_ram[offs + 1] & 0x7f) + ((m_sprite_ram[offs + 2] & mask_bank) << (int)shift_bits)); int color = (m_sprite_ram[offs + 2] & 0x0f) + 16 * m_palette_bank; int flipx = m_sprite_ram[offs + 2] & 0x80; int flipy = m_sprite_ram[offs + 1] & 0x80; /* On the real board, the x and y are read inverted after the first * buffer stage. This due to the fact that the 82S09 delivers complements * of stored data on read! */ int x = (m_sprite_ram[offs + 3] + add_x + 1) & 0xFF; if (m_flip != 0) { x = (x ^ 0xFF) - 15; flipx = (flipx == 0) ? 1 : 0; } y = scanline - ((y + add_y + 1 + scanline_vfc) & 0x0F); m_gfxdecode.target.digfx.gfx(1).transpen(bitmap, cliprect, (u32)code, (u32)color, flipx, flipy, x, y, 0); // wraparound m_gfxdecode.target.digfx.gfx(1).transpen(bitmap, cliprect, (u32)code, (u32)color, flipx, flipy, m_flip != 0 ? x + 256 : x - 256, y, 0); m_gfxdecode.target.digfx.gfx(1).transpen(bitmap, cliprect, (u32)code, (u32)color, flipx, flipy, x, y - 256, 0); num_sprt++; } } }
} //bitmap_ind16(uint16_t *base, int width, int height, int rowpixels) : bitmap16_t(k_bitmap_format, base, width, height, rowpixels) { } public bitmap_ind16(bitmap_ind16 source, rectangle subrect) : base(k_bitmap_format, source, subrect) { }
public uint32_t screen_update_pacman(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { if (m_bgpriority != 0) { bitmap.fill(0, cliprect); } else { m_bg_tilemap.draw(screen, bitmap, cliprect, tilemap_global.TILEMAP_DRAW_OPAQUE, 0); } if (m_spriteram != null) { ListBytesPointer spriteram = m_spriteram.target; //uint8_t *spriteram = m_spriteram; ListBytesPointer spriteram_2 = m_spriteram2.target; //uint8_t *spriteram_2 = m_spriteram2; int offs; rectangle spriteclip = new rectangle(2 * 8, 34 * 8 - 1, 0 * 8, 28 * 8 - 1); spriteclip.intersection(cliprect); // spriteclip &= cliprect; /* Draw the sprites. Note that it is important to draw them exactly in this */ /* order, to have the correct priorities. */ for (offs = (int)m_spriteram.bytes() - 2; offs > 2 * 2; offs -= 2) { int color; int sx; int sy; byte fx; byte fy; if (m_inv_spr != 0) { sx = spriteram_2[offs + 1]; sy = 240 - (spriteram_2[offs]); } else { sx = 272 - spriteram_2[offs + 1]; sy = spriteram_2[offs] - 31; } fx = (byte)((spriteram[offs] & 1) ^ m_inv_spr); fy = (byte)((spriteram[offs] & 2) ^ ((m_inv_spr) << 1)); color = (spriteram[offs + 1] & 0x1f) | (m_colortablebank << 5) | (m_palettebank << 6); m_gfxdecode.target.digfx.gfx(1).transmask(bitmap, spriteclip, (UInt32)((spriteram[offs] >> 2) | (m_spritebank << 6)), (UInt32)color, fx, fy, sx, sy, m_palette.target.palette_interface.transpen_mask(m_gfxdecode.target.digfx.gfx(1), (UInt32)color & 0x3f, 0)); /* also plot the sprite with wraparound (tunnel in Crush Roller) */ m_gfxdecode.target.digfx.gfx(1).transmask(bitmap, spriteclip, (UInt32)((spriteram[offs] >> 2) | (m_spritebank << 6)), (UInt32)color, fx, fy, sx - 256, sy, m_palette.target.palette_interface.transpen_mask(m_gfxdecode.target.digfx.gfx(1), (UInt32)color & 0x3f, 0)); } /* In the Pac Man based games (NOT Pengo) the first two sprites must be offset */ /* one pixel to the left to get a more correct placement */ for (offs = 2 * 2; offs >= 0; offs -= 2) { int color; int sx; int sy; byte fx; byte fy; if (m_inv_spr != 0) { sx = spriteram_2[offs + 1]; sy = 240 - (spriteram_2[offs]); } else { sx = 272 - spriteram_2[offs + 1]; sy = spriteram_2[offs] - 31; } color = (spriteram[offs + 1] & 0x1f) | (m_colortablebank << 5) | (m_palettebank << 6); fx = (byte)((spriteram[offs] & 1) ^ m_inv_spr); fy = (byte)((spriteram[offs] & 2) ^ ((m_inv_spr) << 1)); m_gfxdecode.target.digfx.gfx(1).transmask(bitmap, spriteclip, (UInt32)((spriteram[offs] >> 2) | (m_spritebank << 6)), (UInt32)color, fx, fy, sx, sy + m_xoffsethack, m_palette.target.palette_interface.transpen_mask(m_gfxdecode.target.digfx.gfx(1), (UInt32)color & 0x3f, 0)); /* also plot the sprite with wraparound (tunnel in Crush Roller) */ m_gfxdecode.target.digfx.gfx(1).transmask(bitmap, spriteclip, (UInt32)((spriteram[offs] >> 2) | (m_spritebank << 6)), (UInt32)color, fx, fy, sx - 256, sy + m_xoffsethack, m_palette.target.palette_interface.transpen_mask(m_gfxdecode.target.digfx.gfx(1), (UInt32)color & 0x3f, 0)); } } if (m_bgpriority != 0) { m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); } return(0); }
protected override void draw_sprites(bitmap_ind16 bitmap, rectangle cliprect) { Pointer <uint8_t> spriteram = new Pointer <uint8_t>(m_xevious_sr3.op, 0x780); //uint8_t *spriteram = m_xevious_sr3 + 0x780; Pointer <uint8_t> spriteram_2 = new Pointer <uint8_t>(m_xevious_sr1.op, 0x780); //uint8_t *spriteram_2 = m_xevious_sr1 + 0x780; Pointer <uint8_t> spriteram_3 = new Pointer <uint8_t>(m_xevious_sr2.op, 0x780); //uint8_t *spriteram_3 = m_xevious_sr2 + 0x780; int offs; int sx; int sy; for (offs = 0; offs < 0x80; offs += 2) { if ((spriteram[offs + 1] & 0x40) == 0) /* I'm not sure about this one */ { int bank; int code; int color; int flipx; int flipy; uint32_t transmask; if ((spriteram_3[offs] & 0x80) != 0) { bank = 2; code = (spriteram[offs] & 0x3f) + 0x100; } else { bank = 2; code = spriteram[offs]; } color = spriteram[offs + 1] & 0x7f; flipx = spriteram_3[offs] & 4; flipy = spriteram_3[offs] & 8; sx = spriteram_2[offs + 1] - 40 + 0x100 * (spriteram_3[offs + 1] & 1); sy = 28 * 8 - spriteram_2[offs] - 1; if (flip_screen() != 0) { flipx = flipx == 0 ? 1 : 0; flipy = flipy == 0 ? 1 : 0; } transmask = m_palette.op0.transpen_mask(m_gfxdecode.op0.gfx(bank), (u32)color, 0x80); if ((spriteram_3[offs] & 2) != 0) /* double height (?) */ { if ((spriteram_3[offs] & 1) != 0) /* double width, double height */ { code &= ~3; m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)(code + 3), (u32)color, flipx, flipy, (flipx != 0) ? sx : sx + 16, (flipy != 0) ? sy - 16 : sy, transmask); m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)(code + 1), (u32)color, flipx, flipy, (flipx != 0) ? sx : sx + 16, (flipy != 0) ? sy : sy - 16, transmask); } code &= ~2; m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)(code + 2), (u32)color, flipx, flipy, (flipx != 0) ? sx + 16 : sx, (flipy != 0) ? sy - 16 : sy, transmask); m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)code, (u32)color, flipx, flipy, (flipx != 0) ? sx + 16 : sx, (flipy != 0) ? sy : sy - 16, transmask); } else if ((spriteram_3[offs] & 1) != 0) /* double width */ { code &= ~1; m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)code, (u32)color, flipx, flipy, (flipx != 0) ? sx + 16 : sx, (flipy != 0) ? sy - 16 : sy, transmask); m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)(code + 1), (u32)color, flipx, flipy, (flipx != 0) ? sx : sx + 16, (flipy != 0) ? sy - 16 : sy, transmask); } else /* normal */ { m_gfxdecode.op0.gfx(bank).transmask(bitmap, cliprect, (u32)code, (u32)color, flipx, flipy, sx, sy, transmask); } } } }
u32 screen_update(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { bitmap.fill(rgb_t.black(), cliprect); return(0); }
u32 screen_update(screen_device screen, bitmap_ind16 bitmap, rectangle cliprect) { return((u32)video_update_common(bitmap, cliprect, copy_layer)); }