summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/taito_f3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/taito_f3.cpp')
-rw-r--r--src/mame/video/taito_f3.cpp3111
1 files changed, 0 insertions, 3111 deletions
diff --git a/src/mame/video/taito_f3.cpp b/src/mame/video/taito_f3.cpp
deleted file mode 100644
index 2d1ae3b058e..00000000000
--- a/src/mame/video/taito_f3.cpp
+++ /dev/null
@@ -1,3111 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail
-/***************************************************************************
-
- Taito F3 Video emulation - Bryan McPhail, mish@tendril.co.uk
-
-****************************************************************************
-
-Brief overview:
-
- 4 scrolling layers (512x512 or 1024x512) of 4/5/6 bpp tiles.
- 1 scrolling text layer (512x512, characters generated in vram), 4bpp chars.
- 1 scrolling pixel layer (512x256 pixels generated in pivot ram), 4bpp pixels.
- 2 sprite banks (for double buffering of sprites)
- Sprites can be 4, 5 or 6 bpp
- Sprite scaling.
- Rowscroll on all playfields
- Line by line zoom on all playfields
- Column scroll on all playfields
- Line by line sprite and playfield priority mixing
-
-Notes:
- All special effects are controlled by an area in 'line ram'. Typically
- there are 256 values, one for each line of the screen (including clipped
- lines at the top of the screen). For example, at 0x8000 in lineram,
- there are 4 sets of 256 values (one for each playfield) and each value
- is the scale control for that line in the destination bitmap (screen).
- Therefore each line can have a different zoom value for special effects.
-
- This also applies to playfield priority, rowscroll, column scroll, sprite
- priority and VRAM/pivot layers.
-
- However - at the start of line ram there are also sets of 256 values
- controlling each effect - effects can be selectively applied to individual
- playfields or only certain lines out of the 256 can be active - in which
- case the last allowed value can be latched (typically used so a game can
- use one zoom or row value over the whole playfield).
-
- The programmers of some of these games made strange use of flipscreen -
- some games have all their graphics flipped in ROM, and use the flipscreen
- bit to display them correctly!.
-
- Most games display 232 scanlines, but some use lineram effects to clip
- themselves to 224 or less.
-
-****************************************************************************
-
-Line ram memory map:
-
- Here 'playfield 1' refers to the first playfield in memory, etc
-
- 0x0000: Column line control ram (256 lines)
- 100x: Where bit 0 of x enables effect on playfield 1
- Where bit 1 of x enables effect on playfield 2
- Where bit 2 of x enables effect on playfield 3
- Where bit 3 of x enables effect on playfield 4
- 0x0200: Line control ram for 0x5000 section.
- 0x0400: Line control ram for 0x6000 section.
- 180x: Where bit 0 of x latches sprite alpha value
- Where bit 1 of x latches tilemap alpha value
- 0x0600: Sprite control ram
- 1c0x: Where x enables sprite control word for that line
- 0x0800: Zoom line control ram (256 lines)
- 200x: Where bit 0 of x enables effect on playfield 1
- Where bit 1 of x enables effect on playfield 2
- Where bit 2 of x enables effect on playfield 3
- Where bit 3 of x enables effect on playfield 4
- 0x0a00: Assumed unused.
- 0x0c00: Rowscroll line control ram (256 lines)
- 280x: Where bit 0 of x enables effect on playfield 1
- Where bit 1 of x enables effect on playfield 2
- Where bit 2 of x enables effect on playfield 3
- Where bit 3 of x enables effect on playfield 4
- 0x0e00: Priority line control ram (256 lines)
- 2c0x: Where bit 0 of x enables effect on playfield 1
- Where bit 1 of x enables effect on playfield 2
- Where bit 2 of x enables effect on playfield 3
- Where bit 3 of x enables effect on playfield 4
-
- 0x4000: Column scroll & clipping info
-
- 0x5000: Clip plane 0 (low bits)
- 0x5200: Clip plane 1 (low bits)
- 0x5400: Unused?
- 0x5600: Used by quizhuhu (taito logo and ingame text), and landmakr (winning text),
- special clip used in tandem with b*00 bit 11? [unemulated]
-
- 0x6000: Sync register
- 0x6004: Sprite alpha control
- 0xff00: VRAM/Pixel layer control
- 0xa000 enables pixel layer for this line (Disables VRAM layer)
- 0x2000 enables garbage pixels for this line (maybe another pixel bank?) [unemulated]
- 0x0800 seems to set the vram layer to be opaque [unemulated]
- Effect of other bits is unknown.
- 0x00c0: Alpha mode for sprites with pri value 0x00
- 0x0030: Alpha mode for sprites with pri value 0x00
- 0x000c: Alpha mode for sprites with pri value 0x00
- 0x0003: Alpha mode for sprites with pri value 0x00
- 0x6200: Alpha blending control
-
- 0x6400 - controls X zoom of tile - each tile collapses to 16 single colour lines
- xxx1 - affects bottom playfield
- xxx2 -
- xxx4 -
- xxx8 - affects top playfield
- xxfx - x zoom - 0 = 1st pixel 16 times
- 1 = 1st pixel 8, then 2nd 8
- 8 = 2 per pixel
-
- (these effects only known to be used on spcinvdj title screen and riding fight - not emulated)
-
- 1xxx = interpret palette ram for this playfield line as 15 bit and bilinear filter framebuffer(??)
- 3xxx = interpret palette ram for this playfield line as 15 bit
- 7xxx = interpret palette ram for this playfield line as 24 bit palette
- 8xxx = interpret palette ram for this playfield line as 21 bit palette
-
- (effect not emulated)
-
- 0x6600: Background - background palette entry (under all tilemaps) (takes part in alpha blending)
-
- (effect not emulated)
-
- 0x7000: Pivot/vram layer enable
- 0x7200: Cram layer priority
- 0x7400: Sprite clipping
- 0x7600: Sprite priority values
- 0xf000: Relative priority for sprites with pri value 0xc0
- 0x0f00: Relative priority for sprites with pri value 0x80
- 0x00f0: Relative priority for sprites with pri value 0x40
- 0x000f: Relative priority for sprites with pri value 0x00
-
- 0x8000: Playfield 1 scale (1 word per line, 256 lines, 0x80 = default no scale)
- 0x8200: Playfield 2/4 scale
- 0x8400: Playfield 3 scale
- 0x8600: Playfield 2/4 scale
- 0x00ff = Y scale (0x80 = no scale, > 0x80 is zoom in, < 0x80 is zoom out [0xc0 is half height of 0x80])
- 0xff00 = X scale (0 = no scale, > 0 = zoom in, [0x8000 would be double length])
-
- Playfield 2 & 4 registers seem to be interleaved, playfield 2 Y zoom is stored where you would
- expect playfield 4 y zoom to be and vice versa.
-
- 0x9000: Palette add (can affect opacity) [ not emulated ]
-
- 0xa000: Playfield 1 rowscroll (1 word per line, 256 lines)
- 0xa200: Playfield 2 rowscroll
- 0xa400: Playfield 3 rowscroll
- 0xa600: Playfield 4 rowscroll
-
- 0xb000: Playfield 1 priority (1 word per line, 256 lines)
- 0xb200: Playfield 2 priority
- 0xb400: Playfield 3 priority
- 0xb600: Playfield 4 priority
- 0xf000 = Blend mode, 0x3000 = Normal, 0x7000 = Alpha A, 0xb000 = Alpha B, others disable line
- 0x0800 = Clip line (totally disable line)
- 0x0400 = Assumed unused
- 0x0200 = If set enable clip plane 1
- 0x0100 = If set enable clip plane 0
- 0x00c0 = Assumed unused
- 0x0020 = Enable clip inverse mode for plane 1
- 0x0010 = Enable clip inverse mode for plane 0
- 0x000f = Layer priority
-
- 0xc000 - 0xffff: Unused.
-
- When sprite priority==playfield priority sprite takes precedence (Bubble Symph title)
-
-****************************************************************************
-
- F3 sprite format:
-
- Word 0: 0xffff Tile number (LSB)
- Word 1: 0xff00 X zoom
- 0x00ff Y zoom
- Word 2: 0x03ff X position
- Word 3: 0x03ff Y position
- Word 4: 0xf000 Sprite block controls
- 0x0800 Sprite block start
- 0x0400 Use same colour on this sprite as block start
- 0x0200 Y flip
- 0x0100 X flip
- 0x00ff Colour
- Word 5: 0xffff Tile number (MSB), probably only low bits used
- Word 6: 0x8000 If set, jump to sprite location in low bits
- 0x03ff Location to jump to.
- Word 7: 0xffff Unused? Always zero?
-
-****************************************************************************
-
- Playfield control information (0x660000-1f):
-
- Word 0- 3: X scroll values for the 4 playfields.
- Word 4- 7: Y scroll values for the 4 playfields.
- Word 8-11: Unused. Always zero.
- Word 12: Pixel + VRAM playfields X scroll
- Word 13: Pixel + VRAM playfields Y scroll
- Word 14: Unused. Always zero.
- Word 15: If set to 0x80, then 1024x512 playfields are used, else 512x512
-
- top bits unused - writing to low 4 bits is desync or blank tilemap
-
-Playfield tile info:
- 0xc000 0000 - X/Y Flip
- 0x3000 ffff - Tile index
- 0x0c00 0000 - Extra planes enable (00 = 4bpp, 01 = 5bpp, 10 = unused?, 11 = 6bpp)
- 0x0200 0000 - Alpha blend mode
- 0x01ff 0000 - Colour
-
-***************************************************************************/
-
-#include "emu.h"
-#include "includes/taito_f3.h"
-#include "render.h"
-
-#include <algorithm>
-
-#define VERBOSE 0
-#define DARIUSG_KLUDGE
-//#define DEBUG_F3 1
-
-
-/* Game specific data, some of this can be
-removed when the software values are figured out */
-struct F3config
-{
- int name;
- int extend;
- int sprite_lag;
-};
-
-static const F3config f3_config_table[] =
-{
- /* Name Extend Lag */
- { RINGRAGE, 0, 2 },
- { ARABIANM, 0, 2 },
- { RIDINGF, 1, 1 },
- { GSEEKER, 0, 1 },
- { COMMANDW, 1, 1 },
- { SCFINALS, 0, 1 },
- { TRSTAR, 1, 0 },
- { GUNLOCK, 1, 2 },
- { LIGHTBR, 1, 2 },
- { KAISERKN, 0, 2 },
- { DARIUSG, 0, 2 },
- { BUBSYMPH, 1, 1 },
- { SPCINVDX, 1, 1 },
- { HTHERO95, 0, 1 },
- { QTHEATER, 1, 1 },
- { EACTION2, 1, 2 },
- { RECALH, 1, 1 },
- { SPCINV95, 0, 1 },
- { TWINQIX, 1, 1 },
- { QUIZHUHU, 1, 1 },
- { PBOBBLE2, 0, 1 },
- { GEKIRIDO, 0, 1 },
- { KTIGER2, 0, 0 },
- { BUBBLEM, 1, 1 },
- { CLEOPATR, 0, 1 },
- { PBOBBLE3, 0, 1 },
- { ARKRETRN, 1, 1 },
- { KIRAMEKI, 0, 1 },
- { PUCHICAR, 1, 1 },
- { PBOBBLE4, 0, 1 },
- { POPNPOP, 1, 1 },
- { LANDMAKR, 1, 1 },
- { TMDRILL, 1, 0 },
- {0}
-};
-
-
-/*
-alpha_mode
----- --xx 0:disable 1:nomal 2:alpha 7000 3:alpha b000
----1 ---- alpha level a
---1- ---- alpha level b
-1-------- opaque line
-*/
-
-
-/*
-pri_alp_bitmap
----- ---1 sprite priority 0
----- --1- sprite priority 1
----- -1-- sprite priority 2
----- 1--- sprite priority 3
----1 ---- alpha level a 7000
---1- ---- alpha level b 7000
--1-- ---- alpha level a b000
-1--- ---- alpha level b b000
-1111 1111 opaque pixel
-*/
-
-
-void taito_f3_state::device_post_load()
-{
- /* force a reread of the dynamic tiles in the pixel layer */
- m_gfxdecode->gfx(0)->mark_all_dirty();
- m_gfxdecode->gfx(1)->mark_all_dirty();
-}
-
-/******************************************************************************/
-
-void taito_f3_state::print_debug_info(bitmap_rgb32 &bitmap)
-{
-/* u16 *line_ram = m_line_ram;
- int l[16];
- char buf[64*16];
- char *bufptr = buf;
-
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X\n", m_control_0[0] >> 6, m_control_0[1] >> 6, m_control_0[2] >> 6, m_control_0[3] >> 6);
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X\n", m_control_0[4] >> 7, m_control_0[5] >> 7, m_control_0[6] >> 7, m_control_0[7] >> 7);
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X\n", m_control_1[0], m_control_1[1], m_control_1[2], m_control_1[3]);
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X\n", m_control_1[4], m_control_1[5], m_control_1[6], m_control_1[7]);
-
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X %04X %04X %04X %04X\n", m_spriteram16_buffered[0], m_spriteram16_buffered[1], m_spriteram16_buffered[2], m_spriteram16_buffered[3], m_spriteram16_buffered[4], m_spriteram16_buffered[5], m_spriteram16_buffered[6], m_spriteram16_buffered[7]);
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X %04X %04X %04X %04X\n", m_spriteram16_buffered[8], m_spriteram16_buffered[9], m_spriteram16_buffered[10], m_spriteram16_buffered[11], m_spriteram16_buffered[12], m_spriteram16_buffered[13], m_spriteram16_buffered[14], m_spriteram16_buffered[15]);
- bufptr += sprintf(bufptr,"%04X %04X %04X %04X %04X %04X %04X %04X\n", m_spriteram16_buffered[16], m_spriteram16_buffered[17], m_spriteram16_buffered[18], m_spriteram16_buffered[19], m_spriteram16_buffered[20], m_spriteram16_buffered[21], m_spriteram16_buffered[22], m_spriteram16_buffered[23]);
-
- l[0] = line_ram[0x0040*2] & 0xffff;
- l[1] = line_ram[0x00c0*2] & 0xffff;
- l[2] = line_ram[0x0140*2] & 0xffff;
- l[3] = line_ram[0x01c0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Ctr1: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x0240*2] & 0xffff;
- l[1] = line_ram[0x02c0*2] & 0xffff;
- l[2] = line_ram[0x0340*2] & 0xffff;
- l[3] = line_ram[0x03c0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Ctr2: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x2c60*2] & 0xffff;
- l[1] = line_ram[0x2ce0*2] & 0xffff;
- l[2] = line_ram[0x2d60*2] & 0xffff;
- l[3] = line_ram[0x2de0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Pri : %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x2060*2] & 0xffff;
- l[1] = line_ram[0x20e0*2] & 0xffff;
- l[2] = line_ram[0x2160*2] & 0xffff;
- l[3] = line_ram[0x21e0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Zoom: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x2860*2] & 0xffff;
- l[1] = line_ram[0x28e0*2] & 0xffff;
- l[2] = line_ram[0x2960*2] & 0xffff;
- l[3] = line_ram[0x29e0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Line: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x1c60*2] & 0xffff;
- l[1] = line_ram[0x1ce0*2] & 0xffff;
- l[2] = line_ram[0x1d60*2] & 0xffff;
- l[3] = line_ram[0x1de0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Sprt: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x1860*2] & 0xffff;
- l[1] = line_ram[0x18e0*2] & 0xffff;
- l[2] = line_ram[0x1960*2] & 0xffff;
- l[3] = line_ram[0x19e0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Pivt: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x1060*2] & 0xffff;
- l[1] = line_ram[0x10e0*2] & 0xffff;
- l[2] = line_ram[0x1160*2] & 0xffff;
- l[3] = line_ram[0x11e0*2] & 0xffff;
- bufptr += sprintf(bufptr,"Colm: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- l[0] = line_ram[0x1460*2] & 0xffff;
- l[1] = line_ram[0x14e0*2] & 0xffff;
- l[2] = line_ram[0x1560*2] & 0xffff;
- l[3] = line_ram[0x15e0*2] & 0xffff;
- bufptr += sprintf(bufptr,"5000: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
-
- machine().ui().draw_text(&machine().render().ui_container(), buf, 60, 40); */
-}
-
-/******************************************************************************/
-
-template<unsigned Layer>
-TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info)
-{
- const u32 tile = (m_pf_data[Layer][tile_index * 2 + 0] << 16) | (m_pf_data[Layer][tile_index * 2 + 1] & 0xffff);
- const u8 abtype = (tile >> (16 + 9)) & 1;
- // tiles can be configured to use 4, 5, or 6 bpp data.
- // if tiles use more than 4bpp, the bottom bits of the color code must be masked out.
- // This fixes (at least) the rain in round 6 of Arabian Magic.
- const u8 extra_planes = ((tile >> (16 + 10)) & 3); // 0 = 4bpp, 1 = 5bpp, 2 = unused?, 3 = 6bpp
-
- SET_TILE_INFO_MEMBER(3,
- tile & 0xffff,
- (tile >> 16) & 0x1ff & (~extra_planes),
- TILE_FLIPYX(tile >> 30));
- tileinfo.category = abtype & 1; /* alpha blending type */
- tileinfo.pen_mask = (extra_planes << 4) | 0x0f;
-}
-
-
-TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info_text)
-{
- int flags = 0;
-
- const u16 vram_tile = (m_textram[tile_index] & 0xffff);
-
- if (vram_tile & 0x0100) flags |= TILE_FLIPX;
- if (vram_tile & 0x8000) flags |= TILE_FLIPY;
-
- SET_TILE_INFO_MEMBER(0,
- vram_tile & 0xff,
- (vram_tile >> 9) & 0x3f,
- flags);
-}
-
-TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info_pixel)
-{
- int col_off;
- int flags = 0;
- int y_offs = (m_control_1[5] & 0x1ff);
- if (m_flipscreen) y_offs += 0x100;
-
- /* Colour is shared with VRAM layer */
- if ((((tile_index & 0x1f) * 8 + y_offs) & 0x1ff) > 0xff)
- col_off = 0x800 + ((tile_index & 0x1f) << 6) + ((tile_index & 0xfe0) >> 5);
- else
- col_off = ((tile_index & 0x1f) << 6) + ((tile_index & 0xfe0) >> 5);
-
- const u16 vram_tile = (m_textram[col_off] & 0xffff);
-
- if (vram_tile & 0x0100) flags |= TILE_FLIPX;
- if (vram_tile & 0x8000) flags |= TILE_FLIPY;
-
- SET_TILE_INFO_MEMBER(1,
- tile_index,
- (vram_tile >> 9) & 0x3f,
- flags);
-}
-
-/******************************************************************************/
-
-WRITE_LINE_MEMBER(taito_f3_state::screen_vblank)
-{
- // rising edge
- if (state)
- {
- if (m_sprite_lag==2)
- {
- if (machine().video().skip_this_frame() == 0)
- {
- get_sprite_info(m_spriteram16_buffered.get());
- }
- memcpy(m_spriteram16_buffered.get(), m_spriteram.target(), 0x10000);
- }
- else if (m_sprite_lag == 1)
- {
- if (machine().video().skip_this_frame() == 0)
- {
- get_sprite_info(m_spriteram.target());
- }
- }
- }
-}
-
-void taito_f3_state::video_start()
-{
- const F3config *pCFG = &f3_config_table[0];
-
- m_alpha_level_2as = 127;
- m_alpha_level_2ad = 127;
- m_alpha_level_3as = 127;
- m_alpha_level_3ad = 127;
- m_alpha_level_2bs = 127;
- m_alpha_level_2bd = 127;
- m_alpha_level_3bs = 127;
- m_alpha_level_3bd = 127;
- m_alpha_level_last = -1;
-
- m_pdest_2a = 0x10;
- m_pdest_2b = 0x20;
- m_tr_2a = 0;
- m_tr_2b = 1;
- m_pdest_3a = 0x40;
- m_pdest_3b = 0x80;
- m_tr_3a = 0;
- m_tr_3b = 1;
-
- m_spritelist = nullptr;
- m_spriteram16_buffered = nullptr;
- m_pf_line_inf = nullptr;
- m_tile_opaque_sp = nullptr;
-
- /* Setup individual game */
- do {
- if (pCFG->name == m_game)
- {
- break;
- }
- pCFG++;
- } while (pCFG->name);
-
- m_game_config=pCFG;
-
- if (m_game_config->extend)
- {
- m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<0>), this), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
- m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<1>), this), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
- m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<2>), this), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
- m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<3>), this), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
-
- m_pf_data[0] = m_pf_ram + (0x0000 / 2);
- m_pf_data[1] = m_pf_ram + (0x2000 / 2);
- m_pf_data[2] = m_pf_ram + (0x4000 / 2);
- m_pf_data[3] = m_pf_ram + (0x6000 / 2);
-
- m_width_mask = 0x3ff;
- m_twidth_mask = 0x7f;
- m_twidth_mask_bit = 7;
-
- m_tilemap[0]->set_transparent_pen(0);
- m_tilemap[1]->set_transparent_pen(0);
- m_tilemap[2]->set_transparent_pen(0);
- m_tilemap[3]->set_transparent_pen(0);
- }
- else
- {
- m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<0>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<1>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<2>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<3>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<4>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[5] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<5>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[6] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<6>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
- m_tilemap[7] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info<7>), this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
-
- m_pf_data[0] = m_pf_ram + (0x0000 / 2);
- m_pf_data[1] = m_pf_ram + (0x1000 / 2);
- m_pf_data[2] = m_pf_ram + (0x2000 / 2);
- m_pf_data[3] = m_pf_ram + (0x3000 / 2);
- m_pf_data[4] = m_pf_ram + (0x4000 / 2);
- m_pf_data[5] = m_pf_ram + (0x5000 / 2);
- m_pf_data[6] = m_pf_ram + (0x6000 / 2);
- m_pf_data[7] = m_pf_ram + (0x7000 / 2);
-
- m_width_mask = 0x1ff;
- m_twidth_mask = 0x3f;
- m_twidth_mask_bit = 6;
-
- m_tilemap[0]->set_transparent_pen(0);
- m_tilemap[1]->set_transparent_pen(0);
- m_tilemap[2]->set_transparent_pen(0);
- m_tilemap[3]->set_transparent_pen(0);
- m_tilemap[4]->set_transparent_pen(0);
- m_tilemap[5]->set_transparent_pen(0);
- m_tilemap[6]->set_transparent_pen(0);
- m_tilemap[7]->set_transparent_pen(0);
- }
-
- m_spriteram16_buffered = std::make_unique<u16[]>(0x10000 / 2);
- m_spritelist = std::make_unique<tempsprite[]>(0x400);
- m_sprite_end = &m_spritelist[0];
- m_vram_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info_text), this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
- m_pixel_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(taito_f3_state::get_tile_info_pixel), this), TILEMAP_SCAN_COLS, 8, 8, 64, 32);
- m_pf_line_inf = std::make_unique<f3_playfield_line_inf[]>(5);
- m_sa_line_inf = std::make_unique<f3_spritealpha_line_inf[]>(1);
- m_screen->register_screen_bitmap(m_pri_alp_bitmap);
- m_tile_opaque_sp = std::make_unique<u8[]>(m_gfxdecode->gfx(2)->elements());
- for (int i = 0; i < 8; i++)
- m_tile_opaque_pf[i] = std::make_unique<u8[]>(m_gfxdecode->gfx(3)->elements());
-
- m_vram_layer->set_transparent_pen(0);
- m_pixel_layer->set_transparent_pen(0);
-
- /* Palettes have 4 bpp indexes despite up to 6 bpp data. The unused */
- /* top bits in the gfx data are cleared later. */
- m_gfxdecode->gfx(2)->set_granularity(16);
- m_gfxdecode->gfx(3)->set_granularity(16);
-
- m_flipscreen = 0;
- memset(m_spriteram16_buffered.get(), 0, 0x10000);
- memset(&m_spriteram[0], 0, 0x10000);
-
- save_item(NAME(m_control_0));
- save_item(NAME(m_control_1));
-
- m_gfxdecode->gfx(0)->set_source((u8 *)m_charram.target());
- m_gfxdecode->gfx(1)->set_source((u8 *)m_pivot_ram.target());
-
- m_sprite_lag = m_game_config->sprite_lag;
-
- init_alpha_blend_func();
-
- {
- gfx_element *sprite_gfx = m_gfxdecode->gfx(2);
-
- for (int c = 0; c < sprite_gfx->elements(); c++)
- {
- int chk_trans_or_opa = 0;
- const u8 *dp = sprite_gfx->get_data(c);
- for (int y = 0; y < sprite_gfx->height(); y++)
- {
- for (int x = 0; x < sprite_gfx->width(); x++)
- {
- if (!dp[x]) chk_trans_or_opa |= 2;
- else chk_trans_or_opa |= 1;
- }
- dp += sprite_gfx->rowbytes();
- }
- if (chk_trans_or_opa == 1) m_tile_opaque_sp[c] = 1;
- else m_tile_opaque_sp[c] = 0;
- }
- }
-
- {
- gfx_element *pf_gfx = m_gfxdecode->gfx(3);
-
- for (int c = 0; c < pf_gfx->elements(); c++)
- {
- for (int extra_planes = 0; extra_planes < 4; extra_planes++)
- {
- int chk_trans_or_opa = 0;
- /* 0 = 4bpp, 1=5bpp, 2=?, 3=6bpp */
- const u8 extra_mask = ((extra_planes << 4) | 0x0f);
- const u8 *dp = pf_gfx->get_data(c);
-
- for (int y = 0; y < pf_gfx->height(); y++)
- {
- for (int x = 0; x < pf_gfx->width(); x++)
- {
- if (!(dp[x] & extra_mask))
- chk_trans_or_opa |= 2;
- else
- chk_trans_or_opa |= 1;
- }
- dp += pf_gfx->rowbytes();
- }
- m_tile_opaque_pf[extra_planes][c] = chk_trans_or_opa;
- }
- }
- }
-}
-
-/******************************************************************************/
-
-u16 taito_f3_state::pf_ram_r(offs_t offset)
-{
- return m_pf_ram[offset];
-}
-
-void taito_f3_state::pf_ram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_pf_ram[offset]);
-
- if (m_game_config->extend)
- {
- if (offset < 0x4000)
- m_tilemap[offset >> 12]->mark_tile_dirty((offset & 0xfff) >> 1);
- }
- else
- {
- if (offset < 0x4000)
- m_tilemap[offset >> 11]->mark_tile_dirty((offset & 0x7ff) >> 1);
- }
-}
-
-void taito_f3_state::control_0_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_control_0[offset]);
-}
-
-void taito_f3_state::control_1_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_control_1[offset]);
-}
-
-u16 taito_f3_state::spriteram_r(offs_t offset)
-{
- return m_spriteram[offset];
-}
-
-void taito_f3_state::spriteram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_spriteram[offset]);
-}
-
-u16 taito_f3_state::textram_r(offs_t offset)
-{
- return m_textram[offset];
-}
-
-void taito_f3_state::textram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_textram[offset]);
-
- m_vram_layer->mark_tile_dirty(offset);
- //m_vram_layer->mark_tile_dirty(offset + 1);
-
- if (offset > 0x7ff) offset -= 0x800;
-
- const int tile = offset;
- const int col_off = ((tile & 0x3f) << 5) + ((tile & 0xfc0) >> 6);
-
- m_pixel_layer->mark_tile_dirty(col_off);
- //m_pixel_layer->mark_tile_dirty(col_off+32);
-}
-
-
-u16 taito_f3_state::charram_r(offs_t offset)
-{
- return m_charram[offset];
-}
-
-void taito_f3_state::charram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_charram[offset]);
- m_gfxdecode->gfx(0)->mark_dirty(offset >> 4);
-}
-
-u16 taito_f3_state::pivot_r(offs_t offset)
-{
- return m_pivot_ram[offset];
-}
-
-void taito_f3_state::pivot_w(offs_t offset, u16 data, u16 mem_mask)
-{
- COMBINE_DATA(&m_pivot_ram[offset]);
- m_gfxdecode->gfx(1)->mark_dirty(offset >> 4);
-}
-
-u16 taito_f3_state::lineram_r(offs_t offset)
-{
- return m_line_ram[offset];
-}
-
-void taito_f3_state::lineram_w(offs_t offset, u16 data, u16 mem_mask)
-{
- #ifdef UNUSED_FUNCTION
- /* DariusGX has an interesting bug at the start of Round D - the clearing of lineram
- (0xa000->0x0xa7ff) overflows into priority RAM (0xb000) and creates garbage priority
- values. I'm not sure what the real machine would do with these values, and this
- emulation certainly doesn't like it, so I've chosen to catch the bug here, and prevent
- the trashing of priority ram. If anyone has information on what the real machine does,
- please let me know! */
- /* Update: this doesn't seem to occur anymore, I'll leave this snippet in but commented out.
- * fwiw PC=0x1768a0/0x1768a4 is where the game clears lineram in round D, which is a
- * move.w Dn, (An,D7.w*2) , a kind of opcode that could've been bugged back then.
- */
- if (m_game == DARIUSG)
- {
- if (m_f3_skip_this_frame)
- return;
- if (offset == 0xb000 / 2 && data == 0x003f)
- {
- m_f3_skip_this_frame = 1;
- return;
- }
- }
- #endif
-
- COMBINE_DATA(&m_line_ram[offset]);
-}
-
-void taito_f3_state::palette_24bit_w(offs_t offset, u32 data, u32 mem_mask)
-{
- int r, g, b;
-
- COMBINE_DATA(&m_paletteram32[offset]);
-
- /* 12 bit palette games - there has to be a palette select bit somewhere */
- if (m_game == SPCINVDX || m_game == RIDINGF || m_game == ARABIANM || m_game == RINGRAGE)
- {
- b = 15 * ((m_paletteram32[offset] >> 4) & 0xf);
- g = 15 * ((m_paletteram32[offset] >> 8) & 0xf);
- r = 15 * ((m_paletteram32[offset] >> 12) & 0xf);
- }
-
- /* This is weird - why are only the sprites and VRAM palettes 21 bit? */
- else if (m_game == CLEOPATR)
- {
- if (offset < 0x100 || offset > 0x1000)
- {
- r = ((m_paletteram32[offset] >> 16) & 0x7f) << 1;
- g = ((m_paletteram32[offset] >> 8) & 0x7f) << 1;
- b = ((m_paletteram32[offset] >> 0) & 0x7f) << 1;
- }
- else
- {
- r = (m_paletteram32[offset] >> 16) & 0xff;
- g = (m_paletteram32[offset] >> 8) & 0xff;
- b = (m_paletteram32[offset] >> 0) & 0xff;
- }
- }
-
- /* Another weird couple - perhaps this is alpha blending related? */
- else if (m_game == TWINQIX || m_game == RECALH)
- {
- if (offset > 0x1c00)
- {
- r = ((m_paletteram32[offset] >> 16) & 0x7f) << 1;
- g = ((m_paletteram32[offset] >> 8) & 0x7f) << 1;
- b = ((m_paletteram32[offset] >> 0) & 0x7f) << 1;
- }
- else
- {
- r = (m_paletteram32[offset] >> 16) & 0xff;
- g = (m_paletteram32[offset] >> 8) & 0xff;
- b = (m_paletteram32[offset] >> 0) & 0xff;
- }
- }
-
- /* All other games - standard 24 bit palette */
- else
- {
- r = (m_paletteram32[offset] >> 16) & 0xff;
- g = (m_paletteram32[offset] >> 8) & 0xff;
- b = (m_paletteram32[offset] >> 0) & 0xff;
- }
-
- m_palette->set_pen_color(offset, rgb_t(r, g, b));
-}
-
-/******************************************************************************/
-
-/*============================================================================*/
-
-#define SET_ALPHA_LEVEL(d, s) \
-{ \
- int level = s; \
- if (level == 0) level = -1; \
- d = level + 1; \
-}
-
-inline void taito_f3_state::alpha_set_level()
-{
-// SET_ALPHA_LEVEL(m_alpha_s_1_1, m_alpha_level_2ad)
- SET_ALPHA_LEVEL(m_alpha_s_1_1, 255 - m_alpha_level_2as)
-// SET_ALPHA_LEVEL(m_alpha_s_1_2, m_alpha_level_2bd)
- SET_ALPHA_LEVEL(m_alpha_s_1_2, 255 - m_alpha_level_2bs)
- SET_ALPHA_LEVEL(m_alpha_s_1_4, m_alpha_level_3ad)
-// SET_ALPHA_LEVEL(m_alpha_s_1_5, m_alpha_level_3ad*m_alpha_level_2ad / 255)
- SET_ALPHA_LEVEL(m_alpha_s_1_5, m_alpha_level_3ad * (255 - m_alpha_level_2as) / 255)
-// SET_ALPHA_LEVEL(m_alpha_s_1_6, m_alpha_level_3ad*m_alpha_level_2bd / 255)
- SET_ALPHA_LEVEL(m_alpha_s_1_6, m_alpha_level_3ad * (255 - m_alpha_level_2bs) / 255)
- SET_ALPHA_LEVEL(m_alpha_s_1_8, m_alpha_level_3bd)
-// SET_ALPHA_LEVEL(m_alpha_s_1_9, m_alpha_level_3bd*m_alpha_level_2ad / 255)
- SET_ALPHA_LEVEL(m_alpha_s_1_9, m_alpha_level_3bd * (255 - m_alpha_level_2as) / 255)
-// SET_ALPHA_LEVEL(m_alpha_s_1_a, m_alpha_level_3bd*m_alpha_level_2bd / 255)
- SET_ALPHA_LEVEL(m_alpha_s_1_a, m_alpha_level_3bd * (255 - m_alpha_level_2bs) / 255)
-
- SET_ALPHA_LEVEL(m_alpha_s_2a_0, m_alpha_level_2as)
- SET_ALPHA_LEVEL(m_alpha_s_2a_4, m_alpha_level_2as * m_alpha_level_3ad / 255)
- SET_ALPHA_LEVEL(m_alpha_s_2a_8, m_alpha_level_2as * m_alpha_level_3bd / 255)
-
- SET_ALPHA_LEVEL(m_alpha_s_2b_0, m_alpha_level_2bs)
- SET_ALPHA_LEVEL(m_alpha_s_2b_4, m_alpha_level_2bs * m_alpha_level_3ad / 255)
- SET_ALPHA_LEVEL(m_alpha_s_2b_8, m_alpha_level_2bs * m_alpha_level_3bd / 255)
-
- SET_ALPHA_LEVEL(m_alpha_s_3a_0, m_alpha_level_3as)
- SET_ALPHA_LEVEL(m_alpha_s_3a_1, m_alpha_level_3as * m_alpha_level_2ad / 255)
- SET_ALPHA_LEVEL(m_alpha_s_3a_2, m_alpha_level_3as * m_alpha_level_2bd / 255)
-
- SET_ALPHA_LEVEL(m_alpha_s_3b_0, m_alpha_level_3bs)
- SET_ALPHA_LEVEL(m_alpha_s_3b_1, m_alpha_level_3bs * m_alpha_level_2ad / 255)
- SET_ALPHA_LEVEL(m_alpha_s_3b_2, m_alpha_level_3bs * m_alpha_level_2bd / 255)
-}
-#undef SET_ALPHA_LEVEL
-
-/*============================================================================*/
-
-#define COLOR1 BYTE4_XOR_LE(0)
-#define COLOR2 BYTE4_XOR_LE(1)
-#define COLOR3 BYTE4_XOR_LE(2)
-
-inline void taito_f3_state::alpha_blend32_s(int alphas, u32 s)
-{
- u8 *sc = (u8 *)&s;
- u8 *dc = (u8 *)&m_dval;
- dc[COLOR1] = (alphas * sc[COLOR1]) >> 8;
- dc[COLOR2] = (alphas * sc[COLOR2]) >> 8;
- dc[COLOR3] = (alphas * sc[COLOR3]) >> 8;
-}
-
-inline void taito_f3_state::alpha_blend32_d(int alphas, u32 s)
-{
- u8 *sc = (u8 *)&s;
- u8 *dc = (u8 *)&m_dval;
- dc[COLOR1] = m_add_sat[dc[COLOR1]][(alphas * sc[COLOR1]) >> 8];
- dc[COLOR2] = m_add_sat[dc[COLOR2]][(alphas * sc[COLOR2]) >> 8];
- dc[COLOR3] = m_add_sat[dc[COLOR3]][(alphas * sc[COLOR3]) >> 8];
-}
-
-/*============================================================================*/
-
-inline void taito_f3_state::alpha_blend_1_1(u32 s) { alpha_blend32_d(m_alpha_s_1_1, s); }
-inline void taito_f3_state::alpha_blend_1_2(u32 s) { alpha_blend32_d(m_alpha_s_1_2, s); }
-inline void taito_f3_state::alpha_blend_1_4(u32 s) { alpha_blend32_d(m_alpha_s_1_4, s); }
-inline void taito_f3_state::alpha_blend_1_5(u32 s) { alpha_blend32_d(m_alpha_s_1_5, s); }
-inline void taito_f3_state::alpha_blend_1_6(u32 s) { alpha_blend32_d(m_alpha_s_1_6, s); }
-inline void taito_f3_state::alpha_blend_1_8(u32 s) { alpha_blend32_d(m_alpha_s_1_8, s); }
-inline void taito_f3_state::alpha_blend_1_9(u32 s) { alpha_blend32_d(m_alpha_s_1_9, s); }
-inline void taito_f3_state::alpha_blend_1_a(u32 s) { alpha_blend32_d(m_alpha_s_1_a, s); }
-
-inline void taito_f3_state::alpha_blend_2a_0(u32 s) { alpha_blend32_s(m_alpha_s_2a_0, s); }
-inline void taito_f3_state::alpha_blend_2a_4(u32 s) { alpha_blend32_d(m_alpha_s_2a_4, s); }
-inline void taito_f3_state::alpha_blend_2a_8(u32 s) { alpha_blend32_d(m_alpha_s_2a_8, s); }
-
-inline void taito_f3_state::alpha_blend_2b_0(u32 s) { alpha_blend32_s(m_alpha_s_2b_0, s); }
-inline void taito_f3_state::alpha_blend_2b_4(u32 s) { alpha_blend32_d(m_alpha_s_2b_4, s); }
-inline void taito_f3_state::alpha_blend_2b_8(u32 s) { alpha_blend32_d(m_alpha_s_2b_8, s); }
-
-inline void taito_f3_state::alpha_blend_3a_0(u32 s) { alpha_blend32_s(m_alpha_s_3a_0, s); }
-inline void taito_f3_state::alpha_blend_3a_1(u32 s) { alpha_blend32_d(m_alpha_s_3a_1, s); }
-inline void taito_f3_state::alpha_blend_3a_2(u32 s) { alpha_blend32_d(m_alpha_s_3a_2, s); }
-
-inline void taito_f3_state::alpha_blend_3b_0(u32 s) { alpha_blend32_s(m_alpha_s_3b_0, s); }
-inline void taito_f3_state::alpha_blend_3b_1(u32 s) { alpha_blend32_d(m_alpha_s_3b_1, s); }
-inline void taito_f3_state::alpha_blend_3b_2(u32 s) { alpha_blend32_d(m_alpha_s_3b_2, s); }
-
-/*============================================================================*/
-
-int taito_f3_state::dpix_1_noalpha(u32 s_pix) { m_dval = s_pix; return 1; }
-int taito_f3_state::dpix_ret1(u32 s_pix) { return 1; }
-int taito_f3_state::dpix_ret0(u32 s_pix) { return 0; }
-int taito_f3_state::dpix_1_1(u32 s_pix) { if (s_pix) alpha_blend_1_1(s_pix); return 1; }
-int taito_f3_state::dpix_1_2(u32 s_pix) { if (s_pix) alpha_blend_1_2(s_pix); return 1; }
-int taito_f3_state::dpix_1_4(u32 s_pix) { if (s_pix) alpha_blend_1_4(s_pix); return 1; }
-int taito_f3_state::dpix_1_5(u32 s_pix) { if (s_pix) alpha_blend_1_5(s_pix); return 1; }
-int taito_f3_state::dpix_1_6(u32 s_pix) { if (s_pix) alpha_blend_1_6(s_pix); return 1; }
-int taito_f3_state::dpix_1_8(u32 s_pix) { if (s_pix) alpha_blend_1_8(s_pix); return 1; }
-int taito_f3_state::dpix_1_9(u32 s_pix) { if (s_pix) alpha_blend_1_9(s_pix); return 1; }
-int taito_f3_state::dpix_1_a(u32 s_pix) { if (s_pix) alpha_blend_1_a(s_pix); return 1; }
-
-int taito_f3_state::dpix_2a_0(u32 s_pix)
-{
- if (s_pix) alpha_blend_2a_0(s_pix);
- else m_dval = 0;
- if (m_pdest_2a) { m_pval |= m_pdest_2a; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_2a_4(u32 s_pix)
-{
- if (s_pix) alpha_blend_2a_4(s_pix);
- if (m_pdest_2a) { m_pval |= m_pdest_2a; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_2a_8(u32 s_pix)
-{
- if (s_pix) alpha_blend_2a_8(s_pix);
- if (m_pdest_2a) { m_pval |= m_pdest_2a; return 0; }
- return 1;
-}
-
-int taito_f3_state::dpix_3a_0(u32 s_pix)
-{
- if (s_pix) alpha_blend_3a_0(s_pix);
- else m_dval = 0;
- if (m_pdest_3a) { m_pval |= m_pdest_3a; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_3a_1(u32 s_pix)
-{
- if (s_pix) alpha_blend_3a_1(s_pix);
- if (m_pdest_3a) { m_pval |= m_pdest_3a; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_3a_2(u32 s_pix)
-{
- if (s_pix) alpha_blend_3a_2(s_pix);
- if (m_pdest_3a) { m_pval |= m_pdest_3a; return 0; }
- return 1;
-}
-
-int taito_f3_state::dpix_2b_0(u32 s_pix)
-{
- if (s_pix) alpha_blend_2b_0(s_pix);
- else m_dval = 0;
- if (m_pdest_2b) { m_pval |= m_pdest_2b; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_2b_4(u32 s_pix)
-{
- if (s_pix) alpha_blend_2b_4(s_pix);
- if (m_pdest_2b) { m_pval |= m_pdest_2b; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_2b_8(u32 s_pix)
-{
- if (s_pix) alpha_blend_2b_8(s_pix);
- if (m_pdest_2b) { m_pval |= m_pdest_2b; return 0; }
- return 1;
-}
-
-int taito_f3_state::dpix_3b_0(u32 s_pix)
-{
- if (s_pix) alpha_blend_3b_0(s_pix);
- else m_dval = 0;
- if (m_pdest_3b) { m_pval |= m_pdest_3b; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_3b_1(u32 s_pix)
-{
- if (s_pix) alpha_blend_3b_1(s_pix);
- if (m_pdest_3b) { m_pval |= m_pdest_3b; return 0; }
- return 1;
-}
-int taito_f3_state::dpix_3b_2(u32 s_pix)
-{
- if (s_pix) alpha_blend_3b_2(s_pix);
- if (m_pdest_3b) { m_pval |= m_pdest_3b; return 0; }
- return 1;
-}
-
-int taito_f3_state::dpix_2_0(u32 s_pix)
-{
- const u8 tr2 = m_tval & 1;
- if (s_pix)
- {
- if (tr2 == m_tr_2b) { alpha_blend_2b_0(s_pix); if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
- else if (tr2 == m_tr_2a) { alpha_blend_2a_0(s_pix); if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
- }
- else
- {
- if (tr2 == m_tr_2b) { m_dval = 0; if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
- else if (tr2 == m_tr_2a) { m_dval = 0; if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
- }
- return 0;
-}
-int taito_f3_state::dpix_2_4(u32 s_pix)
-{
- const u8 tr2 = m_tval & 1;
- if (s_pix)
- {
- if (tr2 == m_tr_2b) { alpha_blend_2b_4(s_pix); if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
- else if (tr2 == m_tr_2a) { alpha_blend_2a_4(s_pix); if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
- }
- else
- {
- if (tr2 == m_tr_2b) { if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
- else if (tr2 == m_tr_2a) { if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
- }
- return 0;
-}
-int taito_f3_state::dpix_2_8(u32 s_pix)
-{
- const u8 tr2 = m_tval & 1;
- if (s_pix)
- {
- if (tr2 == m_tr_2b) { alpha_blend_2b_8(s_pix); if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
- else if (tr2 == m_tr_2a) { alpha_blend_2a_8(s_pix); if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
- }
- else
- {
- if (tr2 == m_tr_2b) { if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
- else if (tr2 == m_tr_2a) { if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
- }
- return 0;
-}
-
-int taito_f3_state::dpix_3_0(u32 s_pix)
-{
- const u8 tr2 = m_tval & 1;
- if (s_pix)
- {
- if (tr2 == m_tr_3b) { alpha_blend_3b_0(s_pix); if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
- else if (tr2 == m_tr_3a) { alpha_blend_3a_0(s_pix); if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
- }
- else
- {
- if (tr2 == m_tr_3b) { m_dval = 0; if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
- else if (tr2 == m_tr_3a) { m_dval = 0; if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
- }
- return 0;
-}
-int taito_f3_state::dpix_3_1(u32 s_pix)
-{
- const u8 tr2 = m_tval & 1;
- if (s_pix)
- {
- if (tr2 == m_tr_3b) { alpha_blend_3b_1(s_pix); if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
- else if (tr2 == m_tr_3a) { alpha_blend_3a_1(s_pix); if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
- }
- else
- {
- if (tr2 == m_tr_3b) { if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
- else if (tr2 == m_tr_3a) { if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
- }
- return 0;
-}
-int taito_f3_state::dpix_3_2(u32 s_pix)
-{
- const u8 tr2 = m_tval & 1;
- if (s_pix)
- {
- if (tr2 == m_tr_3b) { alpha_blend_3b_2(s_pix); if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
- else if (tr2 == m_tr_3a) { alpha_blend_3a_2(s_pix); if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
- }
- else
- {
- if (tr2 == m_tr_3b) { if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
- else if (tr2 == m_tr_3a) { if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
- }
- return 0;
-}
-
-inline void taito_f3_state::dpix_1_sprite(u32 s_pix)
-{
- if (s_pix)
- {
- const u8 p1 = m_pval & 0xf0;
- if (p1 == 0x10) alpha_blend_1_1(s_pix);
- else if (p1 == 0x20) alpha_blend_1_2(s_pix);
- else if (p1 == 0x40) alpha_blend_1_4(s_pix);
- else if (p1 == 0x50) alpha_blend_1_5(s_pix);
- else if (p1 == 0x60) alpha_blend_1_6(s_pix);
- else if (p1 == 0x80) alpha_blend_1_8(s_pix);
- else if (p1 == 0x90) alpha_blend_1_9(s_pix);
- else if (p1 == 0xa0) alpha_blend_1_a(s_pix);
- }
-}
-
-inline void taito_f3_state::dpix_bg(u32 bgcolor)
-{
- const u8 p1 = m_pval & 0xf0;
- if (!p1) m_dval = bgcolor;
- else if (p1 == 0x10) alpha_blend_1_1(bgcolor);
- else if (p1 == 0x20) alpha_blend_1_2(bgcolor);
- else if (p1 == 0x40) alpha_blend_1_4(bgcolor);
- else if (p1 == 0x50) alpha_blend_1_5(bgcolor);
- else if (p1 == 0x60) alpha_blend_1_6(bgcolor);
- else if (p1 == 0x80) alpha_blend_1_8(bgcolor);
- else if (p1 == 0x90) alpha_blend_1_9(bgcolor);
- else if (p1 == 0xa0) alpha_blend_1_a(bgcolor);
-}
-
-/******************************************************************************/
-
-void taito_f3_state::init_alpha_blend_func()
-{
- m_dpix_n[0][0x0] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x1] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x2] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x3] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x4] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x5] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x6] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x7] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x8] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0x9] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0xa] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0xb] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0xc] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0xd] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0xe] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[0][0xf] = &taito_f3_state::dpix_1_noalpha;
-
- m_dpix_n[1][0x0] = &taito_f3_state::dpix_1_noalpha;
- m_dpix_n[1][0x1] = &taito_f3_state::dpix_1_1;
- m_dpix_n[1][0x2] = &taito_f3_state::dpix_1_2;
- m_dpix_n[1][0x3] = &taito_f3_state::dpix_ret1;
- m_dpix_n[1][0x4] = &taito_f3_state::dpix_1_4;
- m_dpix_n[1][0x5] = &taito_f3_state::dpix_1_5;
- m_dpix_n[1][0x6] = &taito_f3_state::dpix_1_6;
- m_dpix_n[1][0x7] = &taito_f3_state::dpix_ret1;
- m_dpix_n[1][0x8] = &taito_f3_state::dpix_1_8;
- m_dpix_n[1][0x9] = &taito_f3_state::dpix_1_9;
- m_dpix_n[1][0xa] = &taito_f3_state::dpix_1_a;
- m_dpix_n[1][0xb] = &taito_f3_state::dpix_ret1;
- m_dpix_n[1][0xc] = &taito_f3_state::dpix_ret1;
- m_dpix_n[1][0xd] = &taito_f3_state::dpix_ret1;
- m_dpix_n[1][0xe] = &taito_f3_state::dpix_ret1;
- m_dpix_n[1][0xf] = &taito_f3_state::dpix_ret1;
-
- m_dpix_n[2][0x0] = &taito_f3_state::dpix_2a_0;
- m_dpix_n[2][0x1] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0x2] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0x3] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0x4] = &taito_f3_state::dpix_2a_4;
- m_dpix_n[2][0x5] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0x6] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0x7] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0x8] = &taito_f3_state::dpix_2a_8;
- m_dpix_n[2][0x9] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0xa] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0xb] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0xc] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0xd] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0xe] = &taito_f3_state::dpix_ret0;
- m_dpix_n[2][0xf] = &taito_f3_state::dpix_ret0;
-
- m_dpix_n[3][0x0] = &taito_f3_state::dpix_3a_0;
- m_dpix_n[3][0x1] = &taito_f3_state::dpix_3a_1;
- m_dpix_n[3][0x2] = &taito_f3_state::dpix_3a_2;
- m_dpix_n[3][0x3] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0x4] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0x5] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0x6] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0x7] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0x8] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0x9] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0xa] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0xb] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0xc] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0xd] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0xe] = &taito_f3_state::dpix_ret0;
- m_dpix_n[3][0xf] = &taito_f3_state::dpix_ret0;
-
- m_dpix_n[4][0x0] = &taito_f3_state::dpix_2b_0;
- m_dpix_n[4][0x1] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0x2] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0x3] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0x4] = &taito_f3_state::dpix_2b_4;
- m_dpix_n[4][0x5] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0x6] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0x7] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0x8] = &taito_f3_state::dpix_2b_8;
- m_dpix_n[4][0x9] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0xa] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0xb] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0xc] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0xd] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0xe] = &taito_f3_state::dpix_ret0;
- m_dpix_n[4][0xf] = &taito_f3_state::dpix_ret0;
-
- m_dpix_n[5][0x0] = &taito_f3_state::dpix_3b_0;
- m_dpix_n[5][0x1] = &taito_f3_state::dpix_3b_1;
- m_dpix_n[5][0x2] = &taito_f3_state::dpix_3b_2;
- m_dpix_n[5][0x3] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0x4] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0x5] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0x6] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0x7] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0x8] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0x9] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0xa] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0xb] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0xc] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0xd] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0xe] = &taito_f3_state::dpix_ret0;
- m_dpix_n[5][0xf] = &taito_f3_state::dpix_ret0;
-
- m_dpix_n[6][0x0] = &taito_f3_state::dpix_2_0;
- m_dpix_n[6][0x1] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0x2] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0x3] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0x4] = &taito_f3_state::dpix_2_4;
- m_dpix_n[6][0x5] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0x6] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0x7] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0x8] = &taito_f3_state::dpix_2_8;
- m_dpix_n[6][0x9] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0xa] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0xb] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0xc] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0xd] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0xe] = &taito_f3_state::dpix_ret0;
- m_dpix_n[6][0xf] = &taito_f3_state::dpix_ret0;
-
- m_dpix_n[7][0x0] = &taito_f3_state::dpix_3_0;
- m_dpix_n[7][0x1] = &taito_f3_state::dpix_3_1;
- m_dpix_n[7][0x2] = &taito_f3_state::dpix_3_2;
- m_dpix_n[7][0x3] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0x4] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0x5] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0x6] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0x7] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0x8] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0x9] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0xa] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0xb] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0xc] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0xd] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0xe] = &taito_f3_state::dpix_ret0;
- m_dpix_n[7][0xf] = &taito_f3_state::dpix_ret0;
-
- for (int i = 0; i < 256; i++)
- for (int j = 0; j < 256; j++)
- m_add_sat[i][j] = std::min(i + j, 255);
-}
-
-/******************************************************************************/
-
-#define GET_PIXMAP_POINTER(pf_num) \
-{ \
- const f3_playfield_line_inf *line_tmp = line_t[pf_num]; \
- m_src[pf_num] = line_tmp->src[y]; \
- m_src_s[pf_num] = line_tmp->src_s[y]; \
- m_src_e[pf_num] = line_tmp->src_e[y]; \
- m_tsrc[pf_num] = line_tmp->tsrc[y]; \
- m_tsrc_s[pf_num] = line_tmp->tsrc_s[y]; \
- m_x_count[pf_num] = line_tmp->x_count[y]; \
- m_x_zoom[pf_num] = line_tmp->x_zoom[y]; \
- m_clip_al[pf_num] = line_tmp->clip0[y] & 0xffff; \
- m_clip_ar[pf_num] = line_tmp->clip0[y] >> 16; \
- m_clip_bl[pf_num] = line_tmp->clip1[y] & 0xffff; \
- m_clip_br[pf_num] = line_tmp->clip1[y] >> 16; \
-}
-
-#define CULC_PIXMAP_POINTER(pf_num) \
-{ \
- m_x_count[pf_num] += m_x_zoom[pf_num]; \
- if (m_x_count[pf_num] >> 16) \
- { \
- m_x_count[pf_num] &= 0xffff; \
- m_src[pf_num]++; \
- m_tsrc[pf_num]++; \
- if (m_src[pf_num] == m_src_e[pf_num]) { m_src[pf_num] = m_src_s[pf_num]; m_tsrc[pf_num] = m_tsrc_s[pf_num]; } \
- } \
-}
-
-#define UPDATE_PIXMAP_SP(pf_num) \
- if (cx >= clip_als && cx < clip_ars && !(cx >= clip_bls && cx < clip_brs)) \
- { \
- sprite_pri = sprite[pf_num] & m_pval; \
- if (sprite_pri) \
- { \
- if (sprite[pf_num] & 0x100) break; \
- if (!m_dpix_sp[sprite_pri]) \
- { \
- if (!(m_pval & 0xf0)) break; \
- else { dpix_1_sprite(*dsti); *dsti = m_dval; break; } \
- } \
- if ((this->*m_dpix_sp[sprite_pri][m_pval >> 4])(*dsti)) { *dsti = m_dval; break; } \
- } \
- }
-
-#define UPDATE_PIXMAP_LP(pf_num) \
- if (cx >= m_clip_al[pf_num] && cx < m_clip_ar[pf_num] && !(cx >= m_clip_bl[pf_num] && cx < m_clip_br[pf_num])) \
- { \
- m_tval = *m_tsrc[pf_num]; \
- if (m_tval & 0xf0) \
- if ((this->*m_dpix_lp[pf_num][m_pval >> 4])(clut[*m_src[pf_num]])) { *dsti = m_dval; break; } \
- }
-
-
-/*============================================================================*/
-
-inline void taito_f3_state::draw_scanlines(
- bitmap_rgb32 &bitmap, int xsize, s16 *draw_line_num,
- const f3_playfield_line_inf **line_t,
- const int *sprite,
- u32 orient,
- int skip_layer_num)
-{
- const pen_t *clut = &m_palette->pen(0);
- const u32 bgcolor = clut[0];
-
- const int x = 46;
-
- u16 clip_als = 0, clip_ars = 0, clip_bls = 0, clip_brs = 0;
-
- int yadv = bitmap.rowpixels();
- int yadvp = m_pri_alp_bitmap.rowpixels();
- int i = 0, y = draw_line_num[0];
- int ty = y;
-
- if (orient & ORIENTATION_FLIP_Y)
- {
- ty = bitmap.height() - 1 - ty;
- yadv = -yadv;
- yadvp = -yadvp;
- }
-
- u8 *dstp0 = &m_pri_alp_bitmap.pix8(ty, x);
-
- m_pdest_2a = m_alpha_level_2ad ? 0x10 : 0;
- m_pdest_2b = m_alpha_level_2bd ? 0x20 : 0;
- m_tr_2a =(m_alpha_level_2as == 0 && m_alpha_level_2ad == 255) ? -1 : 0;
- m_tr_2b =(m_alpha_level_2bs == 0 && m_alpha_level_2bd == 255) ? -1 : 1;
- m_pdest_3a = m_alpha_level_3ad ? 0x40 : 0;
- m_pdest_3b = m_alpha_level_3bd ? 0x80 : 0;
- m_tr_3a =(m_alpha_level_3as == 0 && m_alpha_level_3ad == 255) ? -1 : 0;
- m_tr_3b =(m_alpha_level_3bs == 0 && m_alpha_level_3bd == 255) ? -1 : 1;
-
- {
- u32 *dsti0 = &bitmap.pix32(ty, x);
- while (1)
- {
- int cx = 0;
-
- clip_als = m_sa_line_inf[0].sprite_clip0[y] & 0xffff;
- clip_ars = m_sa_line_inf[0].sprite_clip0[y] >> 16;
- clip_bls = m_sa_line_inf[0].sprite_clip1[y] & 0xffff;
- clip_brs = m_sa_line_inf[0].sprite_clip1[y] >> 16;
-
- int length = xsize;
- u32 *dsti = dsti0;
- u8 *dstp = dstp0;
-
- switch (skip_layer_num)
- {
- case 0: GET_PIXMAP_POINTER(0)
- case 1: GET_PIXMAP_POINTER(1)
- case 2: GET_PIXMAP_POINTER(2)
- case 3: GET_PIXMAP_POINTER(3)
- case 4: GET_PIXMAP_POINTER(4)
- }
-
- while (1)
- {
- m_pval = *dstp;
- if (m_pval != 0xff)
- {
- u8 sprite_pri;
- switch (skip_layer_num)
- {
- case 0: UPDATE_PIXMAP_SP(0) UPDATE_PIXMAP_LP(0)
- case 1: UPDATE_PIXMAP_SP(1) UPDATE_PIXMAP_LP(1)
- case 2: UPDATE_PIXMAP_SP(2) UPDATE_PIXMAP_LP(2)
- case 3: UPDATE_PIXMAP_SP(3) UPDATE_PIXMAP_LP(3)
- case 4: UPDATE_PIXMAP_SP(4) UPDATE_PIXMAP_LP(4)
- case 5: UPDATE_PIXMAP_SP(5)
- if (!bgcolor) { if (!(m_pval & 0xf0)) { *dsti = 0; break; } }
- else dpix_bg(bgcolor);
- *dsti = m_dval;
- }
- }
-
- if (!(--length)) break;
- dsti++;
- dstp++;
- cx++;
-
- switch (skip_layer_num)
- {
- case 0: CULC_PIXMAP_POINTER(0)
- case 1: CULC_PIXMAP_POINTER(1)
- case 2: CULC_PIXMAP_POINTER(2)
- case 3: CULC_PIXMAP_POINTER(3)
- case 4: CULC_PIXMAP_POINTER(4)
- }
- }
-
- i++;
- if (draw_line_num[i] < 0) break;
- if (draw_line_num[i] == y + 1)
- {
- dsti0 += yadv;
- dstp0 += yadvp;
- y++;
- continue;
- }
- else
- {
- dsti0 += (draw_line_num[i] - y) * yadv;
- dstp0 += (draw_line_num[i] - y) * yadvp;
- y = draw_line_num[i];
- }
- }
- }
-}
-#undef GET_PIXMAP_POINTER
-#undef CULC_PIXMAP_POINTER
-
-/******************************************************************************/
-
-void taito_f3_state::visible_tile_check(
- f3_playfield_line_inf *line_t,
- int line,
- u32 x_index_fx,u32 y_index,
- u16 *pf_data_n)
-{
- u16 *pf_base;
-
- int alpha_mode = line_t->alpha_mode[line];
- if (!alpha_mode) return;
-
- const u32 total_elements = m_gfxdecode->gfx(3)->elements();
-
- int tile_index = x_index_fx >> 16;
- const int tile_num = (((line_t->x_zoom[line] * 320 + (x_index_fx & 0xffff) + 0xffff) >> 16) + (tile_index & 0xf) + 15) >> 4;
- tile_index >>= 4;
-
- if (m_flipscreen)
- {
- pf_base = pf_data_n + ((31 - (y_index >> 4)) << m_twidth_mask_bit);
- tile_index = (m_twidth_mask - tile_index) - tile_num + 1;
- }
- else pf_base = pf_data_n + ((y_index >> 4) << m_twidth_mask_bit);
-
- bool trans_all = true;
- bool opaque_all = true;
- int alpha_type = 0;
- for (int i = 0; i < tile_num; i++)
- {
- const u32 tile = (pf_base[(tile_index * 2 + 0) & m_twidth_mask] << 16) | (pf_base[(tile_index * 2 + 1) & m_twidth_mask]);
- const u8 extra_planes = (tile >> (16 + 10)) & 3;
- if (tile & 0xffff)
- {
- trans_all = false;
- if (opaque_all)
- {
- if (m_tile_opaque_pf[extra_planes][(tile & 0xffff) % total_elements] != 1) opaque_all = false;
- }
-
- if (alpha_mode == 1)
- {
- if (!opaque_all) return;
- }
- else
- {
- if (alpha_type != 3)
- {
- if ((tile >> (16 + 9)) & 1) alpha_type |= 2;
- else alpha_type |= 1;
- }
- else if (!opaque_all) break;
- }
- }
- else if (opaque_all) opaque_all = false;
-
- tile_index++;
- }
-
- if (trans_all) { line_t->alpha_mode[line] = 0; return; }
-
- if (alpha_mode > 1)
- {
- line_t->alpha_mode[line] |= alpha_type << 4;
- }
-
- if (opaque_all)
- line_t->alpha_mode[line] |= 0x80;
-}
-
-/******************************************************************************/
-
-void taito_f3_state::calculate_clip(int y, u16 pri, u32 *clip0, u32 *clip1, int *line_enable)
-{
- const f3_spritealpha_line_inf *sa_line_t = &m_sa_line_inf[0];
-
- switch (pri)
- {
- case 0x0100: /* Clip plane 1 enable */
- {
- if (sa_line_t->clip0_l[y] > sa_line_t->clip0_r[y])
- *line_enable = 0;
- else
- *clip0 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
- *clip1 = 0;
- }
- break;
- case 0x0110: /* Clip plane 1 enable, inverted */
- {
- *clip1 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
- *clip0 = 0x7fff0000;
- }
- break;
- case 0x0200: /* Clip plane 2 enable */
- {
- if (sa_line_t->clip1_l[y] > sa_line_t->clip1_r[y])
- *line_enable = 0;
- else
- *clip0 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
- *clip1 = 0;
- }
- break;
- case 0x0220: /* Clip plane 2 enable, inverted */
- {
- *clip1 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
- *clip0 = 0x7fff0000;
- }
- break;
- case 0x0300: /* Clip plane 1 & 2 enable */
- {
- int clipl = 0, clipr = 0;
-
- if (sa_line_t->clip1_l[y] > sa_line_t->clip0_l[y])
- clipl = sa_line_t->clip1_l[y];
- else
- clipl = sa_line_t->clip0_l[y];
-
- if (sa_line_t->clip1_r[y] < sa_line_t->clip0_r[y])
- clipr = sa_line_t->clip1_r[y];
- else
- clipr = sa_line_t->clip0_r[y];
-
- if (clipl > clipr)
- *line_enable = 0;
- else
- *clip0 = (clipl) | (clipr << 16);
- *clip1 = 0;
- }
- break;
- case 0x0310: /* Clip plane 1 & 2 enable, plane 1 inverted */
- {
- if (sa_line_t->clip1_l[y] > sa_line_t->clip1_r[y])
- line_enable = nullptr;
- else
- *clip0 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
-
- *clip1 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
- }
- break;
- case 0x0320: /* Clip plane 1 & 2 enable, plane 2 inverted */
- {
- if (sa_line_t->clip0_l[y] > sa_line_t->clip0_r[y])
- line_enable = nullptr;
- else
- *clip0 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
-
- *clip1 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
- }
- break;
- case 0x0330: /* Clip plane 1 & 2 enable, both inverted */
- {
- int clipl = 0, clipr = 0;
-
- if (sa_line_t->clip1_l[y] < sa_line_t->clip0_l[y])
- clipl = sa_line_t->clip1_l[y];
- else
- clipl = sa_line_t->clip0_l[y];
-
- if (sa_line_t->clip1_r[y] > sa_line_t->clip0_r[y])
- clipr = sa_line_t->clip1_r[y];
- else
- clipr = sa_line_t->clip0_r[y];
-
- if (clipl > clipr)
- *line_enable = 0;
- else
- *clip1 = (clipl) | (clipr << 16);
- *clip0 = 0x7fff0000;
- }
- break;
- default:
- // popmessage("Illegal clip mode");
- break;
- }
-}
-
-void taito_f3_state::get_spritealphaclip_info()
-{
- f3_spritealpha_line_inf *line_t = &m_sa_line_inf[0];
-
- int y, y_end, y_inc;
-
- int spri_base, clip_base_low, clip_base_high, inc;
-
- u16 spri = 0;
- u16 sprite_clip = 0;
- u16 clip0_low = 0, clip0_high = 0, clip1_low = 0;
- int alpha_level = 0;
- u16 sprite_alpha = 0;
-
- if (m_flipscreen)
- {
- spri_base = 0x77fe;
- clip_base_low = 0x51fe;
- clip_base_high = 0x45fe;
- inc = -2;
- y = 255;
- y_end = -1;
- y_inc = -1;
-
- }
- else
- {
- spri_base = 0x7600;
- clip_base_low = 0x5000;
- clip_base_high = 0x4400;
- inc = 2;
- y = 0;
- y_end = 256;
- y_inc = 1;
- }
-
- while (y != y_end)
- {
- /* The zoom, column and row values can latch according to control ram */
- {
- if (m_line_ram[0x100 + y] & 1)
- clip0_low = (m_line_ram[clip_base_low / 2] >> 0) & 0xffff;
- if (m_line_ram[0x000 + y] & 4)
- clip0_high = (m_line_ram[clip_base_high / 2] >> 0) & 0xffff;
- if (m_line_ram[0x100 + y] & 2)
- clip1_low = (m_line_ram[(clip_base_low + 0x200) / 2] >> 0) & 0xffff;
-
- if (m_line_ram[(0x0600 / 2) + y] & 0x8)
- spri = m_line_ram[spri_base / 2] & 0xffff;
- if (m_line_ram[(0x0600 / 2) + y] & 0x4)
- sprite_clip = m_line_ram[(spri_base-0x200) / 2] & 0xffff;
- if (m_line_ram[(0x0400 / 2) + y] & 0x1)
- sprite_alpha = m_line_ram[(spri_base-0x1600) / 2] & 0xffff;
- if (m_line_ram[(0x0400 / 2) + y] & 0x2)
- alpha_level = m_line_ram[(spri_base-0x1400) / 2] & 0xffff;
- }
-
-
- line_t->alpha_level[y] = alpha_level;
- line_t->spri[y] = spri;
- line_t->sprite_alpha[y] = sprite_alpha;
- line_t->clip0_l[y] = ((clip0_low & 0xff) | ((clip0_high & 0x1000) >> 4)) - 47;
- line_t->clip0_r[y] = (((clip0_low & 0xff00) >> 8) | ((clip0_high & 0x2000) >> 5)) - 47;
- line_t->clip1_l[y] = ((clip1_low & 0xff) | ((clip0_high & 0x4000) >> 6)) - 47;
- line_t->clip1_r[y] = (((clip1_low & 0xff00) >> 8) | ((clip0_high & 0x8000) >> 7)) - 47;
- if (line_t->clip0_l[y] < 0) line_t->clip0_l[y] = 0;
- if (line_t->clip0_r[y] < 0) line_t->clip0_r[y] = 0;
- if (line_t->clip1_l[y] < 0) line_t->clip1_l[y] = 0;
- if (line_t->clip1_r[y] < 0) line_t->clip1_r[y] = 0;
-
- /* Evaluate sprite clipping */
- if (sprite_clip & 0x080)
- {
- line_t->sprite_clip0[y] = 0x7fff7fff;
- line_t->sprite_clip1[y] = 0;
- }
- else if (sprite_clip & 0x33)
- {
- int line_enable = 1;
- calculate_clip(y, ((sprite_clip & 0x33) << 4), &line_t->sprite_clip0[y], &line_t->sprite_clip1[y], &line_enable);
- if (line_enable == 0)
- line_t->sprite_clip0[y] = 0x7fff7fff;
- }
- else
- {
- line_t->sprite_clip0[y] = 0x7fff0000;
- line_t->sprite_clip1[y] = 0;
- }
-
- spri_base += inc;
- clip_base_low += inc;
- clip_base_high += inc;
- y += y_inc;
- }
-}
-
-/* sx and sy are 16.16 fixed point numbers */
-void taito_f3_state::get_line_ram_info(tilemap_t *tmap, int sx, int sy, int pos, u16 *pf_data_n)
-{
- f3_playfield_line_inf *line_t = &m_pf_line_inf[pos];
-
- int y_start, y_end, y_inc;
- int line_base, zoom_base, col_base, pri_base, inc;
-
- int line_enable;
- int colscroll = 0, x_offset = 0, line_zoom = 0;
- u32 _y_zoom[256];
- u16 pri = 0;
- int bit_select = 1 << pos;
-
- int _colscroll[256];
- u32 _x_offset[256];
- int y_index_fx;
-
- sx += ((46 << 16));
-
- if (m_flipscreen)
- {
- line_base = 0xa1fe + (pos << 9);
- zoom_base = 0x81fe;// + (pos << 9);
- col_base = 0x41fe + (pos << 9);
- pri_base = 0xb1fe + (pos << 9);
- inc = -2;
- y_start = 255;
- y_end = -1;
- y_inc = -1;
-
- /* Adjust for flipped scroll position */
- if (m_game_config->extend)
- sx = -sx + (((188 - 512) & 0xffff) << 16);
- else
- sx = -sx + (188 << 16);
-
- y_index_fx = -sy - (256 << 16); /* Adjust for flipped scroll position */
- }
- else
- {
- line_base = 0xa000 + (pos << 9);
- zoom_base = 0x8000;// + (pos << 9);
- col_base = 0x4000 + (pos << 9);
- pri_base = 0xb000 + (pos << 9);
- inc = 2;
- y_start = 0;
- y_end = 256;
- y_inc = 1;
-
- y_index_fx = sy;
- }
-
- int y = y_start;
-
- while (y != y_end)
- {
- /* The zoom, column and row values can latch according to control ram */
- {
- if (m_line_ram[0x600 + y] & bit_select)
- x_offset = (m_line_ram[line_base / 2] & 0xffff) << 10;
- if (m_line_ram[0x700 + y] & bit_select)
- pri = m_line_ram[pri_base / 2] & 0xffff;
-
- // Zoom for playfields 1 & 3 is interleaved, as is the latch select
- switch (pos)
- {
- case 0:
- if (m_line_ram[0x400 + y] & bit_select)
- line_zoom = m_line_ram[(zoom_base + 0x000) / 2] & 0xffff;
- break;
- case 1:
- if (m_line_ram[0x400 + y] & 0x2)
- line_zoom = ((m_line_ram[(zoom_base + 0x200) / 2] & 0xffff) & 0xff00) | (line_zoom & 0x00ff);
- if (m_line_ram[0x400 + y] & 0x8)
- line_zoom = ((m_line_ram[(zoom_base + 0x600) / 2] & 0xffff) & 0x00ff) | (line_zoom & 0xff00);
- break;
- case 2:
- if (m_line_ram[0x400 + y] & bit_select)
- line_zoom = m_line_ram[(zoom_base + 0x400) / 2] & 0xffff;
- break;
- case 3:
- if (m_line_ram[0x400 + y] & 0x8)
- line_zoom = ((m_line_ram[(zoom_base + 0x600) / 2] & 0xffff) & 0xff00) | (line_zoom & 0x00ff);
- if (m_line_ram[0x400 + y] & 0x2)
- line_zoom = ((m_line_ram[(zoom_base + 0x200) / 2] & 0xffff) & 0x00ff) | (line_zoom & 0xff00);
- break;
- default:
- break;
- }
-
- // Column scroll only affects playfields 2 & 3
- if (pos >= 2 && m_line_ram[0x000 + y] & bit_select)
- colscroll = (m_line_ram[col_base / 2] >> 0) & 0x3ff;
- }
-
- if (!pri || (!m_flipscreen && y < 24) || (m_flipscreen && y > 231) ||
- (pri & 0xc000) == 0xc000 || !(pri & 0x2000)/**/)
- line_enable = 0;
- else if (pri & 0x4000) //alpha1
- line_enable = 2;
- else if (pri & 0x8000) //alpha2
- line_enable = 3;
- else
- line_enable = 1;
-
- _colscroll[y] = colscroll;
- _x_offset[y] = (x_offset & 0xffff0000) - (x_offset & 0x0000ffff);
- _y_zoom[y] = (line_zoom & 0xff) << 9;
-
- /* Evaluate clipping */
- if (pri & 0x0800)
- line_enable = 0;
- else if (pri & 0x0330)
- {
- //fast path todo - remove line enable
- calculate_clip(y, pri & 0x0330, &line_t->clip0[y], &line_t->clip1[y], &line_enable);
- }
- else
- {
- /* No clipping */
- line_t->clip0[y] = 0x7fff0000;
- line_t->clip1[y] = 0;
- }
-
- line_t->x_zoom[y] = 0x10000 - (line_zoom & 0xff00);
- line_t->alpha_mode[y] = line_enable;
- line_t->pri[y] = pri;
-
- zoom_base += inc;
- line_base += inc;
- col_base += inc;
- pri_base += inc;
- y += y_inc;
- }
-
- tilemap_t* tm = tmap;
-
- y = y_start;
- while (y != y_end)
- {
- u32 x_index_fx;
- u32 y_index;
-
- /* The football games use values in the range 0x200 - 0x3ff where the crowd should be drawn - !?
-
- This appears to cause it to reference outside of the normal tilemap RAM area into the unused
- area on the 32x32 tilemap configuration.. but exactly how isn't understood
-
- Until this is understood we're creating additional tilemaps for the otherwise unused area of
- RAM and forcing it to look up there.
-
- the crowd area still seems to 'lag' behind the pitch area however.. but these are the values
- in ram??
- */
- const int cs = _colscroll[y];
-
- if (cs & 0x200)
- {
- if (m_tilemap[4] && m_tilemap[5])
- {
- if (tmap == m_tilemap[2]) tmap = m_tilemap[4]; // pitch -> crowd
- if (tmap == m_tilemap[3]) tmap = m_tilemap[5]; // corruption on goals -> blank (hthero94)
- }
- }
- else
- {
- tmap = tm;
- }
-
- /* set pixmap pointer */
- bitmap_ind16 &srcbitmap = tmap->pixmap();
- bitmap_ind8 &flagsbitmap = tmap->flagsmap();
-
- if (line_t->alpha_mode[y] != 0)
- {
- u16 *src_s;
- u8 *tsrc_s;
-
- x_index_fx = (sx+_x_offset[y]-(10*0x10000) + (10*line_t->x_zoom[y]))&((m_width_mask << 16)|0xffff);
- y_index = ((y_index_fx >> 16)+_colscroll[y]) & 0x1ff;
-
- /* check tile status */
- visible_tile_check(line_t, y, x_index_fx, y_index, pf_data_n);
-
- /* If clipping enabled for this line have to disable 'all opaque' optimisation */
- if (line_t->clip0[y] != 0x7fff0000 || line_t->clip1[y] != 0)
- line_t->alpha_mode[y] &= ~0x80;
-
- /* set pixmap index */
- line_t->x_count[y]=x_index_fx & 0xffff; // Fractional part
- line_t->src_s[y] = src_s = &srcbitmap.pix16(y_index);
- line_t->src_e[y] = &src_s[m_width_mask + 1];
- line_t->src[y] = &src_s[x_index_fx >> 16];
-
- line_t->tsrc_s[y]=tsrc_s = &flagsbitmap.pix8(y_index);
- line_t->tsrc[y] = &tsrc_s[x_index_fx >> 16];
- }
-
- y_index_fx += _y_zoom[y];
- y += y_inc;
- }
-}
-
-void taito_f3_state::get_vram_info(tilemap_t *vram_tilemap, tilemap_t *pixel_tilemap, int sx, int sy)
-{
- const f3_spritealpha_line_inf *sprite_alpha_line_t = &m_sa_line_inf[0];
- f3_playfield_line_inf *line_t = &m_pf_line_inf[4];
-
- int y_start, y_end, y_inc;
- int pri_base, inc;
-
- int line_enable;
-
- u16 pri = 0;
-
- const int vram_width_mask = 0x3ff;
-
- if (m_flipscreen)
- {
- pri_base = 0x73fe;
- inc = -2;
- y_start = 255;
- y_end = -1;
- y_inc = -1;
- }
- else
- {
- pri_base = 0x7200;
- inc = 2;
- y_start = 0;
- y_end = 256;
- y_inc = 1;
-
- }
-
- int y = y_start;
- while (y != y_end)
- {
- /* The zoom, column and row values can latch according to control ram */
- {
- if (m_line_ram[(0x0600 / 2) + y] & 0x2)
- pri = (m_line_ram[pri_base / 2] & 0xffff);
- }
-
- if (!pri || (!m_flipscreen && y < 24) || (m_flipscreen && y > 231) ||
- (pri & 0xc000) == 0xc000 || !(pri & 0x2000)/**/)
- line_enable = 0;
- else if (pri & 0x4000) //alpha1
- line_enable = 2;
- else if (pri & 0x8000) //alpha2
- line_enable = 3;
- else
- line_enable = 1;
-
- line_t->pri[y] = pri;
-
- /* Evaluate clipping */
- if (pri & 0x0800)
- line_enable = 0;
- else if (pri & 0x0330)
- {
- //fast path todo - remove line enable
- calculate_clip(y, pri & 0x0330, &line_t->clip0[y], &line_t->clip1[y], &line_enable);
- }
- else
- {
- /* No clipping */
- line_t->clip0[y] = 0x7fff0000;
- line_t->clip1[y] = 0;
- }
-
- line_t->x_zoom[y] = 0x10000;
- line_t->alpha_mode[y] = line_enable;
- if (line_t->alpha_mode[y] > 1)
- line_t->alpha_mode[y] |= 0x10;
-
- pri_base += inc;
- y += y_inc;
- }
-
- sx &= 0x1ff;
-
- /* set pixmap pointer */
- bitmap_ind16 &srcbitmap_pixel = pixel_tilemap->pixmap();
- bitmap_ind8 &flagsbitmap_pixel = pixel_tilemap->flagsmap();
- bitmap_ind16 &srcbitmap_vram = vram_tilemap->pixmap();
- bitmap_ind8 &flagsbitmap_vram = vram_tilemap->flagsmap();
-
- y = y_start;
- while (y != y_end)
- {
- if (line_t->alpha_mode[y] != 0)
- {
- u16 *src_s;
- u8 *tsrc_s;
-
- // These bits in control ram indicate whether the line is taken from
- // the VRAM tilemap layer or pixel layer.
- const bool usePixelLayer = ((sprite_alpha_line_t->sprite_alpha[y] & 0xa000) == 0xa000);
-
- /* set pixmap index */
- line_t->x_count[y] = 0xffff;
- if (usePixelLayer)
- line_t->src_s[y] = src_s = &srcbitmap_pixel.pix16(sy & 0xff);
- else
- line_t->src_s[y] = src_s = &srcbitmap_vram.pix16(sy & 0x1ff);
- line_t->src_e[y] = &src_s[vram_width_mask + 1];
- line_t->src[y] = &src_s[sx];
-
- if (usePixelLayer)
- line_t->tsrc_s[y]=tsrc_s = &flagsbitmap_pixel.pix8(sy & 0xff);
- else
- line_t->tsrc_s[y]=tsrc_s = &flagsbitmap_vram.pix8(sy & 0x1ff);
- line_t->tsrc[y] = &tsrc_s[sx];
- }
-
- sy++;
- y += y_inc;
- }
-}
-
-/******************************************************************************/
-
-void taito_f3_state::scanline_draw(bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- int i, ys, ye;
- int y_start, y_end, y_start_next, y_end_next;
- u8 draw_line[256];
- s16 draw_line_num[256];
-
- u32 rot = 0;
-
- if (m_flipscreen)
- {
- rot = ORIENTATION_FLIP_Y;
- ys = 0;
- ye = 232;
- }
- else
- {
- ys = 24;
- ye = 256;
- }
-
- y_start = ys;
- y_end = ye;
- std::fill(std::begin(draw_line), std::end(draw_line), 0);
-
- while (1)
- {
- int pos;
- int pri[5],alpha_mode[5],alpha_mode_flag[5];
- u8 sprite_alpha_check;
- u8 sprite_alpha_all_2a;
- int layer_tmp[5];
- f3_playfield_line_inf *pf_line_inf = m_pf_line_inf.get();
- f3_spritealpha_line_inf *sa_line_inf = m_sa_line_inf.get();
- int count_skip_layer = 0;
- int sprite[6] = {0, 0, 0, 0, 0, 0};
- const f3_playfield_line_inf *line_t[5];
-
- /* find same status of scanlines */
- pri[0] = pf_line_inf[0].pri[y_start];
- pri[1] = pf_line_inf[1].pri[y_start];
- pri[2] = pf_line_inf[2].pri[y_start];
- pri[3] = pf_line_inf[3].pri[y_start];
- pri[4] = pf_line_inf[4].pri[y_start];
- alpha_mode[0] = pf_line_inf[0].alpha_mode[y_start];
- alpha_mode[1] = pf_line_inf[1].alpha_mode[y_start];
- alpha_mode[2] = pf_line_inf[2].alpha_mode[y_start];
- alpha_mode[3] = pf_line_inf[3].alpha_mode[y_start];
- alpha_mode[4] = pf_line_inf[4].alpha_mode[y_start];
- const int alpha_level = sa_line_inf[0].alpha_level[y_start];
- const int spri = sa_line_inf[0].spri[y_start];
- const u16 sprite_alpha = sa_line_inf[0].sprite_alpha[y_start];
-
- draw_line[y_start] = 1;
- draw_line_num[i = 0] = y_start;
- y_start_next = -1;
- y_end_next = -1;
- for (int y = y_start + 1; y < y_end; y++)
- {
- if (!draw_line[y])
- {
- if (pri[0] != pf_line_inf[0].pri[y]) y_end_next = y + 1;
- else if (pri[1] != pf_line_inf[1].pri[y]) y_end_next = y + 1;
- else if (pri[2] != pf_line_inf[2].pri[y]) y_end_next = y + 1;
- else if (pri[3] != pf_line_inf[3].pri[y]) y_end_next = y + 1;
- else if (pri[4] != pf_line_inf[4].pri[y]) y_end_next = y + 1;
- else if (alpha_mode[0] != pf_line_inf[0].alpha_mode[y]) y_end_next = y + 1;
- else if (alpha_mode[1] != pf_line_inf[1].alpha_mode[y]) y_end_next = y + 1;
- else if (alpha_mode[2] != pf_line_inf[2].alpha_mode[y]) y_end_next = y + 1;
- else if (alpha_mode[3] != pf_line_inf[3].alpha_mode[y]) y_end_next = y + 1;
- else if (alpha_mode[4] != pf_line_inf[4].alpha_mode[y]) y_end_next = y + 1;
- else if (alpha_level!=sa_line_inf[0].alpha_level[y]) y_end_next = y + 1;
- else if (spri!=sa_line_inf[0].spri[y]) y_end_next = y + 1;
- else if (sprite_alpha!=sa_line_inf[0].sprite_alpha[y]) y_end_next = y + 1;
- else
- {
- draw_line[y] = 1;
- draw_line_num[++i] = y;
- continue;
- }
-
- if (y_start_next < 0) y_start_next = y;
- }
- }
- y_end = y_end_next;
- y_start = y_start_next;
- draw_line_num[++i] = -1;
-
- /* alpha blend */
- alpha_mode_flag[0] = alpha_mode[0] & ~3;
- alpha_mode_flag[1] = alpha_mode[1] & ~3;
- alpha_mode_flag[2] = alpha_mode[2] & ~3;
- alpha_mode_flag[3] = alpha_mode[3] & ~3;
- alpha_mode_flag[4] = alpha_mode[4] & ~3;
- alpha_mode[0] &= 3;
- alpha_mode[1] &= 3;
- alpha_mode[2] &= 3;
- alpha_mode[3] &= 3;
- alpha_mode[4] &= 3;
- if (alpha_mode[0] > 1 ||
- alpha_mode[1] > 1 ||
- alpha_mode[2] > 1 ||
- alpha_mode[3] > 1 ||
- alpha_mode[4] > 1 ||
- (sprite_alpha & 0xff) != 0xff)
- {
- /* set alpha level */
- if (alpha_level != m_alpha_level_last)
- {
- int a = alpha_level;
- const int b = (a >> 8) & 0xf;
- const int c = (a >> 4) & 0xf;
- const int d = (a >> 0) & 0xf;
- a >>= 12;
-
- /* b000 7000 */
- int al_s = std::min(255, ((15 - d) * 256) / 8);
- int al_d = std::min(255, ((15 - b) * 256) / 8);
- m_alpha_level_3as = al_s;
- m_alpha_level_3ad = al_d;
- m_alpha_level_2as = al_d;
- m_alpha_level_2ad = al_s;
-
- al_s = std::min(255, ((15 - c) * 256) / 8);
- al_d = std::min(255, ((15 - a) * 256) / 8);
- m_alpha_level_3bs = al_s;
- m_alpha_level_3bd = al_d;
- m_alpha_level_2bs = al_d;
- m_alpha_level_2bd = al_s;
-
- alpha_set_level();
- m_alpha_level_last = alpha_level;
- }
-
- /* set sprite alpha mode */
- sprite_alpha_check = 0;
- sprite_alpha_all_2a=1;
- m_dpix_sp[1] = nullptr;
- m_dpix_sp[2] = nullptr;
- m_dpix_sp[4] = nullptr;
- m_dpix_sp[8] = nullptr;
- for (i = 0; i < 4; i++) /* i = sprite priority offset */
- {
- const u8 sprite_alpha_mode = (sprite_alpha >> (i * 2)) & 3;
- const u8 sftbit = 1 << i;
- if (m_sprite_pri_usage & sftbit)
- {
- if (sprite_alpha_mode == 1)
- {
- if (m_alpha_level_2as == 0 && m_alpha_level_2ad == 255)
- m_sprite_pri_usage &= ~sftbit; // Disable sprite priority block
- else
- {
- m_dpix_sp[sftbit] = m_dpix_n[2];
- sprite_alpha_check |= sftbit;
- }
- }
- else if (sprite_alpha_mode == 2)
- {
- if (sprite_alpha & 0xff00)
- {
- if (m_alpha_level_3as == 0 && m_alpha_level_3ad == 255) m_sprite_pri_usage &= ~sftbit;
- else
- {
- m_dpix_sp[sftbit] = m_dpix_n[3];
- sprite_alpha_check |= sftbit;
- sprite_alpha_all_2a = 0;
- }
- }
- else
- {
- if (m_alpha_level_3bs == 0 && m_alpha_level_3bd == 255) m_sprite_pri_usage &= ~sftbit;
- else
- {
- m_dpix_sp[sftbit] = m_dpix_n[5];
- sprite_alpha_check |= sftbit;
- sprite_alpha_all_2a = 0;
- }
- }
- }
- }
- }
-
- /* check alpha level */
- for (i = 0; i < 5; i++) /* i = playfield num (pos) */
- {
- const int alpha_type = (alpha_mode_flag[i] >> 4) & 3;
-
- if (alpha_mode[i] == 2)
- {
- if (alpha_type == 1)
- {
- /* if (m_alpha_level_2as == 0 && m_alpha_level_2ad == 255)
- * alpha_mode[i]=3; alpha_mode_flag[i] |= 0x80; }
- * will display continue screen in gseeker (mt 00026) */
- if (m_alpha_level_2as == 0 && m_alpha_level_2ad == 255) alpha_mode[i] = 0;
- else if (m_alpha_level_2as == 255 && m_alpha_level_2ad == 0) alpha_mode[i] = 1;
- }
- else if (alpha_type == 2)
- {
- if (m_alpha_level_2bs == 0 && m_alpha_level_2bd == 255) alpha_mode[i] = 0;
- else if (m_alpha_level_2as == 255 && m_alpha_level_2ad == 0 &&
- m_alpha_level_2bs == 255 && m_alpha_level_2bd == 0) alpha_mode[i] = 1;
- }
- else if (alpha_type == 3)
- {
- if (m_alpha_level_2as == 0 && m_alpha_level_2ad == 255 &&
- m_alpha_level_2bs == 0 && m_alpha_level_2bd == 255) alpha_mode[i] = 0;
- else if (m_alpha_level_2as == 255 && m_alpha_level_2ad == 0 &&
- m_alpha_level_2bs == 255 && m_alpha_level_2bd == 0) alpha_mode[i] = 1;
- }
- }
- else if (alpha_mode[i] == 3)
- {
- if (alpha_type == 1)
- {
- if (m_alpha_level_3as == 0 && m_alpha_level_3ad == 255) alpha_mode[i] = 0;
- else if (m_alpha_level_3as == 255 && m_alpha_level_3ad == 0) alpha_mode[i] = 1;
- }
- else if (alpha_type == 2)
- {
- if (m_alpha_level_3bs == 0 && m_alpha_level_3bd == 255) alpha_mode[i] = 0;
- else if (m_alpha_level_3as == 255 && m_alpha_level_3ad == 0 &&
- m_alpha_level_3bs == 255 && m_alpha_level_3bd == 0) alpha_mode[i] = 1;
- }
- else if (alpha_type == 3)
- {
- if (m_alpha_level_3as == 0 && m_alpha_level_3ad == 255 &&
- m_alpha_level_3bs == 0 && m_alpha_level_3bd == 255) alpha_mode[i] = 0;
- else if (m_alpha_level_3as == 255 && m_alpha_level_3ad == 0 &&
- m_alpha_level_3bs == 255 && m_alpha_level_3bd == 0) alpha_mode[i] = 1;
- }
- }
- }
-
- if ((alpha_mode[0] == 1 || alpha_mode[0] == 2 || !alpha_mode[0]) &&
- (alpha_mode[1] == 1 || alpha_mode[1] == 2 || !alpha_mode[1]) &&
- (alpha_mode[2] == 1 || alpha_mode[2] == 2 || !alpha_mode[2]) &&
- (alpha_mode[3] == 1 || alpha_mode[3] == 2 || !alpha_mode[3]) &&
- (alpha_mode[4] == 1 || alpha_mode[4] == 2 || !alpha_mode[4]) &&
- sprite_alpha_all_2a)
- {
- int alpha_type = (alpha_mode_flag[0] | alpha_mode_flag[1] | alpha_mode_flag[2] | alpha_mode_flag[3]) & 0x30;
- if ((alpha_type == 0x10 && m_alpha_level_2as == 255) ||
- (alpha_type == 0x20 && m_alpha_level_2as == 255 && m_alpha_level_2bs == 255) ||
- (alpha_type == 0x30 && m_alpha_level_2as == 255 && m_alpha_level_2bs == 255))
- {
- if (alpha_mode[0] > 1) alpha_mode[0] = 1;
- if (alpha_mode[1] > 1) alpha_mode[1] = 1;
- if (alpha_mode[2] > 1) alpha_mode[2] = 1;
- if (alpha_mode[3] > 1) alpha_mode[3] = 1;
- if (alpha_mode[4] > 1) alpha_mode[4] = 1;
- sprite_alpha_check = 0;
- m_dpix_sp[1] = nullptr;
- m_dpix_sp[2] = nullptr;
- m_dpix_sp[4] = nullptr;
- m_dpix_sp[8] = nullptr;
- }
- }
- }
- else
- {
- sprite_alpha_check = 0;
- m_dpix_sp[1] = nullptr;
- m_dpix_sp[2] = nullptr;
- m_dpix_sp[4] = nullptr;
- m_dpix_sp[8] = nullptr;
- }
-
- /* set scanline priority */
- {
- int pri_max_opa = -1;
- for (i = 0; i < 5; i++) /* i = playfield num (pos) */
- {
- const int p0 = pri[i];
- const int pri_sl1 = p0 & 0x0f;
-
- layer_tmp[i] = i + (pri_sl1 << 3);
-
- if (!alpha_mode[i])
- {
- layer_tmp[i] |= 0x80;
- count_skip_layer++;
- }
- else if (alpha_mode[i] == 1 && (alpha_mode_flag[i] & 0x80))
- {
- if (layer_tmp[i] > pri_max_opa) pri_max_opa = layer_tmp[i];
- }
- }
-
- if (pri_max_opa != -1)
- {
- if (pri_max_opa > layer_tmp[0]) { layer_tmp[0] |= 0x80; count_skip_layer++; }
- if (pri_max_opa > layer_tmp[1]) { layer_tmp[1] |= 0x80; count_skip_layer++; }
- if (pri_max_opa > layer_tmp[2]) { layer_tmp[2] |= 0x80; count_skip_layer++; }
- if (pri_max_opa > layer_tmp[3]) { layer_tmp[3] |= 0x80; count_skip_layer++; }
- if (pri_max_opa > layer_tmp[4]) { layer_tmp[4] |= 0x80; count_skip_layer++; }
- }
- }
-
- /* sort layer_tmp */
- for (i = 0; i < 4; i++)
- {
- for (int j = i + 1; j < 5; j++)
- {
- if (layer_tmp[i] < layer_tmp[j])
- {
- const int temp = layer_tmp[i];
- layer_tmp[i] = layer_tmp[j];
- layer_tmp[j] = temp;
- }
- }
- }
-
- /* check sprite & layer priority */
- {
- int pri_sp[5];
-
- const int l0 = layer_tmp[0] >> 3;
- const int l1 = layer_tmp[1] >> 3;
- const int l2 = layer_tmp[2] >> 3;
- const int l3 = layer_tmp[3] >> 3;
- const int l4 = layer_tmp[4] >> 3;
-
- pri_sp[0] = spri & 0xf;
- pri_sp[1] = (spri >> 4) & 0xf;
- pri_sp[2] = (spri >> 8) & 0xf;
- pri_sp[3] = spri >> 12;
-
- for (i = 0; i < 4; i++) /* i = sprite priority offset */
- {
- const int sflg = 1 << i;
- if (!(m_sprite_pri_usage & sflg)) continue;
- int sp = pri_sp[i];
-
- /*
- sprite priority==playfield priority
- GSEEKER (plane leaving hangar) --> sprite
- BUBSYMPH (title) ---> sprite
- DARIUSG (ZONE V' BOSS) ---> playfield
- */
-
- if (m_game == BUBSYMPH) sp++; //BUBSYMPH (title)
- if (m_game == GSEEKER) sp++; //GSEEKER (plane leaving hangar)
-
- if ( sp > l0) sprite[0] |= sflg;
- else if (sp <= l0 && sp > l1) sprite[1] |= sflg;
- else if (sp <= l1 && sp > l2) sprite[2] |= sflg;
- else if (sp <= l2 && sp > l3) sprite[3] |= sflg;
- else if (sp <= l3 && sp > l4) sprite[4] |= sflg;
- else if (sp <= l4 ) sprite[5] |= sflg;
- }
- }
-
-
- /* draw scanlines */
- bool alpha = false;
- for (i = count_skip_layer; i < 5; i++)
- {
- pos = layer_tmp[i] & 7;
- line_t[i] = &pf_line_inf[pos];
-
- if (sprite[i] & sprite_alpha_check) alpha = true;
- else if (!alpha) sprite[i] |= 0x100;
-
- if (alpha_mode[pos] > 1)
- {
- int alpha_type = (((alpha_mode_flag[pos] >> 4) & 3) - 1) * 2;
- m_dpix_lp[i] = m_dpix_n[alpha_mode[pos]+alpha_type];
- alpha = true;
- }
- else
- {
- if (alpha) m_dpix_lp[i] = m_dpix_n[1];
- else m_dpix_lp[i] = m_dpix_n[0];
- }
- }
- if (sprite[5] & sprite_alpha_check) alpha = true;
- else if (!alpha) sprite[5] |= 0x100;
-
- draw_scanlines(bitmap, 320, draw_line_num, line_t, sprite, rot, count_skip_layer);
- if (y_start < 0) break;
- }
-}
-
-/******************************************************************************/
-
-#define PSET_T \
- c = *source & m_sprite_pen_mask; \
- if (c) \
- { \
- p = *pri; \
- if (!p || p == 0xff) \
- { \
- *dest = pal[c]; \
- *pri = pri_dst; \
- } \
- }
-
-#define PSET_O \
- p = *pri; \
- if (!p || p == 0xff) \
- { \
- *dest = pal[*source & m_sprite_pen_mask]; \
- *pri = pri_dst; \
- }
-
-#define NEXT_P \
- source += dx; \
- dest++; \
- pri++;
-
-inline void taito_f3_state::f3_drawgfx(bitmap_rgb32 &dest_bmp, const rectangle &clip,
- gfx_element *gfx,
- int code,
- int color,
- int flipx, int flipy,
- int sx, int sy,
- u8 pri_dst)
-{
- rectangle myclip;
-
- pri_dst = 1 << pri_dst;
-
- /* KW 991012 -- Added code to force clip to bitmap boundary */
- myclip = clip;
- myclip &= dest_bmp.cliprect();
-
- if (gfx)
- {
- const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
- const u8 *code_base = gfx->get_data(code % gfx->elements());
-
- {
- /* compute sprite increment per screen pixel */
- int dx = 1;
- int dy = 1;
-
- int ex = sx + 16;
- int ey = sy + 16;
-
- int x_index_base;
- int y_index;
-
- if (flipx)
- {
- x_index_base = 15;
- dx = -1;
- }
- else
- {
- x_index_base = 0;
- }
-
- if (flipy)
- {
- y_index = 15;
- dy = -1;
- }
- else
- {
- y_index = 0;
- }
-
- if (sx < myclip.min_x)
- { /* clip left */
- int pixels = myclip.min_x - sx;
- sx += pixels;
- x_index_base += pixels * dx;
- }
- if (sy < myclip.min_y)
- { /* clip top */
- int pixels = myclip.min_y - sy;
- sy += pixels;
- y_index += pixels * dy;
- }
- /* NS 980211 - fixed incorrect clipping */
- if (ex > myclip.max_x + 1)
- { /* clip right */
- int pixels = ex - myclip.max_x - 1;
- ex -= pixels;
- }
- if (ey > myclip.max_y + 1)
- { /* clip bottom */
- int pixels = ey - myclip.max_y - 1;
- ey -= pixels;
- }
-
- if (ex > sx && ey > sy)
- { /* skip if inner loop doesn't draw anything */
-// if (dest_bmp.bpp == 32)
- {
- int y = ey - sy;
- const int x = (ex - sx - 1) | (m_tile_opaque_sp[code % gfx->elements()] << 4);
- const u8 *source0 = code_base + y_index * 16 + x_index_base;
- u32 *dest0 = &dest_bmp.pix32(sy, sx);
- u8 *pri0 = &m_pri_alp_bitmap.pix8(sy, sx);
- const int yadv = dest_bmp.rowpixels();
- const int yadvp = m_pri_alp_bitmap.rowpixels();
- dy = dy * 16;
- while (1)
- {
- const u8 *source = source0;
- u32 *dest = dest0;
- u8 *pri = pri0;
-
- switch (x)
- {
- int c;
- u8 p;
- case 31: PSET_O NEXT_P
- case 30: PSET_O NEXT_P
- case 29: PSET_O NEXT_P
- case 28: PSET_O NEXT_P
- case 27: PSET_O NEXT_P
- case 26: PSET_O NEXT_P
- case 25: PSET_O NEXT_P
- case 24: PSET_O NEXT_P
- case 23: PSET_O NEXT_P
- case 22: PSET_O NEXT_P
- case 21: PSET_O NEXT_P
- case 20: PSET_O NEXT_P
- case 19: PSET_O NEXT_P
- case 18: PSET_O NEXT_P
- case 17: PSET_O NEXT_P
- case 16: PSET_O break;
-
- case 15: PSET_T NEXT_P
- case 14: PSET_T NEXT_P
- case 13: PSET_T NEXT_P
- case 12: PSET_T NEXT_P
- case 11: PSET_T NEXT_P
- case 10: PSET_T NEXT_P
- case 9: PSET_T NEXT_P
- case 8: PSET_T NEXT_P
- case 7: PSET_T NEXT_P
- case 6: PSET_T NEXT_P
- case 5: PSET_T NEXT_P
- case 4: PSET_T NEXT_P
- case 3: PSET_T NEXT_P
- case 2: PSET_T NEXT_P
- case 1: PSET_T NEXT_P
- case 0: PSET_T
- }
-
- if (!(--y)) break;
- source0 += dy;
- dest0 += yadv;
- pri0 += yadvp;
- }
- }
- }
- }
- }
-}
-#undef PSET_T
-#undef PSET_O
-#undef NEXT_P
-
-
-inline void taito_f3_state::f3_drawgfxzoom(bitmap_rgb32 &dest_bmp, const rectangle &clip,
- gfx_element *gfx,
- int code,
- int color,
- int flipx, int flipy,
- int sx, int sy,
- int scalex, int scaley,
- u8 pri_dst)
-{
- rectangle myclip;
-
- pri_dst = 1 << pri_dst;
-
- /* KW 991012 -- Added code to force clip to bitmap boundary */
- myclip = clip;
- myclip &= dest_bmp.cliprect();
-
- if (gfx)
- {
- const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
- const u8 *code_base = gfx->get_data(code % gfx->elements());
-
- {
- /* compute sprite increment per screen pixel */
- int dx = (16 << 16) / scalex;
- int dy = (16 << 16) / scaley;
-
- int ex = sx + scalex;
- int ey = sy + scaley;
-
- int x_index_base;
- int y_index;
-
- if (flipx)
- {
- x_index_base = (scalex - 1) * dx;
- dx = -dx;
- }
- else
- {
- x_index_base = 0;
- }
-
- if (flipy)
- {
- y_index = (scaley - 1) * dy;
- dy = -dy;
- }
- else
- {
- y_index = 0;
- }
-
- if (sx < myclip.min_x)
- { /* clip left */
- int pixels = myclip.min_x - sx;
- sx += pixels;
- x_index_base += pixels * dx;
- }
- if (sy < myclip.min_y)
- { /* clip top */
- int pixels = myclip.min_y - sy;
- sy += pixels;
- y_index += pixels * dy;
- }
- /* NS 980211 - fixed incorrect clipping */
- if (ex > myclip.max_x + 1)
- { /* clip right */
- int pixels = ex - myclip.max_x - 1;
- ex -= pixels;
- }
- if (ey > myclip.max_y + 1)
- { /* clip bottom */
- int pixels = ey - myclip.max_y - 1;
- ey -= pixels;
- }
-
- if (ex > sx)
- { /* skip if inner loop doesn't draw anything */
-// if (dest_bmp.bpp == 32)
- {
- for (int y = sy; y < ey; y++)
- {
- const u8 *source = code_base + (y_index >> 16) * 16;
- u32 *dest = &dest_bmp.pix32(y);
- u8 *pri = &m_pri_alp_bitmap.pix8(y);
-
- int x_index = x_index_base;
- for (int x = sx; x < ex; x++)
- {
- int c = source[x_index >> 16] & m_sprite_pen_mask;
- if (c)
- {
- const u8 p = pri[x];
- if (p == 0 || p == 0xff)
- {
- dest[x] = pal[c];
- pri[x] = pri_dst;
- }
- }
- x_index += dx;
- }
- y_index += dy;
- }
- }
- }
- }
- }
-}
-
-
-#define CALC_ZOOM(p) { \
- p##_addition = 0x100 - block_zoom_##p + p##_addition_left; \
- p##_addition_left = p##_addition & 0xf; \
- p##_addition = p##_addition >> 4; \
- /*zoom##p = p##_addition << 12; */ \
-}
-
-void taito_f3_state::get_sprite_info(const u16 *spriteram16_ptr)
-{
- const rectangle &visarea = m_screen->visible_area();
- const int min_x = visarea.min_x, max_x = visarea.max_x;
- const int min_y = visarea.min_y, max_y = visarea.max_y;
- int global_x = 0,global_y = 0, subglobal_x = 0, subglobal_y = 0;
- int block_x = 0, block_y = 0;
- int last_color = 0, last_x = 0, last_y = 0,block_zoom_x = 0,block_zoom_y = 0;
- int this_x, this_y;
- int y_addition = 16, x_addition = 16;
- int multi = 0;
-
- int x_addition_left = 8, y_addition_left = 8;
-
- tempsprite *sprite_ptr = &m_spritelist[0];
-
- int total_sprites = 0;
-
- int color = 0;
- int flipx = 0, flipy = 0;
- //int old_x = 0;
- int y = 0, x = 0;
-
- int sprite_top = 0x2000;
- for (int offs = 0; offs < sprite_top && (total_sprites < 0x400); offs += 8)
- {
- const int current_offs = offs; /* Offs can change during loop, current_offs cannot */
-
- /* Check if the sprite list jump command bit is set */
- if ((spriteram16_ptr[current_offs + 6 + 0]) & 0x8000)
- {
- const u32 jump = (spriteram16_ptr[current_offs + 6 + 0]) & 0x3ff;
-
- const u32 new_offs = ((offs & 0x4000) | ((jump << 4) / 2));
- if (new_offs == offs)
- break;
- offs = new_offs - 8;
- }
-
- /* Check if special command bit is set */
- if (spriteram16_ptr[current_offs + 2 + 1] & 0x8000)
- {
- const u32 cntrl = (spriteram16_ptr[current_offs + 4 + 1]) & 0xffff;
- m_flipscreen = cntrl & 0x2000;
-
- /* cntrl & 0x1000 = disabled? (From F2 driver, doesn't seem used anywhere)
- cntrl & 0x0010 = ???
- cntrl & 0x0020 = ???
- cntrl & 0x0002 = enabled when Darius Gaiden sprite trail effect should occur (MT #1922)
- Notice that sprites also completely disappear due of a bug/missing feature in the
- alpha routines.
- */
-
- m_sprite_extra_planes = (cntrl & 0x0300) >> 8; // 0 = 4bpp, 1 = 5bpp, 2 = unused?, 3 = 6bpp
- m_sprite_pen_mask = (m_sprite_extra_planes << 4) | 0x0f;
-
- /* Sprite bank select */
- if (cntrl & 1)
- {
- offs = offs | 0x4000;
- sprite_top = sprite_top | 0x4000;
- }
- }
-
- /* Set global sprite scroll */
- if (((spriteram16_ptr[current_offs + 2 + 0]) & 0xf000) == 0xa000)
- {
- global_x = (spriteram16_ptr[current_offs + 2 + 0]) & 0xfff;
- if (global_x >= 0x800) global_x -= 0x1000;
- global_y = spriteram16_ptr[current_offs + 2 + 1] & 0xfff;
- if (global_y >= 0x800) global_y -= 0x1000;
- }
-
- /* And sub-global sprite scroll */
- if (((spriteram16_ptr[current_offs + 2 + 0]) & 0xf000) == 0x5000)
- {
- subglobal_x = (spriteram16_ptr[current_offs + 2 + 0]) & 0xfff;
- if (subglobal_x >= 0x800) subglobal_x -= 0x1000;
- subglobal_y = spriteram16_ptr[current_offs + 2 + 1] & 0xfff;
- if (subglobal_y >= 0x800) subglobal_y -= 0x1000;
- }
-
- if (((spriteram16_ptr[current_offs + 2 + 0]) & 0xf000) == 0xb000)
- {
- subglobal_x = (spriteram16_ptr[current_offs + 2 + 0]) & 0xfff;
- if (subglobal_x >= 0x800) subglobal_x -= 0x1000;
- subglobal_y = spriteram16_ptr[current_offs + 2 + 1] & 0xfff;
- if (subglobal_y >= 0x800) subglobal_y -= 0x1000;
- global_y = subglobal_y;
- global_x = subglobal_x;
- }
-
- /* A real sprite to process! */
- const int sprite = (spriteram16_ptr[current_offs + 0 + 0]) | ((spriteram16_ptr[current_offs + 4 + 1] & 1) << 16);
- const int spritecont = spriteram16_ptr[current_offs + 4 + 0] >> 8;
-
-/* These games either don't set the XY control bits properly (68020 bug?), or
- have some different mode from the others */
-#ifdef DARIUSG_KLUDGE
- if (m_game == DARIUSG || m_game == GEKIRIDO || m_game == CLEOPATR || m_game == RECALH)
- multi = spritecont & 0xf0;
-#endif
-
- /* Check if this sprite is part of a continued block */
- if (multi)
- {
- /* Bit 0x4 is 'use previous colour' for this block part */
- if (spritecont & 0x4) color=last_color;
- else color = (spriteram16_ptr[current_offs + 4 + 0]) & 0xff;
-
-#ifdef DARIUSG_KLUDGE
- if (m_game == DARIUSG || m_game == GEKIRIDO || m_game == CLEOPATR || m_game == RECALH)
- {
- /* Adjust X Position */
- if ((spritecont & 0x40) == 0)
- {
- if (spritecont & 0x4)
- x = block_x;
- else
- {
- this_x = spriteram16_ptr[current_offs + 2 + 0];
- if (this_x & 0x800) this_x = 0 - (0x800 - (this_x & 0x7ff)); else this_x &= 0x7ff;
-
- if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x8000)
- this_x += 0;
- else if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x4000) /* Ignore subglobal (but apply global) */
- this_x += global_x;
- else /* Apply both scroll offsets */
- this_x += global_x + subglobal_x;
-
- x = block_x = this_x;
- }
- x_addition_left = 8;
- CALC_ZOOM(x)
- }
- else if ((spritecont & 0x80) != 0)
- {
- x = last_x + x_addition;
- CALC_ZOOM(x)
- }
-
- /* Adjust Y Position */
- if ((spritecont & 0x10) == 0)
- {
- if (spritecont & 0x4)
- y = block_y;
- else
- {
- this_y = spriteram16_ptr[current_offs + 2 + 1] & 0xffff;
- if (this_y & 0x800) this_y = 0 - (0x800 - (this_y & 0x7ff)); else this_y &= 0x7ff;
-
- if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x8000)
- this_y += 0;
- else if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x4000) /* Ignore subglobal (but apply global) */
- this_y += global_y;
- else /* Apply both scroll offsets */
- this_y += global_y + subglobal_y;
-
- y = block_y = this_y;
- }
- y_addition_left = 8;
- CALC_ZOOM(y)
- }
- else if ((spritecont & 0x20) != 0)
- {
- y = last_y + y_addition;
- CALC_ZOOM(y)
- }
- }
- else
-#endif
- {
- /* Adjust X Position */
- if ((spritecont & 0x40) == 0)
- {
- x = block_x;
- x_addition_left = 8;
- CALC_ZOOM(x)
- }
- else if ((spritecont & 0x80) != 0)
- {
- x = last_x + x_addition;
- CALC_ZOOM(x)
- }
- /* Adjust Y Position */
- if ((spritecont & 0x10) == 0)
- {
- y = block_y;
- y_addition_left = 8;
- CALC_ZOOM(y)
- }
- else if ((spritecont & 0x20) != 0)
- {
- y = last_y + y_addition;
- CALC_ZOOM(y)
- }
- /* Both zero = reread block latch? */
- }
- }
- /* Else this sprite is the possible start of a block */
- else
- {
- color = (spriteram16_ptr[current_offs + 4 + 0]) & 0xff;
- last_color = color;
-
- /* Sprite positioning */
- this_y = spriteram16_ptr[current_offs + 2 + 1] & 0xffff;
- this_x = spriteram16_ptr[current_offs + 2 + 0] & 0xffff;
- if (this_y & 0x800) this_y = 0 - (0x800 - (this_y & 0x7ff)); else this_y &= 0x7ff;
- if (this_x & 0x800) this_x = 0 - (0x800 - (this_x & 0x7ff)); else this_x &= 0x7ff;
-
- /* Ignore both scroll offsets for this block */
- if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x8000)
- {
- this_x += 0;
- this_y += 0;
- }
- else if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x4000) /* Ignore subglobal (but apply global) */
- {
- this_x += global_x;
- this_y += global_y;
- }
- else /* Apply both scroll offsets */
- {
- this_x += global_x + subglobal_x;
- this_y += global_y + subglobal_y;
- }
-
- block_y = y = this_y;
- block_x = x = this_x;
-
- block_zoom_x = spriteram16_ptr[current_offs + 0 + 1];
- block_zoom_y = (block_zoom_x >> 8) & 0xff;
- block_zoom_x &= 0xff;
-
- x_addition_left = 8;
- CALC_ZOOM(x)
-
- y_addition_left = 8;
- CALC_ZOOM(y)
- }
-
- /* These features are common to sprite and block parts */
- flipx = spritecont & 0x1;
- flipy = spritecont & 0x2;
- multi = spritecont & 0x8;
- last_x=x;
- last_y = y;
-
- if (!sprite) continue;
- if (!x_addition || !y_addition) continue;
-
- if (m_flipscreen)
- {
- const int tx = 512 - x_addition - x;
- const int ty = 256 - y_addition - y;
-
- if (tx + x_addition <= min_x || tx > max_x || ty + y_addition <= min_y || ty > max_y) continue;
- sprite_ptr->x = tx;
- sprite_ptr->y = ty;
- sprite_ptr->flipx = !flipx;
- sprite_ptr->flipy = !flipy;
- }
- else
- {
- if (x + x_addition <= min_x || x > max_x || y + y_addition <= min_y || y > max_y) continue;
- sprite_ptr->x = x;
- sprite_ptr->y = y;
- sprite_ptr->flipx = flipx;
- sprite_ptr->flipy = flipy;
- }
-
- sprite_ptr->code = sprite;
- sprite_ptr->color = color;
- sprite_ptr->zoomx = x_addition;
- sprite_ptr->zoomy = y_addition;
- sprite_ptr->pri = (color & 0xc0) >> 6;
- sprite_ptr++;
- total_sprites++;
- }
- m_sprite_end = sprite_ptr;
-}
-#undef CALC_ZOOM
-
-
-void taito_f3_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- const tempsprite *sprite_ptr;
- gfx_element *sprite_gfx = m_gfxdecode->gfx(2);
-
- sprite_ptr = m_sprite_end;
- m_sprite_pri_usage = 0;
-
- // if sprites use more than 4bpp, the bottom bits of the color code must be masked out.
- // This fixes (at least) stage 1 battle ships and attract mode explosions in Ray Force.
-
- while (sprite_ptr != &m_spritelist[0])
- {
- sprite_ptr--;
-
- const int pri = sprite_ptr->pri;
- m_sprite_pri_usage |= 1 << pri;
-
- if (sprite_ptr->zoomx == 16 && sprite_ptr->zoomy == 16)
- f3_drawgfx(
- bitmap, cliprect, sprite_gfx,
- sprite_ptr->code,
- sprite_ptr->color & (~m_sprite_extra_planes),
- sprite_ptr->flipx, sprite_ptr->flipy,
- sprite_ptr->x, sprite_ptr->y,
- pri);
- else
- f3_drawgfxzoom(
- bitmap, cliprect, sprite_gfx,
- sprite_ptr->code,
- sprite_ptr->color & (~m_sprite_extra_planes),
- sprite_ptr->flipx, sprite_ptr->flipy,
- sprite_ptr->x, sprite_ptr->y,
- sprite_ptr->zoomx, sprite_ptr->zoomy,
- pri);
- }
-}
-
-/******************************************************************************/
-
-u32 taito_f3_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- u32 sy_fix[5], sx_fix[5];
-
- machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
-
- /* Setup scroll */
- sy_fix[0] = ((m_control_0[4] & 0xffff) << 9) + (1 << 16);
- sy_fix[1] = ((m_control_0[5] & 0xffff) << 9) + (1 << 16);
- sy_fix[2] = ((m_control_0[6] & 0xffff) << 9) + (1 << 16);
- sy_fix[3] = ((m_control_0[7] & 0xffff) << 9) + (1 << 16);
- sx_fix[0] = ((m_control_0[0] & 0xffc0) << 10) - (6 << 16);
- sx_fix[1] = ((m_control_0[1] & 0xffc0) << 10) - (10 << 16);
- sx_fix[2] = ((m_control_0[2] & 0xffc0) << 10) - (14 << 16);
- sx_fix[3] = ((m_control_0[3] & 0xffc0) << 10) - (18 << 16);
- sx_fix[4] = -(m_control_1[4]) + 41;
- sy_fix[4] = -(m_control_1[5] & 0x1ff);
-
- sx_fix[0]-=((m_control_0[0] & 0x003f) << 10) + 0x0400 - 0x10000;
- sx_fix[1]-=((m_control_0[1] & 0x003f) << 10) + 0x0400 - 0x10000;
- sx_fix[2]-=((m_control_0[2] & 0x003f) << 10) + 0x0400 - 0x10000;
- sx_fix[3]-=((m_control_0[3] & 0x003f) << 10) + 0x0400 - 0x10000;
-
- if (m_flipscreen)
- {
- sy_fix[0] = 0x3000000 - sy_fix[0];
- sy_fix[1] = 0x3000000 - sy_fix[1];
- sy_fix[2] = 0x3000000 - sy_fix[2];
- sy_fix[3] = 0x3000000 - sy_fix[3];
- sx_fix[0] = -0x1a00000 - sx_fix[0];
- sx_fix[1] = -0x1a00000 - sx_fix[1];
- sx_fix[2] = -0x1a00000 - sx_fix[2];
- sx_fix[3] = -0x1a00000 - sx_fix[3];
- sx_fix[4] = -sx_fix[4] + 75;
- sy_fix[4] = -sy_fix[4];
- }
-
- m_pri_alp_bitmap.fill(0, cliprect);
-
- /* sprites */
- if (m_sprite_lag == 0)
- get_sprite_info(m_spriteram.target());
-
- /* Update sprite buffer */
- draw_sprites(bitmap, cliprect);
-
- /* Parse sprite, alpha & clipping parts of lineram */
- get_spritealphaclip_info();
-
- /* Parse playfield effects */
- get_line_ram_info(m_tilemap[0], sx_fix[0], sy_fix[0], 0, m_pf_data[0]);
- get_line_ram_info(m_tilemap[1], sx_fix[1], sy_fix[1], 1, m_pf_data[1]);
- get_line_ram_info(m_tilemap[2], sx_fix[2], sy_fix[2], 2, m_pf_data[2]);
- get_line_ram_info(m_tilemap[3], sx_fix[3], sy_fix[3], 3, m_pf_data[3]);
- get_vram_info(m_vram_layer, m_pixel_layer, sx_fix[4], sy_fix[4]);
-
- /* Draw final framebuffer */
- scanline_draw(bitmap, cliprect);
-
- if (VERBOSE)
- print_debug_info(bitmap);
- return 0;
-}