summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/equites.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/equites.c')
-rw-r--r--src/mame/video/equites.c681
1 files changed, 681 insertions, 0 deletions
diff --git a/src/mame/video/equites.c b/src/mame/video/equites.c
new file mode 100644
index 00000000000..06782a87cd8
--- /dev/null
+++ b/src/mame/video/equites.c
@@ -0,0 +1,681 @@
+/*******************************************************************************
+
+Equites (c) 1984 Alpha Denshi Co./Sega
+Bull Fighter (c) 1984 Alpha Denshi Co./Sega
+The Koukouyakyuh (c) 1985 Alpha Denshi Co.
+Splendor Blast (c) 1985 Alpha Denshi Co.
+High Voltage (c) 1985 Alpha Denshi Co.
+
+drivers by Acho A. Tang
+
+*******************************************************************************/
+// Directives
+
+#include "driver.h"
+
+#define BMPAD 8
+#define BMW_l2 9
+#define FP_PRECISION 20
+#define FP_HALF ((1<<(FP_PRECISION-1))-1)
+
+/******************************************************************************/
+// Imports
+
+extern int equites_id, equites_flip;
+
+/******************************************************************************/
+// Locals
+
+static tilemap *charmap0, *charmap1, *activecharmap, *inactivecharmap;
+static UINT16 *defcharram, *charram0, *charram1, *activecharram, *inactivecharram;
+static UINT8 *dirtybuf;
+static int maskwidth, maskheight, maskcolor;
+static int scrollx, scrolly;
+static int bgcolor[4];
+static rectangle halfclip;
+static struct PRESTEP_TYPE { unsigned sy, fdx; } *prestep;
+static colortable *equites_colortable;
+
+/******************************************************************************/
+// Exports
+
+UINT16 *splndrbt_scrollx, *splndrbt_scrolly;
+
+/******************************************************************************/
+// Initializations
+
+static void video_init_common(running_machine *machine)
+{
+ int i;
+
+ // set defaults
+ maskwidth = 8;
+ maskheight = machine->screen[0].visarea.max_y - machine->screen[0].visarea.min_y + 1;
+ maskcolor = get_black_pen(machine);
+ scrollx = scrolly = 0;
+ for (i=0; i<4; i++) bgcolor[i] = 0;
+
+ // set uniques
+ switch (equites_id)
+ {
+ case 0x8401:
+ maskwidth = 16;
+ break;
+ case 0x8510:
+ scrollx = 128;
+ scrolly = 8;
+ break;
+ case 0x8511:
+ scrollx = 128;
+ scrolly = 8;
+ break;
+ }
+}
+
+// Equites Hardware
+PALETTE_INIT( equites )
+{
+ UINT8 *clut_ptr;
+ int i;
+
+ equites_colortable = colortable_alloc(machine, 256);
+
+ for (i=0; i<256; i++)
+ colortable_palette_set_color(equites_colortable, i, MAKE_RGB(pal4bit(color_prom[i]), pal4bit(color_prom[i+0x100]), pal4bit(color_prom[i+0x200])));
+
+ for (i=0; i<256; i++)
+ colortable_entry_set_value(equites_colortable, i, i);
+
+ clut_ptr = memory_region(REGION_USER1) + 0x80;
+ for (i=0; i<128; i++)
+ colortable_entry_set_value(equites_colortable, i+0x100, clut_ptr[i]);
+}
+
+static TILE_GET_INFO( equites_charinfo )
+{
+ int tile, color;
+
+ tile_index <<= 1;
+ tile = videoram16[tile_index];
+ color = videoram16[tile_index+1];
+ tile &= 0xff;
+ color &= 0x1f;
+
+ SET_TILE_INFO(0, tile, color, 0);
+}
+
+VIDEO_START( equites )
+{
+ charmap0 = tilemap_create(equites_charinfo, tilemap_scan_cols, TILEMAP_TYPE_PEN, 8, 8, 32, 32);
+ tilemap_set_transparent_pen(charmap0, 0);
+ tilemap_set_scrolldx(charmap0, BMPAD, BMPAD);
+ tilemap_set_scrolldy(charmap0, BMPAD, BMPAD);
+
+ video_init_common(machine);
+}
+
+// Splendor Blast Hardware
+PALETTE_INIT( splndrbt )
+{
+ UINT8 *prom_ptr;
+ int i;
+
+ equites_colortable = colortable_alloc(machine, 256);
+
+ for (i=0; i<0x100; i++)
+ colortable_palette_set_color(equites_colortable, i, MAKE_RGB(pal4bit(color_prom[i]), pal4bit(color_prom[i+0x100]), pal4bit(color_prom[i+0x200])));
+
+ for (i = 0; i < 0x100; i++)
+ colortable_entry_set_value(equites_colortable, i, i);
+
+ prom_ptr = memory_region(REGION_USER1);
+ for (i=0; i<0x80; i++)
+ {
+ colortable_entry_set_value(equites_colortable, i + 0x100, prom_ptr[i] + 0x10);
+ colortable_entry_set_value(equites_colortable, i + 0x180, prom_ptr[i]);
+ }
+
+ prom_ptr += 0x100;
+ for (i=0; i<0x400; i++)
+ colortable_entry_set_value(equites_colortable, i + 0x200, prom_ptr[i]);
+}
+
+static TILE_GET_INFO( splndrbt_char0info )
+{
+ int tile, color;
+
+ tile_index <<= 1;
+ tile = charram0[tile_index];
+ color = charram0[tile_index+1];
+ tile &= 0xff;
+ color &= 0x3f;
+
+ SET_TILE_INFO(0, tile, color, 0);
+ if (color & 0x10)
+ tileinfo->flags |= TILE_FORCE_LAYER0;
+}
+
+static TILE_GET_INFO( splndrbt_char1info )
+{
+ int tile, color;
+
+ tile_index <<= 1;
+ tile = charram1[tile_index];
+ color = charram1[tile_index+1];
+ tile &= 0xff;
+ color &= 0x3f;
+ tile += 0x100;
+
+ SET_TILE_INFO(0, tile, color, 0);
+ if (color & 0x10)
+ tileinfo->flags |= TILE_FORCE_LAYER0;
+}
+
+static void splndrbt_video_reset(void)
+{
+ memset(spriteram16, 0, spriteram_size);
+
+ activecharram = charram0;
+ inactivecharram = charram1;
+
+ activecharmap = charmap0;
+ inactivecharmap = charmap1;
+}
+
+static void splndrbt_prestep(
+ struct PRESTEP_TYPE *ps,
+ const rectangle *dst_clip,
+ int src_w, int src_h,
+ int dst_startw, int dst_endw)
+{
+ double DA, DB, DC, D0, D1, Dsum;
+ int i, dst_vish;
+
+ dst_vish = dst_clip->max_y - dst_clip->min_y;
+
+ DA = (double)(src_w << FP_PRECISION) * dst_vish;
+ DB = dst_endw - dst_startw;
+ DC = dst_startw * dst_vish;
+ D1 = 0;
+
+ for (i=0; i<=dst_vish; i++)
+ {
+ D0 = DA / (DB * i + DC);
+ D1 += D0;
+ ps[i].fdx = (unsigned)D0;
+ }
+
+ DA = src_w * dst_vish;
+ D0 = src_h;
+ D1 /= 1 << FP_PRECISION;
+ Dsum = 0.5;
+
+ for (i=0; i<=dst_vish; i++)
+ {
+ ps[i].sy = (unsigned)Dsum;
+ Dsum += (DA * D0) / ((DB * i + DC) * D1);
+ //logerror("dst_y=%3u src_y=%3u\n", i, ps[i].sy);
+ }
+}
+
+VIDEO_START( splndrbt )
+{
+#define BMW (1<<BMW_l2)
+
+ UINT8 *buf8ptr;
+ int i;
+
+ assert(machine->screen[0].format == BITMAP_FORMAT_INDEXED16);
+
+ halfclip = machine->screen[0].visarea;
+ i = halfclip.max_y - halfclip.min_y + 1;
+ halfclip.max_y = halfclip.min_y + (i >> 1) - 1;
+
+ tmpbitmap = auto_bitmap_alloc(BMW, BMW, machine->screen[0].format);
+
+ charmap0 = tilemap_create(splndrbt_char0info, tilemap_scan_cols, TILEMAP_TYPE_PEN, 8, 8, 32, 32);
+ tilemap_set_transparent_pen(charmap0, 0);
+ tilemap_set_scrolldx(charmap0, 8, 8);
+ tilemap_set_scrolldy(charmap0, 32, 32);
+
+ charmap1 = tilemap_create(splndrbt_char1info, tilemap_scan_cols, TILEMAP_TYPE_PEN, 8, 8, 32, 32);
+ tilemap_set_transparent_pen(charmap1, 0);
+ tilemap_set_scrolldx(charmap1, 8, 8);
+ tilemap_set_scrolldy(charmap1, 32, 32);
+
+ buf8ptr = auto_malloc(videoram_size * 2);
+ charram0 = (UINT16*)buf8ptr;
+ charram1 = (UINT16*)(buf8ptr + videoram_size);
+
+ dirtybuf = auto_malloc(0x800);
+ memset(dirtybuf, 1, 0x800);
+
+ prestep = auto_malloc(i * sizeof(struct PRESTEP_TYPE));
+ splndrbt_prestep(prestep, &machine->screen[0].visarea, BMW, 434, 96, 480);
+
+ defcharram = videoram16 + videoram_size / 2;
+
+ video_init_common(machine);
+ splndrbt_video_reset();
+}
+
+MACHINE_RESET( splndrbt )
+{
+ splndrbt_video_reset();
+}
+
+/******************************************************************************/
+// Realtime Functions
+
+// Equites Hardware
+static void equites_update_clut(running_machine *machine)
+{
+ int i, c;
+
+ /* palette hacks! */
+ c = *bgcolor;
+
+ for (i=0x80; i<0x100; i+=0x08)
+ colortable_entry_set_value(equites_colortable, i, c);
+}
+
+static void equites_draw_scroll(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
+{
+#define TILE_BANKBASE 1
+
+ int i, offsx, offsy, skipx, skipy, dispx, dispy, encode, bank, tile, color, fy, fx, fxy, x, y, flipadjx;
+
+ flipadjx = (equites_flip) ? 10 : 0;
+
+ dispy = scrolly & 0x0f;
+ offsy = scrolly & 0xf0;
+ dispx = (scrollx + flipadjx) & 0x0f;
+ offsx = (scrollx + flipadjx)>>4 & 0xf;
+ if (dispy > 7)
+ {
+ offsy += 0x10;
+ dispy -= 0x10;
+ }
+ if (dispx > 7)
+ {
+ offsx++;
+ dispx -= 0x10;
+ }
+
+ for (i=0; i<255; i++)
+ {
+ skipx = i & 0x0f;
+ skipy = i & 0xf0;
+ encode = spriteram16_2[((offsy + skipy) & 0xf0) + ((offsx + skipx) & 0x0f)];
+ bank = (encode>>8 & 0x01) + TILE_BANKBASE;
+ tile = encode & 0xff;
+ fxy = encode & 0x0800;
+ color = encode>>12 & 0x0f;
+ fx = (encode & 0x0400) | fxy;
+ fy = (encode & 0x0200) | fxy;
+ x = (skipx<<4) - dispx + BMPAD;
+ y = skipy - dispy + BMPAD;
+
+ drawgfx( bitmap,
+ machine->gfx[bank],
+ tile, color,
+ fx, fy,
+ x, y,
+ cliprect, TRANSPARENCY_NONE, 0);
+ }
+
+#undef TILE_BANKBASE
+}
+
+static void equites_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
+{
+#define SPRITE_BANKBASE 3
+#define SHIFTX -4
+#define SHIFTY 1
+
+ gfx_element *gfx;
+ UINT16 *sptr, *eptr;
+ int encode, bank, tile, color, fy, fx, fxy, absx, absy, sx, sy, flipadjx;
+
+ flipadjx = (equites_flip) ? 8 : 0;
+
+ sptr = spriteram16;
+ eptr = sptr + 0x100;
+ for (; sptr<eptr; sptr+=2)
+ {
+ encode = *(sptr + 1);
+ if (encode)
+ {
+ bank = (encode>>8 & 0x01) + SPRITE_BANKBASE;
+ gfx = machine->gfx[bank];
+ tile = encode & 0xff;
+ fxy = encode & 0x800;
+ encode = ~encode & 0xf600;
+ fx = (encode & 0x400) | fxy;
+ fy = (encode & 0x200) | fxy;
+ color = encode>>12 & 0x0f;
+ encode = *sptr;
+ sx = encode>>8 & 0xff;
+ sy = encode & 0xff;
+ absx = (sx + flipadjx + SHIFTX) & 0xff;
+ absy = (sy + SHIFTY) & 0xff;
+ if (absx >= 248) absx -= 256;
+ if (absy >= 248) absy -= 256;
+
+ drawgfx(bitmap,
+ gfx,
+ tile, color,
+ fx, fy,
+ absx + BMPAD, absy + BMPAD,
+ cliprect, TRANSPARENCY_PEN, 0);
+ }
+ }
+
+#undef SHIFTY
+#undef SHIFTX
+#undef SPRITE_BANKBASE
+}
+
+VIDEO_UPDATE( equites )
+{
+ equites_update_clut(machine);
+ equites_draw_scroll(machine, bitmap, cliprect);
+ equites_draw_sprites(machine, bitmap, cliprect);
+ plot_box(bitmap, cliprect->min_x, cliprect->min_y, maskwidth, maskheight, maskcolor);
+ plot_box(bitmap, cliprect->max_x-maskwidth+1, cliprect->min_y, maskwidth, maskheight, maskcolor);
+ tilemap_draw(bitmap, cliprect, charmap0, 0, 0);
+ return 0;
+}
+
+// Splendor Blast Hardware
+static void splndrbt_update_clut(running_machine *machine)
+{
+ int c;
+
+ /* palette hacks! */
+ c = *bgcolor;
+
+ switch(equites_id)
+ {
+ case 0x8511:
+ colortable_entry_set_value(equites_colortable, 0x114, c);
+ break;
+ }
+}
+
+static void splndrbt_draw_scroll(running_machine *machine, mame_bitmap *bitmap)
+{
+#define TILE_BANKBASE 1
+
+ int data, bank, tile, color, fx, fy, x, y, i;
+
+ for (i=0; i<0x400; i++)
+ if (dirtybuf[i])
+ {
+ dirtybuf[i] = 0;
+
+ x = (i & 0x1f) << 4;
+ y = (i & ~0x1f) >> 1;
+ if (!(data = spriteram16_2[i])) { plot_box(bitmap, x, y, 16, 16, *bgcolor); continue; }
+ tile = data & 0xff;
+ data >>= 8;
+ bank = TILE_BANKBASE;
+ color = data>>3 & 0x1f;
+ bank += data & 1;
+ fx = data & 4;
+ fy = data & 2;
+
+ drawgfx(bitmap,
+ machine->gfx[bank],
+ tile, color,
+ fx, fy,
+ x, y,
+ 0, TRANSPARENCY_NONE, 0);
+ }
+
+#undef TILE_BANKBASE
+}
+
+static void splndrbt_slantcopy(
+ mame_bitmap *src_bitmap,
+ mame_bitmap *dst_bitmap,
+ const rectangle *dst_clip,
+ int src_x, int src_y,
+ unsigned src_w, unsigned src_h,
+ unsigned dst_startw, unsigned dst_endw,
+ struct PRESTEP_TYPE *ps)
+{
+#define WRAP ((1<<BMW_l2)-1)
+
+ int src_center_x = ((src_x + (src_w>>1)) & WRAP) << FP_PRECISION;
+ int dst_pitch, dst_wdiff, dst_visw, dst_vish;
+ int dst_curline;
+
+ dst_visw = dst_clip->max_x - dst_clip->min_x + 1;
+ dst_vish = dst_clip->max_y - dst_clip->min_y;
+ dst_pitch = dst_bitmap->rowpixels;
+
+ dst_wdiff = dst_endw - dst_startw;
+
+ for (dst_curline = dst_clip->min_y; dst_curline <= dst_clip->max_y; dst_curline++)
+ {
+ const UINT16 *src_ptr = BITMAP_ADDR16(src_bitmap, (src_y + ps[dst_curline - dst_clip->min_y].sy) & WRAP, 0);
+ UINT16 *dst_ptr = BITMAP_ADDR16(dst_bitmap, dst_curline, dst_clip->min_x + dst_visw / 2);
+ int dst_xend = dst_startw + (dst_wdiff * (dst_curline - dst_clip->min_y)) / dst_vish;
+ int src_fsx = FP_HALF;
+ int src_fdx = ps[dst_curline - dst_clip->min_y].fdx;
+ int dst_x;
+
+ if (dst_xend > dst_visw) dst_xend = dst_visw;
+ dst_xend /= 2;
+
+ for (dst_x = 0; dst_x < dst_xend; dst_x++)
+ {
+ dst_ptr[-dst_x - 1] = src_ptr[((src_center_x - src_fsx) >> FP_PRECISION) & WRAP];
+ dst_ptr[dst_x] = src_ptr[((src_center_x + src_fsx) >> FP_PRECISION) & WRAP];
+ src_fsx += src_fdx;
+ }
+ }
+
+#undef WRAP
+}
+
+static void splndrbt_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *clip)
+{
+#define SPRITE_BANKBASE 3
+#define FP_ONE 0x10000
+#define SHIFTX 0
+#define SHIFTY 0
+
+ gfx_element *gfx;
+ UINT16 *data_ptr;
+ int data, sprite, fx, fy, absx, absy, sx, sy, adjy, scalex, scaley, color, i;
+
+ gfx = machine->gfx[SPRITE_BANKBASE];
+ data_ptr = spriteram16 + 1;
+
+ for (i=0; i<0x7e; i+=2)
+ {
+ data = data_ptr[i];
+ if (!data) continue;
+
+ fx = data & 0x2000;
+ fy = data & 0x1000;
+ sprite = data & 0x7f;
+ scaley = (data>>8 & 0x0f) + 1;
+ adjy = 0x10 - scaley;
+ scaley = (scaley << 12) + (scaley << 8) - 1;
+ if (scaley > FP_ONE) scaley = FP_ONE;
+
+ data = data_ptr[i+1];
+ sx = data & 0xff;
+ absx = (sx + SHIFTX) & 0xff;
+ if (absx >= 252) absx -= 256;
+
+ color = data>>8 & 0x1f;
+
+ data = data_ptr[i+0x80];
+ sy = data & 0xff;
+ absy = (-sy + adjy + SHIFTY) & 0xff;
+
+ data = data_ptr[i+0x81];
+ scalex = (data & 0x0f) + 1;
+ scalex <<= 12;
+
+ drawgfxzoom(bitmap,
+ gfx,
+ sprite, color,
+ fx, fy,
+ absx, absy, clip,
+ TRANSPARENCY_PEN, 0,
+ scalex, scaley);
+ }
+
+#undef SHIFTY
+#undef SHIFTX
+#undef FP_ONE
+#undef SPRITE_BANKBASE
+}
+
+VIDEO_UPDATE( splndrbt )
+{
+ splndrbt_update_clut(machine);
+ fillbitmap(bitmap, *bgcolor, &halfclip);
+ splndrbt_draw_scroll(machine, tmpbitmap);
+
+ splndrbt_slantcopy(
+ tmpbitmap, bitmap, cliprect,
+ *splndrbt_scrollx + scrollx, *splndrbt_scrolly + scrolly,
+ BMW, 434, 96, 480, prestep);
+
+ tilemap_draw(bitmap, cliprect, charmap1, 0, 0);
+ splndrbt_draw_sprites(machine, bitmap, cliprect);
+ tilemap_draw(bitmap, cliprect, charmap0, 0, 0);
+ return 0;
+}
+
+/******************************************************************************/
+// Memory Handlers
+
+// Equites Hardware
+READ16_HANDLER(equites_spriteram_r)
+{
+ if (*spriteram16 == 0x5555) return (0);
+ return (spriteram16[offset]);
+}
+
+WRITE16_HANDLER(equites_charram_w)
+{
+ COMBINE_DATA(videoram16 + offset);
+
+ tilemap_mark_tile_dirty(charmap0, offset>>1);
+}
+
+WRITE16_HANDLER(equites_bgcolor_w)
+{
+ if (!ACCESSING_MSB) return;
+
+ data >>= 8;
+
+ switch (equites_id)
+ {
+ case 0x8400:
+ if (!data) bgcolor[0] = 0;
+ else if (data==0x0e) bgcolor[0] = bgcolor[2];
+ else
+ {
+ bgcolor[2] = bgcolor[1];
+ bgcolor[1] = bgcolor[0] = data;
+ }
+ break;
+ default:
+ *bgcolor = data;
+ }
+}
+
+WRITE16_HANDLER(equites_scrollreg_w)
+{
+ if (ACCESSING_LSB) scrolly = data & 0xff;
+ if (ACCESSING_MSB) scrollx = data >> 8;
+}
+
+// Splendor Blast Hardware
+WRITE16_HANDLER(splndrbt_selchar0_w)
+{
+ activecharram = charram0;
+ inactivecharram = charram1;
+
+ activecharmap = charmap0;
+ inactivecharmap = charmap1;
+}
+
+WRITE16_HANDLER(splndrbt_selchar1_w)
+{
+ activecharram = charram1;
+ inactivecharram = charram0;
+
+ activecharmap = charmap1;
+ inactivecharmap = charmap0;
+}
+
+WRITE16_HANDLER(splndrbt_charram_w)
+{
+ int oddoffs = offset | 1;
+
+ COMBINE_DATA(videoram16 + offset);
+ COMBINE_DATA(defcharram + offset);
+
+ if (data==0x20 && !(offset&1))
+ {
+ activecharram[offset] = inactivecharram[offset] = 0x20;
+ activecharram[oddoffs] = inactivecharram[oddoffs] = 0x08;
+ offset >>= 1;
+ tilemap_mark_tile_dirty(activecharmap, offset);
+ tilemap_mark_tile_dirty(activecharmap, oddoffs);
+ tilemap_mark_tile_dirty(inactivecharmap, offset);
+ tilemap_mark_tile_dirty(inactivecharmap, oddoffs);
+ }
+ else
+ {
+ COMBINE_DATA(activecharram + offset);
+ tilemap_mark_tile_dirty(activecharmap, offset>>1);
+ }
+}
+
+READ16_HANDLER(splndrbt_bankedchar_r)
+{
+ if (defcharram[offset|1]==0x3f) return(0);
+ return(defcharram[offset]);
+}
+
+WRITE16_HANDLER(splndrbt_bankedchar_w)
+{
+ COMBINE_DATA(defcharram + offset);
+ COMBINE_DATA(activecharram + offset);
+ inactivecharram[offset&~1] = 0x20;
+ inactivecharram[offset|1] = 0x08;
+ offset >>= 1;
+ tilemap_mark_tile_dirty(activecharmap, offset);
+ tilemap_mark_tile_dirty(inactivecharmap, offset);
+}
+
+WRITE16_HANDLER(splndrbt_scrollram_w)
+{
+ COMBINE_DATA(spriteram16_2 + offset);
+ dirtybuf[offset] = 1;
+}
+
+#ifdef UNUSED_FUNCTION
+WRITE16_HANDLER(splndrbt_bgcolor_w)
+{
+ data >>= 8;
+
+ if (ACCESSING_MSB && *bgcolor != data)
+ {
+ *bgcolor = data;
+ memset(dirtybuf, 1, 0x400);
+ }
+}
+#endif
+
+/******************************************************************************/