1 /***************************************************************************
2 
3 	breakthru:vidhrdw.c
4 
5 ***************************************************************************/
6 
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 
10 
11 unsigned char *brkthru_scroll;
12 unsigned char *brkthru_videoram;
13 size_t brkthru_videoram_size;
14 static int bgscroll;
15 static int bgbasecolor;
16 static int flipscreen;
17 
18 
19 
20 /***************************************************************************
21 
22   Convert the color PROMs into a more useable format.
23 
24   Break Thru has one 256x8 and one 256x4 palette PROMs.
25   I don't know for sure how the palette PROMs are connected to the RGB
26   output, but it's probably the usual:
27 
28   bit 7 -- 220 ohm resistor  -- GREEN
29         -- 470 ohm resistor  -- GREEN
30         -- 1  kohm resistor  -- GREEN
31         -- 2.2kohm resistor  -- GREEN
32         -- 220 ohm resistor  -- RED
33         -- 470 ohm resistor  -- RED
34         -- 1  kohm resistor  -- RED
35   bit 0 -- 2.2kohm resistor  -- RED
36 
37   bit 3 -- 220 ohm resistor  -- BLUE
38         -- 470 ohm resistor  -- BLUE
39         -- 1  kohm resistor  -- BLUE
40   bit 0 -- 2.2kohm resistor  -- BLUE
41 
42 ***************************************************************************/
brkthru_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)43 void brkthru_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
44 {
45 	int i;
46 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
47 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
48 
49 
50 	for (i = 0;i < Machine->drv->total_colors;i++)
51 	{
52 		int bit0,bit1,bit2,bit3;
53 
54 
55 		bit0 = (color_prom[0] >> 0) & 0x01;
56 		bit1 = (color_prom[0] >> 1) & 0x01;
57 		bit2 = (color_prom[0] >> 2) & 0x01;
58 		bit3 = (color_prom[0] >> 3) & 0x01;
59 		*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
60 		bit0 = (color_prom[0] >> 4) & 0x01;
61 		bit1 = (color_prom[0] >> 5) & 0x01;
62 		bit2 = (color_prom[0] >> 6) & 0x01;
63 		bit3 = (color_prom[0] >> 7) & 0x01;
64 		*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
65 		bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
66 		bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
67 		bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
68 		bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
69 		*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
70 
71 		color_prom++;
72 	}
73 
74 	/* characters use colors 0-7 */
75 	for (i = 0;i < TOTAL_COLORS(0);i++)
76 		COLOR(0,i) = i;
77 
78 	/* background tiles use colors 128-255 */
79 	for (i = 0;i < TOTAL_COLORS(1);i++)
80 		COLOR(1,i) = i + 128;
81 
82 	/* sprites use colors 64-127 */
83 	for (i = 0;i < TOTAL_COLORS(9);i++)
84 		COLOR(9,i) = i + 64;
85 }
86 
87 
88 
89 /***************************************************************************
90 
91   Start the video hardware emulation.
92 
93 ***************************************************************************/
brkthru_vh_start(void)94 int brkthru_vh_start(void)
95 {
96 	if ((dirtybuffer = (unsigned char*)malloc(videoram_size)) == 0)
97 	{
98 		generic_vh_stop();
99 		return 1;
100 	}
101 	memset(dirtybuffer,1,videoram_size);
102 
103 	/* the background area is twice as wide as the screen */
104 	if ((tmpbitmap = bitmap_alloc(2*Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
105 	{
106 		free(dirtybuffer);
107 		return 1;
108 	}
109 
110 	return 0;
111 }
112 
113 
114 
115 /***************************************************************************
116 
117   Stop the video hardware emulation.
118 
119 ***************************************************************************/
brkthru_vh_stop(void)120 void brkthru_vh_stop(void)
121 {
122 	bitmap_free(tmpbitmap);
123 	free(dirtybuffer);
124 }
125 
126 
127 
WRITE_HANDLER(brkthru_1800_w)128 WRITE_HANDLER( brkthru_1800_w )
129 {
130 	if (offset == 0)	/* low 8 bits of scroll */
131 		bgscroll = (bgscroll & 0x100) | data;
132 	else if (offset == 1)
133 	{
134 		int bankaddress;
135 		unsigned char *RAM = memory_region(REGION_CPU1);
136 
137 
138 		/* bit 0-2 = ROM bank select */
139 		bankaddress = 0x10000 + (data & 0x07) * 0x2000;
140 		cpu_setbank(1,&RAM[bankaddress]);
141 
142 		/* bit 3-5 = background tiles color code */
143 		if (((data & 0x38) >> 2) != bgbasecolor)
144 		{
145 			bgbasecolor = (data & 0x38) >> 2;
146 			memset(dirtybuffer,1,videoram_size);
147 		}
148 
149 		/* bit 6 = screen flip */
150 		if (flipscreen != (data & 0x40))
151 		{
152 			flipscreen = data & 0x40;
153 			memset(dirtybuffer,1,videoram_size);
154 		}
155 
156 		/* bit 7 = high bit of scroll */
157 		bgscroll = (bgscroll & 0xff) | ((data & 0x80) << 1);
158 	}
159 }
160 
161 
162 
163 /***************************************************************************
164 
165   Draw the game screen in the given osd_bitmap.
166   Do NOT call osd_update_display() from this function, it will be called by
167   the main emulation engine.
168 
169 ***************************************************************************/
brkthru_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)170 void brkthru_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
171 {
172 	int offs;
173 
174 
175 	/* for every character in the Video RAM, check if it has been modified */
176 	/* since last time and update it accordingly. */
177 	for (offs = videoram_size - 2;offs >= 0;offs -= 2)
178 	{
179 		if (dirtybuffer[offs] || dirtybuffer[offs+1])
180 		{
181 			int sx,sy,code;
182 
183 
184 			dirtybuffer[offs] = dirtybuffer[offs+1] = 0;
185 
186 			sx = (offs/2) / 16;
187 			sy = (offs/2) % 16;
188 			if (flipscreen)
189 			{
190 				sx = 31 - sx;
191 				sy = 15 - sy;
192 			}
193 
194 			code = videoram[offs] + 256 * (videoram[offs+1] & 3);
195 			drawgfx(tmpbitmap,Machine->gfx[1 + (code >> 7)],
196 					code & 0x7f,
197 					bgbasecolor + ((videoram[offs+1] & 0x04) >> 2),
198 					flipscreen,flipscreen,
199 					16*sx,16*sy,
200 					0,TRANSPARENCY_NONE,0);
201 		}
202 	}
203 
204 
205 	/* copy the background graphics */
206 	{
207 		int scroll;
208 
209 
210 		if (flipscreen) scroll = 256 + bgscroll;
211 		else scroll = -bgscroll;
212 		copyscrollbitmap(bitmap,tmpbitmap,1,&scroll,0,0,&Machine->visible_area,TRANSPARENCY_NONE,0);
213 	}
214 
215 
216 	/* Draw the sprites. Note that it is important to draw them exactly in this */
217 	/* order, to have the correct priorities. */
218 	for (offs = 0;offs < spriteram_size; offs += 4)
219 	{
220 		if (spriteram[offs] & 0x01)	/* enable */
221 		{
222 			int sx,sy,code,color;
223 
224 
225 			/* the meaning of bit 3 of [offs] is unknown */
226 
227 			sx = 240 - spriteram[offs+3];
228 			if (sx < -7) sx += 256;
229 			sy = 240 - spriteram[offs+2];
230 			code = spriteram[offs+1] + 128 * (spriteram[offs] & 0x06);
231 			color = (spriteram[offs] & 0xe0) >> 5;
232 			if (flipscreen)
233 			{
234 				sx = 240 - sx;
235 				sy = 240 - sy;
236 			}
237 
238 			if (spriteram[offs] & 0x10)	/* double height */
239 			{
240 				drawgfx(bitmap,Machine->gfx[9],
241 						code & ~1,
242 						color,
243 						flipscreen,flipscreen,
244 						sx,flipscreen? sy + 16 : sy - 16,
245 						&Machine->visible_area,TRANSPARENCY_PEN,0);
246 				drawgfx(bitmap,Machine->gfx[9],
247 						code | 1,
248 						color,
249 						flipscreen,flipscreen,
250 						sx,sy,
251 						&Machine->visible_area,TRANSPARENCY_PEN,0);
252 
253 				/* redraw with wraparound */
254 				drawgfx(bitmap,Machine->gfx[9],
255 						code & ~1,
256 						color,
257 						flipscreen,flipscreen,
258 						sx,(flipscreen? sy + 16 : sy - 16) + 256,
259 						&Machine->visible_area,TRANSPARENCY_PEN,0);
260 				drawgfx(bitmap,Machine->gfx[9],
261 						code | 1,
262 						color,
263 						flipscreen,flipscreen,
264 						sx,sy + 256,
265 						&Machine->visible_area,TRANSPARENCY_PEN,0);
266 			}
267 			else
268 			{
269 				drawgfx(bitmap,Machine->gfx[9],
270 						code,
271 						color,
272 						flipscreen,flipscreen,
273 						sx,sy,
274 						&Machine->visible_area,TRANSPARENCY_PEN,0);
275 
276 				/* redraw with wraparound */
277 				drawgfx(bitmap,Machine->gfx[9],
278 						code,
279 						color,
280 						flipscreen,flipscreen,
281 						sx,sy + 256,
282 						&Machine->visible_area,TRANSPARENCY_PEN,0);
283 			}
284 		}
285 	}
286 
287 
288 	/* draw the frontmost playfield. They are characters, but draw them as sprites */
289 	for (offs = brkthru_videoram_size - 1;offs >= 0;offs--)
290 	{
291 		int sx,sy;
292 
293 
294 		sx = offs % 32;
295 		sy = offs / 32;
296 		if (flipscreen)
297 		{
298 			sx = 31 - sx;
299 			sy = 31 - sy;
300 		}
301 
302 		drawgfx(bitmap,Machine->gfx[0],
303 				brkthru_videoram[offs],
304 				0,
305 				flipscreen,flipscreen,
306 				8*sx,8*sy,
307 				&Machine->visible_area,TRANSPARENCY_PEN,0);
308 	}
309 }
310