/************************************* * * 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); } } }
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); }
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 } }
/************************************* * * 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); } }
/************************************* * * Draw a row of stars * *************************************/ void stars_draw_row(bitmap_rgb32 bitmap, int maxx, int y, uint32_t star_offs, uint8_t starmask) { int x; /* ensure our star offset is valid */ star_offs %= STAR_RNG_PERIOD; /* iterate over the specified number of 6MHz pixels */ for (x = 0; x < maxx; x++) { /* stars are suppressed unless V1 ^ H8 == 1 */ int enable_star = (y ^ (x >> 3)) & 1; uint8_t star; /* * The RNG clock is the master clock (18MHz) ANDed with the pixel clock (6MHz). * The divide-by-3 circuit that produces the pixel clock generates a square wave * with a 2/3 duty cycle, so the result of the AND generates a clock like this: * _ _ _ _ _ _ _ _ * MASTER: _| |_| |_| |_| |_| |_| |_| |_| | * _______ _______ ______ * PIXEL: _| |___| |___| * _ _ _ _ _ _ * RNG: _| |_| |_____| |_| |_____| |_| | * * Thus for each pixel, there are 3 master clocks and 2 RNG clocks, and the RNG * is clocked asymmetrically. To simulate this, we expand the horizontal screen * size by 3 and handle the first RNG clock with one pixel and the second RNG * clock with two pixels. */ /* first RNG clock: one pixel */ star = m_stars[star_offs++]; if (star_offs >= STAR_RNG_PERIOD) { star_offs = 0; } if (enable_star != 0 && (star & 0x80) != 0 && (star & starmask) != 0) { bitmap.pix(y, m_x_scale * x + 0)[0] = m_star_color[star & 0x3f]; } /* second RNG clock: two pixels */ star = m_stars[star_offs++]; if (star_offs >= STAR_RNG_PERIOD) { star_offs = 0; } if (enable_star != 0 && (star & 0x80) != 0 && (star & starmask) != 0) { bitmap.pix(y, m_x_scale * x + 1)[0] = m_star_color[star & 0x3f]; bitmap.pix(y, m_x_scale * x + 2)[0] = m_star_color[star & 0x3f]; } } }
/************************************* * * 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); } }
/************************************* * * 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 }
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]); }
/************************************* * * Background rendering * *************************************/ void galaxian_draw_stars(bitmap_rgb32 bitmap, rectangle cliprect, int maxx) { /* update the star origin to the current frame */ stars_update_origin(); /* render stars if enabled */ if (m_stars_enabled != 0) { int y; /* iterate over scanlines */ for (y = cliprect.min_y; y <= cliprect.max_y; y++) { uint32_t star_offs = m_star_rng_origin + (uint32_t)y * 512; stars_draw_row(bitmap, maxx, y, star_offs, 0xff); } } }
/************************************* * * Background rendering * *************************************/ void galaxian_draw_background(bitmap_rgb32 bitmap, rectangle cliprect) { /* erase the background to black first */ bitmap.fill(rgb_t.black(), cliprect); /* update the star origin to the current frame */ stars_update_origin(); /* render stars if enabled */ if (m_stars_enabled != 0) { int y; /* iterate over scanlines */ for (y = cliprect.min_y; y <= cliprect.max_y; y++) { UInt32 star_offs = m_star_rng_origin + (UInt32)y * 512; stars_draw_row(bitmap, 256, y, star_offs, 0xff); } } }
public void transmask(bitmap_rgb32 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 pen_t paldata = m_palette.pens()[colorbase() + granularity() * (color % colors())]; //DECLARE_NO_PRIORITY; bitmap_t priority = drawgfxm_global.drawgfx_dummy_priority_bitmap; throw new emu_unimplemented(); #if false DRAWGFX_CORE(UInt32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY); #endif }
/************************************* * * Common video update * *************************************/ uint32_t screen_update_galaxian(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { /* draw the background layer (including stars) */ m_draw_background_ptr(bitmap, cliprect); /* draw the tilemap characters over top */ m_bg_tilemap.draw(screen, bitmap, cliprect, 0, 0); /* render the sprites next. Some custom pcbs (eg. zigzag, fantastc) have more than one sprite generator (ideally, this should be rendered in parallel) */ for (int i = 0; i < m_numspritegens; i++) { sprites_draw(bitmap, cliprect, new Pointer <uint8_t>(m_spriteram.op, m_sprites_base + i * 0x20)); } /* if we have bullets to draw, render them following */ if (m_draw_bullet_ptr != null) { bullets_draw(bitmap, cliprect, new Pointer <uint8_t>(m_spriteram.op, m_bullets_base)); } return(0); }
public void transpen(bitmap_rgb32 dest, rectangle cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 trans_pen) { // special case invalid pens to opaque if (trans_pen > 0xff) { 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 & ~(1 << (int)trans_pen)) == 0) { return; } // fully opaque; draw as such if ((usage & (1 << (int)trans_pen)) == 0) { opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); return; } } // render ListPointer <rgb_t> paldata = new ListPointer <rgb_t>(m_palette.pens(), (int)(colorbase() + granularity() * (color % colors()))); //const pen_t *paldata = m_palette.pens() + colorbase() + granularity() * (color % colors()); //DECLARE_NO_PRIORITY; bitmap_t priority = drawgfxm_global.drawgfx_dummy_priority_bitmap; //DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY); drawgfxm_global.DRAWGFX_CORE <u32, drawgfxm_global.NO_PRIORITY>(drawgfxm_global.PIXEL_OP_REMAP_TRANSPEN, cliprect, destx, desty, width(), height(), flipx, flipy, rowbytes(), get_data, code, dest, priority, color, trans_pen, paldata, 2); }
/************************************* * * Video render * *************************************/ u32 screen_update_m52(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { int offs; var paldata = m_sp_palette.op0.pens(); bitmap.fill(paldata[0], cliprect); if (!((m_bgcontrol & 0x20) != 0)) { if (!((m_bgcontrol & 0x10) != 0)) { draw_background(bitmap, cliprect, m_bg2xpos, m_bg2ypos, 0); /* distant mountains */ } // only one of these be drawn at once (they share the same scroll register) (alpha1v leaves everything enabled) if (!((m_bgcontrol & 0x02) != 0)) { draw_background(bitmap, cliprect, m_bg1xpos, m_bg1ypos, 1); /* hills */ } else if (!((m_bgcontrol & 0x04) != 0)) { draw_background(bitmap, cliprect, m_bg1xpos, m_bg1ypos, 2); /* cityscape */ } } m_tx_tilemap.set_flip((flip_screen() != 0) ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0); m_tx_tilemap.draw(screen, bitmap, cliprect, 0, 0); /* draw the sprites */ for (offs = 0x3c; offs <= m_spritelimit; offs += 0x40) { draw_sprites(bitmap, cliprect, offs); } 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.pix(y, x)[0] = color; } x++; if (x >= cliprect.min_x && x <= cliprect.max_x) { bitmap.pix(y, x)[0] = color; } x++; if (x >= cliprect.min_x && x <= cliprect.max_x) { bitmap.pix(y, x)[0] = color; } } }
void background_draw_colorsplit(bitmap_rgb32 bitmap, rectangle cliprect, rgb_t color, int split, int split_flipped) { /* horizontal bgcolor split */ if (m_flipscreen_x != 0) { rectangle draw = cliprect; draw.max_x = std.min(draw.max_x, split_flipped * m_x_scale - 1); if (draw.min_x <= draw.max_x) { bitmap.fill(rgb_t.black(), draw); } draw = cliprect; draw.min_x = std.max(draw.min_x, split_flipped * m_x_scale); if (draw.min_x <= draw.max_x) { bitmap.fill(color, draw); } } else { rectangle draw = cliprect; draw.max_x = std.min(draw.max_x, split * m_x_scale - 1); if (draw.min_x <= draw.max_x) { bitmap.fill(color, draw); } draw = cliprect; draw.min_x = std.max(draw.min_x, split * m_x_scale); if (draw.min_x <= draw.max_x) { bitmap.fill(rgb_t.black(), draw); } } }
public uint32_t screen_update(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { uint32_t flags = PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD) | PRIMFLAG_VECTOR(1); rectangle visarea = screen.visible_area(); float xscale = 1.0f / (65536 * visarea.width()); float yscale = 1.0f / (65536 * visarea.height()); float xoffs = (float)visarea.min_x; float yoffs = (float)visarea.min_y; int curpointIdx = 0; //point *curpoint; int lastx = 0; int lasty = 0; curpointIdx = 0; //curpoint = m_vector_list.get(); var curpoint = m_vector_list; screen.container().empty(); screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, new rgb_t(0xff, 0x00, 0x00, 0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTORBUF(1)); for (int i = 0; i < m_vector_index; i++) { render_bounds coords = new render_bounds(); float intensity = (float)curpoint[curpointIdx].intensity / 255.0f; //float intensity = (float)curpoint->intensity / 255.0f; float intensity_weight = normalized_sigmoid(intensity, vector_options.s_beam_intensity_weight); // check for static intensity float beam_width = m_min_intensity == m_max_intensity ? vector_options.s_beam_width_min : vector_options.s_beam_width_min + intensity_weight * (vector_options.s_beam_width_max - vector_options.s_beam_width_min); // normalize width beam_width *= 1.0f / (float)VECTOR_WIDTH_DENOM; // apply point scale for points if (lastx == curpoint[curpointIdx].x && lasty == curpoint[curpointIdx].y) //if (lastx == curpoint->x && lasty == curpoint->y) { beam_width *= vector_options.s_beam_dot_size; } coords.x0 = ((float)lastx - xoffs) * xscale; coords.y0 = ((float)lasty - yoffs) * yscale; coords.x1 = ((float)curpoint[curpointIdx].x - xoffs) * xscale; //coords.x1 = ((float)curpoint->x - xoffs) * xscale; coords.y1 = ((float)curpoint[curpointIdx].y - yoffs) * yscale; //coords.y1 = ((float)curpoint->y - yoffs) * yscale; if (curpoint[curpointIdx].intensity != 0) //if (curpoint->intensity != 0) { screen.container().add_line( coords.x0, coords.y0, coords.x1, coords.y1, beam_width, new rgb_t(((uint32_t)curpoint[curpointIdx].intensity << 24) | (curpoint[curpointIdx].col & 0xffffff)), //(curpoint->intensity << 24) | (curpoint->col & 0xffffff), flags); } lastx = curpoint[curpointIdx].x; //lastx = curpoint->x; lasty = curpoint[curpointIdx].y; //lasty = curpoint->y; curpointIdx++; //curpoint++; } return(0); }
void frogger_draw_background(bitmap_rgb32 bitmap, rectangle cliprect) { /* according to schematics it is at 128+8; but it has been verified different on real machine. * Video proof: http://www.youtube.com/watch?v=ssr69mQf224 */ background_draw_colorsplit(bitmap, cliprect, new rgb_t(0, 0, 0x47), 128, 128); }
protected virtual uint32_t screen_update(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { //printf("%f %f\n", m_state.m_fragments[0].y, m_state.m_fragments[m_state.m_fragments.size()-1].y); bool force_vector = screen.screen_type() == SCREEN_TYPE_VECTOR || (m_vector.op0.read() & 1) != 0; bool debug_timing = (m_enable.op0.read() & 2) == 2; bool test_pat = (m_enable.op0.read() & 4) == 4; rgb_t backcol = debug_timing ? new rgb_t(0xff, 0xff, 0x00, 0x00) : new rgb_t(0xff, 0x00, 0x00, 0x00); if (!force_vector) { screen.set_video_attributes(0); bitmap.fill(backcol); foreach (var f in m_state.m_fragments) { if (f.y < bitmap.height()) { bitmap.plot_box((int32_t)f.x, (int32_t)f.y, (int32_t)(f.xr - f.x), 1, f.col); } } if (test_pat) { draw_testpat(screen, bitmap, cliprect); } } else { screen.set_video_attributes(VIDEO_SELF_RENDER); uint32_t flags = PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD) | (screen.screen_type() == SCREEN_TYPE_VECTOR ? PRIMFLAG_VECTOR(1) : 0); rectangle visarea = screen.visible_area(); float xscale = 1.0f / (float)visarea.width(); float yscale = 1.0f / (float)visarea.height(); float xoffs = (float)visarea.min_x; float yoffs = (float)visarea.min_y; screen.container().empty(); screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, new rgb_t(0xff, 0x00, 0x00, 0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | (screen.screen_type() == SCREEN_TYPE_VECTOR ? PRIMFLAG_VECTORBUF(1) : 0)); float last_y = -1e6f; foreach (var f in m_state.m_fragments) { float x0 = (f.x - xoffs) * xscale; float y0 = (f.y - yoffs) * yscale; float x1 = (f.xr - xoffs) * xscale; rgb_t col = (debug_timing && f.y < last_y) ? backcol : new rgb_t(f.col); // FIXME: Debug check for proper vsync timing #if false auto w = m_scanline_height * xscale * 0.5; screen.container().add_line( x0 + w, y0, x1 - w, y0, m_scanline_height * yscale, nom_col(f.col), // (0xff << 24) | (f.col & 0xffffff), flags); #elif true float y1 = (f.y + m_scanline_height - yoffs) * yscale; screen.container().add_rect( x0, y0, x1, y1, new rgb_t(nom_col(col)), // (0xaf << 24) | (f.col & 0xffffff), flags); #else const float y1((f.y + m_scanline_height - yoffs) *yscale); // Crashes with bgfx screen.container().add_quad( x0, y0, x1, y1, rgb_t(nom_col(f.col)), // (0xaf << 24) | (f.col & 0xffffff), m_texture, flags); #endif last_y = f.y; } } m_state.m_fragments.clear(); return(0); }
public abstract bool add_sound_to_recording(object sound, int numsamples); //virtual bool add_sound_to_recording(const s16 *sound, int numsamples) = 0; // statics //static movie_recording::ptr create(running_machine &machine, screen_device *screen, format fmt, std::unique_ptr<emu_file> &&file, bitmap_rgb32 &snap_bitmap); //static const char *format_file_extension(format fmt); // virtuals protected abstract bool append_single_video_frame(bitmap_rgb32 bitmap, rgb_t palette, int palette_entries); //virtual bool append_single_video_frame(bitmap_rgb32 &bitmap, const rgb_t *palette, int palette_entries) = 0;
uint32_t screen_update_mw8080bw(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { throw new emu_unimplemented(); }
/************************************* * * Space Encounters * *************************************/ //#define SPCENCTR_TOP_TRENCH_DARK_RGB32_PEN rgb_t(0x4d, 0x4d, 0x4d) //#define SPCENCTR_TOP_TRENCH_LIGHT_RGB32_PEN rgb_t(0xe6, 0xe6, 0xe6) //#define SPCENCTR_SIDE_TRENCH_DARK_RGB32_PEN rgb_t(0x1a, 0x1a, 0x1a) //#define SPCENCTR_SIDE_TRENCH_LIGHT_RGB32_PEN rgb_t(0x80, 0x80, 0x80) //#define SPCENCTR_BOTTOM_TRENCH_DARK_RGB32_PEN rgb_t(0x0d, 0x0d, 0x0d) //#define SPCENCTR_BOTTOM_TRENCH_LIGHT_RGB32_PEN rgb_t(0x66, 0x66, 0x66) //#define SPCENCTR_BRIGHTNESS_DECAY 10 //uint32_t spcenctr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) /************************************* * * Phantom II * *************************************/ //#define PHANTOM2_CLOUD_COUNTER_START (0x0e0b) //#define PHANTOM2_CLOUD_COUNTER_END (0x1000) //#define PHANTOM2_CLOUD_COUNTER_PERIOD (PHANTOM2_CLOUD_COUNTER_END - PHANTOM2_CLOUD_COUNTER_START) //#define PHANTOM2_RGB32_CLOUD_PEN rgb_t(0xc0, 0xc0, 0xc0) //uint32_t mw8080bw_state::screen_update_phantom2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) //WRITE_LINE_MEMBER(mw8080bw_state::screen_vblank_phantom2) /************************************* * * Space Invaders * *************************************/ // the flip screen circuit is just a couple of relays on the monitor PCB uint32_t screen_update_invaders(screen_device screen, bitmap_rgb32 bitmap, rectangle cliprect) { uint8_t x = 0; uint8_t y = MW8080BW_VCOUNTER_START_NO_VBLANK; uint8_t video_data = 0; while (true) { // plot the current pixel pen_t pen = (video_data & 0x01) != 0 ? rgb_t.white() : rgb_t.black(); if (m_flip_screen != 0) { bitmap.pix(MW8080BW_VBSTART - 1 - (y - MW8080BW_VCOUNTER_START_NO_VBLANK), MW8080BW_HPIXCOUNT - 1 - x).SetUInt32(0, pen); } else { bitmap.pix(y - MW8080BW_VCOUNTER_START_NO_VBLANK, x).SetUInt32(0, pen); } // next pixel video_data = (uint8_t)(video_data >> 1); x = (uint8_t)(x + 1); // end of line? if (x == 0) { // yes, flush out the shift register for (int i = 0; i < 4; i++) { pen = (video_data & 0x01) != 0 ? rgb_t.white() : rgb_t.black(); if (m_flip_screen != 0) { bitmap.pix(MW8080BW_VBSTART - 1 - (y - MW8080BW_VCOUNTER_START_NO_VBLANK), MW8080BW_HPIXCOUNT - 1 - (256 + i)).SetUInt32(0, pen); } else { bitmap.pix(y - MW8080BW_VCOUNTER_START_NO_VBLANK, 256 + i).SetUInt32(0, pen); } video_data = (uint8_t)(video_data >> 1); } // next row, video_data is now 0, so the next line will start with 4 blank pixels y = (uint8_t)(y + 1); // end of screen? if (y == 0) { break; } } else if ((x & 0x07) == 0x04) // the video RAM is read at every 8 pixels starting with pixel 4 { offs_t offs = (offs_t)((y << 5) | (x >> 3)); video_data = m_main_ram[offs].op; } } return(0); }
//bitmap_rgb32(uint32_t *base, int width, int height, int rowpixels) : bitmap32_t(k_bitmap_format, base, width, height, rowpixels) { } public bitmap_rgb32(bitmap_rgb32 source, rectangle subrect) : base(k_bitmap_format, source, subrect) { }
public abstract error append_video_frame(bitmap_rgb32 bitmap);