/************************************* * * 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); } } }
/************************************* * * Draw a row of stars * *************************************/ void stars_draw_row(bitmap_rgb32 bitmap, int maxx, int y, UInt32 star_offs, byte 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; byte 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.pix32(y, GALAXIAN_XSCALE*x + 0) = m_star_color[star & 0x3f]; RawBuffer bitmapBuf0; UInt32 bitmapBuf0Offset = bitmap.pix32(out bitmapBuf0, y, GALAXIAN_XSCALE * x + 0); bitmapBuf0.set_uint32((int)bitmapBuf0Offset, 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.pix32(y, GALAXIAN_XSCALE*x + 1) = m_star_color[star & 0x3f]; RawBuffer bitmapBuf1; UInt32 bitmapBuf1Offset = bitmap.pix32(out bitmapBuf1, y, GALAXIAN_XSCALE * x + 1); bitmapBuf1.set_uint32((int)bitmapBuf1Offset, m_star_color[star & 0x3f]); //bitmap.pix32(y, GALAXIAN_XSCALE*x + 2) = m_star_color[star & 0x3f]; RawBuffer bitmapBuf2; UInt32 bitmapBuf2Offset = bitmap.pix32(out bitmapBuf2, y, GALAXIAN_XSCALE * x + 2); bitmapBuf2.set_uint32((int)bitmapBuf2Offset, m_star_color[star & 0x3f]); } } }