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 
13 unsigned char *mrdo_bgvideoram,*mrdo_fgvideoram;
14 static struct tilemap *bg_tilemap,*fg_tilemap;
15 static int flipscreen;
16 
17 
18 
19 /***************************************************************************
20 
21   Convert the color PROMs into a more useable format.
22 
23   Mr. Do! has two 32 bytes palette PROM and a 32 bytes sprite color lookup
24   table PROM.
25   The palette PROMs are connected to the RGB output this way:
26 
27   U2:
28   bit 7 -- unused
29         -- unused
30         -- 100 ohm resistor  -diode- BLUE
31         --  75 ohm resistor  -diode- BLUE
32         -- 100 ohm resistor  -diode- GREEN
33         --  75 ohm resistor  -diode- GREEN
34         -- 100 ohm resistor  -diode- RED
35   bit 0 --  75 ohm resistor  -diode- RED
36 
37   T2:
38   bit 7 -- unused
39         -- unused
40         -- 150 ohm resistor  -diode- BLUE
41         -- 120 ohm resistor  -diode- BLUE
42         -- 150 ohm resistor  -diode- GREEN
43         -- 120 ohm resistor  -diode- GREEN
44         -- 150 ohm resistor  -diode- RED
45   bit 0 -- 120 ohm resistor  -diode- RED
46 
47   200 ohm pulldown on all three components
48 
49 ***************************************************************************/
PALETTE_INIT(mrdo)50 PALETTE_INIT( mrdo )
51 {
52 	int i;
53 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
54 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
55 
56 	const int R1 = 150;
57 	const int R2 = 120;
58 	const int R3 = 100;
59 	const int R4 = 75;
60 	const int pull = 220;
61 	float pot[16];
62 	int weight[16];
63 	const float potadjust = 0.7f;	/* diode voltage drop */
64 
65 	for (i = 0x0f;i >= 0;i--)
66 	{
67 		float par = 0;
68 
69 		if (i & 1) par += 1.0f/(float)R1;
70 		if (i & 2) par += 1.0f/(float)R2;
71 		if (i & 4) par += 1.0f/(float)R3;
72 		if (i & 8) par += 1.0f/(float)R4;
73 		if (par)
74 		{
75 			par = 1/par;
76 			pot[i] = pull/(pull+par) - potadjust;
77 		}
78 		else pot[i] = 0;
79 
80 		weight[i] = 0xff * pot[i] / pot[0x0f];
81 		if (weight[i] < 0) weight[i] = 0;
82 	}
83 
84 	for (i = 0;i < 0x100;i++)
85 	{
86 		int a1,a2;
87 		int bits0,bits2,r,g,b;
88 
89 		a1 = ((i >> 3) & 0x1c) + (i & 0x03) + 32;
90 		a2 = ((i >> 0) & 0x1c) + (i & 0x03);
91 
92 		bits0 = (color_prom[a1] >> 0) & 0x03;
93 		bits2 = (color_prom[a2] >> 0) & 0x03;
94 		r = weight[bits0 + (bits2 << 2)];
95 		bits0 = (color_prom[a1] >> 2) & 0x03;
96 		bits2 = (color_prom[a2] >> 2) & 0x03;
97 		g = weight[bits0 + (bits2 << 2)];
98 		bits0 = (color_prom[a1] >> 4) & 0x03;
99 		bits2 = (color_prom[a2] >> 4) & 0x03;
100 		b = weight[bits0 + (bits2 << 2)];
101 		palette_set_color(i,r,g,b);
102 	}
103 
104 	color_prom += 0x40;
105 
106         /* characters */
107         for (i = 0; i < 0x100; i++)
108                COLOR(0,i) = i;
109 
110 	/* sprites */
111 	for (i = 0x100; i < 0x140 ; i++)
112 	{
113 		unsigned char ctabentry = color_prom[(i - 0x100) & 0x1f];
114 		if ((i - 0x100) & 0x20)
115 			ctabentry >>= 4;	/* high 4 bits are for sprite color n + 8 */
116 		else
117 			ctabentry &= 0x0f;	/* low 4 bits are for sprite color n */
118 
119 		COLOR(1,i) = (ctabentry + ((ctabentry & 0x0c) << 3));
120 	}
121 }
122 
123 
124 
125 /***************************************************************************
126 
127   Callbacks for the TileMap code
128 
129 ***************************************************************************/
130 
get_bg_tile_info(int tile_index)131 static void get_bg_tile_info(int tile_index)
132 {
133 	unsigned char attr = mrdo_bgvideoram[tile_index];
134 	SET_TILE_INFO(
135 			1,
136 			mrdo_bgvideoram[tile_index+0x400] + ((attr & 0x80) << 1),
137 			attr & 0x3f,
138 			(attr & 0x40) ? TILE_IGNORE_TRANSPARENCY : 0)
139 }
140 
get_fg_tile_info(int tile_index)141 static void get_fg_tile_info(int tile_index)
142 {
143 	unsigned char attr = mrdo_fgvideoram[tile_index];
144 	SET_TILE_INFO(
145 			0,
146 			mrdo_fgvideoram[tile_index+0x400] + ((attr & 0x80) << 1),
147 			attr & 0x3f,
148 			(attr & 0x40) ? TILE_IGNORE_TRANSPARENCY : 0)
149 }
150 
151 
152 
153 /***************************************************************************
154 
155   Start the video hardware emulation.
156 
157 ***************************************************************************/
158 
VIDEO_START(mrdo)159 VIDEO_START( mrdo )
160 {
161 	bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
162 	fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,32,32);
163 
164 	if (!bg_tilemap || !fg_tilemap)
165 		return 1;
166 
167 	tilemap_set_transparent_pen(bg_tilemap,0);
168 	tilemap_set_transparent_pen(fg_tilemap,0);
169 
170 	return 0;
171 }
172 
173 
174 
175 /***************************************************************************
176 
177   Memory handlers
178 
179 ***************************************************************************/
180 
WRITE_HANDLER(mrdo_bgvideoram_w)181 WRITE_HANDLER( mrdo_bgvideoram_w )
182 {
183 	if (mrdo_bgvideoram[offset] != data)
184 	{
185 		mrdo_bgvideoram[offset] = data;
186 		tilemap_mark_tile_dirty(bg_tilemap,offset & 0x3ff);
187 	}
188 }
189 
WRITE_HANDLER(mrdo_fgvideoram_w)190 WRITE_HANDLER( mrdo_fgvideoram_w )
191 {
192 	if (mrdo_fgvideoram[offset] != data)
193 	{
194 		mrdo_fgvideoram[offset] = data;
195 		tilemap_mark_tile_dirty(fg_tilemap,offset & 0x3ff);
196 	}
197 }
198 
199 
WRITE_HANDLER(mrdo_scrollx_w)200 WRITE_HANDLER( mrdo_scrollx_w )
201 {
202 	tilemap_set_scrollx(bg_tilemap,0,data);
203 }
204 
WRITE_HANDLER(mrdo_scrolly_w)205 WRITE_HANDLER( mrdo_scrolly_w )
206 {
207 	/* This is NOT affected by flipscreen (so stop it happening) */
208 
209 	if (flipscreen) tilemap_set_scrolly(bg_tilemap,0,((256-data) & 0xff));
210 	else tilemap_set_scrolly(bg_tilemap,0,data);
211 }
212 
213 
WRITE_HANDLER(mrdo_flipscreen_w)214 WRITE_HANDLER( mrdo_flipscreen_w )
215 {
216 	/* bits 1-3 control the playfield priority, but they are not used by */
217 	/* Mr. Do! so we don't emulate them */
218 
219 	flipscreen = data & 0x01;
220 	tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
221 }
222 
223 
224 
225 /***************************************************************************
226 
227   Display refresh
228 
229 ***************************************************************************/
230 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)231 static void draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
232 {
233 	int offs;
234 
235 
236 	for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
237 	{
238 		if (spriteram[offs + 1] != 0)
239 		{
240 			drawgfx(bitmap,Machine->gfx[2],
241 					spriteram[offs],spriteram[offs + 2] & 0x0f,
242 					spriteram[offs + 2] & 0x10,spriteram[offs + 2] & 0x20,
243 					spriteram[offs + 3],256 - spriteram[offs + 1],
244 					cliprect,TRANSPARENCY_PEN,0);
245 		}
246 	}
247 }
248 
VIDEO_UPDATE(mrdo)249 VIDEO_UPDATE( mrdo )
250 {
251 	fillbitmap(bitmap,Machine->pens[0],cliprect);
252 	tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
253 	tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
254 	draw_sprites(bitmap,cliprect);
255 }
256