diff options
Diffstat (limited to 'src/mame/video/f1gp.c')
-rw-r--r-- | src/mame/video/f1gp.c | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/src/mame/video/f1gp.c b/src/mame/video/f1gp.c new file mode 100644 index 00000000000..fbee23d2261 --- /dev/null +++ b/src/mame/video/f1gp.c @@ -0,0 +1,562 @@ +#include "driver.h" +#include "video/konamiic.h" +//#include "f1gp.h" + + +UINT16 *f1gp_spr1vram,*f1gp_spr2vram,*f1gp_spr1cgram,*f1gp_spr2cgram; +UINT16 *f1gp_fgvideoram,*f1gp_rozvideoram; +UINT16 *f1gp2_sprcgram,*f1gp2_spritelist; +UINT16 *f1gpb_rozregs, *f1gpb_fgregs; +size_t f1gp_spr1cgram_size,f1gp_spr2cgram_size; + +static UINT16 *zoomdata; +static int dirtygfx,flipscreen,gfxctrl; +static UINT8 *dirtychar; + +#define TOTAL_CHARS 0x800 + +static tilemap *fg_tilemap,*roz_tilemap; +static int f1gp2_roz_bank; + + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +static TILE_GET_INFO( f1gp_get_roz_tile_info ) +{ + int code = f1gp_rozvideoram[tile_index]; + + SET_TILE_INFO(3,code & 0x7ff,code >> 12,0); +} + +static TILE_GET_INFO( f1gp2_get_roz_tile_info ) +{ + int code = f1gp_rozvideoram[tile_index]; + + SET_TILE_INFO(2,(code & 0x7ff) + (f1gp2_roz_bank << 11),code >> 12,0); +} + +static TILE_GET_INFO( get_fg_tile_info ) +{ + int code = f1gp_fgvideoram[tile_index]; + + SET_TILE_INFO(0,code & 0x7fff,0,(code & 0x8000)?TILE_FLIPY:0); +} + + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +VIDEO_START( f1gp ) +{ + roz_tilemap = tilemap_create(f1gp_get_roz_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,64,64); + fg_tilemap = tilemap_create(get_fg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,64,32); + + K053936_wraparound_enable(0, 1); + K053936_set_offset(0, -58, -2); + + tilemap_set_transparent_pen(fg_tilemap,0xff); + + dirtychar = auto_malloc(TOTAL_CHARS); + memset(dirtychar,1,TOTAL_CHARS); + + zoomdata = (UINT16 *)memory_region(REGION_GFX4); +} + +VIDEO_START( f1gpb ) +{ + roz_tilemap = tilemap_create(f1gp_get_roz_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,64,64); + fg_tilemap = tilemap_create(get_fg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,64,32); + + tilemap_set_transparent_pen(fg_tilemap,0xff); + + dirtychar = auto_malloc(TOTAL_CHARS); + memset(dirtychar,1,TOTAL_CHARS); + + zoomdata = (UINT16 *)memory_region(REGION_GFX4); +} + +VIDEO_START( f1gp2 ) +{ + roz_tilemap = tilemap_create(f1gp2_get_roz_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,64,64); + fg_tilemap = tilemap_create(get_fg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,64,32); + + K053936_wraparound_enable(0, 1); + K053936_set_offset(0, -48, -21); + + tilemap_set_transparent_pen(fg_tilemap,0xff); + tilemap_set_transparent_pen(roz_tilemap,0x0f); + + tilemap_set_scrolldx(fg_tilemap,-80,0); + tilemap_set_scrolldy(fg_tilemap,-26,0); + + dirtychar = auto_malloc(TOTAL_CHARS); + memset(dirtychar,1,TOTAL_CHARS); + + zoomdata = (UINT16 *)memory_region(REGION_GFX4); +} + + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +READ16_HANDLER( f1gp_zoomdata_r ) +{ + return zoomdata[offset]; +} + +WRITE16_HANDLER( f1gp_zoomdata_w ) +{ + int oldword = zoomdata[offset]; + COMBINE_DATA(&zoomdata[offset]); + if (oldword != zoomdata[offset]) + { + dirtygfx = 1; + dirtychar[offset / 64] = 1; + } +} + +READ16_HANDLER( f1gp_rozvideoram_r ) +{ + return f1gp_rozvideoram[offset]; +} + +WRITE16_HANDLER( f1gp_rozvideoram_w ) +{ + COMBINE_DATA(&f1gp_rozvideoram[offset]); + tilemap_mark_tile_dirty(roz_tilemap,offset); +} + +WRITE16_HANDLER( f1gp_fgvideoram_w ) +{ + COMBINE_DATA(&f1gp_fgvideoram[offset]); + tilemap_mark_tile_dirty(fg_tilemap,offset); +} + +WRITE16_HANDLER( f1gp_fgscroll_w ) +{ + static int scroll[2]; + + COMBINE_DATA(&scroll[offset]); + + tilemap_set_scrollx(fg_tilemap,0,scroll[0]); + tilemap_set_scrolly(fg_tilemap,0,scroll[1]); +} + +WRITE16_HANDLER( f1gp_gfxctrl_w ) +{ + if (ACCESSING_LSB) + { + flipscreen = data & 0x20; + gfxctrl = data & 0xdf; + } +} + +WRITE16_HANDLER( f1gp2_gfxctrl_w ) +{ + if (ACCESSING_LSB) + { + flipscreen = data & 0x20; + + /* bit 0/1 = fg/sprite/roz priority */ + /* bit 2 = blank screen */ + + gfxctrl = data & 0xdf; + } + + if (ACCESSING_MSB) + { + if (f1gp2_roz_bank != (data >> 8)) + { + f1gp2_roz_bank = (data >> 8); + tilemap_mark_all_tiles_dirty(roz_tilemap); + } + } +} + + +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +static void f1gp_draw_sprites(running_machine *machine,mame_bitmap *bitmap,const rectangle *cliprect,int chip,int primask) +{ + int attr_start,first; + UINT16 *spram = chip ? f1gp_spr2vram : f1gp_spr1vram; + + first = 4 * spram[0x1fe]; + + for (attr_start = 0x0200-8;attr_start >= first;attr_start -= 4) + { + int map_start; + int ox,oy,x,y,xsize,ysize,zoomx,zoomy,flipx,flipy,color,pri; + /* table hand made by looking at the ship explosion in 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 }; + + if (!(spram[attr_start + 2] & 0x0080)) continue; + + ox = spram[attr_start + 1] & 0x01ff; + xsize = (spram[attr_start + 2] & 0x0700) >> 8; + zoomx = (spram[attr_start + 1] & 0xf000) >> 12; + oy = spram[attr_start + 0] & 0x01ff; + ysize = (spram[attr_start + 2] & 0x7000) >> 12; + zoomy = (spram[attr_start + 0] & 0xf000) >> 12; + flipx = spram[attr_start + 2] & 0x0800; + flipy = spram[attr_start + 2] & 0x8000; + color = (spram[attr_start + 2] & 0x000f);// + 16 * spritepalettebank; + pri = 0;//spram[attr_start + 2] & 0x0010; + map_start = spram[attr_start + 3]; + + zoomx = 16 - zoomtable[zoomx]/8; + zoomy = 16 - zoomtable[zoomy]/8; + + 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; + + if (chip == 0) + code = f1gp_spr1cgram[map_start % (f1gp_spr1cgram_size/2)]; + else + code = f1gp_spr2cgram[map_start % (f1gp_spr2cgram_size/2)]; + + pdrawgfxzoom(bitmap,machine->gfx[1 + chip], + code, + color, + flipx,flipy, + sx,sy, + cliprect,TRANSPARENCY_PEN,15, + 0x1000 * zoomx,0x1000 * zoomy, +// pri ? 0 : 0x2); + primask); + map_start++; + } + + if (xsize == 2) map_start += 1; + if (xsize == 4) map_start += 3; + if (xsize == 5) map_start += 2; + if (xsize == 6) map_start += 1; + } + } +} + +static void f1gpb_draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect) +{ + int attr_start, start_offset = spriteram_size/2 - 4; + + // find the "end of list" to draw the sprites in reverse order + for (attr_start = 4;attr_start < spriteram_size/2;attr_start += 4) + { + if (spriteram16[attr_start+3-4] == 0xffff) /* end of list marker */ + { + start_offset = attr_start - 4; + break; + } + } + + for (attr_start = start_offset;attr_start >= 4;attr_start -= 4) + { + int code,gfx; + int x,y,flipx,flipy,color,pri; + + x = (spriteram16[attr_start + 2] & 0x03ff) - 48; + y = (256 - (spriteram16[attr_start + 3 - 4] & 0x03ff)) - 15; + flipx = spriteram16[attr_start + 1] & 0x0800; + flipy = spriteram16[attr_start + 1] & 0x8000; + color = spriteram16[attr_start + 1] & 0x000f; + code = spriteram16[attr_start + 0] & 0x3fff; + pri = 0; //? + + if((spriteram16[attr_start + 1] & 0x00f0) && (spriteram16[attr_start + 1] & 0x00f0) != 0xc0) + { + printf("attr %X\n",spriteram16[attr_start + 1] & 0x00f0); + code = mame_rand(Machine); + } + +/* + if(spriteram16[attr_start + 1] & ~0x88cf) + printf("1 = %X\n",spriteram16[attr_start + 1] & ~0x88cf); +*/ + if(code >= 0x2000) + { + gfx = 1; + code -= 0x2000; + } + else + { + gfx = 0; + } + + pdrawgfx(bitmap,machine->gfx[1 + gfx], + code, + color, + flipx,flipy, + x,y, + cliprect,TRANSPARENCY_PEN,15, + pri ? 0 : 0x2); + + // wrap around x + pdrawgfx(bitmap,machine->gfx[1 + gfx], + code, + color, + flipx,flipy, + x - 512,y, + cliprect,TRANSPARENCY_PEN,15, + pri ? 0 : 0x2); + } +} + + +VIDEO_UPDATE( f1gp ) +{ + static const gfx_layout tilelayout = + { + 16,16, + TOTAL_CHARS, + 4, + { 0, 1, 2, 3 }, +#ifdef LSB_FIRST + { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4, + 10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 }, +#else + { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4, + 8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 }, +#endif + { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, + 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 }, + 64*16, + }; + + + if (dirtygfx) + { + int i; + + dirtygfx = 0; + + for (i = 0;i < TOTAL_CHARS;i++) + { + if (dirtychar[i]) + { + dirtychar[i] = 0; + decodechar(machine->gfx[3],i,(UINT8 *)zoomdata,&tilelayout); + } + } + + tilemap_mark_all_tiles_dirty(roz_tilemap); + } + + + + fillbitmap(priority_bitmap, 0, cliprect); + + K053936_0_zoom_draw(bitmap,cliprect,roz_tilemap,0,0); + + tilemap_draw(bitmap,cliprect,fg_tilemap,0,1); + + /* quick kludge for "continue" screen priority */ + if (gfxctrl == 0x00) + { + f1gp_draw_sprites(machine,bitmap,cliprect,0,0x02); + f1gp_draw_sprites(machine,bitmap,cliprect,1,0x02); + } + else + { + f1gp_draw_sprites(machine,bitmap,cliprect,0,0x00); + f1gp_draw_sprites(machine,bitmap,cliprect,1,0x02); + } + return 0; +} + +VIDEO_UPDATE( f1gpb ) +{ + UINT32 startx,starty; + int incxx,incxy,incyx,incyy; + + static const gfx_layout tilelayout = + { + 16,16, + TOTAL_CHARS, + 4, + { 0, 1, 2, 3 }, +#ifdef LSB_FIRST + { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4, + 10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 }, +#else + { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4, + 8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 }, +#endif + { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, + 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 }, + 64*16, + }; + + + if (dirtygfx) + { + int i; + + dirtygfx = 0; + + for (i = 0;i < TOTAL_CHARS;i++) + { + if (dirtychar[i]) + { + dirtychar[i] = 0; + decodechar(machine->gfx[3],i,(UINT8 *)zoomdata,&tilelayout); + } + } + + tilemap_mark_all_tiles_dirty(roz_tilemap); + } + + incxy = (INT16)f1gpb_rozregs[1]; + incyx = -incxy; + incxx = incyy = (INT16)f1gpb_rozregs[3]; + startx = f1gpb_rozregs[0] + 328; + starty = f1gpb_rozregs[2]; + + tilemap_set_scrolly(fg_tilemap,0,f1gpb_fgregs[0] + 8); + + fillbitmap(priority_bitmap, 0, cliprect); + + tilemap_draw_roz(bitmap, cliprect, roz_tilemap, + startx << 13, starty << 13, + incxx << 5, incxy << 5, incyx << 5, incyy << 5, + 1, 0, 0); + + tilemap_draw(bitmap,cliprect,fg_tilemap,0,1); + + f1gpb_draw_sprites(machine,bitmap,cliprect); + + return 0; +} + + +static void f1gp2_draw_sprites(running_machine *machine,mame_bitmap *bitmap,const rectangle *cliprect) +{ + int offs; + + + offs = 0; + while (offs < 0x0400 && (f1gp2_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 * (f1gp2_spritelist[offs++] & 0x01ff); + + ox = f1gp2_spritelist[attr_start + 1] & 0x01ff; + xsize = (f1gp2_spritelist[attr_start + 1] & 0x0e00) >> 9; + zoomx = (f1gp2_spritelist[attr_start + 1] & 0xf000) >> 12; + oy = f1gp2_spritelist[attr_start + 0] & 0x01ff; + ysize = (f1gp2_spritelist[attr_start + 0] & 0x0e00) >> 9; + zoomy = (f1gp2_spritelist[attr_start + 0] & 0xf000) >> 12; + flipx = f1gp2_spritelist[attr_start + 2] & 0x4000; + flipy = f1gp2_spritelist[attr_start + 2] & 0x8000; + color = (f1gp2_spritelist[attr_start + 2] & 0x1f00) >> 8; + map_start = f1gp2_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 (f1gp2_spritelist[attr_start + 2] & 0x20ff) color = mame_rand(machine); + + 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 = f1gp2_sprcgram[map_start & 0x3fff]; + map_start++; + + if (flipscreen) + drawgfxzoom(bitmap,machine->gfx[1], + code, + color, + !flipx,!flipy, + 304-sx,208-sy, + cliprect,TRANSPARENCY_PEN,15, + zoomx << 11,zoomy << 11); + else + drawgfxzoom(bitmap,machine->gfx[1], + code, + color, + flipx,flipy, + sx,sy, + cliprect,TRANSPARENCY_PEN,15, + zoomx << 11,zoomy << 11); + } + } + } +} + + +VIDEO_UPDATE( f1gp2 ) +{ + if (gfxctrl & 4) /* blank screen */ + { + fillbitmap(bitmap, get_black_pen(machine), cliprect); + } + else + { + switch (gfxctrl & 3) + { + case 0: + K053936_0_zoom_draw(bitmap,cliprect,roz_tilemap,TILEMAP_DRAW_OPAQUE,0); + f1gp2_draw_sprites(machine,bitmap,cliprect); + tilemap_draw(bitmap,cliprect,fg_tilemap,0,0); + break; + case 1: + K053936_0_zoom_draw(bitmap,cliprect,roz_tilemap,TILEMAP_DRAW_OPAQUE,0); + tilemap_draw(bitmap,cliprect,fg_tilemap,0,0); + f1gp2_draw_sprites(machine,bitmap,cliprect); + break; + case 2: + tilemap_draw(bitmap,cliprect,fg_tilemap,TILEMAP_DRAW_OPAQUE,0); + K053936_0_zoom_draw(bitmap,cliprect,roz_tilemap,0,0); + f1gp2_draw_sprites(machine,bitmap,cliprect); + break; +#ifdef MAME_DEBUG + case 3: + popmessage("unsupported priority 3\n"); +#endif + } + } + return 0; +} |