summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/suprloco.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/suprloco.c')
-rw-r--r--src/mame/video/suprloco.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/mame/video/suprloco.c b/src/mame/video/suprloco.c
new file mode 100644
index 00000000000..35ecaf56b00
--- /dev/null
+++ b/src/mame/video/suprloco.c
@@ -0,0 +1,277 @@
+/***************************************************************************
+
+ video.c
+
+ Functions to emulate the video hardware of the machine.
+
+***************************************************************************/
+
+#include "driver.h"
+
+UINT8 *suprloco_videoram;
+
+static tilemap *bg_tilemap;
+static int control;
+
+#define SPR_Y_TOP 0
+#define SPR_Y_BOTTOM 1
+#define SPR_X 2
+#define SPR_COL 3
+#define SPR_SKIP_LO 4
+#define SPR_SKIP_HI 5
+#define SPR_GFXOFS_LO 6
+#define SPR_GFXOFS_HI 7
+
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ I'm not sure about the resistor values, I'm using the Galaxian ones.
+
+***************************************************************************/
+PALETTE_INIT( suprloco )
+{
+ int i;
+
+
+ for (i = 0;i < 512;i++)
+ {
+ int bit0,bit1,bit2,r,g,b;
+
+ /* red component */
+ bit0 = (color_prom[i] >> 0) & 0x01;
+ bit1 = (color_prom[i] >> 1) & 0x01;
+ bit2 = (color_prom[i] >> 2) & 0x01;
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* green component */
+ bit0 = (color_prom[i] >> 3) & 0x01;
+ bit1 = (color_prom[i] >> 4) & 0x01;
+ bit2 = (color_prom[i] >> 5) & 0x01;
+ g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* blue component */
+ bit0 = 0;
+ bit1 = (color_prom[i] >> 6) & 0x01;
+ bit2 = (color_prom[i] >> 7) & 0x01;
+ b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette_set_color(machine,i,MAKE_RGB(r,g,b));
+
+ /* hack: generate a second bank of sprite palette with red changed to purple */
+ if (i >= 256)
+ {
+ if ((i & 0x0f) == 0x09)
+ palette_set_color(machine,i+256,MAKE_RGB(r,g,0xff));
+ else
+ palette_set_color(machine,i+256,MAKE_RGB(r,g,b));
+ }
+ }
+}
+
+
+
+/***************************************************************************
+
+ Callbacks for the TileMap code
+
+***************************************************************************/
+
+static TILE_GET_INFO( get_tile_info )
+{
+ UINT8 attr = suprloco_videoram[2*tile_index+1];
+ SET_TILE_INFO(
+ 0,
+ suprloco_videoram[2*tile_index] | ((attr & 0x03) << 8),
+ (attr & 0x1c) >> 2,
+ 0);
+ tileinfo->category = (attr & 0x20) >> 5;
+}
+
+
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+
+VIDEO_START( suprloco )
+{
+ bg_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
+
+ tilemap_set_scroll_rows(bg_tilemap,32);
+}
+
+
+
+/***************************************************************************
+
+ Memory handlers
+
+***************************************************************************/
+
+WRITE8_HANDLER( suprloco_videoram_w )
+{
+ suprloco_videoram[offset] = data;
+ tilemap_mark_tile_dirty(bg_tilemap,offset/2);
+}
+
+static int suprloco_scrollram[32];
+
+WRITE8_HANDLER( suprloco_scrollram_w )
+{
+ int adj = flip_screen ? -8 : 8;
+
+ suprloco_scrollram[offset] = data;
+ tilemap_set_scrollx(bg_tilemap,offset, data - adj);
+}
+
+READ8_HANDLER( suprloco_scrollram_r )
+{
+ return suprloco_scrollram[offset];
+}
+
+WRITE8_HANDLER( suprloco_control_w )
+{
+ /* There is probably a palette select in here */
+
+ /* Bit 0 - coin counter A */
+ /* Bit 1 - coin counter B (only used if coinage differs from A) */
+ /* Bit 2-3 - probably unused */
+ /* Bit 4 - ??? */
+ /* Bit 5 - pulsated when loco turns "super" */
+ /* Bit 6 - probably unused */
+ /* Bit 7 - flip screen */
+
+ if ((control & 0x10) != (data & 0x10))
+ {
+ /*logerror("Bit 4 = %d\n", (data >> 4) & 1); */
+ }
+
+ coin_counter_w(0, data & 0x01);
+ coin_counter_w(1, data & 0x02);
+
+ flip_screen_set(data & 0x80);
+ tilemap_set_scrolly(bg_tilemap,0,flip_screen ? -32 : 0);
+
+ control = data;
+}
+
+
+READ8_HANDLER( suprloco_control_r )
+{
+ return control;
+}
+
+
+
+INLINE void draw_pixel(mame_bitmap *bitmap,const rectangle *cliprect,int x,int y,int color)
+{
+ if (flip_screen)
+ {
+ x = bitmap->width - x - 1;
+ y = bitmap->height - y - 1;
+ }
+
+ if (x < cliprect->min_x ||
+ x > cliprect->max_x ||
+ y < cliprect->min_y ||
+ y > cliprect->max_y)
+ return;
+
+ *BITMAP_ADDR16(bitmap, y, x) = color;
+}
+
+
+static void draw_sprite(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect,int spr_number)
+{
+ int sx,sy,col,row,height,src,adjy,dy;
+ UINT8 *spr_reg;
+ const pen_t *spr_palette;
+ short skip; /* bytes to skip before drawing each row (can be negative) */
+
+
+ spr_reg = spriteram + 0x10 * spr_number;
+
+ src = spr_reg[SPR_GFXOFS_LO] + (spr_reg[SPR_GFXOFS_HI] << 8);
+ skip = spr_reg[SPR_SKIP_LO] + (spr_reg[SPR_SKIP_HI] << 8);
+
+ height = spr_reg[SPR_Y_BOTTOM] - spr_reg[SPR_Y_TOP];
+ spr_palette = machine->remapped_colortable + 0x100 + 0x10 * (spr_reg[SPR_COL]&0x03) + ((control & 0x20)?0x100:0);
+ sx = spr_reg[SPR_X];
+ sy = spr_reg[SPR_Y_TOP] + 1;
+
+ if (!flip_screen)
+ {
+ adjy = sy;
+ dy = 1;
+ }
+ else
+ {
+ adjy = sy + height + 30; /* some of the sprites are still off by a pixel */
+ dy = -1;
+ }
+
+ for (row = 0;row < height;row++,adjy+=dy)
+ {
+ int color1,color2,flipx;
+ UINT8 data;
+ UINT8 *gfx;
+
+ src += skip;
+
+ col = 0;
+
+ /* get pointer to packed sprite data */
+ gfx = &(memory_region(REGION_GFX2)[src & 0x7fff]);
+ flipx = src & 0x8000; /* flip x */
+
+ while (1)
+ {
+ if (flipx) /* flip x */
+ {
+ data = *gfx--;
+ color1 = data & 0x0f;
+ color2 = data >> 4;
+ }
+ else
+ {
+ data = *gfx++;
+ color1 = data >> 4;
+ color2 = data & 0x0f;
+ }
+
+ if (color1 == 15) break;
+ if (color1)
+ draw_pixel(bitmap,cliprect,sx+col, adjy,spr_palette[color1]);
+
+ if (color2 == 15) break;
+ if (color2)
+ draw_pixel(bitmap,cliprect,sx+col+1,adjy,spr_palette[color2]);
+
+ col += 2;
+ }
+ }
+}
+
+static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
+{
+ int spr_number;
+ UINT8 *spr_reg;
+
+
+ for (spr_number = 0;spr_number < (spriteram_size >> 4);spr_number++)
+ {
+ spr_reg = spriteram + 0x10 * spr_number;
+ if (spr_reg[SPR_X] != 0xff)
+ draw_sprite(machine, bitmap, cliprect, spr_number);
+ }
+}
+
+VIDEO_UPDATE( suprloco )
+{
+ tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
+ draw_sprites(machine, bitmap,cliprect);
+ tilemap_draw(bitmap,cliprect,bg_tilemap,1,0);
+ return 0;
+}