1 /***************************************************************************
2
3 Sega System 16 Video Hardware
4
5 Each scrolling layer (foreground, background) is an arrangement
6 of 4 pages selected from 16 available pages, laid out as follows:
7
8 Page0 Page1
9 Page2 Page3
10
11 Each page is an arrangement of 8x8 tiles, 64 tiles wide, and 32 tiles high.
12
13 ***************************************************************************/
14 void dump_tilemap(void);
15
16 #include "driver.h"
17
18 //#define SYS16_DEBUG
19 //#define SPACEHARRIER_OFFSETS
20
21 // an attempt at fudging correct gamma for sys16 games, but I'm not sure that it's
22 // really worth using.
23 //#define GAMMA_ADJUST
24 #define TRANSPARENT_SHADOWS
25 #define MAXCOLOURS 8192
26
27 #ifdef TRANSPARENT_SHADOWS
28 #define ShadowColorsShift 8
29 UINT16 shade_table[MAXCOLOURS];
30 int sys16_sh_shadowpal;
31 #endif
32
33 int sys16_MaxShadowColors;
34 static int sys16_MaxShadowColors_Shift;
35
36 #define NUM_SPRITES 128
37
38 extern UINT8 *sys16_textram;
39 extern UINT8 *sys16_spriteram;
40 extern UINT8 *sys16_tileram; /* contains tilemaps for 16 pages */
41
42 static struct sprite_list *sprite_list;
43
44 /* video driver constants (potentially different for each game) */
45 int sys16_spritesystem;
46 int sys16_sprxoffset;
47 int sys16_bgxoffset;
48 int sys16_fgxoffset;
49 int *sys16_obj_bank;
50 int sys16_textmode;
51 int sys16_textlayer_lo_min;
52 int sys16_textlayer_lo_max;
53 int sys16_textlayer_hi_min;
54 int sys16_textlayer_hi_max;
55 int sys16_dactype;
56 int sys16_bg1_trans; // alien syn + sys18
57 int sys16_bg_priority_mode;
58 int sys16_fg_priority_mode;
59 int sys16_bg_priority_value;
60 int sys16_fg_priority_value;
61 int sys16_18_mode;
62 int sys16_spritelist_end;
63 int sys16_tilebank_switch;
64 int sys16_rowscroll_scroll;
65 int sys16_quartet_title_kludge;
66 extern void (* sys16_update_proc)( void );
67
68 /* video registers */
69 int sys16_tile_bank1;
70 int sys16_tile_bank0;
71 int sys16_refreshenable;
72 int sys16_clear_screen;
73 int sys16_bg_scrollx, sys16_bg_scrolly;
74 int sys16_bg_page[4];
75 int sys16_fg_scrollx, sys16_fg_scrolly;
76 int sys16_fg_page[4];
77
78 int sys16_bg2_scrollx, sys16_bg2_scrolly;
79 int sys16_bg2_page[4];
80 int sys16_fg2_scrollx, sys16_fg2_scrolly;
81 int sys16_fg2_page[4];
82
83 int sys18_bg2_active;
84 int sys18_fg2_active;
85 unsigned char *sys18_splittab_bg_x;
86 unsigned char *sys18_splittab_bg_y;
87 unsigned char *sys18_splittab_fg_x;
88 unsigned char *sys18_splittab_fg_y;
89
90 static int sys16_freezepalette;
91 static int sys16_palettedirty[MAXCOLOURS];
92
93 #ifdef SPACEHARRIER_OFFSETS
94 unsigned char *spaceharrier_patternoffsets;
95 #endif
96 unsigned char *gr_ver;
97 unsigned char *gr_hor;
98 unsigned char *gr_pal;
99 unsigned char *gr_flip;
100 int gr_palette;
101 int gr_palette_default;
102 unsigned char gr_colorflip[2][4];
103 unsigned char *gr_second_road;
104
105 static struct tilemap *background, *foreground, *text_layer;
106 static struct tilemap *background2, *foreground2;
107 static int old_bg_page[4],old_fg_page[4], old_tile_bank1, old_tile_bank0;
108 static int old_bg2_page[4],old_fg2_page[4];
109
110 static void draw_quartet_title_screen( struct osd_bitmap *bitmap,int playfield );
111
112 /***************************************************************************/
113
sys16_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)114 UINT32 sys16_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
115 int page = 0;
116 if( row<32 ){ /* top */
117 if( col<64 ) page = 0; else page = 1;
118 }
119 else { /* bottom */
120 if( col<64 ) page = 2; else page = 3;
121 }
122 row = row%32;
123 col = col%64;
124 return page*64*32+row*64+col;
125 }
126
sys16_text_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)127 UINT32 sys16_text_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
128 return row*64+col+(64-40);
129 }
130
131 /***************************************************************************/
132
WRITE_HANDLER(sys16_paletteram_w)133 WRITE_HANDLER( sys16_paletteram_w ){
134 UINT16 oldword = READ_WORD (&paletteram[offset]);
135 UINT16 newword = COMBINE_WORD (oldword, data);
136 if( oldword!=newword ){
137 /* we can do this, because we initialize palette RAM to all black in vh_start */
138 /* byte 0 byte 1 */
139 /* GBGR BBBB GGGG RRRR */
140 /* 5444 3210 3210 3210 */
141 UINT8 r = (newword & 0x00f)<<1;
142 UINT8 g = (newword & 0x0f0)>>2;
143 UINT8 b = (newword & 0xf00)>>7;
144 if( sys16_dactype == 0 ){
145 /* dac_type == 0 (from GCS file) */
146 if (newword&0x1000) r|=1;
147 if (newword&0x2000) g|=2;
148 if (newword&0x8000) g|=1;
149 if (newword&0x4000) b|=1;
150 }
151 else if( sys16_dactype == 1 ){
152 /* dac_type == 1 (from GCS file) Shinobi Only*/
153 if (newword&0x1000) r|=1;
154 if (newword&0x4000) g|=2;
155 if (newword&0x8000) g|=1;
156 if (newword&0x2000) b|=1;
157 }
158
159 #ifndef TRANSPARENT_SHADOWS
160 if( !sys16_freezepalette ){
161 palette_change_color( offset/2,
162 (r << 3) | (r >> 2), /* 5 bits red */
163 (g << 2) | (g >> 4), /* 6 bits green */
164 (b << 3) | (b >> 2) /* 5 bits blue */
165 );
166 }
167 else{
168 r=(r << 3) | (r >> 2); /* 5 bits red */
169 g=(g << 2) | (g >> 4); /* 6 bits green */
170 b=(b << 3) | (b >> 2); /* 5 bits blue */
171 sys16_palettedirty[offset/2]=0xff000000+(r<<16)+(g<<8)+b;
172 }
173 #else
174 if (Machine->scrbitmap->depth == 8){ /* 8 bit shadows */
175 if(!sys16_freezepalette){
176 palette_change_color( offset/2,
177 (r << 3) | (r >> 3), /* 5 bits red */
178 (g << 2) | (g >> 4), /* 6 bits green */
179 (b << 3) | (b >> 3) /* 5 bits blue */
180 );
181 }
182 else {
183 r=(r << 3) | (r >> 3); /* 5 bits red */
184 g=(g << 2) | (g >> 4); /* 6 bits green */
185 b=(b << 3) | (b >> 3); /* 5 bits blue */
186 sys16_palettedirty[offset/2]=0xff000000+(r<<16)+(g<<8)+b;
187 }
188 }
189 else {
190 if(!sys16_freezepalette){
191 r=(r << 3) | (r >> 2); /* 5 bits red */
192 g=(g << 2) | (g >> 4); /* 6 bits green */
193 b=(b << 3) | (b >> 2); /* 5 bits blue */
194
195 palette_change_color( offset/2,r,g,b);
196
197 /* shadow color */
198
199 r= r * 160 / 256;
200 g= g * 160 / 256;
201 b= b * 160 / 256;
202
203 palette_change_color( offset/2+Machine->drv->total_colors/2,r,g,b);
204 }
205 else {
206 r=(r << 3) | (r >> 3); /* 5 bits red */
207 g=(g << 2) | (g >> 4); /* 6 bits green */
208 b=(b << 3) | (b >> 3); /* 5 bits blue */
209 sys16_palettedirty[offset/2]=0xff000000+(r<<16)+(g<<8)+b;
210
211 r= r * 160 / 256;
212 g= g * 160 / 256;
213 b= b * 160 / 256;
214 sys16_palettedirty[offset/2+Machine->drv->total_colors/2]=0xff000000+(r<<16)+(g<<8)+b;
215 }
216 }
217 #endif
218 WRITE_WORD (&paletteram[offset], newword);
219 }
220 }
221
sys16_refresh_palette(void)222 static void sys16_refresh_palette(void){
223 UINT8 r,g,b;
224 int i;
225 for( i=0;i<Machine->drv->total_colors;i++ ){
226 if( sys16_palettedirty[i] ){
227 r=(sys16_palettedirty[i]&0x00ff0000) >> 16;
228 g=(sys16_palettedirty[i]&0x0000ff00) >> 8;
229 b=(sys16_palettedirty[i]&0x000000ff);
230 palette_change_color(i,r,g,b);
231 sys16_palettedirty[i]=0;
232 }
233 }
234 }
235
update_page(void)236 static void update_page( void ){
237 int all_dirty = 0;
238 int i,offset;
239 if( old_tile_bank1 != sys16_tile_bank1 ){
240 all_dirty = 1;
241 old_tile_bank1 = sys16_tile_bank1;
242 }
243 if( old_tile_bank0 != sys16_tile_bank0 ){
244 all_dirty = 1;
245 old_tile_bank0 = sys16_tile_bank0;
246 tilemap_mark_all_tiles_dirty( text_layer );
247 }
248 if( all_dirty ){
249 tilemap_mark_all_tiles_dirty( background );
250 tilemap_mark_all_tiles_dirty( foreground );
251 if( sys16_18_mode ){
252 tilemap_mark_all_tiles_dirty( background2 );
253 tilemap_mark_all_tiles_dirty( foreground2 );
254 }
255 }
256 else {
257 for(i=0;i<4;i++){
258 int page0 = 64*32*i;
259 if( old_bg_page[i]!=sys16_bg_page[i] ){
260 old_bg_page[i] = sys16_bg_page[i];
261 for( offset = page0; offset<page0+64*32; offset++ ){
262 tilemap_mark_tile_dirty( background, offset );
263 }
264 }
265 if( old_fg_page[i]!=sys16_fg_page[i] ){
266 old_fg_page[i] = sys16_fg_page[i];
267 for( offset = page0; offset<page0+64*32; offset++ ){
268 tilemap_mark_tile_dirty( foreground, offset );
269 }
270 }
271 if( sys16_18_mode ){
272 if( old_bg2_page[i]!=sys16_bg2_page[i] ){
273 old_bg2_page[i] = sys16_bg2_page[i];
274 for( offset = page0; offset<page0+64*32; offset++ ){
275 tilemap_mark_tile_dirty( background2, offset );
276 }
277 }
278 if( old_fg2_page[i]!=sys16_fg2_page[i] ){
279 old_fg2_page[i] = sys16_fg2_page[i];
280 for( offset = page0; offset<page0+64*32; offset++ ){
281 tilemap_mark_tile_dirty( foreground2, offset );
282 }
283 }
284 }
285 }
286 }
287 }
288
get_bg_tile_info(int offset)289 static void get_bg_tile_info( int offset ){
290 const UINT16 *source = 64*32*sys16_bg_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
291 int data = source[offset%(64*32)];
292 int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
293
294 if(sys16_textmode==0){
295 SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
296 }
297 else{
298 SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
299 }
300
301 switch(sys16_bg_priority_mode) {
302 case 1: // Alien Syndrome
303 tile_info.priority = (data&0x8000)?1:0;
304 break;
305 case 2: // Body Slam / wrestwar
306 tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
307 break;
308 case 3: // sys18 games
309 if( data&0x8000 ){
310 tile_info.priority = 2;
311 }
312 else {
313 tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
314 }
315 break;
316 }
317 }
318
get_fg_tile_info(int offset)319 static void get_fg_tile_info( int offset ){
320 const UINT16 *source = 64*32*sys16_fg_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
321 int data = source[offset%(64*32)];
322 int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
323
324 if(sys16_textmode==0){
325 SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
326 }
327 else{
328 SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
329 }
330 switch(sys16_fg_priority_mode){
331 case 1: // alien syndrome
332 tile_info.priority = (data&0x8000)?1:0;
333 break;
334
335 case 3:
336 tile_info.priority = ((data&0xff00) >= sys16_fg_priority_value)?1:0;
337 break;
338
339 default:
340 if( sys16_fg_priority_mode>=0 ){
341 tile_info.priority = (data&0x8000)?1:0;
342 }
343 break;
344 }
345 }
346
get_bg2_tile_info(int offset)347 static void get_bg2_tile_info( int offset ){
348 const UINT16 *source = 64*32*sys16_bg2_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
349 int data = source[offset%(64*32)];
350 int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
351 if(sys16_textmode==0){
352 SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
353 }
354 else{
355 SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
356 }
357 tile_info.priority = 0;
358 }
359
get_fg2_tile_info(int offset)360 static void get_fg2_tile_info( int offset ){
361 const UINT16 *source = 64*32*sys16_fg2_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
362 int data = source[offset%(64*32)];
363 int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
364 if(sys16_textmode==0){
365 SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
366 }
367 else{
368 SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
369 }
370 if((data&0xff00) >= sys16_fg_priority_value) tile_info.priority = 1;
371 else tile_info.priority = 0;
372 }
373
WRITE_HANDLER(sys16_tileram_w)374 WRITE_HANDLER( sys16_tileram_w ){
375 int oldword = READ_WORD(&sys16_tileram[offset]);
376 int newword = COMBINE_WORD(oldword,data);
377 if( oldword != newword ){
378 int page;
379 WRITE_WORD(&sys16_tileram[offset],newword);
380 offset = offset/2;
381 page = offset/(64*32);
382 offset = offset%(64*32);
383
384 if( sys16_bg_page[0]==page ) tilemap_mark_tile_dirty( background, offset+64*32*0 );
385 if( sys16_bg_page[1]==page ) tilemap_mark_tile_dirty( background, offset+64*32*1 );
386 if( sys16_bg_page[2]==page ) tilemap_mark_tile_dirty( background, offset+64*32*2 );
387 if( sys16_bg_page[3]==page ) tilemap_mark_tile_dirty( background, offset+64*32*3 );
388
389 if( sys16_fg_page[0]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*0 );
390 if( sys16_fg_page[1]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*1 );
391 if( sys16_fg_page[2]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*2 );
392 if( sys16_fg_page[3]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*3 );
393
394 if( sys16_18_mode ){
395 if( sys16_bg2_page[0]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*0 );
396 if( sys16_bg2_page[1]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*1 );
397 if( sys16_bg2_page[2]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*2 );
398 if( sys16_bg2_page[3]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*3 );
399
400 if( sys16_fg2_page[0]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*0 );
401 if( sys16_fg2_page[1]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*1 );
402 if( sys16_fg2_page[2]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*2 );
403 if( sys16_fg2_page[3]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*3 );
404 }
405 }
406 }
407
READ_HANDLER(sys16_tileram_r)408 READ_HANDLER( sys16_tileram_r ){
409 return READ_WORD (&sys16_tileram[offset]);
410 }
411
412 /***************************************************************************/
413
get_text_tile_info(int offset)414 static void get_text_tile_info( int offset ){
415 const UINT16 *source = (UINT16 *)sys16_textram;
416 int tile_number = source[offset];
417 int pri = tile_number >> 8;
418 if(sys16_textmode==0){
419 SET_TILE_INFO( 0, (tile_number&0x1ff) + sys16_tile_bank0 * 0x1000, (tile_number>>9)%8 );
420 }
421 else{
422 SET_TILE_INFO( 0, (tile_number&0xff) + sys16_tile_bank0 * 0x1000, (tile_number>>8)%8 );
423 }
424 if(pri>=sys16_textlayer_lo_min && pri<=sys16_textlayer_lo_max)
425 tile_info.priority = 1;
426 if(pri>=sys16_textlayer_hi_min && pri<=sys16_textlayer_hi_max)
427 tile_info.priority = 0;
428 }
429
WRITE_HANDLER(sys16_textram_w)430 WRITE_HANDLER( sys16_textram_w ){
431 int oldword = READ_WORD(&sys16_textram[offset]);
432 int newword = COMBINE_WORD(oldword,data);
433 if( oldword != newword ){
434 WRITE_WORD(&sys16_textram[offset],newword);
435 tilemap_mark_tile_dirty( text_layer, offset/2 );
436 }
437 }
438
READ_HANDLER(sys16_textram_r)439 READ_HANDLER( sys16_textram_r ){
440 return READ_WORD (&sys16_textram[offset]);
441 }
442
443 /***************************************************************************/
444
sys16_vh_stop(void)445 void sys16_vh_stop( void ){
446
447 #ifdef SPACEHARRIER_OFFSETS
448 if(spaceharrier_patternoffsets) free(spaceharrier_patternoffsets);
449 spaceharrier_patternoffsets=0;
450 #endif
451 }
452
sys16_vh_start(void)453 int sys16_vh_start( void ){
454 if( !sys16_bg1_trans )
455 background = tilemap_create(
456 get_bg_tile_info,
457 sys16_bg_map,
458 TILEMAP_OPAQUE,
459 8,8,
460 64*2,32*2 );
461 else
462 background = tilemap_create(
463 get_bg_tile_info,
464 sys16_bg_map,
465 TILEMAP_TRANSPARENT,
466 8,8,
467 64*2,32*2 );
468
469 foreground = tilemap_create(
470 get_fg_tile_info,
471 sys16_bg_map,
472 TILEMAP_TRANSPARENT,
473 8,8,
474 64*2,32*2 );
475
476 text_layer = tilemap_create(
477 get_text_tile_info,
478 sys16_text_map,
479 TILEMAP_TRANSPARENT,
480 8,8,
481 40,28 );
482
483 sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
484
485 #ifdef TRANSPARENT_SHADOWS
486 sprite_set_shade_table(shade_table);
487 #endif
488
489 if( background && foreground && text_layer && sprite_list ){
490 /* initialize all entries to black - needed for Golden Axe*/
491 int i;
492 for( i=0; i<Machine->drv->total_colors; i++ ){
493 palette_change_color( i, 0,0,0 );
494 }
495 #ifdef TRANSPARENT_SHADOWS
496 memset(&palette_used_colors[0], PALETTE_COLOR_UNUSED, Machine->drv->total_colors);
497 if (Machine->scrbitmap->depth == 8) /* 8 bit shadows */
498 {
499 int j,color;
500 for(j = 0, i = Machine->drv->total_colors/2;j<sys16_MaxShadowColors;i++,j++)
501 {
502 color=j * 160 / (sys16_MaxShadowColors-1);
503 color=color | 0x04;
504 palette_change_color(i, color, color, color);
505 }
506 }
507 if(sys16_MaxShadowColors==32)
508 sys16_MaxShadowColors_Shift = ShadowColorsShift;
509 else if(sys16_MaxShadowColors==16)
510 sys16_MaxShadowColors_Shift = ShadowColorsShift+1;
511
512 #endif
513 for(i=0;i<MAXCOLOURS;i++){
514 sys16_palettedirty[i]=0;
515 }
516 sys16_freezepalette=0;
517
518 sprite_list->max_priority = 3;
519 sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
520
521 if(sys16_bg1_trans) background->transparent_pen = 0;
522 foreground->transparent_pen = 0;
523 text_layer->transparent_pen = 0;
524
525 sys16_tile_bank0 = 0;
526 sys16_tile_bank1 = 1;
527
528 sys16_fg_scrollx = 0;
529 sys16_fg_scrolly = 0;
530
531 sys16_bg_scrollx = 0;
532 sys16_bg_scrolly = 0;
533
534 sys16_refreshenable = 1;
535 sys16_clear_screen = 0;
536
537 /* common defaults */
538 sys16_update_proc = 0;
539 sys16_spritesystem = 1;
540 sys16_sprxoffset = -0xb8;
541 sys16_textmode = 0;
542 sys16_bgxoffset = 0;
543 sys16_dactype = 0;
544 sys16_bg_priority_mode=0;
545 sys16_fg_priority_mode=0;
546 sys16_spritelist_end=0xffff;
547 sys16_tilebank_switch=0x1000;
548
549 // Defaults for sys16 games
550 sys16_textlayer_lo_min=0;
551 sys16_textlayer_lo_max=0x7f;
552 sys16_textlayer_hi_min=0x80;
553 sys16_textlayer_hi_max=0xff;
554
555 sys16_18_mode=0;
556
557 #ifdef GAMMA_ADJUST
558 {
559 static float sys16_orig_gamma=0;
560 static float sys16_set_gamma=0;
561 float cur_gamma=osd_get_gamma();
562
563 if(sys16_orig_gamma == 0)
564 {
565 sys16_orig_gamma = cur_gamma;
566 sys16_set_gamma = cur_gamma - 0.35;
567 if (sys16_set_gamma < 0.5) sys16_set_gamma = 0.5;
568 if (sys16_set_gamma > 2.0) sys16_set_gamma = 2.0;
569 osd_set_gamma(sys16_set_gamma);
570 }
571 else
572 {
573 if(sys16_orig_gamma == cur_gamma)
574 {
575 osd_set_gamma(sys16_set_gamma);
576 }
577 }
578 }
579 #endif
580 return 0;
581 }
582 return 1;
583 }
584
sys16_ho_vh_start(void)585 int sys16_ho_vh_start( void ){
586 int ret;
587 sys16_bg1_trans=1;
588 ret = sys16_vh_start();
589 if(ret) return 1;
590
591 sys16_textlayer_lo_min=0;
592 sys16_textlayer_lo_max=0;
593 sys16_textlayer_hi_min=0;
594 sys16_textlayer_hi_max=0xff;
595
596 sys16_bg_priority_mode=-1;
597 sys16_bg_priority_value=0x1800;
598 sys16_fg_priority_value=0x2000;
599 return 0;
600 }
601
sys16_or_vh_start(void)602 int sys16_or_vh_start( void ){
603 int ret;
604 sys16_bg1_trans=1;
605 ret = sys16_vh_start();
606 if(ret) return 1;
607
608 sys16_textlayer_lo_min=0;
609 sys16_textlayer_lo_max=0;
610 sys16_textlayer_hi_min=0;
611 sys16_textlayer_hi_max=0xff;
612
613 sys16_bg_priority_mode=-1;
614 sys16_bg_priority_value=0x1800;
615 sys16_fg_priority_value=0x2000;
616 return 0;
617 }
618
619
sys18_vh_start(void)620 int sys18_vh_start( void ){
621 int ret;
622 sys16_bg1_trans=1;
623
624 background2 = tilemap_create(
625 get_bg2_tile_info,
626 sys16_bg_map,
627 TILEMAP_OPAQUE,
628 8,8,
629 64*2,32*2 );
630
631 foreground2 = tilemap_create(
632 get_fg2_tile_info,
633 sys16_bg_map,
634 TILEMAP_TRANSPARENT,
635 8,8,
636 64*2,32*2 );
637
638 if( background2 && foreground2)
639 {
640 ret = sys16_vh_start();
641 if(ret) return 1;
642
643 foreground2->transparent_pen = 0;
644
645 if(sys18_splittab_fg_x)
646 {
647 tilemap_set_scroll_rows( foreground , 64 );
648 tilemap_set_scroll_rows( foreground2 , 64 );
649 }
650 if(sys18_splittab_bg_x)
651 {
652 tilemap_set_scroll_rows( background , 64 );
653 tilemap_set_scroll_rows( background2 , 64 );
654 }
655
656 sys16_textlayer_lo_min=0;
657 sys16_textlayer_lo_max=0x1f;
658 sys16_textlayer_hi_min=0x20;
659 sys16_textlayer_hi_max=0xff;
660
661 sys16_18_mode=1;
662 sys16_bg_priority_mode=3;
663 sys16_fg_priority_mode=3;
664 sys16_bg_priority_value=0x1800;
665 sys16_fg_priority_value=0x2000;
666 return 0;
667 }
668 return 1;
669 }
670
671
672 /***************************************************************************/
673
get_sprite_info(void)674 static void get_sprite_info( void ){
675 const unsigned short *base_pal = Machine->gfx[0]->colortable + 1024;
676 const unsigned char *base_gfx = memory_region(REGION_GFX2);
677
678 UINT16 *source = (UINT16 *)sys16_spriteram;
679 struct sprite *sprite = sprite_list->sprite;
680 const struct sprite *finish = sprite + NUM_SPRITES;
681
682 int passshot_y=0;
683 int passshot_width=0;
684
685 #ifdef SYS16_DEBUG
686 int dump_spritedata=0;
687 if(keyboard_pressed_memory(KEYCODE_W))
688 {
689 dump_spritedata=1;
690 logerror("sprites\n");
691 }
692 #endif
693 switch( sys16_spritesystem ){
694 case 1: /* standard sprite hardware (Shinobi, Altered Beast, Golden Axe, ...) */
695 /*
696 0 bottom-- top----- (screen coordinates)
697 1 ???????X XXXXXXXX (screen coordinate)
698 2 ???????F FWWWWWWW (flipx, flipy, logical width)
699 3 TTTTTTTT TTTTTTTT (pen data)
700 4 ????BBBB PPCCCCCC (attributes: bank, priority, color)
701 5 ??????ZZ ZZZZZZZZ zoomx
702 6 ??????ZZ ZZZZZZZZ zoomy (defaults to zoomx)
703 7 ? "sprite offset"
704 */
705 while( sprite<finish ){
706 UINT16 ypos = source[0];
707 UINT16 width = source[2];
708 int top = ypos&0xff;
709 int bottom = ypos>>8;
710
711 if( bottom == 0xff || width ==sys16_spritelist_end){ /* end of spritelist marker */
712 do {
713 sprite->flags = 0;
714 sprite++;
715 } while( sprite<finish );
716 break;
717 }
718 sprite->flags = 0;
719
720 if(bottom !=0 && bottom > top)
721 {
722 UINT16 attributes = source[4];
723 UINT16 zoomx = source[5]&0x3ff;
724 UINT16 zoomy = (source[6]&0x3ff);
725 int gfx = source[3]*4;
726
727 #ifdef SYS16_DEBUG
728 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
729 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
730 #endif
731
732 if( zoomy==0 || source[6]==0xffff ) zoomy = zoomx; /* if zoomy is 0, use zoomx instead */
733
734 sprite->x = source[1] + sys16_sprxoffset;
735 sprite->y = top;
736 sprite->priority = 3-((attributes>>6)&0x3);
737 sprite->pal_data = base_pal + ((attributes&0x3f)<<4);
738
739 sprite->total_height = bottom-top;
740 sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
741
742 sprite->line_offset = (width&0x7f)*4;
743
744 sprite->flags = SPRITE_VISIBLE;
745 if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
746 if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
747
748 #ifdef TRANSPARENT_SHADOWS
749 if ((attributes&0x3f)==0x3f) // shadow sprite
750 sprite->flags|= SPRITE_SHADOW;
751 #endif
752
753 if( sprite->flags&SPRITE_FLIPY ){
754 sprite->line_offset = 512-sprite->line_offset;
755 if( sprite->flags&SPRITE_FLIPX ){
756 gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
757 }
758 else {
759 gfx -= sprite->line_offset*sprite->tile_height;
760 }
761 }
762 else {
763 if( sprite->flags&SPRITE_FLIPX ){
764 gfx += 4;
765 }
766 else {
767 gfx += sprite->line_offset;
768 }
769 }
770
771 sprite->tile_width = sprite->line_offset;
772 sprite->total_width = sprite->tile_width*(0x800-zoomx)/0x800;
773 sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[(attributes>>8)&0xf] << 17);
774
775 }
776
777 sprite++;
778 source += 8;
779 }
780 break;
781
782 case 8: /* Passing shot 4p */
783 passshot_y=-0x23;
784 passshot_width=1;
785 case 0: /* Passing shot */
786 /*
787 0 ???????X XXXXXXXX (screen coordinate)
788 1 bottom-- top----- (screen coordinates)
789 2 XTTTTTTT YTTTTTTT (pen data, flipx, flipy)
790 3 ???????? ?WWWWWWW (logical width)
791 4 ??????ZZ ZZZZZZZZ zoom
792 5 PP???CCC BBBB???? (attributes: bank, priority, color)
793 6,7 (unused)
794 */
795 while( sprite<finish ){
796 UINT16 attributes = source[5];
797 UINT16 ypos = source[1];
798 int bottom = (ypos>>8)+passshot_y;
799 int top = (ypos&0xff)+passshot_y;
800 sprite->flags = 0;
801
802 if( bottom>top && ypos!=0xffff ){
803 int bank = (attributes>>4)&0xf;
804 UINT16 number = source[2];
805 UINT16 width = source[3];
806
807 int zoom = source[4]&0x3ff;
808 int xpos = source[0] + sys16_sprxoffset;
809
810 #ifdef SYS16_DEBUG
811 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
812 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
813 #endif
814 sprite->priority = 3-((attributes>>14)&0x3);
815 if(passshot_width) /* 4 player bootleg version */
816 {
817 width=-width;
818 number-=width*(bottom-top-1)-1;
819 }
820
821 if( number & 0x8000 ) sprite->flags |= SPRITE_FLIPX;
822 if( width & 0x0080 ) sprite->flags |= SPRITE_FLIPY;
823 sprite->flags |= SPRITE_VISIBLE;
824 sprite->pal_data = base_pal + ((attributes>>4)&0x3f0);
825 sprite->total_height = bottom - top;
826 sprite->tile_height = sprite->total_height*(0x400+zoom)/0x400;
827
828 #ifdef TRANSPARENT_SHADOWS
829 if (((attributes>>8)&0x3f)==0x3f) // shadow sprite
830 sprite->flags|= SPRITE_SHADOW;
831 #endif
832 width &= 0x7f;
833
834 if( sprite->flags&SPRITE_FLIPY ) width = 0x80-width;
835
836 sprite->tile_width = sprite->line_offset = width*4;
837
838 if( sprite->flags&SPRITE_FLIPX ){
839 bank = (bank-1) & 0xf;
840 if( sprite->flags&SPRITE_FLIPY ){
841 xpos += 4;
842 }
843 else {
844 number += 1-width;
845 }
846 }
847 sprite->pen_data = base_gfx + number*4 + (sys16_obj_bank[bank] << 17);
848
849 if( sprite->flags&SPRITE_FLIPY ){
850 sprite->pen_data -= sprite->tile_height*sprite->tile_width;
851 if( sprite->flags&SPRITE_FLIPX ) sprite->pen_data += 2;
852 }
853
854 sprite->x = xpos;
855 sprite->y = top+2;
856
857 if( sprite->flags&SPRITE_FLIPY ){
858 if( sprite->flags&SPRITE_FLIPX ){
859 sprite->tile_width-=4;
860 sprite->pen_data+=4;
861 }
862 else {
863 sprite->pen_data += sprite->line_offset;
864 }
865 }
866
867 sprite->total_width = sprite->tile_width*(0x800-zoom)/0x800;
868 }
869 sprite++;
870 source += 8;
871 }
872 break;
873
874 case 4: // Aurail
875 /*
876 0 bottom-- top----- (screen coordinates)
877 1 ???????X XXXXXXXX (screen coordinate)
878 2 ???????F FWWWWWWW (flipx, flipy, logical width)
879 3 TTTTTTTT TTTTTTTT (pen data)
880 4 ????BBBB PPCCCCCC (attributes: bank, priority, color)
881 5 ??????ZZ ZZZZZZZZ zoomx
882 6 ??????ZZ ZZZZZZZZ zoomy (defaults to zoomx)
883 7 ? "sprite offset"
884 */
885 while( sprite<finish ){
886 UINT16 ypos = source[0];
887 UINT16 width = source[2];
888 UINT16 attributes = source[4];
889 int top = ypos&0xff;
890 int bottom = ypos>>8;
891
892 if( width == sys16_spritelist_end) {
893 do {
894 sprite->flags = 0;
895 sprite++;
896 } while( sprite<finish );
897 break;
898 }
899 sprite->flags = 0;
900 #ifdef TRANSPARENT_SHADOWS
901 if(bottom !=0 && bottom > top)
902 #else
903 if(bottom !=0 && bottom > top && (attributes&0x3f) !=0x3f)
904 #endif
905 {
906 UINT16 zoomx = source[5]&0x3ff;
907 UINT16 zoomy = (source[6]&0x3ff);
908 int gfx = source[3]*4;
909
910 #ifdef SYS16_DEBUG
911 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
912 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
913 #endif
914
915 if( zoomy==0 ) zoomy = zoomx; /* if zoomy is 0, use zoomx instead */
916 sprite->pal_data = base_pal + ((attributes&0x3f)<<4);
917
918 sprite->x = source[1] + sys16_sprxoffset;;
919 sprite->y = top;
920 sprite->priority = 3-((attributes>>6)&0x3);
921
922 sprite->total_height = bottom-top;
923 sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
924
925 sprite->line_offset = (width&0x7f)*4;
926
927 sprite->flags = SPRITE_VISIBLE;
928 if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
929 if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
930 #ifdef TRANSPARENT_SHADOWS
931 if ((attributes&0x3f)==0x3f) // shadow sprite
932 sprite->flags|= SPRITE_SHADOW;
933 #endif
934
935 if( sprite->flags&SPRITE_FLIPY ){
936 sprite->line_offset = 512-sprite->line_offset;
937 if( sprite->flags&SPRITE_FLIPX ){
938 gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
939 }
940 else {
941 gfx -= sprite->line_offset*sprite->tile_height;
942 }
943 }
944 else {
945 if( sprite->flags&SPRITE_FLIPX ){
946 gfx += 4;
947 }
948 else {
949 gfx += sprite->line_offset;
950 }
951 }
952
953 sprite->tile_width = sprite->line_offset;
954 sprite->total_width = sprite->tile_width*(0x800-zoomx)/0x800;
955 sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[(attributes>>8)&0xf] << 17);
956
957 }
958 sprite++;
959 source += 8;
960 }
961 break;
962 case 3: // Fantzone
963 {
964 int spr_no=0;
965 while( sprite<finish ){
966 UINT16 ypos = source[0];
967 UINT16 pal=(source[4]>>8)&0x3f;
968 int top = ypos&0xff;
969 int bottom = ypos>>8;
970
971 if( bottom == 0xff ){ /* end of spritelist marker */
972 do {
973 sprite->flags = 0;
974 sprite++;
975 } while( sprite<finish );
976 break;
977 }
978 sprite->flags = 0;
979
980 #ifdef SYS16_DEBUG
981 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
982 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
983 #endif
984 #ifdef TRANSPARENT_SHADOWS
985 if(bottom !=0 && bottom > top)
986 #else
987 if(bottom !=0 && bottom > top && pal !=0x3f)
988 #endif
989 {
990 UINT16 spr_pri=(source[4])&0xf;
991 UINT16 bank=(source[4]>>4) &0xf;
992 UINT16 tsource[4];
993 UINT16 width;
994 int gfx;
995
996 if (spr_no==5 && (source[4]&0x00ff) == 0x0021 &&
997 ((source[3]&0xff00) == 0x5200 || (source[3]&0xff00) == 0x5300)) spr_pri=2; // tears fix for ending boss
998
999 tsource[2]=source[2];
1000 tsource[3]=source[3];
1001
1002 if((tsource[3] & 0x7f80) == 0x7f80)
1003 {
1004 bank=(bank-1)&0xf;
1005 tsource[3]^=0x8000;
1006 }
1007
1008 tsource[2] &= 0x00ff;
1009 if (tsource[3]&0x8000)
1010 { // reverse
1011 tsource[2] |= 0x0100;
1012 tsource[3] &= 0x7fff;
1013 }
1014
1015 gfx = tsource[3]*4;
1016 width = tsource[2];
1017 top++;
1018 bottom++;
1019
1020 sprite->x = source[1] + sys16_sprxoffset;
1021 if(sprite->x > 0x140) sprite->x-=0x200;
1022 sprite->y = top;
1023 sprite->priority = 3-spr_pri;
1024 sprite->pal_data = base_pal + (pal<<4);
1025
1026 sprite->total_height = bottom-top;
1027 sprite->tile_height = sprite->total_height;
1028
1029 sprite->line_offset = (width&0x7f)*4;
1030
1031 sprite->flags = SPRITE_VISIBLE;
1032 if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1033 if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1034 #ifdef TRANSPARENT_SHADOWS
1035 if (pal==0x3f) // shadow sprite
1036 sprite->flags|= SPRITE_SHADOW;
1037 #endif
1038
1039 if( sprite->flags&SPRITE_FLIPY ){
1040 sprite->line_offset = 512-sprite->line_offset;
1041 if( sprite->flags&SPRITE_FLIPX ){
1042 gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
1043 }
1044 else {
1045 gfx -= sprite->line_offset*sprite->tile_height;
1046 }
1047 }
1048 else {
1049 if( sprite->flags&SPRITE_FLIPX ){
1050 gfx += 4;
1051 }
1052 else {
1053 gfx += sprite->line_offset;
1054 }
1055 }
1056
1057 sprite->tile_width = sprite->line_offset;
1058 if(width==0) sprite->tile_width=320; // fixes laser
1059 sprite->total_width = sprite->tile_width;
1060 sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[bank] << 17);
1061
1062 }
1063
1064 source+=8;
1065 sprite++;
1066 spr_no++;
1067 }
1068 }
1069 break;
1070 case 2: // Quartet2 /Alexkidd + others
1071 while( sprite<finish ){
1072 UINT16 ypos = source[0];
1073 int top = ypos&0xff;
1074 int bottom = ypos>>8;
1075
1076 if( bottom == 0xff ){ /* end of spritelist marker */
1077 do {
1078 sprite->flags = 0;
1079 sprite++;
1080 } while( sprite<finish );
1081 break;
1082 }
1083 sprite->flags = 0;
1084
1085 if(bottom !=0 && bottom > top)
1086 {
1087 UINT16 spr_pri=(source[4])&0xf;
1088 UINT16 bank=(source[4]>>4) &0xf;
1089 UINT16 pal=(source[4]>>8)&0x3f;
1090 UINT16 tsource[4];
1091 UINT16 width;
1092 int gfx;
1093
1094 #ifdef SYS16_DEBUG
1095 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
1096 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1097 #endif
1098
1099 tsource[2]=source[2];
1100 tsource[3]=source[3];
1101 #ifndef TRANSPARENT_SHADOWS
1102 if (pal==0x3f) // shadow sprite
1103 pal=(bank<<1);
1104 #endif
1105
1106 if((tsource[3] & 0x7f80) == 0x7f80)
1107 {
1108 bank=(bank-1)&0xf;
1109 tsource[3]^=0x8000;
1110 }
1111
1112 tsource[2] &= 0x00ff;
1113 if (tsource[3]&0x8000)
1114 { // reverse
1115 tsource[2] |= 0x0100;
1116 tsource[3] &= 0x7fff;
1117 }
1118
1119 gfx = tsource[3]*4;
1120 width = tsource[2];
1121 top++;
1122 bottom++;
1123
1124 sprite->x = source[1] + sys16_sprxoffset;
1125 if(sprite->x > 0x140) sprite->x-=0x200;
1126 sprite->y = top;
1127 sprite->priority = 3 - spr_pri;
1128 sprite->pal_data = base_pal + (pal<<4);
1129
1130 sprite->total_height = bottom-top;
1131 sprite->tile_height = sprite->total_height;
1132
1133 sprite->line_offset = (width&0x7f)*4;
1134
1135 sprite->flags = SPRITE_VISIBLE;
1136 if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1137 if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1138 #ifdef TRANSPARENT_SHADOWS
1139 if (pal==0x3f) // shadow sprite
1140 sprite->flags|= SPRITE_SHADOW;
1141 #endif
1142
1143 if( sprite->flags&SPRITE_FLIPY ){
1144 sprite->line_offset = 512-sprite->line_offset;
1145 if( sprite->flags&SPRITE_FLIPX ){
1146 gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
1147 }
1148 else {
1149 gfx -= sprite->line_offset*sprite->tile_height;
1150 }
1151 }
1152 else {
1153 if( sprite->flags&SPRITE_FLIPX ){
1154 gfx += 4;
1155 }
1156 else {
1157 gfx += sprite->line_offset;
1158 }
1159 }
1160
1161 sprite->tile_width = sprite->line_offset;
1162 sprite->total_width = sprite->tile_width;
1163 sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[bank] << 17);
1164 }
1165
1166 source+=8;
1167 sprite++;
1168 }
1169 break;
1170 case 5: // Hang-On
1171 while( sprite<finish ){
1172 UINT16 ypos = source[0];
1173 int top = ypos&0xff;
1174 int bottom = ypos>>8;
1175
1176 if( bottom == 0xff ){ /* end of spritelist marker */
1177 do {
1178 sprite->flags = 0;
1179 sprite++;
1180 } while( sprite<finish );
1181 break;
1182 }
1183 sprite->flags = 0;
1184
1185 if(bottom !=0 && bottom > top)
1186 {
1187 UINT16 bank=(source[1]>>12);
1188 UINT16 pal=(source[4]>>8)&0x3f;
1189 UINT16 tsource[4];
1190 UINT16 width;
1191 int gfx;
1192 int zoomx,zoomy;
1193
1194 #ifdef SYS16_DEBUG
1195 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
1196 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1197 #endif
1198
1199 tsource[2]=source[2];
1200 tsource[3]=source[3];
1201
1202 zoomx=((source[4]>>2) & 0x3f) *(1024/64);
1203 zoomy = (1060*zoomx)/(2048-zoomx);
1204
1205 // if (pal==0x3f) // ????????????
1206 // pal=(bank<<1);
1207
1208 if((tsource[3] & 0x7f80) == 0x7f80)
1209 {
1210 bank=(bank-1)&0xf;
1211 tsource[3]^=0x8000;
1212 }
1213
1214 if (tsource[3]&0x8000)
1215 { // reverse
1216 tsource[2] |= 0x0100;
1217 tsource[3] &= 0x7fff;
1218 }
1219
1220 gfx = tsource[3]*4;
1221 width = tsource[2];
1222
1223 sprite->x = ((source[1] & 0x3ff) + sys16_sprxoffset);
1224 if(sprite->x >= 0x200) sprite->x-=0x200;
1225 sprite->y = top;
1226 sprite->priority = 0;
1227 sprite->pal_data = base_pal + (pal<<4);
1228
1229 sprite->total_height = bottom-top;
1230 sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
1231
1232 sprite->line_offset = (width&0x7f)*4;
1233
1234 sprite->flags = SPRITE_VISIBLE;
1235 if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1236 if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1237
1238
1239 // sprite->flags|= SPRITE_PARTIAL_SHADOW;
1240 // sprite->shadow_pen=10;
1241
1242 if( sprite->flags&SPRITE_FLIPY ){
1243 sprite->line_offset = 512-sprite->line_offset;
1244 if( sprite->flags&SPRITE_FLIPX ){
1245 gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
1246 }
1247 else {
1248 gfx -= sprite->line_offset*sprite->tile_height;
1249 }
1250 }
1251 else {
1252 if( sprite->flags&SPRITE_FLIPX ){
1253 gfx += 4;
1254 }
1255 else {
1256 gfx += sprite->line_offset;
1257 }
1258 }
1259
1260 sprite->tile_width = sprite->line_offset;
1261 sprite->total_width = sprite->tile_width*(0x0800 - zoomx)/0x800;
1262 sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[bank] << 17);
1263
1264 }
1265
1266 source+=8;
1267 sprite++;
1268 }
1269 break;
1270 case 6: // Space Harrier
1271 while( sprite<finish ){
1272 UINT16 ypos = source[0];
1273 int top = ypos&0xff;
1274 int bottom = ypos>>8;
1275
1276 if( bottom == 0xff ){ /* end of spritelist marker */
1277 do {
1278 sprite->flags = 0;
1279 sprite++;
1280 } while( sprite<finish );
1281 break;
1282 }
1283 sprite->flags = 0;
1284
1285 if(bottom !=0 && bottom > top)
1286 {
1287 UINT16 bank=(source[1]>>12);
1288 UINT16 pal=(source[2]>>8)&0x3f;
1289 UINT16 tsource[4];
1290 UINT16 width;
1291 int gfx;
1292 int zoomx,zoomy;
1293
1294 #ifdef SYS16_DEBUG
1295 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
1296 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1297 #endif
1298
1299 tsource[2]=source[2]&0xff;
1300 tsource[3]=source[3];
1301
1302 zoomx=(source[4] & 0x3f) *(1024/64);
1303 zoomy = (1024*zoomx)/(2048-zoomx);
1304
1305 #ifndef TRANSPARENT_SHADOWS
1306 if (pal==0x3f) // shadow sprite
1307 pal=(bank<<1);
1308 #endif
1309
1310 if((tsource[3] & 0x7f80) == 0x7f80)
1311 {
1312 bank=(bank-1)&0xf;
1313 tsource[3]^=0x8000;
1314 }
1315
1316 if (tsource[3]&0x8000)
1317 { // reverse
1318 tsource[2] |= 0x0100;
1319 tsource[3] &= 0x7fff;
1320 }
1321
1322 gfx = tsource[3]*4;
1323 width = tsource[2];
1324
1325 sprite->x = ((source[1] & 0x3ff) + sys16_sprxoffset);
1326 if(sprite->x >= 0x200) sprite->x-=0x200;
1327 sprite->y = top+1;
1328 sprite->priority = 0;
1329 sprite->pal_data = base_pal + (pal<<4);
1330
1331 sprite->total_height = bottom-top;
1332 // sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
1333 sprite->tile_height = ((sprite->total_height)<<4|0xf)*(0x400+zoomy)/0x4000;
1334
1335 sprite->line_offset = (width&0x7f)*4;
1336
1337 sprite->flags = SPRITE_VISIBLE;
1338 if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1339 if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1340
1341 #ifdef TRANSPARENT_SHADOWS
1342 if (sys16_sh_shadowpal == 0) // space harrier
1343 {
1344 if (pal==sys16_sh_shadowpal) // shadow sprite
1345 sprite->flags|= SPRITE_SHADOW;
1346 // I think this looks better, but I'm sure it's wrong.
1347 // else if(READ_WORD(&paletteram[2048+pal*2+20]) == 0)
1348 // {
1349 // sprite->flags|= SPRITE_PARTIAL_SHADOW;
1350 // sprite->shadow_pen=10;
1351 // }
1352 }
1353 else // enduro
1354 {
1355 sprite->flags|= SPRITE_PARTIAL_SHADOW;
1356 sprite->shadow_pen=10;
1357 }
1358 #endif
1359 if( sprite->flags&SPRITE_FLIPY ){
1360 sprite->line_offset = 512-sprite->line_offset;
1361 if( sprite->flags&SPRITE_FLIPX ){
1362 gfx += 4 - sprite->line_offset*(sprite->tile_height+1) /*+4*/;
1363 }
1364 else {
1365 gfx -= sprite->line_offset*sprite->tile_height;
1366 }
1367 }
1368 else {
1369 if( sprite->flags&SPRITE_FLIPX ){
1370 gfx += 4 /*+ 4*/; // +2 ???
1371 }
1372 else {
1373 gfx += sprite->line_offset;
1374 }
1375 }
1376
1377 sprite->line_offset<<=1;
1378 sprite->tile_width = sprite->line_offset;
1379 sprite->total_width = sprite->tile_width*(0x0800 - zoomx)/0x800;
1380
1381 sprite->pen_data = base_gfx + (((gfx &0x3ffff) + (sys16_obj_bank[bank] << 17)) << 1);
1382
1383
1384 #ifdef SPACEHARRIER_OFFSETS
1385 // doesn't seem to work properly and I'm not sure why it's needed.
1386 if( !(width & 0x180) && (width & 0x7f))
1387 {
1388 unsigned addr=tsource[3];
1389 unsigned offset_addr= (bank<<12) | (addr>>4);
1390 char rebuild = 0;
1391
1392 if (spaceharrier_patternoffsets[offset_addr]!=0x7f)
1393 {
1394 offset = spaceharrier_patternoffsets[offset_addr];
1395 }
1396 else
1397 { // build pattern offset
1398 unsigned width2=width&0x7f;
1399 UINT8 *p,*p0;
1400 unsigned height=sprite->tile_height;
1401 unsigned width_bytes;
1402 int len_pattern;
1403 int i,j;
1404
1405 len_pattern = height*width2;
1406 if (len_pattern >= 16)
1407 {
1408
1409 len_pattern >>= 4;
1410
1411 // 32 bit sprite hardware ///////////////////////////////////////////
1412 width_bytes = width2<<3;
1413 p0 = (UINT8 *)sprite->pen_data;
1414 /////////////////////////////////////////////////////////////////////
1415
1416 offset=0xe;
1417 for (i=0, p=p0; i<height; i++, p+=width_bytes)
1418 {
1419 for (j=0; j<width_bytes && j<offset; j++)
1420 {
1421 if ((p[j]!=0xff && p[j]!=0x00) /*|| (p[j+1]!=0xff && p[j+1]!=0x00 )*/) break;
1422 }
1423 if (j<offset) offset = j;
1424 }
1425
1426 // printf("rebuild %02x:%04x = %d\n", bank, addr, offset);
1427
1428 p=&spaceharrier_patternoffsets[offset_addr];
1429
1430 offset/=2;
1431 for (i=0; i<len_pattern; i++,p++) *p = offset;
1432
1433 logerror("addr=%04x offset=%4x bank=%02x offset=%d height=%d zoomy=%04x len_pattern=%d width=%d offset_addr=%04x\n", addr, offset, bank, offset, height, zoomy, len_pattern, width2, offset_addr);
1434 }
1435 }
1436 }
1437 sprite->pen_data += offset*2;
1438 #endif
1439 }
1440
1441 source+=8;
1442 sprite++;
1443 }
1444 break;
1445 case 7: // Out Run
1446 while( sprite<finish ){
1447
1448 if( source[0] == 0xffff ){ /* end of spritelist marker */
1449 do {
1450 sprite->flags = 0;
1451 sprite++;
1452 } while( sprite<finish );
1453 break;
1454 }
1455 sprite->flags = 0;
1456
1457 if (!(source[0]&0x4000))
1458 {
1459 UINT16 bank=(source[0]>>8)&7;
1460 UINT16 pal=(source[5])&0x7f;
1461 UINT16 width;
1462 int gfx;
1463 int zoom;
1464 int x;
1465
1466 #ifdef SYS16_DEBUG
1467 if(dump_spritedata) logerror("0:%4x 1:%4x 2:%4x 3:%4x 4:%4x 5:%4x 6:%4x 7:%4x\n",
1468 source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1469 #endif
1470
1471 zoom=source[4]&0xfff;
1472 // if (zoom==0x32c) zoom=0x3cf; //???
1473
1474 if(zoom==0) zoom=1;
1475
1476 if (source[1]&0x8000) bank=(bank+1)&0x7;
1477
1478 gfx = (source[1]&0x7fff)*4;
1479 width = source[2]>>9;
1480
1481 x = (source[2] & 0x1ff);
1482
1483 // patch misplaced sprite on map
1484 // if(zoom == 0x3f0 && source[1]==0x142e && (source[0]&0xff)==0x19)
1485 // x-=2;
1486
1487 sprite->y = source[0]&0xff;
1488 sprite->priority = 0;
1489 sprite->pal_data = base_pal + (pal<<4) + 1024;
1490
1491 sprite->total_height = (source[5]>>8)+1;
1492 sprite->tile_height = ((sprite->total_height<<4)| 0xf)*(zoom)/0x2000;
1493
1494 sprite->line_offset = (width&0x7f)*4;
1495
1496 sprite->flags = SPRITE_VISIBLE;
1497 #ifdef TRANSPARENT_SHADOWS
1498 if(pal==0)
1499 sprite->flags|= SPRITE_SHADOW;
1500 else if(source[3]&0x4000)
1501 // if(pal==0 || source[3]&0x4000)
1502 {
1503 sprite->flags|= SPRITE_PARTIAL_SHADOW;
1504 sprite->shadow_pen=10;
1505 }
1506 #endif
1507 if(!(source[4]&0x2000))
1508 {
1509 if(!(source[4]&0x4000))
1510 {
1511 // Should be drawn right to left, but this should be ok.
1512 x-=(sprite->line_offset*2)*0x200/zoom;
1513 gfx+=4-sprite->line_offset;
1514 }
1515 else
1516 {
1517 int ofs=(sprite->line_offset*2)*0x200/zoom;
1518 x-=ofs;
1519 sprite->flags |= SPRITE_FLIPX;
1520
1521 // x position compensation for rocks in round2R and round4RRR
1522 /* if((source[0]&0xff00)==0x0300)
1523 {
1524 if (source[1]==0xc027)
1525 {
1526 if ((source[2]>>8)==0x59) x += ofs/2;
1527 else if ((source[2]>>8)>0x59) x += ofs;
1528 }
1529 else if (source[1]==0xcf73)
1530 {
1531 if ((source[2]>>8)==0x2d) x += ofs/2;
1532 else if ((source[2]>>8)>0x2d) x += ofs;
1533 }
1534 else if (source[1]==0xd3046)
1535 {
1536 if ((source[2]>>8)==0x19) x += ofs/2;
1537 else if ((source[2]>>8)>0x19) x += ofs;
1538 }
1539 else if (source[1]==0xd44e)
1540 {
1541 if ((source[2]>>8)==0x0d) x += ofs/2;
1542 else if ((source[2]>>8)>0x0d) x += ofs;
1543 }
1544 else if (source[1]==0xd490)
1545 {
1546 if ((source[2]>>8)==0x09) x += ofs/2;
1547 else if ((source[2]>>8)>0x09) x += ofs;
1548 }
1549 }
1550 */
1551 }
1552 }
1553 else
1554 {
1555 if(!(source[4]&0x4000))
1556 {
1557 gfx-=sprite->line_offset-4;
1558 sprite->flags |= SPRITE_FLIPX;
1559 }
1560 else
1561 {
1562 if (source[4]&0x8000)
1563 { // patch for car shadow position
1564 if (source[4]==0xe1a9 && source[1]==0x5817)
1565 x-=2;
1566 }
1567 }
1568 }
1569
1570 sprite->x = x + sys16_sprxoffset;
1571
1572 sprite->line_offset<<=1;
1573 sprite->tile_width = sprite->line_offset;
1574 sprite->total_width = sprite->tile_width*0x200/zoom;
1575 sprite->pen_data = base_gfx + (((gfx &0x3ffff) + (sys16_obj_bank[bank] << 17)) << 1);
1576 }
1577 source+=8;
1578 sprite++;
1579 }
1580 break;
1581 }
1582 }
1583
1584 /***************************************************************************/
1585
mark_sprite_colors(void)1586 static void mark_sprite_colors( void ){
1587 unsigned short *source = (unsigned short *)sys16_spriteram;
1588 unsigned short *finish = source+NUM_SPRITES*8;
1589 int pal_start=1024,pal_size=64;
1590
1591 char used[128];
1592 memset( used, 0, 128 );
1593
1594 switch( sys16_spritesystem ){
1595 case 1: /* standard sprite hardware */
1596 do{
1597 if( source[0]>>8 == 0xff || source[2] == sys16_spritelist_end) break;
1598 used[source[4]&0x3f] = 1;
1599 source+=8;
1600 }while( source<finish );
1601 break;
1602 case 4: /* Aurail */
1603 do{
1604 if( (source[2]) == sys16_spritelist_end) break;
1605 used[source[4]&0x3f] = 1;
1606 source+=8;
1607 }while( source<finish );
1608 break;
1609
1610 case 3: /* Fantzone */
1611 case 5: /* Hang-On */
1612 case 2: /* Quartet2 / alex kidd + others */
1613 do{
1614 if( (source[0]>>8) == 0xff ) break;;
1615 used[(source[4]>>8)&0x3f] = 1;
1616 source+=8;
1617 }while( source<finish );
1618 break;
1619 case 6: /* Space Harrier */
1620 do{
1621 if( (source[0]>>8) == 0xff ) break;;
1622 used[(source[2]>>8)&0x3f] = 1;
1623 source+=8;
1624 }while( source<finish );
1625 break;
1626 case 7: /* Out Run */
1627 do{
1628 if( (source[0]) == 0xffff ) break;;
1629 used[(source[5])&0x7f] = 1;
1630 source+=8;
1631 }while( source<finish );
1632 pal_start=2048;
1633 pal_size=128;
1634 break;
1635 case 0: /* passing shot */
1636 case 8: /* passing shot 4p */
1637 do{
1638 if( source[1]!=0xffff ) used[(source[5]>>8)&0x3f] = 1;
1639 source+=8;
1640 }while( source<finish );
1641 break;
1642 }
1643
1644 {
1645 unsigned char *pal = &palette_used_colors[pal_start];
1646 int i;
1647 for (i = 0; i < pal_size; i++){
1648 if ( used[i] ){
1649 pal[0] = PALETTE_COLOR_UNUSED;
1650 memset( &pal[1],PALETTE_COLOR_USED,14 );
1651 pal[15] = PALETTE_COLOR_UNUSED;
1652 }
1653 else {
1654 memset( pal, PALETTE_COLOR_UNUSED, 16 );
1655 }
1656 pal += 16;
1657 }
1658 }
1659 #ifdef TRANSPARENT_SHADOWS
1660 if (Machine->scrbitmap->depth == 8) /* 8 bit shadows */
1661 {
1662 memset(&palette_used_colors[Machine->drv->total_colors/2], PALETTE_COLOR_USED, sys16_MaxShadowColors);
1663 }
1664 else if(sys16_MaxShadowColors != 0) /* 16 bit shadows */
1665 {
1666 /* Mark the shadowed versions of the used pens */
1667 memcpy(&palette_used_colors[Machine->drv->total_colors/2], &palette_used_colors[0], Machine->drv->total_colors/2);
1668 }
1669 #endif
1670 }
1671
1672 #ifdef TRANSPARENT_SHADOWS
build_shadow_table(void)1673 static void build_shadow_table(void)
1674 {
1675 int i,size;
1676 int color_start=Machine->drv->total_colors/2;
1677 /* build the shading lookup table */
1678 if (Machine->scrbitmap->depth == 8) /* 8 bit shadows */
1679 {
1680 if(sys16_MaxShadowColors == 0) return;
1681 for (i = 0; i < 256; i++)
1682 {
1683 unsigned char r, g, b;
1684 int y;
1685 osd_get_pen(i, &r, &g, &b);
1686 y = (r * 10 + g * 18 + b * 4) >> sys16_MaxShadowColors_Shift;
1687 shade_table[i] = Machine->pens[color_start + y];
1688 }
1689 for(i=0;i<sys16_MaxShadowColors;i++)
1690 {
1691 shade_table[Machine->pens[color_start + i]]=Machine->pens[color_start + i];
1692 }
1693 }
1694 else
1695 {
1696 if(sys16_MaxShadowColors != 0)
1697 {
1698 size=Machine->drv->total_colors/2;
1699 for(i=0;i<size;i++)
1700 {
1701 shade_table[Machine->pens[i]]=Machine->pens[size + i];
1702 shade_table[Machine->pens[size+i]]=Machine->pens[size + i];
1703 }
1704 }
1705 else
1706 {
1707 size=Machine->drv->total_colors;
1708 for(i=0;i<size;i++)
1709 {
1710 shade_table[Machine->pens[i]]=Machine->pens[i];
1711 }
1712 }
1713 }
1714 }
1715 #else
1716 #define build_shadow_table()
1717 #endif
1718
sys16_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1719 void sys16_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
1720 if( sys16_update_proc ) sys16_update_proc();
1721 update_page();
1722
1723 // from sys16 emu (Not sure if this is the best place for this?)
1724 {
1725 static int freeze_counter=0;
1726 if (!sys16_refreshenable)
1727 {
1728 freeze_counter=4;
1729 sys16_freezepalette=1;
1730 }
1731 if (freeze_counter)
1732 {
1733 if( sys16_clear_screen)
1734 fillbitmap(bitmap,palette_transparent_color,&Machine->visible_area);
1735 freeze_counter--;
1736 return;
1737 }
1738 else if(sys16_freezepalette)
1739 {
1740 sys16_refresh_palette();
1741 sys16_freezepalette=0;
1742 }
1743 }
1744
1745 if( sys16_refreshenable ){
1746
1747 if(sys18_splittab_bg_x)
1748 {
1749 if((sys16_bg_scrollx&0xff00) != sys16_rowscroll_scroll)
1750 {
1751 tilemap_set_scroll_rows( background , 1 );
1752 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1753 }
1754 else
1755 {
1756 int offset, scroll,i;
1757
1758 tilemap_set_scroll_rows( background , 64 );
1759 offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
1760
1761 for(i=0;i<29;i++)
1762 {
1763 scroll = READ_WORD(&sys18_splittab_bg_x[i*2]);
1764 tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1765 }
1766 }
1767 }
1768 else
1769 {
1770 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1771 }
1772
1773 if(sys18_splittab_bg_y)
1774 {
1775 if((sys16_bg_scrolly&0xff00) != sys16_rowscroll_scroll)
1776 {
1777 tilemap_set_scroll_cols( background , 1 );
1778 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1779 }
1780 else
1781 {
1782 int offset, scroll,i;
1783
1784 tilemap_set_scroll_cols( background , 128 );
1785 offset = 127-((sys16_bg_scrollx&0x3f8) >> 3)-40+2;
1786
1787 for(i=0;i<41;i++)
1788 {
1789 scroll = READ_WORD(&sys18_splittab_bg_y[(i+24)&0xfffe]);
1790 tilemap_set_scrolly( background , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1791 }
1792 }
1793 }
1794 else
1795 {
1796 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1797 }
1798
1799 if(sys18_splittab_fg_x)
1800 {
1801 if((sys16_fg_scrollx&0xff00) != sys16_rowscroll_scroll)
1802 {
1803 tilemap_set_scroll_rows( foreground , 1 );
1804 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1805 }
1806 else
1807 {
1808 int offset, scroll,i;
1809
1810 tilemap_set_scroll_rows( foreground , 64 );
1811 offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1812
1813 for(i=0;i<29;i++)
1814 {
1815 scroll = READ_WORD(&sys18_splittab_fg_x[i*2]);
1816
1817
1818 tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1819 }
1820 }
1821 }
1822 else
1823 {
1824 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1825 }
1826
1827 if(sys18_splittab_fg_y)
1828 {
1829 if((sys16_fg_scrolly&0xff00) != sys16_rowscroll_scroll)
1830 {
1831 tilemap_set_scroll_cols( foreground , 1 );
1832 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1833 }
1834 else
1835 {
1836 int offset, scroll,i;
1837
1838 tilemap_set_scroll_cols( foreground , 128 );
1839 offset = 127-((sys16_fg_scrollx&0x3f8) >> 3)-40+2;
1840
1841 for(i=0;i<41;i++)
1842 {
1843 scroll = READ_WORD(&sys18_splittab_fg_y[(i+24)&0xfffe]);
1844 tilemap_set_scrolly( foreground , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1845 }
1846 }
1847 }
1848 else
1849 {
1850 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1851 }
1852
1853 if(sys16_quartet_title_kludge)
1854 {
1855 int top,bottom,left,right;
1856 int top2,bottom2,left2,right2;
1857 struct rectangle clip;
1858
1859 left = background->clip_left;
1860 right = background->clip_right;
1861 top = background->clip_top;
1862 bottom = background->clip_bottom;
1863
1864 left2 = foreground->clip_left;
1865 right2 = foreground->clip_right;
1866 top2 = foreground->clip_top;
1867 bottom2 = foreground->clip_bottom;
1868
1869 clip.min_x=0;
1870 clip.min_y=0;
1871 clip.max_x=1024;
1872 clip.max_y=512;
1873
1874 tilemap_set_clip( background, &clip );
1875 tilemap_set_clip( foreground, &clip );
1876
1877 tilemap_update( ALL_TILEMAPS );
1878
1879 background->clip_left = left;
1880 background->clip_right = right;
1881 background->clip_top = top;
1882 background->clip_bottom = bottom;
1883
1884 foreground->clip_left = left2;
1885 foreground->clip_right = right2;
1886 foreground->clip_top = top2;
1887 foreground->clip_bottom = bottom2;
1888
1889 }
1890 else
1891 tilemap_update( ALL_TILEMAPS );
1892
1893
1894 get_sprite_info();
1895
1896 palette_init_used_colors();
1897 mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
1898 sprite_update();
1899
1900 if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
1901 build_shadow_table();
1902 tilemap_render( ALL_TILEMAPS );
1903
1904 if(!sys16_quartet_title_kludge)
1905 {
1906 tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY );
1907 if(sys16_bg_priority_mode) tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY | 1 );
1908 }
1909 else
1910 draw_quartet_title_screen( bitmap, 0 );
1911
1912 sprite_draw(sprite_list,3); // needed for Aurail
1913 if(sys16_bg_priority_mode==2) tilemap_draw( bitmap, background, 1 ); // body slam (& wrestwar??)
1914 sprite_draw(sprite_list,2);
1915 if(sys16_bg_priority_mode==1) tilemap_draw( bitmap, background, 1 ); // alien syndrome / aurail
1916
1917 if(!sys16_quartet_title_kludge)
1918 {
1919 tilemap_draw( bitmap, foreground, 0 );
1920 sprite_draw(sprite_list,1);
1921 tilemap_draw( bitmap, foreground, 1 );
1922 }
1923 else
1924 {
1925 draw_quartet_title_screen( bitmap, 1 );
1926 sprite_draw(sprite_list,1);
1927 }
1928
1929 if(sys16_textlayer_lo_max!=0) tilemap_draw( bitmap, text_layer, 1 ); // needed for Body Slam
1930 sprite_draw(sprite_list,0);
1931 tilemap_draw( bitmap, text_layer, 0 );
1932 }
1933 #ifdef SYS16_DEBUG
1934 dump_tilemap();
1935 #endif
1936 }
1937
sys18_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1938 void sys18_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
1939 int i;
1940 if( sys16_update_proc ) sys16_update_proc();
1941 update_page();
1942
1943 // from sys16 emu (Not sure if this is the best place for this?)
1944 {
1945 static int freeze_counter=0;
1946 if (!sys16_refreshenable)
1947 {
1948 freeze_counter=4;
1949 sys16_freezepalette=1;
1950 }
1951 if (freeze_counter)
1952 {
1953 // if( sys16_clear_screen)
1954 // fillbitmap(bitmap,palette_transparent_color,&Machine->visible_area);
1955 freeze_counter--;
1956 return;
1957 }
1958 else if(sys16_freezepalette)
1959 {
1960 sys16_refresh_palette();
1961 sys16_freezepalette=0;
1962 }
1963 }
1964
1965 if( sys16_refreshenable ){
1966
1967 if(sys18_splittab_bg_x)
1968 {
1969 int offset,offset2, scroll,scroll2,orig_scroll;
1970
1971 offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
1972 offset2 = 32+((sys16_bg2_scrolly&0x1f8) >> 3);
1973
1974 for(i=0;i<29;i++)
1975 {
1976 orig_scroll = scroll2 = scroll = READ_WORD(&sys18_splittab_bg_x[i*2]);
1977
1978 if((sys16_bg_scrollx &0xff00) != 0x8000)
1979 scroll = sys16_bg_scrollx;
1980
1981 if((sys16_bg2_scrollx &0xff00) != 0x8000)
1982 scroll2 = sys16_bg2_scrollx;
1983
1984 if(orig_scroll&0x8000)
1985 {
1986 tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1987 tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1988 }
1989 else
1990 {
1991 tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1992 tilemap_set_scrollx( background2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1993 }
1994 }
1995 }
1996 else
1997 {
1998 tilemap_set_scrollx( background , 0, -320-(sys16_bg_scrollx&0x3ff)+sys16_bgxoffset );
1999 tilemap_set_scrollx( background2, 0, -320-(sys16_bg2_scrollx&0x3ff)+sys16_bgxoffset );
2000 }
2001
2002 tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
2003 tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
2004
2005 if(sys18_splittab_fg_x)
2006 {
2007 int offset,offset2, scroll,scroll2,orig_scroll;
2008
2009 offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
2010 offset2 = 32+((sys16_fg2_scrolly&0x1f8) >> 3);
2011
2012 for(i=0;i<29;i++)
2013 {
2014 orig_scroll = scroll2 = scroll = READ_WORD(&sys18_splittab_fg_x[i*2]);
2015
2016 if((sys16_fg_scrollx &0xff00) != 0x8000)
2017 scroll = sys16_fg_scrollx;
2018
2019 if((sys16_fg2_scrollx &0xff00) != 0x8000)
2020 scroll2 = sys16_fg2_scrollx;
2021
2022 if(orig_scroll&0x8000)
2023 {
2024 tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
2025 tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
2026 }
2027 else
2028 {
2029 tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
2030 tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
2031 }
2032 }
2033 }
2034 else
2035 {
2036 tilemap_set_scrollx( foreground , 0, -320-(sys16_fg_scrollx&0x3ff)+sys16_fgxoffset );
2037 tilemap_set_scrollx( foreground2, 0, -320-(sys16_fg2_scrollx&0x3ff)+sys16_fgxoffset );
2038 }
2039
2040
2041 tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
2042 tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
2043
2044 tilemap_set_enable( background2, sys18_bg2_active );
2045 tilemap_set_enable( foreground2, sys18_fg2_active );
2046
2047 tilemap_update( ALL_TILEMAPS );
2048 get_sprite_info();
2049
2050 palette_init_used_colors();
2051 mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
2052 sprite_update();
2053
2054 if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
2055 build_shadow_table();
2056 tilemap_render( ALL_TILEMAPS );
2057
2058 if(sys18_bg2_active)
2059 tilemap_draw( bitmap, background2, 0 );
2060 else
2061 fillbitmap(bitmap,palette_transparent_color,&Machine->visible_area);
2062
2063 tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY );
2064 tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY | 1 ); //??
2065 tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY | 2 ); //??
2066
2067 sprite_draw(sprite_list,3);
2068 tilemap_draw( bitmap, background, 1 );
2069 sprite_draw(sprite_list,2);
2070 tilemap_draw( bitmap, background, 2 );
2071
2072 if(sys18_fg2_active) tilemap_draw( bitmap, foreground2, 0 );
2073 tilemap_draw( bitmap, foreground, 0 );
2074 sprite_draw(sprite_list,1);
2075 if(sys18_fg2_active) tilemap_draw( bitmap, foreground2, 1 );
2076 tilemap_draw( bitmap, foreground, 1 );
2077
2078 tilemap_draw( bitmap, text_layer, 1 );
2079 sprite_draw(sprite_list,0);
2080 tilemap_draw( bitmap, text_layer, 0 );
2081 }
2082 }
2083
2084 extern int gr_bitmap_width;
2085
gr_colors(void)2086 static void gr_colors(void)
2087 {
2088 int i;
2089 UINT16 ver_data;
2090 int colorflip;
2091 UINT8 *data_ver=gr_ver;
2092
2093 for(i=0;i<224;i++)
2094 {
2095 ver_data=READ_WORD(data_ver);
2096 palette_used_colors[(READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff) + gr_palette] = PALETTE_COLOR_USED;
2097
2098 if(!((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200))
2099 {
2100 ver_data=ver_data & 0x00ff;
2101 colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2102
2103 palette_used_colors[ gr_colorflip[colorflip][0] + gr_palette_default ] = PALETTE_COLOR_USED;
2104 palette_used_colors[ gr_colorflip[colorflip][1] + gr_palette_default ] = PALETTE_COLOR_USED;
2105 palette_used_colors[ gr_colorflip[colorflip][2] + gr_palette_default ] = PALETTE_COLOR_USED;
2106 palette_used_colors[ gr_colorflip[colorflip][3] + gr_palette_default ] = PALETTE_COLOR_USED;
2107 }
2108 data_ver+=2;
2109 }
2110 }
2111
render_gr(struct osd_bitmap * bitmap,int priority)2112 static void render_gr(struct osd_bitmap *bitmap,int priority)
2113 {
2114 int i,j;
2115 UINT8 *data = memory_region(REGION_GFX3);
2116 UINT8 *source;
2117 UINT8 *line;
2118 UINT16 *line16;
2119 UINT32 *line32;
2120 UINT8 *data_ver=gr_ver;
2121 UINT32 ver_data,hor_pos;
2122 UINT16 colors[5];
2123 // UINT8 colors[5];
2124 UINT32 fastfill;
2125 int colorflip;
2126 int yflip=0,ypos;
2127 int dx=1,xoff=0;
2128
2129 UINT16 *paldata1 = Machine->gfx[0]->colortable + gr_palette;
2130 UINT16 *paldata2 = Machine->gfx[0]->colortable + gr_palette_default;
2131
2132 priority=priority << 10;
2133
2134 if (Machine->scrbitmap->depth == 16) /* 16 bit */
2135 {
2136 if( Machine->orientation & ORIENTATION_SWAP_XY )
2137 {
2138 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2139 dx=-1;
2140 xoff=319;
2141 }
2142 if( Machine->orientation & ORIENTATION_FLIP_X ){
2143 yflip=1;
2144 }
2145
2146 for(i=0;i<224;i++)
2147 {
2148 if(yflip) ypos=223-i;
2149 else ypos=i;
2150 ver_data=READ_WORD(data_ver);
2151 if((ver_data & 0x400) == priority)
2152 {
2153 colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2154
2155 if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2156 {
2157 // fill line
2158 for(j=0;j<320;j++)
2159 {
2160 line16=(UINT16 *)bitmap->line[j]+ypos;
2161 *line16=colors[0];
2162 }
2163 }
2164 else
2165 {
2166 // copy line
2167 ver_data=ver_data & 0x00ff;
2168 colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2169
2170 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2171 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2172 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2173 colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2174
2175 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2176 ver_data = ver_data << gr_bitmap_width;
2177
2178 if(hor_pos & 0xf000)
2179 {
2180 // reverse
2181 hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2182 }
2183 else
2184 {
2185 // normal
2186 hor_pos=(hor_pos+0x200) & 0x3ff;
2187 }
2188
2189 source = data + hor_pos + ver_data + 18 + 8;
2190
2191 for(j=0;j<320;j++)
2192 {
2193 line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
2194 *line16 = colors[*source++];
2195 }
2196 }
2197 }
2198 data_ver+=2;
2199 }
2200 }
2201 else
2202 {
2203 if( Machine->orientation & ORIENTATION_FLIP_X ){
2204 dx=-1;
2205 xoff=319;
2206 }
2207 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2208 yflip=1;
2209 }
2210
2211 for(i=0;i<224;i++)
2212 {
2213 if(yflip) ypos=223-i;
2214 else ypos=i;
2215 ver_data=READ_WORD(data_ver);
2216 if((ver_data & 0x400) == priority)
2217 {
2218 colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2219
2220 if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2221 {
2222 line16=(UINT16 *)bitmap->line[ypos];
2223 for(j=0;j<320;j++)
2224 {
2225 *line16++=colors[0];
2226 }
2227 }
2228 else
2229 {
2230 // copy line
2231 line16 = (UINT16 *)bitmap->line[ypos]+xoff;
2232 ver_data=ver_data & 0x00ff;
2233 colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2234
2235 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2236 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2237 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2238 colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2239
2240 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2241 ver_data = ver_data << gr_bitmap_width;
2242
2243 if(hor_pos & 0xf000)
2244 {
2245 // reverse
2246 hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2247 }
2248 else
2249 {
2250 // normal
2251 hor_pos=(hor_pos+0x200) & 0x3ff;
2252 }
2253
2254 source = data + hor_pos + ver_data + 18 + 8;
2255
2256 for(j=0;j<320;j++)
2257 {
2258 *line16 = colors[*source++];
2259 line16+=dx;
2260 }
2261 }
2262 }
2263 data_ver+=2;
2264 }
2265 }
2266 }
2267 else /* 8 bit */
2268 {
2269 if( Machine->orientation & ORIENTATION_SWAP_XY )
2270 {
2271 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2272 dx=-1;
2273 xoff=319;
2274 }
2275 if( Machine->orientation & ORIENTATION_FLIP_X ){
2276 yflip=1;
2277 }
2278
2279 for(i=0;i<224;i++)
2280 {
2281 if(yflip) ypos=223-i;
2282 else ypos=i;
2283 ver_data=READ_WORD(data_ver);
2284 if((ver_data & 0x400) == priority)
2285 {
2286 colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2287
2288 if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2289 {
2290 // fill line
2291 for(j=0;j<320;j++)
2292 {
2293 bitmap->line[j][ypos]=colors[0];
2294 }
2295 }
2296 else
2297 {
2298 // copy line
2299 ver_data=ver_data & 0x00ff;
2300 colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2301
2302 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2303 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2304 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2305 colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2306
2307 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2308 ver_data = ver_data << gr_bitmap_width;
2309
2310 if(hor_pos & 0xf000)
2311 {
2312 // reverse
2313 hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2314 }
2315 else
2316 {
2317 // normal
2318 hor_pos=(hor_pos+0x200) & 0x3ff;
2319 }
2320
2321 source = data + hor_pos + ver_data + 18 + 8;
2322
2323 for(j=0;j<320;j++)
2324 {
2325 bitmap->line[xoff+j*dx][ypos] = colors[*source++];
2326 }
2327 }
2328 }
2329 data_ver+=2;
2330 }
2331 }
2332 else
2333 {
2334 if( Machine->orientation & ORIENTATION_FLIP_X ){
2335 dx=-1;
2336 xoff=319;
2337 }
2338 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2339 yflip=1;
2340 }
2341
2342 for(i=0;i<224;i++)
2343 {
2344 if(yflip) ypos=223-i;
2345 else ypos=i;
2346 ver_data=READ_WORD(data_ver);
2347 if((ver_data & 0x400) == priority)
2348 {
2349 colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2350
2351 if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2352 {
2353 // fill line
2354 line32 = (UINT32 *)bitmap->line[ypos];
2355 fastfill = colors[0] + (colors[0] << 8) + (colors[0] << 16) + (colors[0] << 24);
2356 for(j=0;j<320;j+=4)
2357 {
2358 *line32++ = fastfill;
2359 }
2360 }
2361 else
2362 {
2363 // copy line
2364 line = bitmap->line[ypos]+xoff;
2365 ver_data=ver_data & 0x00ff;
2366 colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2367
2368 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2369 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2370 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2371 colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2372
2373 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2374 ver_data = ver_data << gr_bitmap_width;
2375
2376 if(hor_pos & 0xf000)
2377 {
2378 // reverse
2379 hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2380 }
2381 else
2382 {
2383 // normal
2384 hor_pos=(hor_pos+0x200) & 0x3ff;
2385 }
2386
2387 source = data + hor_pos + ver_data + 18 + 8;
2388
2389 for(j=0;j<320;j++)
2390 {
2391 *line = colors[*source++];
2392 line+=dx;
2393 }
2394 }
2395 }
2396 data_ver+=2;
2397 }
2398 }
2399 }
2400 }
2401
2402
2403
2404
2405 // Refresh for hang-on, etc.
sys16_ho_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)2406 void sys16_ho_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
2407 if( sys16_update_proc ) sys16_update_proc();
2408 update_page();
2409
2410 // from sys16 emu (Not sure if this is the best place for this?)
2411 {
2412 static int freeze_counter=0;
2413 if (!sys16_refreshenable)
2414 {
2415 freeze_counter=4;
2416 sys16_freezepalette=1;
2417 }
2418 if (freeze_counter)
2419 {
2420 freeze_counter--;
2421 return;
2422 }
2423 else if(sys16_freezepalette)
2424 {
2425 sys16_refresh_palette();
2426 sys16_freezepalette=0;
2427 }
2428 }
2429
2430 if( sys16_refreshenable ){
2431
2432 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
2433 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
2434
2435 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
2436 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
2437
2438 tilemap_update( ALL_TILEMAPS );
2439 get_sprite_info();
2440
2441 palette_init_used_colors();
2442 mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
2443 sprite_update();
2444 gr_colors();
2445
2446 if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
2447 build_shadow_table();
2448 tilemap_render( ALL_TILEMAPS );
2449
2450 render_gr(bitmap,0);
2451
2452 tilemap_draw( bitmap, background, 0 );
2453 tilemap_draw( bitmap, foreground, 0 );
2454
2455 render_gr(bitmap,1);
2456
2457 sprite_draw(sprite_list,0);
2458 tilemap_draw( bitmap, text_layer, 0 );
2459
2460 }
2461
2462 #ifdef SYS16_DEBUG
2463 dump_tilemap();
2464 #endif
2465 }
2466
2467
grv2_colors(void)2468 static void grv2_colors(void)
2469 {
2470 int i;
2471 UINT16 ver_data;
2472 int colorflip,colorflip_info;
2473 UINT8 *data_ver=gr_ver;
2474
2475 for(i=0;i<224;i++)
2476 {
2477 ver_data=READ_WORD(data_ver);
2478
2479 if(!(ver_data & 0x800))
2480 {
2481 ver_data=ver_data & 0x01ff;
2482 colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2483
2484 palette_used_colors[ (((colorflip_info >> 8) & 0x1f) + 0x20) + gr_palette_default] = PALETTE_COLOR_USED;
2485
2486 colorflip = (colorflip_info >> 3) & 1;
2487
2488 palette_used_colors[ gr_colorflip[colorflip][0] + gr_palette_default ] = PALETTE_COLOR_USED;
2489 palette_used_colors[ gr_colorflip[colorflip][1] + gr_palette_default ] = PALETTE_COLOR_USED;
2490 palette_used_colors[ gr_colorflip[colorflip][2] + gr_palette_default ] = PALETTE_COLOR_USED;
2491 }
2492 else
2493 {
2494 palette_used_colors[(ver_data&0x3f) + gr_palette] = PALETTE_COLOR_USED;
2495 }
2496 data_ver+=2;
2497 }
2498 }
2499
render_grv2(struct osd_bitmap * bitmap,int priority)2500 static void render_grv2(struct osd_bitmap *bitmap,int priority)
2501 {
2502 int i,j;
2503 UINT8 *data = memory_region(REGION_GFX3);
2504 UINT8 *source,*source2,*temp;
2505 UINT8 *line;
2506 UINT16 *line16;
2507 UINT32 *line32;
2508 UINT8 *data_ver=gr_ver;
2509 UINT32 ver_data,hor_pos,hor_pos2;
2510 UINT16 colors[5];
2511 UINT32 fastfill;
2512 int colorflip,colorflip_info;
2513 int yflip=0,ypos;
2514 int dx=1,xoff=0;
2515
2516 int second_road = READ_WORD(gr_second_road);
2517
2518 UINT16 *paldata1 = Machine->gfx[0]->colortable + gr_palette;
2519 UINT16 *paldata2 = Machine->gfx[0]->colortable + gr_palette_default;
2520
2521 priority=priority << 11;
2522
2523 if (Machine->scrbitmap->depth == 16) /* 16 bit */
2524 {
2525 if( Machine->orientation & ORIENTATION_SWAP_XY )
2526 {
2527 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2528 dx=-1;
2529 xoff=319;
2530 }
2531 if( Machine->orientation & ORIENTATION_FLIP_X ){
2532 yflip=1;
2533 }
2534
2535 for(i=0;i<224;i++)
2536 {
2537 if(yflip) ypos=223-i;
2538 else ypos=i;
2539 ver_data=READ_WORD(data_ver);
2540 if((ver_data & 0x800) == priority)
2541 {
2542
2543 if(ver_data & 0x800)
2544 {
2545 colors[0] = paldata1[ ver_data&0x3f ];
2546 // fill line
2547 for(j=0;j<320;j++)
2548 {
2549 line16=(UINT16 *)bitmap->line[j]+ypos;
2550 *line16=colors[0];
2551 }
2552 }
2553 else
2554 {
2555 // copy line
2556 ver_data=ver_data & 0x01ff; //???
2557 colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2558
2559 colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ]; //??
2560
2561 colorflip = (colorflip_info >> 3) & 1;
2562
2563 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2564 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2565 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2566
2567 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2568 hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2569
2570 ver_data=ver_data>>1;
2571 if( ver_data != 0 )
2572 {
2573 ver_data = (ver_data-1) << gr_bitmap_width;
2574 }
2575
2576 source = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2577 source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2578
2579 switch(second_road)
2580 {
2581 case 0: source2=source; break;
2582 case 2: temp=source;source=source2;source2=temp; break;
2583 case 3: source=source2; break;
2584 }
2585
2586 source2++;
2587
2588 for(j=0;j<320;j++)
2589 {
2590 line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
2591 if(*source2 <= *source)
2592 *line16 = colors[*source];
2593 else
2594 *line16 = colors[*source2];
2595 source++;
2596 source2++;
2597 }
2598 }
2599 }
2600 data_ver+=2;
2601 }
2602 }
2603 else
2604 {
2605 if( Machine->orientation & ORIENTATION_FLIP_X ){
2606 dx=-1;
2607 xoff=319;
2608 }
2609 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2610 yflip=1;
2611 }
2612
2613 for(i=0;i<224;i++)
2614 {
2615 if(yflip) ypos=223-i;
2616 else ypos=i;
2617 ver_data=READ_WORD(data_ver);
2618 if((ver_data & 0x800) == priority)
2619 {
2620
2621 if(ver_data & 0x800)
2622 {
2623 colors[0] = paldata1[ ver_data&0x3f ];
2624 // fill line
2625 line16 = (UINT16 *)bitmap->line[ypos];
2626 for(j=0;j<320;j++)
2627 {
2628 *line16++ = colors[0];
2629 }
2630 }
2631 else
2632 {
2633 // copy line
2634 line16 = (UINT16 *)bitmap->line[ypos]+xoff;
2635 ver_data=ver_data & 0x01ff; //???
2636 colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2637
2638 colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ]; //??
2639
2640 colorflip = (colorflip_info >> 3) & 1;
2641
2642 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2643 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2644 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2645
2646 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2647 hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2648
2649 ver_data=ver_data>>1;
2650 if( ver_data != 0 )
2651 {
2652 ver_data = (ver_data-1) << gr_bitmap_width;
2653 }
2654
2655 source = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2656 source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2657
2658 switch(second_road)
2659 {
2660 case 0: source2=source; break;
2661 case 2: temp=source;source=source2;source2=temp; break;
2662 case 3: source=source2; break;
2663 }
2664
2665 source2++;
2666
2667 for(j=0;j<320;j++)
2668 {
2669 if(*source2 <= *source)
2670 *line16 = colors[*source];
2671 else
2672 *line16 = colors[*source2];
2673 source++;
2674 source2++;
2675 line16+=dx;
2676 }
2677 }
2678 }
2679 data_ver+=2;
2680 }
2681 }
2682 }
2683 else
2684 {
2685 if( Machine->orientation & ORIENTATION_SWAP_XY )
2686 {
2687 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2688 dx=-1;
2689 xoff=319;
2690 }
2691 if( Machine->orientation & ORIENTATION_FLIP_X ){
2692 yflip=1;
2693 }
2694
2695 for(i=0;i<224;i++)
2696 {
2697 if(yflip) ypos=223-i;
2698 else ypos=i;
2699 ver_data=READ_WORD(data_ver);
2700 if((ver_data & 0x800) == priority)
2701 {
2702
2703 if(ver_data & 0x800)
2704 {
2705 colors[0] = paldata1[ ver_data&0x3f ];
2706 // fill line
2707 for(j=0;j<320;j++)
2708 {
2709 bitmap->line[j][ypos]=colors[0];
2710 }
2711 }
2712 else
2713 {
2714 // copy line
2715 ver_data=ver_data & 0x01ff; //???
2716 colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2717
2718 colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ]; //??
2719
2720 colorflip = (colorflip_info >> 3) & 1;
2721
2722 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2723 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2724 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2725
2726 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2727 hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2728
2729 ver_data=ver_data>>1;
2730 if( ver_data != 0 )
2731 {
2732 ver_data = (ver_data-1) << gr_bitmap_width;
2733 }
2734
2735 source = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2736 source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2737
2738 switch(second_road)
2739 {
2740 case 0: source2=source; break;
2741 case 2: temp=source;source=source2;source2=temp; break;
2742 case 3: source=source2; break;
2743 }
2744
2745 source2++;
2746
2747 for(j=0;j<320;j++)
2748 {
2749 if(*source2 <= *source)
2750 bitmap->line[xoff+j*dx][ypos] = colors[*source];
2751 else
2752 bitmap->line[xoff+j*dx][ypos] = colors[*source2];
2753 source++;
2754 source2++;
2755 }
2756 }
2757 }
2758 data_ver+=2;
2759 }
2760 }
2761 else
2762 {
2763 if( Machine->orientation & ORIENTATION_FLIP_X ){
2764 dx=-1;
2765 xoff=319;
2766 }
2767 if( Machine->orientation & ORIENTATION_FLIP_Y ){
2768 yflip=1;
2769 }
2770
2771 for(i=0;i<224;i++)
2772 {
2773 if(yflip) ypos=223-i;
2774 else ypos=i;
2775 ver_data=READ_WORD(data_ver);
2776 if((ver_data & 0x800) == priority)
2777 {
2778
2779 if(ver_data & 0x800)
2780 {
2781 colors[0] = paldata1[ ver_data&0x3f ];
2782 // fill line
2783 line32 = (UINT32 *)bitmap->line[ypos];
2784 fastfill = colors[0] + (colors[0] << 8) + (colors[0] << 16) + (colors[0] << 24);
2785 for(j=0;j<320;j+=4)
2786 {
2787 *line32++ = fastfill;
2788 }
2789 }
2790 else
2791 {
2792 // copy line
2793 line = bitmap->line[ypos]+xoff;
2794 ver_data=ver_data & 0x01ff; //???
2795 colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2796
2797 colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ]; //??
2798
2799 colorflip = (colorflip_info >> 3) & 1;
2800
2801 colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2802 colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2803 colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2804
2805 hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2806 hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2807
2808 ver_data=ver_data>>1;
2809 if( ver_data != 0 )
2810 {
2811 ver_data = (ver_data-1) << gr_bitmap_width;
2812 }
2813
2814 source = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2815 source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2816
2817 switch(second_road)
2818 {
2819 case 0: source2=source; break;
2820 case 2: temp=source;source=source2;source2=temp; break;
2821 case 3: source=source2; break;
2822 }
2823
2824 source2++;
2825
2826 for(j=0;j<320;j++)
2827 {
2828 if(*source2 <= *source)
2829 *line = colors[*source];
2830 else
2831 *line = colors[*source2];
2832 source++;
2833 source2++;
2834 line+=dx;
2835 }
2836 }
2837 }
2838 data_ver+=2;
2839 }
2840 }
2841 }
2842 }
2843
2844 // Refresh for Outrun
sys16_or_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)2845 void sys16_or_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
2846 if( sys16_update_proc ) sys16_update_proc();
2847 update_page();
2848
2849 // from sys16 emu (Not sure if this is the best place for this?)
2850 {
2851 static int freeze_counter=0;
2852 if (!sys16_refreshenable)
2853 {
2854 freeze_counter=4;
2855 sys16_freezepalette=1;
2856 }
2857 if (freeze_counter)
2858 {
2859 freeze_counter--;
2860 return;
2861 }
2862 else if(sys16_freezepalette)
2863 {
2864 sys16_refresh_palette();
2865 sys16_freezepalette=0;
2866 }
2867 }
2868
2869 if( sys16_refreshenable ){
2870
2871 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
2872 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
2873
2874 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
2875 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
2876
2877 tilemap_update( ALL_TILEMAPS );
2878 get_sprite_info();
2879
2880 palette_init_used_colors();
2881 mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
2882 sprite_update();
2883 grv2_colors();
2884
2885 if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
2886 build_shadow_table();
2887 tilemap_render( ALL_TILEMAPS );
2888
2889 render_grv2(bitmap,1);
2890
2891 tilemap_draw( bitmap, background, 0 );
2892 tilemap_draw( bitmap, foreground, 0 );
2893
2894 render_grv2(bitmap,0);
2895
2896 sprite_draw(sprite_list,0);
2897
2898 tilemap_draw( bitmap, text_layer, 0 );
2899
2900 }
2901
2902 #ifdef SYS16_DEBUG
2903 dump_tilemap();
2904 #endif
2905 }
2906
2907
2908 // hideous kludge to display quartet title screen correctly
draw_quartet_title_screen(struct osd_bitmap * bitmap,int playfield)2909 static void draw_quartet_title_screen( struct osd_bitmap *bitmap,int playfield )
2910 {
2911 unsigned char *xscroll,*yscroll;
2912 int r,c,scroll;
2913 struct tilemap *tilemap;
2914 struct rectangle clip;
2915
2916 int top,bottom,left,right;
2917
2918
2919 if(playfield==0) // background
2920 {
2921 xscroll=&sys16_textram[0x0fc0];
2922 yscroll=&sys16_textram[0x0f58];
2923 tilemap=background;
2924 }
2925 else
2926 {
2927 xscroll=&sys16_textram[0x0f80];
2928 yscroll=&sys16_textram[0x0f30];
2929 tilemap=foreground;
2930 }
2931
2932 left = tilemap->clip_left;
2933 right = tilemap->clip_right;
2934 top = tilemap->clip_top;
2935 bottom = tilemap->clip_bottom;
2936
2937 for(r=0;r<14;r++)
2938 {
2939 clip.min_y=r*16;
2940 clip.max_y=r*16+15;
2941 for(c=0;c<10;c++)
2942 {
2943 clip.min_x=c*32;
2944 clip.max_x=c*32+31;
2945 tilemap_set_clip( tilemap, &clip );
2946 scroll = READ_WORD(&xscroll[r*4])&0x3ff;
2947 tilemap_set_scrollx( tilemap, 0, (-320-scroll+sys16_bgxoffset)&0x3ff );
2948 scroll = READ_WORD(&yscroll[c*4])&0x1ff;
2949 tilemap_set_scrolly( tilemap, 0, (-256+scroll)&0x1ff );
2950 tilemap_draw( bitmap, tilemap, 0 );
2951 }
2952 }
2953 /*
2954 for(r=0;r<28;r++)
2955 {
2956 clip.min_y=r*8;
2957 clip.max_y=r*8+7;
2958 for(c=0;c<20;c++)
2959 {
2960 clip.min_x=c*16;
2961 clip.max_x=c*16+15;
2962 tilemap_set_clip( tilemap, &clip );
2963 scroll = READ_WORD(&xscroll[r*2])&0x3ff;
2964 tilemap_set_scrollx( tilemap, 0, (-320-scroll+sys16_bgxoffset)&0x3ff );
2965 scroll = READ_WORD(&yscroll[c*2])&0x1ff;
2966 tilemap_set_scrolly( tilemap, 0, (-256+scroll)&0x1ff );
2967 tilemap_draw( bitmap, tilemap, 0 );
2968 }
2969 }
2970 */
2971 tilemap->clip_left = left;
2972 tilemap->clip_right = right;
2973 tilemap->clip_top = top;
2974 tilemap->clip_bottom = bottom;
2975 }
2976
2977
2978 #ifdef SYS16_DEBUG
dump_tilemap(void)2979 void dump_tilemap(void)
2980 {
2981 const UINT16 *source;
2982 int row,col,r,c;
2983 int data;
2984
2985 if(!keyboard_pressed_memory(KEYCODE_Y)) return;
2986
2987 logerror("Back %2x %2x %2x %2x\n",sys16_bg_page[0],sys16_bg_page[1],sys16_bg_page[2],sys16_bg_page[3]);
2988 for(r=0;r<64;r++)
2989 {
2990 for(c=0;c<128;c++)
2991 {
2992 source = (const UINT16 *)sys16_tileram;
2993 row=r;col=c;
2994 if( row<32 ){
2995 if( col<64 ){
2996 source += 64*32*sys16_bg_page[0];
2997 }
2998 else {
2999 source += 64*32*sys16_bg_page[1];
3000 }
3001 }
3002 else {
3003 if( col<64 ){
3004 source += 64*32*sys16_bg_page[2];
3005 }
3006 else {
3007 source += 64*32*sys16_bg_page[3];
3008 }
3009 }
3010 row = row%32;
3011 col = col%64;
3012
3013 data = source[row*64+col];
3014 logerror("%4x ",data);
3015 }
3016 logerror("\n");
3017 }
3018
3019 logerror("Front %2x %2x %2x %2x\n",sys16_fg_page[0],sys16_fg_page[1],sys16_fg_page[2],sys16_fg_page[3]);
3020 for(r=0;r<64;r++)
3021 {
3022 for(c=0;c<128;c++)
3023 {
3024 source = (const UINT16 *)sys16_tileram;
3025 row=r;col=c;
3026 if( row<32 ){
3027 if( col<64 ){
3028 source += 64*32*sys16_fg_page[0];
3029 }
3030 else {
3031 source += 64*32*sys16_fg_page[1];
3032 }
3033 }
3034 else {
3035 if( col<64 ){
3036 source += 64*32*sys16_fg_page[2];
3037 }
3038 else {
3039 source += 64*32*sys16_fg_page[3];
3040 }
3041 }
3042 row = row%32;
3043 col = col%64;
3044
3045 data = source[row*64+col];
3046 logerror("%4x ",data);
3047 }
3048 logerror("\n");
3049 }
3050
3051 logerror("Text\n");
3052 for(r=0;r<28;r++)
3053 {
3054 for(c=0;c<64;c++)
3055 {
3056 source = (const UINT16 *)sys16_textram;
3057 data = source[r*64+c];
3058 logerror("%4x ",data);
3059 }
3060 logerror("\n");
3061 }
3062 }
3063 #endif
3064
3065