1 /***************************************************************************
2
3 vidhrdw.c
4
5 Functions to emulate the video hardware of the machine.
6
7 ***************************************************************************/
8
9 #define JEDI_PLAYFIELD
10
11 #include "driver.h"
12 #include "vidhrdw/generic.h"
13
14 unsigned char *jedi_backgroundram;
15 size_t jedi_backgroundram_size;
16 unsigned char *jedi_PIXIRAM;
17 static unsigned int jedi_vscroll;
18 static unsigned int jedi_hscroll;
19 static unsigned int jedi_alpha_bank;
20 static int video_off,smooth_table;
21 static unsigned char *dirtybuffer2;
22 static struct osd_bitmap *tmpbitmap2,*tmpbitmap3;
23
24
25
26 /* Color RAM format
27 Color RAM is 1024x12
28 RAM address: A0..A3 = Playfield color code
29 A4..A7 = Motion object color code
30 A8..A9 = Alphanumeric color code
31 RAM data:
32 0..2 = Blue
33 3..5 = Green
34 6..8 = Blue
35 9..11 = Intesnsity
36 Output resistor values:
37 bit 0 = 22K
38 bit 1 = 10K
39 bit 2 = 4.7K
40 */
41
42
WRITE_HANDLER(jedi_paletteram_w)43 WRITE_HANDLER( jedi_paletteram_w )
44 {
45 int r,g,b;
46 int bits,intensity;
47 unsigned int color;
48
49
50 paletteram[offset] = data;
51 color = paletteram[offset & 0x3FF] | (paletteram[offset | 0x400] << 8);
52 intensity = (color >> 9) & 0x07;
53 bits = (color >> 6) & 0x07;
54 r = 5 * bits * intensity;
55 bits = (color >> 3) & 0x07;
56 g = 5 * bits * intensity;
57 bits = (color >> 0) & 0x07;
58 b = 5 * bits * intensity;
59
60 palette_change_color (offset & 0x3ff,r,g,b);
61 }
62
63
64
65 /***************************************************************************
66
67 Start the video hardware emulation.
68
69 ***************************************************************************/
jedi_vh_start(void)70 int jedi_vh_start(void)
71 {
72 if ((dirtybuffer = (unsigned char*)malloc(videoram_size)) == 0)
73 {
74 return 1;
75 }
76 memset(dirtybuffer,1,videoram_size);
77
78 if ((tmpbitmap = bitmap_alloc_depth(Machine->drv->screen_width,Machine->drv->screen_height,8)) == 0)
79 {
80 free(dirtybuffer);
81 return 1;
82 }
83
84 if ((dirtybuffer2 = (unsigned char*)malloc(jedi_backgroundram_size)) == 0)
85 {
86 bitmap_free(tmpbitmap);
87 free(dirtybuffer);
88 return 1;
89 }
90 memset(dirtybuffer2,1,jedi_backgroundram_size);
91
92 if ((tmpbitmap2 = bitmap_alloc_depth(Machine->drv->screen_width,Machine->drv->screen_height,8)) == 0)
93 {
94 bitmap_free(tmpbitmap);
95 free(dirtybuffer);
96 free(dirtybuffer2);
97 return 1;
98 }
99
100 /* the background area is 256x256, doubled by the hardware*/
101 if ((tmpbitmap3 = bitmap_alloc_depth(256,256,8)) == 0)
102 {
103 bitmap_free(tmpbitmap);
104 bitmap_free(tmpbitmap2);
105 free(dirtybuffer);
106 free(dirtybuffer2);
107 return 1;
108 }
109
110 /* reserve color 1024 for black (disabled display) */
111 palette_change_color(1024,0,0,0);
112
113 return 0;
114 }
115
jedi_vh_stop(void)116 void jedi_vh_stop(void)
117 {
118 bitmap_free(tmpbitmap);
119 bitmap_free(tmpbitmap2);
120 bitmap_free(tmpbitmap3);
121 free(dirtybuffer);
122 free(dirtybuffer2);
123 }
124
125
126
WRITE_HANDLER(jedi_backgroundram_w)127 WRITE_HANDLER( jedi_backgroundram_w )
128 {
129 if (jedi_backgroundram[offset] != data)
130 {
131 dirtybuffer2[offset] = 1;
132
133 jedi_backgroundram[offset] = data;
134 }
135 }
136
WRITE_HANDLER(jedi_vscroll_w)137 WRITE_HANDLER( jedi_vscroll_w )
138 {
139 jedi_vscroll = data | (offset << 8);
140 }
141
WRITE_HANDLER(jedi_hscroll_w)142 WRITE_HANDLER( jedi_hscroll_w )
143 {
144 jedi_hscroll = data | (offset << 8);
145 }
146
WRITE_HANDLER(jedi_alpha_banksel_w)147 WRITE_HANDLER( jedi_alpha_banksel_w )
148 {
149 if (jedi_alpha_bank != 2*(data & 0x80))
150 {
151 jedi_alpha_bank = 2*(data & 0x80);
152 memset(dirtybuffer,1,videoram_size);
153 }
154 }
155
WRITE_HANDLER(jedi_video_off_w)156 WRITE_HANDLER( jedi_video_off_w )
157 {
158 video_off = data;
159 }
160
WRITE_HANDLER(jedi_PIXIRAM_w)161 WRITE_HANDLER( jedi_PIXIRAM_w )
162 {
163 smooth_table = data & 0x03;
164 }
165
166
167
168 /***************************************************************************
169
170 Draw the game screen in the given osd_bitmap.
171 Do NOT call osd_update_display() from this function, it will be called by
172 the main emulation engine.
173
174 ***************************************************************************/
jedi_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)175 void jedi_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
176 {
177 int offs;
178
179
180 if (palette_recalc())
181 {
182 memset(dirtybuffer,1,videoram_size);
183 memset(dirtybuffer2,1,jedi_backgroundram_size);
184 }
185
186 if (video_off)
187 {
188 fillbitmap(bitmap,Machine->pens[1024],&Machine->visible_area);
189 return;
190 }
191
192
193 /* Return of the Jedi has a peculiar playfield/sprite priority system. That */
194 /* is, there is no priority system ;-) The color of the pixel which appears on */
195 /* screen depends on all three of the foreground, background and sprites. The */
196 /* 1024 colors palette is appropriately set up by the program to "emulate" a */
197 /* priority system, but it can also be used to display completely different */
198 /* colors (see the palette test in service mode) */
199
200 /* foreground */
201 for (offs = videoram_size - 1;offs >= 0;offs--)
202 {
203 if (dirtybuffer[offs])
204 {
205 int sx,sy;
206
207
208 dirtybuffer[offs] = 0;
209
210 sx = offs % 64;
211 sy = offs / 64;
212
213 drawgfx(tmpbitmap,Machine->gfx[0],
214 videoram[offs] + jedi_alpha_bank,
215 0,
216 0,0,
217 8*sx,8*sy,
218 &Machine->visible_area,TRANSPARENCY_NONE_RAW,0);
219 }
220 }
221
222
223 /* background */
224 for (offs = jedi_backgroundram_size/2 - 1;offs >= 0;offs--)
225 {
226 if (dirtybuffer2[offs] != 0 || dirtybuffer2[offs + 0x400] != 0)
227 {
228 int sx,sy,b,c;
229
230
231 dirtybuffer2[offs] = dirtybuffer2[offs + 0x400] = 0;
232
233 sx = offs % 32;
234 sy = offs / 32;
235 c = (jedi_backgroundram[offs] & 0xFF);
236 b = (jedi_backgroundram[offs + 0x400] & 0x0F);
237 c |= (b & 0x01) << 8;
238 c |= (b & 0x08) << 6;
239 c |= (b & 0x02) << 9;
240
241 drawgfx(tmpbitmap3,Machine->gfx[1],
242 c,
243 0,
244 b & 0x04,0,
245 8*sx,8*sy,
246 0,TRANSPARENCY_NONE_RAW,0);
247 }
248 }
249
250
251 /* Draw the sprites. Note that it is important to draw them exactly in this */
252 /* order, to have the correct priorities. */
253 fillbitmap(tmpbitmap2,0,&Machine->visible_area);
254
255 for (offs = 0;offs < 0x30;offs++)
256 {
257 int x,y,flipx,flipy;
258 int b,c;
259
260
261 b = ((spriteram[offs+0x40] & 0x02) >> 1);
262 b = b | ((spriteram[offs+0x40] & 0x40) >> 5);
263 b = b | (spriteram[offs+0x40] & 0x04);
264
265 c = spriteram[offs] + (b * 256);
266 if (spriteram[offs+0x40] & 0x08) c |= 1; /* double height */
267
268 /* coordinates adjustments made to match screenshot */
269 x = spriteram[offs+0x100] + ((spriteram[offs+0x40] & 0x01) << 8) - 2;
270 y = 240-spriteram[offs+0x80] + 1;
271 flipx = spriteram[offs+0x40] & 0x10;
272 flipy = spriteram[offs+0x40] & 0x20;
273
274 drawgfx(tmpbitmap2,Machine->gfx[2],
275 c,
276 0,
277 flipx,flipy,
278 x,y,
279 &Machine->visible_area,TRANSPARENCY_PEN_RAW,0);
280
281 if (spriteram[offs+0x40] & 0x08) /* double height */
282 drawgfx(tmpbitmap2,Machine->gfx[2],
283 c-1,
284 0,
285 flipx,flipy,
286 x,y-16,
287 &Machine->visible_area,TRANSPARENCY_PEN_RAW,0);
288 }
289
290
291 /* compose the three layers */
292 {
293 int x,y;
294 UINT8 *s1,*s2,*s3,*s3b;
295 UINT8 *prom = memory_region(REGION_PROMS) + smooth_table * 0x100;
296
297
298 if (bitmap->depth == 16)
299 {
300 for (y = 0;y < bitmap->height;y++)
301 {
302 UINT16 *d = (UINT16 *)bitmap->line[y];
303
304 s1 = tmpbitmap->line[y];
305 s2 = tmpbitmap2->line[y];
306 s3 = tmpbitmap3->line[((y + jedi_vscroll) & 0x1ff) / 2];
307 s3b = tmpbitmap3->line[((y + jedi_vscroll - 1) & 0x1ff) / 2];
308
309 for (x = 0;x < bitmap->width;x++)
310 {
311 int tl,tr,bl,br,mixt,mixb,mix;
312
313 tr = s3b[((x + jedi_hscroll + 1) & 0x1ff) / 2];
314 br = s3 [((x + jedi_hscroll + 1) & 0x1ff) / 2];
315
316 if ((x + jedi_hscroll) & 1)
317 {
318 tl = s3b[((x + jedi_hscroll) & 0x1ff) / 2];
319 bl = s3 [((x + jedi_hscroll) & 0x1ff) / 2];
320 mixt = prom[16 * tl + tr];
321 mixb = prom[16 * bl + br];
322 mix = prom[0x400 + 16 * mixt + mixb];
323 }
324 else
325 mix = prom[0x400 + 16 * tr + br];
326
327 *(d++) = Machine->pens[(*(s1++) << 8) | (*(s2++) << 4) | mix ];
328 }
329 }
330 }
331 else
332 {
333 for (y = 0;y < bitmap->height;y++)
334 {
335 UINT8 *d = bitmap->line[y];
336
337 s1 = tmpbitmap->line[y];
338 s2 = tmpbitmap2->line[y];
339 s3 = tmpbitmap3->line[((y + jedi_vscroll) & 0x1ff) / 2];
340 s3b = tmpbitmap3->line[((y + jedi_vscroll - 1) & 0x1ff) / 2];
341
342 for (x = 0;x < bitmap->width;x++)
343 {
344 int tl,tr,bl,br,mixt,mixb,mix;
345
346 tr = s3b[((x + jedi_hscroll + 1) & 0x1ff) / 2];
347 br = s3 [((x + jedi_hscroll + 1) & 0x1ff) / 2];
348
349 if ((x + jedi_hscroll) & 1)
350 {
351 tl = s3b[((x + jedi_hscroll) & 0x1ff) / 2];
352 bl = s3 [((x + jedi_hscroll) & 0x1ff) / 2];
353 mixt = prom[16 * tl + tr];
354 mixb = prom[16 * bl + br];
355 mix = prom[0x400 + 16 * mixt + mixb];
356 }
357 else
358 mix = prom[0x400 + 16 * tr + br];
359
360 *(d++) = Machine->pens[(*(s1++) << 8) | (*(s2++) << 4) | mix ];
361 }
362 }
363 }
364 }
365 }
366