📄 megasys1.c
字号:
/***************************************************************************
-= Jaleco Mega System 1 =-
driver by Luca Elia (eliavit@unina.it)
Note: if MAME_DEBUG is defined, pressing Z with:
Q shows scroll 1
W shows scroll 2
E shows scroll 3
A shows sprites with attribute 0-3
S shows sprites with attribute 4-7
D shows sprites with attribute 8-b
F shows sprites with attribute c-f
Keys can be used togheter!
********** There are 3 scrolling layers, 2 bytes per tile info:
* Note: MS1-Z has 2 layers only.
A page is 256x256, approximately the visible screen size. Each layer is
made up of 8 pages (8x8 tiles) or 32 pages (16x16 tiles). The number of
horizontal pages and the tiles size is selectable, using the layer's
control register. I think that when tiles are 16x16 a layer can be made
of 16x2, 8x4, 4x8 or 2x16 pages (see below). When tile size is 8x8 we
have two examples to guide the choice:
the copyright screen of p47j (0x12) should be 4x2 (unless it's been hacked :)
the ending sequence of 64th street (0x13) should be 2x4.
I don't see a relation.
MS1-A MS1-B MS1-C
-----------------
Scrolling layers:
90000 50000 e0000 Scroll 1
94000 54000 e8000 Scroll 2
98000 58000 f0000 Scroll 3 * Note: missing on MS1-Z
Tile format: fedc------------ Palette
----ba9876543210 Tile Number
84000 44000 c2208 Layers Enable * Note: missing on MS1-Z?
fedc ---- ---- ---- ? (unused?)
---- ba-- ---- ---- ? (used!)
---- --9- ---- ---- Sprites below fg (sprites over fg on MS1-C?)
---- ---8 ---- ---- Swap txt with fg (swap bg with fg on MS1-C?)
---- ---- 7654 ---- ? (unused?)
---- ---- ---- 3--- Enable Sprites
---- ---- ---- -210 Enable Layer 321
84200 44200 c2000 Scroll 1 Control
84208 44208 c2008 Scroll 2 Control
84008 44008 c2100 Scroll 3 Control * Note: missing on MS1-Z
Offset: 00 Scroll X
02 Scroll Y
04 fedc ba98 765- ---- ? (unused?)
---- ---- ---4 ---- 16x16 Tiles
---- ---- ---- 32-- ? (used, by p47!)
---- ---- ---- --10 N: Layer H pages = 16 / (2^N)
84300 44300 c2308 Screen Control
fedc ba9- ---- ---- ? (unused?)
---- ---8 ---- ---- Portrait F/F (?FullFill?)
---- ---- 765- ---- ? (unused?)
---- ---- ---4 ---- ? (used, see p47j copyright screen!)
---- ---- ---- 321- ? (unused?)
---- ---- ---- ---0 Screen V Flip
********** There are 256*4 colors (256*3 for MS1-Z):
Colors MS1-A/C MS1-Z
000-0ff Scroll 1 Scroll 1
100-1ff Scroll 2 Sprites
200-2ff Scroll 3 Scroll 2
300-3ff Sprites -
88000 48000 f8000 Palette
fedc--------3--- Red
----ba98-----2-- Blue
--------7654--1- Green
---------------0 ? (used, not RGB! [not changed in fades])
********** There are 256 sprites (128 for MS1-Z):
RAM[8000] Sprite Data (16 bytes/entry. 128? entries)
Offset: 0-6 ? (used, but as normal RAM, I think)
08 fed- ---- ---- ---- ?
---c ---- ---- ---- mosaic sol. (?)
---- ba98 ---- ---- mosaic (?)
---- ---- 7--- ---- y flip
---- ---- -6-- ---- x flip
---- ---- --45 ---- ?
---- ---- ---- 3210 color code (* bit 3 = priority *)
0A H position
0C V position
0E fedc ---- ---- ---- ? (used by p47j, 0-8!)
---- ba98 7654 3210 Number
Object RAM tells the hw how to use Sprite Data (missing on MS1-Z).
This makes it possible to group multiple small sprite, up to 256,
into one big virtual sprite (up to a whole screen):
8e000 4e000 d2000 Object RAM (8 bytes/entry. 256*4 entries)
Offset: 00 Index into Sprite Data RAM
02 H Displacement
04 V Displacement
06 Number Displacement
Only one of these four 256 entries is used to see if the sprite is to be
displayed, according to this latter's flipx/y state:
Object RAM entries: Useb by sprites with:
000-0ff No Flip
100-1ff Flip X
200-2ff Flip Y
300-3ff Flip X & Y
No? No? c2108 Sprite Bank
fedc ba98 7654 321- ? (unused?)
---- ---- ---- ---0 Sprite Bank
84100 44100 c2200 Sprite Control
fedc ba9- ---- ---- ? (unused?)
---- ---8 ---- ---- Enable sprite priority effect ? (see p47j sprite test 1!)
---- ---- 765- ---- ? (unused?)
---- ---- ---4 ---- Enable Effect (?)
---- ---- ---- 3210 Effect Number (?)
I think bit 4 enables some sort of color cycling for sprites having priority
bit set. See code of p7j at 6488, affecting the rotating sprites before the
Jaleco logo is shown: values 11-1f, then 0. I fear the Effect Number is an
offset to be applied over the pens used by those sprites. As for bit 8, it's
not used during game, but it is turned on when sprite/foreground priority is
tested, along with Effect Number being 1, so ...
********** Priority (ouch!)
Sprite order is from first in Sprite Data RAM (frontmost) to last.
* Note: the opposite on MS1-Z
Foreground isn't splittable in a "back" part using, say, pens 0-7 and a
"front part" using pens 8-15 usually. Sprites aren't splittable either.
But level A of 64th street has fg that is splittable. I think bit 0 of
the color in paletteram has a role also.
Here's how I draw things (surely incomplete/inaccurate):
MS1-Z/A/B MS1-C
bg Scroll RAM 1 Scroll RAM 2
fg Scroll RAM 2 Scroll RAM 1
txt Scroll RAM 3 Scroll RAM 3
MS1-Z -
MS1-A bit 8 of 84000 is on -> swap fg, txt
MS1-B bit 8 of 44000 is on -> swap fg, txt
MS1-C bit 8 of c2208 is off -> swap bg, fg
bit x is sprite priority enable: bit 8 of 84100 44100 c2200
bit 9 is a foreground priority control: bit 9 of 84000 44000 !c2208
bg
if bit x
if !bit 9 fg
sprites (priority bit 1)
if bit 9 fg
sprites (priority bit 0)
else
if !bit 9 fg
sprites (priority doesn't affect order)
if bit 9 fg
txt (missing on MS1-Z)
***************************************************************************/
#include "vidhrdw/generic.h"
extern unsigned char *scrollram[3],*scrollram_dirty[3];
extern unsigned char *objectram, *videoregs, *ram;
extern int scrollx[3],scrolly[3],scrollflag[3],nx[3],ny[3];
extern int active_layers, spritebank, screenflag, spriteflag,hardware_type;
extern int bg, fg, txt;
extern struct GameDriver avspirit_driver;
struct osd_bitmap *scroll_bitmap[3];
/* these are for debug purposes */
int debugsprites;
void mark_dirty(int n) { memset(scrollram_dirty[n],1,256*256/64*8); }
void mark_dirty_all(void)
{
mark_dirty(0);
mark_dirty(1);
mark_dirty(2);
}
int vh_start(void)
{
int i;
/* allocate a dirty page for each scrolling layer */
for (i = 0; i < 3; i++)
if ((scrollram_dirty[i] = malloc(256*4*256*2/64))==0) return 1;
/* temporary bitmaps are not created here. They are instead
created on the fly when refreshing the screen. */
mark_dirty_all();
return 0;
}
void vh_stop(void)
{
int i;
for (i = 0; i < 3; i++)
{
if (scroll_bitmap[i]) osd_free_bitmap(scroll_bitmap[i]);
if (scrollram_dirty[i]) free(scrollram_dirty[i]);
}
}
/*
Draw sprites in the given bitmap. Priority may be:
0 Draw sprites whose priority bit is 0
1 Draw sprites whose priority bit is 1
-1 Draw sprites regardless of their priority
Sprite Data:
Offset Data
00-07 ?
08 fed- ---- ---- ---- ?
---c ---- ---- ---- mosaic sol. (?)
---- ba98 ---- ---- mosaic (?)
---- ---- 7--- ---- y flip
---- ---- -6-- ---- x flip
---- ---- --45 ---- ?
---- ---- ---- 3210 color code (bit 3 = priority)
0A H position
0C V position
0E Number
*/
static void draw_sprites(struct osd_bitmap *bitmap, int priority)
{
int color,code,sx,sy,attr,xdisp,ydisp,ndisp,sprite,offs;
unsigned char *spritedata, *objectdata;
/* objram: 0x100*4 entries spritedata: 0x80? entries */
/* move the bit to the relevant position (and invert it) */
if (priority != -1) priority = (priority ^ 1) << 3;
/* sprite order is from first in Sprite Data RAM (frontmost) to last */
if (hardware_type != 'Z')
{
for (sprite = 0x80-1; sprite >= 0 ; sprite --)
{
spritedata = &spriteram[sprite*0x10];
attr = READ_WORD(&spritedata[0x08]);
if ( (attr & 0x08) == priority ) continue;
#ifdef MAME_DEBUG
if ( (debugsprites) && (((attr & 0x0f)/4) != (debugsprites-1)) ) continue;
#endif
objectdata = &objectram[((attr & 0xc0) >> 6) * 0x800];
for (offs = 0x000; offs < 0x800 ; offs += 8)
{
/* seek a reference to current sprite */
if ( sprite != READ_WORD(&objectdata[offs+0x00]) ) continue;
/* apply the position displacements */
sx = ( READ_WORD(&spritedata[0x0A]) + READ_WORD(&objectdata[offs+0x02]) ) % 512;
sy = ( READ_WORD(&spritedata[0x0C]) + READ_WORD(&objectdata[offs+0x04]) ) % 512;
if (sx > 256-1) sx -= 512;
if (sy > 256-1) sy -= 512;
/* out of screen */
if ((sx > 256-1) ||(sy > 256-1) ||(sx < 0-15) ||(sy < 0-15)) continue;
code = READ_WORD(&spritedata[0x0E]) + READ_WORD(&objectdata[offs+0x06]);
color = (attr & 0x0F);
drawgfx(bitmap,Machine->gfx[3],
(code & 0xfff ) + (spritebank << 12),
color,
attr & 0x40,attr & 0x80,
sx, sy,
&Machine->drv->visible_area,
TRANSPARENCY_PEN,15);
} /* offs */
} /* sprite */
} /* non Z hw */
else
{
/* MS1-Z just draws Sprite Data, and in reverse order */
for (sprite = 0; sprite < 0x80 ; sprite ++)
{
spritedata = &spriteram[sprite*0x10];
attr = READ_WORD(&spritedata[0x08]);
if ( (attr & 0x08) == priority ) continue;
#ifdef MAME_DEBUG
if ( (debugsprites) && (((attr & 0x0f)/4) == (debugsprites-1)) ) continue;
#endif
sx = READ_WORD(&spritedata[0x0A]) % 512;
sy = READ_WORD(&spritedata[0x0C]) % 512;
if (sx > 256-1) sx -= 512;
if (sy > 256-1) sy -= 512;
/* out of screen */
if ((sx > 256-1) ||(sy > 256-1) ||(sx < 0-15) ||(sy < 0-15)) continue;
code = READ_WORD(&spritedata[0x0E]);
color = (attr & 0x0F);
drawgfx(bitmap,Machine->gfx[2],
code,
color,
attr & 0x40,attr & 0x80,
sx, sy,
&Machine->drv->visible_area,
TRANSPARENCY_PEN,15);
} /* sprite */
} /* Z hw */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -