static void draw_testpat(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { // Test pattern Grey scale const int stripes = 255; //auto va(screen.visible_area()); var va = cliprect; for (int i = 0; i < stripes; i++) { int l = va.left() + (i * va.width() / stripes); int w = (va.left() + (i + 1) * va.width() / stripes) - l; int v = (255 * i) / stripes; bitmap.plot_box(l, va.top() + 20, w, va.height() / 2 - 20, new rgb_t(0xff, (uint8_t)v, (uint8_t)v, (uint8_t)v)); } { int l = va.left() + va.width() / 4; int w = va.width() / 4; int t = va.top() + va.height() / 2; int h = va.height() / 2; // 50% Test pattern for (int i = t; i < t + h; i += 2) { bitmap.plot_box(l, i, w, i, new rgb_t(0xff, 0xff, 0xff, 0xff)); bitmap.plot_box(l, i + 1, w, i + 1, new rgb_t(0xff, 0, 0, 0)); } l += va.width() / 4; bitmap.plot_box(l, t, w, h, new rgb_t(0xff, 0xc3, 0xc3, 0xc3)); // 195 } }
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); }
/************************************* * * Bullet rendering * *************************************/ void galaxian_draw_pixel(bitmap_rgb32 bitmap, rectangle cliprect, int y, int x, rgb_t color) { if (y >= cliprect.min_y && y <= cliprect.max_y) { x *= GALAXIAN_XSCALE; x += GALAXIAN_H0START; if (x >= cliprect.min_x && x <= cliprect.max_x) { //bitmap.pix32(y, x) = color; RawBuffer bitmapBuf; UInt32 bitmapBufOffset = bitmap.pix32(out bitmapBuf, y, x); bitmapBuf.set_uint32((int)bitmapBufOffset, color); } x++; if (x >= cliprect.min_x && x <= cliprect.max_x) { //bitmap.pix32(y, x) = color; RawBuffer bitmapBuf; UInt32 bitmapBufOffset = bitmap.pix32(out bitmapBuf, y, x); bitmapBuf.set_uint32((int)bitmapBufOffset, color); } x++; if (x >= cliprect.min_x && x <= cliprect.max_x) { //bitmap.pix32(y, x) = color; RawBuffer bitmapBuf; UInt32 bitmapBufOffset = bitmap.pix32(out bitmapBuf, y, x); bitmapBuf.set_uint32((int)bitmapBufOffset, color); } } }
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); }
/************************************* * * 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); }
/************************************* * * 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); }
// construction/destruction public sparse_dirty_bitmap(int granularity = 3) { m_width = 0; m_height = 0; m_granularity = granularity; m_rect_list_bounds = new rectangle(0, -1, 0, -1); }
void galaxian_draw_background(bitmap_rgb32 bitmap, rectangle cliprect) { /* erase the background to black first */ bitmap.fill(rgb_t.black(), cliprect); galaxian_draw_stars(bitmap, cliprect, 256); }
// drawing public void draw_async(rectangle cliprect, bool clearit = true) { // if the cliprect exceeds our current bitmap dimensions, expand if (cliprect.right() >= m_bitmap.width() || cliprect.bottom() >= m_bitmap.height()) { int new_width = std.max(cliprect.right() + 1, m_bitmap.width()); int new_height = std.max(cliprect.bottom() + 1, m_bitmap.height()); m_bitmap.resize(new_width, new_height, BITMAP_SLOP, BITMAP_SLOP); m_dirty.resize(new_width, new_height); } // clear out the region if (clearit) { clear(cliprect); } // wrap the bitmap, adjusting for x/y origins _BitmapType wrapped = m_bitmapCreator(m_bitmap.pix(0) - m_xorigin - m_yorigin * m_bitmap.rowpixels(), m_xorigin + cliprect.right() + 1, m_yorigin + cliprect.bottom() + 1, m_bitmap.rowpixels()); //_BitmapType wrapped(&m_bitmap.pix(0) - m_xorigin - m_yorigin * m_bitmap.rowpixels(), m_xorigin + cliprect.right() + 1, m_yorigin + cliprect.bottom() + 1, m_bitmap.rowpixels()); // compute adjusted cliprect in source space rectangle adjusted = cliprect; adjusted.offset(m_xorigin, m_yorigin); // render draw(wrapped, adjusted); }
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); }
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); }
} //void set_spriteram(_SpriteRAMType *base, uint32_t bytes) { assert(base != nullptr && bytes != 0); m_spriteram = base; m_spriteram_bytes = bytes; m_buffer.resize(m_spriteram_bytes / sizeof(_SpriteRAMType)); } //void set_origin(int32_t xorigin = 0, int32_t yorigin = 0) { m_xorigin = xorigin; m_yorigin = yorigin; } //void set_xorigin(int32_t xorigin) { m_xorigin = xorigin; } //void set_yorigin(int32_t yorigin) { m_yorigin = yorigin; } // buffering //void copy_to_buffer() { assert(m_spriteram != nullptr); memcpy(m_buffer, m_spriteram, m_spriteram_bytes); } // clearing //void clear() { clear(m_bitmap.cliprect()); } void clear(rectangle cliprect) { for (sparse_dirty_rect rect = m_dirty.first_dirty_rect(cliprect); rect != null; rect = rect.next()) { m_bitmap.fill(~0U, rect.m_rect); } m_dirty.clean(cliprect); }
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); } } } }
/************************************* * * Sprite rendering * *************************************/ void sprites_draw(bitmap_rgb32 bitmap, rectangle cliprect, ListBytesPointer spritebase) //, uint8_t *spritebase) { rectangle clip = new rectangle(cliprect); int sprnum; /* the existence of +1 (sprite vs tile layer) is supported by a LOT of games */ const int hoffset = 1; /* 16 of the 256 pixels of the sprites are hard-clipped at the line buffer */ /* according to the schematics, it should be the first 16 pixels */ clip.min_x = Math.Max(clip.min_x, ((m_flipscreen_x == 0) ? 1 : 0) * (16 + hoffset) * GALAXIAN_XSCALE); clip.max_x = Math.Min(clip.max_x, (256 - m_flipscreen_x * (16 + hoffset)) * GALAXIAN_XSCALE - 1); /* The line buffer is only written if it contains a '0' currently; */ /* it is cleared during the visible area, and populated during HBLANK */ /* To simulate this, we render backwards so that lower numbered sprites */ /* have priority over higher numbered sprites. */ for (sprnum = 7; sprnum >= 0; sprnum--) { ListBytesPointer base_ = new ListBytesPointer(spritebase, sprnum * 4); //const uint8_t *base = &spritebase[sprnum * 4]; /* Frogger: top and bottom 4 bits swapped entering the adder */ byte base0 = m_frogger_adjust != 0 ? (byte)((base_[0] >> 4) | (base_[0] << 4)) : base_[0]; /* the first three sprites match against y-1 */ byte sy = (byte)(240 - (base0 - ((sprnum < 3) ? 1 : 0))); UInt16 code = (UInt16)(base_[1] & 0x3f); byte flipx = (byte)(base_[1] & 0x40); byte flipy = (byte)(base_[1] & 0x80); byte color = (byte)(base_[2] & 7); byte sx = (byte)(base_[3] + hoffset); /* extend the sprite information */ if (m_extend_sprite_info_ptr != null) { m_extend_sprite_info_ptr(base_, ref sx, ref sy, ref flipx, ref flipy, ref code, ref color); } /* apply flipscreen in X direction */ if (m_flipscreen_x != 0) { sx = (byte)(240 - sx); flipx = flipx == 0 ? (byte)1 : (byte)0; } /* apply flipscreen in Y direction */ if (m_flipscreen_y != 0) { sy = (byte)(240 - sy); flipy = flipy == 0 ? (byte)1 : (byte)0; } /* draw */ m_gfxdecode.target.digfx.gfx(1).transpen(bitmap, clip, code, color, flipx, flipy, GALAXIAN_H0START + GALAXIAN_XSCALE * sx, sy, 0); } }
/************************************* * * Sprite rendering * *************************************/ void sprites_draw(bitmap_rgb32 bitmap, rectangle cliprect, Pointer <uint8_t> spritebase) //void sprites_draw(bitmap_rgb32 &bitmap, const rectangle &cliprect, const uint8_t *spritebase) { rectangle clip = cliprect; int sprnum; /* the existence of +1 (sprite vs tile layer) is supported by a LOT of games */ const int hoffset = 1; /* 16 of the 256 pixels of the sprites are hard-clipped at the line buffer */ /* according to the schematics, it should be the first 16 pixels */ clip.min_x = std.max(clip.min_x, ((m_flipscreen_x == 0) ? 1 : 0) * (m_leftspriteclip + hoffset) * m_x_scale); clip.max_x = std.min(clip.max_x, (256 - m_flipscreen_x * (16 + hoffset)) * m_x_scale - 1); /* The line buffer is only written if it contains a '0' currently; */ /* it is cleared during the visible area, and populated during HBLANK */ /* To simulate this, we render backwards so that lower numbered sprites */ /* have priority over higher numbered sprites. */ for (sprnum = 7; sprnum >= 0; sprnum--) { Pointer <uint8_t> base_ = new Pointer <uint8_t>(spritebase, sprnum * 4); //const uint8_t *base = &spritebase[sprnum * 4]; /* Frogger: top and bottom 4 bits swapped entering the adder */ uint8_t base0 = m_frogger_adjust ? (uint8_t)((base_[0] >> 4) | (base_[0] << 4)) : base_[0]; /* the first three sprites match against y-1 (seems other way around for sfx/monsterz) */ uint8_t sy = (uint8_t)(240 - (base0 - (m_sfx_adjust ? ((sprnum >= 3) ? 1 : 0) : ((sprnum < 3) ? 1 : 0)))); uint16_t code = (uint16_t)(base_[1] & 0x3f); uint8_t flipx = (uint8_t)(base_[1] & 0x40); uint8_t flipy = (uint8_t)(base_[1] & 0x80); uint8_t color = (uint8_t)(base_[2] & 7); uint8_t sx = (uint8_t)(base_[3] + hoffset); /* extend the sprite information */ m_extend_sprite_info_ptr(base_, ref sx, ref sy, ref flipx, ref flipy, ref code, ref color); /* apply flipscreen in X direction */ if (m_flipscreen_x != 0) { sx = (uint8_t)(240 - sx); flipx = flipx == 0 ? (uint8_t)1 : (uint8_t)0; } /* apply flipscreen in Y direction */ if (m_flipscreen_y != 0) { sy = (uint8_t)(240 - sy); flipy = flipy == 0 ? (uint8_t)1 : (uint8_t)0; } /* draw */ m_gfxdecode.op0.gfx(1).transpen(bitmap, clip, code, color, flipx, flipy, m_h0_start + m_x_scale * sx, sy, 0); } }
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); }
//------------------------------------------------- // dirty -- dirty a region //------------------------------------------------- public void dirty(int32_t left, int32_t right, int32_t top, int32_t bottom) { // compute a rectangle in dirty space, and fill it with 1 rectangle rect = new rectangle(left >> m_granularity, right >> m_granularity, top >> m_granularity, bottom >> m_granularity); m_bitmap.fill(1, rect); // invalidate existing rect list invalidate_rect_list(); }
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); } } } }
// ----- 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); }
public sparse_dirty_bitmap(int width, int height, int granularity = 3) { m_width = 0; m_height = 0; m_granularity = granularity; m_rect_list_bounds = new rectangle(0, -1, 0, -1); // resize to the specified width/height resize(width, height); }
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); } }
/************************************* * * Sprites rendering * *************************************/ void draw_sprites(bitmap_rgb32 bitmap, rectangle cliprect, int initoffs) { int offs; /* draw the sprites */ for (offs = initoffs; offs >= (initoffs & 0xc0); offs -= 4) { int sy = 257 - m_spriteram.op[offs]; int color = m_spriteram.op[offs + 1] & 0x3f; int flipx = m_spriteram.op[offs + 1] & 0x40; int flipy = m_spriteram.op[offs + 1] & 0x80; int code = m_spriteram.op[offs + 2]; int sx = m_spriteram.op[offs + 3]; /* sprites from offsets $00-$7F are processed in the upper half of the frame */ /* sprites from offsets $80-$FF are processed in the lower half of the frame */ rectangle clip = cliprect; if (!((offs & 0x80) != 0)) { clip.min_y = 0; clip.max_y = 127; } else { clip.min_y = 128; clip.max_y = 255; } /* adjust for flipping */ if (flip_screen() != 0) { int temp = clip.min_y; clip.min_y = 255 - clip.max_y; clip.max_y = 255 - temp; flipx = (!(flipx != 0)) ? 1 : 0; flipy = (!(flipy != 0)) ? 1 : 0; sx = 238 - sx; sy = 282 - sy; } sx += 129; /* in theory anyways; in practice, some of the molecule-looking guys get clipped */ #if SPLIT_SPRITES sect_rect(&clip, cliprect); #else clip = cliprect; #endif m_sp_gfxdecode.op0.gfx(0).transmask(bitmap, clip, (u32)code, (u32)color, flipx, flipy, sx, sy, m_sp_palette.op0.transpen_mask(m_sp_gfxdecode.op0.gfx(0), (u32)color, 0)); } }
/************************************* * * Background rendering * *************************************/ void draw_background(bitmap_rgb32 bitmap, rectangle cliprect, int xpos, int ypos, int image) { rectangle rect; rectangle visarea = m_screen.op0.visible_area(); var paldata = m_bg_palette.op0.pens(); if (flip_screen() != 0) { xpos = 264 - xpos; ypos = 264 - ypos - BGHEIGHT; } xpos += 124; /* this may not be correct */ ypos += 16; m_bg_gfxdecode.op0.gfx(image).transpen(bitmap, cliprect, 0, 0, (int)flip_screen(), (int)flip_screen(), xpos, ypos, 0); m_bg_gfxdecode.op0.gfx(image).transpen(bitmap, cliprect, 0, 0, (int)flip_screen(), (int)flip_screen(), xpos - 256, ypos, 0); // create a solid fill below the 64 pixel high bg images if (m_do_bg_fills) { rect.min_x = visarea.min_x; rect.max_x = visarea.max_x; if (flip_screen() != 0) { rect.min_y = ypos - BGHEIGHT; rect.max_y = ypos - 1; } else { rect.min_y = ypos + BGHEIGHT; rect.max_y = ypos + 2 * BGHEIGHT - 1; } bitmap.fill(paldata[m_bg_gfxdecode.op0.gfx(image).colorbase() + 3], rect); } }
public void vsync_end_cb(double refresh_time) { var expected_frame_period = m_monitor.clock_period() * m_monitor.vtotal() * m_monitor.htotal(); var refresh_limited = std.min(4.0 * expected_frame_period, std.max(refresh_time, 0.25 * expected_frame_period)); rectangle visarea = new rectangle(m_monitor.minh(), m_monitor.maxh(), m_monitor.minv(), m_monitor.maxv()); m_divideo.screen().configure(m_monitor.htotal_scaled(), m_monitor.vtotal(), visarea, DOUBLE_TO_ATTOSECONDS(refresh_limited)); m_divideo.screen().reset_origin(m_state.m_last_y - (m_monitor.vsync_width() + m_monitor.vbackporch_width()), 0); }
protected override void device_start() { base.device_start(); rectangle visarea = m_vector.op0.m_divideo.screen().visible_area(); m_xmin = visarea.min_x; m_ymin = visarea.min_y; m_xcenter = 512; m_ycenter = 512; }
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); } }
void galaxian_draw_bullet(bitmap_rgb32 bitmap, rectangle cliprect, int offs, int x, int y) { /* * Both "shells" and "missiles" begin displaying when the horizontal counter * reaches $FC, and they stop displaying when it reaches $00, resulting in * 4-pixel-long shots. The first 7 entries are called "shells" and render as * white; the final entry is called a "missile" and renders as yellow. */ x -= 4; galaxian_draw_pixel(bitmap, cliprect, y, x++, m_bullet_color[offs]); galaxian_draw_pixel(bitmap, cliprect, y, x++, m_bullet_color[offs]); galaxian_draw_pixel(bitmap, cliprect, y, x++, m_bullet_color[offs]); galaxian_draw_pixel(bitmap, cliprect, y, x++, m_bullet_color[offs]); }
/************************************* * * Bullets rendering * *************************************/ void bullets_draw(bitmap_rgb32 bitmap, rectangle cliprect, ListBytesPointer base_) //, const uint8_t *base) { int y; /* iterate over scanlines */ for (y = cliprect.min_y; y <= cliprect.max_y; y++) { byte shell = 0xff; byte missile = 0xff; byte effy; int which; /* the first 3 entries match Y-1 */ effy = m_flipscreen_y != 0 ? (byte)((y - 1) ^ 255) : (byte)(y - 1); for (which = 0; which < 3; which++) { if ((byte)(base_[which * 4 + 1] + effy) == 0xff) { shell = (byte)which; } } /* remaining entries match Y */ effy = m_flipscreen_y != 0 ? (byte)(y ^ 255) : (byte)y; for (which = 3; which < 8; which++) { if ((byte)(base_[which * 4 + 1] + effy) == 0xff) { if (which != 7) { shell = (byte)which; } else { missile = (byte)which; } } } /* draw the shell */ if (shell != 0xff) { m_draw_bullet_ptr(bitmap, cliprect, shell, 255 - base_[shell * 4 + 3], y); } if (missile != 0xff) { m_draw_bullet_ptr(bitmap, cliprect, missile, 255 - base_[missile * 4 + 3], y); } } }
void opaque(bitmap_rgb32 dest, rectangle cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty) { pen_t paldata = m_palette.pens()[colorbase() + granularity() * (color % colors())]; //m_palette.pens() + colorbase() + granularity() * (color % colors()); code %= elements(); //DECLARE_NO_PRIORITY; bitmap_t priority = drawgfxm_global.drawgfx_dummy_priority_bitmap; throw new emu_unimplemented(); #if false DRAWGFX_CORE(u32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); #endif }