summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/copsnrob.cpp
blob: 109f13fcf9bb2f4af227267999a23a49d81c6dc7 (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
// license:BSD-3-Clause
// copyright-holders:Zsolt Vasvari
/***************************************************************************

    Atari Cops'n Robbers hardware

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

#include "emu.h"
#include "includes/copsnrob.h"


uint32_t copsnrob_state::screen_update_copsnrob(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int offs, x, y;

	/* redrawing the entire display is faster in this case */

	for (offs = m_videoram.bytes(); offs >= 0; offs--)
	{
		int sx,sy;

		sx = 31 - (offs % 32);
		sy = offs / 32;

		m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,
				m_videoram[offs] & 0x3f,0,
				0,0,
				8*sx,8*sy);
	}


	/* Draw the cars. Positioning was based on a screen shot */
	if (m_cary[0])
		m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
				m_carimage[0],0,
				1,0,
				0xe4,256 - m_cary[0],0);

	if (m_cary[1])
		m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
				m_carimage[1],0,
				1,0,
				0xc4,256 - m_cary[1],0);

	if (m_cary[2])
		m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
				m_carimage[2],0,
				0,0,
				0x24,256 - m_cary[2],0);

	if (m_cary[3])
		m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
				m_carimage[3],0,
				0,0,
				0x04,256 - m_cary[3],0);


	/* Draw the beer truck. Positioning was based on a screen shot.
	    We scan the truck's window RAM for a location whose bit is set and
	    which corresponds either to the truck's front end or the truck's back
	    end (based on the value of the truck image line sync register). We
	    then draw a truck image in the proper place and continue scanning.
	    This is not a perfect emulation of the game hardware, but it should
	    suffice for the way the game software uses the hardware.  It does take
	    care of the problem of displaying multiple beer trucks and of scrolling
	    truck images smoothly off the top of the screen. */

	for (y = 0; y < 256; y++)
	{
		/* y is going up the screen, but the truck window RAM locations
		go down the screen. */

		if (m_truckram[255 - y])
		{
			/* The hardware only uses the low 5 bits of the truck image line
			sync register. */
			if ((m_trucky[0] & 0x1f) == ((y + 31) & 0x1f))
			{
				/* We've hit a truck's back end, so draw the truck.  The front
				   end may be off the top of the screen, but we don't care. */
				m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
						0,0,
						0,0,
						0x80,256 - (y + 31),0);
				/* Skip past this truck's front end so we don't draw this
				truck twice. */
				y += 31;
			}
			else if ((m_trucky[0] & 0x1f) == (y & 0x1f))
			{
				/* We missed a truck's back end (it was off the bottom of the
				   screen) but have hit its front end, so draw the truck. */
				m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
						0,0,
						0,0,
						0x80,256 - y,0);
			}
		}
	}


	/* Draw the bullets.
	   They are flickered on/off every frame by the software, so don't
	   play it with frameskip 1 or 3, as they could become invisible */

	for (x = 0; x < 256; x++)
	{
		int bullet, mask1, mask2, val;

		val = m_bulletsram[x];

		// Check for the most common case
		if (!(val & 0x0f))
			continue;

		mask1 = 0x01;
		mask2 = 0x10;

		// Check each bullet
		for (bullet = 0; bullet < 4; bullet++)
		{
			if (val & mask1)
			{
				for (y = cliprect.top(); y <= cliprect.bottom(); y++)
					if (m_bulletsram[y] & mask2)
						bitmap.pix16(y, 256 - x) = 1;
			}

			mask1 <<= 1;
			mask2 <<= 1;
		}
	}
	return 0;
}