1 /***************************************************************************
2
3 Sega System 16 Video Hardware
4
5 Known issues:
6 - better abstraction of tilemap hardware is needed; a lot of this mess could and should
7 be consolidated further
8 - many games have ROM patches - why? let's emulate protection when possible
9 - several games fail their RAM self-test because of hacks in the drivers
10 - many registers are suspiciously plucked from working RAM
11 - several games have nvram according to the self test, but we aren't yet saving it
12 - many games suffer from sys16_refreshenable register not being mapped
13 - hangon road isn't displayed(!) emulation bug?
14 - road-rendering routines need to be cleaned up or at least better described
15 - logical sprite height computation isn't quite right - garbage pixels are drawn
16 - screen orientation support for sprite drawing
17 - sprite drawing is unoptimized
18 - end-of-sprite marker support will fix some glitches
19 - shadow and partial shadow sprite support
20 - to achieve sprite-tilemap orthogonality we must draw sprites from front to back;
21 this will also allow us to avoid processing the same shadowed pixel twice.
22
23 The System16 video hardware consists of:
24
25 - Road Layer (present only for certain games)
26
27 - Two scrolling tilemap layers
28
29 - Two alternate scrolling tilemap layers, normally invisible.
30
31 - A fixed tilemap layer, normally used for score, lives display
32
33 Each scrolling layer (foreground, background) is an arrangement
34 of 4 pages selected from 16 available pages, laid out as follows:
35
36 Page0 Page1
37 Page2 Page3
38
39 Each page is an arrangement of 8x8 tiles, 64 tiles wide, and 32 tiles high.
40
41 Layers normally scroll as a whole, with xscroll and yscroll.
42
43 However, layers can also be configured with screenwise rowscroll, if the most significant
44 bit of xscroll is set. When a layer is in this mode, the splittable is used.
45
46 When rowscroll is in effect, the most significant bit of rowscroll selects between the
47 default layer and an alternate layer associated with it.
48
49 The foreground layer's tiles may be flagged as high-priority; this is used to mask
50 sprites, i.e. the grass in Altered Beast.
51
52 The background layer's tiles may also be flagged as high-priority. In this case,
53 it's really a transparency_pen effect rather. Aurail uses this.
54
55 Most games map Video Registers in textram as follows:
56
57 type0:
58 most games
59
60 type1:
61 alexkidd,fantzone,shinobl,hangon
62 mjleague
63
64 others:
65 shangon, shdancbl,
66 dduxbl,eswat,
67 passsht,passht4b
68 quartet,quartet2,
69 tetris,tturfbl,wb3bl
70
71 sys16_textram:
72 type1 type0 function
73 ---------------------------------------
74 0x74f 0x740 sys16_fg_page
75 0x74e 0x741 sys16_bg_page
76 0x742 sys16_fg2_page
77 0x743 sys16_bg2_page
78
79 0x792 0x748 sys16_fg_scrolly
80 0x793 0x749 sys16_bg_scrolly
81 0x74a sys16_fg2_scrolly
82 0x74b sys16_bg2_scrolly
83
84 0x7fc 0x74c sys16_fg_scrollx
85 0x7fd 0x74d sys16_bg_scrollx
86 0x74e sys16_fg2_scrollx
87 0x74f sys16_bg2_scrollx
88
89 0x7c0..0x7df sys18_splittab_fg_x
90 0x7e0..0x7ff sys18_splittab_bg_x
91
92 ***************************************************************************/
93 #include "driver.h"
94 #include "system16.h"
95
96 /*
97 static void debug_draw( struct mame_bitmap *bitmap, int x, int y, unsigned int data ){
98 int digit;
99 for( digit=0; digit<4; digit++ ){
100 drawgfx( bitmap, Machine->uifont,
101 "0123456789abcdef"[data>>12],
102 0,
103 0,0,
104 x+digit*6,y,
105 &Machine->visible_area,TRANSPARENCY_NONE,0);
106 data = (data<<4)&0xffff;
107 }
108 }
109
110 static void debug_vreg( struct mame_bitmap *bitmap ){
111 int g = 0x740;
112 int i;
113
114 if( keyboard_pressed( KEYCODE_Q ) ) g+=0x10;
115 if( keyboard_pressed( KEYCODE_W ) ) g+=0x20;
116 if( keyboard_pressed( KEYCODE_E ) ) g+=0x40;
117 if( keyboard_pressed( KEYCODE_R ) ) g+=0x80;
118
119 for( i=0; i<16; i++ ){
120 debug_draw( bitmap, 8,8*i,sys16_textram[g+i] );
121 }
122 }
123 */
124
125 /* callback to poll video registers */
126 void (* sys16_update_proc)( void );
127
128 data16_t *sys16_tileram;
129 data16_t *sys16_textram;
130 data16_t *sys16_spriteram;
131 data16_t *sys16_roadram;
132
133 static int num_sprites;
134
135 #define MAXCOLOURS 0x2000 /* 8192 */
136
137 int sys16_sh_shadowpal;
138 int sys16_MaxShadowColors;
139
140 /* video driver constants (potentially different for each game) */
141 int sys16_gr_bitmap_width;
142 int (*sys16_spritesystem)( struct sys16_sprite_attributes *sprite, const UINT16 *source, int bJustGetColor );
143 int *sys16_obj_bank;
144 int sys16_sprxoffset;
145 int sys16_bgxoffset;
146 int sys16_fgxoffset;
147 int sys16_textmode;
148 int sys16_textlayer_lo_min;
149 int sys16_textlayer_lo_max;
150 int sys16_textlayer_hi_min;
151 int sys16_textlayer_hi_max;
152 int sys16_dactype;
153 int sys16_bg1_trans; // alien syn + sys18
154 int sys16_bg_priority_mode;
155 int sys16_fg_priority_mode;
156 int sys16_bg_priority_value;
157 int sys16_fg_priority_value;
158 int sys16_18_mode;
159 int sys16_spritelist_end;
160 int sys16_tilebank_switch;
161 int sys16_rowscroll_scroll;
162 int sys16_quartet_title_kludge;
163
164 /* video registers */
165 int sys16_tile_bank1;
166 int sys16_tile_bank0;
167 int sys16_refreshenable;
168
169 int sys16_bg_scrollx, sys16_bg_scrolly;
170 int sys16_bg2_scrollx, sys16_bg2_scrolly;
171 int sys16_fg_scrollx, sys16_fg_scrolly;
172 int sys16_fg2_scrollx, sys16_fg2_scrolly;
173
174 int sys16_bg_page[4];
175 int sys16_bg2_page[4];
176 int sys16_fg_page[4];
177 int sys16_fg2_page[4];
178
179 int sys18_bg2_active;
180 int sys18_fg2_active;
181 data16_t *sys18_splittab_bg_x;
182 data16_t *sys18_splittab_bg_y;
183 data16_t *sys18_splittab_fg_x;
184 data16_t *sys18_splittab_fg_y;
185
186 data16_t *sys16_gr_ver;
187 data16_t *sys16_gr_hor;
188 data16_t *sys16_gr_pal;
189 data16_t *sys16_gr_flip;
190 int sys16_gr_palette;
191 int sys16_gr_palette_default;
192 unsigned char sys16_gr_colorflip[2][4];
193 data16_t *sys16_gr_second_road;
194
195 static struct tilemap *background, *foreground, *text_layer;
196 static struct tilemap *background2, *foreground2;
197 static int old_bg_page[4],old_fg_page[4], old_tile_bank1, old_tile_bank0;
198 static int old_bg2_page[4],old_fg2_page[4];
199
200 /***************************************************************************/
201
READ16_HANDLER(sys16_textram_r)202 READ16_HANDLER( sys16_textram_r ){
203 return sys16_textram[offset];
204 }
205
READ16_HANDLER(sys16_tileram_r)206 READ16_HANDLER( sys16_tileram_r ){
207 return sys16_tileram[offset];
208 }
209
210 /***************************************************************************/
211
212 /*
213 We mark the priority buffer as follows:
214 text (0xf)
215 fg (hi) (0x7)
216 fg (lo) (0x3)
217 bg (hi) (0x1)
218 bg (lo) (0x0)
219
220 Each sprite has 4 levels of priority, specifying where they are placed between bg(lo) and text.
221 */
222
draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect,const unsigned char * addr,int pitch,const pen_t * paldata,int x0,int y0,int screen_width,int screen_height,int width,int height,int flipx,int flipy,int priority,int shadow,int shadow_pen,int eos)223 static void draw_sprite( //*
224 struct mame_bitmap *bitmap,
225 const struct rectangle *cliprect,
226 const unsigned char *addr, int pitch,
227 const pen_t *paldata,
228 int x0, int y0, int screen_width, int screen_height,
229 int width, int height,
230 int flipx, int flipy,
231 int priority,
232 int shadow,
233 int shadow_pen, int eos )
234 {
235 const pen_t *shadow_base = Machine->gfx[0]->colortable + (Machine->drv->total_colors/2);
236 const UINT8 *source;
237 int full_shadow=shadow&SYS16_SPR_SHADOW;
238 int partial_shadow=shadow&SYS16_SPR_PARTIAL_SHADOW;
239 int shadow_mask=(Machine->drv->total_colors/2)-1;
240 int sx, x, xcount;
241 int sy, y, ycount = 0;
242 int dx,dy;
243 UINT16 *dest;
244 UINT8 *pri;
245 unsigned pen, data;
246
247 priority = 1<<priority;
248
249 if( flipy ){
250 dy = -1;
251 y0 += screen_height-1;
252 }
253 else {
254 dy = 1;
255 }
256
257 if( flipx ){
258 dx = -1;
259 x0 += screen_width-1;
260 }
261 else {
262 dx = 1;
263 }
264
265 if (!eos)
266 {
267 sy = y0;
268 for( y=height; y; y-- ){
269 ycount += screen_height;
270 while( ycount>=height ){
271 if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
272 source = addr;
273 dest = (UINT16 *)bitmap->line[sy];
274 pri = priority_bitmap->line[sy];
275 sx = x0;
276 xcount = 0;
277 for( x=width; x; x-=2 ){
278 data = (unsigned)*source++; /* next 2 pixels */
279 pen = data>>4;
280 xcount += screen_width;
281 while( xcount>=width )
282 {
283 if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
284 if(!(pri[sx]&priority)){
285 if (full_shadow)
286 dest[sx] = shadow_base[dest[sx]&shadow_mask];
287 else if (partial_shadow && pen==shadow_pen)
288 dest[sx] = shadow_base[dest[sx]&shadow_mask];
289 else
290 dest[sx] = paldata[pen];
291 }
292 }
293 xcount -= width;
294 sx+=dx;
295 }
296 pen = data&0xf;
297 xcount += screen_width;
298 while( xcount>=width )
299 {
300 if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
301 if(!(pri[sx]&priority)){
302 if (full_shadow)
303 dest[sx] = shadow_base[dest[sx]&shadow_mask];
304 else if (partial_shadow && pen==shadow_pen)
305 dest[sx] = shadow_base[dest[sx]&shadow_mask];
306 else
307 dest[sx] = paldata[pen];
308 }
309 }
310 xcount -= width;
311 sx+=dx;
312 }
313 }
314 }
315 ycount -= height;
316 sy+=dy;
317 }
318 addr += pitch;
319 }
320 }
321 else
322 {
323 sy = y0;
324 for( y=height; y; y-- ){
325 ycount += screen_height;
326 while( ycount>=height ){
327 if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
328 source = addr;
329 dest = (UINT16 *)bitmap->line[sy];
330 pri = priority_bitmap->line[sy];
331 sx = x0;
332 xcount = 0;
333 for( x=width; x; x-=2 ){
334 data = (unsigned)*source++; /* next 2 pixels */
335 pen = data>>4;
336 if (pen==0xf) break;
337 xcount += screen_width;
338 while( xcount>=width )
339 {
340 if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x )
341 if(!(pri[sx]&priority)) dest[sx] = paldata[pen];
342 xcount -= width;
343 sx+=dx;
344 }
345 pen = data&0xf;
346 xcount += screen_width;
347 while( xcount>=width )
348 {
349 if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x )
350 if(!(pri[sx]&priority)) dest[sx] = paldata[pen];
351 xcount -= width;
352 sx+=dx;
353 }
354 }
355 }
356 ycount -= height;
357 sy+=dy;
358 }
359 addr += pitch;
360 }
361 }
362 }
363
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int b3d)364 static void draw_sprites( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int b3d ) //*
365 {
366 const pen_t *base_pal = Machine->gfx[0]->colortable;
367 const unsigned char *base_gfx = memory_region(REGION_GFX2);
368 const int gfx_rom_size = memory_region_length(REGION_GFX2);
369 const data16_t *source = sys16_spriteram;
370 struct sys16_sprite_attributes sprite;
371 int xpos, ypos, screen_width, width, logical_height, pitch, flipy, flipx;
372 int i, mod_h, mod_x, eos;
373 unsigned gfx;
374
375 memset(&sprite, 0x00, sizeof(sprite));
376
377 for(i=0; i<num_sprites; i++)
378 {
379 sprite.flags = 0;
380 if (sys16_spritesystem(&sprite, source, 0)) return; /* end-of-spritelist */
381 source += 8;
382
383 if( sprite.flags & SYS16_SPR_VISIBLE )
384 {
385 xpos = sprite.x;
386 flipx = sprite.flags & SYS16_SPR_FLIPX;
387 ypos = sprite.y;
388 pitch = sprite.pitch;
389 flipy = pitch & 0x80;
390 width = pitch & 0x7f;
391 if (pitch & 0x80) width = 0x80 - width;
392 pitch = width << 1;
393 width <<= 2;
394 eos = 0;
395
396 if( b3d ) // outrun/aburner
397 {
398 if (b3d == 2) eos = 1;
399 if (xpos < 0 && flipx) continue;
400 if (ypos >= 240) ypos -= 256;
401 sprite.screen_height++;
402 logical_height = (sprite.screen_height<<4)*sprite.zoomy/0x2000;
403 screen_width = width*0x200/sprite.zoomx;
404
405 if (flipx && flipy) { mod_h = -logical_height; mod_x = 4; }
406 else if (flipx) { mod_h = -1; xpos++; mod_x = 4; }
407 else if (flipy) { mod_h = -logical_height; mod_x = 0; }
408 else { mod_h = 0; mod_x = 0; }
409
410 if( sprite.flags & SYS16_SPR_DRAW_TO_TOP )
411 {
412 ypos -= sprite.screen_height;
413 flipy = !flipy;
414 }
415
416 if( sprite.flags & SYS16_SPR_DRAW_TO_LEFT )
417 {
418 xpos -= screen_width;
419 flipx = !flipx;
420 }
421 }
422 else if( sys16_spritesystem==sys16_sprite_sharrier )
423 {
424 logical_height = (sprite.screen_height<<4)*(0x400+sprite.zoomy)/0x4000;
425 screen_width = width*(0x800-sprite.zoomx)/0x800;
426
427 if (flipx && flipy) { mod_h = -logical_height-1; mod_x = 4; }
428 else if (flipx) { mod_h = 0; mod_x = 4; }
429 else if (flipy) { mod_h = -logical_height; mod_x = 0; }
430 else { mod_h = 1; mod_x = 0; }
431 }
432 else
433 {
434 if (!width) { width = 512; eos = 1; } // used by fantasy zone for laser
435 screen_width = width;
436 logical_height = sprite.screen_height;
437
438 if (sprite.zoomy) logical_height = logical_height*(0x400 + sprite.zoomy)/0x400 - 1;
439 if (sprite.zoomx) screen_width = screen_width*(0x800 - sprite.zoomx)/0x800 + 2;
440
441 if (flipx && flipy) { mod_h = -logical_height-1; mod_x = 2; }
442 else if (flipx) { mod_h = 0; mod_x = 2; }
443 else if (flipy) { mod_h = -logical_height; mod_x = 0; }
444 else { mod_h = 1; mod_x = 0; }
445 }
446
447 gfx = sprite.gfx + pitch * mod_h + mod_x;
448 if (gfx >= gfx_rom_size) gfx %= gfx_rom_size;
449
450 draw_sprite(
451 bitmap,cliprect,
452 base_gfx + gfx, pitch,
453 base_pal + (sprite.color<<4),
454 xpos, ypos, screen_width, sprite.screen_height,
455 width, logical_height,
456 flipx, flipy,
457 sprite.priority,
458 sprite.flags,
459 sprite.shadow_pen, eos);
460 }
461 }
462 }
463
464 /***************************************************************************/
465
sys16_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)466 UINT32 sys16_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
467 int page = 0;
468 if( row<32 ){ /* top */
469 if( col<64 ) page = 0; else page = 1;
470 }
471 else { /* bottom */
472 if( col<64 ) page = 2; else page = 3;
473 }
474 row = row%32;
475 col = col%64;
476 return page*64*32+row*64+col;
477 }
478
sys16_text_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)479 UINT32 sys16_text_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
480 return row*64+col+(64-40);
481 }
482
483 /***************************************************************************/
484
WRITE16_HANDLER(sys16_paletteram_w)485 WRITE16_HANDLER( sys16_paletteram_w ){
486 data16_t oldword = paletteram16[offset];
487 data16_t newword;
488 COMBINE_DATA( &paletteram16[offset] );
489 newword = paletteram16[offset];
490 if( oldword!=newword ){ /* we can do this, because we initialize palette RAM to all black in vh_start */
491 /* byte 0 byte 1 */
492 /* GBGR BBBB GGGG RRRR */
493 /* 5444 3210 3210 3210 */
494 UINT8 r = (newword & 0x00f)<<1;
495 UINT8 g = (newword & 0x0f0)>>2;
496 UINT8 b = (newword & 0xf00)>>7;
497 if( sys16_dactype == 0 ){ /* we should really use two distinct paletteram_w handlers */
498 /* dac_type == 0 (from GCS file) */
499 if (newword&0x1000) r|=1;
500 if (newword&0x2000) g|=2;
501 if (newword&0x8000) g|=1;
502 if (newword&0x4000) b|=1;
503 }
504 else if( sys16_dactype == 1 ){
505 /* dac_type == 1 (from GCS file) Shinobi Only*/
506 if (newword&0x1000) r|=1;
507 if (newword&0x4000) g|=2;
508 if (newword&0x8000) g|=1;
509 if (newword&0x2000) b|=1;
510 }
511
512 #ifndef TRANSPARENT_SHADOWS
513 palette_set_color( offset,
514 (r << 3) | (r >> 2), /* 5 bits red */
515 (g << 2) | (g >> 4), /* 6 bits green */
516 (b << 3) | (b >> 2) /* 5 bits blue */
517 );
518 #else
519 { extern struct GameDriver driver_aburner, driver_aburner2; //JUN
520 r=(r << 3) | (r >> 2); /* 5 bits red */
521 g=(g << 2) | (g >> 4); /* 6 bits green */
522 b=(b << 3) | (b >> 2); /* 5 bits blue */
523
524 palette_set_color( offset,r,g,b);
525 if (Machine->gamedrv != &driver_aburner && Machine->gamedrv != &driver_aburner2) { //JUN
526 /* shadow color */
527 r= r * 160 / 256;
528 g= g * 160 / 256;
529 b= b * 160 / 256;
530
531 palette_set_color( offset+Machine->drv->total_colors/2,r,g,b); }
532 }
533 #endif
534 }
535 }
536
update_page(void)537 static void update_page( void ){
538 int all_dirty = 0;
539 int i,offset;
540 if( old_tile_bank1 != sys16_tile_bank1 ){
541 all_dirty = 1;
542 old_tile_bank1 = sys16_tile_bank1;
543 }
544 if( old_tile_bank0 != sys16_tile_bank0 ){
545 all_dirty = 1;
546 old_tile_bank0 = sys16_tile_bank0;
547 tilemap_mark_all_tiles_dirty( text_layer );
548 }
549 if( all_dirty ){
550 tilemap_mark_all_tiles_dirty( background );
551 tilemap_mark_all_tiles_dirty( foreground );
552 if( sys16_18_mode ){
553 tilemap_mark_all_tiles_dirty( background2 );
554 tilemap_mark_all_tiles_dirty( foreground2 );
555 }
556 }
557 else {
558 for(i=0;i<4;i++){
559 int page0 = 64*32*i;
560 if( old_bg_page[i]!=sys16_bg_page[i] ){
561 old_bg_page[i] = sys16_bg_page[i];
562 for( offset = page0; offset<page0+64*32; offset++ ){
563 tilemap_mark_tile_dirty( background, offset );
564 }
565 }
566 if( old_fg_page[i]!=sys16_fg_page[i] ){
567 old_fg_page[i] = sys16_fg_page[i];
568 for( offset = page0; offset<page0+64*32; offset++ ){
569 tilemap_mark_tile_dirty( foreground, offset );
570 }
571 }
572 if( sys16_18_mode ){
573 if( old_bg2_page[i]!=sys16_bg2_page[i] ){
574 old_bg2_page[i] = sys16_bg2_page[i];
575 for( offset = page0; offset<page0+64*32; offset++ ){
576 tilemap_mark_tile_dirty( background2, offset );
577 }
578 }
579 if( old_fg2_page[i]!=sys16_fg2_page[i] ){
580 old_fg2_page[i] = sys16_fg2_page[i];
581 for( offset = page0; offset<page0+64*32; offset++ ){
582 tilemap_mark_tile_dirty( foreground2, offset );
583 }
584 }
585 }
586 }
587 }
588 }
589
get_bg_tile_info(int offset)590 static void get_bg_tile_info( int offset ){
591 const UINT16 *source = 64*32*sys16_bg_page[offset/(64*32)] + sys16_tileram;
592 int data = source[offset%(64*32)];
593 int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
594
595 if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
596 SET_TILE_INFO(
597 0,
598 tile_number,
599 512+384+((data>>6)&0x7f),
600 0)
601 }
602 else if(sys16_textmode==0){
603 SET_TILE_INFO(
604 0,
605 tile_number,
606 (data>>6)&0x7f,
607 0)
608 }
609 else{
610 SET_TILE_INFO(
611 0,
612 tile_number,
613 (data>>5)&0x7f,
614 0)
615 }
616
617 switch(sys16_bg_priority_mode) {
618 case 1: // Alien Syndrome
619 tile_info.priority = (data&0x8000)?1:0;
620 break;
621 case 2: // Body Slam / wrestwar
622 tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
623 break;
624 case 3: // sys18 games
625 if( data&0x8000 ){
626 tile_info.priority = 2;
627 }
628 else {
629 tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
630 }
631 break;
632 }
633 }
634
get_fg_tile_info(int offset)635 static void get_fg_tile_info( int offset ){
636 const UINT16 *source = 64*32*sys16_fg_page[offset/(64*32)] + sys16_tileram;
637 int data = source[offset%(64*32)];
638 int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
639
640 if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
641 SET_TILE_INFO(
642 0,
643 tile_number,
644 512+384+((data>>6)&0x7f),
645 0)
646 }
647 else if(sys16_textmode==0){
648 SET_TILE_INFO(
649 0,
650 tile_number,
651 (data>>6)&0x7f,
652 0)
653 }
654 else{
655 SET_TILE_INFO(
656 0,
657 tile_number,
658 (data>>5)&0x7f,
659 0)
660 }
661 switch(sys16_fg_priority_mode){
662 case 1: // alien syndrome
663 tile_info.priority = (data&0x8000)?1:0;
664 break;
665
666 case 3:
667 tile_info.priority = ((data&0xff00) >= sys16_fg_priority_value)?1:0;
668 break;
669
670 default:
671 if( sys16_fg_priority_mode>=0 ){
672 tile_info.priority = (data&0x8000)?1:0;
673 }
674 break;
675 }
676 }
677
get_bg2_tile_info(int offset)678 static void get_bg2_tile_info( int offset ){
679 const UINT16 *source = 64*32*sys16_bg2_page[offset/(64*32)] + sys16_tileram;
680 int data = source[offset%(64*32)];
681 int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
682
683 if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
684 SET_TILE_INFO(
685 0,
686 tile_number,
687 512+384+((data>>6)&0x7f),
688 0)
689 }
690 else if(sys16_textmode==0){
691 SET_TILE_INFO(
692 0,
693 tile_number,
694 (data>>6)&0x7f,
695 0)
696 }
697 else{
698 SET_TILE_INFO(
699 0,
700 tile_number,
701 (data>>5)&0x7f,
702 0)
703 }
704 tile_info.priority = 0;
705 }
706
get_fg2_tile_info(int offset)707 static void get_fg2_tile_info( int offset ){
708 const UINT16 *source = 64*32*sys16_fg2_page[offset/(64*32)] + sys16_tileram;
709 int data = source[offset%(64*32)];
710 int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
711
712 if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
713 SET_TILE_INFO(
714 0,
715 tile_number,
716 512+384+((data>>6)&0x7f),
717 0)
718 }
719 else if(sys16_textmode==0){
720 SET_TILE_INFO(
721 0,
722 tile_number,
723 (data>>6)&0x7f,
724 0)
725 }
726 else{
727 SET_TILE_INFO(
728 0,
729 tile_number,
730 (data>>5)&0x7f,
731 0)
732 }
733 if((data&0xff00) >= sys16_fg_priority_value) tile_info.priority = 1;
734 else tile_info.priority = 0;
735 }
736
WRITE16_HANDLER(sys16_tileram_w)737 WRITE16_HANDLER( sys16_tileram_w ){
738 data16_t oldword = sys16_tileram[offset];
739 COMBINE_DATA( &sys16_tileram[offset] );
740 if( oldword != sys16_tileram[offset] ){
741 int page = offset/(64*32);
742 offset = offset%(64*32);
743
744 if( sys16_bg_page[0]==page ) tilemap_mark_tile_dirty( background, offset+64*32*0 );
745 if( sys16_bg_page[1]==page ) tilemap_mark_tile_dirty( background, offset+64*32*1 );
746 if( sys16_bg_page[2]==page ) tilemap_mark_tile_dirty( background, offset+64*32*2 );
747 if( sys16_bg_page[3]==page ) tilemap_mark_tile_dirty( background, offset+64*32*3 );
748
749 if( sys16_fg_page[0]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*0 );
750 if( sys16_fg_page[1]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*1 );
751 if( sys16_fg_page[2]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*2 );
752 if( sys16_fg_page[3]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*3 );
753
754 if( sys16_18_mode ){
755 if( sys16_bg2_page[0]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*0 );
756 if( sys16_bg2_page[1]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*1 );
757 if( sys16_bg2_page[2]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*2 );
758 if( sys16_bg2_page[3]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*3 );
759
760 if( sys16_fg2_page[0]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*0 );
761 if( sys16_fg2_page[1]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*1 );
762 if( sys16_fg2_page[2]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*2 );
763 if( sys16_fg2_page[3]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*3 );
764 }
765 }
766 }
767
768 /***************************************************************************/
769
get_text_tile_info(int offset)770 static void get_text_tile_info( int offset ){
771 const data16_t *source = sys16_textram;
772 int tile_number = source[offset];
773 int pri = tile_number >> 8;
774 if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
775 SET_TILE_INFO(
776 0,
777 (tile_number&0x1ff) + sys16_tile_bank0 * 0x1000,
778 512+384+((tile_number>>9)&0x7),
779 0)
780 }
781 else if(sys16_textmode==0){
782 SET_TILE_INFO(
783 0,
784 (tile_number&0x1ff) + sys16_tile_bank0 * 0x1000,
785 (tile_number>>9)%8,
786 0)
787 }
788 else{
789 SET_TILE_INFO(
790 0,
791 (tile_number&0xff) + sys16_tile_bank0 * 0x1000,
792 (tile_number>>8)%8,
793 0)
794 }
795 if(pri>=sys16_textlayer_lo_min && pri<=sys16_textlayer_lo_max)
796 tile_info.priority = 1;
797 if(pri>=sys16_textlayer_hi_min && pri<=sys16_textlayer_hi_max)
798 tile_info.priority = 0;
799 }
800
WRITE16_HANDLER(sys16_textram_w)801 WRITE16_HANDLER( sys16_textram_w ){
802 int oldword = sys16_textram[offset];
803 COMBINE_DATA( &sys16_textram[offset] );
804 if( oldword!=sys16_textram[offset] ){
805 tilemap_mark_tile_dirty( text_layer, offset );
806 }
807 }
808
809 /***************************************************************************/
810
VIDEO_START(system16)811 VIDEO_START( system16 ){
812 static int bank_default[16] = {
813 0x0,0x1,0x2,0x3,
814 0x4,0x5,0x6,0x7,
815 0x8,0x9,0xa,0xb,
816 0xc,0xd,0xe,0xf
817 };
818 sys16_obj_bank = bank_default;
819
820 if( !sys16_bg1_trans )
821 background = tilemap_create(
822 get_bg_tile_info,
823 sys16_bg_map,
824 TILEMAP_OPAQUE,
825 8,8,
826 64*2,32*2 );
827 else
828 background = tilemap_create(
829 get_bg_tile_info,
830 sys16_bg_map,
831 TILEMAP_TRANSPARENT,
832 8,8,
833 64*2,32*2 );
834
835 foreground = tilemap_create(
836 get_fg_tile_info,
837 sys16_bg_map,
838 TILEMAP_TRANSPARENT,
839 8,8,
840 64*2,32*2 );
841
842 text_layer = tilemap_create(
843 get_text_tile_info,
844 sys16_text_map,
845 TILEMAP_TRANSPARENT,
846 8,8,
847 40,28 );
848
849 num_sprites = 128*2; /* only 128 for most games; aburner uses 256 */
850
851 if( background && foreground && text_layer ){
852 /* initialize all entries to black - needed for Golden Axe*/
853 int i;
854 for( i=0; i<Machine->drv->total_colors; i++ ){
855 palette_set_color( i, 0,0,0 );
856 }
857
858 if(sys16_bg1_trans) tilemap_set_transparent_pen( background, 0 );
859 tilemap_set_transparent_pen( foreground, 0 );
860 tilemap_set_transparent_pen( text_layer, 0 );
861
862 sys16_tile_bank0 = 0;
863 sys16_tile_bank1 = 1;
864
865 sys16_fg_scrollx = 0;
866 sys16_fg_scrolly = 0;
867
868 sys16_bg_scrollx = 0;
869 sys16_bg_scrolly = 0;
870
871 sys16_refreshenable = 1;
872
873 /* common defaults */
874 sys16_update_proc = 0;
875 sys16_spritesystem = sys16_sprite_shinobi;
876 sys16_sprxoffset = -0xb8;
877 sys16_textmode = 0;
878 sys16_bgxoffset = 0;
879 sys16_dactype = 0;
880 sys16_bg_priority_mode=0;
881 sys16_fg_priority_mode=0;
882 sys16_spritelist_end=0xffff;
883 sys16_tilebank_switch=0x1000;
884
885 // Defaults for sys16 games
886 sys16_textlayer_lo_min=0;
887 sys16_textlayer_lo_max=0x7f;
888 sys16_textlayer_hi_min=0x80;
889 sys16_textlayer_hi_max=0xff;
890
891 sys16_18_mode=0;
892
893 #ifdef GAMMA_ADJUST
894 {
895 static float sys16_orig_gamma=0;
896 static float sys16_set_gamma=0;
897 float cur_gamma=osd_get_gamma();
898
899 if(sys16_orig_gamma == 0)
900 {
901 sys16_orig_gamma = cur_gamma;
902 sys16_set_gamma = cur_gamma - 0.35;
903 if (sys16_set_gamma < 0.5) sys16_set_gamma = 0.5;
904 if (sys16_set_gamma > 2.0) sys16_set_gamma = 2.0;
905 osd_set_gamma(sys16_set_gamma);
906 }
907 else
908 {
909 if(sys16_orig_gamma == cur_gamma)
910 {
911 osd_set_gamma(sys16_set_gamma);
912 }
913 }
914 }
915 #endif
916 return 0;
917 }
918 return 1;
919 }
920
VIDEO_START(hangon)921 VIDEO_START( hangon ){
922 int ret;
923 sys16_bg1_trans=1;
924 ret = video_start_system16();
925 if(ret) return 1;
926
927 sys16_textlayer_lo_min=0;
928 sys16_textlayer_lo_max=0;
929 sys16_textlayer_hi_min=0;
930 sys16_textlayer_hi_max=0xff;
931
932 sys16_bg_priority_mode=-1;
933 sys16_bg_priority_value=0x1800;
934 sys16_fg_priority_value=0x2000;
935 return 0;
936 }
937
VIDEO_START(system18)938 VIDEO_START( system18 ){
939 sys16_bg1_trans=1;
940
941 background2 = tilemap_create(
942 get_bg2_tile_info,
943 sys16_bg_map,
944 TILEMAP_OPAQUE,
945 8,8,
946 64*2,32*2 );
947
948 foreground2 = tilemap_create(
949 get_fg2_tile_info,
950 sys16_bg_map,
951 TILEMAP_TRANSPARENT,
952 8,8,
953 64*2,32*2 );
954
955 if( background2 && foreground2 ){
956 if( video_start_system16()==0 ){
957 tilemap_set_transparent_pen( foreground2, 0 );
958
959 if(sys18_splittab_fg_x){
960 tilemap_set_scroll_rows( foreground , 64 );
961 tilemap_set_scroll_rows( foreground2 , 64 );
962 }
963 if(sys18_splittab_bg_x){
964 tilemap_set_scroll_rows( background , 64 );
965 tilemap_set_scroll_rows( background2 , 64 );
966 }
967
968 sys16_textlayer_lo_min=0;
969 sys16_textlayer_lo_max=0x1f;
970 sys16_textlayer_hi_min=0x20;
971 sys16_textlayer_hi_max=0xff;
972
973 sys16_18_mode=1;
974 sys16_bg_priority_mode=3;
975 sys16_fg_priority_mode=3;
976 sys16_bg_priority_value=0x1800;
977 sys16_fg_priority_value=0x2000;
978
979 return 0;
980 }
981 }
982 return 1;
983 }
984
985 /***************************************************************************/
986
sys16_vh_refresh_helper(void)987 static void sys16_vh_refresh_helper( void ){
988 if( sys18_splittab_bg_x ){
989 if( (sys16_bg_scrollx&0xff00) != sys16_rowscroll_scroll ){
990 tilemap_set_scroll_rows( background , 1 );
991 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
992 }
993 else {
994 int offset, scroll,i;
995
996 tilemap_set_scroll_rows( background , 64 );
997 offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
998
999 for( i=0; i<29; i++ ){
1000 scroll = sys18_splittab_bg_x[i];
1001 tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1002 }
1003 }
1004 }
1005 else {
1006 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1007 }
1008
1009 if( sys18_splittab_bg_y ){
1010 if( (sys16_bg_scrolly&0xff00) != sys16_rowscroll_scroll ){
1011 tilemap_set_scroll_cols( background , 1 );
1012 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1013 }
1014 else {
1015 int offset, scroll,i;
1016
1017 tilemap_set_scroll_cols( background , 128 );
1018 offset = 127-((sys16_bg_scrollx&0x3f8) >> 3)-40+2;
1019
1020 for( i=0;i<41;i++ ){
1021 scroll = sys18_splittab_bg_y[(i+24)>>1];
1022 tilemap_set_scrolly( background , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1023 }
1024 }
1025 }
1026 else {
1027 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1028 }
1029
1030 if( sys18_splittab_fg_x ){
1031 if( (sys16_fg_scrollx&0xff00) != sys16_rowscroll_scroll ){
1032 tilemap_set_scroll_rows( foreground , 1 );
1033 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1034 }
1035 else {
1036 int offset, scroll,i;
1037
1038 tilemap_set_scroll_rows( foreground , 64 );
1039 offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1040
1041 for(i=0;i<29;i++){
1042 scroll = sys18_splittab_fg_x[i];
1043 tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1044 }
1045 }
1046 }
1047 else {
1048 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1049 }
1050
1051 if( sys18_splittab_fg_y ){
1052 if( (sys16_fg_scrolly&0xff00) != sys16_rowscroll_scroll ){
1053 tilemap_set_scroll_cols( foreground , 1 );
1054 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1055 }
1056 else {
1057 int offset, scroll,i;
1058
1059 tilemap_set_scroll_cols( foreground , 128 );
1060 offset = 127-((sys16_fg_scrollx&0x3f8) >> 3)-40+2;
1061
1062 for( i=0; i<41; i++ ){
1063 scroll = sys18_splittab_fg_y[(i+24)>>1];
1064 tilemap_set_scrolly( foreground , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1065 }
1066 }
1067 }
1068 else {
1069 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1070 }
1071 }
1072
sys18_vh_screenrefresh_helper(void)1073 static void sys18_vh_screenrefresh_helper( void ){
1074 int i;
1075 if( sys18_splittab_bg_x ){ // screenwise rowscroll?
1076 int offset,offset2, scroll,scroll2,orig_scroll;
1077
1078 offset = 32+((sys16_bg_scrolly&0x1f8) >> 3); // 0x00..0x3f
1079 offset2 = 32+((sys16_bg2_scrolly&0x1f8) >> 3); // 0x00..0x3f
1080
1081 for( i=0;i<29;i++ ){
1082 orig_scroll = scroll2 = scroll = sys18_splittab_bg_x[i];
1083 if((sys16_bg_scrollx &0xff00) != 0x8000) scroll = sys16_bg_scrollx;
1084 if((sys16_bg2_scrollx &0xff00) != 0x8000) scroll2 = sys16_bg2_scrollx;
1085
1086 if(orig_scroll&0x8000){ // background2
1087 tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1088 tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1089 }
1090 else{ // background
1091 tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1092 tilemap_set_scrollx( background2, (i+offset2)&0x3f, TILE_LINE_DISABLED );
1093 }
1094 }
1095 }
1096 else {
1097 tilemap_set_scrollx( background , 0, -320-(sys16_bg_scrollx&0x3ff)+sys16_bgxoffset );
1098 tilemap_set_scrollx( background2, 0, -320-(sys16_bg2_scrollx&0x3ff)+sys16_bgxoffset );
1099 }
1100
1101 tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
1102 tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
1103
1104 if( sys18_splittab_fg_x ){
1105 int offset,offset2, scroll,scroll2,orig_scroll;
1106
1107 offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1108 offset2 = 32+((sys16_fg2_scrolly&0x1f8) >> 3);
1109
1110 for( i=0;i<29;i++ ){
1111 orig_scroll = scroll2 = scroll = sys18_splittab_fg_x[i];
1112 if( (sys16_fg_scrollx &0xff00) != 0x8000 ) scroll = sys16_fg_scrollx;
1113
1114 if( (sys16_fg2_scrollx &0xff00) != 0x8000 ) scroll2 = sys16_fg2_scrollx;
1115
1116 if( orig_scroll&0x8000 ){
1117 tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
1118 tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
1119 }
1120 else {
1121 tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1122 tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1123 }
1124 }
1125 }
1126 else {
1127 tilemap_set_scrollx( foreground , 0, -320-(sys16_fg_scrollx&0x3ff)+sys16_fgxoffset );
1128 tilemap_set_scrollx( foreground2, 0, -320-(sys16_fg2_scrollx&0x3ff)+sys16_fgxoffset );
1129 }
1130
1131
1132 tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
1133 tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
1134
1135 tilemap_set_enable( background2, sys18_bg2_active );
1136 tilemap_set_enable( foreground2, sys18_fg2_active );
1137 }
1138
VIDEO_UPDATE(system16)1139 VIDEO_UPDATE( system16 ){
1140 if (!sys16_refreshenable) return;
1141
1142 if( sys16_update_proc ) sys16_update_proc();
1143 update_page();
1144 sys16_vh_refresh_helper(); /* set scroll registers */
1145
1146 fillbitmap(priority_bitmap,0,cliprect);
1147
1148 tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY, 0x00 );
1149 if(sys16_bg_priority_mode) tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 1, 0x00 );
1150 // sprite_draw(sprite_list,3); // needed for Aurail
1151 if( sys16_bg_priority_mode==2 ) tilemap_draw( bitmap,cliprect, background, 1, 0x01 );// body slam (& wrestwar??)
1152 // sprite_draw(sprite_list,2);
1153 else if( sys16_bg_priority_mode==1 ) tilemap_draw( bitmap,cliprect, background, 1, 0x03 );// alien syndrome / aurail
1154 tilemap_draw( bitmap,cliprect, foreground, 0, 0x03 );
1155 // sprite_draw(sprite_list,1);
1156 tilemap_draw( bitmap,cliprect, foreground, 1, 0x07 );
1157 if( sys16_textlayer_lo_max!=0 ) tilemap_draw( bitmap,cliprect, text_layer, 1, 7 );// needed for Body Slam
1158 // sprite_draw(sprite_list,0);
1159 tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1160
1161 draw_sprites( bitmap,cliprect,0 );
1162 }
1163
VIDEO_UPDATE(system18)1164 VIDEO_UPDATE( system18 ){
1165 if (!sys16_refreshenable) return;
1166 if( sys16_update_proc ) sys16_update_proc();
1167 update_page();
1168 sys18_vh_screenrefresh_helper(); /* set scroll registers */
1169
1170 fillbitmap(priority_bitmap,0,NULL);
1171 if(sys18_bg2_active)
1172 tilemap_draw( bitmap,cliprect, background2, 0, 0 );
1173 else
1174 fillbitmap(bitmap,Machine->pens[0],cliprect);
1175
1176 tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY, 0 );
1177 tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 1, 0 ); //??
1178 tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 2, 0 ); //??
1179
1180 // sprite_draw(sprite_list,3);
1181 tilemap_draw( bitmap,cliprect, background, 1, 0x1 );
1182 // sprite_draw(sprite_list,2);
1183 tilemap_draw( bitmap,cliprect, background, 2, 0x3 );
1184
1185 if(sys18_fg2_active) tilemap_draw( bitmap,cliprect, foreground2, 0, 0x3 );
1186 tilemap_draw( bitmap,cliprect, foreground, 0, 0x3 );
1187 // sprite_draw(sprite_list,1);
1188 if(sys18_fg2_active) tilemap_draw( bitmap,cliprect, foreground2, 1, 0x7 );
1189 tilemap_draw( bitmap,cliprect, foreground, 1, 0x7 );
1190
1191 tilemap_draw( bitmap,cliprect, text_layer, 1, 0x7 );
1192 // sprite_draw(sprite_list,0);
1193 tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1194
1195 draw_sprites( bitmap,cliprect, 0 );
1196 }
1197
1198
render_gr(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)1199 static void render_gr(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority){
1200 /* the road is a 4 color bitmap */
1201 int i,j;
1202 UINT8 *data = memory_region(REGION_GFX3);
1203 UINT8 *source;
1204 UINT16 *line16;
1205 UINT16 *data_ver=sys16_gr_ver;
1206 UINT32 ver_data,hor_pos;
1207 UINT16 colors[5];
1208 int colorflip;
1209 int yflip=0, ypos;
1210 int dx=1,xoff=0;
1211
1212 pen_t *paldata1 = Machine->gfx[0]->colortable + sys16_gr_palette;
1213 pen_t *paldata2 = Machine->gfx[0]->colortable + sys16_gr_palette_default;
1214
1215 #if 0
1216 if( keyboard_pressed( KEYCODE_S ) ){
1217 FILE *f;
1218 int i;
1219 char fname[64];
1220 static int fcount = 0;
1221 while( keyboard_pressed( KEYCODE_S ) ){}
1222 sprintf( fname, "road%d.txt",fcount );
1223 fcount++;
1224 f = fopen( fname,"w" );
1225 if( f ){
1226 const UINT16 *source = sys16_gr_ver;
1227 for( i=0; i<0x1000; i++ ){
1228 if( (i&0x1f)==0 ) fprintf( f, "\n %04x: ", i );
1229 fprintf( f, "%04x ", source[i] );
1230 }
1231 fclose( f );
1232 }
1233 }
1234 #endif
1235
1236 priority=priority << 10;
1237
1238 if (Machine->scrbitmap->depth == 16) /* 16 bit */
1239 {
1240 if( Machine->orientation & ORIENTATION_SWAP_XY ){
1241 if( Machine->orientation & ORIENTATION_FLIP_Y ){
1242 dx=-1;
1243 xoff=319;
1244 }
1245 if( Machine->orientation & ORIENTATION_FLIP_X ){
1246 yflip=1;
1247 }
1248
1249 for(i=cliprect->min_y;i<=cliprect->max_y;i++){
1250 if(yflip) ypos=223-i;
1251 else ypos=i;
1252 ver_data=*data_ver;
1253 if((ver_data & 0x400) == priority)
1254 {
1255 colors[0] = paldata1[ sys16_gr_pal[(ver_data)&0xff]&0xff ];
1256
1257 if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
1258 {
1259 // fill line
1260 for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1261 {
1262 line16=(UINT16 *)bitmap->line[j]+ypos;
1263 *line16=colors[0];
1264 }
1265 }
1266 else
1267 {
1268 // copy line
1269 ver_data=ver_data & 0x00ff;
1270 colorflip = (sys16_gr_flip[ver_data] >> 3) & 1;
1271
1272 colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1273 colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1274 colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1275 colors[4] = paldata2[ sys16_gr_colorflip[colorflip][3] ];
1276
1277 hor_pos = sys16_gr_hor[ver_data];
1278 ver_data = ver_data << sys16_gr_bitmap_width;
1279
1280 if(hor_pos & 0xf000)
1281 {
1282 // reverse
1283 hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
1284 }
1285 else
1286 {
1287 // normal
1288 hor_pos=(hor_pos+0x200) & 0x3ff;
1289 }
1290
1291 source = data + hor_pos + ver_data + 18 + 8;
1292
1293 for(j=cliprect->min_x;j<cliprect->max_x;j++)
1294 {
1295 line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
1296 *line16 = colors[*source++];
1297 }
1298 }
1299 }
1300 data_ver++;
1301 }
1302 }
1303 else
1304 { /* 16 bpp, normal screen orientation */
1305 if( Machine->orientation & ORIENTATION_FLIP_X ){
1306 dx=-1;
1307 xoff=319;
1308 }
1309 if( Machine->orientation & ORIENTATION_FLIP_Y ){
1310 yflip=1;
1311 }
1312
1313 for(i=cliprect->min_y;i<=cliprect->max_y;i++){ /* with each scanline */
1314 if( yflip ) ypos=223-i; else ypos=i;
1315 ver_data= *data_ver; /* scanline parameters */
1316 /*
1317 gr_ver:
1318 ---- -x-- ---- ---- priority
1319 ---- --x- ---- ---- ?
1320 ---- ---x ---- ---- ?
1321 ---- ---- xxxx xxxx ypos (source bitmap)
1322
1323 gr_flip:
1324 ---- ---- ---- x--- flip colors
1325
1326 gr_hor:
1327 xxxx xxxx xxxx xxxx xscroll
1328
1329 gr_pal:
1330 ---- ---- xxxx xxxx palette
1331 */
1332 if( (ver_data & 0x400) == priority ){
1333 colors[0] = paldata1[ sys16_gr_pal[ver_data&0xff]&0xff ];
1334
1335 if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200){
1336 line16 = (UINT16 *)bitmap->line[ypos]; /* dest for drawing */
1337 for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1338 *line16++=colors[0]; /* opaque fill with background color */
1339 }
1340 }
1341 else {
1342 // copy line
1343 line16 = (UINT16 *)bitmap->line[ypos]+xoff; /* dest for drawing */
1344 ver_data &= 0xff;
1345
1346 colorflip = (sys16_gr_flip[ver_data] >> 3) & 1;
1347 colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1348 colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1349 colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1350 colors[4] = paldata2[ sys16_gr_colorflip[colorflip][3] ];
1351
1352 hor_pos = sys16_gr_hor[ver_data];
1353 if( hor_pos & 0xf000 ){ // reverse (precalculated)
1354 hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
1355 }
1356 else { // normal
1357 hor_pos=(hor_pos+0x200) & 0x3ff;
1358 }
1359
1360 ver_data <<= sys16_gr_bitmap_width;
1361 source = data + hor_pos + ver_data + 18 + 8;
1362
1363 for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1364 *line16 = colors[*source++];
1365 line16+=dx;
1366 }
1367 }
1368 }
1369 data_ver++;
1370 }
1371 }
1372 }
1373 }
1374
VIDEO_UPDATE(hangon)1375 VIDEO_UPDATE( hangon ){
1376 if (!sys16_refreshenable) return;
1377 if( sys16_update_proc ) sys16_update_proc();
1378 update_page();
1379
1380 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1381 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1382 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1383 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1384
1385 fillbitmap(priority_bitmap,0,cliprect);
1386
1387 render_gr(bitmap,cliprect,0); /* sky */
1388 tilemap_draw( bitmap,cliprect, background, 0, 0 );
1389 tilemap_draw( bitmap,cliprect, foreground, 0, 0 );
1390 render_gr(bitmap,cliprect,1); /* floor */
1391 tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1392
1393 draw_sprites( bitmap,cliprect, 0 );
1394 }
1395
render_grv2(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)1396 static void render_grv2(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority)
1397 {
1398 int i,j;
1399 UINT8 *data = memory_region(REGION_GFX3);
1400 UINT8 *source,*source2,*temp;
1401 UINT16 *line16;
1402 UINT16 *data_ver=sys16_gr_ver;
1403 UINT32 ver_data,hor_pos,hor_pos2;
1404 UINT16 colors[5];
1405 int colorflip,colorflip_info;
1406 int yflip=0,ypos;
1407 int dx=1,xoff=0;
1408
1409 int second_road = sys16_gr_second_road[0];
1410
1411 pen_t *paldata1 = Machine->gfx[0]->colortable + sys16_gr_palette;
1412 pen_t *paldata2 = Machine->gfx[0]->colortable + sys16_gr_palette_default;
1413
1414 priority=priority << 11;
1415
1416 if (Machine->scrbitmap->depth == 16) /* 16 bit */
1417 {
1418 if( Machine->orientation & ORIENTATION_SWAP_XY )
1419 {
1420 if( Machine->orientation & ORIENTATION_FLIP_Y ){
1421 dx=-1;
1422 xoff=319;
1423 }
1424 if( Machine->orientation & ORIENTATION_FLIP_X ){
1425 yflip=1;
1426 }
1427
1428 for(i=cliprect->min_y;i<=cliprect->max_y;i++)
1429 {
1430 if(yflip) ypos=223-i;
1431 else ypos=i;
1432 ver_data = *data_ver;
1433 if((ver_data & 0x800) == priority)
1434 {
1435
1436 if(ver_data & 0x800) /* disable */
1437 {
1438 colors[0] = paldata1[ ver_data&0x3f ];
1439 // fill line
1440 for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1441 {
1442 line16=(UINT16 *)bitmap->line[j]+ypos;
1443 *line16=colors[0];
1444 }
1445 }
1446 else
1447 {
1448 // copy line
1449 ver_data=ver_data & 0x01ff; //???
1450 colorflip_info = sys16_gr_flip[ver_data];
1451
1452 colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ]; //??
1453
1454 colorflip = (colorflip_info >> 3) & 1;
1455
1456 colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1457 colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1458 colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1459
1460 hor_pos = sys16_gr_hor[ver_data];
1461 hor_pos2= sys16_gr_hor[ver_data+0x200];
1462
1463 ver_data=ver_data>>1;
1464 if( ver_data != 0 )
1465 {
1466 ver_data = (ver_data-1) << sys16_gr_bitmap_width;
1467 }
1468 source = data + ((hor_pos +0x200) & 0x7ff) + 0x300 + ver_data + 8;
1469 source2 = data + ((hor_pos2+0x200) & 0x7ff) + 0x300 + ver_data + 8;
1470
1471 switch(second_road)
1472 {
1473 case 0: source2=source; break;
1474 case 2: temp=source;source=source2;source2=temp; break;
1475 case 3: source=source2; break;
1476 }
1477
1478 source2++;
1479
1480 for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1481 {
1482 line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
1483 if(*source2 <= *source)
1484 *line16 = colors[*source];
1485 else
1486 *line16 = colors[*source2];
1487 source++;
1488 source2++;
1489 }
1490 }
1491 }
1492 data_ver++;
1493 }
1494 }
1495 else
1496 {
1497 if( Machine->orientation & ORIENTATION_FLIP_X ){
1498 dx=-1;
1499 xoff=319;
1500 }
1501 if( Machine->orientation & ORIENTATION_FLIP_Y ){
1502 yflip=1;
1503 }
1504
1505 for(i=cliprect->min_y;i<=cliprect->max_y;i++){
1506 if(yflip) ypos=223-i;
1507 else ypos=i;
1508 ver_data= *data_ver;
1509 if((ver_data & 0x800) == priority){
1510 if(ver_data & 0x800){
1511 colors[0] = paldata1[ ver_data&0x3f ];
1512 // fill line
1513 line16 = (UINT16 *)bitmap->line[ypos];
1514 for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1515 *line16++ = colors[0];
1516 }
1517 }
1518 else {
1519 // copy line
1520 line16 = (UINT16 *)bitmap->line[ypos]+xoff;
1521 ver_data &= 0x01ff; //???
1522 colorflip_info = sys16_gr_flip[ver_data];
1523 colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ]; //??
1524 colorflip = (colorflip_info >> 3) & 1;
1525 colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1526 colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1527 colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1528 hor_pos = sys16_gr_hor[ver_data];
1529 hor_pos2= sys16_gr_hor[ver_data+0x200];
1530 ver_data=ver_data>>1;
1531 if( ver_data != 0 ){
1532 ver_data = (ver_data-1) << sys16_gr_bitmap_width;
1533 }
1534 source = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
1535 source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
1536 switch(second_road){
1537 case 0: source2=source; break;
1538 case 2: temp=source;source=source2;source2=temp; break;
1539 case 3: source=source2; break;
1540 }
1541 source2++;
1542 for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1543 if(*source2 <= *source) *line16 = colors[*source]; else *line16 = colors[*source2];
1544 source++;
1545 source2++;
1546 line16+=dx;
1547 }
1548 }
1549 }
1550 data_ver++;
1551 }
1552 }
1553 }
1554 }
1555
1556
VIDEO_START(outrun)1557 VIDEO_START( outrun ){
1558 int ret;
1559 sys16_bg1_trans=1;
1560 ret = video_start_system16();
1561 if(ret) return 1;
1562
1563 sys16_textlayer_lo_min=0;
1564 sys16_textlayer_lo_max=0;
1565 sys16_textlayer_hi_min=0;
1566 sys16_textlayer_hi_max=0xff;
1567
1568 sys16_bg_priority_mode=-1;
1569 sys16_bg_priority_value=0x1800;
1570 sys16_fg_priority_value=0x2000;
1571 return 0;
1572 }
1573
VIDEO_UPDATE(outrun)1574 VIDEO_UPDATE( outrun ){
1575 if( sys16_refreshenable ){
1576 if( sys16_update_proc ) sys16_update_proc();
1577 update_page();
1578
1579 tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1580 tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1581
1582 tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1583 tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1584
1585 render_grv2(bitmap,cliprect,1);
1586 tilemap_draw( bitmap,cliprect, background, 0, 0 );
1587 tilemap_draw( bitmap,cliprect, foreground, 0, 0 );
1588 render_grv2(bitmap,cliprect,0);
1589
1590 draw_sprites( bitmap,cliprect, 1 );
1591
1592 tilemap_draw( bitmap,cliprect, text_layer, 0, 0 );
1593 }
1594 }
1595
1596 /***************************************************************************/
1597
1598 static UINT8 *aburner_backdrop;
1599
aburner_unpack_backdrop(const UINT8 * baseaddr)1600 UINT8 *aburner_unpack_backdrop( const UINT8 *baseaddr ){
1601 UINT8 *result = auto_malloc(512*256*2);
1602 if( result ){
1603 int page;
1604 for( page=0; page<2; page++ ){
1605 UINT8 *dest = result + 512*256*page;
1606 const UINT8 *source = baseaddr + 0x8000*page;
1607 int y;
1608 for( y=0; y<256; y++ ){
1609 int x;
1610 for( x=0; x<512; x++ ){
1611 int data0 = source[x/8];
1612 int data1 = source[x/8 + 0x4000];
1613 int bit = 0x80>>(x&7);
1614 int pen = 0;
1615 if( data0 & bit ) pen+=1;
1616 if( data1 & bit ) pen+=2;
1617 dest[x] = pen;
1618 }
1619
1620 {
1621 int edge_color = dest[0];
1622 for( x=0; x<512; x++ ){
1623 if( dest[x]==edge_color ) dest[x] = 4; else break;
1624 }
1625 edge_color = dest[511];
1626 for( x=511; x>=0; x-- ){
1627 if( dest[x]==edge_color ) dest[x] = 4; else break;
1628 }
1629 }
1630
1631 source += 0x40;
1632 dest += 512;
1633 }
1634 }
1635 }
1636 return result;
1637 }
1638
VIDEO_START(aburner)1639 VIDEO_START( aburner ){
1640 int ret;
1641
1642 aburner_backdrop = aburner_unpack_backdrop( memory_region(REGION_GFX3) );
1643
1644 sys16_bg1_trans=1;
1645 ret = video_start_system16();
1646 if(ret) return 1;
1647
1648 foreground2 = tilemap_create(
1649 get_fg2_tile_info,
1650 sys16_bg_map,
1651 TILEMAP_TRANSPARENT,
1652 8,8,
1653 64*2,32*2 );
1654
1655 background2 = tilemap_create(
1656 get_bg2_tile_info,
1657 sys16_bg_map,
1658 TILEMAP_TRANSPARENT,
1659 8,8,
1660 64*2,32*2 );
1661
1662 if( foreground2 && background2 ){
1663 ret = video_start_system16();
1664 if(ret) return 1;
1665 tilemap_set_transparent_pen( foreground2, 0 );
1666 sys16_18_mode = 1;
1667
1668 tilemap_set_scroll_rows( foreground , 64 );
1669 tilemap_set_scroll_rows( foreground2 , 64 );
1670 tilemap_set_scroll_rows( background , 64 );
1671 tilemap_set_scroll_rows( background2 , 64 );
1672
1673 return 0;
1674 }
1675 return 1;
1676 }
1677
aburner_draw_road(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1678 static void aburner_draw_road( struct mame_bitmap *bitmap, const struct rectangle *cliprect ){
1679 /*
1680 sys16_roadram[0x1000]:
1681 0x04: flying (sky/horizon)
1682 0x43: (flying->landing)
1683 0xc3: runway landing
1684 0xe3: (landing -> flying)
1685 0x03: rocky canyon
1686
1687 Thunderblade: 0x04, 0xfe
1688 */
1689
1690 /* Palette:
1691 ** 0x1700 ground(8), road(4), road(4)
1692 ** 0x1720 sky(16)
1693 ** 0x1730 road edge(2)
1694 ** 0x1780 background color(16)
1695 */
1696
1697 const UINT16 *vreg = sys16_roadram;
1698 /* 0x000..0x0ff: 0x800: disable; 0x100: enable
1699 0x100..0x1ff: color/line_select
1700 0x200..0x2ff: xscroll
1701 0x400..0x4ff: 0x5b0?
1702 0x600..0x6ff: flip colors
1703 */
1704 int page = sys16_roadram[0x1000];
1705 int sy;
1706
1707 for( sy=cliprect->min_y; sy<=cliprect->max_y; sy++ ){
1708 UINT16 *dest = (UINT16 *)bitmap->line[sy] + cliprect->min_x; /* assume 16bpp */
1709 int sx;
1710 UINT16 line = vreg[0x100+sy];
1711
1712 if( page&4 ){ /* flying */
1713 int xscroll = vreg[0x200+sy] - 0x552;
1714 UINT16 sky = Machine->pens[0x1720];
1715 UINT16 ground = Machine->pens[0x1700];
1716 for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1717 int temp = xscroll+sx;
1718 if( temp<0 ){
1719 *dest++ = sky;
1720 }
1721 else if( temp < 0x200 ){
1722 *dest++ = ground;
1723 }
1724 else {
1725 *dest++ = sky;
1726 }
1727 }
1728 }
1729 else if( line&0x800 ){
1730 /* opaque fill; the least significant nibble selects color */
1731 unsigned short color = Machine->pens[0x1780+(line&0xf)];
1732 for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1733 *dest++ = color;
1734 }
1735 }
1736 else if( page&0xc0 ){ /* road */
1737 const UINT8 *source = aburner_backdrop+(line&0xff)*512 + 512*256*(page&1);
1738 UINT16 xscroll = (512-320)/2;
1739 // 040d 04b0 0552: normal: sky,horizon,sea
1740
1741 UINT16 flip = vreg[0x600+sy];
1742 int clut[5];
1743 {
1744 int road_color = 0x1708+(flip&0x1);
1745 clut[0] = Machine->pens[road_color];
1746 clut[1] = Machine->pens[road_color+2];
1747 clut[2] = Machine->pens[road_color+4];
1748 clut[3] = Machine->pens[road_color+6];
1749 clut[4] = Machine->pens[(flip&0x100)?0x1730:0x1731]; /* edge of road */
1750 }
1751 for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1752 int xpos = (sx + xscroll)&0x1ff;
1753 *dest++ = clut[source[xpos]];
1754 }
1755 }
1756 else { /* rocky canyon */
1757 UINT16 flip = vreg[0x600+sy];
1758 unsigned short color = Machine->pens[(flip&0x100)?0x1730:0x1731];
1759 for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1760 *dest++ = color;
1761 }
1762 }
1763 }
1764 #if 0
1765 if( keyboard_pressed( KEYCODE_S ) ){ /* debug */
1766 FILE *f;
1767 int i;
1768 char fname[64];
1769 static int fcount = 0;
1770 while( keyboard_pressed( KEYCODE_S ) ){}
1771 sprintf( fname, "road%d.txt",fcount );
1772 fcount++;
1773 f = fopen( fname,"w" );
1774 if( f ){
1775 const UINT16 *source = sys16_roadram;
1776 for( i=0; i<0x1000; i++ ){
1777 if( (i&0x1f)==0 ) fprintf( f, "\n %04x: ", i );
1778 fprintf( f, "%04x ", source[i] );
1779 }
1780 fclose( f );
1781 }
1782 }
1783 #endif
1784 }
1785
sys16_aburner_vh_screenrefresh_helper(void)1786 static void sys16_aburner_vh_screenrefresh_helper( void ){
1787 const data16_t *vreg = &sys16_textram[0x740];
1788 int i;
1789
1790 {
1791 UINT16 data = vreg[0];
1792 sys16_fg_page[0] = data>>12;
1793 sys16_fg_page[1] = (data>>8)&0xf;
1794 sys16_fg_page[2] = (data>>4)&0xf;
1795 sys16_fg_page[3] = data&0xf;
1796 sys16_fg_scrolly = vreg[8];
1797 sys16_fg_scrollx = vreg[12];
1798 }
1799
1800 {
1801 UINT16 data = vreg[0+1];
1802 sys16_bg_page[0] = data>>12;
1803 sys16_bg_page[1] = (data>>8)&0xf;
1804 sys16_bg_page[2] = (data>>4)&0xf;
1805 sys16_bg_page[3] = data&0xf;
1806 sys16_bg_scrolly = vreg[8+1];
1807 sys16_bg_scrollx = vreg[12+1];
1808 }
1809
1810 {
1811 UINT16 data = vreg[0+2];
1812 sys16_fg2_page[0] = data>>12;
1813 sys16_fg2_page[1] = (data>>8)&0xf;
1814 sys16_fg2_page[2] = (data>>4)&0xf;
1815 sys16_fg2_page[3] = data&0xf;
1816 sys16_fg2_scrolly = vreg[8+2];
1817 sys16_fg2_scrollx = vreg[12+2];
1818 }
1819
1820 {
1821 UINT16 data = vreg[0+3];
1822 sys16_bg2_page[0] = data>>12;
1823 sys16_bg2_page[1] = (data>>8)&0xf;
1824 sys16_bg2_page[2] = (data>>4)&0xf;
1825 sys16_bg2_page[3] = data&0xf;
1826 sys16_bg2_scrolly = vreg[8+3];
1827 sys16_bg2_scrollx = vreg[12+3];
1828 }
1829
1830 sys18_splittab_fg_x = &sys16_textram[0x7c0];
1831 sys18_splittab_bg_x = &sys16_textram[0x7e0];
1832
1833 {
1834 int offset,offset2, scroll,scroll2,orig_scroll;
1835 offset = 32+((sys16_bg_scrolly >>3)&0x3f ); // screenwise rowscroll
1836 offset2 = 32+((sys16_bg2_scrolly>>3)&0x3f ); // screenwise rowscroll
1837
1838 for( i=0;i<29;i++ ){
1839 orig_scroll = scroll2 = scroll = sys18_splittab_bg_x[i];
1840 if((sys16_bg_scrollx &0xff00) != 0x8000) scroll = sys16_bg_scrollx;
1841 if((sys16_bg2_scrollx &0xff00) != 0x8000) scroll2 = sys16_bg2_scrollx;
1842
1843 if( orig_scroll&0x8000 ){ // background2
1844 tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1845 tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1846 }
1847 else{ // background1
1848 tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1849 tilemap_set_scrollx( background2, (i+offset2)&0x3f, TILE_LINE_DISABLED );
1850 }
1851 }
1852 }
1853
1854 tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
1855 tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
1856
1857 {
1858 int offset,offset2, scroll,scroll2,orig_scroll;
1859 offset = 32+((sys16_fg_scrolly >>3)&0x3f ); // screenwise rowscroll
1860 offset2 = 32+((sys16_fg2_scrolly>>3)&0x3f ); // screenwise rowscroll
1861
1862 for( i=0;i<29;i++ ){
1863 orig_scroll = scroll2 = scroll = sys18_splittab_fg_x[i];
1864 if( (sys16_fg_scrollx &0xff00) != 0x8000 ) scroll = sys16_fg_scrollx;
1865
1866 if( (sys16_fg2_scrollx &0xff00) != 0x8000 ) scroll2 = sys16_fg2_scrollx;
1867
1868 if( orig_scroll&0x8000 ){ // foreground2
1869 tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
1870 tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
1871 }
1872 else { // foreground
1873 tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1874 tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1875 }
1876 }
1877 }
1878
1879 tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
1880 tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
1881 }
1882
VIDEO_UPDATE(aburner)1883 VIDEO_UPDATE( aburner ){
1884 sys16_aburner_vh_screenrefresh_helper();
1885 update_page();
1886
1887 fillbitmap(priority_bitmap,0,cliprect);
1888
1889 aburner_draw_road( bitmap,cliprect );
1890
1891 // tilemap_draw( bitmap,cliprect, background2, 0, 7 );
1892 // tilemap_draw( bitmap,cliprect, background2, 1, 7 );
1893
1894 /* speed indicator, high score header */
1895 tilemap_draw( bitmap,cliprect, background, 0, 7 );
1896 tilemap_draw( bitmap,cliprect, background, 1, 7 );
1897
1898 /* radar view */
1899 tilemap_draw( bitmap,cliprect, foreground2, 0, 7 );
1900 tilemap_draw( bitmap,cliprect, foreground2, 1, 7 );
1901
1902 /* hand, scores */
1903 tilemap_draw( bitmap,cliprect, foreground, 0, 7 );
1904 tilemap_draw( bitmap,cliprect, foreground, 1, 7 );
1905
1906 tilemap_draw( bitmap,cliprect, text_layer, 0, 7 );
1907 draw_sprites( bitmap,cliprect, 2 );
1908
1909 // debug_draw( bitmap,cliprect, 8,8,sys16_roadram[0x1000] );
1910 }
1911