1 #define NEW_DRAWSPRITE 1
2 /* System 32 Video Hardware */
3
4 /* todo:
5
6 add linezoom, clipping window effects on bg tilemaps
7 fix sprite clipping effect? (outside area clip)
8 fix / improve alphablending
9 fix alphablending enable, amount etc. (sonic almost certainly shouldn't have it enabled ?)
10 fix / add row-select, linescroll
11 fix priorities properly (will need vmixer)
12 find rad rally title screen background
13 remaining colour problems (sonic?)
14 solid flag on tiles? (rad rally..)
15 background colour
16 any remaining glitches
17
18 */
19
20 #include "driver.h"
21 #define MAX_COLOURS (16384)
22
23 /* Debugging flags and kludges*/
24 extern int system32_temp_kludge;
25 int priloop;
26
27 extern int multi32;
28
29 extern data16_t *sys32_spriteram16;
30 data8_t *sys32_spriteram8; /* I maintain this to make drawing ram based sprites easier */
31 extern data16_t *system32_mixerregs[2]; /* mixer registers*/
32 data16_t *sys32_videoram;
33 data32_t *multi32_videoram;
34 data8_t sys32_ramtile_dirty[0x1000];
35 extern data16_t sys32_displayenable;
36 extern data16_t sys32_tilebank_external;
37 data16_t sys32_old_tilebank_external;
38
39 int sys32_tilebank_internal;
40 int sys32_old_tilebank_internal;
41
42 int sys32_paletteshift[4];
43 int sys32_palettebank[4];
44 int sys32_old_paletteshift[4];
45 int sys32_old_palettebank[4];
46
47 extern int system32_mixerShift;
48 int system32_screen_mode;
49 int system32_screen_old_mode;
50 int system32_allow_high_resolution;
51 static int sys32_old_brightness[2][3];
52 int sys32_brightness[2][3];
53
54 data8_t system32_dirty_window[0x100];
55 data8_t system32_windows[4][4];
56 data8_t system32_old_windows[4][4];
57
58 /* these are the various attributes a sprite can have, will decide which need to be global later, maybe put them in a struct */
59
60 static int sys32sprite_indirect_palette;
61 static int sys32sprite_indirect_interleave;
62 static int sys32sprite_is_shadow;
63 static int sys32sprite_rambasedgfx;
64 static int sys32sprite_8bpp;
65 static int sys32sprite_draw_colour_f;
66 static int sys32sprite_yflip;
67 static int sys32sprite_xflip;
68 static int sys32sprite_use_yoffset;
69 static int sys32sprite_use_xoffset;
70 static int sys32sprite_yalign;
71 static int sys32sprite_xalign;
72 static int sys32sprite_rom_height;
73 static int sys32sprite_rom_width;
74 static int sys32sprite_rom_bank_low;
75 static int sys32sprite_unknown_1;
76 static int sys32sprite_unknown_2;
77 /*static int sys32sprite_solid;*/
78 static int sys32sprite_screen_height;
79 static int sys32sprite_unknown_3;
80 static int sys32sprite_rom_bank_high;
81 static int sys32sprite_unknown_4;
82 static int sys32sprite_unknown_5;
83 static int sys32sprite_rom_bank_mid;
84 static int sys32sprite_screen_width;
85 static int sys32sprite_ypos;
86 static int sys32sprite_xpos;
87 static int sys32sprite_rom_offset;
88 static int sys32sprite_palette;
89 static int sys32sprite_monitor_select; /* multi32*/
90 static int sys32sprite_priority;
91
92 static data16_t *sys32sprite_table;
93
94 static int spritenum; /* used to go through the sprite list */
95 static int jump_x, jump_y; /* these are set during a jump command and sometimes used by the sprites afterwards */
96 static data16_t *spritedata_source; /* a pointer into spriteram */
97
98 #if !NEW_DRAWSPRITE
99 static UINT32 sys32sprite_x_zoom;
100 static UINT32 sys32sprite_y_zoom;
101 #else
102 static int sys32mon_old4, sys32mon_old8;
103 #endif
104
105 /*
106
107 this actually draws the sprite, and could probably be optimized quite a bit ;-)
108 currently zooming isn't supported etc.
109
110 */
111 #if NEW_DRAWSPRITE
112
113 /** AT050703 new drawsprite (unproven, general testing required)*/
system32_draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect)114 static INLINE void system32_draw_sprite ( struct mame_bitmap *bitmap, const struct rectangle *cliprect )
115 {
116 #define FP 20
117 #define FPONE (1<<FP)
118 #define FPHALF (1<<(FP-1))
119
120 /* FP entry vaule(FPENT) should normally be 0.5(FPHALF) but it causes sprite gaps occationally.*/
121 #define FPENT 0
122
123 static UINT32 idp_cache8[256];
124 static UINT32 idp_cache4[16];
125 static data16_t *idp_base, *idb_old=0;
126 static int idi_old=-1;
127
128 /* one-time*/
129 int src_fw, src_fh;
130 int dst_minx, dst_maxx, dst_miny, dst_maxy;
131 int dst_skipx, dst_skipy, dst_x, dst_y, dst_lastx, dst_lasty; /* Buy Warren Spector's Deus Ex2. It's cool.*/
132 int flipx, flipy;
133
134 /* inner loop*/
135 UINT8 *src_ptr;
136 register int edx, eax, ecx;
137 int src_fx, src_fdx, transparent_pen;
138 UINT32 *pal_base;
139 UINT32 *dst_ptr;
140
141 /* outter loop*/
142 int src_fby, src_fdy;
143 int dst_pitch;
144 int src_pitch, src_fbx;
145 UINT8 *src_base;
146 int dst_w, dst_h;
147
148
149 /* fill internal data structure with default values*/
150 src_base = memory_region(REGION_GFX2);
151 src_pitch = sys32sprite_rom_width;
152 src_fw = sys32sprite_rom_width;
153 src_fh = sys32sprite_rom_height;
154
155 idp_base = sys32sprite_table;
156 pal_base = Machine->gfx[0]->colortable;
157
158 dst_ptr = bitmap->base;
159 dst_pitch = bitmap->rowpixels;
160 dst_minx = cliprect->min_x;
161 dst_maxx = cliprect->max_x;
162 dst_miny = cliprect->min_y;
163 dst_maxy = cliprect->max_y;
164 dst_x = sys32sprite_xpos;
165 dst_y = sys32sprite_ypos;
166 dst_w = sys32sprite_screen_width;
167 dst_h = sys32sprite_screen_height;
168
169 flipx = sys32sprite_xflip;
170 flipy = sys32sprite_yflip;
171 transparent_pen = 0;
172
173 /* cull zero dimension and off-screen objects*/
174 if (!src_fw || !src_fh || !dst_w || !dst_h) return;
175 if (dst_x > dst_maxx || dst_y > dst_maxy) return;
176 dst_lastx = dst_x + dst_w - 1;
177 if (dst_lastx < dst_minx) return;
178 dst_lasty = dst_y + dst_h - 1;
179 if (dst_lasty < dst_miny) return;
180
181 /* calculate zoom factors*/
182 src_fw <<= FP;
183 src_fh <<= FP;
184 src_fdx = src_fw / dst_w;
185 src_fdy = src_fh / dst_h;
186
187 /* clip destination*/
188 dst_skipx = 0;
189 eax = dst_minx; if ((eax -= dst_x) > 0) { dst_skipx = eax; dst_w -= eax; dst_x = dst_minx; }
190 eax = dst_lastx; if ((eax -= dst_maxx) > 0) dst_w -= eax;
191 dst_skipy = 0;
192 eax = dst_miny; if ((eax -= dst_y) > 0) { dst_skipy = eax; dst_h -= eax; dst_y = dst_miny; }
193 eax = dst_lasty; if ((eax -= dst_maxy) > 0) dst_h -= eax;
194
195 /* clip source (precision loss from MUL after DIV is intentional to maintain pixel consistency)*/
196 if (flipx)
197 {
198 src_fbx = src_fw - FPENT - 1;
199 src_fdx = -src_fdx;
200 }
201 else src_fbx = FPENT;
202 src_fbx += dst_skipx * src_fdx;
203 if (flipy)
204 {
205 src_fby = src_fh - FPENT - 1;
206 src_fdy = -src_fdy;
207 }
208 else src_fby = FPENT;
209 src_fby += dst_skipy * src_fdy;
210
211
212 /* modify oddities*/
213 /* if the gfx data is coming from RAM instead of ROM change the pointer*/
214 if (sys32sprite_rambasedgfx)
215 {
216 src_base = sys32_spriteram8;
217 sys32sprite_rom_offset &= 0x1ffff; /* right mask?*/
218 }
219
220 if (sys32sprite_monitor_select)
221 {
222 pal_base += MAX_COLOURS;
223 dst_x += system32_screen_mode ? 52*8 : 40*8;
224 }
225
226 if (!sys32sprite_8bpp)
227 {
228 src_pitch >>= 1;
229 if (!sys32sprite_draw_colour_f) transparent_pen = 0x0f;
230 }
231 else
232 if (!sys32sprite_draw_colour_f) transparent_pen = 0xff;
233
234 if (!sys32sprite_is_shadow)
235 {
236 if (sys32sprite_indirect_palette)
237 {
238 /* update indirect palette cache if necessary*/
239 if (!sys32sprite_8bpp)
240 {
241 if (idb_old != idp_base || sys32mon_old4 != sys32sprite_monitor_select)
242 {
243 idb_old = idp_base;
244 sys32mon_old4 = sys32sprite_monitor_select;
245
246 for (ecx=0; ecx<0x10; ecx+=2)
247 {
248 eax = idp_base[ecx]; edx = idp_base[ecx+1];
249 eax &= 0x0fff; edx &= 0x0fff; /* no apparent side-effect observed*/
250 eax = pal_base[eax]; edx = pal_base[edx];
251 idp_cache4[ecx] = eax; idp_cache4[ecx+1] = edx;
252 }
253 }
254 }
255 else
256 {
257 edx = *idp_base & 0xfff;
258 if (idi_old != edx || sys32mon_old8 != sys32sprite_monitor_select)
259 {
260 idi_old = edx;
261 sys32mon_old8 = sys32sprite_monitor_select;
262 pal_base += edx;
263
264 for (ecx=0; ecx<0x100; ecx+=2)
265 {
266 eax = pal_base[ecx]; edx = pal_base[ecx+1];
267 idp_cache8[ecx] = eax; idp_cache8[ecx+1] = edx;
268 }
269 }
270 }
271 }
272 else
273 pal_base += sys32sprite_palette<<4;
274 }
275 else
276 sys32sprite_indirect_palette = 0; /* make sure full-shadows and IDP's are mutually exclusive*/
277
278
279 /* adjust insertion points and pre-entry constants*/
280 src_base += sys32sprite_rom_offset;
281 dst_ptr += dst_y * dst_pitch + dst_x + dst_w;
282 dst_w = -dst_w;
283
284 ecx = src_fby;
285 src_fby += src_fdy;
286 ecx >>= FP;
287 src_ptr = src_base;
288 ecx *= src_pitch;
289 src_fx = src_fbx;
290 edx = src_fbx;
291 src_ptr += ecx;
292 ecx = dst_w;
293
294 if (!sys32sprite_8bpp)
295 {
296 /* 4bpp*/
297 edx >>= FP+1;
298
299 if (sys32sprite_indirect_palette)
300 {
301 do {
302 do {
303 eax = src_ptr[edx];
304 edx = src_fx;
305 if (src_fx & FPONE) eax &= 0xf; else eax >>= 4;
306 edx += src_fdx;
307 src_fx += src_fdx;
308 edx >>= FP+1;
309
310 if (!eax || eax == transparent_pen) continue;
311 if (eax != 0x0e)
312 dst_ptr[ecx] = idp_cache4[eax];
313 else
314 {
315 eax = dst_ptr[ecx];
316 eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
317 dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
318 }
319
320 } while (++ecx);
321
322 ecx = src_fby; src_fby += src_fdy;
323 ecx >>= FP; dst_ptr += dst_pitch;
324 ecx *= src_pitch; src_fx = src_fbx;
325 edx = src_fbx;
326 src_ptr = src_base; edx >>= FP+1;
327 src_ptr += ecx; ecx = dst_w;
328
329 } while (--dst_h);
330 }
331 else if (!sys32sprite_is_shadow)
332 {
333 do {
334 do {
335 eax = src_ptr[edx];
336 edx = src_fx;
337 if (src_fx & FPONE) eax &= 0xf; else eax >>= 4;
338 edx += src_fdx;
339 src_fx += src_fdx;
340 edx >>= (FP+1);
341
342 if (!eax || eax == transparent_pen) continue;
343 dst_ptr[ecx] = pal_base[eax];
344
345 } while (++ecx);
346
347 ecx = src_fby; src_fby += src_fdy;
348 ecx >>= FP; dst_ptr += dst_pitch;
349 ecx *= src_pitch; src_fx = src_fbx;
350 edx = src_fbx;
351 src_ptr = src_base; edx >>= FP+1;
352 src_ptr += ecx; ecx = dst_w;
353
354 } while (--dst_h);
355 }
356 else
357 {
358 do {
359 do {
360 eax = src_ptr[edx];
361 edx = src_fx;
362 if (src_fx & FPONE) eax &= 0xf; else eax >>= 4;
363 edx += src_fdx;
364 src_fx += src_fdx;
365 edx >>= (FP+1);
366
367 if (!eax || eax == transparent_pen) continue;
368 eax = dst_ptr[ecx];
369 eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
370 dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
371
372 } while (++ecx);
373
374 ecx = src_fby; src_fby += src_fdy;
375 ecx >>= FP; dst_ptr += dst_pitch;
376 ecx *= src_pitch; src_fx = src_fbx;
377 edx = src_fbx;
378 src_ptr = src_base; edx >>= FP+1;
379 src_ptr += ecx; ecx = dst_w;
380
381 } while (--dst_h);
382 }
383 }
384 else
385 {
386 /* 8bpp*/
387 edx >>= FP;
388 src_fx += src_fdx;
389
390 if (sys32sprite_indirect_palette)
391 {
392 do {
393 do {
394 eax = src_ptr[edx];
395 edx = src_fx;
396 src_fx += src_fdx;
397 edx >>= FP;
398
399 if (!eax || eax == 0xe0 || eax == transparent_pen) continue;
400 if (eax != 0xf0)
401 dst_ptr[ecx] = idp_cache8[eax];
402 else
403 {
404 eax = dst_ptr[ecx];
405 eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
406 dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
407 }
408
409 } while (++ecx);
410
411 ecx = src_fby; src_fby += src_fdy;
412 ecx >>= FP; dst_ptr += dst_pitch;
413 ecx *= src_pitch; src_fx = src_fbx;
414 edx = src_fbx; src_fx += src_fdx;
415 src_ptr = src_base; edx >>= FP;
416 src_ptr += ecx; ecx = dst_w;
417
418 } while (--dst_h);
419 }
420 else if (!sys32sprite_is_shadow)
421 {
422 do {
423 do {
424 eax = src_ptr[edx];
425 edx = src_fx;
426 src_fx += src_fdx;
427 edx >>= FP;
428
429 if (!eax || eax == transparent_pen) continue;
430 dst_ptr[ecx] = pal_base[eax];
431
432 } while (++ecx);
433
434 ecx = src_fby; src_fby += src_fdy;
435 ecx >>= FP; dst_ptr += dst_pitch;
436 ecx *= src_pitch; src_fx = src_fbx;
437 edx = src_fbx; src_fx += src_fdx;
438 src_ptr = src_base; edx >>= FP;
439 src_ptr += ecx; ecx = dst_w;
440
441 } while (--dst_h);
442 }
443 else
444 {
445 do {
446 do {
447 eax = src_ptr[edx];
448 edx = src_fx;
449 src_fx += src_fdx;
450 edx >>= FP;
451
452 if (!eax || eax == transparent_pen) continue;
453 eax = dst_ptr[ecx];
454 eax = (eax>>9&0x7c00) | (eax>>6&0x03e0) | (eax>>3&0x001f);
455 dst_ptr[ecx] = ((UINT32*)palette_shadow_table)[eax];
456
457 } while (++ecx);
458
459 ecx = src_fby; src_fby += src_fdy;
460 ecx >>= FP; dst_ptr += dst_pitch;
461 ecx *= src_pitch; src_fx = src_fbx;
462 edx = src_fbx; src_fx += src_fdx;
463 src_ptr = src_base; edx >>= FP;
464 src_ptr += ecx; ecx = dst_w;
465
466 } while (--dst_h);
467 }
468 }
469 #undef FP
470 #undef FPONE
471 #undef FPHALF
472 #undef FPENT
473 }
474
475 #else
476
477 /* old drawsprite (working and proven)*/
system32_draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect)478 void system32_draw_sprite ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) {
479 data8_t *sprite_gfxdata = memory_region ( REGION_GFX2 );
480 UINT32 xsrc,ysrc;
481 UINT32 xdst,ydst;
482 /* um .. probably a better way to do this */
483 struct GfxElement *gfx=Machine->gfx[0];
484 const pen_t *paldata = &gfx->colortable[0];
485
486 /* if the gfx data is coming from RAM instead of ROM change the pointer */
487 if ( sys32sprite_rambasedgfx ) {
488 sprite_gfxdata = sys32_spriteram8;
489 sys32sprite_rom_offset &= 0x1ffff; /* right mask? */
490 }
491
492 ysrc = 0;
493 ydst = 0;
494
495 while ( ysrc < (sys32sprite_rom_height<<16) ) {
496 int drawypos;
497 xsrc = 0;
498 xdst = 0;
499
500 if (!sys32sprite_yflip) {
501 drawypos = sys32sprite_ypos+ydst; /* no flip*/
502 if (drawypos > cliprect->max_y) ysrc = sys32sprite_rom_height<<16; /* quit drawing if we've gone off the right*/
503 }
504 else {
505 drawypos = sys32sprite_ypos+((sys32sprite_screen_height-1)-ydst); /* y flip*/
506 if (drawypos < cliprect->min_y) ysrc = sys32sprite_rom_height<<16; /* quit drawing if we've gone off the left on a flipped sprite*/
507 }
508
509 if ((drawypos >= cliprect->min_y) && (drawypos <= cliprect->max_y)) {
510 UINT32 *destline = (bitmap->line[drawypos]);
511
512 while ( xsrc < (sys32sprite_rom_width<<16) ) {
513
514 int drawxpos;
515
516 if (!sys32sprite_xflip) {
517 drawxpos = sys32sprite_xpos+xdst; /* no flip*/
518 if (drawxpos > cliprect->max_x) xsrc = sys32sprite_rom_width<<16; /* quit drawing if we've gone off the right*/
519 }
520 else {
521 drawxpos = sys32sprite_xpos+((sys32sprite_screen_width-1)-xdst); /* x flip*/
522 if (drawxpos < cliprect->min_x) xsrc = sys32sprite_rom_width<<16; /* quit drawing if we've gone off the left on a flipped sprite*/
523 }
524
525 if ((drawxpos >= cliprect->min_x) && (drawxpos <= cliprect->max_x)) {
526 int gfxdata;
527 int data;
528 int r,g,b;
529
530 if (sys32sprite_monitor_select) drawxpos+=system32_screen_mode?52*8:40*8;
531 if (!sys32sprite_8bpp) { /* 4bpp*/
532 gfxdata = (sprite_gfxdata[sys32sprite_rom_offset+((xsrc>>16)/2)+(ysrc>>16)*(sys32sprite_rom_width/2)]);
533
534 if (xsrc & 0x10000) gfxdata = gfxdata & 0x0f;
535 else gfxdata = (gfxdata & 0xf0) >> 4;
536
537 if ( (!sys32sprite_draw_colour_f && gfxdata == 0x0f) ) gfxdata = 0;
538 if (sys32sprite_indirect_palette) {
539 switch (gfxdata) {
540 case 0x00:
541 break;
542
543 case 0x0f: /* Transparent*/
544 break;
545
546 case 0x0e: /* Shadow*/
547 data=destline[drawxpos];
548
549 r = ((data >> 16) & 0xff)*0.5;
550 g = ((data >> 8) & 0xff)*0.5;
551 b = ((data >> 0) & 0xff)*0.5;
552
553 destline[drawxpos] = MAKE_RGB(r,g,b);
554 break;
555
556 default:
557 destline[drawxpos] = paldata[(sys32sprite_table[gfxdata] & 0xfff)+(sys32sprite_monitor_select*MAX_COLOURS)];
558 break;
559 }
560 }
561 else {
562 if (sys32sprite_is_shadow) {
563 data=destline[drawxpos];
564
565 r = ((data >> 16) & 0xff)*0.5;
566 g = ((data >> 8) & 0xff)*0.5;
567 b = ((data >> 0) & 0xff)*0.5;
568
569 if (gfxdata) destline[drawxpos] = MAKE_RGB(r,g,b);
570 }
571 else {
572
573 switch (gfxdata) {
574 case 0x00:
575 break;
576 default:
577 destline[drawxpos] = paldata[gfxdata + (sys32sprite_palette * 16)+(sys32sprite_monitor_select*MAX_COLOURS)];
578 break;
579 }
580
581 }
582 }
583 }
584 else { /* 8bpp*/
585 gfxdata = (sprite_gfxdata[sys32sprite_rom_offset+(xsrc>>16)+(ysrc>>16)*(sys32sprite_rom_width)]);
586
587 if ( (!sys32sprite_draw_colour_f) && (gfxdata == 0xff) ) gfxdata = 0;
588
589 if (sys32sprite_indirect_palette) {
590 switch (gfxdata) {
591 case 0x00:
592 break;
593 case 0xe0: /* Transparent*/
594 break;
595 case 0xf0: /* Shadow*/
596 data=destline[drawxpos];
597
598 r = ((data >> 16) & 0xff)*0.5;
599 g = ((data >> 8) & 0xff)*0.5;
600 b = ((data >> 0) & 0xff)*0.5;
601
602 destline[drawxpos] = MAKE_RGB(r,g,b);
603 break;
604 default:
605 destline[drawxpos] = paldata[gfxdata+(sys32sprite_table[0] & 0xfff)+sys32sprite_monitor_select*MAX_COLOURS];
606 break;
607 }
608 }
609 else {
610 if (sys32sprite_is_shadow) {
611 data=destline[drawxpos];
612
613 r = ((data >> 16) & 0xff)*0.5;
614 g = ((data >> 8) & 0xff)*0.5;
615 b = ((data >> 0) & 0xff)*0.5;
616
617 if (gfxdata) destline[drawxpos] = MAKE_RGB(r,g,b);
618 }
619 else {
620 if (gfxdata) destline[drawxpos] = paldata[gfxdata + (sys32sprite_palette * 16)+sys32sprite_monitor_select*MAX_COLOURS];
621 }
622 }
623 } /* bpp */
624 } /* xclipping */
625 xsrc+=sys32sprite_x_zoom;
626 xdst++;
627 }
628 }
629 ysrc+=sys32sprite_y_zoom;
630 ydst++;
631 }
632 }
633
634 #endif
635
636 /* system32_get_sprite_info
637
638 this function is used to get information on the sprite from spriteram and call the
639 drawing functions
640
641 spriteram Sprite Entry layout
642
643 0: ffffffff ffffffff 1: HHHHHHHH WWWWWWWW 2: hhhhhhhh hhhhhhhh 3: wwwwwwww wwwwwwww
644 4: yyyyyyyy yyyyyyyy 5: xxxxxxxx xxxxxxxx 6: rrrrrrrr rrrrrrrr 7: pppppppp pppppppp
645
646 f = various flags
647 xx------ -------- (0xc000) : Command (00 for a sprite, other values would mean this isn't a sprite)
648 --x----- -------- (0x2000) : Sprite uses Indirect Palette (TRUSTED)
649 ---x---- -------- (0x1000) : Sprite uses Indirect Palette which is Interleaved in Spritelist (GA2?)
650 ----x--- -------- (0x0800) : Sprite is a shadow. Uses upper 16 values of the sprite priority table
651 -----x-- -------- (0x0400) : Sprite GFX data comes from Spriteram, not ROM (TRUSTED)
652 ------x- -------- (0x0200) : Sprite is 8bpp not 4bpp (TRUSTED)
653 -------x -------- (0x0100) : If NOT set colour in palette 0x0f is transparent (TRUSTED)
654 -------- x------- (0x0080) : Sprite Y-Flip (TRUSTED)
655 -------- -x------ (0x0040) : Sprite X-Flip (TRUSTED)
656 -------- --x----- (0x0020) : Use Y offset (offset set in last jump) (not trusted)
657 -------- ---x---- (0x0010) : Use X offset (offset set in last jump) (TRUSTED)
658 -------- ----xx-- (0x000c) : Y alignment. 00=Center, 10=Start, 01=End (TRUSTED)
659 -------- ------xx (0x0003) : X alignment. 00=Center, 10=Start, 01=End (TRUSTED)
660
661 H = height of sprite in ROM
662 W = width of sprite in ROM (multiply by 4 to get screen width)
663
664 System32:
665 w = width to draw on SCREEN + extra attributes
666 x------- -------- (0x8000) : unknown
667 -x------ -------- (0x4000) : Bit 5 of Sprite ROM Bank (TRUSTED)
668 --x----- -------- (0x2000) : unknown
669 ---x---- -------- (0x1000) : unknown
670 ----x--- -------- (0x0800) : Bit 4 of Sprite ROM Bank (TRUSTED)
671 -----xxx xxxxxxxx (0x07ff) : Width to draw on screen (TRUSTED)
672
673 Multi32:
674 w = width to draw on SCREEN + extra attributes
675 x------- -------- (0x8000) : bit 5 of the sprite bank (TRUSTED)
676 -x------ -------- (0x4000) : unknown
677 --x----- -------- (0x2000) : Bit 4 of the sprite bank (TRUSTED)
678 ---x---- -------- (0x1000) : unknown
679 ----x--- -------- (0x0800) : Monitor selection for this sprite (TRUSTED)
680 -----xxx xxxxxxxx (0x07ff) : Width to draw on screen (TRUSTED)
681 y = y-position (12-bit?, high bit = sign bit?)
682
683 x = x-position (12-bit, high bit = sign bit)
684
685 r = ROM Offset of GFX data (multiply by 4 to get real offset)
686
687 p = Palette & Priority bits, I think these change depending on the mode (Direct or Indirect)
688 DIRECT MODE *probably wrong, holoseum needed a kludge to work
689 xxxxx--- -------- (0xf800) : unknown
690 -----xxx xxxx---- (0x07f0) : palette #
691 -------- ----xxxx (0x000f) : unknown
692
693 */
694
695 /** AT050703: minor clean-up's*/
system32_get_sprite_info(struct mame_bitmap * bitmap,const struct rectangle * cliprect)696 static INLINE void system32_get_sprite_info ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) {
697 /* get attributes */
698 int mixerinput, sprite_palette_mask, sprite_priority_levels, sys32sprite_priority_lookup;
699
700 sys32sprite_indirect_palette = (spritedata_source[0]&0x2000) >> 13;
701 sys32sprite_indirect_interleave = (spritedata_source[0]&0x1000) >> 12;
702 sys32sprite_is_shadow = (spritedata_source[0]&0x0800) >> 11;
703 sys32sprite_rambasedgfx = (spritedata_source[0]&0x0400) >> 10;
704 sys32sprite_8bpp = (spritedata_source[0]&0x0200) >> 9;
705 sys32sprite_draw_colour_f = (spritedata_source[0]&0x0100) >> 8;
706 sys32sprite_yflip = (spritedata_source[0]&0x0080) >> 7;
707 sys32sprite_xflip = (spritedata_source[0]&0x0040) >> 6;
708 sys32sprite_use_yoffset = (spritedata_source[0]&0x0020) >> 5;
709 sys32sprite_use_xoffset = (spritedata_source[0]&0x0010) >> 4;
710 sys32sprite_yalign = (spritedata_source[0]&0x000c) >> 2;
711 sys32sprite_xalign = (spritedata_source[0]&0x0003) >> 0;
712
713 sys32sprite_rom_height = (spritedata_source[1]&0xff00) >> 8;
714 sys32sprite_rom_width = (spritedata_source[1]&0x00ff) >> 0;
715
716 sys32sprite_rom_bank_low = (spritedata_source[2]&0xf000) >> 12;
717 sys32sprite_unknown_1 = (spritedata_source[2]&0x0800) >> 11;
718 sys32sprite_unknown_2 = (spritedata_source[2]&0x0400) >> 10;
719 sys32sprite_screen_height = (spritedata_source[2]&0x03ff) >> 0;
720
721 if (multi32) {
722 sys32sprite_rom_bank_high = (spritedata_source[3]&0x8000) >> 15;
723 sys32sprite_unknown_3 = (spritedata_source[3]&0x4000) >> 14;
724 sys32sprite_rom_bank_mid = (spritedata_source[3]&0x2000) >> 13;
725 sys32sprite_unknown_4 = (spritedata_source[3]&0x1000) >> 12;
726 sys32sprite_monitor_select = (spritedata_source[3]&0x0800) >> 11;
727 }
728 else {
729 sys32sprite_unknown_3 = (spritedata_source[3]&0x8000) >> 15;
730 sys32sprite_rom_bank_high = (spritedata_source[3]&0x4000) >> 14;
731 sys32sprite_unknown_4 = (spritedata_source[3]&0x2000) >> 13;
732 sys32sprite_unknown_5 = (spritedata_source[3]&0x1000) >> 12;
733 sys32sprite_rom_bank_mid = (spritedata_source[3]&0x0800) >> 11;
734 sys32sprite_monitor_select = 0;
735 }
736 sys32sprite_screen_width = (spritedata_source[3]&0x07ff) >> 0;
737
738 sys32sprite_ypos = (spritedata_source[4]&0xffff) >> 0;
739
740 sys32sprite_xpos = (spritedata_source[5]&0xffff) >> 0;
741
742 sys32sprite_rom_offset = (spritedata_source[6]&0xffff) >> 0;
743
744 sprite_palette_mask=(1<<(system32_mixerShift+4))-1;
745 sprite_priority_levels=system32_mixerregs[sys32sprite_monitor_select][0x4d/2]&2?15:3;
746 mixerinput = (spritedata_source[7] >> (system32_mixerShift + 8)) & 0xf;
747 sys32sprite_palette = (spritedata_source[7] >> 4) & sprite_palette_mask;
748 sys32sprite_palette += (system32_mixerregs[sys32sprite_monitor_select][mixerinput] & 0x30)<<2;
749
750 /* process attributes */
751
752 sys32sprite_rom_width = sys32sprite_rom_width << 2;
753 sys32sprite_rom_offset = sys32sprite_rom_offset | (sys32sprite_rom_bank_low << 16) | (sys32sprite_rom_bank_mid << 20) | (sys32sprite_rom_bank_high << 21);
754 sys32sprite_rom_offset = sys32sprite_rom_offset << 2;
755
756 /* Determine the sprites palette and priority. The actual priority of the sprite is found by looking up
757 the sprite priority table in the mixer registers. The lookup value is found by reading the first colour
758 in the sprites palette in the case of indirect sprites. For direct sprites, the lookup value is found by
759 reading the sprite priority data.
760 */
761 if (sys32sprite_indirect_palette) {
762 if (sys32sprite_indirect_interleave) /* indirect mode where the table is included in the display list */
763 {
764 sys32sprite_table = spritedata_source+8;
765 spritenum+=2;
766 }
767 else /* indirect mode where the display list contains an offset to the table */
768 {
769 sys32sprite_table = sys32_spriteram16 + ((spritedata_source[7] & ((1<<(8+system32_mixerShift))-1))*8);
770 }
771 if (sys32sprite_table[0]==0xffff) sys32sprite_priority_lookup=1;
772 else sys32sprite_priority_lookup = (sys32sprite_table[0]>>(8+system32_mixerShift))&0xf;
773 }
774 else {
775 /* If all of the palette bits are set, the sprite is a shadow. This is a secondary
776 method to define sprite shadows alongside the sys32sprite_is_shadow bit.
777 Direct palette shadow sprites use the upper 16 values in the sprite priority lookup table. */
778 if (sprite_palette_mask==((spritedata_source[7]>>4)&sprite_palette_mask)) sys32sprite_is_shadow=1;
779 sys32sprite_priority_lookup = (spritedata_source[7]>>(system32_mixerShift+8))&0xf;
780 }
781
782 sys32sprite_priority = system32_mixerregs[sys32sprite_monitor_select][sys32sprite_priority_lookup&sprite_priority_levels]&0xf;
783 if (sys32sprite_is_shadow && ((!strcmp(Machine->gamedrv->name,"f1en")) || (!strcmp(Machine->gamedrv->name,"f1lap")))) sys32sprite_is_shadow=0; /* f1en turns this flag on the car sprites?*/
784
785 if (sys32sprite_use_yoffset) sys32sprite_ypos += jump_y;
786 if (sys32sprite_use_xoffset) sys32sprite_xpos += jump_x;
787
788 /* adjust positions according to offsets if used (radm, radr, alien3, darkedge etc.) */
789
790 /* adjust sprite positions based on alignment, pretty much straight from modeler */
791 switch (sys32sprite_xalign) {
792 case 0: /* centerX*/
793 case 3:
794 sys32sprite_xpos -= (sys32sprite_screen_width-1) / 2; /* this is trusted again spiderman truck door*/
795 break;
796 case 1: /* rightX*/
797 sys32sprite_xpos -= sys32sprite_screen_width - 1;
798 break;
799 case 2: /* leftX*/
800 break;
801 }
802
803 switch (sys32sprite_yalign) {
804 case 0: /* centerY*/
805 case 3:
806 sys32sprite_ypos -= (sys32sprite_screen_height-1) / 2; /* this is trusted against alien3 energy bars*/
807 break;
808 case 1: /* bottomY*/
809 sys32sprite_ypos -= sys32sprite_screen_height - 1;
810 break;
811 case 2: /* topY*/
812 break;
813 }
814
815 sys32sprite_xpos &= 0x0fff;
816 sys32sprite_ypos &= 0x0fff;
817
818 /* sprite positions are signed */
819 if (sys32sprite_ypos & 0x0800) sys32sprite_ypos -= 0x1000;
820 if (sys32sprite_xpos & 0x0800) sys32sprite_xpos -= 0x1000;
821
822 /* Inefficient sprite priority hack to get things working for now. Will change to arrays later.
823 Currently, draw_sprite is a lot more processor intensive and has a greater need for optimisation. */
824 if (priloop==sys32sprite_priority)
825 if (!multi32 || (multi32 && (readinputport(0xf)&(sys32sprite_monitor_select+1))>>sys32sprite_monitor_select))
826 system32_draw_sprite ( bitmap, cliprect );
827 }
828
829 /* Sprite RAM
830
831 each entry in the sprite list is 16 bytes (8 words)
832 the sprite list itself consists of 4 main different types of entry
833 a normal sprite
834
835 0: 00------ -------- 1: -------- -------- 2: -------- -------- 3: -------- --------
836 4: -------- -------- 5: -------- -------- 6: -------- -------- 7: -------- --------
837
838 (See Above for bit usage)
839
840 a command to set the clipping area
841
842 0: 01------ -------- 1: -------- -------- 2: -------- -------- 3: -------- --------
843 4: -------- -------- 5: -------- -------- 6: -------- -------- 7: -------- --------
844
845 (to be filled in later)
846
847 a jump command
848
849 0: 10ujjjjj jjjjjjjj 1: yyyyyyyy yyyyyyyy 2: xxxxxxxx xxxxxxxx 3: -------- --------
850 4: -------- -------- 5: -------- -------- 6: -------- -------- 7: -------- --------
851
852 u = set sprite offset positions with this jump (alien3 proves this test is needed)
853 j = sprite number to jump to
854 y = sprite y offset to use (? bits) (only set if u = 1)
855 x = sprite x offset to use (? bits) (only set if u = 1)
856
857 other bits unused / unknown
858
859 a terminate list command
860
861 0: 11------ -------- 1: -------- -------- 2: -------- -------- 3: -------- --------
862 4: -------- -------- 5: -------- -------- 6: -------- -------- 7: -------- --------
863
864 (other bits unused, list is terminated)
865
866 sprite ram can also contain palette look up data for the special indirect
867 palette modes, as well as sprite gfx data which is used instead of the gfx
868 in the roms if a bit in the sprite entry is set.
869
870 */
871
system32_process_spritelist(struct mame_bitmap * bitmap,const struct rectangle * cliprect)872 void system32_process_spritelist ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) {
873 int processed;
874 int command;
875 struct rectangle clip;
876
877 /* set clipping defaults */
878 clip.min_x = Machine->visible_area.min_x;
879 clip.max_x = Machine->visible_area.max_x;
880 clip.min_y = Machine->visible_area.min_y;
881 clip.max_y = Machine->visible_area.max_y;
882
883 processed = 0;
884 spritenum = 0;
885
886 while (spritenum < 0x20000/16) {
887 spritedata_source = sys32_spriteram16 + 8 * spritenum;
888
889 command = (spritedata_source[0] & 0xc000) >> 14;
890
891 switch (command) {
892 case 0x3: /* end of sprite list */
893 /* logerror ("SPRITELIST: terminated at sprite %06x\n", spritenum*16);*/
894 spritenum = 60000; /* just set a high sprite number so we stop processing */
895 break;
896 case 0x2: /* jump to position in sprite list*/
897 /* logerror ("SPRITELIST: jump at sprite %06x to %06x extra data 0 %04x 1 %04x, 2 %04x 3 %04x 4 %04x 5 %04x 6 %04x 7 %04x\n", spritenum*16, (spritedata_source[0] & 0x1fff)*16, spritedata_source[0] & 0x2000, spritedata_source[1], spritedata_source[2], spritedata_source[3] , spritedata_source[4] , spritedata_source[5] ,spritedata_source[6] , spritedata_source[7] );*/
898 spritenum = spritedata_source[0] & 0x1fff;
899 if (spritedata_source[0] & 0x2000) {
900 jump_y = spritedata_source[1];
901 jump_x = spritedata_source[2];
902 }
903 break;
904 case 0x1: /* set clipping registers */
905 /* logerror ("SPRITELIST: set clip regs at %06x extra data 0 %04x 1 %04x 2 %04x 3 %04x 4 %04x 5 %04x 6 %04x 7 %04x\n", spritenum*16, spritedata_source[0], spritedata_source[1],spritedata_source[2],spritedata_source[3],spritedata_source[4],spritedata_source[5],spritedata_source[6],spritedata_source[7] );*/
906 {
907
908 if (spritedata_source[0] & 0x3000) /* alien 3 needs something like this ... */
909 {
910 clip.min_y = spritedata_source[0]& 0x0fff;
911 clip.max_y = spritedata_source[1]& 0x0fff;
912 clip.min_x = spritedata_source[2]& 0x0fff;
913 clip.max_x = spritedata_source[3]& 0x0fff;
914
915 if (clip.max_y > Machine->visible_area.max_y) clip.max_y = Machine->visible_area.max_y;
916 if (clip.max_x > Machine->visible_area.max_x) clip.max_x = Machine->visible_area.max_x;
917 }
918 else {
919 clip.min_x = Machine->visible_area.min_x;
920 clip.max_x = Machine->visible_area.max_x;
921 clip.min_y = Machine->visible_area.min_y;
922 clip.max_y = Machine->visible_area.max_y;
923 }
924
925 }
926
927 spritenum ++;
928 break;
929 case 0x0: /* draw sprite */
930 /* logerror ("SPRITELIST: draw sprite at %06x\n", spritenum*16 );*/
931 system32_get_sprite_info (bitmap, &clip);
932 spritenum ++;
933 break;
934 }
935
936 processed++;
937 if (processed > 0x20000/16) /* its dead ;-) */
938 {
939 /* logerror ("SPRITELIST: terminated due to infinite loop\n");*/
940 spritenum = 16384;
941 };
942 }
943 }
944
945 /* 0x31ff00 - 0x31ffff are video registers
946
947 tile banking is controlled by a register in here as well as a register external to the tilemap chip
948 which is mapped at 0xc0000e
949
950 00 | rR-- -b-- ---- ---- | b = tile bank low bit ( | 0x2000 ), not multi-32 r = screen resolution R also resolution?
951 02 | ---- ---- ---- dddd | d = tilemap disable registers
952 04 | bbbb bbbb ???? SsRr S = layer 3 rowselect enable
953 s = layer 2 rowselect enable
954 R = layer 3 rowscroll enable
955 r = layer 2 rowscroll enable
956 b = table bases
957 jpark sets one of the ?
958 06 |
959 08 |
960 0a |
961 0c |
962 0e |
963 10 |
964 12 | scroll x for tilemap 0
965 14 |
966 16 | scroll y for tilemap 0
967 18 |
968 1a | scroll x for tilemap 1
969 1c |
970 1e | scroll y for tilemap 1
971 20 |
972 22 | scroll x for tilemap 2
973 24 |
974 26 | scroll y for tilemap 2
975 28 |
976 2a | scroll x for tilemap 3
977 2c |
978 2e | scroll y for tilemap 3
979 30 | scroll x offset tilemap 0
980 32 | scroll y offset tilemap 0
981 34 | scroll x offset tilemap 1
982 36 | scroll y offset tilemap 1
983 38 | scroll x offset tilemap 2
984 3a | scroll y offset tilemap 2
985 3c | scroll x offset tilemap 3
986 3e | scroll y offset tilemap 3
987 40 | pages 0 + 1 of tilemap 0
988 42 | pages 2 + 3 of tilemap 0
989 44 | pages 0 + 1 of tilemap 1
990 46 | pages 2 + 3 of tilemap 1
991 48 | pages 0 + 1 of tilemap 2
992 4a | pages 2 + 3 of tilemap 2
993 4c | pages 0 + 1 of tilemap 3
994 4e | pages 2 + 3 of tilemap 4
995 50 |
996 52 |
997 54 |
998 56 |
999 58 |
1000 5a |
1001 5c |
1002 5e |
1003 60 |
1004 62 |
1005 64 |
1006 66 |
1007 .... etc.. fill the rest in later
1008
1009 */
1010
1011
1012 /* Mixer Registers
1013
1014 00 ---- ---- ---- pppp p = Sprite Priority Table
1015 02 ---- ---- ---- pppp p = Sprite Priority Table
1016 04 ---- ---- ---- pppp p = Sprite Priority Table
1017 06 ---- ---- ---- pppp p = Sprite Priority Table
1018 08 ---- ---- ---- pppp p = Sprite Priority Table
1019 0a ---- ---- ---- pppp p = Sprite Priority Table
1020 0c ---- ---- ---- pppp p = Sprite Priority Table
1021 0e ---- ---- ---- pppp p = Sprite Priority Table
1022 10 ---- ---- ---- pppp p = Sprite shadow? Priority Table
1023 12 ---- ---- ---- pppp p = Sprite shadow? Priority Table
1024 14 ---- ---- ---- pppp p = Sprite shadow? Priority Table
1025 16 ---- ---- ---- pppp p = Sprite shadow? Priority Table
1026 18 ---- ---- ---- pppp p = Sprite shadow? Priority Table
1027 1a ---- ---- ---- pppp p = Sprite shadow? Priority Table
1028 1c ---- ---- ---- pppp p = Sprite shadow? Priority Table
1029 1e ---- ---- ---- pppp p = Sprite shadow? Priority Table
1030 20 ---- ---- ssss ssss s = Mixershift?
1031 22 ---- ssss bbbb pppp Tilemap Palette Base + Shifting, b = bank, s = shift p = priority 0
1032 24 ---- ssss bbbb pppp p = priority 1
1033 26 ---- ssss bbbb pppp p = priority 2
1034 28 ---- ssss bbbb pppp p = priority 3
1035 2a ---- ---- ---- f--- f = tilemap flip x 0
1036 2c ---- ---- ---- f--- f = tilemap flip x 1
1037 2e ---- ---- ---- f--- f = tilemap flip x 2
1038 30 ---- ---- ---- f--- f = tilemap flip x 3
1039 32 ---e ---- ---e ---- e = alpha enable 0
1040 34 ---e ---- ---e ---- e = alpha enable 1
1041 36 ---e ---- ---e ---- e = alpha enable 2
1042 38 ---e ---- ---e ---- e = alpha enable 3
1043 3a
1044 3c
1045 3e ---- ---- ---- ---w w = tilemap wrap disable?
1046 40 bbbb bbbb bbbb bbbb b = brightness (red)
1047 42 bbbb bbbb bbbb bbbb b = brightness (green)
1048 44 bbbb bbbb bbbb bbbb b = brightness (blue)
1049 46 bbbb bbbb bbbb bbbb b = brightness? (layer?) 2? or r ? (jpark)
1050 48 bbbb bbbb bbbb bbbb b = brightness? (layer?) 3? or g ? (jpark)
1051 4a bbbb bbbb bbbb bbbb b = brightness? (layer?) or b ? (jpark)
1052 4c ---- ---- ---- --l- l = number of sprite layers?16:4
1053 4e bbbb bbbb ---- ---- b = alpha blend amount?
1054
1055 */
1056
1057 /** AT050703: minor code shufflings*/
system32_draw_text_layer(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1058 void system32_draw_text_layer ( struct mame_bitmap *bitmap, const struct rectangle *cliprect ) /* using this for now to save me tilemap system related headaches */
1059 {
1060 int x,y;
1061 int textbank = sys32_videoram[0x01ff5c/2] & 0x0007;
1062 int tmaddress = (sys32_videoram[0x01ff5c/2] & 0x00f0) >> 4;
1063
1064 int monitor_select, monitor_offset;
1065 struct GfxElement *gfx = Machine->gfx[1];
1066 struct GfxLayout *gfxlayout = Machine->drv->gfxdecodeinfo[1].gfxlayout;
1067 data8_t *txtile_gfxregion = memory_region(REGION_GFX3);
1068 data16_t* tx_tilemapbase = sys32_videoram + ((0x10000+tmaddress*0x1000) /2);
1069
1070 if (multi32)
1071 {
1072 monitor_select = readinputport(0xf) & 3;
1073 monitor_offset = system32_screen_mode ? 52*8 : 40*8;
1074 }
1075 else
1076 {
1077 monitor_select = 1;
1078 monitor_offset = 0;
1079 }
1080
1081 /* this register is like this
1082
1083 ---- ---- tttt -bbb
1084
1085 t = address of tilemap data (used by dbzvrvs)
1086 b = address of tile gfx data (used by radmobile / radrally ingame, jpark)
1087
1088 */
1089
1090 for (y = 0; y < 32 ; y++) {
1091 for (x = 0; x < 64 ; x++) {
1092 int data=tx_tilemapbase[x+y*64];
1093 int code = data & 0x01ff;
1094 int pal = (data>>9) & 0x7f;
1095 int drawypos, flip;
1096
1097 pal += (((system32_mixerregs[0][0x10] & 0xf0) >> 4) * 0x40);
1098
1099 code += textbank * 0x200;
1100
1101 if (sys32_ramtile_dirty[code]) {
1102 decodechar(gfx, code, (data8_t*)txtile_gfxregion, gfxlayout);
1103 sys32_ramtile_dirty[code] = 0;
1104 }
1105
1106 if (system32_temp_kludge != 1) {
1107 drawypos = y*8;
1108 flip = 0;
1109 }
1110 else /* holoseum, actually probably requires the sprites to be globally flipped + game ROT180 not the tilemap */
1111 {
1112 drawypos = 215-y*8;
1113 flip = 1;
1114 }
1115
1116 if (monitor_select & 1)
1117 drawgfx(bitmap,gfx,code,pal,0,flip,(x<<3),drawypos,cliprect,TRANSPARENCY_PEN,0);
1118
1119 /* Multi32: Draw the same text on Monitor B*/
1120 if (monitor_select & 2)
1121 drawgfx(bitmap,gfx,code,pal,0,flip,(x<<3)+monitor_offset,drawypos,cliprect,TRANSPARENCY_PEN,0);
1122 }
1123 }
1124 }
1125
READ16_HANDLER(sys32_videoram_r)1126 READ16_HANDLER ( sys32_videoram_r ) {
1127 return sys32_videoram[offset];
1128 }
1129
WRITE16_HANDLER(sys32_videoram_w)1130 WRITE16_HANDLER ( sys32_videoram_w ) {
1131 data8_t *txtile_gfxregion = memory_region(REGION_GFX3);
1132
1133 COMBINE_DATA(&sys32_videoram[offset]);
1134
1135
1136 /* also write it to another region so its easier (imo) to work with the ram based tiles */
1137 if (ACCESSING_MSB)
1138 txtile_gfxregion[offset*2+1] = (data & 0xff00) >> 8;
1139
1140 if (ACCESSING_LSB)
1141 txtile_gfxregion[offset*2] = (data & 0x00ff );
1142
1143 /* each tile is 0x10 words */
1144 sys32_ramtile_dirty[offset / 0x10] = 1;
1145
1146 system32_dirty_window[offset>>9]=1;
1147
1148 }
1149
WRITE16_HANDLER(sys32_spriteram_w)1150 WRITE16_HANDLER ( sys32_spriteram_w ) {
1151
1152 COMBINE_DATA(&sys32_spriteram16[offset]);
1153
1154 /* also write it to another region so its easier to work with when drawing sprites with RAM based gfx */
1155 if (ACCESSING_MSB)
1156 sys32_spriteram8[offset*2+1] = (data & 0xff00) >> 8;
1157
1158 if (ACCESSING_LSB)
1159 sys32_spriteram8[offset*2] = (data & 0x00ff );
1160 }
1161
1162 /*
1163
1164 Tilemaps are made of 4 windows
1165
1166 each window is 32x16 in size
1167
1168 */
1169
sys32_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)1170 UINT32 sys32_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ) {
1171 int page = 0;
1172 if( row<16 ) { /* top */
1173 if( col<32 ) page = 0; else page = 1;
1174 }
1175 else { /* bottom */
1176 if( col<32 ) page = 2; else page = 3;
1177 }
1178
1179 return ((col & 31) + (row & 15) * 32) + page * 0x200;
1180
1181 }
1182
1183
1184 static struct tilemap *system32_layer_tilemap[4];
1185
get_system32_tile_info(int tile_index,int layer)1186 static void get_system32_tile_info ( int tile_index, int layer ) {
1187 int tileno, s32palette;
1188 int page;
1189 int yxflip;
1190 int monitor=multi32?layer%2:0;
1191
1192 page = tile_index >> 9;
1193
1194 tileno = sys32_videoram[(tile_index&0x1ff)+system32_windows[layer][page]*0x200];
1195 s32palette = ((tileno & 0x1ff0) >> (sys32_paletteshift[layer]+4));
1196 yxflip = (tileno & 0xc000)>>14;
1197
1198 tileno &= 0x1fff;
1199
1200 if (multi32) {
1201
1202 /*
1203 External tilebank register (0xc0000e)
1204
1205 -------- x------- Tilemap Layer 3 bank += 0x4000
1206 -------- -x------ Tilemap Layer 3 bank += 0x2000
1207 -------- --x----- Tilemap Layer 2 bank += 0x4000
1208 -------- ---x---- Tilemap Layer 2 bank += 0x2000
1209 -------- ----x--- Tilemap Layer 1 bank += 0x4000
1210 -------- -----x-- Tilemap Layer 1 bank += 0x2000
1211 -------- ------x- Tilemap Layer 0 bank += 0x4000
1212 -------- -------x Tilemap Layer 0 bank += 0x2000
1213 */
1214
1215 tileno|=(sys32_tilebank_external>>(layer*2)&3)*0x2000;
1216 }
1217 else {
1218 if (sys32_tilebank_internal) tileno |= 0x2000;
1219 if (sys32_tilebank_external&1) tileno |= 0x4000;
1220 }
1221
1222 /* Multi32: use palette_b for monitor 2*/
1223 SET_TILE_INFO(0,tileno,sys32_palettebank[layer]+s32palette+(monitor*MAX_COLOURS/0x10),TILE_FLIPYX(yxflip))
1224 }
1225
get_system32_layer0_tile_info(int tile_index)1226 static void get_system32_layer0_tile_info(int tile_index) {
1227 get_system32_tile_info(tile_index,0);
1228 }
get_system32_layer1_tile_info(int tile_index)1229 static void get_system32_layer1_tile_info(int tile_index) {
1230 get_system32_tile_info(tile_index,1);
1231 }
get_system32_layer2_tile_info(int tile_index)1232 static void get_system32_layer2_tile_info(int tile_index) {
1233 get_system32_tile_info(tile_index,2);
1234 }
get_system32_layer3_tile_info(int tile_index)1235 static void get_system32_layer3_tile_info(int tile_index) {
1236 get_system32_tile_info(tile_index,3);
1237 }
1238
VIDEO_START(system32)1239 VIDEO_START( system32 ) {
1240 int i;
1241
1242 system32_layer_tilemap[0] = tilemap_create(get_system32_layer0_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1243 tilemap_set_transparent_pen(system32_layer_tilemap[0],0);
1244 system32_layer_tilemap[1] = tilemap_create(get_system32_layer1_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1245 tilemap_set_transparent_pen(system32_layer_tilemap[1],0);
1246 system32_layer_tilemap[2] = tilemap_create(get_system32_layer2_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1247 tilemap_set_transparent_pen(system32_layer_tilemap[2],0);
1248 system32_layer_tilemap[3] = tilemap_create(get_system32_layer3_tile_info,sys32_bg_map,TILEMAP_TRANSPARENT, 16, 16,64,32);
1249 tilemap_set_transparent_pen(system32_layer_tilemap[3],0);
1250
1251 sys32_spriteram8 = auto_malloc ( 0x20000 ); /* for ram sprites*/
1252 sys32_videoram = auto_malloc ( 0x20000 );
1253
1254 for (i=0; i <= multi32; i++) {
1255 sys32_old_brightness[i][0] = 0;
1256 sys32_old_brightness[i][1] = 0;
1257 sys32_old_brightness[i][2] = 0;
1258 sys32_brightness[i][0] = 0xff;
1259 sys32_brightness[i][1] = 0xff;
1260 sys32_brightness[i][2] = 0xff;
1261 }
1262
1263 for (i = 0; i < 0x100; i++)
1264 system32_dirty_window[i] = 1;
1265
1266 return 0;
1267 }
1268
1269 void system32_set_colour (int offset);
1270 void multi32_set_colour (int offset, int monitor);
1271
system32_recalc_palette(int monitor)1272 static void system32_recalc_palette( int monitor ) {
1273 int i;
1274 for (i = 0; i < MAX_COLOURS; i++) {
1275 if (multi32) multi32_set_colour (i,monitor);
1276 else system32_set_colour(i);
1277 }
1278 }
1279
system32_draw_bg_layer(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer)1280 void system32_draw_bg_layer ( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer ) {
1281 int trans = 0;
1282 int alphaamount = 0;
1283 int rowscroll=0, rowselect=0;
1284 int monitor = multi32?layer%2:0;
1285 int monitor_res = 0;
1286 struct rectangle clip;
1287
1288 if ((system32_mixerregs[monitor][(0x32+2*layer)/2] & 0x1010) == 0x1010) {
1289 trans = TILEMAP_ALPHA;
1290 alphaamount = 255-((((system32_mixerregs[monitor][0x4e/2])>>8) & 7) <<5); /*umm this is almost certainly wrong*/
1291 alpha_set_level(alphaamount);
1292 }
1293
1294 /* rowselect / rowscroll
1295
1296 outrunners road - works ok
1297 svf pitch - works ok with tilemap flip / clipping hack
1298 brival floor - seems ok
1299 arabfgt floor - seems ok, bit shakey
1300 rad rally mirror - reasonable but doesn't scroll smoothly
1301 rad mobile backgrounds - wrong?
1302 sonic title screen background - ok
1303
1304 what effect does alien3 use? zooming instead?
1305 jurassic park enables rowscroll on one of the levels in the attract but its hard to see what for
1306
1307 */
1308
1309 if (layer == 2) {
1310 rowscroll = (sys32_videoram[0x01FF04/2] & 0x0001);
1311 rowselect = (sys32_videoram[0x01FF04/2] & 0x0004)>>2;
1312 }
1313
1314 if (layer == 3) {
1315 rowscroll = (sys32_videoram[0x01FF04/2] & 0x0002)>>1;
1316 rowselect = (sys32_videoram[0x01FF04/2] & 0x0008)>>3;
1317 }
1318
1319 /* Switch to Machine->visible_area.max_x later*/
1320 monitor_res=system32_screen_mode?52*8:40*8;
1321
1322 if (multi32) {
1323 /* clip.min_x = Machine->visible_area.min_x;*/
1324 /* clip.max_x = Machine->visible_area.max_x;*/
1325 clip.min_x = (layer%2)*monitor_res;
1326 clip.max_x = (layer%2+1)*monitor_res;
1327 clip.min_y = 0;
1328 clip.max_y = 28*8;
1329 }
1330 else {
1331 clip.min_x = Machine->visible_area.min_x;
1332 clip.max_x = Machine->visible_area.max_x;
1333 clip.min_y = Machine->visible_area.min_y;
1334 clip.max_y = Machine->visible_area.max_y;
1335 }
1336
1337 if (rowscroll || rowselect) {
1338 int line;
1339
1340 int tableaddress = sys32_videoram[0x01FF04/2]>>8;
1341
1342 tableaddress = (tableaddress * 0x200);
1343
1344 if ((system32_mixerregs[monitor][(0x32+layer*2)/2]&8)>>3) {
1345 if (layer==2) tilemap_set_flip(system32_layer_tilemap[layer], TILEMAP_FLIPX);
1346 }
1347
1348 for (line = 0; line < 224;line++) {
1349 int xscroll = (sys32_videoram[(0x01FF12+8*layer)/2]);
1350 int yscroll = (sys32_videoram[(0x01FF16+8*layer)/2]);
1351
1352 clip.min_y = clip.max_y = line;
1353
1354 if (rowscroll) xscroll+=(sys32_videoram[((tableaddress+(layer-2)*0x200)/2)+line]);
1355 if (rowselect) yscroll+=(sys32_videoram[((tableaddress+0x400+(layer-2)*0x200)/2)+line])-line;
1356
1357
1358 if ((system32_mixerregs[monitor][(0x32+layer*2)/2]&8)>>3) {
1359 /* disable wrap on this tilemap, should be done on the other too but its less important
1360 this is a bit messy because mame has no core functionality for this without resorting
1361 to tilemap_draw_roz which I can't do because of RGB_DIRECT, it might be wrong anyway,
1362 maybe its using the system32 clipping windows somehow */
1363 if (layer == 3) {
1364 int x2;
1365 x2 =xscroll&0x7ff;
1366 x2 = 0x7ff-x2;
1367 if (x2 > 0x3ff) clip.min_x = 0;
1368 else clip.min_x = x2;
1369 clip.max_x = 320-1;
1370 }
1371 }
1372 /* Multi32: Shift layer 3's rowscroll left one screen so that it lines up*/
1373 tilemap_set_scrollx(system32_layer_tilemap[layer],0, (xscroll & 0x3ff));
1374 tilemap_set_scrolly(system32_layer_tilemap[layer],0, (yscroll & 0x1ff));
1375 tilemap_set_scrolldx(system32_layer_tilemap[layer], (sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)+monitor*monitor_res, -(sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)-monitor*monitor_res);
1376 tilemap_set_scrolldy(system32_layer_tilemap[layer], sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff, -sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff);
1377 tilemap_draw(bitmap,&clip,system32_layer_tilemap[layer],trans,0);
1378 }
1379 }
1380 else {
1381 /* Multi32: Shift layer 3's rowscroll left one screen so that it lines up*/
1382 tilemap_set_scrollx(system32_layer_tilemap[layer],0,((sys32_videoram[(0x01FF12+8*layer)/2]) & 0x3ff));
1383 tilemap_set_scrolly(system32_layer_tilemap[layer],0,((sys32_videoram[(0x01FF16+8*layer)/2]) & 0x1ff));
1384 tilemap_set_scrolldx(system32_layer_tilemap[layer], (sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)+monitor*monitor_res, -(sys32_videoram[(0x01FF30+layer*4)/2]&0x00ff)-monitor*monitor_res);
1385 tilemap_set_scrolldy(system32_layer_tilemap[layer], sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff, -sys32_videoram[(0x01FF32+layer*4)/2]&0x00ff);
1386 tilemap_draw(bitmap,&clip,system32_layer_tilemap[layer],trans,0);
1387 }
1388 }
1389
VIDEO_UPDATE(system32)1390 VIDEO_UPDATE( system32 ) {
1391 int i;
1392
1393 int monitor_setting;
1394 int monitor_display_start;
1395 int monitor_display_width;
1396 int monitor_vertical_offset;
1397
1398 int sys32_tmap_disabled = sys32_videoram[0x1FF02/2] & 0x000f;
1399
1400 int priority0 = (system32_mixerregs[0][0x22/2] & 0x000f);
1401 int priority1 = (system32_mixerregs[multi32][0x24/2] & 0x000f);
1402 int priority2 = (system32_mixerregs[0][0x26/2] & 0x000f);
1403 int priority3 = (system32_mixerregs[multi32][0x28/2] & 0x000f);
1404 int sys32_palette_dirty[2] = {0, 0};
1405
1406 /* -------------------------------------- experimental wip code --------------------------------*/
1407 int tm,ii;
1408
1409 #if NEW_DRAWSPRITE
1410 /** force IDP recache*/
1411 sys32mon_old8 = sys32mon_old4 = -1;
1412 #endif
1413
1414 /* if the windows number used by a tilemap use change then that window of the tilemap needs to be considered dirty*/
1415 for (tm = 0; tm < 4; tm++) {
1416 system32_windows[tm][0] = (sys32_videoram[(0x01FF40+4*tm)/2] & 0x007f);
1417 system32_windows[tm][1] = (sys32_videoram[(0x01FF40+4*tm)/2] & 0x7f00)>>8;
1418 system32_windows[tm][2] = (sys32_videoram[(0x01FF42+4*tm)/2] & 0x007f);
1419 system32_windows[tm][3] = (sys32_videoram[(0x01FF42+4*tm)/2] & 0x7f00)>>8;
1420
1421 if (system32_windows[tm][0] != system32_old_windows[tm][0]) {
1422 for (ii = 0x000 ; ii < 0x200 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1423 }
1424 if (system32_windows[tm][1] != system32_old_windows[tm][1]) {
1425 for (ii = 0x200 ; ii < 0x400 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1426 }
1427 if (system32_windows[tm][2] != system32_old_windows[tm][2]) {
1428 for (ii = 0x400 ; ii < 0x600 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1429 }
1430 if (system32_windows[tm][3] != system32_old_windows[tm][3]) {
1431 for (ii = 0x600 ; ii < 0x800 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1432 }
1433
1434 /* if the actual windows are dirty we also need to mark them dirty in the tilemap*/
1435 if (system32_dirty_window [ system32_windows[tm][0] ]) {
1436 for (ii = 0x000 ; ii < 0x200 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1437 }
1438 if (system32_dirty_window [ system32_windows[tm][1] ]) {
1439 for (ii = 0x200 ; ii < 0x400 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1440 }
1441 if (system32_dirty_window [ system32_windows[tm][2] ]) {
1442 for (ii = 0x400 ; ii < 0x600 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1443 }
1444 if (system32_dirty_window [ system32_windows[tm][3] ]) {
1445 for (ii = 0x600 ; ii < 0x800 ; ii++) tilemap_mark_tile_dirty(system32_layer_tilemap[tm],ii);
1446 }
1447
1448 system32_old_windows[tm][0] = system32_windows[tm][0];
1449 system32_old_windows[tm][1] = system32_windows[tm][1];
1450 system32_old_windows[tm][2] = system32_windows[tm][2];
1451 system32_old_windows[tm][3] = system32_windows[tm][3];
1452 }
1453
1454 /* we can clean the dirty window markers now*/
1455 for (ii = 0; ii < 0x100; ii++)
1456 system32_dirty_window[ii] = 0;
1457
1458 /* if the internal tilebank changed everything is dirty*/
1459 sys32_tilebank_internal = sys32_videoram[0x01FF00/2] & 0x0400;
1460 if (sys32_tilebank_internal != sys32_old_tilebank_internal) {
1461 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[0]);
1462 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[1]);
1463 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[2]);
1464 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[3]);
1465 }
1466 sys32_old_tilebank_internal = sys32_tilebank_internal;
1467
1468 /* if the external tilebank changed everything is dirty*/
1469
1470 if ( (sys32_tilebank_external) != sys32_old_tilebank_external ) {
1471 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[0]);
1472 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[1]);
1473 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[2]);
1474 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[3]);
1475 }
1476 sys32_old_tilebank_external = sys32_tilebank_external;
1477
1478 /* if the palette shift /bank registers changed the tilemap is dirty, not sure these are regs 100% correct some odd colours in sonic / jpark*/
1479 for (tm = 0; tm < 4; tm++) {
1480 int monitor=multi32?tm%2:0;
1481 sys32_paletteshift[tm] = (system32_mixerregs[monitor][(0x22+tm*2)/2] & 0x0f00)>>8;
1482 if (sys32_paletteshift[tm] != sys32_old_paletteshift[tm]) {
1483 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[tm]);
1484 sys32_old_paletteshift[tm] = sys32_paletteshift[tm];
1485 }
1486
1487 sys32_palettebank[tm] = ((system32_mixerregs[monitor][(0x22+tm*2)/2] & 0x00f0)>>4)*0x40;
1488 if (sys32_palettebank[tm] != sys32_old_palettebank[tm]) {
1489 tilemap_mark_all_tiles_dirty(system32_layer_tilemap[tm]);
1490 sys32_old_palettebank[tm] = sys32_palettebank[tm];
1491 }
1492 }
1493 /*---------------------------------------- end wip code -----------------------------------------------*/
1494
1495 /* palette dirty check */
1496
1497 for (i=0; i <= multi32; i++) {
1498 sys32_brightness[i][0] = (system32_mixerregs[i][0x40/2]);
1499 sys32_brightness[i][1] = (system32_mixerregs[i][0x42/2]);
1500 sys32_brightness[i][2] = (system32_mixerregs[i][0x44/2]);
1501
1502 if (sys32_brightness[i][0] != sys32_old_brightness[i][0]) {
1503 sys32_old_brightness[i][0] = sys32_brightness[i][0]; sys32_palette_dirty[i] = 1;
1504 }
1505 if (sys32_brightness[i][1] != sys32_old_brightness[i][1]) {
1506 sys32_old_brightness[i][1] = sys32_brightness[i][1]; sys32_palette_dirty[i] = 1;
1507 }
1508 if (sys32_brightness[i][2] != sys32_old_brightness[i][2]) {
1509 sys32_old_brightness[i][2] = sys32_brightness[i][2]; sys32_palette_dirty[i] = 1;
1510 }
1511
1512 if (sys32_palette_dirty[i]) {
1513 sys32_palette_dirty[i] = 0;
1514 system32_recalc_palette(i);
1515 }
1516 }
1517
1518 /* end palette dirty*/
1519
1520 system32_screen_mode = sys32_videoram[0x01FF00/2] & 0xc000; /* this should be 0x8000 according to modeler but then brival is broken? this way alien3 and arabfgt try to change when they shouldn't .. wrong register?*/
1521
1522 if (multi32) {
1523 monitor_setting=readinputport(0xf);
1524 monitor_vertical_offset=1;
1525 monitor_display_start=0;
1526 if (monitor_setting==2) monitor_display_start=1;
1527 if (monitor_setting==3) {
1528 monitor_vertical_offset=2;
1529 monitor_display_width=2;
1530 }
1531 else
1532 monitor_display_width=1+monitor_display_start;
1533 }
1534 else {
1535 monitor_display_start=0;
1536 monitor_display_width=1;
1537 monitor_vertical_offset=1;
1538 }
1539
1540 fillbitmap(bitmap, 0, 0);
1541
1542 if (system32_screen_mode && system32_allow_high_resolution) {
1543 set_visible_area(52*monitor_display_start*8, 52*8*monitor_display_width-1, 0, 28*8*monitor_vertical_offset-1);
1544 }
1545 else {
1546 set_visible_area(40*monitor_display_start*8, 40*8*monitor_display_width-1, 0, 28*8*monitor_vertical_offset-1);
1547 }
1548
1549 fillbitmap(bitmap, 0, 0);
1550
1551 /* Priority loop. Draw layers 1 and 3 on Multi32's Monitor B*/
1552 if (sys32_displayenable & 0x0002) {
1553 for (priloop=0; priloop < 0x10; priloop++) {
1554 if (priloop == priority0 && (!multi32 || (multi32 && (readinputport(0xf)&1)))) {
1555 if (!(sys32_tmap_disabled & 0x1)) system32_draw_bg_layer (bitmap,cliprect,0);
1556 }
1557 if (priloop == priority1 && (!multi32 || (multi32 && (readinputport(0xf)&2)>>1))) {
1558 if (!(sys32_tmap_disabled & 0x2)) system32_draw_bg_layer (bitmap,cliprect,1);
1559 }
1560 if (priloop == priority2 && (!multi32 || (multi32 && (readinputport(0xf)&1)))) {
1561 if (!(sys32_tmap_disabled & 0x4)) system32_draw_bg_layer (bitmap,cliprect,2);
1562 }
1563 if (priloop == priority3 && (!multi32 || (multi32 && (readinputport(0xf)&2)>>1))) {
1564 if (!(sys32_tmap_disabled & 0x8)) system32_draw_bg_layer (bitmap,cliprect,3);
1565 }
1566 system32_process_spritelist (bitmap, cliprect);
1567 }
1568 }
1569 system32_draw_text_layer (bitmap, cliprect);
1570 }
1571