void vsystem_spr_device::common_sprite_drawgfx( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect) { gfx_element *gfx = machine.gfx[m_gfx_region]; int priority_mask = 0x00; curr_sprite.oy += m_yoffs; curr_sprite.ox += m_xoffs; if (m_pdraw) { switch (curr_sprite.pri) { default: case 0: priority_mask = 0x00; break; case 3: priority_mask = 0xfe; break; case 2: priority_mask = 0xfc; break; case 1: priority_mask = 0xf0; break; } } curr_sprite.zoomx = 32 - curr_sprite.zoomx; curr_sprite.zoomy = 32 - curr_sprite.zoomy; int ystart, yend, yinc; if (!curr_sprite.flipy) { ystart = 0; yend = curr_sprite.ysize+1; yinc = 1; } else { ystart = curr_sprite.ysize; yend = -1; yinc = -1; } int ycnt = ystart; while (ycnt != yend) { int xstart, xend, xinc; if (!curr_sprite.flipx) { xstart = 0; xend = curr_sprite.xsize+1; xinc = 1; } else { xstart = curr_sprite.xsize; xend = -1; xinc = -1; } int xcnt = xstart; while (xcnt != xend) { int startno = m_newtilecb(curr_sprite.map++); if (m_pdraw) { pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_transpen); pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_transpen); pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_transpen); pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_transpen); } else { drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_transpen); drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_transpen); drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_transpen); drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_transpen); } xcnt+=xinc; } ycnt+=yinc; } }
static void draw_sprites( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) { orbit_state *state = machine.driver_data<orbit_state>(); const UINT8* p = state->m_sprite_ram; int i; for (i = 0; i < 16; i++) { int code = *p++; int vpos = *p++; int hpos = *p++; int flag = *p++; int layout = ((flag & 0xc0) == 0x80) ? 1 : ((flag & 0xc0) == 0xc0) ? 2 : 0; int flip_x = BIT(code, 6); int flip_y = BIT(code, 7); int zoom_x = 0x10000; int zoom_y = 0x10000; code &= 0x3f; if (flag & 1) code |= 0x40; if (flag & 2) zoom_x *= 2; vpos = 240 - vpos; hpos <<= 1; vpos <<= 1; drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[layout], code, 0, flip_x, flip_y, hpos, vpos, zoom_x, zoom_y, 0); } }
static void draw_spaceship(running_machine *machine, bitmap_t* bitmap, const rectangle* cliprect) { starshp1_state *state = machine->driver_data<starshp1_state>(); double scaler = -5 * log(1 - state->ship_size / 256.0); /* ? */ unsigned xzoom = 2 * 0x10000 * scaler; unsigned yzoom = 1 * 0x10000 * scaler; int x = get_sprite_hpos(state, 14); int y = get_sprite_vpos(state, 14); if (x <= 0) x -= (xzoom * state->ship_hoffset) >> 16; if (y <= 0) y -= (yzoom * state->ship_voffset) >> 16; drawgfxzoom_transpen(bitmap, cliprect, machine->gfx[2], state->ship_picture & 0x03, state->ship_explode, state->ship_picture & 0x80, 0, x, y, xzoom, yzoom, 0); }
static void f1gp2_draw_sprites( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) { f1gp_state *state = machine.driver_data<f1gp_state>(); int offs; offs = 0; while (offs < 0x0400 && (state->m_spritelist[offs] & 0x4000) == 0) { int attr_start; int map_start; int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; attr_start = 4 * (state->m_spritelist[offs++] & 0x01ff); ox = state->m_spritelist[attr_start + 1] & 0x01ff; xsize = (state->m_spritelist[attr_start + 1] & 0x0e00) >> 9; zoomx = (state->m_spritelist[attr_start + 1] & 0xf000) >> 12; oy = state->m_spritelist[attr_start + 0] & 0x01ff; ysize = (state->m_spritelist[attr_start + 0] & 0x0e00) >> 9; zoomy = (state->m_spritelist[attr_start + 0] & 0xf000) >> 12; flipx = state->m_spritelist[attr_start + 2] & 0x4000; flipy = state->m_spritelist[attr_start + 2] & 0x8000; color = (state->m_spritelist[attr_start + 2] & 0x1f00) >> 8; map_start = state->m_spritelist[attr_start + 3] & 0x7fff; // aerofgt has the following adjustment, but doing it here would break the title screen // ox += (xsize*zoomx+2)/4; // oy += (ysize*zoomy+2)/4; zoomx = 32 - zoomx; zoomy = 32 - zoomy; if (state->m_spritelist[attr_start + 2] & 0x20ff) color = machine.rand(); for (y = 0; y <= ysize; y++) { int sx,sy; if (flipy) sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16; else sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16; for (x = 0; x <= xsize; x++) { int code; if (flipx) sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16; else sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16; code = state->m_sprcgram[map_start & 0x3fff]; map_start++; if (state->m_flipscreen) drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1], code, color, !flipx,!flipy, 304-sx,208-sy, zoomx << 11,zoomy << 11,15); else drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1], code, color, flipx,flipy, sx,sy, zoomx << 11,zoomy << 11,15); } } } }
static void draw_sprites(running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect,const int *primasks,int x_offs,int y_offs) { gunbustr_state *state = machine.driver_data<gunbustr_state>(); UINT32 *spriteram32 = state->m_spriteram; UINT16 *spritemap = (UINT16 *)machine.region("user1")->base(); int offs, data, tilenum, color, flipx, flipy; int x, y, priority, dblsize, curx, cury; int sprites_flipscreen = 0; int zoomx, zoomy, zx, zy; int sprite_chunk,map_offset,code,j,k,px,py; int dimension,total_chunks,bad_chunks; /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list while processing sprite ram and then draw them all at the end */ struct tempsprite *sprite_ptr = state->m_spritelist; for (offs = (state->m_spriteram_size/4-4);offs >= 0;offs -= 4) { data = spriteram32[offs+0]; flipx = (data & 0x00800000) >> 23; zoomx = (data & 0x007f0000) >> 16; tilenum = (data & 0x00007fff); data = spriteram32[offs+2]; priority = (data & 0x000c0000) >> 18; color = (data & 0x0003fc00) >> 10; x = (data & 0x000003ff); data = spriteram32[offs+3]; dblsize = (data & 0x00040000) >> 18; flipy = (data & 0x00020000) >> 17; zoomy = (data & 0x0001fc00) >> 10; y = (data & 0x000003ff); color |= 0x80; if (!tilenum) continue; flipy = !flipy; zoomx += 1; zoomy += 1; y += y_offs; /* treat coords as signed */ if (x>0x340) x -= 0x400; if (y>0x340) y -= 0x400; x -= x_offs; bad_chunks = 0; dimension = ((dblsize*2) + 2); // 2 or 4 total_chunks = ((dblsize*3) + 1) << 2; // 4 or 16 map_offset = tilenum << 2; { for (sprite_chunk=0;sprite_chunk<total_chunks;sprite_chunk++) { j = sprite_chunk / dimension; /* rows */ k = sprite_chunk % dimension; /* chunks per row */ px = k; py = j; /* pick tiles back to front for x and y flips */ if (flipx) px = dimension-1-k; if (flipy) py = dimension-1-j; code = spritemap[map_offset + px + (py<<(dblsize+1))]; if (code==0xffff) { bad_chunks += 1; continue; } curx = x + ((k*zoomx)/dimension); cury = y + ((j*zoomy)/dimension); zx= x + (((k+1)*zoomx)/dimension) - curx; zy= y + (((j+1)*zoomy)/dimension) - cury; if (sprites_flipscreen) { /* -zx/y is there to fix zoomed sprite coords in screenflip. drawgfxzoom does not know to draw from flip-side of sprites when screen is flipped; so we must correct the coords ourselves. */ curx = 320 - curx - zx; cury = 256 - cury - zy; flipx = !flipx; flipy = !flipy; } sprite_ptr->gfx = 0; sprite_ptr->code = code; sprite_ptr->color = color; sprite_ptr->flipx = !flipx; sprite_ptr->flipy = flipy; sprite_ptr->x = curx; sprite_ptr->y = cury; sprite_ptr->zoomx = zx << 12; sprite_ptr->zoomy = zy << 12; if (primasks) { sprite_ptr->primask = primasks[priority]; sprite_ptr++; } else { drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[sprite_ptr->gfx], sprite_ptr->code, sprite_ptr->color, sprite_ptr->flipx,sprite_ptr->flipy, sprite_ptr->x,sprite_ptr->y, sprite_ptr->zoomx,sprite_ptr->zoomy,0); } } } if (bad_chunks) logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks); } /* this happens only if primsks != NULL */ while (sprite_ptr != state->m_spritelist) { sprite_ptr--; pdrawgfxzoom_transpen(bitmap,cliprect,machine.gfx[sprite_ptr->gfx], sprite_ptr->code, sprite_ptr->color, sprite_ptr->flipx,sprite_ptr->flipy, sprite_ptr->x,sprite_ptr->y, sprite_ptr->zoomx,sprite_ptr->zoomy, machine.priority_bitmap,sprite_ptr->primask,0); } }
static void parentj_draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int priority ) { /* Y chain size is 16/32?/64/64? pixels. X chain size is always 64 pixels. */ taitoo_state *state = machine->driver_data<taitoo_state>(); static const int size[] = { 1, 2, 4, 4 }; int x0, y0, x, y, dx, dy, ex, ey, zx, zy; int ysize; int j, k; int offs; /* sprite RAM offset */ int tile_offs; /* sprite chain offset */ int zoomx, zoomy; /* zoom value */ for (offs = 0x03f8 / 2; offs >= 0; offs -= 0x008 / 2) { if (offs < 0x01b0 && priority == 0) continue; if (offs >= 0x01b0 && priority == 1) continue; x0 = tc0080vco_sprram_r(state->tc0080vco, offs + 1, 0xffff) & 0x3ff; y0 = tc0080vco_sprram_r(state->tc0080vco, offs + 0, 0xffff) & 0x3ff; zoomx = (tc0080vco_sprram_r(state->tc0080vco, offs + 2, 0xffff) & 0x7f00) >> 8; zoomy = (tc0080vco_sprram_r(state->tc0080vco, offs + 2, 0xffff) & 0x007f); tile_offs = (tc0080vco_sprram_r(state->tc0080vco, offs + 3, 0xffff) & 0x1fff) << 2; ysize = size[(tc0080vco_sprram_r(state->tc0080vco, offs, 0xffff) & 0x0c00) >> 10]; if (tile_offs) { /* Convert zoomy value to real value as zoomx */ zoomy = zoomy_conv_table[zoomy]; if (zoomx < 63) { dx = 8 + (zoomx + 2) / 8; ex = (zoomx + 2) % 8; zx = ((dx << 1) + ex) << 11; } else { dx = 16 + (zoomx - 63) / 4; ex = (zoomx - 63) % 4; zx = (dx + ex) << 12; } if (zoomy < 63) { dy = 8 + (zoomy + 2) / 8; ey = (zoomy + 2) % 8; zy = ((dy << 1) + ey) << 11; } else { dy = 16 + (zoomy - 63) / 4; ey = (zoomy - 63) % 4; zy = (dy + ey) << 12; } if (x0 >= 0x200) x0 -= 0x400; if (y0 >= 0x200) y0 -= 0x400; if (tc0080vco_flipscreen_r(state->tc0080vco)) { x0 = 497 - x0; y0 = 498 - y0; dx = -dx; dy = -dy; } else { x0 += 1; y0 += 2; } y = y0; for (j = 0; j < ysize; j ++) { x = x0; for (k = 0; k < 4; k ++) { if (tile_offs >= 0x1000) { int tile, color, flipx, flipy; tile = tc0080vco_cram_0_r(state->tc0080vco, tile_offs, 0xffff) & 0x7fff; color = tc0080vco_cram_1_r(state->tc0080vco, tile_offs, 0xffff) & 0x001f; flipx = tc0080vco_cram_1_r(state->tc0080vco, tile_offs, 0xffff) & 0x0040; flipy = tc0080vco_cram_1_r(state->tc0080vco, tile_offs, 0xffff) & 0x0080; if (tc0080vco_flipscreen_r(state->tc0080vco)) { flipx ^= 0x0040; flipy ^= 0x0080; } drawgfxzoom_transpen( bitmap, cliprect, machine -> gfx[0], tile, color, flipx, flipy, x, y, zx, zy, 0 ); } tile_offs ++; x += dx; } y += dy; } } } }
static void draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect ) { flower_state *state = machine.driver_data<flower_state>(); const gfx_element *gfx = machine.gfx[1]; UINT8 *source = state->m_spriteram + 0x200; UINT8 *finish = source - 0x200; source -= 8; while( source>=finish ) { int xblock,yblock; int sy = 256-32-source[0]+1; int sx = (source[4]|(source[5]<<8))-55; int code = source[1] & 0x3f; int color = (source[6]>>4); /* Byte 0: Y Byte 1: 0x80 - FlipY 0x40 - FlipX 0x3f - Tile Byte 2: 0x08 - Tile MSB 0x01 - Tile MSB Byte 3: 0x07 - X Zoom 0x08 - X Size 0x70 - Y Zoom 0x80 - Y Size Byte 4: X LSB Byte 5: X MSB Byte 6: 0xf0 - Colour */ int flipy = source[1] & 0x80; int flipx = source[1] & 0x40; int size = source[3]; int xsize = ((size & 0x08)>>3); int ysize = ((size & 0x80)>>7); xsize++; ysize++; if (ysize==2) sy -= 16; code |= ((source[2] & 0x01) << 6); code |= ((source[2] & 0x08) << 4); if(flip_screen_get(machine)) { flipx = !flipx; flipy = !flipy; sx = sx+16; sy = 250-sy; if (ysize==2) sy += 16; } for (xblock = 0; xblock<xsize; xblock++) { int xoffs=!flipx ? (xblock*8) : ((xsize-xblock-1)*8); int zoomx=((size&7)+1)<<13; int zoomy=((size&0x70)+0x10)<<9; int xblocksizeinpixels=(zoomx*16)>>16; int yblocksizeinpixels=(zoomy*16)>>16; for (yblock = 0; yblock<ysize; yblock++) { int yoffs=!flipy ? yblock : (ysize-yblock-1); int sxoffs=(16-xblocksizeinpixels)/2; int syoffs=(16-yblocksizeinpixels)/2; if (xblock) sxoffs+=xblocksizeinpixels; if (yblock) syoffs+=yblocksizeinpixels; drawgfxzoom_transpen(bitmap,cliprect,gfx, code+yoffs+xoffs, color, flipx,flipy, sx+sxoffs,sy+syoffs, zoomx,zoomy,15); } } source -= 8; } }
/* todo, fix zooming correctly, it's _not_ like aerofgt */ static void draw_sprites( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) { /* SPRITE INFO Video System hardware, like aerofgt etc. the sprites use 2 areas of ram, one containing a spritelist + sprite attributes, the other contains the sprite tile #'s to use sprite attribute info (4 words per sprite) | ZZZZ hhhy yyyy yyyy | zzzz wwwx xxxx xxxx | -fpp pppp ---- ---- | -ooo oooo oooo oooo | x = x position y = y position w = width h = height zZ = y zoom / x zoom f = xflip p = palette / colour o = offset to tile data in other ram area */ suprslam_state *state = machine.driver_data<suprslam_state>(); const gfx_element *gfx = machine.gfx[1]; UINT16 *source = state->m_spriteram; UINT16 *source2 = state->m_spriteram; UINT16 *finish = source + 0x2000/2; while (source < finish) { UINT32 sprnum = source[0] & 0x03ff; if (source[0] == 0x4000) break; sprnum *= 4; source++; /* DRAW START */ { int ypos = source2[sprnum + 0] & 0x1ff; int high = (source2[sprnum + 0] & 0x0e00) >> 9; int yzoom = (source2[sprnum + 0] & 0xf000) >> 12; int xpos = source2[sprnum + 1] & 0x1ff; int wide = (source2[sprnum + 1] & 0x0e00) >> 9; int xzoom = (source2[sprnum + 1] & 0xf000) >> 12; int col = (source2[sprnum + 2] & 0x3f00) >> 8; int flipx = (source2[sprnum + 2] & 0x4000) >> 14; // int flipy = (source2[sprnum + 2] & 0x8000) >> 15; int word_offset = source2[sprnum + 3] & 0x7fff; int xcnt, ycnt; int loopno = 0; xzoom = 32 - xzoom; yzoom = 32 - yzoom; if (ypos > 0xff) ypos -=0x200; for (ycnt = 0; ycnt < high+1; ycnt ++) { if (!flipx) { for (xcnt = 0; xcnt < wide+1; xcnt ++) { int tileno = state->m_sp_videoram[word_offset + loopno]; drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 0, 0,xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 0, 0,-0x200+xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); loopno ++; } } else { for (xcnt = wide; xcnt >= 0; xcnt --) { int tileno = state->m_sp_videoram[word_offset + loopno]; drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 1, 0,xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 1, 0,-0x200+xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); loopno ++; } } } } } }
void undrfire_state::draw_sprites_cbombers(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const int *primasks,int x_offs,int y_offs) { UINT32 *spriteram32 = m_spriteram; UINT16 *spritemap = (UINT16 *)memregion("user1")->base(); UINT8 *spritemapHibit = (UINT8 *)memregion("user2")->base(); int offs, data, tilenum, color, flipx, flipy; int x, y, priority, dblsize, curx, cury; int sprites_flipscreen = 0; int zoomx, zoomy, zx, zy; int sprite_chunk,map_offset,code,j,k,px,py; int dimension,total_chunks; /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list while processing sprite ram and then draw them all at the end */ struct tempsprite *sprite_ptr = m_spritelist; for (offs = (m_spriteram.bytes()/4-4);offs >= 0;offs -= 4) { data = spriteram32[offs+0]; flipx = (data & 0x00800000) >> 23; zoomx = (data & 0x007f0000) >> 16; tilenum = (data & 0x0000ffff); data = spriteram32[offs+2]; priority = (data & 0x000c0000) >> 18; color = (data & 0x0003fc00) >> 10; x = (data & 0x000003ff); data = spriteram32[offs+3]; dblsize = (data & 0x00040000) >> 18; flipy = (data & 0x00020000) >> 17; zoomy = (data & 0x0001fc00) >> 10; y = (data & 0x000003ff); color |= (/*0x100 +*/ (priority << 6)); /* priority bits select color bank */ color /= 2; /* as sprites are 5bpp */ flipy = !flipy; if (!tilenum) continue; zoomx += 1; zoomy += 1; y += y_offs; /* treat coords as signed */ if (x>0x340) x -= 0x400; if (y>0x340) y -= 0x400; x -= x_offs; dimension = ((dblsize*2) + 2); // 2 or 4 total_chunks = ((dblsize*3) + 1) << 2; // 4 or 16 map_offset = tilenum << 2; for (sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++) { int map_addr; j = sprite_chunk / dimension; /* rows */ k = sprite_chunk % dimension; /* chunks per row */ px = k; py = j; /* pick tiles back to front for x and y flips */ if (flipx) px = dimension-1-k; if (flipy) py = dimension-1-j; map_addr = map_offset + px + (py << (dblsize + 1)); code = (spritemapHibit[map_addr] << 16) | spritemap[map_addr]; curx = x + ((k*zoomx)/dimension); cury = y + ((j*zoomy)/dimension); zx= x + (((k+1)*zoomx)/dimension) - curx; zy= y + (((j+1)*zoomy)/dimension) - cury; if (sprites_flipscreen) { /* -zx/y is there to fix zoomed sprite coords in screenflip. drawgfxzoom does not know to draw from flip-side of sprites when screen is flipped; so we must correct the coords ourselves. */ curx = 320 - curx - zx; cury = 256 - cury - zy; flipx = !flipx; flipy = !flipy; } sprite_ptr->gfx = 0; sprite_ptr->code = code; sprite_ptr->color = color; sprite_ptr->flipx = !flipx; sprite_ptr->flipy = flipy; sprite_ptr->x = curx; sprite_ptr->y = cury; sprite_ptr->zoomx = zx << 12; sprite_ptr->zoomy = zy << 12; if (primasks) { sprite_ptr->primask = primasks[priority]; sprite_ptr++; } else { drawgfxzoom_transpen(bitmap,cliprect,machine().gfx[sprite_ptr->gfx], sprite_ptr->code, sprite_ptr->color, sprite_ptr->flipx,sprite_ptr->flipy, sprite_ptr->x,sprite_ptr->y, sprite_ptr->zoomx,sprite_ptr->zoomy,0); } } } /* this happens only if primsks != NULL */ while (sprite_ptr != m_spritelist) { sprite_ptr--; pdrawgfxzoom_transpen(bitmap,cliprect,machine().gfx[sprite_ptr->gfx], sprite_ptr->code, sprite_ptr->color, sprite_ptr->flipx,sprite_ptr->flipy, sprite_ptr->x,sprite_ptr->y, sprite_ptr->zoomx,sprite_ptr->zoomy, screen.priority(),sprite_ptr->primask,0); } }
static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap,const rectangle &cliprect) { crshrace_state *state = machine.driver_data<crshrace_state>(); UINT16 *buffered_spriteram = machine.generic.buffered_spriteram.u16; UINT16 *buffered_spriteram_2 = machine.generic.buffered_spriteram2.u16; int offs; offs = 0; while (offs < 0x0400 && (buffered_spriteram[offs] & 0x4000) == 0) { int attr_start; int map_start; int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; /* table hand made by looking at the ship explosion in aerofgt attract mode */ /* it's almost a logarithmic scale but not exactly */ static const int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 }; attr_start = 4 * (buffered_spriteram[offs++] & 0x03ff); ox = buffered_spriteram[attr_start + 1] & 0x01ff; xsize = (buffered_spriteram[attr_start + 1] & 0x0e00) >> 9; zoomx = (buffered_spriteram[attr_start + 1] & 0xf000) >> 12; oy = buffered_spriteram[attr_start + 0] & 0x01ff; ysize = (buffered_spriteram[attr_start + 0] & 0x0e00) >> 9; zoomy = (buffered_spriteram[attr_start + 0] & 0xf000) >> 12; flipx = buffered_spriteram[attr_start + 2] & 0x4000; flipy = buffered_spriteram[attr_start + 2] & 0x8000; color = (buffered_spriteram[attr_start + 2] & 0x1f00) >> 8; map_start = buffered_spriteram[attr_start + 3] & 0x7fff; zoomx = 16 - zoomtable[zoomx] / 8; zoomy = 16 - zoomtable[zoomy] / 8; if (buffered_spriteram[attr_start + 2] & 0x20ff) color = machine.rand(); for (y = 0; y <= ysize; y++) { int sx,sy; if (flipy) sy = ((oy + zoomy * (ysize - y) + 16) & 0x1ff) - 16; else sy = ((oy + zoomy * y + 16) & 0x1ff) - 16; for (x = 0; x <= xsize; x++) { int code; if (flipx) sx = ((ox + zoomx * (xsize - x) + 16) & 0x1ff) - 16; else sx = ((ox + zoomx * x + 16) & 0x1ff) - 16; code = buffered_spriteram_2[map_start & 0x7fff]; map_start++; if (state->m_flipscreen) drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2], code, color, !flipx,!flipy, 304-sx,208-sy, 0x1000 * zoomx,0x1000 * zoomy,15); else drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2], code, color, flipx,flipy, sx,sy, 0x1000 * zoomx,0x1000 * zoomy,15); } } } }
static void syvalion_draw_sprites( running_machine *machine,bitmap_t *bitmap, const rectangle *cliprect ) { /* Y chain size is 16/32?/64/64? pixels. X chain size is always 64 pixels. */ taitoh_state *state = (taitoh_state *)machine->driver_data; static const int size[] = { 1, 2, 4, 4 }; int x0, y0, x, y, dx, ex, zx; int ysize; int j, k; int offs; /* sprite RAM offset */ int tile_offs; /* sprite chain offset */ int zoomx; /* zoomx value */ for (offs = 0x03f8 / 2; offs >= 0; offs -= 0x008 / 2) { x0 = tc0080vco_sprram_r(state->tc0080vco, offs + 1, 0xffff) & 0x3ff; y0 = tc0080vco_sprram_r(state->tc0080vco, offs + 0, 0xffff) & 0x3ff; zoomx = (tc0080vco_sprram_r(state->tc0080vco, offs + 2, 0xffff) & 0x7f00) >> 8; tile_offs = (tc0080vco_sprram_r(state->tc0080vco, offs + 3, 0xffff) & 0x1fff) << 2; ysize = size[(tc0080vco_sprram_r(state->tc0080vco, offs, 0xffff) & 0x0c00) >> 10]; if (tile_offs) { /* The increasing ratio of expansion is different whether zoom value */ /* is less or more than 63. */ if (zoomx < 63) { dx = 8 + (zoomx + 2) / 8; ex = (zoomx + 2) % 8; zx = ((dx << 1) + ex) << 11; } else { dx = 16 + (zoomx - 63) / 4; ex = (zoomx - 63) % 4; zx = (dx + ex) << 12; } if (x0 >= 0x200) x0 -= 0x400; if (y0 >= 0x200) y0 -= 0x400; if (tc0080vco_flipscreen_r(state->tc0080vco)) { x0 = 497 - x0; y0 = 498 - y0; dx = -dx; } else { x0 += 1; y0 += 2; } y = y0; for (j = 0; j < ysize; j++) { x = x0; for (k = 0; k < 4; k++) { if (tile_offs >= 0x1000) { int tile, color, flipx, flipy; tile = tc0080vco_cram_0_r(state->tc0080vco, tile_offs, 0xffff) & 0x7fff; color = tc0080vco_cram_1_r(state->tc0080vco, tile_offs, 0xffff) & 0x001f; flipx = tc0080vco_cram_1_r(state->tc0080vco, tile_offs, 0xffff) & 0x0040; flipy = tc0080vco_cram_1_r(state->tc0080vco, tile_offs, 0xffff) & 0x0080; if (tc0080vco_flipscreen_r(state->tc0080vco)) { flipx ^= 0x0040; flipy ^= 0x0080; } drawgfxzoom_transpen( bitmap, cliprect, machine -> gfx[0], tile, color, flipx, flipy, x, y, zx, zx, 0 ); } tile_offs ++; x += dx; } y += dx; } } } }
static void draw_sprite(running_machine *machine, UINT16 spriteno, bitmap_t *bitmap, const rectangle *cliprect ) { /*- SPR RAM Format -** 4 words per sprite zzzz sssp pppp pppp (y zoom, y size, y position) zzzz sssp pppp pppp (x zoom, x size, x position) yxpc cccc ---- ---- (flipy, flipx, priority?, colour) -nnn nnnn nnnn nnnn (tile lookup) */ int x,y; UINT16 *source = &taotaido_spriteram_older[spriteno*4]; const gfx_element *gfx = machine->gfx[0]; int yzoom = (source[0] & 0xf000) >> 12; int xzoom = (source[1] & 0xf000) >> 12; int ysize = (source[0] & 0x0e00) >> 9; int xsize = (source[1] & 0x0e00) >> 9; int ypos = source[0] & 0x01ff; int xpos = source[1] & 0x01ff; int yflip = source[2] & 0x8000; int xflip = source[2] & 0x4000; int color = (source[2] & 0x1f00) >> 8; int tile = source[3] & 0xffff; xpos += (xsize*xzoom+2)/4; ypos += (ysize*yzoom+2)/4; xzoom = 32 - xzoom; yzoom = 32 - yzoom; for (y = 0;y <= ysize;y++) { int sx,sy; if (yflip) sy = ((ypos + yzoom * (ysize - y)/2 + 16) & 0x1ff) - 16; else sy = ((ypos + yzoom * y / 2 + 16) & 0x1ff) - 16; for (x = 0;x <= xsize;x++) { /* this indirection is a bit different to the other video system games */ int realtile; realtile = taotaido_spriteram2_older[tile&0x7fff]; if (realtile > 0x3fff) { int block; block = (realtile & 0x3800)>>11; realtile &= 0x07ff; realtile |= taotaido_sprite_character_bank_select[block] * 0x800; } if (xflip) sx = ((xpos + xzoom * (xsize - x) / 2 + 16) & 0x1ff) - 16; else sx = ((xpos + xzoom * x / 2 + 16) & 0x1ff) - 16; drawgfxzoom_transpen(bitmap,cliprect,gfx, realtile, color, xflip,yflip, sx,sy, xzoom << 11, yzoom << 11,15); tile++; } }
static void draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, const int *primasks, int y_offs ) { othunder_state *state = machine->driver_data<othunder_state>(); UINT16 *spritemap = (UINT16 *)memory_region(machine, "user1"); UINT16 tile_mask = (machine->gfx[0]->total_elements) - 1; UINT16 *spriteram16 = state->spriteram; int offs, data, tilenum, color, flipx, flipy; int x, y, priority, curx, cury; int sprites_flipscreen = 0; int zoomx, zoomy, zx, zy; int sprite_chunk, map_offset, code, j, k, px, py; int bad_chunks; /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list while processing sprite ram and then draw them all at the end */ struct othunder_tempsprite *sprite_ptr = state->spritelist; for (offs = (state->spriteram_size / 2) - 4; offs >= 0; offs -= 4) { data = spriteram16[offs + 0]; zoomy = (data & 0xfe00) >> 9; y = data & 0x1ff; data = spriteram16[offs + 1]; flipx = (data & 0x4000) >> 14; priority = (data & 0x8000) >> 15; x = data & 0x1ff; data = spriteram16[offs + 2]; color = (data & 0xff00) >> 8; zoomx = (data & 0x7f); data = spriteram16[offs + 3]; tilenum = data & 0x1fff; // $80000 spritemap rom maps up to $2000 64x64 sprites flipy = (data & 0x8000) >> 15; if (!tilenum) continue; map_offset = tilenum << 5; zoomx += 1; zoomy += 1; y += y_offs; /* treat coords as signed */ if (x > 0x140) x -= 0x200; if (y > 0x140) y -= 0x200; bad_chunks = 0; for (sprite_chunk = 0; sprite_chunk < 32; sprite_chunk++) { k = sprite_chunk % 4; /* 4 chunks per row */ j = sprite_chunk / 4; /* 8 rows */ px = k; py = j; if (flipx) px = 3 - k; /* pick tiles back to front for x and y flips */ if (flipy) py = 7 - j; code = spritemap[map_offset + px + (py << 2)] & tile_mask; if (code == 0xffff) { bad_chunks += 1; continue; } curx = x + ((k * zoomx) / 4); cury = y + ((j * zoomy) / 8); zx= x + (((k + 1) * zoomx) / 4) - curx; zy= y + (((j + 1) * zoomy) / 8) - cury; if (sprites_flipscreen) { /* -zx/y is there to fix zoomed sprite coords in screenflip. drawgfxzoom does not know to draw from flip-side of sprites when screen is flipped; so we must correct the coords ourselves. */ curx = 320 - curx - zx; cury = 256 - cury - zy; flipx = !flipx; flipy = !flipy; } sprite_ptr->code = code; sprite_ptr->color = color; sprite_ptr->flipx = flipx; sprite_ptr->flipy = flipy; sprite_ptr->x = curx; sprite_ptr->y = cury; sprite_ptr->zoomx = zx << 12; sprite_ptr->zoomy = zy << 13; if (primasks) { sprite_ptr->primask = primasks[priority]; sprite_ptr++; } else { drawgfxzoom_transpen(bitmap,cliprect,machine->gfx[0], sprite_ptr->code, sprite_ptr->color, sprite_ptr->flipx,sprite_ptr->flipy, sprite_ptr->x,sprite_ptr->y, sprite_ptr->zoomx,sprite_ptr->zoomy,0); } } if (bad_chunks) logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks); } /* this happens only if primsks != NULL */ while (sprite_ptr != state->spritelist) { sprite_ptr--; pdrawgfxzoom_transpen(bitmap,cliprect,machine->gfx[0], sprite_ptr->code, sprite_ptr->color, sprite_ptr->flipx,sprite_ptr->flipy, sprite_ptr->x,sprite_ptr->y, sprite_ptr->zoomx,sprite_ptr->zoomy, machine->priority_bitmap,sprite_ptr->primask,0); } }
static void aerofgt_draw_sprites( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority ) { aerofgt_state *state = machine.driver_data<aerofgt_state>(); int offs; priority <<= 12; offs = 0; while (offs < 0x0400 && (state->m_spriteram3[offs] & 0x8000) == 0) { int attr_start = 4 * (state->m_spriteram3[offs] & 0x03ff); /* is the way I handle priority correct? Or should I just check bit 13? */ if ((state->m_spriteram3[attr_start + 2] & 0x3000) == priority) { int map_start; int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; ox = state->m_spriteram3[attr_start + 1] & 0x01ff; xsize = (state->m_spriteram3[attr_start + 1] & 0x0e00) >> 9; zoomx = (state->m_spriteram3[attr_start + 1] & 0xf000) >> 12; oy = state->m_spriteram3[attr_start + 0] & 0x01ff; ysize = (state->m_spriteram3[attr_start + 0] & 0x0e00) >> 9; zoomy = (state->m_spriteram3[attr_start + 0] & 0xf000) >> 12; flipx = state->m_spriteram3[attr_start + 2] & 0x4000; flipy = state->m_spriteram3[attr_start + 2] & 0x8000; color = (state->m_spriteram3[attr_start + 2] & 0x0f00) >> 8; map_start = state->m_spriteram3[attr_start + 3] & 0x3fff; ox += (xsize * zoomx + 2) / 4; oy += (ysize * zoomy + 2) / 4; zoomx = 32 - zoomx; zoomy = 32 - zoomy; for (y = 0; y <= ysize; y++) { int sx, sy; if (flipy) sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16; else sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16; for (x = 0; x <= xsize; x++) { int code; if (flipx) sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16; else sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16; if (map_start < 0x2000) code = state->m_spriteram1[map_start & 0x1fff] & 0x1fff; else code = state->m_spriteram2[map_start & 0x1fff] & 0x1fff; drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[state->m_sprite_gfx + (map_start >= 0x2000 ? 1 : 0)], code, color, flipx,flipy, sx,sy, zoomx << 11, zoomy << 11,15); map_start++; } } } offs++; }