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