#include "driver.h" #include "profiler.h" UINT8 *buggychl_scrollv,*buggychl_scrollh; 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; }