- 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
This commit is contained in:
Zsolt Vasvari 2008-01-26 13:58:31 +00:00
parent f3f249af3f
commit e3df2f0f54
3 changed files with 251 additions and 258 deletions

View File

@ -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 )

View File

@ -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 );

View File

@ -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;
}