diff options
Diffstat (limited to 'src/mame/video/taito_f3.cpp')
-rw-r--r-- | src/mame/video/taito_f3.cpp | 3111 |
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; -} |