diff options
Diffstat (limited to 'src/mame/video/buggychl.c')
-rw-r--r-- | src/mame/video/buggychl.c | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/src/mame/video/buggychl.c b/src/mame/video/buggychl.c new file mode 100644 index 00000000000..4b93edd304d --- /dev/null +++ b/src/mame/video/buggychl.c @@ -0,0 +1,275 @@ +#include "driver.h" +#include "profiler.h" + + + +UINT8 *buggychl_scrollv,*buggychl_scrollh; +static UINT8 buggychl_sprite_lookup[0x2000]; +UINT8 *buggychl_character_ram; + +static int *dirtychar; + +static mame_bitmap *tmpbitmap1,*tmpbitmap2; +static int sl_bank,bg_on,sky_on,sprite_color_base,bg_scrollx; + + + +PALETTE_INIT( buggychl ) +{ + int i; + + /* arbitrary blue shading for the sky */ + for (i = 0;i < 128;i++) + palette_set_color(machine,i+128,MAKE_RGB(0,i,2*i)); +} + + + + +VIDEO_START( buggychl ) +{ + dirtybuffer = auto_malloc(videoram_size); + dirtychar = auto_malloc(256 * sizeof(*dirtychar)); + tmpbitmap1 = auto_bitmap_alloc(256,256,machine->screen[0].format); + tmpbitmap2 = auto_bitmap_alloc(256,256,machine->screen[0].format); + + memset(dirtybuffer,1,videoram_size); + memset(dirtychar,0xff,256 * sizeof(*dirtychar)); +} + + + +WRITE8_HANDLER( buggychl_chargen_w ) +{ + if (buggychl_character_ram[offset] != data) + { + buggychl_character_ram[offset] = data; + + dirtychar[(offset / 8) & 0xff] = 1; + } +} + +WRITE8_HANDLER( buggychl_sprite_lookup_bank_w ) +{ + sl_bank = (data & 0x10) << 8; +} + +WRITE8_HANDLER( buggychl_sprite_lookup_w ) +{ + buggychl_sprite_lookup[offset + sl_bank] = data; +} + +WRITE8_HANDLER( buggychl_ctrl_w ) +{ +/* + bit7 = lamp + bit6 = lockout + bit4 = OJMODE + bit3 = SKY OFF + bit2 = /SN3OFF + bit1 = HINV + bit0 = VINV +*/ + + flip_screen_y_set(data & 0x01); + flip_screen_x_set(data & 0x02); + + bg_on = data & 0x04; + sky_on = data & 0x08; + + sprite_color_base = (data & 0x10) ? 1*16 : 3*16; + + coin_lockout_global_w((~data & 0x40) >> 6); + set_led_status(0,~data & 0x80); +} + +WRITE8_HANDLER( buggychl_bg_scrollx_w ) +{ + bg_scrollx = -(data - 0x12); +} + + + + +static void draw_sky(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int x,y; + + for (y = 0;y < 256;y++) + { + for (x = 0;x < 256;x++) + { + *BITMAP_ADDR16(bitmap, y, x) = machine->pens[128 + x/2]; + } + } +} + + +static void draw_bg(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int offs; + int scroll[256]; + + for (offs = 0;offs < 0x400;offs++) + { + int code = videoram[0x400+offs]; + + if (dirtybuffer[0x400+offs] || dirtychar[code]) + { + int sx = offs % 32; + int sy = offs / 32; + + dirtybuffer[0x400+offs] = 0; + + if (flip_screen_x) sx = 31 - sx; + if (flip_screen_y) sy = 31 - sy; + + drawgfx(tmpbitmap1,machine->gfx[0], + code, + 2, + flip_screen_x,flip_screen_y, + 8*sx,8*sy, + NULL,TRANSPARENCY_NONE,0); + } + } + + /* first copy to a temp bitmap doing column scroll */ + for (offs = 0;offs < 256;offs++) + scroll[offs] = -buggychl_scrollv[offs/8]; + + copyscrollbitmap(tmpbitmap2,tmpbitmap1,1,&bg_scrollx,256,scroll,NULL,TRANSPARENCY_NONE,0); + + /* then copy to the screen doing row scroll */ + for (offs = 0;offs < 256;offs++) + scroll[offs] = -buggychl_scrollh[offs]; + + copyscrollbitmap(bitmap,tmpbitmap2,256,scroll,0,0,cliprect,TRANSPARENCY_COLOR,32); +} + + +static void draw_fg(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int offs; + + + for (offs = 0;offs < 0x400;offs++) + { + int sx = offs % 32; + int sy = offs / 32; + /* the following line is most likely wrong */ + int transp = (bg_on && sx >= 22) ? TRANSPARENCY_NONE : TRANSPARENCY_PEN; + + int code = videoram[offs]; + + if (flip_screen_x) sx = 31 - sx; + if (flip_screen_y) sy = 31 - sy; + + drawgfx(bitmap,machine->gfx[0], + code, + 0, + flip_screen_x,flip_screen_y, + 8*sx,8*sy, + cliprect,transp,0); + } +} + + +static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int offs; + + profiler_mark(PROFILER_USER1); + + for (offs = 0;offs < spriteram_size;offs += 4) + { + int sx,sy,flipy,zoom,ch,x,px,y; + const UINT8 *lookup; + const UINT8 *zoomx_rom,*zoomy_rom; + + + sx = spriteram[offs+3] - ((spriteram[offs+2] & 0x80) << 1); + sy = 256-64 - spriteram[offs] + ((spriteram[offs+1] & 0x80) << 1); + flipy = spriteram[offs+1] & 0x40; + zoom = spriteram[offs+1] & 0x3f; + zoomy_rom = memory_region(REGION_GFX2) + (zoom << 6); + zoomx_rom = memory_region(REGION_GFX2) + 0x2000 + (zoom << 3); + + lookup = buggychl_sprite_lookup + ((spriteram[offs+2] & 0x7f) << 6); + + for (y = 0;y < 64;y++) + { + int dy = flip_screen_y ? (255 - sy - y) : (sy + y); + + if ((dy & ~0xff) == 0) + { + int charline,base_pos; + + charline = zoomy_rom[y] & 0x07; + base_pos = zoomy_rom[y] & 0x38; + if (flipy) base_pos ^= 0x38; + + px = 0; + for (ch = 0;ch < 4;ch++) + { + int pos,code,realflipy; + const UINT8 *pendata; + + pos = base_pos + 2*ch; + code = 8 * (lookup[pos] | ((lookup[pos+1] & 0x07) << 8)); + realflipy = (lookup[pos+1] & 0x80) ? !flipy : flipy; + code += (realflipy ? (charline ^ 7) : charline); + pendata = machine->gfx[1]->gfxdata + code*16; + + for (x = 0;x < 16;x++) + { + int col; + + col = pendata[x]; + if (col) + { + int dx = flip_screen_x ? (255 - sx - px) : (sx + px); + if ((dx & ~0xff) == 0) + *BITMAP_ADDR16(bitmap, dy, dx) = machine->pens[sprite_color_base+col]; + } + + /* the following line is almost certainly wrong */ + if (zoomx_rom[7-(2*ch+x/8)] & (1 << (x & 7))) + px++; + } + } + } + } + } + + profiler_mark(PROFILER_END); +} + + +VIDEO_UPDATE( buggychl ) +{ + int code; + + + if (sky_on) + draw_sky(machine, bitmap, cliprect); + else + fillbitmap(bitmap,machine->pens[0],cliprect); + + /* decode modified characters */ + for (code = 0;code < 256;code++) + { + if (dirtychar[code]) + decodechar(machine->gfx[0],code,buggychl_character_ram,machine->drv->gfxdecodeinfo[0].gfxlayout); + } + + if (bg_on) + draw_bg(machine, bitmap, cliprect); + + draw_sprites(machine, bitmap, cliprect); + + draw_fg(machine, bitmap, cliprect); + + for (code = 0;code < 256;code++) + dirtychar[code] = 0; + return 0; +} |