diff options
Diffstat (limited to 'src/mame/video/equites.c')
-rw-r--r-- | src/mame/video/equites.c | 681 |
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 + +/******************************************************************************/ |