1 /***************************************************************************
2
3 vidhrdw.c
4
5 Functions to emulate the video hardware of the machine.
6
7 ***************************************************************************/
8
9 #include "driver.h"
10 #include "vidhrdw/generic.h"
11
12 unsigned char *redalert_backram;
13 unsigned char *redalert_spriteram1;
14 unsigned char *redalert_spriteram2;
15 unsigned char *redalert_spriteram3;
16 unsigned char *redalert_characterram;
17 unsigned char *redalert_characterram2;
18
19 static unsigned char redalert_dirtyback[0x400];
20 static unsigned char redalert_dirtycharacter[0x100];
21 static unsigned char redalert_dirtycharacter2[0x100];
22 static unsigned char redalert_backcolor[0x400];
23
24
25 /* There might be a color PROM that dictates this? */
26 /* These guesses are based on comparing the color bars on the test
27 screen with the picture in the manual */
28 static unsigned char color_lookup[] = {
29 1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,
30 1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,
31 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
32 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,
33 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
34 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,
35 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
36 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
37
38 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
39 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
40 2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
41 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,
42 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
43 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
44 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
45 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
46 };
47
48 static int backcolor, flip=0;
49
WRITE_HANDLER(redalert_c040_w)50 WRITE_HANDLER( redalert_c040_w )
51 {
52 /* Only seems to load D0-D3 into a flip-flop. */
53 /* D0/D1 seem to head off to unconnected circuits */
54 /* D2 connects to a "NL" line, and NOTted to a "NH" line */
55 /* D3 connects to a "YI" line */
56
57 /*
58 D0 == 1 -> 1 player
59 D1 == 1 and D0 == 1 -> 2 players
60 */
61 flip = !(data & 0x04);
62 }
63
WRITE_HANDLER(redalert_backcolor_w)64 WRITE_HANDLER( redalert_backcolor_w )
65 {
66 /* Only seems to load D0-D2 into a flip-flop. */
67 /* Outputs feed into RAM which seems to feed to RGB lines. */
68 backcolor = data & 0x07;
69 }
70
WRITE_HANDLER(demoneye_c040_w)71 WRITE_HANDLER( demoneye_c040_w )
72 {
73 /*
74 D0 == 1 -> 1 player
75 D1 == 1 and D0 == 1 -> 2 players
76 */
77 flip = data & 0x04;
78 }
79
80 /***************************************************************************
81 redalert_backram_w
82 ***************************************************************************/
83
WRITE_HANDLER(redalert_backram_w)84 WRITE_HANDLER( redalert_backram_w )
85 {
86 int charnum;
87
88 charnum = offset / 8 % 0x400;
89
90 if ((redalert_backram[offset] != data) ||
91 (redalert_backcolor[charnum] != backcolor))
92 {
93 redalert_dirtyback[charnum] = 1;
94 dirtybuffer[charnum] = 1;
95 redalert_backcolor[charnum] = backcolor;
96
97 redalert_backram[offset] = data;
98 }
99 }
100
101 /***************************************************************************
102 redalert_spriteram1_w
103 ***************************************************************************/
104
WRITE_HANDLER(redalert_spriteram1_w)105 WRITE_HANDLER( redalert_spriteram1_w )
106 {
107 if (redalert_spriteram1[offset] != data)
108 {
109 redalert_dirtycharacter[((offset / 8) % 0x80) + 0x80] = 1;
110
111 redalert_spriteram1[offset] = data;
112 }
113 }
114
115 /***************************************************************************
116 redalert_spriteram2_w
117 ***************************************************************************/
118
WRITE_HANDLER(redalert_spriteram2_w)119 WRITE_HANDLER( redalert_spriteram2_w )
120 {
121 if (redalert_spriteram2[offset] != data)
122 {
123
124 redalert_dirtycharacter[((offset / 8) % 0x80) + 0x80] = 1;
125
126 redalert_spriteram2[offset] = data;
127 }
128 }
129
130 /***************************************************************************
131 redalert_characterram_w
132 ***************************************************************************/
133
WRITE_HANDLER(redalert_characterram_w)134 WRITE_HANDLER( redalert_characterram_w )
135 {
136 if (redalert_characterram[offset] != data)
137 {
138 redalert_dirtycharacter[((offset / 8) % 0x80)] = 1;
139
140 redalert_characterram[offset] = data;
141 }
142 }
143
WRITE_HANDLER(redalert_characterram2_w)144 WRITE_HANDLER( redalert_characterram2_w )
145 {
146 if (redalert_characterram2[offset] != data)
147 {
148 redalert_dirtycharacter[((offset / 8) % 0x80)] = 1;
149
150 redalert_characterram2[offset] = data;
151 }
152 }
153
WRITE_HANDLER(redalert_spriteram3_w)154 WRITE_HANDLER( redalert_spriteram3_w )
155 {
156 if (redalert_spriteram3[offset] != data)
157 {
158 redalert_dirtycharacter2[((offset / 8) % 0x80) + 0x80] = 1;
159
160 redalert_spriteram3[offset] = data;
161 }
162
163 }
164
165
166 /***************************************************************************
167
168 Draw the game screen in the given mame_bitmap.
169 Do NOT call osd_update_display() from this function, it will be called by
170 the main emulation engine.
171
172 ***************************************************************************/
VIDEO_UPDATE(redalert)173 VIDEO_UPDATE( redalert )
174 {
175 int offs,i;
176
177 /* for every character in the Video RAM, check if it has been modified */
178 /* since last time and update it accordingly. */
179 for (offs = videoram_size - 1;offs >= 0;offs--)
180 {
181 int charcode;
182 int stat_transparent;
183
184
185 charcode = videoram[offs];
186
187 if (dirtybuffer[offs] || redalert_dirtycharacter[charcode] || redalert_dirtycharacter2[charcode])
188 {
189 int sx,sy,color;
190
191
192 /* decode modified background */
193 if (redalert_dirtyback[offs] == 1)
194 {
195 decodechar(Machine->gfx[0],offs,redalert_backram,
196 Machine->drv->gfxdecodeinfo[0].gfxlayout);
197 redalert_dirtyback[offs] = 2;
198 }
199
200 /* decode modified characters */
201 if (redalert_dirtycharacter[charcode] == 1)
202 {
203 if (charcode < 0x80)
204 decodechar(Machine->gfx[1],charcode,redalert_characterram,
205 Machine->drv->gfxdecodeinfo[1].gfxlayout);
206 else
207 decodechar(Machine->gfx[2],charcode-0x80,redalert_spriteram1,
208 Machine->drv->gfxdecodeinfo[2].gfxlayout);
209 redalert_dirtycharacter[charcode] = 2;
210 }
211
212 if (redalert_dirtycharacter2[charcode] == 1)
213 {
214 decodechar(Machine->gfx[3],charcode-0x80,redalert_spriteram3,
215 Machine->drv->gfxdecodeinfo[3].gfxlayout);
216 redalert_dirtycharacter2[charcode] = 2;
217 }
218
219 dirtybuffer[offs] = 0;
220
221 sx = 31 - offs / 32;
222 sy = offs % 32;
223
224 stat_transparent = TRANSPARENCY_NONE;
225
226 /* First layer of color */
227 if (charcode >= 0xC0)
228 {
229 stat_transparent = TRANSPARENCY_COLOR;
230
231 color = color_lookup[charcode];
232
233 drawgfx(tmpbitmap,Machine->gfx[2],
234 charcode-0x80,
235 color,
236 0,0,
237 8*sx,8*sy,
238 &Machine->visible_area,TRANSPARENCY_NONE,0);
239
240 if( redalert_dirtycharacter2[charcode] != 0 )
241 drawgfx(tmpbitmap,Machine->gfx[3],
242 charcode-0x80,
243 color,
244 0,0,
245 8*sx,8*sy,
246 &Machine->visible_area,TRANSPARENCY_COLOR,0);
247
248 }
249
250 /* Second layer - background */
251 color = redalert_backcolor[offs];
252 drawgfx(tmpbitmap,Machine->gfx[0],
253 offs,
254 color,
255 0,0,
256 8*sx,8*sy,
257 &Machine->visible_area,stat_transparent,0);
258
259 /* Third layer - alphanumerics & sprites */
260 if (charcode < 0x80)
261 {
262 color = color_lookup[charcode];
263 drawgfx(tmpbitmap,Machine->gfx[1],
264 charcode,
265 color,
266 0,0,
267 8*sx,8*sy,
268 &Machine->visible_area,TRANSPARENCY_COLOR,0);
269 }
270 else if (charcode < 0xC0)
271 {
272 color = color_lookup[charcode];
273 drawgfx(tmpbitmap,Machine->gfx[2],
274 charcode-0x80,
275 color,
276 0,0,
277 8*sx,8*sy,
278 &Machine->visible_area,TRANSPARENCY_COLOR,0);
279
280 if( redalert_dirtycharacter2[charcode] != 0 )
281 drawgfx(tmpbitmap,Machine->gfx[3],
282 charcode-0x80,
283 color,
284 0,0,
285 8*sx,8*sy,
286 &Machine->visible_area,TRANSPARENCY_COLOR,0);
287
288 }
289
290 }
291 }
292
293 for (i = 0;i < 256;i++)
294 {
295 if (redalert_dirtycharacter[i] == 2)
296 redalert_dirtycharacter[i] = 0;
297
298 if (redalert_dirtycharacter2[i] == 2)
299 redalert_dirtycharacter2[i] = 0;
300 }
301
302 for (i = 0;i < 0x400;i++)
303 {
304 if (redalert_dirtyback[i] == 2)
305 redalert_dirtyback[i] = 0;
306 }
307
308 /* copy the character mapped graphics */
309 copybitmap(bitmap,tmpbitmap,flip,flip,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
310
311 }
312