1 // license:BSD-3-Clause
2 // copyright-holders:Bryan McPhail
3 /***************************************************************************
4 
5    Taito F3 Video emulation - Bryan McPhail, mish@tendril.co.uk
6 
7 ****************************************************************************
8 
9 Brief overview:
10 
11     4 scrolling layers (512x512 or 1024x512) of 4/5/6 bpp tiles.
12     1 scrolling text layer (512x512, characters generated in vram), 4bpp chars.
13     1 scrolling pixel layer (512x256 pixels generated in pivot ram), 4bpp pixels.
14     2 sprite banks (for double buffering of sprites)
15     Sprites can be 4, 5 or 6 bpp
16     Sprite scaling.
17     Rowscroll on all playfields
18     Line by line zoom on all playfields
19     Column scroll on all playfields
20     Line by line sprite and playfield priority mixing
21 
22 Notes:
23     All special effects are controlled by an area in 'line ram'.  Typically
24     there are 256 values, one for each line of the screen (including clipped
25     lines at the top of the screen).  For example, at 0x8000 in lineram,
26     there are 4 sets of 256 values (one for each playfield) and each value
27     is the scale control for that line in the destination bitmap (screen).
28     Therefore each line can have a different zoom value for special effects.
29 
30     This also applies to playfield priority, rowscroll, column scroll, sprite
31     priority and VRAM/pivot layers.
32 
33     However - at the start of line ram there are also sets of 256 values
34     controlling each effect - effects can be selectively applied to individual
35     playfields or only certain lines out of the 256 can be active - in which
36     case the last allowed value can be latched (typically used so a game can
37     use one zoom or row value over the whole playfield).
38 
39     The programmers of some of these games made strange use of flipscreen -
40     some games have all their graphics flipped in ROM, and use the flipscreen
41     bit to display them correctly!.
42 
43     Most games display 232 scanlines, but some use lineram effects to clip
44     themselves to 224 or less.
45 
46 ****************************************************************************
47 
48 Line ram memory map:
49 
50     Here 'playfield 1' refers to the first playfield in memory, etc
51 
52     0x0000: Column line control ram (256 lines)
53         100x:   Where bit 0 of x enables effect on playfield 1
54                 Where bit 1 of x enables effect on playfield 2
55                 Where bit 2 of x enables effect on playfield 3
56                 Where bit 3 of x enables effect on playfield 4
57     0x0200: Line control ram for 0x5000 section.
58     0x0400: Line control ram for 0x6000 section.
59         180x:   Where bit 0 of x latches sprite alpha value
60                 Where bit 1 of x latches tilemap alpha value
61     0x0600: Sprite control ram
62         1c0x:   Where x enables sprite control word for that line
63     0x0800: Zoom line control ram (256 lines)
64         200x:   Where bit 0 of x enables effect on playfield 1
65                 Where bit 1 of x enables effect on playfield 2
66                 Where bit 2 of x enables effect on playfield 3
67                 Where bit 3 of x enables effect on playfield 4
68     0x0a00: Assumed unused.
69     0x0c00: Rowscroll line control ram (256 lines)
70         280x:   Where bit 0 of x enables effect on playfield 1
71                 Where bit 1 of x enables effect on playfield 2
72                 Where bit 2 of x enables effect on playfield 3
73                 Where bit 3 of x enables effect on playfield 4
74     0x0e00: Priority line control ram (256 lines)
75         2c0x:   Where bit 0 of x enables effect on playfield 1
76                 Where bit 1 of x enables effect on playfield 2
77                 Where bit 2 of x enables effect on playfield 3
78                 Where bit 3 of x enables effect on playfield 4
79 
80     0x4000: Column scroll & clipping info
81 
82     0x5000: Clip plane 0 (low bits)
83     0x5200: Clip plane 1 (low bits)
84     0x5400: Unused?
85     0x5600: Used by quizhuhu (taito logo and ingame text), and landmakr (winning text),
86             special clip used in tandem with b*00 bit 11? [unemulated]
87 
88     0x6000: Sync register
89     0x6004: Sprite alpha control
90         0xff00: VRAM/Pixel layer control
91             0xa000 enables pixel layer for this line (Disables VRAM layer)
92             0x2000 enables garbage pixels for this line (maybe another pixel bank?) [unemulated]
93             0x0800 seems to set the vram layer to be opaque [unemulated]
94             Effect of other bits is unknown.
95         0x00c0: Alpha mode for sprites with pri value 0x00
96         0x0030: Alpha mode for sprites with pri value 0x00
97         0x000c: Alpha mode for sprites with pri value 0x00
98         0x0003: Alpha mode for sprites with pri value 0x00
99     0x6200: Alpha blending control
100 
101     0x6400 - controls X zoom of tile - each tile collapses to 16 single colour lines
102         xxx1 - affects bottom playfield
103         xxx2 -
104         xxx4 -
105         xxx8 - affects top playfield
106         xxfx - x zoom - 0 = 1st pixel 16 times
107                         1 = 1st pixel 8, then 2nd 8
108                         8 = 2 per pixel
109 
110         (these effects only known to be used on spcinvdj title screen and riding fight - not emulated)
111 
112         1xxx = interpret palette ram for this playfield line as 15 bit and bilinear filter framebuffer(??)
113         3xxx = interpret palette ram for this playfield line as 15 bit
114         7xxx = interpret palette ram for this playfield line as 24 bit palette
115         8xxx = interpret palette ram for this playfield line as 21 bit palette
116 
117         (effect not emulated)
118 
119     0x6600: Background - background palette entry (under all tilemaps) (takes part in alpha blending)
120 
121         (effect not emulated)
122 
123     0x7000: Pivot/vram layer enable
124     0x7200: Cram layer priority
125     0x7400: Sprite clipping
126     0x7600: Sprite priority values
127         0xf000: Relative priority for sprites with pri value 0xc0
128         0x0f00: Relative priority for sprites with pri value 0x80
129         0x00f0: Relative priority for sprites with pri value 0x40
130         0x000f: Relative priority for sprites with pri value 0x00
131 
132     0x8000: Playfield 1 scale (1 word per line, 256 lines, 0x80 = default no scale)
133     0x8200: Playfield 2/4 scale
134     0x8400: Playfield 3 scale
135     0x8600: Playfield 2/4 scale
136         0x00ff = Y scale (0x80 = no scale, > 0x80 is zoom in, < 0x80 is zoom out [0xc0 is half height of 0x80])
137         0xff00 = X scale (0 = no scale, > 0 = zoom in, [0x8000 would be double length])
138 
139         Playfield 2 & 4 registers seem to be interleaved, playfield 2 Y zoom is stored where you would
140         expect playfield 4 y zoom to be and vice versa.
141 
142     0x9000: Palette add (can affect opacity) [ not emulated ]
143 
144     0xa000: Playfield 1 rowscroll (1 word per line, 256 lines)
145     0xa200: Playfield 2 rowscroll
146     0xa400: Playfield 3 rowscroll
147     0xa600: Playfield 4 rowscroll
148 
149     0xb000: Playfield 1 priority (1 word per line, 256 lines)
150     0xb200: Playfield 2 priority
151     0xb400: Playfield 3 priority
152     0xb600: Playfield 4 priority
153         0xf000 = Blend mode, 0x3000 = Normal, 0x7000 = Alpha A, 0xb000 = Alpha B, others disable line
154         0x0800 = Clip line (totally disable line)
155         0x0400 = Assumed unused
156         0x0200 = If set enable clip plane 1
157         0x0100 = If set enable clip plane 0
158         0x00c0 = Assumed unused
159         0x0020 = Enable clip inverse mode for plane 1
160         0x0010 = Enable clip inverse mode for plane 0
161         0x000f = Layer priority
162 
163     0xc000 - 0xffff: Unused.
164 
165     When sprite priority==playfield priority sprite takes precedence (Bubble Symph title)
166 
167 ****************************************************************************
168 
169     F3 sprite format:
170 
171     Word 0: 0xffff      Tile number (LSB)
172     Word 1: 0xff00      X zoom
173             0x00ff      Y zoom
174     Word 2: 0x03ff      X position
175     Word 3: 0x03ff      Y position
176     Word 4: 0xf000      Sprite block controls
177             0x0800      Sprite block start
178             0x0400      Use same colour on this sprite as block start
179             0x0200      Y flip
180             0x0100      X flip
181             0x00ff      Colour
182     Word 5: 0xffff      Tile number (MSB), probably only low bits used
183     Word 6: 0x8000      If set, jump to sprite location in low bits
184             0x03ff      Location to jump to.
185     Word 7: 0xffff      Unused?  Always zero?
186 
187 ****************************************************************************
188 
189     Playfield control information (0x660000-1f):
190 
191     Word 0- 3: X scroll values for the 4 playfields.
192     Word 4- 7: Y scroll values for the 4 playfields.
193     Word 8-11: Unused.  Always zero.
194     Word   12: Pixel + VRAM playfields X scroll
195     Word   13: Pixel + VRAM playfields Y scroll
196     Word   14: Unused. Always zero.
197     Word   15: If set to 0x80, then 1024x512 playfields are used, else 512x512
198 
199     top bits unused - writing to low 4 bits is desync or blank tilemap
200 
201 Playfield tile info:
202     0xc000 0000 - X/Y Flip
203     0x3000 ffff - Tile index
204     0x0c00 0000 - Extra planes enable (00 = 4bpp, 01 = 5bpp, 10 = unused?, 11 = 6bpp)
205     0x0200 0000 - Alpha blend mode
206     0x01ff 0000 - Colour
207 
208 ***************************************************************************/
209 
210 #include "emu.h"
211 #include "includes/taito_f3.h"
212 #include "render.h"
213 
214 #include <algorithm>
215 
216 #define VERBOSE 0
217 #define DARIUSG_KLUDGE
218 //#define DEBUG_F3 1
219 
220 
221 /* Game specific data, some of this can be
222 removed when the software values are figured out */
223 struct F3config
224 {
225 	int name;
226 	int extend;
227 	int sprite_lag;
228 };
229 
230 static const F3config f3_config_table[] =
231 {
232 	/* Name    Extend  Lag */
233 	{ RINGRAGE,  0,     2 },
234 	{ ARABIANM,  0,     2 },
235 	{ RIDINGF,   1,     1 },
236 	{ GSEEKER,   0,     1 },
237 	{ COMMANDW,  1,     1 },
238 	{ SCFINALS,  0,     1 },
239 	{ TRSTAR,    1,     0 },
240 	{ GUNLOCK,   1,     2 },
241 	{ LIGHTBR,   1,     2 },
242 	{ KAISERKN,  0,     2 },
243 	{ DARIUSG,   0,     2 },
244 	{ BUBSYMPH,  1,     1 },
245 	{ SPCINVDX,  1,     1 },
246 	{ HTHERO95,  0,     1 },
247 	{ QTHEATER,  1,     1 },
248 	{ EACTION2,  1,     2 },
249 	{ RECALH,    1,     1 },
250 	{ SPCINV95,  0,     1 },
251 	{ TWINQIX,   1,     1 },
252 	{ QUIZHUHU,  1,     1 },
253 	{ PBOBBLE2,  0,     1 },
254 	{ GEKIRIDO,  0,     1 },
255 	{ KTIGER2,   0,     0 },
256 	{ BUBBLEM,   1,     1 },
257 	{ CLEOPATR,  0,     1 },
258 	{ PBOBBLE3,  0,     1 },
259 	{ ARKRETRN,  1,     1 },
260 	{ KIRAMEKI,  0,     1 },
261 	{ PUCHICAR,  1,     1 },
262 	{ PBOBBLE4,  0,     1 },
263 	{ POPNPOP,   1,     1 },
264 	{ LANDMAKR,  1,     1 },
265 	{ TMDRILL,   1,     0 },
266 	{0}
267 };
268 
269 
270 /*
271 alpha_mode
272 ---- --xx    0:disable 1:nomal 2:alpha 7000 3:alpha b000
273 ---1 ----    alpha level a
274 --1- ----    alpha level b
275 1--------    opaque line
276 */
277 
278 
279 /*
280 pri_alp_bitmap
281 ---- ---1    sprite priority 0
282 ---- --1-    sprite priority 1
283 ---- -1--    sprite priority 2
284 ---- 1---    sprite priority 3
285 ---1 ----    alpha level a 7000
286 --1- ----    alpha level b 7000
287 -1-- ----    alpha level a b000
288 1--- ----    alpha level b b000
289 1111 1111    opaque pixel
290 */
291 
292 
device_post_load()293 void taito_f3_state::device_post_load()
294 {
295 	/* force a reread of the dynamic tiles in the pixel layer */
296 	m_gfxdecode->gfx(0)->mark_all_dirty();
297 	m_gfxdecode->gfx(1)->mark_all_dirty();
298 }
299 
300 /******************************************************************************/
301 
print_debug_info(bitmap_rgb32 & bitmap)302 void taito_f3_state::print_debug_info(bitmap_rgb32 &bitmap)
303 {
304 /*  u16 *line_ram = m_line_ram;
305     int l[16];
306     char buf[64*16];
307     char *bufptr = buf;
308 
309     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);
310     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);
311     bufptr += sprintf(bufptr,"%04X %04X %04X %04X\n", m_control_1[0], m_control_1[1], m_control_1[2], m_control_1[3]);
312     bufptr += sprintf(bufptr,"%04X %04X %04X %04X\n", m_control_1[4], m_control_1[5], m_control_1[6], m_control_1[7]);
313 
314     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]);
315     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]);
316     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]);
317 
318     l[0] = line_ram[0x0040*2] & 0xffff;
319     l[1] = line_ram[0x00c0*2] & 0xffff;
320     l[2] = line_ram[0x0140*2] & 0xffff;
321     l[3] = line_ram[0x01c0*2] & 0xffff;
322     bufptr += sprintf(bufptr,"Ctr1: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
323 
324     l[0] = line_ram[0x0240*2] & 0xffff;
325     l[1] = line_ram[0x02c0*2] & 0xffff;
326     l[2] = line_ram[0x0340*2] & 0xffff;
327     l[3] = line_ram[0x03c0*2] & 0xffff;
328     bufptr += sprintf(bufptr,"Ctr2: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
329 
330     l[0] = line_ram[0x2c60*2] & 0xffff;
331     l[1] = line_ram[0x2ce0*2] & 0xffff;
332     l[2] = line_ram[0x2d60*2] & 0xffff;
333     l[3] = line_ram[0x2de0*2] & 0xffff;
334     bufptr += sprintf(bufptr,"Pri : %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
335 
336     l[0] = line_ram[0x2060*2] & 0xffff;
337     l[1] = line_ram[0x20e0*2] & 0xffff;
338     l[2] = line_ram[0x2160*2] & 0xffff;
339     l[3] = line_ram[0x21e0*2] & 0xffff;
340     bufptr += sprintf(bufptr,"Zoom: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
341 
342     l[0] = line_ram[0x2860*2] & 0xffff;
343     l[1] = line_ram[0x28e0*2] & 0xffff;
344     l[2] = line_ram[0x2960*2] & 0xffff;
345     l[3] = line_ram[0x29e0*2] & 0xffff;
346     bufptr += sprintf(bufptr,"Line: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
347 
348     l[0] = line_ram[0x1c60*2] & 0xffff;
349     l[1] = line_ram[0x1ce0*2] & 0xffff;
350     l[2] = line_ram[0x1d60*2] & 0xffff;
351     l[3] = line_ram[0x1de0*2] & 0xffff;
352     bufptr += sprintf(bufptr,"Sprt: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
353 
354     l[0] = line_ram[0x1860*2] & 0xffff;
355     l[1] = line_ram[0x18e0*2] & 0xffff;
356     l[2] = line_ram[0x1960*2] & 0xffff;
357     l[3] = line_ram[0x19e0*2] & 0xffff;
358     bufptr += sprintf(bufptr,"Pivt: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
359 
360     l[0] = line_ram[0x1060*2] & 0xffff;
361     l[1] = line_ram[0x10e0*2] & 0xffff;
362     l[2] = line_ram[0x1160*2] & 0xffff;
363     l[3] = line_ram[0x11e0*2] & 0xffff;
364     bufptr += sprintf(bufptr,"Colm: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
365 
366     l[0] = line_ram[0x1460*2] & 0xffff;
367     l[1] = line_ram[0x14e0*2] & 0xffff;
368     l[2] = line_ram[0x1560*2] & 0xffff;
369     l[3] = line_ram[0x15e0*2] & 0xffff;
370     bufptr += sprintf(bufptr,"5000: %04x %04x %04x %04x\n", l[0], l[1], l[2], l[3]);
371 
372     machine().ui().draw_text(&machine().render().ui_container(), buf, 60, 40); */
373 }
374 
375 /******************************************************************************/
376 
377 template<unsigned Layer>
TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info)378 TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info)
379 {
380 	const u32 tile = (m_pf_data[Layer][tile_index * 2 + 0] << 16) | (m_pf_data[Layer][tile_index * 2 + 1] & 0xffff);
381 	const u8 abtype = (tile >> (16 + 9)) & 1;
382 	// tiles can be configured to use 4, 5, or 6 bpp data.
383 	// if tiles use more than 4bpp, the bottom bits of the color code must be masked out.
384 	// This fixes (at least) the rain in round 6 of Arabian Magic.
385 	const u8 extra_planes = ((tile >> (16 + 10)) & 3); // 0 = 4bpp, 1 = 5bpp, 2 = unused?, 3 = 6bpp
386 
387 	tileinfo.set(3,
388 			tile & 0xffff,
389 			(tile >> 16) & 0x1ff & (~extra_planes),
390 			TILE_FLIPYX(tile >> 30));
391 	tileinfo.category =  abtype & 1;      /* alpha blending type */
392 	tileinfo.pen_mask = (extra_planes << 4) | 0x0f;
393 }
394 
395 
TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info_text)396 TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info_text)
397 {
398 	int flags = 0;
399 
400 	const u16 vram_tile = (m_textram[tile_index] & 0xffff);
401 
402 	if (vram_tile & 0x0100) flags |= TILE_FLIPX;
403 	if (vram_tile & 0x8000) flags |= TILE_FLIPY;
404 
405 	tileinfo.set(0,
406 			vram_tile & 0xff,
407 			(vram_tile >> 9) & 0x3f,
408 			flags);
409 }
410 
TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info_pixel)411 TILE_GET_INFO_MEMBER(taito_f3_state::get_tile_info_pixel)
412 {
413 	int col_off;
414 	int flags = 0;
415 	int y_offs = (m_control_1[5] & 0x1ff);
416 	if (m_flipscreen) y_offs += 0x100;
417 
418 	/* Colour is shared with VRAM layer */
419 	if ((((tile_index & 0x1f) * 8 + y_offs) & 0x1ff) > 0xff)
420 		col_off = 0x800 + ((tile_index & 0x1f) << 6) + ((tile_index & 0xfe0) >> 5);
421 	else
422 		col_off = ((tile_index & 0x1f) << 6) + ((tile_index & 0xfe0) >> 5);
423 
424 	const u16 vram_tile = (m_textram[col_off] & 0xffff);
425 
426 	if (vram_tile & 0x0100) flags |= TILE_FLIPX;
427 	if (vram_tile & 0x8000) flags |= TILE_FLIPY;
428 
429 	tileinfo.set(1,
430 			tile_index,
431 			(vram_tile >> 9) & 0x3f,
432 			flags);
433 }
434 
435 /******************************************************************************/
436 
WRITE_LINE_MEMBER(taito_f3_state::screen_vblank)437 WRITE_LINE_MEMBER(taito_f3_state::screen_vblank)
438 {
439 	// rising edge
440 	if (state)
441 	{
442 		if (m_sprite_lag==2)
443 		{
444 			if (machine().video().skip_this_frame() == 0)
445 			{
446 				get_sprite_info(m_spriteram16_buffered.get());
447 			}
448 			memcpy(m_spriteram16_buffered.get(), m_spriteram.target(), 0x10000);
449 		}
450 		else if (m_sprite_lag == 1)
451 		{
452 			if (machine().video().skip_this_frame() == 0)
453 			{
454 				get_sprite_info(m_spriteram.target());
455 			}
456 		}
457 	}
458 }
459 
video_start()460 void taito_f3_state::video_start()
461 {
462 	const F3config *pCFG = &f3_config_table[0];
463 
464 	m_alpha_level_2as = 127;
465 	m_alpha_level_2ad = 127;
466 	m_alpha_level_3as = 127;
467 	m_alpha_level_3ad = 127;
468 	m_alpha_level_2bs = 127;
469 	m_alpha_level_2bd = 127;
470 	m_alpha_level_3bs = 127;
471 	m_alpha_level_3bd = 127;
472 	m_alpha_level_last = -1;
473 
474 	m_pdest_2a = 0x10;
475 	m_pdest_2b = 0x20;
476 	m_tr_2a = 0;
477 	m_tr_2b = 1;
478 	m_pdest_3a = 0x40;
479 	m_pdest_3b = 0x80;
480 	m_tr_3a = 0;
481 	m_tr_3b = 1;
482 
483 	m_spritelist = nullptr;
484 	m_spriteram16_buffered = nullptr;
485 	m_pf_line_inf = nullptr;
486 	m_tile_opaque_sp = nullptr;
487 
488 	/* Setup individual game */
489 	do {
490 		if (pCFG->name == m_game)
491 		{
492 			break;
493 		}
494 		pCFG++;
495 	} while (pCFG->name);
496 
497 	m_game_config=pCFG;
498 
499 	if (m_game_config->extend)
500 	{
501 		m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
502 		m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
503 		m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<2>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
504 		m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<3>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 32);
505 
506 		m_pf_data[0] = m_pf_ram + (0x0000 / 2);
507 		m_pf_data[1] = m_pf_ram + (0x2000 / 2);
508 		m_pf_data[2] = m_pf_ram + (0x4000 / 2);
509 		m_pf_data[3] = m_pf_ram + (0x6000 / 2);
510 
511 		m_width_mask = 0x3ff;
512 		m_twidth_mask = 0x7f;
513 		m_twidth_mask_bit = 7;
514 
515 		m_tilemap[0]->set_transparent_pen(0);
516 		m_tilemap[1]->set_transparent_pen(0);
517 		m_tilemap[2]->set_transparent_pen(0);
518 		m_tilemap[3]->set_transparent_pen(0);
519 	}
520 	else
521 	{
522 		m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
523 		m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
524 		m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<2>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
525 		m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<3>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
526 		m_tilemap[4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<4>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
527 		m_tilemap[5] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<5>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
528 		m_tilemap[6] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<6>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
529 		m_tilemap[7] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info<7>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
530 
531 		m_pf_data[0] = m_pf_ram + (0x0000 / 2);
532 		m_pf_data[1] = m_pf_ram + (0x1000 / 2);
533 		m_pf_data[2] = m_pf_ram + (0x2000 / 2);
534 		m_pf_data[3] = m_pf_ram + (0x3000 / 2);
535 		m_pf_data[4] = m_pf_ram + (0x4000 / 2);
536 		m_pf_data[5] = m_pf_ram + (0x5000 / 2);
537 		m_pf_data[6] = m_pf_ram + (0x6000 / 2);
538 		m_pf_data[7] = m_pf_ram + (0x7000 / 2);
539 
540 		m_width_mask = 0x1ff;
541 		m_twidth_mask = 0x3f;
542 		m_twidth_mask_bit = 6;
543 
544 		m_tilemap[0]->set_transparent_pen(0);
545 		m_tilemap[1]->set_transparent_pen(0);
546 		m_tilemap[2]->set_transparent_pen(0);
547 		m_tilemap[3]->set_transparent_pen(0);
548 		m_tilemap[4]->set_transparent_pen(0);
549 		m_tilemap[5]->set_transparent_pen(0);
550 		m_tilemap[6]->set_transparent_pen(0);
551 		m_tilemap[7]->set_transparent_pen(0);
552 	}
553 
554 	m_spriteram16_buffered = std::make_unique<u16[]>(0x10000 / 2);
555 	m_spritelist = std::make_unique<tempsprite[]>(0x400);
556 	m_sprite_end = &m_spritelist[0];
557 	m_vram_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info_text)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
558 	m_pixel_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(taito_f3_state::get_tile_info_pixel)), TILEMAP_SCAN_COLS, 8, 8, 64, 32);
559 	m_pf_line_inf = std::make_unique<f3_playfield_line_inf[]>(5);
560 	m_sa_line_inf = std::make_unique<f3_spritealpha_line_inf[]>(1);
561 	m_screen->register_screen_bitmap(m_pri_alp_bitmap);
562 	m_tile_opaque_sp = std::make_unique<u8[]>(m_gfxdecode->gfx(2)->elements());
563 	for (int i = 0; i < 8; i++)
564 		m_tile_opaque_pf[i] = std::make_unique<u8[]>(m_gfxdecode->gfx(3)->elements());
565 
566 	m_vram_layer->set_transparent_pen(0);
567 	m_pixel_layer->set_transparent_pen(0);
568 
569 	// Palettes have 4 bpp indexes despite up to 6 bpp data. The unused top bits in the gfx data are cleared later.
570 	m_gfxdecode->gfx(2)->set_granularity(16);
571 	m_gfxdecode->gfx(3)->set_granularity(16);
572 
573 	m_flipscreen = 0;
574 	memset(m_spriteram16_buffered.get(), 0, 0x10000);
575 	memset(&m_spriteram[0], 0, 0x10000);
576 
577 	save_item(NAME(m_control_0));
578 	save_item(NAME(m_control_1));
579 
580 	m_gfxdecode->gfx(0)->set_source((u8 *)m_charram.target());
581 	m_gfxdecode->gfx(1)->set_source((u8 *)m_pivot_ram.target());
582 
583 	m_sprite_lag = m_game_config->sprite_lag;
584 
585 	init_alpha_blend_func();
586 
587 	{
588 		gfx_element *sprite_gfx = m_gfxdecode->gfx(2);
589 
590 		for (int c = 0; c < sprite_gfx->elements(); c++)
591 		{
592 			int chk_trans_or_opa = 0;
593 			const u8 *dp = sprite_gfx->get_data(c);
594 			for (int y = 0; y < sprite_gfx->height(); y++)
595 			{
596 				for (int x = 0; x < sprite_gfx->width(); x++)
597 				{
598 					if (!dp[x]) chk_trans_or_opa |= 2;
599 					else        chk_trans_or_opa |= 1;
600 				}
601 				dp += sprite_gfx->rowbytes();
602 			}
603 			if (chk_trans_or_opa == 1) m_tile_opaque_sp[c] = 1;
604 			else                       m_tile_opaque_sp[c] = 0;
605 		}
606 	}
607 
608 	{
609 		gfx_element *pf_gfx = m_gfxdecode->gfx(3);
610 
611 		for (int c = 0; c < pf_gfx->elements(); c++)
612 		{
613 			for (int extra_planes = 0; extra_planes < 4; extra_planes++)
614 			{
615 				int chk_trans_or_opa = 0;
616 				/* 0 = 4bpp, 1=5bpp, 2=?, 3=6bpp */
617 				const u8 extra_mask = ((extra_planes << 4) | 0x0f);
618 				const u8 *dp = pf_gfx->get_data(c);
619 
620 				for (int y = 0; y < pf_gfx->height(); y++)
621 				{
622 					for (int x = 0; x < pf_gfx->width(); x++)
623 					{
624 						if (!(dp[x] & extra_mask))
625 							chk_trans_or_opa |= 2;
626 						else
627 							chk_trans_or_opa |= 1;
628 					}
629 					dp += pf_gfx->rowbytes();
630 				}
631 				m_tile_opaque_pf[extra_planes][c] = chk_trans_or_opa;
632 			}
633 		}
634 	}
635 }
636 
637 /******************************************************************************/
638 
pf_ram_r(offs_t offset)639 u16 taito_f3_state::pf_ram_r(offs_t offset)
640 {
641 	return m_pf_ram[offset];
642 }
643 
pf_ram_w(offs_t offset,u16 data,u16 mem_mask)644 void taito_f3_state::pf_ram_w(offs_t offset, u16 data, u16 mem_mask)
645 {
646 	COMBINE_DATA(&m_pf_ram[offset]);
647 
648 	if (m_game_config->extend)
649 	{
650 		if (offset < 0x4000)
651 			m_tilemap[offset >> 12]->mark_tile_dirty((offset & 0xfff) >> 1);
652 	}
653 	else
654 	{
655 		if (offset < 0x4000)
656 			m_tilemap[offset >> 11]->mark_tile_dirty((offset & 0x7ff) >> 1);
657 	}
658 }
659 
control_0_w(offs_t offset,u16 data,u16 mem_mask)660 void taito_f3_state::control_0_w(offs_t offset, u16 data, u16 mem_mask)
661 {
662 	COMBINE_DATA(&m_control_0[offset]);
663 }
664 
control_1_w(offs_t offset,u16 data,u16 mem_mask)665 void taito_f3_state::control_1_w(offs_t offset, u16 data, u16 mem_mask)
666 {
667 	COMBINE_DATA(&m_control_1[offset]);
668 }
669 
spriteram_r(offs_t offset)670 u16 taito_f3_state::spriteram_r(offs_t offset)
671 {
672 	return m_spriteram[offset];
673 }
674 
spriteram_w(offs_t offset,u16 data,u16 mem_mask)675 void taito_f3_state::spriteram_w(offs_t offset, u16 data, u16 mem_mask)
676 {
677 	COMBINE_DATA(&m_spriteram[offset]);
678 }
679 
textram_r(offs_t offset)680 u16 taito_f3_state::textram_r(offs_t offset)
681 {
682 	return m_textram[offset];
683 }
684 
textram_w(offs_t offset,u16 data,u16 mem_mask)685 void taito_f3_state::textram_w(offs_t offset, u16 data, u16 mem_mask)
686 {
687 	COMBINE_DATA(&m_textram[offset]);
688 
689 	m_vram_layer->mark_tile_dirty(offset);
690 	//m_vram_layer->mark_tile_dirty(offset + 1);
691 
692 	if (offset > 0x7ff) offset -= 0x800;
693 
694 	const int tile = offset;
695 	const int col_off = ((tile & 0x3f) << 5) + ((tile & 0xfc0) >> 6);
696 
697 	m_pixel_layer->mark_tile_dirty(col_off);
698 	//m_pixel_layer->mark_tile_dirty(col_off+32);
699 }
700 
701 
charram_r(offs_t offset)702 u16 taito_f3_state::charram_r(offs_t offset)
703 {
704 	return m_charram[offset];
705 }
706 
charram_w(offs_t offset,u16 data,u16 mem_mask)707 void taito_f3_state::charram_w(offs_t offset, u16 data, u16 mem_mask)
708 {
709 	COMBINE_DATA(&m_charram[offset]);
710 	m_gfxdecode->gfx(0)->mark_dirty(offset >> 4);
711 }
712 
pivot_r(offs_t offset)713 u16 taito_f3_state::pivot_r(offs_t offset)
714 {
715 	return m_pivot_ram[offset];
716 }
717 
pivot_w(offs_t offset,u16 data,u16 mem_mask)718 void taito_f3_state::pivot_w(offs_t offset, u16 data, u16 mem_mask)
719 {
720 	COMBINE_DATA(&m_pivot_ram[offset]);
721 	m_gfxdecode->gfx(1)->mark_dirty(offset >> 4);
722 }
723 
lineram_r(offs_t offset)724 u16 taito_f3_state::lineram_r(offs_t offset)
725 {
726 	return m_line_ram[offset];
727 }
728 
lineram_w(offs_t offset,u16 data,u16 mem_mask)729 void taito_f3_state::lineram_w(offs_t offset, u16 data, u16 mem_mask)
730 {
731 	#ifdef UNUSED_FUNCTION
732 	/* DariusGX has an interesting bug at the start of Round D - the clearing of lineram
733 	(0xa000->0x0xa7ff) overflows into priority RAM (0xb000) and creates garbage priority
734 	values.  I'm not sure what the real machine would do with these values, and this
735 	emulation certainly doesn't like it, so I've chosen to catch the bug here, and prevent
736 	the trashing of priority ram.  If anyone has information on what the real machine does,
737 	please let me know! */
738 	/* Update: this doesn't seem to occur anymore, I'll leave this snippet in but commented out.
739 	 *         fwiw PC=0x1768a0/0x1768a4 is where the game clears lineram in round D, which is a
740 	 *         move.w Dn, (An,D7.w*2) , a kind of opcode that could've been bugged back then.
741 	 */
742 	if (m_game == DARIUSG)
743 	{
744 		if (m_f3_skip_this_frame)
745 			return;
746 		if (offset == 0xb000 / 2 && data == 0x003f)
747 		{
748 			m_f3_skip_this_frame = 1;
749 			return;
750 		}
751 	}
752 	#endif
753 
754 	COMBINE_DATA(&m_line_ram[offset]);
755 }
756 
palette_24bit_w(offs_t offset,u32 data,u32 mem_mask)757 void taito_f3_state::palette_24bit_w(offs_t offset, u32 data, u32 mem_mask)
758 {
759 	int r, g, b;
760 
761 	COMBINE_DATA(&m_paletteram32[offset]);
762 
763 	/* 12 bit palette games - there has to be a palette select bit somewhere */
764 	if (m_game == SPCINVDX || m_game == RIDINGF || m_game == ARABIANM || m_game == RINGRAGE)
765 	{
766 		b = 15 * ((m_paletteram32[offset] >> 4) & 0xf);
767 		g = 15 * ((m_paletteram32[offset] >> 8) & 0xf);
768 		r = 15 * ((m_paletteram32[offset] >> 12) & 0xf);
769 	}
770 
771 	/* This is weird - why are only the sprites and VRAM palettes 21 bit? */
772 	else if (m_game == CLEOPATR)
773 	{
774 		if (offset < 0x100 || offset > 0x1000)
775 		{
776 			r = ((m_paletteram32[offset] >> 16) & 0x7f) << 1;
777 			g = ((m_paletteram32[offset] >> 8) & 0x7f) << 1;
778 			b = ((m_paletteram32[offset] >> 0) & 0x7f) << 1;
779 		}
780 		else
781 		{
782 			r = (m_paletteram32[offset] >> 16) & 0xff;
783 			g = (m_paletteram32[offset] >> 8) & 0xff;
784 			b = (m_paletteram32[offset] >> 0) & 0xff;
785 		}
786 	}
787 
788 	/* Another weird couple - perhaps this is alpha blending related? */
789 	else if (m_game == TWINQIX || m_game == RECALH)
790 	{
791 		if (offset > 0x1c00)
792 		{
793 			r = ((m_paletteram32[offset] >> 16) & 0x7f) << 1;
794 			g = ((m_paletteram32[offset] >> 8) & 0x7f) << 1;
795 			b = ((m_paletteram32[offset] >> 0) & 0x7f) << 1;
796 		}
797 		else
798 		{
799 			r = (m_paletteram32[offset] >> 16) & 0xff;
800 			g = (m_paletteram32[offset] >> 8) & 0xff;
801 			b = (m_paletteram32[offset] >> 0) & 0xff;
802 		}
803 	}
804 
805 	/* All other games - standard 24 bit palette */
806 	else
807 	{
808 		r = (m_paletteram32[offset] >> 16) & 0xff;
809 		g = (m_paletteram32[offset] >> 8) & 0xff;
810 		b = (m_paletteram32[offset] >> 0) & 0xff;
811 	}
812 
813 	m_palette->set_pen_color(offset, rgb_t(r, g, b));
814 }
815 
816 /******************************************************************************/
817 
818 /*============================================================================*/
819 
820 #define SET_ALPHA_LEVEL(d, s)           \
821 {                                       \
822 	int level = s;                      \
823 	if (level == 0) level = -1;         \
824 	d = level + 1;                      \
825 }
826 
alpha_set_level()827 inline void taito_f3_state::alpha_set_level()
828 {
829 //  SET_ALPHA_LEVEL(m_alpha_s_1_1, m_alpha_level_2ad)
830 	SET_ALPHA_LEVEL(m_alpha_s_1_1, 255 - m_alpha_level_2as)
831 //  SET_ALPHA_LEVEL(m_alpha_s_1_2, m_alpha_level_2bd)
832 	SET_ALPHA_LEVEL(m_alpha_s_1_2, 255 - m_alpha_level_2bs)
833 	SET_ALPHA_LEVEL(m_alpha_s_1_4, m_alpha_level_3ad)
834 //  SET_ALPHA_LEVEL(m_alpha_s_1_5, m_alpha_level_3ad*m_alpha_level_2ad / 255)
835 	SET_ALPHA_LEVEL(m_alpha_s_1_5, m_alpha_level_3ad * (255 - m_alpha_level_2as) / 255)
836 //  SET_ALPHA_LEVEL(m_alpha_s_1_6, m_alpha_level_3ad*m_alpha_level_2bd / 255)
837 	SET_ALPHA_LEVEL(m_alpha_s_1_6, m_alpha_level_3ad * (255 - m_alpha_level_2bs) / 255)
838 	SET_ALPHA_LEVEL(m_alpha_s_1_8, m_alpha_level_3bd)
839 //  SET_ALPHA_LEVEL(m_alpha_s_1_9, m_alpha_level_3bd*m_alpha_level_2ad / 255)
840 	SET_ALPHA_LEVEL(m_alpha_s_1_9, m_alpha_level_3bd * (255 - m_alpha_level_2as) / 255)
841 //  SET_ALPHA_LEVEL(m_alpha_s_1_a, m_alpha_level_3bd*m_alpha_level_2bd / 255)
842 	SET_ALPHA_LEVEL(m_alpha_s_1_a, m_alpha_level_3bd * (255 - m_alpha_level_2bs) / 255)
843 
844 	SET_ALPHA_LEVEL(m_alpha_s_2a_0, m_alpha_level_2as)
845 	SET_ALPHA_LEVEL(m_alpha_s_2a_4, m_alpha_level_2as * m_alpha_level_3ad / 255)
846 	SET_ALPHA_LEVEL(m_alpha_s_2a_8, m_alpha_level_2as * m_alpha_level_3bd / 255)
847 
848 	SET_ALPHA_LEVEL(m_alpha_s_2b_0, m_alpha_level_2bs)
849 	SET_ALPHA_LEVEL(m_alpha_s_2b_4, m_alpha_level_2bs * m_alpha_level_3ad / 255)
850 	SET_ALPHA_LEVEL(m_alpha_s_2b_8, m_alpha_level_2bs * m_alpha_level_3bd / 255)
851 
852 	SET_ALPHA_LEVEL(m_alpha_s_3a_0, m_alpha_level_3as)
853 	SET_ALPHA_LEVEL(m_alpha_s_3a_1, m_alpha_level_3as * m_alpha_level_2ad / 255)
854 	SET_ALPHA_LEVEL(m_alpha_s_3a_2, m_alpha_level_3as * m_alpha_level_2bd / 255)
855 
856 	SET_ALPHA_LEVEL(m_alpha_s_3b_0, m_alpha_level_3bs)
857 	SET_ALPHA_LEVEL(m_alpha_s_3b_1, m_alpha_level_3bs * m_alpha_level_2ad / 255)
858 	SET_ALPHA_LEVEL(m_alpha_s_3b_2, m_alpha_level_3bs * m_alpha_level_2bd / 255)
859 }
860 #undef SET_ALPHA_LEVEL
861 
862 /*============================================================================*/
863 
864 #define COLOR1 BYTE4_XOR_LE(0)
865 #define COLOR2 BYTE4_XOR_LE(1)
866 #define COLOR3 BYTE4_XOR_LE(2)
867 
alpha_blend32_s(int alphas,u32 s)868 inline void taito_f3_state::alpha_blend32_s(int alphas, u32 s)
869 {
870 	u8 *sc = (u8 *)&s;
871 	u8 *dc = (u8 *)&m_dval;
872 	dc[COLOR1] = (alphas * sc[COLOR1]) >> 8;
873 	dc[COLOR2] = (alphas * sc[COLOR2]) >> 8;
874 	dc[COLOR3] = (alphas * sc[COLOR3]) >> 8;
875 }
876 
alpha_blend32_d(int alphas,u32 s)877 inline void taito_f3_state::alpha_blend32_d(int alphas, u32 s)
878 {
879 	u8 *sc = (u8 *)&s;
880 	u8 *dc = (u8 *)&m_dval;
881 	dc[COLOR1] = m_add_sat[dc[COLOR1]][(alphas * sc[COLOR1]) >> 8];
882 	dc[COLOR2] = m_add_sat[dc[COLOR2]][(alphas * sc[COLOR2]) >> 8];
883 	dc[COLOR3] = m_add_sat[dc[COLOR3]][(alphas * sc[COLOR3]) >> 8];
884 }
885 
886 /*============================================================================*/
887 
alpha_blend_1_1(u32 s)888 inline void taito_f3_state::alpha_blend_1_1(u32 s) { alpha_blend32_d(m_alpha_s_1_1, s); }
alpha_blend_1_2(u32 s)889 inline void taito_f3_state::alpha_blend_1_2(u32 s) { alpha_blend32_d(m_alpha_s_1_2, s); }
alpha_blend_1_4(u32 s)890 inline void taito_f3_state::alpha_blend_1_4(u32 s) { alpha_blend32_d(m_alpha_s_1_4, s); }
alpha_blend_1_5(u32 s)891 inline void taito_f3_state::alpha_blend_1_5(u32 s) { alpha_blend32_d(m_alpha_s_1_5, s); }
alpha_blend_1_6(u32 s)892 inline void taito_f3_state::alpha_blend_1_6(u32 s) { alpha_blend32_d(m_alpha_s_1_6, s); }
alpha_blend_1_8(u32 s)893 inline void taito_f3_state::alpha_blend_1_8(u32 s) { alpha_blend32_d(m_alpha_s_1_8, s); }
alpha_blend_1_9(u32 s)894 inline void taito_f3_state::alpha_blend_1_9(u32 s) { alpha_blend32_d(m_alpha_s_1_9, s); }
alpha_blend_1_a(u32 s)895 inline void taito_f3_state::alpha_blend_1_a(u32 s) { alpha_blend32_d(m_alpha_s_1_a, s); }
896 
alpha_blend_2a_0(u32 s)897 inline void taito_f3_state::alpha_blend_2a_0(u32 s) { alpha_blend32_s(m_alpha_s_2a_0, s); }
alpha_blend_2a_4(u32 s)898 inline void taito_f3_state::alpha_blend_2a_4(u32 s) { alpha_blend32_d(m_alpha_s_2a_4, s); }
alpha_blend_2a_8(u32 s)899 inline void taito_f3_state::alpha_blend_2a_8(u32 s) { alpha_blend32_d(m_alpha_s_2a_8, s); }
900 
alpha_blend_2b_0(u32 s)901 inline void taito_f3_state::alpha_blend_2b_0(u32 s) { alpha_blend32_s(m_alpha_s_2b_0, s); }
alpha_blend_2b_4(u32 s)902 inline void taito_f3_state::alpha_blend_2b_4(u32 s) { alpha_blend32_d(m_alpha_s_2b_4, s); }
alpha_blend_2b_8(u32 s)903 inline void taito_f3_state::alpha_blend_2b_8(u32 s) { alpha_blend32_d(m_alpha_s_2b_8, s); }
904 
alpha_blend_3a_0(u32 s)905 inline void taito_f3_state::alpha_blend_3a_0(u32 s) { alpha_blend32_s(m_alpha_s_3a_0, s); }
alpha_blend_3a_1(u32 s)906 inline void taito_f3_state::alpha_blend_3a_1(u32 s) { alpha_blend32_d(m_alpha_s_3a_1, s); }
alpha_blend_3a_2(u32 s)907 inline void taito_f3_state::alpha_blend_3a_2(u32 s) { alpha_blend32_d(m_alpha_s_3a_2, s); }
908 
alpha_blend_3b_0(u32 s)909 inline void taito_f3_state::alpha_blend_3b_0(u32 s) { alpha_blend32_s(m_alpha_s_3b_0, s); }
alpha_blend_3b_1(u32 s)910 inline void taito_f3_state::alpha_blend_3b_1(u32 s) { alpha_blend32_d(m_alpha_s_3b_1, s); }
alpha_blend_3b_2(u32 s)911 inline void taito_f3_state::alpha_blend_3b_2(u32 s) { alpha_blend32_d(m_alpha_s_3b_2, s); }
912 
913 /*============================================================================*/
914 
dpix_1_noalpha(u32 s_pix)915 int taito_f3_state::dpix_1_noalpha(u32 s_pix) { m_dval = s_pix; return 1; }
dpix_ret1(u32 s_pix)916 int taito_f3_state::dpix_ret1(u32 s_pix) { return 1; }
dpix_ret0(u32 s_pix)917 int taito_f3_state::dpix_ret0(u32 s_pix) { return 0; }
dpix_1_1(u32 s_pix)918 int taito_f3_state::dpix_1_1(u32 s_pix) { if (s_pix) alpha_blend_1_1(s_pix); return 1; }
dpix_1_2(u32 s_pix)919 int taito_f3_state::dpix_1_2(u32 s_pix) { if (s_pix) alpha_blend_1_2(s_pix); return 1; }
dpix_1_4(u32 s_pix)920 int taito_f3_state::dpix_1_4(u32 s_pix) { if (s_pix) alpha_blend_1_4(s_pix); return 1; }
dpix_1_5(u32 s_pix)921 int taito_f3_state::dpix_1_5(u32 s_pix) { if (s_pix) alpha_blend_1_5(s_pix); return 1; }
dpix_1_6(u32 s_pix)922 int taito_f3_state::dpix_1_6(u32 s_pix) { if (s_pix) alpha_blend_1_6(s_pix); return 1; }
dpix_1_8(u32 s_pix)923 int taito_f3_state::dpix_1_8(u32 s_pix) { if (s_pix) alpha_blend_1_8(s_pix); return 1; }
dpix_1_9(u32 s_pix)924 int taito_f3_state::dpix_1_9(u32 s_pix) { if (s_pix) alpha_blend_1_9(s_pix); return 1; }
dpix_1_a(u32 s_pix)925 int taito_f3_state::dpix_1_a(u32 s_pix) { if (s_pix) alpha_blend_1_a(s_pix); return 1; }
926 
dpix_2a_0(u32 s_pix)927 int taito_f3_state::dpix_2a_0(u32 s_pix)
928 {
929 	if (s_pix) alpha_blend_2a_0(s_pix);
930 	else      m_dval = 0;
931 	if (m_pdest_2a) { m_pval |= m_pdest_2a; return 0; }
932 	return 1;
933 }
dpix_2a_4(u32 s_pix)934 int taito_f3_state::dpix_2a_4(u32 s_pix)
935 {
936 	if (s_pix) alpha_blend_2a_4(s_pix);
937 	if (m_pdest_2a) { m_pval |= m_pdest_2a; return 0; }
938 	return 1;
939 }
dpix_2a_8(u32 s_pix)940 int taito_f3_state::dpix_2a_8(u32 s_pix)
941 {
942 	if (s_pix) alpha_blend_2a_8(s_pix);
943 	if (m_pdest_2a) { m_pval |= m_pdest_2a; return 0; }
944 	return 1;
945 }
946 
dpix_3a_0(u32 s_pix)947 int taito_f3_state::dpix_3a_0(u32 s_pix)
948 {
949 	if (s_pix) alpha_blend_3a_0(s_pix);
950 	else      m_dval = 0;
951 	if (m_pdest_3a) { m_pval |= m_pdest_3a; return 0; }
952 	return 1;
953 }
dpix_3a_1(u32 s_pix)954 int taito_f3_state::dpix_3a_1(u32 s_pix)
955 {
956 	if (s_pix) alpha_blend_3a_1(s_pix);
957 	if (m_pdest_3a) { m_pval |= m_pdest_3a; return 0; }
958 	return 1;
959 }
dpix_3a_2(u32 s_pix)960 int taito_f3_state::dpix_3a_2(u32 s_pix)
961 {
962 	if (s_pix) alpha_blend_3a_2(s_pix);
963 	if (m_pdest_3a) { m_pval |= m_pdest_3a; return 0; }
964 	return 1;
965 }
966 
dpix_2b_0(u32 s_pix)967 int taito_f3_state::dpix_2b_0(u32 s_pix)
968 {
969 	if (s_pix) alpha_blend_2b_0(s_pix);
970 	else      m_dval = 0;
971 	if (m_pdest_2b) { m_pval |= m_pdest_2b; return 0; }
972 	return 1;
973 }
dpix_2b_4(u32 s_pix)974 int taito_f3_state::dpix_2b_4(u32 s_pix)
975 {
976 	if (s_pix) alpha_blend_2b_4(s_pix);
977 	if (m_pdest_2b) { m_pval |= m_pdest_2b; return 0; }
978 	return 1;
979 }
dpix_2b_8(u32 s_pix)980 int taito_f3_state::dpix_2b_8(u32 s_pix)
981 {
982 	if (s_pix) alpha_blend_2b_8(s_pix);
983 	if (m_pdest_2b) { m_pval |= m_pdest_2b; return 0; }
984 	return 1;
985 }
986 
dpix_3b_0(u32 s_pix)987 int taito_f3_state::dpix_3b_0(u32 s_pix)
988 {
989 	if (s_pix) alpha_blend_3b_0(s_pix);
990 	else      m_dval = 0;
991 	if (m_pdest_3b) { m_pval |= m_pdest_3b; return 0; }
992 	return 1;
993 }
dpix_3b_1(u32 s_pix)994 int taito_f3_state::dpix_3b_1(u32 s_pix)
995 {
996 	if (s_pix) alpha_blend_3b_1(s_pix);
997 	if (m_pdest_3b) { m_pval |= m_pdest_3b; return 0; }
998 	return 1;
999 }
dpix_3b_2(u32 s_pix)1000 int taito_f3_state::dpix_3b_2(u32 s_pix)
1001 {
1002 	if (s_pix) alpha_blend_3b_2(s_pix);
1003 	if (m_pdest_3b) { m_pval |= m_pdest_3b; return 0; }
1004 	return 1;
1005 }
1006 
dpix_2_0(u32 s_pix)1007 int taito_f3_state::dpix_2_0(u32 s_pix)
1008 {
1009 	const u8 tr2 = m_tval & 1;
1010 	if (s_pix)
1011 	{
1012 		if (tr2 == m_tr_2b)      { alpha_blend_2b_0(s_pix); if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
1013 		else if (tr2 == m_tr_2a) { alpha_blend_2a_0(s_pix); if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
1014 	}
1015 	else
1016 	{
1017 		if (tr2 == m_tr_2b)      { m_dval = 0; if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
1018 		else if (tr2 == m_tr_2a) { m_dval = 0; if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
1019 	}
1020 	return 0;
1021 }
dpix_2_4(u32 s_pix)1022 int taito_f3_state::dpix_2_4(u32 s_pix)
1023 {
1024 	const u8 tr2 = m_tval & 1;
1025 	if (s_pix)
1026 	{
1027 		if (tr2 == m_tr_2b)      { alpha_blend_2b_4(s_pix); if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
1028 		else if (tr2 == m_tr_2a) { alpha_blend_2a_4(s_pix); if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
1029 	}
1030 	else
1031 	{
1032 		if (tr2 == m_tr_2b)      { if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
1033 		else if (tr2 == m_tr_2a) { if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
1034 	}
1035 	return 0;
1036 }
dpix_2_8(u32 s_pix)1037 int taito_f3_state::dpix_2_8(u32 s_pix)
1038 {
1039 	const u8 tr2 = m_tval & 1;
1040 	if (s_pix)
1041 	{
1042 		if (tr2 == m_tr_2b)      { alpha_blend_2b_8(s_pix); if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
1043 		else if (tr2 == m_tr_2a) { alpha_blend_2a_8(s_pix); if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
1044 	}
1045 	else
1046 	{
1047 		if (tr2 == m_tr_2b)      { if (m_pdest_2b) m_pval |= m_pdest_2b; else return 1; }
1048 		else if (tr2 == m_tr_2a) { if (m_pdest_2a) m_pval |= m_pdest_2a; else return 1; }
1049 	}
1050 	return 0;
1051 }
1052 
dpix_3_0(u32 s_pix)1053 int taito_f3_state::dpix_3_0(u32 s_pix)
1054 {
1055 	const u8 tr2 = m_tval & 1;
1056 	if (s_pix)
1057 	{
1058 		if (tr2 == m_tr_3b)      { alpha_blend_3b_0(s_pix); if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
1059 		else if (tr2 == m_tr_3a) { alpha_blend_3a_0(s_pix); if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
1060 	}
1061 	else
1062 	{
1063 		if (tr2 == m_tr_3b)      { m_dval = 0; if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
1064 		else if (tr2 == m_tr_3a) { m_dval = 0; if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
1065 	}
1066 	return 0;
1067 }
dpix_3_1(u32 s_pix)1068 int taito_f3_state::dpix_3_1(u32 s_pix)
1069 {
1070 	const u8 tr2 = m_tval & 1;
1071 	if (s_pix)
1072 	{
1073 		if (tr2 == m_tr_3b)      { alpha_blend_3b_1(s_pix); if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
1074 		else if (tr2 == m_tr_3a) { alpha_blend_3a_1(s_pix); if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
1075 	}
1076 	else
1077 	{
1078 		if (tr2 == m_tr_3b)      { if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
1079 		else if (tr2 == m_tr_3a) { if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
1080 	}
1081 	return 0;
1082 }
dpix_3_2(u32 s_pix)1083 int taito_f3_state::dpix_3_2(u32 s_pix)
1084 {
1085 	const u8 tr2 = m_tval & 1;
1086 	if (s_pix)
1087 	{
1088 		if (tr2 == m_tr_3b)      { alpha_blend_3b_2(s_pix); if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
1089 		else if (tr2 == m_tr_3a) { alpha_blend_3a_2(s_pix); if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
1090 	}
1091 	else
1092 	{
1093 		if (tr2 == m_tr_3b)      { if (m_pdest_3b) m_pval |= m_pdest_3b; else return 1; }
1094 		else if (tr2 == m_tr_3a) { if (m_pdest_3a) m_pval |= m_pdest_3a; else return 1; }
1095 	}
1096 	return 0;
1097 }
1098 
dpix_1_sprite(u32 s_pix)1099 inline void taito_f3_state::dpix_1_sprite(u32 s_pix)
1100 {
1101 	if (s_pix)
1102 	{
1103 		const u8 p1 = m_pval & 0xf0;
1104 		if      (p1 == 0x10) alpha_blend_1_1(s_pix);
1105 		else if (p1 == 0x20) alpha_blend_1_2(s_pix);
1106 		else if (p1 == 0x40) alpha_blend_1_4(s_pix);
1107 		else if (p1 == 0x50) alpha_blend_1_5(s_pix);
1108 		else if (p1 == 0x60) alpha_blend_1_6(s_pix);
1109 		else if (p1 == 0x80) alpha_blend_1_8(s_pix);
1110 		else if (p1 == 0x90) alpha_blend_1_9(s_pix);
1111 		else if (p1 == 0xa0) alpha_blend_1_a(s_pix);
1112 	}
1113 }
1114 
dpix_bg(u32 bgcolor)1115 inline void taito_f3_state::dpix_bg(u32 bgcolor)
1116 {
1117 	const u8 p1 = m_pval & 0xf0;
1118 	if (!p1)         m_dval = bgcolor;
1119 	else if (p1 == 0x10) alpha_blend_1_1(bgcolor);
1120 	else if (p1 == 0x20) alpha_blend_1_2(bgcolor);
1121 	else if (p1 == 0x40) alpha_blend_1_4(bgcolor);
1122 	else if (p1 == 0x50) alpha_blend_1_5(bgcolor);
1123 	else if (p1 == 0x60) alpha_blend_1_6(bgcolor);
1124 	else if (p1 == 0x80) alpha_blend_1_8(bgcolor);
1125 	else if (p1 == 0x90) alpha_blend_1_9(bgcolor);
1126 	else if (p1 == 0xa0) alpha_blend_1_a(bgcolor);
1127 }
1128 
1129 /******************************************************************************/
1130 
init_alpha_blend_func()1131 void taito_f3_state::init_alpha_blend_func()
1132 {
1133 	m_dpix_n[0][0x0] = &taito_f3_state::dpix_1_noalpha;
1134 	m_dpix_n[0][0x1] = &taito_f3_state::dpix_1_noalpha;
1135 	m_dpix_n[0][0x2] = &taito_f3_state::dpix_1_noalpha;
1136 	m_dpix_n[0][0x3] = &taito_f3_state::dpix_1_noalpha;
1137 	m_dpix_n[0][0x4] = &taito_f3_state::dpix_1_noalpha;
1138 	m_dpix_n[0][0x5] = &taito_f3_state::dpix_1_noalpha;
1139 	m_dpix_n[0][0x6] = &taito_f3_state::dpix_1_noalpha;
1140 	m_dpix_n[0][0x7] = &taito_f3_state::dpix_1_noalpha;
1141 	m_dpix_n[0][0x8] = &taito_f3_state::dpix_1_noalpha;
1142 	m_dpix_n[0][0x9] = &taito_f3_state::dpix_1_noalpha;
1143 	m_dpix_n[0][0xa] = &taito_f3_state::dpix_1_noalpha;
1144 	m_dpix_n[0][0xb] = &taito_f3_state::dpix_1_noalpha;
1145 	m_dpix_n[0][0xc] = &taito_f3_state::dpix_1_noalpha;
1146 	m_dpix_n[0][0xd] = &taito_f3_state::dpix_1_noalpha;
1147 	m_dpix_n[0][0xe] = &taito_f3_state::dpix_1_noalpha;
1148 	m_dpix_n[0][0xf] = &taito_f3_state::dpix_1_noalpha;
1149 
1150 	m_dpix_n[1][0x0] = &taito_f3_state::dpix_1_noalpha;
1151 	m_dpix_n[1][0x1] = &taito_f3_state::dpix_1_1;
1152 	m_dpix_n[1][0x2] = &taito_f3_state::dpix_1_2;
1153 	m_dpix_n[1][0x3] = &taito_f3_state::dpix_ret1;
1154 	m_dpix_n[1][0x4] = &taito_f3_state::dpix_1_4;
1155 	m_dpix_n[1][0x5] = &taito_f3_state::dpix_1_5;
1156 	m_dpix_n[1][0x6] = &taito_f3_state::dpix_1_6;
1157 	m_dpix_n[1][0x7] = &taito_f3_state::dpix_ret1;
1158 	m_dpix_n[1][0x8] = &taito_f3_state::dpix_1_8;
1159 	m_dpix_n[1][0x9] = &taito_f3_state::dpix_1_9;
1160 	m_dpix_n[1][0xa] = &taito_f3_state::dpix_1_a;
1161 	m_dpix_n[1][0xb] = &taito_f3_state::dpix_ret1;
1162 	m_dpix_n[1][0xc] = &taito_f3_state::dpix_ret1;
1163 	m_dpix_n[1][0xd] = &taito_f3_state::dpix_ret1;
1164 	m_dpix_n[1][0xe] = &taito_f3_state::dpix_ret1;
1165 	m_dpix_n[1][0xf] = &taito_f3_state::dpix_ret1;
1166 
1167 	m_dpix_n[2][0x0] = &taito_f3_state::dpix_2a_0;
1168 	m_dpix_n[2][0x1] = &taito_f3_state::dpix_ret0;
1169 	m_dpix_n[2][0x2] = &taito_f3_state::dpix_ret0;
1170 	m_dpix_n[2][0x3] = &taito_f3_state::dpix_ret0;
1171 	m_dpix_n[2][0x4] = &taito_f3_state::dpix_2a_4;
1172 	m_dpix_n[2][0x5] = &taito_f3_state::dpix_ret0;
1173 	m_dpix_n[2][0x6] = &taito_f3_state::dpix_ret0;
1174 	m_dpix_n[2][0x7] = &taito_f3_state::dpix_ret0;
1175 	m_dpix_n[2][0x8] = &taito_f3_state::dpix_2a_8;
1176 	m_dpix_n[2][0x9] = &taito_f3_state::dpix_ret0;
1177 	m_dpix_n[2][0xa] = &taito_f3_state::dpix_ret0;
1178 	m_dpix_n[2][0xb] = &taito_f3_state::dpix_ret0;
1179 	m_dpix_n[2][0xc] = &taito_f3_state::dpix_ret0;
1180 	m_dpix_n[2][0xd] = &taito_f3_state::dpix_ret0;
1181 	m_dpix_n[2][0xe] = &taito_f3_state::dpix_ret0;
1182 	m_dpix_n[2][0xf] = &taito_f3_state::dpix_ret0;
1183 
1184 	m_dpix_n[3][0x0] = &taito_f3_state::dpix_3a_0;
1185 	m_dpix_n[3][0x1] = &taito_f3_state::dpix_3a_1;
1186 	m_dpix_n[3][0x2] = &taito_f3_state::dpix_3a_2;
1187 	m_dpix_n[3][0x3] = &taito_f3_state::dpix_ret0;
1188 	m_dpix_n[3][0x4] = &taito_f3_state::dpix_ret0;
1189 	m_dpix_n[3][0x5] = &taito_f3_state::dpix_ret0;
1190 	m_dpix_n[3][0x6] = &taito_f3_state::dpix_ret0;
1191 	m_dpix_n[3][0x7] = &taito_f3_state::dpix_ret0;
1192 	m_dpix_n[3][0x8] = &taito_f3_state::dpix_ret0;
1193 	m_dpix_n[3][0x9] = &taito_f3_state::dpix_ret0;
1194 	m_dpix_n[3][0xa] = &taito_f3_state::dpix_ret0;
1195 	m_dpix_n[3][0xb] = &taito_f3_state::dpix_ret0;
1196 	m_dpix_n[3][0xc] = &taito_f3_state::dpix_ret0;
1197 	m_dpix_n[3][0xd] = &taito_f3_state::dpix_ret0;
1198 	m_dpix_n[3][0xe] = &taito_f3_state::dpix_ret0;
1199 	m_dpix_n[3][0xf] = &taito_f3_state::dpix_ret0;
1200 
1201 	m_dpix_n[4][0x0] = &taito_f3_state::dpix_2b_0;
1202 	m_dpix_n[4][0x1] = &taito_f3_state::dpix_ret0;
1203 	m_dpix_n[4][0x2] = &taito_f3_state::dpix_ret0;
1204 	m_dpix_n[4][0x3] = &taito_f3_state::dpix_ret0;
1205 	m_dpix_n[4][0x4] = &taito_f3_state::dpix_2b_4;
1206 	m_dpix_n[4][0x5] = &taito_f3_state::dpix_ret0;
1207 	m_dpix_n[4][0x6] = &taito_f3_state::dpix_ret0;
1208 	m_dpix_n[4][0x7] = &taito_f3_state::dpix_ret0;
1209 	m_dpix_n[4][0x8] = &taito_f3_state::dpix_2b_8;
1210 	m_dpix_n[4][0x9] = &taito_f3_state::dpix_ret0;
1211 	m_dpix_n[4][0xa] = &taito_f3_state::dpix_ret0;
1212 	m_dpix_n[4][0xb] = &taito_f3_state::dpix_ret0;
1213 	m_dpix_n[4][0xc] = &taito_f3_state::dpix_ret0;
1214 	m_dpix_n[4][0xd] = &taito_f3_state::dpix_ret0;
1215 	m_dpix_n[4][0xe] = &taito_f3_state::dpix_ret0;
1216 	m_dpix_n[4][0xf] = &taito_f3_state::dpix_ret0;
1217 
1218 	m_dpix_n[5][0x0] = &taito_f3_state::dpix_3b_0;
1219 	m_dpix_n[5][0x1] = &taito_f3_state::dpix_3b_1;
1220 	m_dpix_n[5][0x2] = &taito_f3_state::dpix_3b_2;
1221 	m_dpix_n[5][0x3] = &taito_f3_state::dpix_ret0;
1222 	m_dpix_n[5][0x4] = &taito_f3_state::dpix_ret0;
1223 	m_dpix_n[5][0x5] = &taito_f3_state::dpix_ret0;
1224 	m_dpix_n[5][0x6] = &taito_f3_state::dpix_ret0;
1225 	m_dpix_n[5][0x7] = &taito_f3_state::dpix_ret0;
1226 	m_dpix_n[5][0x8] = &taito_f3_state::dpix_ret0;
1227 	m_dpix_n[5][0x9] = &taito_f3_state::dpix_ret0;
1228 	m_dpix_n[5][0xa] = &taito_f3_state::dpix_ret0;
1229 	m_dpix_n[5][0xb] = &taito_f3_state::dpix_ret0;
1230 	m_dpix_n[5][0xc] = &taito_f3_state::dpix_ret0;
1231 	m_dpix_n[5][0xd] = &taito_f3_state::dpix_ret0;
1232 	m_dpix_n[5][0xe] = &taito_f3_state::dpix_ret0;
1233 	m_dpix_n[5][0xf] = &taito_f3_state::dpix_ret0;
1234 
1235 	m_dpix_n[6][0x0] = &taito_f3_state::dpix_2_0;
1236 	m_dpix_n[6][0x1] = &taito_f3_state::dpix_ret0;
1237 	m_dpix_n[6][0x2] = &taito_f3_state::dpix_ret0;
1238 	m_dpix_n[6][0x3] = &taito_f3_state::dpix_ret0;
1239 	m_dpix_n[6][0x4] = &taito_f3_state::dpix_2_4;
1240 	m_dpix_n[6][0x5] = &taito_f3_state::dpix_ret0;
1241 	m_dpix_n[6][0x6] = &taito_f3_state::dpix_ret0;
1242 	m_dpix_n[6][0x7] = &taito_f3_state::dpix_ret0;
1243 	m_dpix_n[6][0x8] = &taito_f3_state::dpix_2_8;
1244 	m_dpix_n[6][0x9] = &taito_f3_state::dpix_ret0;
1245 	m_dpix_n[6][0xa] = &taito_f3_state::dpix_ret0;
1246 	m_dpix_n[6][0xb] = &taito_f3_state::dpix_ret0;
1247 	m_dpix_n[6][0xc] = &taito_f3_state::dpix_ret0;
1248 	m_dpix_n[6][0xd] = &taito_f3_state::dpix_ret0;
1249 	m_dpix_n[6][0xe] = &taito_f3_state::dpix_ret0;
1250 	m_dpix_n[6][0xf] = &taito_f3_state::dpix_ret0;
1251 
1252 	m_dpix_n[7][0x0] = &taito_f3_state::dpix_3_0;
1253 	m_dpix_n[7][0x1] = &taito_f3_state::dpix_3_1;
1254 	m_dpix_n[7][0x2] = &taito_f3_state::dpix_3_2;
1255 	m_dpix_n[7][0x3] = &taito_f3_state::dpix_ret0;
1256 	m_dpix_n[7][0x4] = &taito_f3_state::dpix_ret0;
1257 	m_dpix_n[7][0x5] = &taito_f3_state::dpix_ret0;
1258 	m_dpix_n[7][0x6] = &taito_f3_state::dpix_ret0;
1259 	m_dpix_n[7][0x7] = &taito_f3_state::dpix_ret0;
1260 	m_dpix_n[7][0x8] = &taito_f3_state::dpix_ret0;
1261 	m_dpix_n[7][0x9] = &taito_f3_state::dpix_ret0;
1262 	m_dpix_n[7][0xa] = &taito_f3_state::dpix_ret0;
1263 	m_dpix_n[7][0xb] = &taito_f3_state::dpix_ret0;
1264 	m_dpix_n[7][0xc] = &taito_f3_state::dpix_ret0;
1265 	m_dpix_n[7][0xd] = &taito_f3_state::dpix_ret0;
1266 	m_dpix_n[7][0xe] = &taito_f3_state::dpix_ret0;
1267 	m_dpix_n[7][0xf] = &taito_f3_state::dpix_ret0;
1268 
1269 	for (int i = 0; i < 256; i++)
1270 		for (int j = 0; j < 256; j++)
1271 			m_add_sat[i][j] = std::min(i + j, 255);
1272 }
1273 
1274 /******************************************************************************/
1275 
1276 #define GET_PIXMAP_POINTER(pf_num) \
1277 { \
1278 	const f3_playfield_line_inf *line_tmp = line_t[pf_num]; \
1279 	m_src[pf_num] = line_tmp->src[y]; \
1280 	m_src_s[pf_num] = line_tmp->src_s[y]; \
1281 	m_src_e[pf_num] = line_tmp->src_e[y]; \
1282 	m_tsrc[pf_num] = line_tmp->tsrc[y]; \
1283 	m_tsrc_s[pf_num] = line_tmp->tsrc_s[y]; \
1284 	m_x_count[pf_num] = line_tmp->x_count[y]; \
1285 	m_x_zoom[pf_num] = line_tmp->x_zoom[y]; \
1286 	m_clip_al[pf_num] = line_tmp->clip0[y] & 0xffff; \
1287 	m_clip_ar[pf_num] = line_tmp->clip0[y] >> 16; \
1288 	m_clip_bl[pf_num] = line_tmp->clip1[y] & 0xffff; \
1289 	m_clip_br[pf_num] = line_tmp->clip1[y] >> 16; \
1290 }
1291 
1292 #define CULC_PIXMAP_POINTER(pf_num) \
1293 { \
1294 	m_x_count[pf_num] += m_x_zoom[pf_num]; \
1295 	if (m_x_count[pf_num] >> 16) \
1296 	{ \
1297 		m_x_count[pf_num] &= 0xffff; \
1298 		m_src[pf_num]++; \
1299 		m_tsrc[pf_num]++; \
1300 		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]; } \
1301 	} \
1302 }
1303 
1304 #define UPDATE_PIXMAP_SP(pf_num) \
1305 	if (cx >= clip_als && cx < clip_ars && !(cx >= clip_bls && cx < clip_brs)) \
1306 	{ \
1307 		sprite_pri = sprite[pf_num] & m_pval; \
1308 		if (sprite_pri) \
1309 		{ \
1310 			if (sprite[pf_num] & 0x100) break; \
1311 			if (!m_dpix_sp[sprite_pri]) \
1312 			{ \
1313 				if (!(m_pval & 0xf0)) break; \
1314 				else { dpix_1_sprite(*dsti); *dsti = m_dval; break; } \
1315 			} \
1316 			if ((this->*m_dpix_sp[sprite_pri][m_pval >> 4])(*dsti)) { *dsti = m_dval; break; } \
1317 		} \
1318 	}
1319 
1320 #define UPDATE_PIXMAP_LP(pf_num) \
1321 	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])) \
1322 	{ \
1323 		m_tval = *m_tsrc[pf_num]; \
1324 		if (m_tval & 0xf0) \
1325 			if ((this->*m_dpix_lp[pf_num][m_pval >> 4])(clut[*m_src[pf_num]])) { *dsti = m_dval; break; } \
1326 	}
1327 
1328 
1329 /*============================================================================*/
1330 
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)1331 inline void taito_f3_state::draw_scanlines(
1332 							bitmap_rgb32 &bitmap, int xsize, s16 *draw_line_num,
1333 							const f3_playfield_line_inf **line_t,
1334 							const int *sprite,
1335 							u32 orient,
1336 							int skip_layer_num)
1337 {
1338 	const pen_t *clut = &m_palette->pen(0);
1339 	const u32 bgcolor = clut[0];
1340 
1341 	const int x = 46;
1342 
1343 	u16 clip_als = 0, clip_ars = 0, clip_bls = 0, clip_brs = 0;
1344 
1345 	int yadv = bitmap.rowpixels();
1346 	int yadvp = m_pri_alp_bitmap.rowpixels();
1347 	int i = 0, y = draw_line_num[0];
1348 	int ty = y;
1349 
1350 	if (orient & ORIENTATION_FLIP_Y)
1351 	{
1352 		ty = bitmap.height() - 1 - ty;
1353 		yadv = -yadv;
1354 		yadvp = -yadvp;
1355 	}
1356 
1357 	u8 *dstp0 = &m_pri_alp_bitmap.pix(ty, x);
1358 
1359 	m_pdest_2a = m_alpha_level_2ad ? 0x10 : 0;
1360 	m_pdest_2b = m_alpha_level_2bd ? 0x20 : 0;
1361 	m_tr_2a =(m_alpha_level_2as == 0 && m_alpha_level_2ad == 255) ? -1 : 0;
1362 	m_tr_2b =(m_alpha_level_2bs == 0 && m_alpha_level_2bd == 255) ? -1 : 1;
1363 	m_pdest_3a = m_alpha_level_3ad ? 0x40 : 0;
1364 	m_pdest_3b = m_alpha_level_3bd ? 0x80 : 0;
1365 	m_tr_3a =(m_alpha_level_3as == 0 && m_alpha_level_3ad == 255) ? -1 : 0;
1366 	m_tr_3b =(m_alpha_level_3bs == 0 && m_alpha_level_3bd == 255) ? -1 : 1;
1367 
1368 	{
1369 		u32 *dsti0 = &bitmap.pix(ty, x);
1370 		while (1)
1371 		{
1372 			int cx = 0;
1373 
1374 			clip_als = m_sa_line_inf[0].sprite_clip0[y] & 0xffff;
1375 			clip_ars = m_sa_line_inf[0].sprite_clip0[y] >> 16;
1376 			clip_bls = m_sa_line_inf[0].sprite_clip1[y] & 0xffff;
1377 			clip_brs = m_sa_line_inf[0].sprite_clip1[y] >> 16;
1378 
1379 			int length = xsize;
1380 			u32 *dsti = dsti0;
1381 			u8 *dstp = dstp0;
1382 
1383 			switch (skip_layer_num)
1384 			{
1385 				case 0: GET_PIXMAP_POINTER(0)
1386 				case 1: GET_PIXMAP_POINTER(1)
1387 				case 2: GET_PIXMAP_POINTER(2)
1388 				case 3: GET_PIXMAP_POINTER(3)
1389 				case 4: GET_PIXMAP_POINTER(4)
1390 			}
1391 
1392 			while (1)
1393 			{
1394 				m_pval = *dstp;
1395 				if (m_pval != 0xff)
1396 				{
1397 					u8 sprite_pri;
1398 					switch (skip_layer_num)
1399 					{
1400 						case 0: UPDATE_PIXMAP_SP(0) UPDATE_PIXMAP_LP(0)
1401 						case 1: UPDATE_PIXMAP_SP(1) UPDATE_PIXMAP_LP(1)
1402 						case 2: UPDATE_PIXMAP_SP(2) UPDATE_PIXMAP_LP(2)
1403 						case 3: UPDATE_PIXMAP_SP(3) UPDATE_PIXMAP_LP(3)
1404 						case 4: UPDATE_PIXMAP_SP(4) UPDATE_PIXMAP_LP(4)
1405 						case 5: UPDATE_PIXMAP_SP(5)
1406 								if (!bgcolor) { if (!(m_pval & 0xf0)) { *dsti = 0; break; } }
1407 								else dpix_bg(bgcolor);
1408 								*dsti = m_dval;
1409 					}
1410 				}
1411 
1412 				if (!(--length)) break;
1413 				dsti++;
1414 				dstp++;
1415 				cx++;
1416 
1417 				switch (skip_layer_num)
1418 				{
1419 					case 0: CULC_PIXMAP_POINTER(0)
1420 					case 1: CULC_PIXMAP_POINTER(1)
1421 					case 2: CULC_PIXMAP_POINTER(2)
1422 					case 3: CULC_PIXMAP_POINTER(3)
1423 					case 4: CULC_PIXMAP_POINTER(4)
1424 				}
1425 			}
1426 
1427 			i++;
1428 			if (draw_line_num[i] < 0) break;
1429 			if (draw_line_num[i] == y + 1)
1430 			{
1431 				dsti0 += yadv;
1432 				dstp0 += yadvp;
1433 				y++;
1434 				continue;
1435 			}
1436 			else
1437 			{
1438 				dsti0 += (draw_line_num[i] - y) * yadv;
1439 				dstp0 += (draw_line_num[i] - y) * yadvp;
1440 				y = draw_line_num[i];
1441 			}
1442 		}
1443 	}
1444 }
1445 #undef GET_PIXMAP_POINTER
1446 #undef CULC_PIXMAP_POINTER
1447 
1448 /******************************************************************************/
1449 
visible_tile_check(f3_playfield_line_inf * line_t,int line,u32 x_index_fx,u32 y_index,u16 * pf_data_n)1450 void taito_f3_state::visible_tile_check(
1451 						f3_playfield_line_inf *line_t,
1452 						int line,
1453 						u32 x_index_fx,u32 y_index,
1454 						u16 *pf_data_n)
1455 {
1456 	u16 *pf_base;
1457 
1458 	int alpha_mode = line_t->alpha_mode[line];
1459 	if (!alpha_mode) return;
1460 
1461 	const u32 total_elements = m_gfxdecode->gfx(3)->elements();
1462 
1463 	int tile_index = x_index_fx >> 16;
1464 	const int tile_num = (((line_t->x_zoom[line] * 320 + (x_index_fx & 0xffff) + 0xffff) >> 16) + (tile_index & 0xf) + 15) >> 4;
1465 	tile_index >>= 4;
1466 
1467 	if (m_flipscreen)
1468 	{
1469 		pf_base = pf_data_n + ((31 - (y_index >> 4)) << m_twidth_mask_bit);
1470 		tile_index = (m_twidth_mask - tile_index) - tile_num + 1;
1471 	}
1472 	else pf_base = pf_data_n + ((y_index >> 4) << m_twidth_mask_bit);
1473 
1474 	bool trans_all = true;
1475 	bool opaque_all = true;
1476 	int alpha_type = 0;
1477 	for (int i = 0; i < tile_num; i++)
1478 	{
1479 		const u32 tile = (pf_base[(tile_index * 2 + 0) & m_twidth_mask] << 16) | (pf_base[(tile_index * 2 + 1) & m_twidth_mask]);
1480 		const u8  extra_planes = (tile >> (16 + 10)) & 3;
1481 		if (tile & 0xffff)
1482 		{
1483 			trans_all = false;
1484 			if (opaque_all)
1485 			{
1486 				if (m_tile_opaque_pf[extra_planes][(tile & 0xffff) % total_elements] != 1) opaque_all = false;
1487 			}
1488 
1489 			if (alpha_mode == 1)
1490 			{
1491 				if (!opaque_all) return;
1492 			}
1493 			else
1494 			{
1495 				if (alpha_type != 3)
1496 				{
1497 					if ((tile >> (16 + 9)) & 1) alpha_type |= 2;
1498 					else                        alpha_type |= 1;
1499 				}
1500 				else if (!opaque_all) break;
1501 			}
1502 		}
1503 		else if (opaque_all) opaque_all = false;
1504 
1505 		tile_index++;
1506 	}
1507 
1508 	if (trans_all) { line_t->alpha_mode[line] = 0; return; }
1509 
1510 	if (alpha_mode > 1)
1511 	{
1512 		line_t->alpha_mode[line] |= alpha_type << 4;
1513 	}
1514 
1515 	if (opaque_all)
1516 		line_t->alpha_mode[line] |= 0x80;
1517 }
1518 
1519 /******************************************************************************/
1520 
calculate_clip(int y,u16 pri,u32 * clip0,u32 * clip1,int * line_enable)1521 void taito_f3_state::calculate_clip(int y, u16 pri, u32 *clip0, u32 *clip1, int *line_enable)
1522 {
1523 	const f3_spritealpha_line_inf *sa_line_t = &m_sa_line_inf[0];
1524 
1525 	switch (pri)
1526 	{
1527 	case 0x0100: /* Clip plane 1 enable */
1528 		{
1529 			if (sa_line_t->clip0_l[y] > sa_line_t->clip0_r[y])
1530 				*line_enable = 0;
1531 			else
1532 				*clip0 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
1533 			*clip1 = 0;
1534 		}
1535 		break;
1536 	case 0x0110: /* Clip plane 1 enable, inverted */
1537 		{
1538 			*clip1 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
1539 			*clip0 = 0x7fff0000;
1540 		}
1541 		break;
1542 	case 0x0200: /* Clip plane 2 enable */
1543 		{
1544 			if (sa_line_t->clip1_l[y] > sa_line_t->clip1_r[y])
1545 				*line_enable = 0;
1546 			else
1547 				*clip0 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
1548 			*clip1 = 0;
1549 		}
1550 		break;
1551 	case 0x0220: /* Clip plane 2 enable, inverted */
1552 		{
1553 			*clip1 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
1554 			*clip0 = 0x7fff0000;
1555 		}
1556 		break;
1557 	case 0x0300: /* Clip plane 1 & 2 enable */
1558 		{
1559 			int clipl = 0, clipr = 0;
1560 
1561 			if (sa_line_t->clip1_l[y] > sa_line_t->clip0_l[y])
1562 				clipl = sa_line_t->clip1_l[y];
1563 			else
1564 				clipl = sa_line_t->clip0_l[y];
1565 
1566 			if (sa_line_t->clip1_r[y] < sa_line_t->clip0_r[y])
1567 				clipr = sa_line_t->clip1_r[y];
1568 			else
1569 				clipr = sa_line_t->clip0_r[y];
1570 
1571 			if (clipl > clipr)
1572 				*line_enable = 0;
1573 			else
1574 				*clip0 = (clipl) | (clipr << 16);
1575 			*clip1 = 0;
1576 		}
1577 		break;
1578 	case 0x0310: /* Clip plane 1 & 2 enable, plane 1 inverted */
1579 		{
1580 			if (sa_line_t->clip1_l[y] > sa_line_t->clip1_r[y])
1581 				line_enable = nullptr;
1582 			else
1583 				*clip0 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
1584 
1585 			*clip1 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
1586 		}
1587 		break;
1588 	case 0x0320: /* Clip plane 1 & 2 enable, plane 2 inverted */
1589 		{
1590 			if (sa_line_t->clip0_l[y] > sa_line_t->clip0_r[y])
1591 				line_enable = nullptr;
1592 			else
1593 				*clip0 = (sa_line_t->clip0_l[y]) | (sa_line_t->clip0_r[y] << 16);
1594 
1595 			*clip1 = (sa_line_t->clip1_l[y]) | (sa_line_t->clip1_r[y] << 16);
1596 		}
1597 		break;
1598 	case 0x0330: /* Clip plane 1 & 2 enable, both inverted */
1599 		{
1600 			int clipl = 0, clipr = 0;
1601 
1602 			if (sa_line_t->clip1_l[y] < sa_line_t->clip0_l[y])
1603 				clipl = sa_line_t->clip1_l[y];
1604 			else
1605 				clipl = sa_line_t->clip0_l[y];
1606 
1607 			if (sa_line_t->clip1_r[y] > sa_line_t->clip0_r[y])
1608 				clipr = sa_line_t->clip1_r[y];
1609 			else
1610 				clipr = sa_line_t->clip0_r[y];
1611 
1612 			if (clipl > clipr)
1613 				*line_enable = 0;
1614 			else
1615 				*clip1 = (clipl) | (clipr << 16);
1616 			*clip0 = 0x7fff0000;
1617 		}
1618 		break;
1619 	default:
1620 		// popmessage("Illegal clip mode");
1621 		break;
1622 	}
1623 }
1624 
get_spritealphaclip_info()1625 void taito_f3_state::get_spritealphaclip_info()
1626 {
1627 	f3_spritealpha_line_inf *line_t = &m_sa_line_inf[0];
1628 
1629 	int y, y_end, y_inc;
1630 
1631 	int spri_base, clip_base_low, clip_base_high, inc;
1632 
1633 	u16 spri = 0;
1634 	u16 sprite_clip = 0;
1635 	u16 clip0_low = 0, clip0_high = 0, clip1_low = 0;
1636 	int alpha_level = 0;
1637 	u16 sprite_alpha = 0;
1638 
1639 	if (m_flipscreen)
1640 	{
1641 		spri_base = 0x77fe;
1642 		clip_base_low = 0x51fe;
1643 		clip_base_high = 0x45fe;
1644 		inc = -2;
1645 		y = 255;
1646 		y_end = -1;
1647 		y_inc = -1;
1648 
1649 	}
1650 	else
1651 	{
1652 		spri_base = 0x7600;
1653 		clip_base_low = 0x5000;
1654 		clip_base_high = 0x4400;
1655 		inc = 2;
1656 		y = 0;
1657 		y_end = 256;
1658 		y_inc = 1;
1659 	}
1660 
1661 	while (y != y_end)
1662 	{
1663 		/* The zoom, column and row values can latch according to control ram */
1664 		{
1665 			if (m_line_ram[0x100 + y] & 1)
1666 				clip0_low = (m_line_ram[clip_base_low / 2] >> 0) & 0xffff;
1667 			if (m_line_ram[0x000 + y] & 4)
1668 				clip0_high = (m_line_ram[clip_base_high / 2] >> 0) & 0xffff;
1669 			if (m_line_ram[0x100 + y] & 2)
1670 				clip1_low = (m_line_ram[(clip_base_low + 0x200) / 2] >> 0) & 0xffff;
1671 
1672 			if (m_line_ram[(0x0600 / 2) + y] & 0x8)
1673 				spri = m_line_ram[spri_base / 2] & 0xffff;
1674 			if (m_line_ram[(0x0600 / 2) + y] & 0x4)
1675 				sprite_clip = m_line_ram[(spri_base-0x200) / 2] & 0xffff;
1676 			if (m_line_ram[(0x0400 / 2) + y] & 0x1)
1677 				sprite_alpha = m_line_ram[(spri_base-0x1600) / 2] & 0xffff;
1678 			if (m_line_ram[(0x0400 / 2) + y] & 0x2)
1679 				alpha_level = m_line_ram[(spri_base-0x1400) / 2] & 0xffff;
1680 		}
1681 
1682 
1683 		line_t->alpha_level[y] = alpha_level;
1684 		line_t->spri[y] = spri;
1685 		line_t->sprite_alpha[y] = sprite_alpha;
1686 		line_t->clip0_l[y] = ((clip0_low & 0xff) | ((clip0_high & 0x1000) >> 4)) - 47;
1687 		line_t->clip0_r[y] = (((clip0_low & 0xff00) >> 8) | ((clip0_high & 0x2000) >> 5)) - 47;
1688 		line_t->clip1_l[y] = ((clip1_low & 0xff) | ((clip0_high & 0x4000) >> 6)) - 47;
1689 		line_t->clip1_r[y] = (((clip1_low & 0xff00) >> 8) | ((clip0_high & 0x8000) >> 7)) - 47;
1690 		if (line_t->clip0_l[y] < 0) line_t->clip0_l[y] = 0;
1691 		if (line_t->clip0_r[y] < 0) line_t->clip0_r[y] = 0;
1692 		if (line_t->clip1_l[y] < 0) line_t->clip1_l[y] = 0;
1693 		if (line_t->clip1_r[y] < 0) line_t->clip1_r[y] = 0;
1694 
1695 		/* Evaluate sprite clipping */
1696 		if (sprite_clip & 0x080)
1697 		{
1698 			line_t->sprite_clip0[y] = 0x7fff7fff;
1699 			line_t->sprite_clip1[y] = 0;
1700 		}
1701 		else if (sprite_clip & 0x33)
1702 		{
1703 			int line_enable = 1;
1704 			calculate_clip(y, ((sprite_clip & 0x33) << 4), &line_t->sprite_clip0[y], &line_t->sprite_clip1[y], &line_enable);
1705 			if (line_enable == 0)
1706 				line_t->sprite_clip0[y] = 0x7fff7fff;
1707 		}
1708 		else
1709 		{
1710 			line_t->sprite_clip0[y] = 0x7fff0000;
1711 			line_t->sprite_clip1[y] = 0;
1712 		}
1713 
1714 		spri_base += inc;
1715 		clip_base_low += inc;
1716 		clip_base_high += inc;
1717 		y += y_inc;
1718 	}
1719 }
1720 
1721 /* sx and sy are 16.16 fixed point numbers */
get_line_ram_info(tilemap_t * tmap,int sx,int sy,int pos,u16 * pf_data_n)1722 void taito_f3_state::get_line_ram_info(tilemap_t *tmap, int sx, int sy, int pos, u16 *pf_data_n)
1723 {
1724 	f3_playfield_line_inf *line_t = &m_pf_line_inf[pos];
1725 
1726 	int y_start, y_end, y_inc;
1727 	int line_base, zoom_base, col_base, pri_base, inc;
1728 
1729 	int line_enable;
1730 	int colscroll = 0, x_offset = 0, line_zoom = 0;
1731 	u32 _y_zoom[256];
1732 	u16 pri = 0;
1733 	int bit_select = 1 << pos;
1734 
1735 	int _colscroll[256];
1736 	u32 _x_offset[256];
1737 	int y_index_fx;
1738 
1739 	sx += ((46 << 16));
1740 
1741 	if (m_flipscreen)
1742 	{
1743 		line_base = 0xa1fe + (pos << 9);
1744 		zoom_base = 0x81fe;// + (pos << 9);
1745 		col_base = 0x41fe + (pos << 9);
1746 		pri_base = 0xb1fe + (pos << 9);
1747 		inc = -2;
1748 		y_start = 255;
1749 		y_end = -1;
1750 		y_inc = -1;
1751 
1752 		 /* Adjust for flipped scroll position */
1753 		if (m_game_config->extend)
1754 			sx = -sx + (((188 - 512) & 0xffff) << 16);
1755 		else
1756 			sx = -sx + (188 << 16);
1757 
1758 		y_index_fx = -sy - (256 << 16); /* Adjust for flipped scroll position */
1759 	}
1760 	else
1761 	{
1762 		line_base = 0xa000 + (pos << 9);
1763 		zoom_base = 0x8000;// + (pos << 9);
1764 		col_base = 0x4000 + (pos << 9);
1765 		pri_base = 0xb000 + (pos << 9);
1766 		inc = 2;
1767 		y_start = 0;
1768 		y_end = 256;
1769 		y_inc = 1;
1770 
1771 		y_index_fx = sy;
1772 	}
1773 
1774 	int y = y_start;
1775 
1776 	while (y != y_end)
1777 	{
1778 		/* The zoom, column and row values can latch according to control ram */
1779 		{
1780 			if (m_line_ram[0x600 + y] & bit_select)
1781 				x_offset = (m_line_ram[line_base / 2] & 0xffff) << 10;
1782 			if (m_line_ram[0x700 + y] & bit_select)
1783 				pri = m_line_ram[pri_base / 2] & 0xffff;
1784 
1785 			// Zoom for playfields 1 & 3 is interleaved, as is the latch select
1786 			switch (pos)
1787 			{
1788 			case 0:
1789 				if (m_line_ram[0x400 + y] & bit_select)
1790 					line_zoom = m_line_ram[(zoom_base + 0x000) / 2] & 0xffff;
1791 				break;
1792 			case 1:
1793 				if (m_line_ram[0x400 + y] & 0x2)
1794 					line_zoom = ((m_line_ram[(zoom_base + 0x200) / 2] & 0xffff) & 0xff00) | (line_zoom & 0x00ff);
1795 				if (m_line_ram[0x400 + y] & 0x8)
1796 					line_zoom = ((m_line_ram[(zoom_base + 0x600) / 2] & 0xffff) & 0x00ff) | (line_zoom & 0xff00);
1797 				break;
1798 			case 2:
1799 				if (m_line_ram[0x400 + y] & bit_select)
1800 					line_zoom = m_line_ram[(zoom_base + 0x400) / 2] & 0xffff;
1801 				break;
1802 			case 3:
1803 				if (m_line_ram[0x400 + y] & 0x8)
1804 					line_zoom = ((m_line_ram[(zoom_base + 0x600) / 2] & 0xffff) & 0xff00) | (line_zoom & 0x00ff);
1805 				if (m_line_ram[0x400 + y] & 0x2)
1806 					line_zoom = ((m_line_ram[(zoom_base + 0x200) / 2] & 0xffff) & 0x00ff) | (line_zoom & 0xff00);
1807 				break;
1808 			default:
1809 				break;
1810 			}
1811 
1812 			// Column scroll only affects playfields 2 & 3
1813 			if (pos >= 2 && m_line_ram[0x000 + y] & bit_select)
1814 				colscroll = (m_line_ram[col_base / 2] >> 0) & 0x3ff;
1815 		}
1816 
1817 		if (!pri || (!m_flipscreen && y < 24) || (m_flipscreen && y > 231) ||
1818 			(pri & 0xc000) == 0xc000 || !(pri & 0x2000)/**/)
1819 			line_enable = 0;
1820 		else if (pri & 0x4000) //alpha1
1821 			line_enable = 2;
1822 		else if (pri & 0x8000) //alpha2
1823 			line_enable = 3;
1824 		else
1825 			line_enable = 1;
1826 
1827 		_colscroll[y] = colscroll;
1828 		_x_offset[y] = (x_offset & 0xffff0000) - (x_offset & 0x0000ffff);
1829 		_y_zoom[y] = (line_zoom & 0xff) << 9;
1830 
1831 		/* Evaluate clipping */
1832 		if (pri & 0x0800)
1833 			line_enable = 0;
1834 		else if (pri & 0x0330)
1835 		{
1836 			//fast path todo - remove line enable
1837 			calculate_clip(y, pri & 0x0330, &line_t->clip0[y], &line_t->clip1[y], &line_enable);
1838 		}
1839 		else
1840 		{
1841 			/* No clipping */
1842 			line_t->clip0[y] = 0x7fff0000;
1843 			line_t->clip1[y] = 0;
1844 		}
1845 
1846 		line_t->x_zoom[y] = 0x10000 - (line_zoom & 0xff00);
1847 		line_t->alpha_mode[y] = line_enable;
1848 		line_t->pri[y] = pri;
1849 
1850 		zoom_base += inc;
1851 		line_base += inc;
1852 		col_base += inc;
1853 		pri_base += inc;
1854 		y += y_inc;
1855 	}
1856 
1857 	tilemap_t* tm = tmap;
1858 
1859 	y = y_start;
1860 	while (y != y_end)
1861 	{
1862 		u32 x_index_fx;
1863 		u32 y_index;
1864 
1865 		/* The football games use values in the range 0x200 - 0x3ff where the crowd should be drawn - !?
1866 
1867 		   This appears to cause it to reference outside of the normal tilemap RAM area into the unused
1868 		   area on the 32x32 tilemap configuration.. but exactly how isn't understood
1869 
1870 		    Until this is understood we're creating additional tilemaps for the otherwise unused area of
1871 		    RAM and forcing it to look up there.
1872 
1873 		    the crowd area still seems to 'lag' behind the pitch area however.. but these are the values
1874 		    in ram??
1875 		*/
1876 		const int cs = _colscroll[y];
1877 
1878 		if (cs & 0x200)
1879 		{
1880 			if (m_tilemap[4] && m_tilemap[5])
1881 			{
1882 				if (tmap == m_tilemap[2]) tmap = m_tilemap[4]; // pitch -> crowd
1883 				if (tmap == m_tilemap[3]) tmap = m_tilemap[5]; // corruption on goals -> blank (hthero94)
1884 			}
1885 		}
1886 		else
1887 		{
1888 			tmap = tm;
1889 		}
1890 
1891 		/* set pixmap pointer */
1892 		bitmap_ind16 &srcbitmap = tmap->pixmap();
1893 		bitmap_ind8 &flagsbitmap = tmap->flagsmap();
1894 
1895 		if (line_t->alpha_mode[y] != 0)
1896 		{
1897 			u16 *src_s;
1898 			u8 *tsrc_s;
1899 
1900 			x_index_fx = (sx+_x_offset[y]-(10*0x10000) + (10*line_t->x_zoom[y]))&((m_width_mask << 16)|0xffff);
1901 			y_index = ((y_index_fx >> 16)+_colscroll[y]) & 0x1ff;
1902 
1903 			/* check tile status */
1904 			visible_tile_check(line_t, y, x_index_fx, y_index, pf_data_n);
1905 
1906 			/* If clipping enabled for this line have to disable 'all opaque' optimisation */
1907 			if (line_t->clip0[y] != 0x7fff0000 || line_t->clip1[y] != 0)
1908 				line_t->alpha_mode[y] &= ~0x80;
1909 
1910 			/* set pixmap index */
1911 			line_t->x_count[y]=x_index_fx & 0xffff; // Fractional part
1912 			line_t->src_s[y] = src_s = &srcbitmap.pix(y_index);
1913 			line_t->src_e[y] = &src_s[m_width_mask + 1];
1914 			line_t->src[y] = &src_s[x_index_fx >> 16];
1915 
1916 			line_t->tsrc_s[y]=tsrc_s = &flagsbitmap.pix(y_index);
1917 			line_t->tsrc[y] = &tsrc_s[x_index_fx >> 16];
1918 		}
1919 
1920 		y_index_fx += _y_zoom[y];
1921 		y += y_inc;
1922 	}
1923 }
1924 
get_vram_info(tilemap_t * vram_tilemap,tilemap_t * pixel_tilemap,int sx,int sy)1925 void taito_f3_state::get_vram_info(tilemap_t *vram_tilemap, tilemap_t *pixel_tilemap, int sx, int sy)
1926 {
1927 	const f3_spritealpha_line_inf *sprite_alpha_line_t = &m_sa_line_inf[0];
1928 	f3_playfield_line_inf *line_t = &m_pf_line_inf[4];
1929 
1930 	int y_start, y_end, y_inc;
1931 	int pri_base, inc;
1932 
1933 	int line_enable;
1934 
1935 	u16 pri = 0;
1936 
1937 	const int vram_width_mask = 0x3ff;
1938 
1939 	if (m_flipscreen)
1940 	{
1941 		pri_base = 0x73fe;
1942 		inc = -2;
1943 		y_start = 255;
1944 		y_end = -1;
1945 		y_inc = -1;
1946 	}
1947 	else
1948 	{
1949 		pri_base = 0x7200;
1950 		inc = 2;
1951 		y_start = 0;
1952 		y_end = 256;
1953 		y_inc = 1;
1954 
1955 	}
1956 
1957 	int y = y_start;
1958 	while (y != y_end)
1959 	{
1960 		/* The zoom, column and row values can latch according to control ram */
1961 		{
1962 			if (m_line_ram[(0x0600 / 2) + y] & 0x2)
1963 				pri = (m_line_ram[pri_base / 2] & 0xffff);
1964 		}
1965 
1966 		if (!pri || (!m_flipscreen && y < 24) || (m_flipscreen && y > 231) ||
1967 			(pri & 0xc000) == 0xc000 || !(pri & 0x2000)/**/)
1968 			line_enable = 0;
1969 		else if (pri & 0x4000) //alpha1
1970 			line_enable = 2;
1971 		else if (pri & 0x8000) //alpha2
1972 			line_enable = 3;
1973 		else
1974 			line_enable = 1;
1975 
1976 		line_t->pri[y] = pri;
1977 
1978 		/* Evaluate clipping */
1979 		if (pri & 0x0800)
1980 			line_enable = 0;
1981 		else if (pri & 0x0330)
1982 		{
1983 			//fast path todo - remove line enable
1984 			calculate_clip(y, pri & 0x0330, &line_t->clip0[y], &line_t->clip1[y], &line_enable);
1985 		}
1986 		else
1987 		{
1988 			/* No clipping */
1989 			line_t->clip0[y] = 0x7fff0000;
1990 			line_t->clip1[y] = 0;
1991 		}
1992 
1993 		line_t->x_zoom[y] = 0x10000;
1994 		line_t->alpha_mode[y] = line_enable;
1995 		if (line_t->alpha_mode[y] > 1)
1996 			line_t->alpha_mode[y] |= 0x10;
1997 
1998 		pri_base += inc;
1999 		y += y_inc;
2000 	}
2001 
2002 	sx &= 0x1ff;
2003 
2004 	/* set pixmap pointer */
2005 	bitmap_ind16 &srcbitmap_pixel = pixel_tilemap->pixmap();
2006 	bitmap_ind8 &flagsbitmap_pixel = pixel_tilemap->flagsmap();
2007 	bitmap_ind16 &srcbitmap_vram = vram_tilemap->pixmap();
2008 	bitmap_ind8 &flagsbitmap_vram = vram_tilemap->flagsmap();
2009 
2010 	y = y_start;
2011 	while (y != y_end)
2012 	{
2013 		if (line_t->alpha_mode[y] != 0)
2014 		{
2015 			u16 *src_s;
2016 			u8 *tsrc_s;
2017 
2018 			// These bits in control ram indicate whether the line is taken from
2019 			// the VRAM tilemap layer or pixel layer.
2020 			const bool usePixelLayer = ((sprite_alpha_line_t->sprite_alpha[y] & 0xa000) == 0xa000);
2021 
2022 			/* set pixmap index */
2023 			line_t->x_count[y] = 0xffff;
2024 			if (usePixelLayer)
2025 				line_t->src_s[y] = src_s = &srcbitmap_pixel.pix(sy & 0xff);
2026 			else
2027 				line_t->src_s[y] = src_s = &srcbitmap_vram.pix(sy & 0x1ff);
2028 			line_t->src_e[y] = &src_s[vram_width_mask + 1];
2029 			line_t->src[y] = &src_s[sx];
2030 
2031 			if (usePixelLayer)
2032 				line_t->tsrc_s[y]=tsrc_s = &flagsbitmap_pixel.pix(sy & 0xff);
2033 			else
2034 				line_t->tsrc_s[y]=tsrc_s = &flagsbitmap_vram.pix(sy & 0x1ff);
2035 			line_t->tsrc[y] = &tsrc_s[sx];
2036 		}
2037 
2038 		sy++;
2039 		y += y_inc;
2040 	}
2041 }
2042 
2043 /******************************************************************************/
2044 
scanline_draw(bitmap_rgb32 & bitmap,const rectangle & cliprect)2045 void taito_f3_state::scanline_draw(bitmap_rgb32 &bitmap, const rectangle &cliprect)
2046 {
2047 	int i, ys, ye;
2048 	int y_start, y_end, y_start_next, y_end_next;
2049 	u8 draw_line[256];
2050 	s16 draw_line_num[256];
2051 
2052 	u32 rot = 0;
2053 
2054 	if (m_flipscreen)
2055 	{
2056 		rot = ORIENTATION_FLIP_Y;
2057 		ys = 0;
2058 		ye = 232;
2059 	}
2060 	else
2061 	{
2062 		ys = 24;
2063 		ye = 256;
2064 	}
2065 
2066 	y_start = ys;
2067 	y_end = ye;
2068 	std::fill(std::begin(draw_line), std::end(draw_line), 0);
2069 
2070 	while (1)
2071 	{
2072 		int pos;
2073 		int pri[5],alpha_mode[5],alpha_mode_flag[5];
2074 		u8 sprite_alpha_check;
2075 		u8 sprite_alpha_all_2a;
2076 		int layer_tmp[5];
2077 		f3_playfield_line_inf *pf_line_inf = m_pf_line_inf.get();
2078 		f3_spritealpha_line_inf *sa_line_inf = m_sa_line_inf.get();
2079 		int count_skip_layer = 0;
2080 		int sprite[6] = {0, 0, 0, 0, 0, 0};
2081 		const f3_playfield_line_inf *line_t[5];
2082 
2083 		/* find same status of scanlines */
2084 		pri[0] = pf_line_inf[0].pri[y_start];
2085 		pri[1] = pf_line_inf[1].pri[y_start];
2086 		pri[2] = pf_line_inf[2].pri[y_start];
2087 		pri[3] = pf_line_inf[3].pri[y_start];
2088 		pri[4] = pf_line_inf[4].pri[y_start];
2089 		alpha_mode[0] = pf_line_inf[0].alpha_mode[y_start];
2090 		alpha_mode[1] = pf_line_inf[1].alpha_mode[y_start];
2091 		alpha_mode[2] = pf_line_inf[2].alpha_mode[y_start];
2092 		alpha_mode[3] = pf_line_inf[3].alpha_mode[y_start];
2093 		alpha_mode[4] = pf_line_inf[4].alpha_mode[y_start];
2094 		const int alpha_level = sa_line_inf[0].alpha_level[y_start];
2095 		const int spri = sa_line_inf[0].spri[y_start];
2096 		const u16 sprite_alpha = sa_line_inf[0].sprite_alpha[y_start];
2097 
2098 		draw_line[y_start] = 1;
2099 		draw_line_num[i = 0] = y_start;
2100 		y_start_next = -1;
2101 		y_end_next = -1;
2102 		for (int y = y_start + 1; y < y_end; y++)
2103 		{
2104 			if (!draw_line[y])
2105 			{
2106 				if (pri[0] != pf_line_inf[0].pri[y]) y_end_next = y + 1;
2107 				else if (pri[1] != pf_line_inf[1].pri[y]) y_end_next = y + 1;
2108 				else if (pri[2] != pf_line_inf[2].pri[y]) y_end_next = y + 1;
2109 				else if (pri[3] != pf_line_inf[3].pri[y]) y_end_next = y + 1;
2110 				else if (pri[4] != pf_line_inf[4].pri[y]) y_end_next = y + 1;
2111 				else if (alpha_mode[0] != pf_line_inf[0].alpha_mode[y]) y_end_next = y + 1;
2112 				else if (alpha_mode[1] != pf_line_inf[1].alpha_mode[y]) y_end_next = y + 1;
2113 				else if (alpha_mode[2] != pf_line_inf[2].alpha_mode[y]) y_end_next = y + 1;
2114 				else if (alpha_mode[3] != pf_line_inf[3].alpha_mode[y]) y_end_next = y + 1;
2115 				else if (alpha_mode[4] != pf_line_inf[4].alpha_mode[y]) y_end_next = y + 1;
2116 				else if (alpha_level!=sa_line_inf[0].alpha_level[y]) y_end_next = y + 1;
2117 				else if (spri!=sa_line_inf[0].spri[y]) y_end_next = y + 1;
2118 				else if (sprite_alpha!=sa_line_inf[0].sprite_alpha[y]) y_end_next = y + 1;
2119 				else
2120 				{
2121 					draw_line[y] = 1;
2122 					draw_line_num[++i] = y;
2123 					continue;
2124 				}
2125 
2126 				if (y_start_next < 0) y_start_next = y;
2127 			}
2128 		}
2129 		y_end = y_end_next;
2130 		y_start = y_start_next;
2131 		draw_line_num[++i] = -1;
2132 
2133 		/* alpha blend */
2134 		alpha_mode_flag[0] = alpha_mode[0] & ~3;
2135 		alpha_mode_flag[1] = alpha_mode[1] & ~3;
2136 		alpha_mode_flag[2] = alpha_mode[2] & ~3;
2137 		alpha_mode_flag[3] = alpha_mode[3] & ~3;
2138 		alpha_mode_flag[4] = alpha_mode[4] & ~3;
2139 		alpha_mode[0] &= 3;
2140 		alpha_mode[1] &= 3;
2141 		alpha_mode[2] &= 3;
2142 		alpha_mode[3] &= 3;
2143 		alpha_mode[4] &= 3;
2144 		if (alpha_mode[0] > 1 ||
2145 			alpha_mode[1] > 1 ||
2146 			alpha_mode[2] > 1 ||
2147 			alpha_mode[3] > 1 ||
2148 			alpha_mode[4] > 1 ||
2149 			(sprite_alpha & 0xff) != 0xff)
2150 		{
2151 			/* set alpha level */
2152 			if (alpha_level != m_alpha_level_last)
2153 			{
2154 				int a = alpha_level;
2155 				const int b = (a >> 8) & 0xf;
2156 				const int c = (a >> 4) & 0xf;
2157 				const int d = (a >> 0) & 0xf;
2158 				a >>= 12;
2159 
2160 				/* b000 7000 */
2161 				int al_s = std::min(255, ((15 - d) * 256) / 8);
2162 				int al_d = std::min(255, ((15 - b) * 256) / 8);
2163 				m_alpha_level_3as = al_s;
2164 				m_alpha_level_3ad = al_d;
2165 				m_alpha_level_2as = al_d;
2166 				m_alpha_level_2ad = al_s;
2167 
2168 				al_s = std::min(255, ((15 - c) * 256) / 8);
2169 				al_d = std::min(255, ((15 - a) * 256) / 8);
2170 				m_alpha_level_3bs = al_s;
2171 				m_alpha_level_3bd = al_d;
2172 				m_alpha_level_2bs = al_d;
2173 				m_alpha_level_2bd = al_s;
2174 
2175 				alpha_set_level();
2176 				m_alpha_level_last = alpha_level;
2177 			}
2178 
2179 			/* set sprite alpha mode */
2180 			sprite_alpha_check = 0;
2181 			sprite_alpha_all_2a=1;
2182 			m_dpix_sp[1] = nullptr;
2183 			m_dpix_sp[2] = nullptr;
2184 			m_dpix_sp[4] = nullptr;
2185 			m_dpix_sp[8] = nullptr;
2186 			for (i = 0; i < 4; i++)    /* i = sprite priority offset */
2187 			{
2188 				const u8 sprite_alpha_mode = (sprite_alpha >> (i * 2)) & 3;
2189 				const u8 sftbit = 1 << i;
2190 				if (m_sprite_pri_usage & sftbit)
2191 				{
2192 					if (sprite_alpha_mode == 1)
2193 					{
2194 						if (m_alpha_level_2as == 0 && m_alpha_level_2ad == 255)
2195 							m_sprite_pri_usage &= ~sftbit;  // Disable sprite priority block
2196 						else
2197 						{
2198 							m_dpix_sp[sftbit] = m_dpix_n[2];
2199 							sprite_alpha_check |= sftbit;
2200 						}
2201 					}
2202 					else if (sprite_alpha_mode == 2)
2203 					{
2204 						if (sprite_alpha & 0xff00)
2205 						{
2206 							if (m_alpha_level_3as == 0 && m_alpha_level_3ad == 255) m_sprite_pri_usage &= ~sftbit;
2207 							else
2208 							{
2209 								m_dpix_sp[sftbit] = m_dpix_n[3];
2210 								sprite_alpha_check |= sftbit;
2211 								sprite_alpha_all_2a = 0;
2212 							}
2213 						}
2214 						else
2215 						{
2216 							if (m_alpha_level_3bs == 0 && m_alpha_level_3bd == 255) m_sprite_pri_usage &= ~sftbit;
2217 							else
2218 							{
2219 								m_dpix_sp[sftbit] = m_dpix_n[5];
2220 								sprite_alpha_check |= sftbit;
2221 								sprite_alpha_all_2a = 0;
2222 							}
2223 						}
2224 					}
2225 				}
2226 			}
2227 
2228 			/* check alpha level */
2229 			for (i = 0; i < 5; i++)    /* i = playfield num (pos) */
2230 			{
2231 				const int alpha_type = (alpha_mode_flag[i] >> 4) & 3;
2232 
2233 				if (alpha_mode[i] == 2)
2234 				{
2235 					if (alpha_type == 1)
2236 					{
2237 						/* if (m_alpha_level_2as == 0   && m_alpha_level_2ad == 255)
2238 						 *     alpha_mode[i]=3; alpha_mode_flag[i] |= 0x80; }
2239 						 * will display continue screen in gseeker (mt 00026) */
2240 						if      (m_alpha_level_2as == 0   && m_alpha_level_2ad == 255) alpha_mode[i] = 0;
2241 						else if (m_alpha_level_2as == 255 && m_alpha_level_2ad ==   0) alpha_mode[i] = 1;
2242 					}
2243 					else if (alpha_type == 2)
2244 					{
2245 						if      (m_alpha_level_2bs == 0   && m_alpha_level_2bd == 255) alpha_mode[i] = 0;
2246 						else if (m_alpha_level_2as == 255 && m_alpha_level_2ad ==   0 &&
2247 								 m_alpha_level_2bs == 255 && m_alpha_level_2bd ==   0) alpha_mode[i] = 1;
2248 					}
2249 					else if (alpha_type == 3)
2250 					{
2251 						if      (m_alpha_level_2as == 0   && m_alpha_level_2ad == 255 &&
2252 								 m_alpha_level_2bs == 0   && m_alpha_level_2bd == 255) alpha_mode[i] = 0;
2253 						else if (m_alpha_level_2as == 255 && m_alpha_level_2ad ==   0 &&
2254 								 m_alpha_level_2bs == 255 && m_alpha_level_2bd ==   0) alpha_mode[i] = 1;
2255 					}
2256 				}
2257 				else if (alpha_mode[i] == 3)
2258 				{
2259 					if (alpha_type == 1)
2260 					{
2261 						if      (m_alpha_level_3as == 0   && m_alpha_level_3ad == 255) alpha_mode[i] = 0;
2262 						else if (m_alpha_level_3as == 255 && m_alpha_level_3ad ==   0) alpha_mode[i] = 1;
2263 					}
2264 					else if (alpha_type == 2)
2265 					{
2266 						if      (m_alpha_level_3bs == 0   && m_alpha_level_3bd == 255) alpha_mode[i] = 0;
2267 						else if (m_alpha_level_3as == 255 && m_alpha_level_3ad ==   0 &&
2268 								 m_alpha_level_3bs == 255 && m_alpha_level_3bd ==   0) alpha_mode[i] = 1;
2269 					}
2270 					else if (alpha_type == 3)
2271 					{
2272 						if      (m_alpha_level_3as == 0   && m_alpha_level_3ad == 255 &&
2273 								 m_alpha_level_3bs == 0   && m_alpha_level_3bd == 255) alpha_mode[i] = 0;
2274 						else if (m_alpha_level_3as == 255 && m_alpha_level_3ad ==   0 &&
2275 								 m_alpha_level_3bs == 255 && m_alpha_level_3bd ==   0) alpha_mode[i] = 1;
2276 					}
2277 				}
2278 			}
2279 
2280 			if ((alpha_mode[0] == 1 || alpha_mode[0] == 2 || !alpha_mode[0]) &&
2281 				(alpha_mode[1] == 1 || alpha_mode[1] == 2 || !alpha_mode[1]) &&
2282 				(alpha_mode[2] == 1 || alpha_mode[2] == 2 || !alpha_mode[2]) &&
2283 				(alpha_mode[3] == 1 || alpha_mode[3] == 2 || !alpha_mode[3]) &&
2284 				(alpha_mode[4] == 1 || alpha_mode[4] == 2 || !alpha_mode[4]) &&
2285 				sprite_alpha_all_2a)
2286 			{
2287 				int alpha_type = (alpha_mode_flag[0] | alpha_mode_flag[1] | alpha_mode_flag[2] | alpha_mode_flag[3]) & 0x30;
2288 				if ((alpha_type == 0x10 && m_alpha_level_2as == 255) ||
2289 					(alpha_type == 0x20 && m_alpha_level_2as == 255 && m_alpha_level_2bs == 255) ||
2290 					(alpha_type == 0x30 && m_alpha_level_2as == 255 && m_alpha_level_2bs == 255))
2291 				{
2292 					if (alpha_mode[0] > 1) alpha_mode[0] = 1;
2293 					if (alpha_mode[1] > 1) alpha_mode[1] = 1;
2294 					if (alpha_mode[2] > 1) alpha_mode[2] = 1;
2295 					if (alpha_mode[3] > 1) alpha_mode[3] = 1;
2296 					if (alpha_mode[4] > 1) alpha_mode[4] = 1;
2297 					sprite_alpha_check = 0;
2298 					m_dpix_sp[1] = nullptr;
2299 					m_dpix_sp[2] = nullptr;
2300 					m_dpix_sp[4] = nullptr;
2301 					m_dpix_sp[8] = nullptr;
2302 				}
2303 			}
2304 		}
2305 		else
2306 		{
2307 			sprite_alpha_check = 0;
2308 			m_dpix_sp[1] = nullptr;
2309 			m_dpix_sp[2] = nullptr;
2310 			m_dpix_sp[4] = nullptr;
2311 			m_dpix_sp[8] = nullptr;
2312 		}
2313 
2314 		/* set scanline priority */
2315 		{
2316 			int pri_max_opa = -1;
2317 			for (i = 0; i < 5; i++)    /* i = playfield num (pos) */
2318 			{
2319 				const int p0 = pri[i];
2320 				const int pri_sl1 = p0 & 0x0f;
2321 
2322 				layer_tmp[i] = i + (pri_sl1 << 3);
2323 
2324 				if (!alpha_mode[i])
2325 				{
2326 					layer_tmp[i] |= 0x80;
2327 					count_skip_layer++;
2328 				}
2329 				else if (alpha_mode[i] == 1 && (alpha_mode_flag[i] & 0x80))
2330 				{
2331 					if (layer_tmp[i] > pri_max_opa) pri_max_opa = layer_tmp[i];
2332 				}
2333 			}
2334 
2335 			if (pri_max_opa != -1)
2336 			{
2337 				if (pri_max_opa > layer_tmp[0]) { layer_tmp[0] |= 0x80; count_skip_layer++; }
2338 				if (pri_max_opa > layer_tmp[1]) { layer_tmp[1] |= 0x80; count_skip_layer++; }
2339 				if (pri_max_opa > layer_tmp[2]) { layer_tmp[2] |= 0x80; count_skip_layer++; }
2340 				if (pri_max_opa > layer_tmp[3]) { layer_tmp[3] |= 0x80; count_skip_layer++; }
2341 				if (pri_max_opa > layer_tmp[4]) { layer_tmp[4] |= 0x80; count_skip_layer++; }
2342 			}
2343 		}
2344 
2345 		/* sort layer_tmp */
2346 		for (i = 0; i < 4; i++)
2347 		{
2348 			for (int j = i + 1; j < 5; j++)
2349 			{
2350 				if (layer_tmp[i] < layer_tmp[j])
2351 				{
2352 					const int temp = layer_tmp[i];
2353 					layer_tmp[i] = layer_tmp[j];
2354 					layer_tmp[j] = temp;
2355 				}
2356 			}
2357 		}
2358 
2359 		/* check sprite & layer priority */
2360 		{
2361 			int pri_sp[5];
2362 
2363 			const int l0 = layer_tmp[0] >> 3;
2364 			const int l1 = layer_tmp[1] >> 3;
2365 			const int l2 = layer_tmp[2] >> 3;
2366 			const int l3 = layer_tmp[3] >> 3;
2367 			const int l4 = layer_tmp[4] >> 3;
2368 
2369 			pri_sp[0] =  spri & 0xf;
2370 			pri_sp[1] = (spri >> 4) & 0xf;
2371 			pri_sp[2] = (spri >> 8) & 0xf;
2372 			pri_sp[3] =  spri >> 12;
2373 
2374 			for (i = 0; i < 4; i++)    /* i = sprite priority offset */
2375 			{
2376 				const int sflg = 1 << i;
2377 				if (!(m_sprite_pri_usage & sflg)) continue;
2378 				int sp = pri_sp[i];
2379 
2380 				/*
2381 				    sprite priority==playfield priority
2382 				        GSEEKER (plane leaving hangar) --> sprite
2383 				        BUBSYMPH (title)       ---> sprite
2384 				        DARIUSG (ZONE V' BOSS) ---> playfield
2385 				*/
2386 
2387 				if (m_game == BUBSYMPH) sp++;        //BUBSYMPH (title)
2388 				if (m_game == GSEEKER) sp++;     //GSEEKER (plane leaving hangar)
2389 
2390 				if      (            sp > l0) sprite[0] |= sflg;
2391 				else if (sp <= l0 && sp > l1) sprite[1] |= sflg;
2392 				else if (sp <= l1 && sp > l2) sprite[2] |= sflg;
2393 				else if (sp <= l2 && sp > l3) sprite[3] |= sflg;
2394 				else if (sp <= l3 && sp > l4) sprite[4] |= sflg;
2395 				else if (sp <= l4           ) sprite[5] |= sflg;
2396 			}
2397 		}
2398 
2399 
2400 		/* draw scanlines */
2401 		bool alpha = false;
2402 		for (i = count_skip_layer; i < 5; i++)
2403 		{
2404 			pos = layer_tmp[i] & 7;
2405 			line_t[i] = &pf_line_inf[pos];
2406 
2407 			if (sprite[i] & sprite_alpha_check) alpha = true;
2408 			else if (!alpha) sprite[i] |= 0x100;
2409 
2410 			if (alpha_mode[pos] > 1)
2411 			{
2412 				int alpha_type = (((alpha_mode_flag[pos] >> 4) & 3) - 1) * 2;
2413 				m_dpix_lp[i] = m_dpix_n[alpha_mode[pos]+alpha_type];
2414 				alpha = true;
2415 			}
2416 			else
2417 			{
2418 				if (alpha) m_dpix_lp[i] = m_dpix_n[1];
2419 				else       m_dpix_lp[i] = m_dpix_n[0];
2420 			}
2421 		}
2422 		if (sprite[5] & sprite_alpha_check) alpha = true;
2423 		else if (!alpha) sprite[5] |= 0x100;
2424 
2425 		draw_scanlines(bitmap, 320, draw_line_num, line_t, sprite, rot, count_skip_layer);
2426 		if (y_start < 0) break;
2427 	}
2428 }
2429 
2430 /******************************************************************************/
2431 
2432 #define PSET_T                  \
2433 	c = *source & m_sprite_pen_mask; \
2434 	if (c)                       \
2435 	{                           \
2436 		p = *pri;                 \
2437 		if (!p || p == 0xff)       \
2438 		{                       \
2439 			*dest = pal[c];     \
2440 			*pri = pri_dst;     \
2441 		}                       \
2442 	}
2443 
2444 #define PSET_O                  \
2445 	p = *pri;                     \
2446 	if (!p || p == 0xff)           \
2447 	{                           \
2448 		*dest = pal[*source & m_sprite_pen_mask];    \
2449 		*pri = pri_dst;         \
2450 	}
2451 
2452 #define NEXT_P                  \
2453 	source += dx;               \
2454 	dest++;                     \
2455 	pri++;
2456 
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)2457 inline void taito_f3_state::f3_drawgfx(bitmap_rgb32 &dest_bmp, const rectangle &clip,
2458 		gfx_element *gfx,
2459 		int code,
2460 		int color,
2461 		int flipx, int flipy,
2462 		int sx, int sy,
2463 		u8 pri_dst)
2464 {
2465 	rectangle myclip;
2466 
2467 	pri_dst = 1 << pri_dst;
2468 
2469 	/* KW 991012 -- Added code to force clip to bitmap boundary */
2470 	myclip = clip;
2471 	myclip &= dest_bmp.cliprect();
2472 
2473 	if (gfx)
2474 	{
2475 		const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
2476 		const u8 *code_base = gfx->get_data(code % gfx->elements());
2477 
2478 		{
2479 			/* compute sprite increment per screen pixel */
2480 			int dx = 1;
2481 			int dy = 1;
2482 
2483 			int ex = sx + 16;
2484 			int ey = sy + 16;
2485 
2486 			int x_index_base;
2487 			int y_index;
2488 
2489 			if (flipx)
2490 			{
2491 				x_index_base = 15;
2492 				dx = -1;
2493 			}
2494 			else
2495 			{
2496 				x_index_base = 0;
2497 			}
2498 
2499 			if (flipy)
2500 			{
2501 				y_index = 15;
2502 				dy = -1;
2503 			}
2504 			else
2505 			{
2506 				y_index = 0;
2507 			}
2508 
2509 			if (sx < myclip.min_x)
2510 			{ /* clip left */
2511 				int pixels = myclip.min_x - sx;
2512 				sx += pixels;
2513 				x_index_base += pixels * dx;
2514 			}
2515 			if (sy < myclip.min_y)
2516 			{ /* clip top */
2517 				int pixels = myclip.min_y - sy;
2518 				sy += pixels;
2519 				y_index += pixels * dy;
2520 			}
2521 			/* NS 980211 - fixed incorrect clipping */
2522 			if (ex > myclip.max_x + 1)
2523 			{ /* clip right */
2524 				int pixels = ex - myclip.max_x - 1;
2525 				ex -= pixels;
2526 			}
2527 			if (ey > myclip.max_y + 1)
2528 			{ /* clip bottom */
2529 				int pixels = ey - myclip.max_y - 1;
2530 				ey -= pixels;
2531 			}
2532 
2533 			if (ex > sx && ey > sy)
2534 			{ /* skip if inner loop doesn't draw anything */
2535 //              if (dest_bmp.bpp == 32)
2536 				{
2537 					int y = ey - sy;
2538 					const int x = (ex - sx - 1) | (m_tile_opaque_sp[code % gfx->elements()] << 4);
2539 					const u8 *source0 = code_base + y_index * 16 + x_index_base;
2540 					u32 *dest0 = &dest_bmp.pix(sy, sx);
2541 					u8 *pri0 = &m_pri_alp_bitmap.pix(sy, sx);
2542 					const int yadv = dest_bmp.rowpixels();
2543 					const int yadvp = m_pri_alp_bitmap.rowpixels();
2544 					dy = dy * 16;
2545 					while (1)
2546 					{
2547 						const u8 *source = source0;
2548 						u32 *dest = dest0;
2549 						u8 *pri = pri0;
2550 
2551 						switch (x)
2552 						{
2553 							int c;
2554 							u8 p;
2555 							case 31: PSET_O NEXT_P
2556 							case 30: PSET_O NEXT_P
2557 							case 29: PSET_O NEXT_P
2558 							case 28: PSET_O NEXT_P
2559 							case 27: PSET_O NEXT_P
2560 							case 26: PSET_O NEXT_P
2561 							case 25: PSET_O NEXT_P
2562 							case 24: PSET_O NEXT_P
2563 							case 23: PSET_O NEXT_P
2564 							case 22: PSET_O NEXT_P
2565 							case 21: PSET_O NEXT_P
2566 							case 20: PSET_O NEXT_P
2567 							case 19: PSET_O NEXT_P
2568 							case 18: PSET_O NEXT_P
2569 							case 17: PSET_O NEXT_P
2570 							case 16: PSET_O break;
2571 
2572 							case 15: PSET_T NEXT_P
2573 							case 14: PSET_T NEXT_P
2574 							case 13: PSET_T NEXT_P
2575 							case 12: PSET_T NEXT_P
2576 							case 11: PSET_T NEXT_P
2577 							case 10: PSET_T NEXT_P
2578 							case  9: PSET_T NEXT_P
2579 							case  8: PSET_T NEXT_P
2580 							case  7: PSET_T NEXT_P
2581 							case  6: PSET_T NEXT_P
2582 							case  5: PSET_T NEXT_P
2583 							case  4: PSET_T NEXT_P
2584 							case  3: PSET_T NEXT_P
2585 							case  2: PSET_T NEXT_P
2586 							case  1: PSET_T NEXT_P
2587 							case  0: PSET_T
2588 						}
2589 
2590 						if (!(--y)) break;
2591 						source0 += dy;
2592 						dest0 += yadv;
2593 						pri0 += yadvp;
2594 					}
2595 				}
2596 			}
2597 		}
2598 	}
2599 }
2600 #undef PSET_T
2601 #undef PSET_O
2602 #undef NEXT_P
2603 
2604 
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)2605 inline void taito_f3_state::f3_drawgfxzoom(bitmap_rgb32 &dest_bmp, const rectangle &clip,
2606 		gfx_element *gfx,
2607 		int code,
2608 		int color,
2609 		int flipx, int flipy,
2610 		int sx, int sy,
2611 		int scalex, int scaley,
2612 		u8 pri_dst)
2613 {
2614 	rectangle myclip;
2615 
2616 	pri_dst = 1 << pri_dst;
2617 
2618 	/* KW 991012 -- Added code to force clip to bitmap boundary */
2619 	myclip = clip;
2620 	myclip &= dest_bmp.cliprect();
2621 
2622 	if (gfx)
2623 	{
2624 		const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
2625 		const u8 *code_base = gfx->get_data(code % gfx->elements());
2626 
2627 		{
2628 			/* compute sprite increment per screen pixel */
2629 			int dx = (16 << 16) / scalex;
2630 			int dy = (16 << 16) / scaley;
2631 
2632 			int ex = sx + scalex;
2633 			int ey = sy + scaley;
2634 
2635 			int x_index_base;
2636 			int y_index;
2637 
2638 			if (flipx)
2639 			{
2640 				x_index_base = (scalex - 1) * dx;
2641 				dx = -dx;
2642 			}
2643 			else
2644 			{
2645 				x_index_base = 0;
2646 			}
2647 
2648 			if (flipy)
2649 			{
2650 				y_index = (scaley - 1) * dy;
2651 				dy = -dy;
2652 			}
2653 			else
2654 			{
2655 				y_index = 0;
2656 			}
2657 
2658 			if (sx < myclip.min_x)
2659 			{ /* clip left */
2660 				int pixels = myclip.min_x - sx;
2661 				sx += pixels;
2662 				x_index_base += pixels * dx;
2663 			}
2664 			if (sy < myclip.min_y)
2665 			{ /* clip top */
2666 				int pixels = myclip.min_y - sy;
2667 				sy += pixels;
2668 				y_index += pixels * dy;
2669 			}
2670 			/* NS 980211 - fixed incorrect clipping */
2671 			if (ex > myclip.max_x + 1)
2672 			{ /* clip right */
2673 				int pixels = ex - myclip.max_x - 1;
2674 				ex -= pixels;
2675 			}
2676 			if (ey > myclip.max_y + 1)
2677 			{ /* clip bottom */
2678 				int pixels = ey - myclip.max_y - 1;
2679 				ey -= pixels;
2680 			}
2681 
2682 			if (ex > sx)
2683 			{ /* skip if inner loop doesn't draw anything */
2684 //              if (dest_bmp.bpp == 32)
2685 				{
2686 					for (int y = sy; y < ey; y++)
2687 					{
2688 						const u8 *source = code_base + (y_index >> 16) * 16;
2689 						u32 *dest = &dest_bmp.pix(y);
2690 						u8 *pri = &m_pri_alp_bitmap.pix(y);
2691 
2692 						int x_index = x_index_base;
2693 						for (int x = sx; x < ex; x++)
2694 						{
2695 							int c = source[x_index >> 16] & m_sprite_pen_mask;
2696 							if (c)
2697 							{
2698 								const u8 p = pri[x];
2699 								if (p == 0 || p == 0xff)
2700 								{
2701 									dest[x] = pal[c];
2702 									pri[x] = pri_dst;
2703 								}
2704 							}
2705 							x_index += dx;
2706 						}
2707 						y_index += dy;
2708 					}
2709 				}
2710 			}
2711 		}
2712 	}
2713 }
2714 
2715 
2716 #define CALC_ZOOM(p)    {                                       \
2717 	p##_addition = 0x100 - block_zoom_##p + p##_addition_left;  \
2718 	p##_addition_left = p##_addition & 0xf;                     \
2719 	p##_addition = p##_addition >> 4;                           \
2720 	/*zoom##p = p##_addition << 12; */                           \
2721 }
2722 
get_sprite_info(const u16 * spriteram16_ptr)2723 void taito_f3_state::get_sprite_info(const u16 *spriteram16_ptr)
2724 {
2725 	const rectangle &visarea = m_screen->visible_area();
2726 	const int min_x = visarea.min_x, max_x = visarea.max_x;
2727 	const int min_y = visarea.min_y, max_y = visarea.max_y;
2728 	int global_x = 0,global_y = 0, subglobal_x = 0, subglobal_y = 0;
2729 	int block_x = 0, block_y = 0;
2730 	int last_color = 0, last_x = 0, last_y = 0,block_zoom_x = 0,block_zoom_y = 0;
2731 	int this_x, this_y;
2732 	int y_addition = 16, x_addition = 16;
2733 	int multi = 0;
2734 
2735 	int x_addition_left = 8, y_addition_left = 8;
2736 
2737 	tempsprite *sprite_ptr = &m_spritelist[0];
2738 
2739 	int total_sprites = 0;
2740 
2741 	int color = 0;
2742 	int flipx = 0, flipy = 0;
2743 	//int old_x = 0;
2744 	int y = 0, x = 0;
2745 
2746 	int sprite_top = 0x2000;
2747 	for (int offs = 0; offs < sprite_top && (total_sprites < 0x400); offs += 8)
2748 	{
2749 		const int current_offs = offs; /* Offs can change during loop, current_offs cannot */
2750 
2751 		/* Check if the sprite list jump command bit is set */
2752 		if ((spriteram16_ptr[current_offs + 6 + 0]) & 0x8000)
2753 		{
2754 			const u32 jump = (spriteram16_ptr[current_offs + 6 + 0]) & 0x3ff;
2755 
2756 			const u32 new_offs = ((offs & 0x4000) | ((jump << 4) / 2));
2757 			if (new_offs == offs)
2758 				break;
2759 			offs = new_offs - 8;
2760 		}
2761 
2762 		/* Check if special command bit is set */
2763 		if (spriteram16_ptr[current_offs + 2 + 1] & 0x8000)
2764 		{
2765 			const u32 cntrl = (spriteram16_ptr[current_offs + 4 + 1]) & 0xffff;
2766 			m_flipscreen = cntrl & 0x2000;
2767 
2768 			/*  cntrl & 0x1000 = disabled?  (From F2 driver, doesn't seem used anywhere)
2769 			    cntrl & 0x0010 = ???
2770 			    cntrl & 0x0020 = ???
2771 			    cntrl & 0x0002 = enabled when Darius Gaiden sprite trail effect should occur (MT #1922)
2772 			                     Notice that sprites also completely disappear due of a bug/missing feature in the
2773 			             alpha routines.
2774 			*/
2775 
2776 			m_sprite_extra_planes = (cntrl & 0x0300) >> 8;   // 0 = 4bpp, 1 = 5bpp, 2 = unused?, 3 = 6bpp
2777 			m_sprite_pen_mask = (m_sprite_extra_planes << 4) | 0x0f;
2778 
2779 			/* Sprite bank select */
2780 			if (cntrl & 1)
2781 			{
2782 				offs = offs | 0x4000;
2783 				sprite_top = sprite_top | 0x4000;
2784 			}
2785 		}
2786 
2787 		/* Set global sprite scroll */
2788 		if (((spriteram16_ptr[current_offs + 2 + 0]) & 0xf000) == 0xa000)
2789 		{
2790 			global_x = (spriteram16_ptr[current_offs + 2 + 0]) & 0xfff;
2791 			if (global_x >= 0x800) global_x -= 0x1000;
2792 			global_y = spriteram16_ptr[current_offs + 2 + 1] & 0xfff;
2793 			if (global_y >= 0x800) global_y -= 0x1000;
2794 		}
2795 
2796 		/* And sub-global sprite scroll */
2797 		if (((spriteram16_ptr[current_offs + 2 + 0]) & 0xf000) == 0x5000)
2798 		{
2799 			subglobal_x = (spriteram16_ptr[current_offs + 2 + 0]) & 0xfff;
2800 			if (subglobal_x >= 0x800) subglobal_x -= 0x1000;
2801 			subglobal_y = spriteram16_ptr[current_offs + 2 + 1] & 0xfff;
2802 			if (subglobal_y >= 0x800) subglobal_y -= 0x1000;
2803 		}
2804 
2805 		if (((spriteram16_ptr[current_offs + 2 + 0]) & 0xf000) == 0xb000)
2806 		{
2807 			subglobal_x = (spriteram16_ptr[current_offs + 2 + 0]) & 0xfff;
2808 			if (subglobal_x >= 0x800) subglobal_x -= 0x1000;
2809 			subglobal_y = spriteram16_ptr[current_offs + 2 + 1] & 0xfff;
2810 			if (subglobal_y >= 0x800) subglobal_y -= 0x1000;
2811 			global_y = subglobal_y;
2812 			global_x = subglobal_x;
2813 		}
2814 
2815 		/* A real sprite to process! */
2816 		const int sprite = (spriteram16_ptr[current_offs + 0 + 0]) | ((spriteram16_ptr[current_offs + 4 + 1] & 1) << 16);
2817 		const int spritecont = spriteram16_ptr[current_offs + 4 + 0] >> 8;
2818 
2819 /* These games either don't set the XY control bits properly (68020 bug?), or
2820     have some different mode from the others */
2821 #ifdef DARIUSG_KLUDGE
2822 		if (m_game == DARIUSG || m_game == GEKIRIDO || m_game == CLEOPATR || m_game == RECALH)
2823 			multi = spritecont & 0xf0;
2824 #endif
2825 
2826 		/* Check if this sprite is part of a continued block */
2827 		if (multi)
2828 		{
2829 			/* Bit 0x4 is 'use previous colour' for this block part */
2830 			if (spritecont & 0x4) color=last_color;
2831 			else color = (spriteram16_ptr[current_offs + 4 + 0]) & 0xff;
2832 
2833 #ifdef DARIUSG_KLUDGE
2834 			if (m_game == DARIUSG || m_game == GEKIRIDO || m_game == CLEOPATR || m_game == RECALH)
2835 			{
2836 				/* Adjust X Position */
2837 				if ((spritecont & 0x40) == 0)
2838 				{
2839 					if (spritecont & 0x4)
2840 						x = block_x;
2841 					else
2842 					{
2843 						this_x = spriteram16_ptr[current_offs + 2 + 0];
2844 						if (this_x & 0x800) this_x = 0 - (0x800 - (this_x & 0x7ff)); else this_x &= 0x7ff;
2845 
2846 						if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x8000)
2847 							this_x += 0;
2848 						else if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x4000) /* Ignore subglobal (but apply global) */
2849 							this_x += global_x;
2850 						else /* Apply both scroll offsets */
2851 							this_x += global_x + subglobal_x;
2852 
2853 						x = block_x = this_x;
2854 					}
2855 					x_addition_left = 8;
2856 					CALC_ZOOM(x)
2857 				}
2858 				else if ((spritecont & 0x80) != 0)
2859 				{
2860 					x = last_x + x_addition;
2861 					CALC_ZOOM(x)
2862 				}
2863 
2864 				/* Adjust Y Position */
2865 				if ((spritecont & 0x10) == 0)
2866 				{
2867 					if (spritecont & 0x4)
2868 						y = block_y;
2869 					else
2870 					{
2871 						this_y = spriteram16_ptr[current_offs + 2 + 1] & 0xffff;
2872 						if (this_y & 0x800) this_y = 0 - (0x800 - (this_y & 0x7ff)); else this_y &= 0x7ff;
2873 
2874 						if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x8000)
2875 							this_y += 0;
2876 						else if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x4000) /* Ignore subglobal (but apply global) */
2877 							this_y += global_y;
2878 						else /* Apply both scroll offsets */
2879 							this_y += global_y + subglobal_y;
2880 
2881 						y = block_y = this_y;
2882 					}
2883 					y_addition_left = 8;
2884 					CALC_ZOOM(y)
2885 				}
2886 				else if ((spritecont & 0x20) != 0)
2887 				{
2888 					y = last_y + y_addition;
2889 					CALC_ZOOM(y)
2890 				}
2891 			}
2892 			else
2893 #endif
2894 			{
2895 				/* Adjust X Position */
2896 				if ((spritecont & 0x40) == 0)
2897 				{
2898 					x = block_x;
2899 					x_addition_left = 8;
2900 					CALC_ZOOM(x)
2901 				}
2902 				else if ((spritecont & 0x80) != 0)
2903 				{
2904 					x = last_x + x_addition;
2905 					CALC_ZOOM(x)
2906 				}
2907 				/* Adjust Y Position */
2908 				if ((spritecont & 0x10) == 0)
2909 				{
2910 					y = block_y;
2911 					y_addition_left = 8;
2912 					CALC_ZOOM(y)
2913 				}
2914 				else if ((spritecont & 0x20) != 0)
2915 				{
2916 					y = last_y + y_addition;
2917 					CALC_ZOOM(y)
2918 				}
2919 				/* Both zero = reread block latch? */
2920 			}
2921 		}
2922 		/* Else this sprite is the possible start of a block */
2923 		else
2924 		{
2925 			color = (spriteram16_ptr[current_offs + 4 + 0]) & 0xff;
2926 			last_color = color;
2927 
2928 			/* Sprite positioning */
2929 			this_y = spriteram16_ptr[current_offs + 2 + 1] & 0xffff;
2930 			this_x = spriteram16_ptr[current_offs + 2 + 0] & 0xffff;
2931 			if (this_y & 0x800) this_y = 0 - (0x800 - (this_y & 0x7ff)); else this_y &= 0x7ff;
2932 			if (this_x & 0x800) this_x = 0 - (0x800 - (this_x & 0x7ff)); else this_x &= 0x7ff;
2933 
2934 			/* Ignore both scroll offsets for this block */
2935 			if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x8000)
2936 			{
2937 				this_x += 0;
2938 				this_y += 0;
2939 			}
2940 			else if ((spriteram16_ptr[current_offs + 2 + 0]) & 0x4000) /* Ignore subglobal (but apply global) */
2941 			{
2942 				this_x += global_x;
2943 				this_y += global_y;
2944 			}
2945 			else /* Apply both scroll offsets */
2946 			{
2947 				this_x += global_x + subglobal_x;
2948 				this_y += global_y + subglobal_y;
2949 			}
2950 
2951 			block_y = y = this_y;
2952 			block_x = x = this_x;
2953 
2954 			block_zoom_x = spriteram16_ptr[current_offs + 0 + 1];
2955 			block_zoom_y = (block_zoom_x >> 8) & 0xff;
2956 			block_zoom_x &= 0xff;
2957 
2958 			x_addition_left = 8;
2959 			CALC_ZOOM(x)
2960 
2961 			y_addition_left = 8;
2962 			CALC_ZOOM(y)
2963 		}
2964 
2965 		/* These features are common to sprite and block parts */
2966 		flipx = spritecont & 0x1;
2967 		flipy = spritecont & 0x2;
2968 		multi = spritecont & 0x8;
2969 		last_x=x;
2970 		last_y = y;
2971 
2972 		if (!sprite) continue;
2973 		if (!x_addition || !y_addition) continue;
2974 
2975 		if (m_flipscreen)
2976 		{
2977 			const int tx = 512 - x_addition - x;
2978 			const int ty = 256 - y_addition - y;
2979 
2980 			if (tx + x_addition <= min_x || tx > max_x || ty + y_addition <= min_y || ty > max_y) continue;
2981 			sprite_ptr->x = tx;
2982 			sprite_ptr->y = ty;
2983 			sprite_ptr->flipx = !flipx;
2984 			sprite_ptr->flipy = !flipy;
2985 		}
2986 		else
2987 		{
2988 			if (x + x_addition <= min_x || x > max_x || y + y_addition <= min_y || y > max_y) continue;
2989 			sprite_ptr->x = x;
2990 			sprite_ptr->y = y;
2991 			sprite_ptr->flipx = flipx;
2992 			sprite_ptr->flipy = flipy;
2993 		}
2994 
2995 		sprite_ptr->code = sprite;
2996 		sprite_ptr->color = color;
2997 		sprite_ptr->zoomx = x_addition;
2998 		sprite_ptr->zoomy = y_addition;
2999 		sprite_ptr->pri = (color & 0xc0) >> 6;
3000 		sprite_ptr++;
3001 		total_sprites++;
3002 	}
3003 	m_sprite_end = sprite_ptr;
3004 }
3005 #undef CALC_ZOOM
3006 
3007 
draw_sprites(bitmap_rgb32 & bitmap,const rectangle & cliprect)3008 void taito_f3_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
3009 {
3010 	const tempsprite *sprite_ptr;
3011 	gfx_element *sprite_gfx = m_gfxdecode->gfx(2);
3012 
3013 	sprite_ptr = m_sprite_end;
3014 	m_sprite_pri_usage = 0;
3015 
3016 	// if sprites use more than 4bpp, the bottom bits of the color code must be masked out.
3017 	// This fixes (at least) stage 1 battle ships and attract mode explosions in Ray Force.
3018 
3019 	while (sprite_ptr != &m_spritelist[0])
3020 	{
3021 		sprite_ptr--;
3022 
3023 		const int pri = sprite_ptr->pri;
3024 		m_sprite_pri_usage |= 1 << pri;
3025 
3026 		if (sprite_ptr->zoomx == 16 && sprite_ptr->zoomy == 16)
3027 			f3_drawgfx(
3028 					bitmap, cliprect, sprite_gfx,
3029 					sprite_ptr->code,
3030 					sprite_ptr->color & (~m_sprite_extra_planes),
3031 					sprite_ptr->flipx, sprite_ptr->flipy,
3032 					sprite_ptr->x, sprite_ptr->y,
3033 					pri);
3034 		else
3035 			f3_drawgfxzoom(
3036 					bitmap, cliprect, sprite_gfx,
3037 					sprite_ptr->code,
3038 					sprite_ptr->color & (~m_sprite_extra_planes),
3039 					sprite_ptr->flipx, sprite_ptr->flipy,
3040 					sprite_ptr->x, sprite_ptr->y,
3041 					sprite_ptr->zoomx, sprite_ptr->zoomy,
3042 					pri);
3043 	}
3044 }
3045 
3046 /******************************************************************************/
3047 
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)3048 u32 taito_f3_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
3049 {
3050 	u32 sy_fix[5], sx_fix[5];
3051 
3052 	machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
3053 
3054 	/* Setup scroll */
3055 	sy_fix[0] = ((m_control_0[4] & 0xffff) <<  9) + (1 << 16);
3056 	sy_fix[1] = ((m_control_0[5] & 0xffff) <<  9) + (1 << 16);
3057 	sy_fix[2] = ((m_control_0[6] & 0xffff) <<  9) + (1 << 16);
3058 	sy_fix[3] = ((m_control_0[7] & 0xffff) <<  9) + (1 << 16);
3059 	sx_fix[0] = ((m_control_0[0] & 0xffc0) << 10) - (6 << 16);
3060 	sx_fix[1] = ((m_control_0[1] & 0xffc0) << 10) - (10 << 16);
3061 	sx_fix[2] = ((m_control_0[2] & 0xffc0) << 10) - (14 << 16);
3062 	sx_fix[3] = ((m_control_0[3] & 0xffc0) << 10) - (18 << 16);
3063 	sx_fix[4] = -(m_control_1[4]) + 41;
3064 	sy_fix[4] = -(m_control_1[5] & 0x1ff);
3065 
3066 	sx_fix[0]-=((m_control_0[0] & 0x003f) << 10) + 0x0400 - 0x10000;
3067 	sx_fix[1]-=((m_control_0[1] & 0x003f) << 10) + 0x0400 - 0x10000;
3068 	sx_fix[2]-=((m_control_0[2] & 0x003f) << 10) + 0x0400 - 0x10000;
3069 	sx_fix[3]-=((m_control_0[3] & 0x003f) << 10) + 0x0400 - 0x10000;
3070 
3071 	if (m_flipscreen)
3072 	{
3073 		sy_fix[0] =  0x3000000 - sy_fix[0];
3074 		sy_fix[1] =  0x3000000 - sy_fix[1];
3075 		sy_fix[2] =  0x3000000 - sy_fix[2];
3076 		sy_fix[3] =  0x3000000 - sy_fix[3];
3077 		sx_fix[0] = -0x1a00000 - sx_fix[0];
3078 		sx_fix[1] = -0x1a00000 - sx_fix[1];
3079 		sx_fix[2] = -0x1a00000 - sx_fix[2];
3080 		sx_fix[3] = -0x1a00000 - sx_fix[3];
3081 		sx_fix[4] = -sx_fix[4] + 75;
3082 		sy_fix[4] = -sy_fix[4];
3083 	}
3084 
3085 	m_pri_alp_bitmap.fill(0, cliprect);
3086 
3087 	/* sprites */
3088 	if (m_sprite_lag == 0)
3089 		get_sprite_info(m_spriteram.target());
3090 
3091 	/* Update sprite buffer */
3092 	draw_sprites(bitmap, cliprect);
3093 
3094 	/* Parse sprite, alpha & clipping parts of lineram */
3095 	get_spritealphaclip_info();
3096 
3097 	/* Parse playfield effects */
3098 	get_line_ram_info(m_tilemap[0], sx_fix[0], sy_fix[0], 0, m_pf_data[0]);
3099 	get_line_ram_info(m_tilemap[1], sx_fix[1], sy_fix[1], 1, m_pf_data[1]);
3100 	get_line_ram_info(m_tilemap[2], sx_fix[2], sy_fix[2], 2, m_pf_data[2]);
3101 	get_line_ram_info(m_tilemap[3], sx_fix[3], sy_fix[3], 3, m_pf_data[3]);
3102 	get_vram_info(m_vram_layer, m_pixel_layer, sx_fix[4], sy_fix[4]);
3103 
3104 	/* Draw final framebuffer */
3105 	scanline_draw(bitmap, cliprect);
3106 
3107 	if (VERBOSE)
3108 		print_debug_info(bitmap);
3109 	return 0;
3110 }
3111