1 /***************************************************************************
2
3 vidhrdw.c
4
5 ***************************************************************************/
6
7 #include "driver.h"
8 #include "vidhrdw/generic.h"
9 #include <math.h>
10
11 data16_t *nemesis_videoram1b;
12 data16_t *nemesis_videoram2b;
13 data16_t *nemesis_videoram1f;
14 data16_t *nemesis_videoram2f;
15
16 data16_t *nemesis_characterram;
17 size_t nemesis_characterram_size;
18 data16_t *nemesis_xscroll1,*nemesis_xscroll2,*nemesis_yscroll;
19 data16_t *nemesis_yscroll1,*nemesis_yscroll2;
20
21 static int spriteram_words;
22 static int tilemap_flip;
23 static int flipscreen;
24
25 static struct tilemap *background, *foreground;
26
27 static unsigned char *blank_characterdata; /* pseudo character */
28
29 /* gfxram dirty flags */
30 static unsigned char *char_dirty; /* 2048 chars */
31
32 /* we should be able to draw sprite gfx directly without caching to GfxElements */
33 static unsigned char *sprite_dirty; /* 512 sprites */
34 static unsigned char *sprite3216_dirty; /* 256 sprites */
35 static unsigned char *sprite816_dirty; /* 1024 sprites */
36 static unsigned char *sprite1632_dirty; /* 256 sprites */
37 static unsigned char *sprite3232_dirty; /* 128 sprites */
38 static unsigned char *sprite168_dirty; /* 1024 sprites */
39 static unsigned char *sprite6464_dirty; /* 32 sprites */
40
get_bg_tile_info(int offs)41 static void get_bg_tile_info( int offs )
42 {
43 int code,color,flags;
44 code = nemesis_videoram1f[offs];
45 color = nemesis_videoram2f[offs];
46 flags = 0;
47 if ( color & 0x80) flags |= TILE_FLIPX;
48 if ( code & 0x0800) flags |= TILE_FLIPY;
49 if ((~code & 0x2000) || ((code & 0xc000) == 0x4000))
50 flags |= TILE_IGNORE_TRANSPARENCY;
51 if (code & 0xf800) {
52 SET_TILE_INFO( 0, code&0x7ff, color&0x7f, flags );
53 } else {
54 SET_TILE_INFO( 0, 0x800, 0x00, 0 );
55 }
56 tile_info.priority = (code & 0x1000)>>12;
57 }
58
get_fg_tile_info(int offs)59 static void get_fg_tile_info( int offs )
60 {
61 int code,color,flags;
62 code = nemesis_videoram1b[offs];
63 color = nemesis_videoram2b[offs];
64 flags = 0;
65 if ( color & 0x80) flags |= TILE_FLIPX;
66 if ( code & 0x0800) flags |= TILE_FLIPY;
67 if ((~code & 0x2000) || ((code & 0xc000) == 0x4000))
68 flags |= TILE_IGNORE_TRANSPARENCY;
69 if (code & 0xf800) {
70 SET_TILE_INFO( 0, code&0x7ff, color&0x7f, flags );
71 } else {
72 SET_TILE_INFO( 0, 0x800, 0x00, 0 );
73 }
74 tile_info.priority = (code & 0x1000)>>12;
75 }
76
WRITE16_HANDLER(nemesis_gfx_flipx_w)77 WRITE16_HANDLER( nemesis_gfx_flipx_w )
78 {
79 if (ACCESSING_LSB)
80 {
81 flipscreen = data & 0x01;
82 if (flipscreen)
83 tilemap_flip |= TILEMAP_FLIPX;
84 else
85 tilemap_flip &= ~TILEMAP_FLIPX;
86
87 tilemap_set_flip(ALL_TILEMAPS, tilemap_flip);
88 }
89 }
90
WRITE16_HANDLER(nemesis_gfx_flipy_w)91 WRITE16_HANDLER( nemesis_gfx_flipy_w )
92 {
93 if (ACCESSING_LSB)
94 {
95 if (data & 0x01)
96 tilemap_flip |= TILEMAP_FLIPY;
97 else
98 tilemap_flip &= ~TILEMAP_FLIPY;
99
100 tilemap_set_flip(ALL_TILEMAPS, tilemap_flip);
101 }
102 }
103
WRITE16_HANDLER(nemesis_palette_word_w)104 WRITE16_HANDLER( nemesis_palette_word_w )
105 {
106 int r,g,b,bit1,bit2,bit3,bit4,bit5;
107
108 COMBINE_DATA(paletteram16 + offset);
109 data = paletteram16[offset];
110
111 /* Mish, 30/11/99 - Schematics show the resistor values are:
112 300 Ohms
113 620 Ohms
114 1200 Ohms
115 2400 Ohms
116 4700 Ohms
117
118 So the correct weights per bit are 8, 17, 33, 67, 130
119 */
120
121 #define MULTIPLIER 8 * bit1 + 17 * bit2 + 33 * bit3 + 67 * bit4 + 130 * bit5
122
123 bit1=(data >> 0)&1;
124 bit2=(data >> 1)&1;
125 bit3=(data >> 2)&1;
126 bit4=(data >> 3)&1;
127 bit5=(data >> 4)&1;
128 r = MULTIPLIER;
129 r = pow (r/255.0, 2)*255;
130 bit1=(data >> 5)&1;
131 bit2=(data >> 6)&1;
132 bit3=(data >> 7)&1;
133 bit4=(data >> 8)&1;
134 bit5=(data >> 9)&1;
135 g = MULTIPLIER;
136 g = pow (g/255.0, 2)*255;
137 bit1=(data >> 10)&1;
138 bit2=(data >> 11)&1;
139 bit3=(data >> 12)&1;
140 bit4=(data >> 13)&1;
141 bit5=(data >> 14)&1;
142 b = MULTIPLIER;
143 b = pow (b/255.0, 2)*255;
144
145 palette_set_color(offset,r,g,b);
146 }
147
WRITE16_HANDLER(salamander_palette_word_w)148 WRITE16_HANDLER( salamander_palette_word_w )
149 {
150 int r,g,b;
151
152 COMBINE_DATA(paletteram16 + offset);
153 offset &= ~1;
154
155 data = ((paletteram16[offset] << 8) & 0xff00) | (paletteram16[offset+1] & 0xff);
156
157 r = (data >> 0) & 0x1f;
158 g = (data >> 5) & 0x1f;
159 b = (data >> 10) & 0x1f;
160
161 r = (r << 3) | (r >> 2);
162 g = (g << 3) | (g >> 2);
163 b = (b << 3) | (b >> 2);
164
165 palette_set_color(offset / 2,r,g,b);
166 }
167
READ16_HANDLER(nemesis_videoram1b_word_r)168 READ16_HANDLER( nemesis_videoram1b_word_r )
169 {
170 return nemesis_videoram1b[offset];
171 }
READ16_HANDLER(nemesis_videoram1f_word_r)172 READ16_HANDLER( nemesis_videoram1f_word_r )
173 {
174 return nemesis_videoram1f[offset];
175 }
176
WRITE16_HANDLER(nemesis_videoram1b_word_w)177 WRITE16_HANDLER( nemesis_videoram1b_word_w )
178 {
179 COMBINE_DATA(nemesis_videoram1b + offset);
180 tilemap_mark_tile_dirty( foreground,offset );
181 }
WRITE16_HANDLER(nemesis_videoram1f_word_w)182 WRITE16_HANDLER( nemesis_videoram1f_word_w )
183 {
184 COMBINE_DATA(nemesis_videoram1f + offset);
185 tilemap_mark_tile_dirty( background,offset );
186 }
187
READ16_HANDLER(nemesis_videoram2b_word_r)188 READ16_HANDLER( nemesis_videoram2b_word_r )
189 {
190 return nemesis_videoram2b[offset];
191 }
READ16_HANDLER(nemesis_videoram2f_word_r)192 READ16_HANDLER( nemesis_videoram2f_word_r )
193 {
194 return nemesis_videoram2f[offset];
195 }
196
WRITE16_HANDLER(nemesis_videoram2b_word_w)197 WRITE16_HANDLER( nemesis_videoram2b_word_w )
198 {
199 COMBINE_DATA(nemesis_videoram2b + offset);
200 tilemap_mark_tile_dirty( foreground,offset );
201 }
WRITE16_HANDLER(nemesis_videoram2f_word_w)202 WRITE16_HANDLER( nemesis_videoram2f_word_w )
203 {
204 COMBINE_DATA(nemesis_videoram2f + offset);
205 tilemap_mark_tile_dirty( background,offset );
206 }
207
208
READ16_HANDLER(gx400_xscroll1_word_r)209 READ16_HANDLER( gx400_xscroll1_word_r ) { return nemesis_xscroll1[offset];}
READ16_HANDLER(gx400_xscroll2_word_r)210 READ16_HANDLER( gx400_xscroll2_word_r ) { return nemesis_xscroll2[offset];}
READ16_HANDLER(gx400_yscroll_word_r)211 READ16_HANDLER( gx400_yscroll_word_r ) { return nemesis_yscroll[offset];}
READ16_HANDLER(gx400_yscroll1_word_r)212 READ16_HANDLER( gx400_yscroll1_word_r ) { return nemesis_yscroll1[offset];}
READ16_HANDLER(gx400_yscroll2_word_r)213 READ16_HANDLER( gx400_yscroll2_word_r ) { return nemesis_yscroll2[offset];}
214
WRITE16_HANDLER(gx400_xscroll1_word_w)215 WRITE16_HANDLER( gx400_xscroll1_word_w ) { COMBINE_DATA(nemesis_xscroll1 + offset);}
WRITE16_HANDLER(gx400_xscroll2_word_w)216 WRITE16_HANDLER( gx400_xscroll2_word_w ) { COMBINE_DATA(nemesis_xscroll2 + offset);}
WRITE16_HANDLER(gx400_yscroll_word_w)217 WRITE16_HANDLER( gx400_yscroll_word_w ) { COMBINE_DATA(nemesis_yscroll + offset);}
WRITE16_HANDLER(gx400_yscroll1_word_w)218 WRITE16_HANDLER( gx400_yscroll1_word_w ) { COMBINE_DATA(nemesis_yscroll1 + offset);}
WRITE16_HANDLER(gx400_yscroll2_word_w)219 WRITE16_HANDLER( gx400_yscroll2_word_w ) { COMBINE_DATA(nemesis_yscroll2 + offset);}
220
221
222 /* we have to straighten out the 16-bit word into bytes for gfxdecode() to work */
READ16_HANDLER(nemesis_characterram_word_r)223 READ16_HANDLER( nemesis_characterram_word_r )
224 {
225 return nemesis_characterram[offset];
226 }
227
WRITE16_HANDLER(nemesis_characterram_word_w)228 WRITE16_HANDLER( nemesis_characterram_word_w )
229 {
230 data16_t oldword = nemesis_characterram[offset];
231 COMBINE_DATA(nemesis_characterram + offset);
232 data = nemesis_characterram[offset];
233
234 if (oldword != data)
235 {
236 char_dirty[offset / 16] = 1;
237 sprite_dirty[offset / 64] = 1;
238 sprite3216_dirty[offset / 128] = 1;
239 sprite1632_dirty[offset / 128] = 1;
240 sprite3232_dirty[offset / 256] = 1;
241 sprite168_dirty[offset / 32] = 1;
242 sprite816_dirty[offset / 32] = 1;
243 sprite6464_dirty[offset / 1024] = 1;
244 }
245 }
246
247
248 /* Fix the gdx decode info for lsb first systems */
nemesis_lsbify_gfx(void)249 static void nemesis_lsbify_gfx(void)
250 {
251 int i, j;
252 for(i=0; i<8; i++)
253 for(j=0; j<Machine->drv->gfxdecodeinfo[i].gfxlayout->width; j++)
254 Machine->drv->gfxdecodeinfo[i].gfxlayout->xoffset[j] ^= 8;
255 }
256
257
258 /* claim a palette dirty array */
VIDEO_START(nemesis)259 VIDEO_START( nemesis )
260 {
261 #ifndef MSB_FIRST
262 nemesis_lsbify_gfx();
263 #endif
264
265 spriteram_words = spriteram_size / 2;
266
267 background = tilemap_create(
268 get_bg_tile_info, tilemap_scan_rows, TILEMAP_TRANSPARENT, 8,8, 64,32 );
269
270 foreground = tilemap_create(
271 get_fg_tile_info, tilemap_scan_rows, TILEMAP_TRANSPARENT, 8,8, 64,32 );
272
273 if( !(background && foreground) )
274 return 1;
275
276 tilemap_set_transparent_pen( background, 0 );
277 tilemap_set_transparent_pen( foreground, 0 );
278 tilemap_set_scroll_rows( background, 256 );
279 tilemap_set_scroll_rows( foreground, 256 );
280
281 char_dirty = auto_malloc(2048);
282 if (!char_dirty)
283 return 1;
284 memset(char_dirty,1,2048);
285
286 sprite_dirty = auto_malloc(512);
287 if (!sprite_dirty)
288 return 1;
289 memset(sprite_dirty,1,512);
290
291 sprite3216_dirty = auto_malloc(256);
292 if (!sprite3216_dirty)
293 return 1;
294 memset(sprite3216_dirty,1,256);
295
296 sprite1632_dirty = auto_malloc(256);
297 if (!sprite1632_dirty)
298 return 1;
299 memset(sprite1632_dirty,1,256);
300
301 sprite3232_dirty = auto_malloc(128);
302 if (!sprite3232_dirty)
303 return 1;
304 memset(sprite3232_dirty,1,128);
305
306 sprite168_dirty = auto_malloc(1024);
307 if (!sprite168_dirty)
308 return 1;
309 memset(sprite168_dirty,1,1024);
310
311 sprite816_dirty = auto_malloc(1024);
312 if (!sprite816_dirty)
313 return 1;
314 memset(sprite816_dirty,1,32);
315
316 sprite6464_dirty = auto_malloc(32);
317 if (!sprite6464_dirty)
318 return 1;
319 memset(sprite6464_dirty,1,32);
320
321 memset(nemesis_characterram,0,nemesis_characterram_size);
322
323
324 blank_characterdata = auto_malloc(32*8/8*(2048+1));
325 if (!blank_characterdata)
326 return 1;
327 memset(blank_characterdata,0x00,32*8/8*(2048+1));
328 decodechar(Machine->gfx[0],0x800,(unsigned char *)blank_characterdata,
329 Machine->drv->gfxdecodeinfo[0].gfxlayout);
330
331 flipscreen = 0;
332 tilemap_flip = 0;
333
334 return 0;
335 }
336
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)337 static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect)
338 {
339 /*
340 * 16 bytes per sprite, in memory from 56000-56fff
341 *
342 * byte 0 : relative priority.
343 * byte 2 : size (?) value #E0 means not used., bit 0x01 is flipx
344 0xc0 is upper 2 bits of zoom.
345 0x38 is size.
346 * byte 4 : zoom = 0xff
347 * byte 6 : low bits sprite code.
348 * byte 8 : color + hi bits sprite code., bit 0x20 is flipy bit. bit 0x01 is high bit of X pos.
349 * byte A : X position.
350 * byte C : Y position.
351 * byte E : not used.
352 */
353
354 int adress; /* start of sprite in spriteram */
355 int sx; /* sprite X-pos */
356 int sy; /* sprite Y-pos */
357 int code; /* start of sprite in obj RAM */
358 int color; /* color of the sprite */
359 int flipx,flipy;
360 int zoom;
361 int char_type;
362 int priority;
363 int size;
364 int w,h;
365
366 for (priority=256-1; priority>=0; priority--)
367 {
368 for (adress = spriteram_words-8; adress >= 0; adress -= 8)
369 {
370 if((spriteram16[adress] & 0xff)!=priority) continue;
371
372 zoom = spriteram16[adress+2] & 0xff;
373 if (!(spriteram16[adress+2] & 0xff00) && ((spriteram16[adress+3] & 0xff00) != 0xff00))
374 code = spriteram16[adress+3] + ((spriteram16[adress+4] & 0xc0) << 2);
375 else
376 code = (spriteram16[adress+3] & 0xff) + ((spriteram16[adress+4] & 0xc0) << 2);
377
378 if (zoom != 0xFF || code!=0)
379 {
380 size=spriteram16[adress+1];
381 zoom+=(size&0xc0)<<2;
382
383 sx = spriteram16[adress+5]&0xff;
384 sy = spriteram16[adress+6]&0xff;
385 if(spriteram16[adress+4]&1)
386 sx-=0x100; /* fixes left side clip */
387 color = (spriteram16[adress+4] & 0x1e) >> 1;
388 flipx = spriteram16[adress+1] & 0x01;
389 flipy = spriteram16[adress+4] & 0x20;
390
391 switch(size&0x38)
392 {
393 case 0x00: /* sprite 32x32*/
394 char_type=4;
395 code/=8;
396 w=32;
397 h=32;
398 break;
399 case 0x08: /* sprite 16x32 */
400 char_type=5;
401 code/=4;
402 w=16;
403 h=32;
404 break;
405 case 0x10: /* sprite 32x16 */
406 char_type=2;
407 code/=4;
408 w=32;
409 h=16;
410 break;
411 case 0x18: /* sprite 64x64 */
412 char_type=7;
413 code/=32;
414 w=64;
415 h=64;
416 break;
417 case 0x20: /* char 8x8 */
418 char_type=0;
419 code*=2;
420 w=8;
421 h=8;
422 break;
423 case 0x28: /* sprite 16x8 */
424 char_type=6;
425 w=16;
426 h=8;
427 break;
428 case 0x30: /* sprite 8x16 */
429 char_type=3;
430 w=8;
431 h=16;
432 break;
433 case 0x38:
434 default: /* sprite 16x16 */
435 char_type=1;
436 code/=2;
437 w=16;
438 h=16;
439 break;
440 }
441
442 if( zoom )
443 {
444 zoom = ((1<<16)*0x80/zoom) + 0x0200;
445 if (flipscreen)
446 {
447 sx = 256 - ((zoom * w) >> 16) - sx;
448 sy = 256 - ((zoom * h) >> 16) - sy;
449 flipx = !flipx;
450 flipy = !flipy;
451 }
452 pdrawgfxzoom(bitmap,Machine->gfx[char_type],
453 code,
454 color,
455 flipx,flipy,
456 sx,sy,
457 cliprect,TRANSPARENCY_PEN,0,
458 zoom,zoom,
459 0xfff0 );
460 }
461 } /* if sprite */
462 } /* for loop */
463 } /* priority */
464 }
465
466 /******************************************************************************/
467
update_gfx(void)468 static void update_gfx(void)
469 {
470 int offs,code;
471 int bAnyDirty;
472
473 bAnyDirty = 0;
474 for (offs = 0x800 - 1;offs >= 0;offs --)
475 {
476 if (char_dirty[offs] )
477 {
478 decodechar(Machine->gfx[0],offs,(unsigned char *)nemesis_characterram,
479 Machine->drv->gfxdecodeinfo[0].gfxlayout);
480 bAnyDirty = 1;
481 char_dirty[offs] = 0;
482 }
483 }
484 if( bAnyDirty )
485 {
486 tilemap_mark_all_tiles_dirty( background );
487 tilemap_mark_all_tiles_dirty( foreground );
488 }
489
490 for (offs = 0;offs < spriteram_words;offs += 8)
491 {
492 int char_type;
493 int zoom;
494
495 zoom = spriteram16[offs+2] & 0xff;
496 if (!(spriteram16[offs+2] & 0xff00) && ((spriteram16[offs+3] & 0xff00) != 0xff00))
497 code = spriteram16[offs+3] + ((spriteram16[offs+4] & 0xc0) << 2);
498 else
499 code = (spriteram16[offs+3] & 0xff) + ((spriteram16[offs+4] & 0xc0) << 2);
500
501 if (zoom != 0xFF || code!=0)
502 {
503 int size = spriteram16[offs+1];
504 switch(size&0x38)
505 {
506 case 0x00:
507 /* sprite 32x32*/
508 char_type=4;
509 code/=8;
510 if (sprite3232_dirty[code] == 1)
511 {
512 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
513 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
514 sprite3232_dirty[code] = 0;
515 }
516 break;
517 case 0x08:
518 /* sprite 16x32 */
519 char_type=5;
520 code/=4;
521 if (sprite1632_dirty[code] == 1)
522 {
523 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
524 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
525 sprite1632_dirty[code] = 0;
526
527 }
528 break;
529 case 0x10:
530 /* sprite 32x16 */
531 char_type=2;
532 code/=4;
533 if (sprite3216_dirty[code] == 1)
534 {
535 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
536 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
537 sprite3216_dirty[code] = 0;
538 }
539 break;
540 case 0x18:
541 /* sprite 64x64 */
542 char_type=7;
543 code/=32;
544 if (sprite6464_dirty[code] == 1)
545 {
546 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
547 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
548 sprite6464_dirty[code] = 0;
549 }
550 break;
551 case 0x20:
552 /* char 8x8 */
553 char_type=0;
554 code*=2;
555 if (char_dirty[code] == 1)
556 {
557 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
558 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
559 char_dirty[code] = 0;
560 }
561 break;
562 case 0x28:
563 /* sprite 16x8 */
564 char_type=6;
565 if (sprite168_dirty[code] == 1)
566 {
567 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
568 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
569 sprite168_dirty[code] = 0;
570 }
571 break;
572 case 0x30:
573 /* sprite 8x16 */
574 char_type=3;
575 if (sprite816_dirty[code] == 1)
576 {
577 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
578 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
579 sprite816_dirty[code] = 0;
580 }
581 break;
582 default:
583 logerror("UN-SUPPORTED SPRITE SIZE %-4x\n",size&0x38);
584 case 0x38:
585 /* sprite 16x16 */
586 char_type=1;
587 code/=2;
588 if (sprite_dirty[code] == 1)
589 {
590 decodechar(Machine->gfx[char_type],code,(unsigned char *)nemesis_characterram,
591 Machine->drv->gfxdecodeinfo[char_type].gfxlayout);
592 sprite_dirty[code] = 2;
593
594 }
595 break;
596 }
597 }
598 }
599 }
600
601 /******************************************************************************/
602
VIDEO_UPDATE(nemesis)603 VIDEO_UPDATE( nemesis )
604 {
605 int offs;
606
607 update_gfx();
608
609 fillbitmap(priority_bitmap,0,cliprect);
610 fillbitmap(bitmap,Machine->pens[0],cliprect);
611
612 tilemap_set_scrolly( background, 0, (nemesis_yscroll[0x180] & 0xff) );
613
614 for (offs = 0;offs < 256;offs++)
615 {
616 tilemap_set_scrollx( background, offs,
617 (nemesis_xscroll2[offs] & 0xff) + ((nemesis_xscroll2[0x100 + offs] & 0x01) << 8) - (flipscreen ? 0x107 : 0) );
618 tilemap_set_scrollx( foreground, offs,
619 (nemesis_xscroll1[offs] & 0xff) + ((nemesis_xscroll1[0x100 + offs] & 0x01) << 8) - (flipscreen ? 0x107 : 0) );
620 }
621
622 tilemap_draw(bitmap,cliprect,background,0,1);
623 tilemap_draw(bitmap,cliprect,foreground,0,2);
624 tilemap_draw(bitmap,cliprect,background,1,4);
625 tilemap_draw(bitmap,cliprect,foreground,1,8);
626
627 draw_sprites(bitmap,cliprect);
628 }
629
VIDEO_UPDATE(salamand)630 VIDEO_UPDATE( salamand )
631 {
632 int offs;
633 struct rectangle clip;
634
635 update_gfx();
636
637 fillbitmap(priority_bitmap,0,cliprect);
638 fillbitmap(bitmap,Machine->pens[0],cliprect);
639
640 clip.min_x = 0;
641 clip.max_x = 255;
642
643 tilemap_set_scroll_cols( background, 64 );
644 tilemap_set_scroll_cols( foreground, 64 );
645 tilemap_set_scroll_rows( background, 1 );
646 tilemap_set_scroll_rows( foreground, 1 );
647
648 for (offs = 0; offs < 64; offs++)
649 {
650 tilemap_set_scrolly( background, offs, nemesis_yscroll1[offs] );
651 tilemap_set_scrolly( foreground, offs, nemesis_yscroll2[offs] );
652 }
653
654 for (offs = cliprect->min_y; offs <= cliprect->max_y; offs++)
655 {
656 clip.min_y = offs;
657 clip.max_y = offs;
658
659 tilemap_set_scrollx( background, 0,
660 ((nemesis_xscroll2[offs] & 0xff) + ((nemesis_xscroll2[0x100 + offs] & 1) << 8)) );
661 tilemap_set_scrollx( foreground, 0,
662 ((nemesis_xscroll1[offs] & 0xff) + ((nemesis_xscroll1[0x100 + offs] & 1) << 8)) );
663
664 tilemap_draw(bitmap,&clip,foreground,0,1);
665 tilemap_draw(bitmap,&clip,background,0,2);
666 tilemap_draw(bitmap,&clip,foreground,1,4);
667 tilemap_draw(bitmap,&clip,background,1,8);
668 }
669
670 draw_sprites(bitmap,cliprect);
671 }
672