summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/esd16.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/esd16.c')
-rw-r--r--src/mame/video/esd16.c380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/mame/video/esd16.c b/src/mame/video/esd16.c
new file mode 100644
index 00000000000..12bac4acaa2
--- /dev/null
+++ b/src/mame/video/esd16.c
@@ -0,0 +1,380 @@
+/***************************************************************************
+
+ -= ESD 16 Bit Games =-
+
+ driver by Luca Elia (l.elia@tin.it)
+
+
+Note: if MAME_DEBUG is defined, pressing Z with:
+
+ Q / W Shows Layer 0 / 1
+ A Shows Sprites
+
+ Keys can be used together!
+
+
+ [ 2 Scrolling Layers ]
+
+ Tile Size: 8 x 8 x 8
+ Color Codes: 1 per Layer (banked for Layer 0)
+ Layer Size (tiles) : 128 x 64
+ Layer Size (pixels): 1024 x 512
+
+ [ 256 Sprites ]
+
+ Sprites are made of 16 x 16 x 5 tiles. Size can vary from 1 to
+ 8 tiles vertically, while their width is always 1 tile.
+
+ [ Priorities ]
+
+ The game only uses this scheme:
+
+ Back -> Front: Layer 0, Layer 1, Sprites
+
+***************************************************************************/
+
+#include "driver.h"
+
+/* Variables needed by drivers: */
+
+UINT16 *esd16_vram_0, *esd16_scroll_0;
+UINT16 *esd16_vram_1, *esd16_scroll_1;
+UINT16 *head_layersize;
+static int esd16_tilemap0_color = 0;
+
+/* Functions defined in video: */
+
+WRITE16_HANDLER( esd16_vram_0_w );
+WRITE16_HANDLER( esd16_vram_1_w );
+WRITE16_HANDLER( esd16_tilemap0_color_w );
+
+VIDEO_START( esd16 );
+VIDEO_UPDATE( esd16 );
+
+
+/***************************************************************************
+
+ Tilemaps
+
+ Offset: Bits: Value:
+
+ 0.w Code
+
+ Color code: layer 0 (backmost) can bank at every 256 colors,
+ layer 1 uses the first 256.
+
+***************************************************************************/
+
+static tilemap *esdtilemap_0;
+static tilemap *esdtilemap_1;
+tilemap *esdtilemap_1_16x16;
+
+static TILE_GET_INFO( get_tile_info_0 )
+{
+ UINT16 code = esd16_vram_0[tile_index];
+ SET_TILE_INFO(
+ 1,
+ code,
+ esd16_tilemap0_color,
+ 0);
+}
+
+static TILE_GET_INFO( get_tile_info_1 )
+{
+ UINT16 code = esd16_vram_1[tile_index];
+ SET_TILE_INFO(
+ 1,
+ code,
+ 0,
+ 0);
+}
+
+static TILE_GET_INFO( get_tile_info_1_16x16 )
+{
+ UINT16 code = esd16_vram_1[tile_index];
+ SET_TILE_INFO(
+ 2,
+ code,
+ 0,
+ 0);
+}
+
+WRITE16_HANDLER( esd16_vram_0_w )
+{
+ COMBINE_DATA(&esd16_vram_0[offset]);
+ tilemap_mark_tile_dirty(esdtilemap_0,offset);
+}
+
+WRITE16_HANDLER( esd16_vram_1_w )
+{
+ COMBINE_DATA(&esd16_vram_1[offset]);
+ tilemap_mark_tile_dirty(esdtilemap_1,offset);
+ tilemap_mark_tile_dirty(esdtilemap_1_16x16,offset);
+}
+
+WRITE16_HANDLER( esd16_tilemap0_color_w )
+{
+ esd16_tilemap0_color = data & 3;
+ tilemap_mark_all_tiles_dirty(esdtilemap_0);
+
+ flip_screen_set(data & 0x80);
+}
+
+
+/***************************************************************************
+
+
+ Video Hardware Init
+
+
+***************************************************************************/
+
+
+VIDEO_START( esd16 )
+{
+ esdtilemap_0 = tilemap_create( get_tile_info_0, tilemap_scan_rows,
+ TILEMAP_TYPE_PEN, 8,8, 0x80,0x40);
+
+ esdtilemap_1 = tilemap_create( get_tile_info_1, tilemap_scan_rows,
+ TILEMAP_TYPE_PEN, 8,8, 0x80,0x40);
+
+ /* hedpanic changes tilemap 1 to 16x16 at various times */
+ esdtilemap_1_16x16 = tilemap_create( get_tile_info_1_16x16, tilemap_scan_rows,
+ TILEMAP_TYPE_PEN, 16,16, 0x40,0x40);
+
+ tilemap_set_scrolldx(esdtilemap_0, -0x60 + 2, -0x60 );
+ tilemap_set_scrolldx(esdtilemap_1, -0x60 , -0x60 + 2 );
+ tilemap_set_scrolldx(esdtilemap_1_16x16, -0x60 , -0x60 + 2 );
+
+ tilemap_set_transparent_pen(esdtilemap_1,0x00);
+ tilemap_set_transparent_pen(esdtilemap_1_16x16,0x00);
+}
+
+
+
+
+/***************************************************************************
+
+ Sprites Drawing
+
+ Offset: Bits: Value:
+
+ 0.w fedc b--- ---- ----
+ ---- -a9- ---- ---- Y Size: (1 << N) Tiles
+ ---- ---8 7654 3210 Y (Signed, Bottom-Up)
+
+ 2.w Code
+
+ 4.w f--- ---- ---- ---- Sprite priority
+ -ed- ---- ---- ----
+ ---c ---- ---- ---- Color?
+ ---- ba9- ---- ---- Color
+ ---- ---8 7654 3210 X (Signed)
+
+ 6.w fedc ba9- ---- ----
+ ---- ---8 ---- ---- ? 1 (Display Sprite?)
+ ---- ---- 7654 3210
+
+- To Do: Flip X&Y ? They seem unused.
+
+***************************************************************************/
+
+static void esd16_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
+{
+ int offs;
+
+ int max_x = machine->screen[0].width;
+ int max_y = machine->screen[0].height;
+
+ for ( offs = spriteram_size/2 - 8/2; offs >= 0 ; offs -= 8/2 )
+ {
+ int y, starty, endy, incy;
+
+ int sy = spriteram16[ offs + 0 ];
+ int code = spriteram16[ offs + 1 ];
+ int sx = spriteram16[ offs + 2 ];
+ int attr = spriteram16[ offs + 3 ];
+
+ int dimy = 1 << ((sy >> 9) & 3);
+
+ int flipx = attr & 0x0000;
+ int flipy = attr & 0x0000;
+
+ int color = (sx >> 9) & 0xf;
+
+ int pri_mask;
+
+ if(sx & 0x8000)
+ pri_mask = 0xfffe; // under "tilemap 1"
+ else
+ pri_mask = 0; // above everything
+
+ sx = sx & 0x1ff;
+ if (sx >= 0x180) sx -= 0x200;
+
+ sy = 0x100 - ((sy & 0xff) - (sy & 0x100));
+ sy -= dimy*16;
+
+ if (flip_screen)
+ { flipx = !flipx; sx = max_x - sx - 1 * 16 + 2; // small offset
+ flipy = !flipy; sy = max_y - sy - dimy * 16; }
+
+ if (flipy) { starty = sy+(dimy-1)*16; endy = sy-16; incy = -16; }
+ else { starty = sy; endy = sy+dimy*16; incy = +16; }
+
+ for (y = starty ; y != endy ; y += incy)
+ {
+ pdrawgfx( bitmap, machine->gfx[0],
+ code++,
+ color,
+ flipx, flipy,
+ sx, y,
+ cliprect, TRANSPARENCY_PEN, 0, pri_mask );
+ }
+ }
+}
+
+/* note, check if i can re-merge this with the other or if its really different */
+static void hedpanic_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
+{
+ int offs;
+
+ int max_x = machine->screen[0].width;
+ int max_y = machine->screen[0].height;
+
+ for ( offs = spriteram_size/2 - 8/2; offs >= 0 ; offs -= 8/2 )
+ {
+ int y, starty, endy, incy;
+
+ int sy = spriteram16[ offs + 0 ];
+ int code = spriteram16[ offs + 1 ];
+ int sx = spriteram16[ offs + 2 ];
+// int attr = spriteram16[ offs + 3 ];
+
+ int dimy = 1 << ((sy >> 9) & 3);
+
+ int flipx = spriteram16[ offs + 0 ] & 0x2000;
+ int flipy = sy & 0x0000;
+
+ int color = (sx >> 9) & 0xf;
+
+ int pri_mask;
+
+ if(sx & 0x8000)
+ pri_mask = 0xfffe; // under "tilemap 1"
+ else
+ pri_mask = 0; // above everything
+
+ sx = sx & 0x1ff;
+ if (sx >= 0x180) sx -= 0x200;
+
+ sy &= 0x1ff;
+
+ sx -= 24;
+
+ sy = 0x1ff-sy;
+
+ if (flip_screen)
+ { flipx = !flipx; sx = max_x - sx - 1 * 16 + 2; // small offset
+ flipy = !flipy; sy = max_y - sy - dimy * 16; }
+
+ if (flipy) { starty = sy+(dimy-1)*16; endy = sy-16; incy = -16; }
+ else { starty = sy-dimy*16; endy = sy; incy = +16; }
+
+ for (y = starty ; y != endy ; y += incy)
+ {
+ pdrawgfx( bitmap, machine->gfx[0],
+ code++,
+ color,
+ flipx, flipy,
+ sx, y,
+ cliprect, TRANSPARENCY_PEN, 0, pri_mask );
+ }
+ }
+}
+
+
+
+/***************************************************************************
+
+
+ Screen Drawing
+
+
+***************************************************************************/
+
+VIDEO_UPDATE( esd16 )
+{
+ int layers_ctrl = -1;
+
+ fillbitmap(priority_bitmap,0,cliprect);
+
+ tilemap_set_scrollx(esdtilemap_0, 0, esd16_scroll_0[0]);
+ tilemap_set_scrolly(esdtilemap_0, 0, esd16_scroll_0[1]);
+
+ tilemap_set_scrollx(esdtilemap_1, 0, esd16_scroll_1[0]);
+ tilemap_set_scrolly(esdtilemap_1, 0, esd16_scroll_1[1]);
+
+#ifdef MAME_DEBUG
+if ( input_code_pressed(KEYCODE_Z) )
+{ int msk = 0;
+ if (input_code_pressed(KEYCODE_Q)) msk |= 1;
+ if (input_code_pressed(KEYCODE_W)) msk |= 2;
+ if (input_code_pressed(KEYCODE_A)) msk |= 4;
+ if (msk != 0) layers_ctrl &= msk; }
+#endif
+
+ if (layers_ctrl & 1) tilemap_draw(bitmap,cliprect,esdtilemap_0,0,0);
+ else fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ if (layers_ctrl & 2) tilemap_draw(bitmap,cliprect,esdtilemap_1,0,1);
+
+ if (layers_ctrl & 4) esd16_draw_sprites(machine,bitmap,cliprect);
+ return 0;
+}
+
+
+VIDEO_UPDATE( hedpanic )
+{
+ int layers_ctrl = -1;
+
+ fillbitmap(priority_bitmap,0,cliprect);
+
+ tilemap_set_scrollx(esdtilemap_0, 0, esd16_scroll_0[0]);
+ tilemap_set_scrolly(esdtilemap_0, 0, esd16_scroll_0[1]);
+
+#ifdef MAME_DEBUG
+if ( input_code_pressed(KEYCODE_Z) )
+{ int msk = 0;
+ if (input_code_pressed(KEYCODE_Q)) msk |= 1;
+ if (input_code_pressed(KEYCODE_W)) msk |= 2;
+ if (input_code_pressed(KEYCODE_A)) msk |= 4;
+ if (msk != 0) layers_ctrl &= msk; }
+#endif
+
+ if (layers_ctrl & 1) tilemap_draw(bitmap,cliprect,esdtilemap_0,0,0);
+ else fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ if (layers_ctrl & 2)
+ {
+ if (head_layersize[0]&0x0002)
+ {
+ tilemap_set_scrollx(esdtilemap_1_16x16, 0, esd16_scroll_1[0]);
+ tilemap_set_scrolly(esdtilemap_1_16x16, 0, esd16_scroll_1[1]);
+ tilemap_draw(bitmap,cliprect,esdtilemap_1_16x16,0,1);
+ }
+ else
+ {
+ tilemap_set_scrollx(esdtilemap_1, 0, esd16_scroll_1[0]);
+ tilemap_set_scrolly(esdtilemap_1, 0, esd16_scroll_1[1]);
+ tilemap_draw(bitmap,cliprect,esdtilemap_1,0,1);
+ }
+
+ }
+
+ if (layers_ctrl & 4) hedpanic_draw_sprites(machine,bitmap,cliprect);
+
+
+// popmessage("%04x %04x %04x %04x %04x",head_unknown1[0],head_layersize[0],head_unknown3[0],head_unknown4[0],head_unknown5[0]);
+ return 0;
+}