/***************************************************************************
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;
}