summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/dassault.c
blob: c552fc58a229ba80757432583f08b5ae49993e9d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/***************************************************************************

   Desert Assault Video emulation - Bryan McPhail, mish@tendril.co.uk

  I'm not sure if one of the alpha blending effects is correct (mode 0x8000,
  the usual mode 0x4000 should be correct).  It may be some kind of orthogonal
  priority effect where it should cut a hole in other higher priority sprites
  to reveal a non-alpha'd hole, or alpha against a further back tilemap.
  (is this the helicopter shadow at the end of lv.1 ?)

  Also, some priorities are still a little questionable.


****************************************************************************/

#include "emu.h"
#include "video/deco16ic.h"
#include "includes/dassault.h"
#include "video/decocomn.h"
#include "video/decospr.h"

/******************************************************************************/

VIDEO_START(dassault)
{
	machine.device<decospr_device>("spritegen1")->alloc_sprite_bitmap();
	machine.device<decospr_device>("spritegen2")->alloc_sprite_bitmap();
}

static void mixdassaultlayer(running_machine &machine, bitmap_rgb32 &bitmap, bitmap_ind16* sprite_bitmap, const rectangle &cliprect, UINT16 pri, UINT16 primask, UINT16 penbase, UINT8 alpha)
{
	int y, x;
	const pen_t *paldata = machine.pens;

	UINT16* srcline;
	UINT32* dstline;

	for (y=cliprect.min_y;y<=cliprect.max_y;y++)
	{
		srcline=&sprite_bitmap->pix16(y,0);
		dstline=&bitmap.pix32(y,0);

		for (x=cliprect.min_x;x<=cliprect.max_x;x++)
		{
			UINT16 pix = srcline[x];

			if ((pix & primask) != pri)
				continue;

			if (pix&0xf)
			{
				UINT16 pen = pix&0x1ff;
				if (pix & 0x800) pen += 0x200;

				if (alpha!=0xff)
				{
					if (pix&0x600)
					{
						UINT32 base = dstline[x];
						dstline[x] = alpha_blend_r32(base, paldata[pen+penbase], alpha);
					}
					else
					{
						dstline[x] = paldata[pen+penbase];
					}
				}
				else
				{
					dstline[x] = paldata[pen+penbase];
				}
			}
		}
	}
}

/* are the priorities 100% correct? they're the same as they were before conversion to DECO52 sprite device, but if (for example) you walk to the side of the crates in the first part of the game you appear over them... */
SCREEN_UPDATE_RGB32( dassault )
{
	dassault_state *state = screen.machine().driver_data<dassault_state>();
	UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff);
	UINT16 priority = decocomn_priority_r(state->m_decocomn, 0, 0xffff);

	screen.machine().device<decospr_device>("spritegen2")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 0x400, false);
	screen.machine().device<decospr_device>("spritegen1")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0x400, false);
	bitmap_ind16* sprite_bitmap1 = &screen.machine().device<decospr_device>("spritegen1")->get_sprite_temp_bitmap();
	bitmap_ind16* sprite_bitmap2 = &screen.machine().device<decospr_device>("spritegen2")->get_sprite_temp_bitmap();

	/* Update tilemaps */
	flip_screen_set(screen.machine(), BIT(flip, 7));
	deco16ic_pf_update(state->m_deco_tilegen1, 0, state->m_pf2_rowscroll);
	deco16ic_pf_update(state->m_deco_tilegen2, 0, state->m_pf4_rowscroll);

	/* Draw playfields/update priority bitmap */
	screen.machine().priority_bitmap.fill(0, cliprect);
	bitmap.fill(screen.machine().pens[3072], cliprect);
	deco16ic_tilemap_2_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);

	/* The middle playfields can be swapped priority-wise */
	if ((priority & 3) == 0)
	{
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0600, 0x0600,  0x400, 0xff); // 1
		deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 2); // 2
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0400, 0x0600,  0x400, 0xff); // 8
		deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 16); // 16
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0200, 0x0600,  0x400, 0xff); // 32
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap2, cliprect,  0x0000, 0x0000,  0x800, 0x80); // 64?
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0000, 0x0600,  0x400, 0xff); // 128

	}
	else if ((priority & 3) == 1)
	{
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0600, 0x0600,  0x400, 0xff); // 1
		deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 2); // 2
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0400, 0x0600,  0x400, 0xff); // 8
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap2, cliprect,  0x0000, 0x0000,  0x800, 0x80); // 16?
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0200, 0x0600,  0x400, 0xff); // 32
		deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 64); // 64
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0000, 0x0600,  0x400, 0xff); // 128
	}
	else if ((priority & 3) == 3)
	{
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0600, 0x0600,  0x400, 0xff); // 1
		deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 2); // 2
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0400, 0x0600,  0x400, 0xff); // 8
		deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 16); // 16
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0200, 0x0600,  0x400, 0xff); // 32
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap2, cliprect,  0x0000, 0x0000,  0x800, 0x80); // 64?
		mixdassaultlayer(screen.machine(), bitmap, sprite_bitmap1, cliprect,  0x0000, 0x0600,  0x400, 0xff); // 128
	}
	else
	{
		/* Unused */
	}

	deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0);
	return 0;
}