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