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