1 // license:BSD-3-Clause
2 // copyright-holders:Chris Hardy
3 /***************************************************************************
4 
5   video.c
6 
7   Functions to emulate the video hardware of the machine.
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "video/resnet.h"
13 #include "includes/megazone.h"
14 
15 /***************************************************************************
16 Based on driver from MAME 0.55
17 Changes by Martin M. (pfloyd@gmx.net) 14.10.2001:
18 
19  - Added support for screen flip in cocktail mode (tricky!) */
20 
21 
22 /***************************************************************************
23 
24   Convert the color PROMs into a more useable format.
25 
26   Megazone has one 32x8 palette PROM and two 256x4 lookup table PROMs
27   (one for characters, one for sprites).
28   The palette PROM is connected to the RGB output this way:
29 
30   bit 7 -- 220 ohm resistor  -- BLUE
31         -- 470 ohm resistor  -- BLUE
32         -- 220 ohm resistor  -- GREEN
33         -- 470 ohm resistor  -- GREEN
34         -- 1  kohm resistor  -- GREEN
35         -- 220 ohm resistor  -- RED
36         -- 470 ohm resistor  -- RED
37   bit 0 -- 1  kohm resistor  -- RED
38 
39 ***************************************************************************/
40 
megazone_palette(palette_device & palette) const41 void megazone_state::megazone_palette(palette_device &palette) const
42 {
43 	const uint8_t *color_prom = memregion("proms")->base();
44 	static constexpr int resistances_rg[3] = { 1000, 470, 220 };
45 	static constexpr int resistances_b [2] = { 470, 220 };
46 
47 	// compute the color output resistor weights
48 	double rweights[3], gweights[3], bweights[2];
49 	compute_resistor_weights(0, 255, -1.0,
50 			3, &resistances_rg[0], rweights, 1000, 0,
51 			3, &resistances_rg[0], gweights, 1000, 0,
52 			2, &resistances_b[0],  bweights, 1000, 0);
53 
54 	// create a lookup table for the palette
55 	for (int i = 0; i < 0x20; i++)
56 	{
57 		int bit0, bit1, bit2;
58 
59 		// red component
60 		bit0 = BIT(color_prom[i], 0);
61 		bit1 = BIT(color_prom[i], 1);
62 		bit2 = BIT(color_prom[i], 2);
63 		int const r = combine_weights(rweights, bit0, bit1, bit2);
64 
65 		// green component
66 		bit0 = BIT(color_prom[i], 3);
67 		bit1 = BIT(color_prom[i], 4);
68 		bit2 = BIT(color_prom[i], 5);
69 		int const g = combine_weights(gweights, bit0, bit1, bit2);
70 
71 		// blue component
72 		bit0 = BIT(color_prom[i], 6);
73 		bit1 = BIT(color_prom[i], 7);
74 		int const b = combine_weights(bweights, bit0, bit1);
75 
76 		palette.set_indirect_color(i, rgb_t(r, g, b));
77 	}
78 
79 	// color_prom now points to the beginning of the lookup table
80 	color_prom += 0x20;
81 
82 	// sprites
83 	for (int i = 0; i < 0x100; i++)
84 	{
85 		uint8_t const ctabentry = color_prom[i] & 0x0f;
86 		palette.set_pen_indirect(i, ctabentry);
87 	}
88 
89 	// characters
90 	for (int i = 0x100; i < 0x200; i++)
91 	{
92 		uint8_t const ctabentry = (color_prom[i] & 0x0f) | 0x10;
93 		palette.set_pen_indirect(i, ctabentry);
94 	}
95 }
96 
WRITE_LINE_MEMBER(megazone_state::flipscreen_w)97 WRITE_LINE_MEMBER(megazone_state::flipscreen_w)
98 {
99 	m_flipscreen = state;
100 }
101 
video_start()102 void megazone_state::video_start()
103 {
104 	m_tmpbitmap = std::make_unique<bitmap_ind16>(256, 256);
105 
106 	save_item(NAME(*m_tmpbitmap));
107 }
108 
109 
screen_update_megazone(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)110 uint32_t megazone_state::screen_update_megazone(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
111 {
112 	int offs;
113 	int x, y;
114 
115 	/* for every character in the Video RAM */
116 	for (offs = m_videoram.bytes() - 1; offs >= 0; offs--)
117 	{
118 		int sx, sy, flipx, flipy;
119 
120 		sx = offs % 32;
121 		sy = offs / 32;
122 		flipx = m_colorram[offs] & (1 << 6);
123 		flipy = m_colorram[offs] & (1 << 5);
124 
125 		if (m_flipscreen)
126 		{
127 			sx = 31 - sx;
128 			sy = 31 - sy;
129 			flipx = !flipx;
130 			flipy = !flipy;
131 		}
132 
133 		m_gfxdecode->gfx(1)->opaque(*m_tmpbitmap,m_tmpbitmap->cliprect(),
134 				((int)m_videoram[offs]) + ((m_colorram[offs] & (1 << 7) ? 256 : 0) ),
135 				(m_colorram[offs] & 0x0f) + 0x10,
136 				flipx,flipy,
137 				8*sx,8*sy);
138 	}
139 
140 	/* copy the temporary bitmap to the screen */
141 	{
142 		int scrollx;
143 		int scrolly;
144 
145 		if (m_flipscreen)
146 		{
147 			scrollx = *m_scrolly;
148 			scrolly = *m_scrollx;
149 		}
150 		else
151 		{
152 			scrollx = - *m_scrolly + 4 * 8; // leave space for credit&score overlay
153 			scrolly = - *m_scrollx;
154 		}
155 
156 
157 		copyscrollbitmap(bitmap, *m_tmpbitmap, 1, &scrollx, 1, &scrolly, cliprect);
158 	}
159 
160 
161 	/* Draw the sprites. */
162 	{
163 		uint8_t *spriteram = m_spriteram;
164 		for (offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
165 		{
166 			int sx = spriteram[offs + 3];
167 			int sy = 255 - ((spriteram[offs + 1] + 16) & 0xff);
168 			int color =  spriteram[offs + 0] & 0x0f;
169 			int flipx = ~spriteram[offs + 0] & 0x40;
170 			int flipy =  spriteram[offs + 0] & 0x80;
171 
172 			if (m_flipscreen)
173 			{
174 				sx = sx - 11;
175 				sy = sy + 2;
176 			}
177 			else
178 				sx = sx + 32;
179 
180 			m_gfxdecode->gfx(0)->transmask(bitmap,cliprect,
181 					spriteram[offs + 2],
182 					color,
183 					flipx,flipy,
184 					sx,sy,
185 					m_palette->transpen_mask(*m_gfxdecode->gfx(0), color, 0));
186 		}
187 	}
188 
189 	for (y = 0; y < 32;y++)
190 	{
191 		offs = y * 32;
192 		for (x = 0; x < 6; x++)
193 		{
194 			int sx, sy, flipx, flipy;
195 
196 			sx = x;
197 			sy = y;
198 
199 			flipx = m_colorram2[offs] & (1 << 6);
200 			flipy = m_colorram2[offs] & (1 << 5);
201 
202 			if (m_flipscreen)
203 			{
204 				sx = 35 - sx;
205 				sy = 31 - sy;
206 				flipx = !flipx;
207 				flipy = !flipy;
208 			}
209 
210 
211 
212 
213 			m_gfxdecode->gfx(1)->opaque(bitmap,cliprect,
214 					((int)m_videoram2[offs]) + ((m_colorram2[offs] & (1 << 7) ? 256 : 0) ),
215 					(m_colorram2[offs] & 0x0f) + 0x10,
216 					flipx,flipy,
217 					8*sx,8*sy);
218 			offs++;
219 		}
220 	}
221 	return 0;
222 }
223