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