/*
Malzak
Video functions
SAA 5050 -- Character display
S2636 (x2) -- Sprites, Sprite->Sprite collisions
Playfield graphics generator
(TODO: probably best to switch this to tilemaps one day, figure out banking)
*/
#include "driver.h"
#include "video/s2636.h"
static INT8 frame_count;
#define SAA5050_DBLHI 0x0001
#define SAA5050_SEPGR 0x0002
#define SAA5050_FLASH 0x0004
#define SAA5050_BOX 0x0008
#define SAA5050_GRAPH 0x0010
#define SAA5050_CONCEAL 0x0020
#define SAA5050_HOLDGR 0x0040
#define SAA5050_BLACK 0
#define SAA5050_WHITE 7
struct {
UINT16 saa5050_flags;
UINT8 saa5050_forecol;
UINT8 saa5050_backcol;
UINT8 saa5050_prvcol;
UINT8 saa5050_prvchr;
} saa5050_state;
UINT8* saa5050_vidram; /* Video RAM for SAA 5050 */
static mame_bitmap* collision_bitmap;
int malzak_x;
int malzak_y;
static struct playfield
{
//int x;
//int y;
int code;
} field[256];
VIDEO_START( malzak )
{
collision_bitmap = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,BITMAP_FORMAT_INDEXED8);
saa5050_vidram = auto_malloc(0x800);
s2636_1_ram = auto_malloc(0x100);
s2636_2_ram = auto_malloc(0x100);
}
VIDEO_UPDATE( malzak )
{
int code, colour;
int sx, sy;
int x,y;
fillbitmap(bitmap,0,0);
// SAA 5050 - Teletext character generator
for (sy = 24; sy >= 0; sy--)
{
/* Set start of line state */
saa5050_state.saa5050_flags = 0;
saa5050_state.saa5050_prvchr = 32;
saa5050_state.saa5050_forecol = SAA5050_WHITE;
saa5050_state.saa5050_prvcol = SAA5050_WHITE;
saa5050_state.saa5050_backcol = SAA5050_BLACK;
for (sx = 0; sx < 42; sx++)
{
int blank = 0;
code = saa5050_vidram[sy * 64 + sx];
if (code < 32)
{
switch (code) {
case 0x00:
blank = 1; // code 0x00 should not display anything
break; // unless HOLDGR is set
case 0x01: case 0x02: case 0x03: case 0x04:
case 0x05: case 0x06: case 0x07:
saa5050_state.saa5050_prvcol = saa5050_state.saa5050_forecol = code;
saa5050_state.saa5050_flags &= ~(SAA5050_GRAPH | SAA5050_CONCEAL);
break;
case 0x11: case 0x12: case 0x13: case 0x14:
case 0x15: case 0x16: case 0x17:
saa5050_state.saa5050_prvcol = (saa5050_state.saa5050_forecol =
(code & 0x07));
saa5050_state.saa5050_flags &= ~SAA5050_CONCEAL;
saa5050_state.saa5050_flags |= SAA5050_GRAPH;
break;
case 0x08:
saa5050_state.saa5050_flags |= SAA5050_FLASH;
break;
case 0x09:
saa5050_state.saa5050_flags &= ~SAA5050_FLASH;
break;
case 0x0a:
saa5050_state.saa5050_flags |= SAA5050_BOX;
break;
case 0x0b:
saa5050_state.saa5050_flags &= ~SAA5050_BOX;
break;
case 0x0c:
saa5050_state.saa5050_flags &= ~SAA5050_DBLHI;
break;
case 0x0d:
saa5050_state.saa5050_flags |= SAA5050_DBLHI;
break;
case 0x18:
saa5050_state.saa5050_flags |= SAA5050_CONCEAL;
break;
case 0x19:
saa5050_state.saa5050_flags |= SAA5050_SEPGR;
break;
case 0x1a:
saa5050_state.saa5050_flags &= ~SAA5050_SEPGR;
break;
case 0x1c:
saa5050_state.saa5050_backcol = SAA5050_BLACK;
break;
case 0x1d:
saa5050_state.saa5050_backcol = saa5050_state.saa5050_prvcol;
break;
case 0x1e:
saa5050_state.saa5050_flags |= SAA5050_HOLDGR;
break;
case 0x1f:
saa5050_state.saa5050_flags &= ~SAA5050_HOLDGR;
break;
}
if (saa5050_state.saa5050_flags & SAA5050_HOLDGR)
code = saa5050_state.saa5050_prvchr;
else
code = 32;
}
if (code & 0x80)
colour = (saa5050_state.saa5050_forecol << 3) | saa5050_state.saa5050_backcol;
else
colour = saa5050_state.saa5050_forecol | (saa5050_state.saa5050_backcol << 3);
if (saa5050_state.saa5050_flags & SAA5050_CONCEAL)
code = 32;
else if ((saa5050_state.saa5050_flags & SAA5050_FLASH) && (frame_count > 38))
code = 32;
else
{
saa5050_state.saa5050_prvchr = code;
if ((saa5050_state.saa5050_flags & SAA5050_GRAPH) && (code & 0x20))
{
code += (code & 0x40) ? 64 : 96;
if (saa5050_state.saa5050_flags & SAA5050_SEPGR)
code += 64;
}
}
if((blank == 0) || (saa5050_state.saa5050_flags & SAA5050_HOLDGR))
{
if (saa5050_state.saa5050_flags & SAA5050_DBLHI)
{
drawgfx (bitmap, machine->gfx[4], code, colour, 0, 0,
sx * 6, sy * 10, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0);
drawgfx (bitmap, machine->gfx[5], code, colour, 0, 0,
sx * 6, (sy + 1) * 10, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0);
}
else
{
drawgfx (bitmap, machine->gfx[3], code, colour, 0, 0,
sx * 6, sy * 10, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0);
}
}
}
if (saa5050_state.saa5050_flags & SAA5050_DBLHI)
{
sy--;
saa5050_state.saa5050_flags &= ~SAA5050_DBLHI;
}
}
frame_count++;
if(frame_count > 50)
frame_count = 0;
// playfield - not sure exactly how this works...
for(x = 0;x < 16;x++)
for(y = 0; y < 16;y++)
{
sx = ((x*16-48) - malzak_x);
sy = ((y*16) - malzak_y);
if(sx < -271)
sx+=512;
if(sx < -15)
sx+=256;
drawgfx(bitmap,machine->gfx[0],field[x*16 + y].code,7,0,0,
sx, sy, &machine->screen[0].visarea, TRANSPARENCY_COLOR, 0);
}
// S2636 - Sprites / Collision detection (x2)
s2636_x_offset = -16;
// s2636_y_offset = -8;
s2636_update_bitmap(machine,bitmap,s2636_1_ram,s2636_1_dirty,1,collision_bitmap);
s2636_update_bitmap(machine,bitmap,s2636_2_ram,s2636_2_dirty,2,collision_bitmap);
return 0;
}
WRITE8_HANDLER( playfield_w )
{
int tile = ((malzak_x / 16) * 16) + (offset / 16);
// field[tile].x = malzak_x / 16;
// field[tile].y = malzak_y;
field[tile].code = (data & 0x1f);
logerror("GFX: 0x16%02x write 0x%02x\n",offset,data);
}