From e3df2f0f546e468442788ce5012b462ead9b1158 Mon Sep 17 00:00:00 2001 From: Zsolt Vasvari Date: Sat, 26 Jan 2008 13:58:31 +0000 Subject: [PATCH] - Changed video code to directly manipulate the game bitmap - Background smoothing now happens at the same time as the background is drawn - Our smoothing PROMs are half the size shown on the schamatics. The schematics shows A8-A10 connected, indicating 8 different smoothing tables. Our dumps are only 0x400 bytes long, half the size they should be. I marked them BAD_DUMP and the game IMPERFECT_GRAPHICS --- src/mame/drivers/jedi.c | 85 ++------ src/mame/includes/jedi.h | 5 +- src/mame/video/jedi.c | 419 +++++++++++++++++++++------------------ 3 files changed, 251 insertions(+), 258 deletions(-) diff --git a/src/mame/drivers/jedi.c b/src/mame/drivers/jedi.c index 693ee013252..5107fa279c1 100644 --- a/src/mame/drivers/jedi.c +++ b/src/mame/drivers/jedi.c @@ -8,7 +8,7 @@ * Return of the Jedi Known bugs: - * none at this time + * smoothing PROMs were dumped at half size **************************************************************************** @@ -308,7 +308,7 @@ static READ8_HANDLER( soundstat_r ) static WRITE8_HANDLER( jedi_coin_counter_w ) { - coin_counter_w(offset, data >> 7); + coin_counter_w(offset, data); } @@ -382,15 +382,15 @@ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x1e00, 0x1e00) AM_WRITE(main_irq_ack_w) AM_RANGE(0x1e80, 0x1e81) AM_WRITE(jedi_coin_counter_w) AM_RANGE(0x1e82, 0x1e83) AM_WRITE(MWA8_NOP) /* LED control; not used */ - AM_RANGE(0x1e84, 0x1e84) AM_WRITE(jedi_alpha_banksel_w) + AM_RANGE(0x1e84, 0x1e84) AM_WRITE(MWA8_RAM) AM_BASE(&jedi_foreground_bank) AM_RANGE(0x1e86, 0x1e86) AM_WRITE(sound_reset_w) AM_RANGE(0x1e87, 0x1e87) AM_WRITE(jedi_video_off_w) AM_RANGE(0x1f00, 0x1f00) AM_WRITE(sound_latch_w) AM_RANGE(0x1f80, 0x1f80) AM_WRITE(rom_banksel_w) - AM_RANGE(0x2000, 0x27ff) AM_RAM AM_BASE(&jedi_backgroundram) AM_SIZE(&jedi_backgroundram_size) - AM_RANGE(0x2800, 0x2fff) AM_READWRITE(MRA8_RAM, jedi_paletteram_w) AM_BASE(&paletteram) - AM_RANGE(0x3000, 0x37bf) AM_RAM AM_BASE(&videoram) AM_SIZE(&videoram_size) - AM_RANGE(0x37c0, 0x3bff) AM_RAM AM_BASE(&spriteram) AM_SIZE(&spriteram_size) + AM_RANGE(0x2000, 0x27ff) AM_RAM AM_BASE(&jedi_backgroundram) + AM_RANGE(0x2800, 0x2fff) AM_RAM AM_BASE(&jedi_paletteram) + AM_RANGE(0x3000, 0x37bf) AM_RAM AM_BASE(&jedi_foregroundram) + AM_RANGE(0x37c0, 0x3bff) AM_RAM AM_BASE(&jedi_spriteram) AM_RANGE(0x3c00, 0x3c01) AM_WRITE(jedi_vscroll_w) AM_RANGE(0x3d00, 0x3d01) AM_WRITE(jedi_hscroll_w) AM_RANGE(0x3e00, 0x3fff) AM_WRITE(jedi_PIXIRAM_w) @@ -457,57 +457,6 @@ INPUT_PORTS_END -/************************************* - * - * Graphics layouts - * - *************************************/ - -static const gfx_layout charlayout = -{ - 8,8, - RGN_FRAC(1,1), - 2, - { 0, 1 }, - { 0, 2, 4, 6, 8, 10, 12, 14 }, - { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, - 16*8 -}; - - -static const gfx_layout pflayout = -{ - 8,8, - RGN_FRAC(1,2), - 4, - { 0, 4, RGN_FRAC(1,2), RGN_FRAC(1,2)+4 }, - { 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3 }, - { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, - 16*8 -}; - - -static const gfx_layout spritelayout = -{ - 8,16, - RGN_FRAC(1,2), - 4, - { 0, 4, RGN_FRAC(1,2), RGN_FRAC(1,2)+4 }, - { 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3}, - { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16, - 8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16 }, - 32*8 -}; - - -static GFXDECODE_START( jedi ) - GFXDECODE_ENTRY( REGION_GFX1, 0, charlayout, 0, 1 ) - GFXDECODE_ENTRY( REGION_GFX2, 0, pflayout, 0, 1 ) - GFXDECODE_ENTRY( REGION_GFX3, 0, spritelayout, 0, 1 ) -GFXDECODE_END - - - /************************************* * * Machine driver @@ -532,11 +481,9 @@ static MACHINE_DRIVER_START( jedi ) /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(37*8, 262) /* verify vert size */ + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) + MDRV_SCREEN_SIZE(64*8, 262) /* verify vert size */ MDRV_SCREEN_VISIBLE_AREA(0*8, 37*8-1, 0*8, 30*8-1) - MDRV_GFXDECODE(jedi) - MDRV_PALETTE_LENGTH(1024+1) MDRV_VIDEO_START(jedi) MDRV_VIDEO_UPDATE(jedi) @@ -583,22 +530,22 @@ ROM_START( jedi ) ROM_LOAD( "136030-133.01c", 0x8000, 0x4000, CRC(6c601c69) SHA1(618b77800bbbb4db34a53ca974a71bdaf89b5930) ) ROM_LOAD( "136030-134.01a", 0xC000, 0x4000, CRC(5e36c564) SHA1(4b0afceb9a1d912f1d5c1f26928d244d5b14ea4a) ) - ROM_REGION( 0x02000, REGION_GFX1, ROMREGION_DISPOSE ) + ROM_REGION( 0x02000, REGION_GFX1,0 ) ROM_LOAD( "136030-215.11t", 0x00000, 0x2000, CRC(3e49491f) SHA1(ade5e846069c2fa6edf667469d13ce5a6a45c06d) ) /* Alphanumeric */ - ROM_REGION( 0x10000, REGION_GFX2, ROMREGION_DISPOSE ) + ROM_REGION( 0x10000, REGION_GFX2,0 ) ROM_LOAD( "136030-126.06r", 0x00000, 0x8000, CRC(9c55ece8) SHA1(b8faa23314bb0d199ef46199bfabd9cb17510dd3) ) /* Playfield */ ROM_LOAD( "136030-127.06n", 0x08000, 0x8000, CRC(4b09dcc5) SHA1(d46b5f4fb69c4b8d823dd9c4d92f8713badfa44a) ) - ROM_REGION( 0x20000, REGION_GFX3, ROMREGION_DISPOSE ) + ROM_REGION( 0x20000, REGION_GFX3, 0 ) ROM_LOAD( "136030-130.01h", 0x00000, 0x8000, CRC(2646a793) SHA1(dcb5fd50eafbb27565bce099a884be83a9d82285) ) /* Sprites */ ROM_LOAD( "136030-131.01f", 0x08000, 0x8000, CRC(60107350) SHA1(ded03a46996d3f2349df7f59fd435a7ad6ed465e) ) ROM_LOAD( "136030-128.01m", 0x10000, 0x8000, CRC(24663184) SHA1(5eba142ed926671ee131430944e59f21a55a5c57) ) ROM_LOAD( "136030-129.01k", 0x18000, 0x8000, CRC(ac86b98c) SHA1(9f86c8801a7293fa46e9432f1651dd85bf00f4b9) ) - ROM_REGION( 0x0800, REGION_PROMS, 0 ) /* background smoothing */ - ROM_LOAD( "136030-117.bin", 0x0000, 0x0400, CRC(9831bd55) SHA1(12945ef2d1582914125b9ee591567034d71d6573) ) - ROM_LOAD( "136030-118.bin", 0x0400, 0x0400, CRC(261fbfe7) SHA1(efc65a74a3718563a07b718e34d8a7aa23339a69) ) + ROM_REGION( 0x1000, REGION_PROMS, 0 ) /* background smoothing */ + ROM_LOAD( "136030-117.bin", 0x0000, 0x0800, BAD_DUMP CRC(9831bd55) SHA1(12945ef2d1582914125b9ee591567034d71d6573) ) + ROM_LOAD( "136030-118.bin", 0x0800, 0x0800, BAD_DUMP CRC(261fbfe7) SHA1(efc65a74a3718563a07b718e34d8a7aa23339a69) ) ROM_END @@ -609,4 +556,4 @@ ROM_END * *************************************/ -GAME( 1984, jedi, 0, jedi, jedi, 0, ROT0, "Atari", "Return of the Jedi", GAME_SUPPORTS_SAVE ) +GAME( 1984, jedi, 0, jedi, jedi, 0, ROT0, "Atari", "Return of the Jedi", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE ) diff --git a/src/mame/includes/jedi.h b/src/mame/includes/jedi.h index 80ba0bf018a..babf5863ce3 100644 --- a/src/mame/includes/jedi.h +++ b/src/mame/includes/jedi.h @@ -6,8 +6,11 @@ /*----------- defined in video/jedi.c -----------*/ +extern UINT8 *jedi_foregroundram; extern UINT8 *jedi_backgroundram; -extern size_t jedi_backgroundram_size; +extern UINT8 *jedi_spriteram; +extern UINT8 *jedi_paletteram; +extern UINT8 *jedi_foreground_bank; VIDEO_START( jedi ); VIDEO_UPDATE( jedi ); diff --git a/src/mame/video/jedi.c b/src/mame/video/jedi.c index 65206dc0723..84edd57d5c8 100644 --- a/src/mame/video/jedi.c +++ b/src/mame/video/jedi.c @@ -2,24 +2,35 @@ Atari Return of the Jedi hardware + Return of the Jedi has a peculiar playfield/motion object + priority system. That is, there is no priority system ;-) + The color of the pixel which appears on screen depends on + all three of the foreground, background and motion objects. + The 1024 colors palette is appropriately set up by the program + to "emulate" a priority system, but it can also be used to display + completely different colors (see the palette test in service mode) + ***************************************************************************/ #include "driver.h" -#include "deprecat.h" #include "jedi.h" -/* globals */ -UINT8 *jedi_backgroundram; -size_t jedi_backgroundram_size; +#define NUM_PENS (0x1000) +/* globals */ +UINT8 *jedi_foregroundram; +UINT8 *jedi_backgroundram; +UINT8 *jedi_spriteram; +UINT8 *jedi_paletteram; +UINT8 *jedi_foreground_bank; + /* local variables */ static UINT32 jedi_vscroll; static UINT32 jedi_hscroll; -static UINT32 jedi_alpha_bank; -static UINT8 video_off, smooth_table; -static mame_bitmap *fgbitmap, *mobitmap, *bgbitmap, *bgexbitmap; +static UINT8 video_off; +static UINT8 smoothing_table; @@ -31,28 +42,11 @@ static mame_bitmap *fgbitmap, *mobitmap, *bgbitmap, *bgexbitmap; VIDEO_START( jedi ) { - /* allocate an 8bpp bitmap for the raw foreground characters */ - fgbitmap = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format); - - /* allocate an 8bpp bitmap for the motion objects */ - mobitmap = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format); - fillbitmap(mobitmap, 0, &machine->screen[0].visarea); - - /* the background area is 256x256, doubled by the hardware*/ - bgbitmap = auto_bitmap_alloc(256, 256, machine->screen[0].format); - - /* the expanded background area is 512x512 */ - bgexbitmap = auto_bitmap_alloc(512, 512, machine->screen[0].format); - - /* reserve color 1024 for black (disabled display) */ - palette_set_color(machine, 1024, MAKE_RGB(0, 0, 0)); - /* register for saving */ state_save_register_global(jedi_vscroll); state_save_register_global(jedi_hscroll); - state_save_register_global(jedi_alpha_bank); state_save_register_global(video_off); - state_save_register_global(smooth_table); + state_save_register_global(smoothing_table); } @@ -83,36 +77,39 @@ VIDEO_START( jedi ) * *************************************/ -WRITE8_HANDLER( jedi_paletteram_w ) +static void get_pens(pen_t *pens) { - int r, g, b, bits, intensity; - UINT32 color; + offs_t offs; - paletteram[offset] = data; - color = paletteram[offset & 0x3FF] | (paletteram[offset | 0x400] << 8); + for (offs = 0; offs < NUM_PENS; offs++) + { + int r, g, b, bits, intensity; - intensity = (color >> 9) & 7; - bits = (color >> 6) & 7; - r = 5 * bits * intensity; - bits = (color >> 3) & 7; - g = 5 * bits * intensity; - bits = (color >> 0) & 7; - b = 5 * bits * intensity; + UINT16 color = jedi_paletteram[offs] | (jedi_paletteram[offs | 0x400] << 8); - palette_set_color(Machine, offset & 0x3ff, MAKE_RGB(r, g, b)); + intensity = (color >> 9) & 7; + bits = (color >> 6) & 7; + r = 5 * bits * intensity; + bits = (color >> 3) & 7; + g = 5 * bits * intensity; + bits = (color >> 0) & 7; + b = 5 * bits * intensity; + + pens[offs] = MAKE_RGB(r, g, b); + } } - -/************************************* - * - * Foreground banking - * - *************************************/ - -WRITE8_HANDLER( jedi_alpha_banksel_w ) +static void do_pen_lookup(mame_bitmap *bitmap, const rectangle *cliprect) { - jedi_alpha_bank = 2 * (data & 0x80); + int y, x; + pen_t pens[NUM_PENS]; + + get_pens(pens); + + for (y = cliprect->min_y; y <= cliprect->max_y; y++) + for(x = cliprect->min_x; x <= cliprect->max_x; x++) + *BITMAP_ADDR32(bitmap, y, x) = pens[*BITMAP_ADDR32(bitmap, y, x)]; } @@ -150,68 +147,204 @@ WRITE8_HANDLER( jedi_video_off_w ) WRITE8_HANDLER( jedi_PIXIRAM_w ) { - smooth_table = data & 0x03; + /* this should really be 0x07, but the PROMs were + dumped at half size */ + smoothing_table = data & 0x03; } /************************************* * - * Background smoothing + * Foreground drawing * *************************************/ -static void update_smoothing(int bgtilerow) +static void draw_foreground(mame_bitmap *bitmap) { - UINT8 *prom = memory_region(REGION_PROMS) + smooth_table * 0x100; - UINT8 bgscan[2][256]; - UINT8 *bgcurr = bgscan[0], *bglast = bgscan[1]; - int x, y; + offs_t offs; + UINT32 *dst = BITMAP_ADDR32(bitmap, 0, 0); - /* - smoothing notes: - * even scanlines blend the previous (Y-1) and current (Y) line - * odd scanlines are just taken from the current line (Y) - * therefore, if we modify source scanlines 8-15, we must update dest scanlines 16-32 - - * even pixels are just taken from the current pixel (X) - * odd pixels blend the current (X) and next (X+1) pixels - * therefore, if we modify source pixels 8-15, we must update dest pixels 15-31 - */ - - /* extract the previous bg scanline */ - extract_scanline8(bgbitmap, 0, ((bgtilerow * 16 - 1) & 0x1ff) / 2, 256, bgcurr); - - /* loop over height */ - for (y = 0; y <= 16; y++) + /* draw the bitmap 4 pixels at a time */ + for (offs = 0; offs < 0x7c00; offs++) { - int curry = (bgtilerow * 16 + y) & 0x1ff; + UINT16 code = ((*jedi_foreground_bank & 0x80) << 1) | + jedi_foregroundram[((offs & 0x7c00) >> 4) | ((offs & 0x7e) >> 1)]; - /* swap background buffers */ - UINT8 *bgtemp = bgcurr; - bgcurr = bglast; - bglast = bgtemp; + UINT8 data = memory_region(REGION_GFX1)[(code << 4) | ((offs & 0x380) >> 6) | (offs & 0x01)]; - /* extract current bg scanline */ - extract_scanline8(bgbitmap, 0, curry / 2, 256, bgcurr); + /* the background pixel determines pen address bits A8 and A9 */ + dst[0] = (dst[0] & 0xff) | ((data & 0xc0) << 2); + dst[1] = (dst[1] & 0xff) | ((data & 0x30) << 4); + dst[2] = (dst[2] & 0xff) | ((data & 0x0c) << 6); + dst[3] = (dst[3] & 0xff) | ((data & 0x03) << 8); - /* loop over columns */ - for (x = -1; x <= 511; x++) + dst = dst + 4; + } +} + + + +/************************************* + * + * Background drawing with smoothing + * + *************************************/ + +static void draw_and_smooth_background(mame_bitmap *bitmap, const rectangle *cliprect) +{ + int y; + UINT32 background_line_buffer[0x200]; /* RAM chip at 2A */ + + UINT8 *prom1 = &memory_region(REGION_PROMS)[0x0000 | (smoothing_table << 8)]; + UINT8 *prom2 = &memory_region(REGION_PROMS)[0x0800 | (smoothing_table << 8)]; + + memset(background_line_buffer, 0, 0x200 * sizeof(UINT32)); + + for (y = cliprect->min_y; y <= cliprect->max_y; y++) + { + int x; + UINT32 last_col = 0; + + for (x = cliprect->min_x; x <= cliprect->max_x; x += 2) { - int tr = bglast[((x + 1) & 0x1ff) / 2]; - int br = bgcurr[((x + 1) & 0x1ff) / 2]; + UINT32 col; + UINT32 tempcol; + offs_t gfx_offs; + UINT8 data1; + UINT8 data2; - /* smooth pixels */ - if (x & 1) + int sy = y + jedi_vscroll; + int sx = x + jedi_hscroll; + + offs_t backgroundram_offs = ((sy & 0x1f0) << 1) | ((sx & 0x1f0) >> 4); + + /* shuffle the bank bits in */ + UINT8 bank = jedi_backgroundram[0x0400 | backgroundram_offs]; + UINT16 code = jedi_backgroundram[0x0000 | backgroundram_offs] | + ((bank & 0x01) << 8) | + ((bank & 0x08) << 6) | + ((bank & 0x02) << 9); + + /* flip X */ + if (bank & 0x04) + sx = sx ^ 0x0f; + + /* get the pointer to the graphics */ + gfx_offs = (code << 4) | (sy & 0x0e) | (((sx & 0x08) >> 3)); + + data1 = memory_region(REGION_GFX2)[0x0000 | gfx_offs]; + data2 = memory_region(REGION_GFX2)[0x8000 | gfx_offs]; + + /* the foreground pixel determines pen address bits A0-A3 */ + switch (sx & 0x06) { - int tl = bglast[(x & 0x1ff) / 2]; - int bl = bgcurr[(x & 0x1ff) / 2]; - int mixt = prom[16 * tl + tr]; - int mixb = prom[16 * bl + br]; - *BITMAP_ADDR16(bgexbitmap, curry, x & 0x1ff) = prom[0x400 + 16 * mixt + mixb]; + case 0x00: col = ((data1 & 0x80) >> 4) | ((data1 & 0x08) >> 1) | ((data2 & 0x80) >> 6) | ((data2 & 0x08) >> 3); break; + case 0x02: col = ((data1 & 0x40) >> 3) | ((data1 & 0x04) >> 0) | ((data2 & 0x40) >> 5) | ((data2 & 0x04) >> 2); break; + case 0x04: col = ((data1 & 0x20) >> 2) | ((data1 & 0x02) << 1) | ((data2 & 0x20) >> 4) | ((data2 & 0x02) >> 1); break; + default: col = ((data1 & 0x10) >> 1) | ((data1 & 0x01) << 2) | ((data2 & 0x10) >> 3) | ((data2 & 0x01) >> 0); break; } + + /* the first pixel is smoothed via a lookup using the current and last pixel value - + the next pixel just uses the current value directly. After we done with a pixel + save it for later in the line buffer RAM */ + tempcol = prom1[(last_col << 4) | col]; + *BITMAP_ADDR32(bitmap, y, x + 0) = prom2[(background_line_buffer[x + 0] << 4) | tempcol]; + *BITMAP_ADDR32(bitmap, y, x + 1) = prom2[(background_line_buffer[x + 1] << 4) | col]; + background_line_buffer[x + 0] = tempcol; + background_line_buffer[x + 1] = col; + + last_col = col; + } + } +} + + + +/************************************* + * + * Sprite drawing + * + *************************************/ + +static void draw_sprites(mame_bitmap *bitmap) +{ + offs_t offs; + + for (offs = 0x00; offs < 0x30; offs++) + { + int sy; + int y_size; + UINT8 *gfx; + + /* coordinates adjustments made to match screenshot */ + UINT8 y = 240 - jedi_spriteram[offs + 0x80] + 1; + int flip_x = jedi_spriteram[offs + 0x40] & 0x10; + int flip_y = jedi_spriteram[offs + 0x40] & 0x20; + int tall = jedi_spriteram[offs + 0x40] & 0x08; + + /* shuffle the bank bits in */ + UINT16 code = jedi_spriteram[offs] | + ((jedi_spriteram[offs + 0x40] & 0x04) << 8) | + ((jedi_spriteram[offs + 0x40] & 0x40) << 3) | + ((jedi_spriteram[offs + 0x40] & 0x02) << 7); + + /* adjust for double-height */ + if (tall) + { + code &= ~1; + y_size = 0x20; + y = y - 0x10; + } + else + y_size = 0x10; + + gfx = &memory_region(REGION_GFX3)[code << 5]; + + if (flip_y) + y = y + y_size - 1; + + for (sy = 0; sy < y_size; sy++) + { + int i; + UINT16 x = jedi_spriteram[offs + 0x100] + ((jedi_spriteram[offs + 0x40] & 0x01) << 8) - 2; + + if (flip_x) + x = x + 7; + + for (i = 0; i < 2; i++) + { + int sx; + UINT8 data1 = *(0x00000 + gfx); + UINT8 data2 = *(0x10000 + gfx); + + for (sx = 0; sx < 4; sx++) + { + /* the sprite pixel determines pen address bits A4-A7 */ + UINT32 col = ((data1 & 0x80) >> 0) | ((data1 & 0x08) << 3) | ((data2 & 0x80) >> 2) | ((data2 & 0x08) << 1); + + x = x & 0x1ff; + + if (col) + *BITMAP_ADDR32(bitmap, y, x) = (*BITMAP_ADDR32(bitmap, y, x) & 0x30f) | col; + + /* next pixel */ + if (flip_x) + x = x - 1; + else + x = x + 1; + + data1 = data1 << 1; + data2 = data2 << 1; + } + + gfx = gfx + 1; + } + + if (flip_y) + y = y - 1; else - *BITMAP_ADDR16(bgexbitmap, curry, x & 0x1ff) = prom[0x400 + 16 * tr + br]; + y = y + 1; } } } @@ -226,109 +359,19 @@ static void update_smoothing(int bgtilerow) VIDEO_UPDATE( jedi ) { - int offs; - - /* if no video, clear it all to black */ if (video_off) + fillbitmap(bitmap, RGB_BLACK, cliprect); + else { - fillbitmap(bitmap, machine->pens[1024], &machine->screen[0].visarea); - return 0; + /* draw the background - it needs to be done first */ + draw_and_smooth_background(bitmap, cliprect); + + draw_foreground(bitmap); + draw_sprites(bitmap); + + do_pen_lookup(bitmap, cliprect); } - /* Return of the Jedi has a peculiar playfield/motion object priority system. That */ - /* is, there is no priority system ;-) The color of the pixel which appears on */ - /* screen depends on all three of the foreground, background and motion objects. The */ - /* 1024 colors palette is appropriately set up by the program to "emulate" a */ - /* priority system, but it can also be used to display completely different */ - /* colors (see the palette test in service mode) */ - - /* update foreground bitmap as a raw bitmap*/ - for (offs = videoram_size - 1; offs >= 0; offs--) - { - int sx = offs % 64; - int sy = offs / 64; - - drawgfx(fgbitmap, machine->gfx[0], videoram[offs] + jedi_alpha_bank, - 0, 0, 0, 8*sx, 8*sy, &machine->screen[0].visarea, TRANSPARENCY_NONE_RAW, 0); - } - - /* update background bitmap as a raw bitmap */ - for (offs = jedi_backgroundram_size / 2 - 1; offs >= 0; offs--) - { - int sx = offs % 32; - int sy = offs / 32; - int code = (jedi_backgroundram[offs] & 0xFF); - int bank = (jedi_backgroundram[offs + 0x400] & 0x0F); - - /* shuffle the bank bits in */ - code |= (bank & 0x01) << 8; - code |= (bank & 0x08) << 6; - code |= (bank & 0x02) << 9; - - drawgfx(bgbitmap, machine->gfx[1], code, - 0, bank & 0x04, 0, 8*sx, 8*sy, 0, TRANSPARENCY_NONE_RAW, 0); - } - - /* update smoothed version of background */ - for (offs = 0; offs < 32; offs++) - update_smoothing(offs); - - /* draw the motion objects */ - for (offs = 0; offs < 0x30; offs++) - { - /* coordinates adjustments made to match screenshot */ - int x = spriteram[offs + 0x100] + ((spriteram[offs + 0x40] & 0x01) << 8) - 2; - int y = 240 - spriteram[offs + 0x80] + 1; - int flipx = spriteram[offs + 0x40] & 0x10; - int flipy = spriteram[offs + 0x40] & 0x20; - int tall = spriteram[offs + 0x40] & 0x08; - int code, bank; - - /* shuffle the bank bits in */ - bank = ((spriteram[offs + 0x40] & 0x02) >> 1); - bank |= ((spriteram[offs + 0x40] & 0x40) >> 5); - bank |= (spriteram[offs + 0x40] & 0x04); - code = spriteram[offs] + (bank * 256); - - /* adjust for double-height */ - if (tall) - code |= 1; - - /* draw motion object */ - drawgfx(mobitmap, machine->gfx[2], code, - 0, flipx, flipy, x, y, &machine->screen[0].visarea, TRANSPARENCY_PEN_RAW, 0); - - /* handle double-height */ - if (tall) - drawgfx(mobitmap, machine->gfx[2], code - 1, - 0, flipx, flipy, x, y - 16, &machine->screen[0].visarea, TRANSPARENCY_PEN_RAW, 0); - } - - /* compose the three layers */ - { - int xscroll = -jedi_hscroll; - int yscroll = -jedi_vscroll; - copyscrollbitmap(bitmap, bgexbitmap, 1, &xscroll, 1, &yscroll, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); - copybitmap(bitmap, mobitmap, 0, 0, 0, 0, &machine->screen[0].visarea, TRANSPARENCY_BLEND_RAW, 4); - copybitmap(bitmap, fgbitmap, 0, 0, 0, 0, &machine->screen[0].visarea, TRANSPARENCY_BLEND, 8); - } - - /* erase the motion objects */ - for (offs = 0; offs < 0x30; offs++) - { - /* coordinates adjustments made to match screenshot */ - int x = spriteram[offs + 0x100] + ((spriteram[offs + 0x40] & 0x01) << 8) - 2; - int y = 240 - spriteram[offs + 0x80] + 1; - int tall = spriteram[offs + 0x40] & 0x08; - rectangle bounds; - - /* compute the bounds */ - bounds.min_x = x; - bounds.max_x = x + 15; - bounds.min_y = tall ? (y - 16) : y; - bounds.max_y = y + (tall ? 31 : 15); - fillbitmap(mobitmap, 0, &bounds); - } return 0; }