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