/*************************************************************************** Alpha 68k video emulation - Bryan McPhail, mish@tendril.co.uk ****************************************************************************/ #include "driver.h" static tilemap *fix_tilemap; static int bank_base,flipscreen; extern void (*alpha68k_video_banking)(int *bank, int data); extern int alpha68k_microcontroller_id; /******************************************************************************/ void alpha68k_flipscreen_w(int flip) { flipscreen = flip; } void alpha68k_V_video_bank_w(int bank) { bank_base = bank&0xf; } WRITE16_HANDLER( alpha68k_paletteram_w ) { int newword; int r,g,b; COMBINE_DATA(paletteram16 + offset); newword = paletteram16[offset]; r = ((newword >> 7) & 0x1e) | ((newword >> 14) & 0x01); g = ((newword >> 3) & 0x1e) | ((newword >> 13) & 0x01); b = ((newword << 1) & 0x1e) | ((newword >> 12) & 0x01); palette_set_color_rgb(Machine,offset,pal5bit(r),pal5bit(g),pal5bit(b)); } /******************************************************************************/ static TILE_GET_INFO( get_tile_info ) { int tile = videoram16[2*tile_index] &0xff; int color = videoram16[2*tile_index+1] &0x0f; tile=tile | (bank_base<<8); SET_TILE_INFO(0, tile, color, 0); } WRITE16_HANDLER( alpha68k_videoram_w ) { /* Doh. */ if(ACCESSING_LSB) if(ACCESSING_MSB) videoram16[offset] = data; else videoram16[offset] = data & 0xff; else videoram16[offset] = (data >> 8) & 0xff; tilemap_mark_tile_dirty(fix_tilemap,offset/2); } VIDEO_START( alpha68k ) { fix_tilemap = tilemap_create(get_tile_info,tilemap_scan_cols,TILEMAP_TYPE_PEN,8,8,32,32); tilemap_set_transparent_pen(fix_tilemap,0); } /******************************************************************************/ //AT static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int j, int s, int e) { int offs,mx,my,color,tile,fx,fy,i; for (offs = s; offs < e; offs += 0x40 ) { my = spriteram16[offs+3+(j<<1)]; mx = spriteram16[offs+2+(j<<1)]<<1 | my>>15; my = -my & 0x1ff; mx = ((mx + 0x100) & 0x1ff) - 0x100; if (j==0 && s==0x7c0) my++; //ZT if (flipscreen) { mx=240-mx; my=240-my; } for (i=0; i<0x40; i+=2) { tile = spriteram16[offs+1+i+(0x800*j)+0x800]; color = spriteram16[offs +i+(0x800*j)+0x800]&0x7f; fy=tile&0x8000; fx=tile&0x4000; tile&=0x3fff; if (flipscreen) { if (fx) fx=0; else fx=1; if (fy) fy=0; else fy=1; } if (color) drawgfx(bitmap,machine->gfx[1], tile, color, fx,fy, mx,my, cliprect,TRANSPARENCY_PEN,0); if (flipscreen) my=(my-16)&0x1ff; else my=(my+16)&0x1ff; } } } /******************************************************************************/ VIDEO_UPDATE( alpha68k_II ) { static int last_bank=0; if (last_bank!=bank_base) tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); last_bank=bank_base; tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); fillbitmap(bitmap,machine->pens[2047],cliprect); //AT draw_sprites(machine, bitmap,cliprect,0,0x07c0,0x0800); draw_sprites(machine, bitmap,cliprect,1,0x0000,0x0800); draw_sprites(machine, bitmap,cliprect,2,0x0000,0x0800); draw_sprites(machine, bitmap,cliprect,0,0x0000,0x07c0); //ZT tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); return 0; } /******************************************************************************/ /* Video banking: Write to these locations in this order for correct bank: 20 28 30 for Bank 0 60 28 30 for Bank 1 20 68 30 etc 60 68 30 20 28 70 60 28 70 20 68 70 60 68 70 for Bank 7 Actual data values written don't matter! */ WRITE16_HANDLER( alpha68k_II_video_bank_w ) { static int buffer_28,buffer_60,buffer_68; switch (offset) { case 0x10: /* Reset */ bank_base=buffer_28=buffer_60=buffer_68=0; return; case 0x14: if (buffer_60) bank_base=1; else bank_base=0; buffer_28=1; return; case 0x18: if (buffer_68) {if (buffer_60) bank_base=3; else bank_base=2; } if (buffer_28) {if (buffer_60) bank_base=1; else bank_base=0; } return; case 0x30: buffer_28=buffer_68=0; bank_base=1; buffer_60=1; return; case 0x34: if (buffer_60) bank_base=3; else bank_base=2; buffer_68=1; return; case 0x38: if (buffer_68) {if (buffer_60) bank_base=7; else bank_base=6; } if (buffer_28) {if (buffer_60) bank_base=5; else bank_base=4; } return; case 0x08: /* Graphics flags? Not related to fix chars anyway */ case 0x0c: case 0x28: case 0x2c: return; } logerror("%04x \n",offset); } /******************************************************************************/ WRITE16_HANDLER( alpha68k_V_video_control_w ) { switch (offset) { case 0x08: /* Graphics flags? Not related to fix chars anyway */ case 0x0c: case 0x28: case 0x2c: return; } } static void draw_sprites_V(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int j, int s, int e, int fx_mask, int fy_mask, int sprite_mask) { int offs,mx,my,color,tile,fx,fy,i; for (offs = s; offs < e; offs += 0x40 ) { //AT my = spriteram16[offs+3+(j<<1)]; mx = spriteram16[offs+2+(j<<1)]<<1 | my>>15; my = -my & 0x1ff; mx = ((mx + 0x100) & 0x1ff) - 0x100; if (j==0 && s==0x7c0) my++; //ZT if (flipscreen) { mx=240-mx; my=240-my; } for (i=0; i<0x40; i+=2) { tile = spriteram16[offs+1+i+(0x800*j)+0x800]; color = spriteram16[offs +i+(0x800*j)+0x800]&0xff; fx=tile&fx_mask; fy=tile&fy_mask; tile=tile&sprite_mask; if (tile>0x4fff) continue; if (flipscreen) { if (fx) fx=0; else fx=1; if (fy) fy=0; else fy=1; } if (color) drawgfx(bitmap,machine->gfx[1], tile, color, fx,fy, mx,my, cliprect,TRANSPARENCY_PEN,0); if (flipscreen) my=(my-16)&0x1ff; else my=(my+16)&0x1ff; } } } VIDEO_UPDATE( alpha68k_V ) { static int last_bank=0; if (last_bank!=bank_base) tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); last_bank=bank_base; tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); fillbitmap(bitmap,machine->pens[4095],cliprect); /* This appears to be correct priority */ if (alpha68k_microcontroller_id == 0x8814) /* Sky Adventure */ { draw_sprites_V(machine, bitmap,cliprect,0,0x07c0,0x0800,0,0x8000,0x7fff); draw_sprites_V(machine, bitmap,cliprect,1,0x0000,0x0800,0,0x8000,0x7fff); //AT: *KLUDGE* fixes priest priority in level 1(could be a game bug) if (spriteram16[0x1bde]==0x24 && (spriteram16[0x1bdf]>>8)==0x3b) { draw_sprites_V(machine, bitmap,cliprect,2,0x03c0,0x0800,0,0x8000,0x7fff); draw_sprites_V(machine, bitmap,cliprect,2,0x0000,0x03c0,0,0x8000,0x7fff); } else draw_sprites_V(machine, bitmap,cliprect,2,0x0000,0x0800,0,0x8000,0x7fff); draw_sprites_V(machine, bitmap,cliprect,0,0x0000,0x07c0,0,0x8000,0x7fff); } else /* gangwars */ { draw_sprites_V(machine, bitmap,cliprect,0,0x07c0,0x0800,0x8000,0,0x7fff); draw_sprites_V(machine, bitmap,cliprect,1,0x0000,0x0800,0x8000,0,0x7fff); draw_sprites_V(machine, bitmap,cliprect,2,0x0000,0x0800,0x8000,0,0x7fff); draw_sprites_V(machine, bitmap,cliprect,0,0x0000,0x07c0,0x8000,0,0x7fff); } tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); return 0; } VIDEO_UPDATE( alpha68k_V_sb ) { static int last_bank=0; if (last_bank!=bank_base) tilemap_mark_all_tiles_dirty(ALL_TILEMAPS); last_bank=bank_base; tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); fillbitmap(bitmap,machine->pens[4095],cliprect); /* This appears to be correct priority */ draw_sprites_V(machine,bitmap,cliprect,0,0x07c0,0x0800,0x4000,0x8000,0x3fff); draw_sprites_V(machine,bitmap,cliprect,1,0x0000,0x0800,0x4000,0x8000,0x3fff); draw_sprites_V(machine,bitmap,cliprect,2,0x0000,0x0800,0x4000,0x8000,0x3fff); draw_sprites_V(machine,bitmap,cliprect,0,0x0000,0x07c0,0x4000,0x8000,0x3fff); tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); return 0; } /******************************************************************************/ //AT static void draw_sprites_I(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int c, int d, int yshift) { int data, offs, mx, my, tile, color, fy, i; UINT8 *color_prom = memory_region(REGION_USER1); gfx_element *gfx = machine->gfx[0]; for (offs=0; offs<0x400; offs+=0x20) { mx = spriteram16[offs+c]; my = (yshift-(mx>>8)) & 0xff; mx &= 0xff; for (i=0; i<0x20; i++) { data = spriteram16[offs+d+i]; tile = data & 0x3fff; fy = data & 0x4000; color = color_prom[tile<<1|data>>15]; drawgfx(bitmap, gfx, tile, color, 0, fy, mx, my, cliprect, TRANSPARENCY_PEN, 0); my = (my + 8) & 0xff; } } } VIDEO_UPDATE( alpha68k_I ) { int yshift = (alpha68k_microcontroller_id == 0x890a) ? 1 : 0; // The Next Space is 1 pixel off fillbitmap(bitmap,machine->pens[0],cliprect); /* This appears to be correct priority */ draw_sprites_I(machine, bitmap,cliprect,2,0x0800,yshift); draw_sprites_I(machine, bitmap,cliprect,3,0x0c00,yshift); draw_sprites_I(machine, bitmap,cliprect,1,0x0400,yshift); return 0; } //ZT /******************************************************************************/ PALETTE_INIT( kyros ) { int i,bit0,bit1,bit2,bit3,r,g,b; for (i = 0;i < 256;i++) { bit0 = (color_prom[0] >> 0) & 0x01; bit1 = (color_prom[0] >> 1) & 0x01; bit2 = (color_prom[0] >> 2) & 0x01; bit3 = (color_prom[0] >> 3) & 0x01; r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[0x100] >> 0) & 0x01; bit1 = (color_prom[0x100] >> 1) & 0x01; bit2 = (color_prom[0x100] >> 2) & 0x01; bit3 = (color_prom[0x100] >> 3) & 0x01; g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[0x200] >> 0) & 0x01; bit1 = (color_prom[0x200] >> 1) & 0x01; bit2 = (color_prom[0x200] >> 2) & 0x01; bit3 = (color_prom[0x200] >> 3) & 0x01; b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; palette_set_color(machine,i,MAKE_RGB(r,g,b)); color_prom++; } color_prom += 0x200; for (i = 0;i < 256;i++) { *colortable++ = ((color_prom[0] & 0x0f) << 4) | (color_prom[0x100] & 0x0f); color_prom++; } } PALETTE_INIT( paddlem ) { int i,bit0,bit1,bit2,bit3,r,g,b; for (i = 0;i < 256;i++) { bit0 = (color_prom[0] >> 0) & 0x01; bit1 = (color_prom[0] >> 1) & 0x01; bit2 = (color_prom[0] >> 2) & 0x01; bit3 = (color_prom[0] >> 3) & 0x01; r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[0x100] >> 0) & 0x01; bit1 = (color_prom[0x100] >> 1) & 0x01; bit2 = (color_prom[0x100] >> 2) & 0x01; bit3 = (color_prom[0x100] >> 3) & 0x01; g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[0x200] >> 0) & 0x01; bit1 = (color_prom[0x200] >> 1) & 0x01; bit2 = (color_prom[0x200] >> 2) & 0x01; bit3 = (color_prom[0x200] >> 3) & 0x01; b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; palette_set_color(machine,i,MAKE_RGB(r,g,b)); color_prom++; } /* Fill in clut */ color_prom += 0x200; for (i=0; i<1024; i++) colortable[i] = color_prom[i]|(color_prom[i+0x400]<<4); } void kyros_video_banking(int *bank, int data) { *bank = (data>>13 & 4) | (data>>10 & 3); } void jongbou_video_banking(int *bank, int data) { *bank = (data>>11 & 4) | (data>>10 & 3); } static void kyros_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int c,int d) { int offs,mx,my,color,tile,i,bank,fy,fx; int data; UINT8 *color_prom = memory_region(REGION_USER1); //AT for (offs=0; offs<0x400; offs+=0x20) { mx = spriteram16[offs+c]; my = -(mx>>8) & 0xff; mx &= 0xff; if (flipscreen) { my=249-my; } for (i=0; i<0x20; i++) { data = spriteram16[offs+d+i]; if (data!=0x20) { color = color_prom[(data>>1&0x1000)|(data&0xffc)|(data>>14&3)]; if (color!=0xff) { fy = data & 0x1000; fx = 0; if(flipscreen) { if (fy) fy=0; else fy=1; fx = 1; } tile = (data>>3 & 0x400) | (data & 0x3ff); alpha68k_video_banking(&bank, data); drawgfx(bitmap, machine->gfx[bank], tile, color, fx, fy, mx, my, cliprect, TRANSPARENCY_PEN, 0); } } //ZT if(flipscreen) my=(my-8)&0xff; else my=(my+8)&0xff; } } } VIDEO_UPDATE( kyros ) { fillbitmap(bitmap,*videoram16 & 0xff,cliprect); //AT kyros_draw_sprites(machine, bitmap,cliprect,2,0x0800); kyros_draw_sprites(machine, bitmap,cliprect,3,0x0c00); kyros_draw_sprites(machine, bitmap,cliprect,1,0x0400); return 0; } /******************************************************************************/ static void sstingry_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int c,int d) { //AT int data,offs,mx,my,color,tile,i,bank,fy,fx; for (offs=0; offs<0x400; offs+=0x20) { mx = spriteram16[offs+c]; my = -(mx>>8) & 0xff; mx &= 0xff; if (mx > 0xf8) mx -= 0x100; if (flipscreen) { my=249-my; } for (i=0; i<0x20; i++) { data = spriteram16[offs+d+i]; if (data!=0x40) { fy = data & 0x1000; fx = 0; if(flipscreen) { if (fy) fy=0; else fy=1; fx = 1; } color = (data>>7 & 0x18) | (data>>13 & 7); tile = data & 0x3ff; bank = data>>10 & 3; drawgfx(bitmap, machine->gfx[bank], tile, color, fx, fy, mx, my, cliprect, TRANSPARENCY_PEN, 0); } //ZT if(flipscreen) my=(my-8)&0xff; else my=(my+8)&0xff; } } } VIDEO_UPDATE( sstingry ) { fillbitmap(bitmap,*videoram16 & 0xff,cliprect); //AT sstingry_draw_sprites(machine, bitmap,cliprect,2,0x0800); sstingry_draw_sprites(machine, bitmap,cliprect,3,0x0c00); sstingry_draw_sprites(machine, bitmap,cliprect,1,0x0400); return 0; }