summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/radicasi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/radicasi.cpp')
-rw-r--r--src/mame/drivers/radicasi.cpp221
1 files changed, 160 insertions, 61 deletions
diff --git a/src/mame/drivers/radicasi.cpp b/src/mame/drivers/radicasi.cpp
index b8a83f4953a..5bb34123398 100644
--- a/src/mame/drivers/radicasi.cpp
+++ b/src/mame/drivers/radicasi.cpp
@@ -128,6 +128,7 @@
Flaws (NOT emulation bugs, happen on hardware):
+ --
In QIX the sprites lag behind the line drawing, so you see the line infront of your player until you stop moving
@@ -137,6 +138,19 @@
Colony 7 has a typo in the instructions
+ The fake 'colour band' effect does not apply to the thruster (and several other elements) in Lunar Rescue
+
+ Enemies in Phoenix are rendered above the score panel
+
+ The 200pt right facing bird on the Phoenix score table is corrupt
+
+ Uncertain (to check)
+
+ Space Invaders seems to be using a darker than expected palette, there are lighter colours in the palette but
+ they don't seem to be used. It's difficult to judge from hardware videos, although it definitely isn't as
+ white as the menu, so this might also be a non-bug.
+
+
*/
#include "emu.h"
@@ -306,6 +320,8 @@ private:
void handle_sound_1_w(int which, int offset, uint8_t data);
uint8_t handle_sound_1_r(int which, int offset);
+ bool get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2);
+ void draw_tilemaps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int drawpri);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
};
@@ -325,14 +341,15 @@ void radica_6502_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap
/*
Sprites
- AA yy xx ?? XX YY aa bb
+ AA yy xx cc XX YY aa bb
yy = y position
xx = x position
XX = texture x start
YY = texture y start
- aa = same as final param on tiles?
+ aa = same as unk2 on tiles
bb = sometimes set in invaders
+ cc = same as attr on tiles (colour / priority?)
AA = attributes
e--- fFsS
@@ -349,23 +366,60 @@ void radica_6502_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap
uint8_t x = m_spriteram[i + 2];
uint8_t y = m_spriteram[i + 1];
+ /*
+ Space Invaders draws the player base with this specific y value before the start of each life
+ and expects it to NOT wrap around. There are no high priority tiles or anything else to hide
+ and it doesn't appear on real hardware.
+
+ it's possible sprites don't wrap around at all (but then you couldn't have smooth entry at the
+ top of the screen - there are no extra y co-ordinate bits. However there would have been easier
+ ways to hide this tho as there are a bunch of unseen lines at the bottom of the screen anyway!
+
+ needs further investigation.
+ */
+ if (y==255)
+ continue;
+
uint8_t tex_x = m_spriteram[i + 4];
uint8_t tex_y = m_spriteram[i + 5];
- uint8_t attrs = m_spriteram[i + 0];
+ uint8_t flags = m_spriteram[i + 0];
+ uint8_t attr = m_spriteram[i + 3];
+ uint8_t unk2 = m_spriteram[i + 6];
+
+
+ //int priority = attr & 0x0f;
+ int colour = attr & 0xf0;
+
+ // ? game select has this set to 0xff, but clearly doesn't want the palette to change!
+ // while in Space Invaders this has to be palette for the UFO to be red.
+ if (colour & 0x80)
+ colour = 0;
- if (!(attrs & 0x80))
+ int transpen = 0;
+
+ /* HACK - how is this calculated
+ phoenix and the game select need it like this
+ it isn't a simple case of unk2 being transpen either because Qix has some elements set to 0x07
+ where the transpen needs to be 0x00 and Space Invaders has it set to 0x04
+ it could be a global register rather than something in the spritelist?
+ */
+ if ((attr == 0xff) && (unk2 == 0xff))
+ transpen = 0xff;
+
+
+ if (!(flags & 0x80))
continue;
int sizex = 8;
int sizey = 8;
- if (attrs & 0x01)
+ if (flags & 0x01)
{
sizex = 16;
}
- if (attrs & 0x02)
+ if (flags & 0x02)
{
sizey = 16;
}
@@ -375,8 +429,8 @@ void radica_6502_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap
for (int yy = 0; yy < sizey; yy++)
{
uint16_t* row;
-
- if (attrs & 0x08) // guess flipy
+
+ if (flags & 0x08) // guess flipy
{
row = &bitmap.pix16((y + (sizey - 1 - yy)) & 0xff);
}
@@ -387,20 +441,20 @@ void radica_6502_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap
for (int xx = 0; xx < sizex; xx++)
{
- int realaddr = base + ((tex_x+xx)&0xff);
- realaddr += ((tex_y+yy)&0xff) * 256;
+ int realaddr = base + ((tex_x + xx) & 0xff);
+ realaddr += ((tex_y + yy) & 0xff) * 256;
uint8_t pix = fullbankspace.read_byte(realaddr);
- if (pix)
+ if (pix != transpen)
{
- if (attrs & 0x04) // flipx
+ if (flags & 0x04) // flipx
{
- row[(x + (sizex - 1 - xx)) & 0xff] = pix;// + attr;
+ row[(x + (sizex - 1 - xx)) & 0xff] = (pix + ((colour & 0x70) << 1)) & 0xff;
}
else
{
- row[(x + xx) & 0xff] = pix;// + attr;
+ row[(x + xx) & 0xff] = (pix + ((colour & 0x70) << 1)) & 0xff;
}
}
}
@@ -418,46 +472,36 @@ double hue2rgb(double p, double q, double t)
return p;
}
-uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+// a hacky mess for now
+bool radica_6502_state::get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2)
{
- bitmap.fill(0, cliprect);
-
- // Palette
- int offs = 0;
- for (int index = 0;index < 256; index++)
- {
- uint16_t dat = m_palram[offs++] << 8;
- dat |= m_palram[offs++];
-
- // llll lsss ---h hhhh
- int l_raw = (dat & 0xf800) >> 11;
- int sl_raw = (dat & 0x0700) >> 8;
- int h_raw = (dat & 0x001f) >> 0;
-
- double l = (double)l_raw / 31.0f;
- double s = (double)sl_raw / 7.0f;
- double h = (double)h_raw / 24.0f;
-
- double r, g, b;
+ tile = m_vram[base * 4] + (m_vram[(base * 4) + 1] << 8);
+
+ // these seem to be the basically the same as attr/unk2 in the sprites, which also make
+ // very little sense.
+ attr = m_vram[(base * 4) + 2];
+ unk2 = m_vram[(base * 4) + 3];
- if (s == 0) {
- r = g = b = l; // greyscale
- } else {
- double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
- double p = 2 * l - q;
- r = hue2rgb(p, q, h + 1/3.0f);
- g = hue2rgb(p, q, h);
- b = hue2rgb(p, q, h - 1/3.0f);
- }
+ /* hack for phoenix title screens.. the have attr set to 0x3f which change the colour bank in ways we don't want
+ and also by our interpretation of 0x0f bits sets the tiles to priority over sprites (although in this case
+ that might tbe ok, because it looks like the sprites also have that set */
+ if (unk2 == 0x07)
+ attr = 0;
- int r_real = r * 255.0f;
- int g_real = g * 255.0f;
- int b_real = b * 255.0f;
+ int priority = attr & 0x0f;
- m_palette->set_pen_color(index, r_real, g_real, b_real);
- }
+ // likely wrong
+ if ((drawpri == 0 && priority == 0x0f) || (drawpri == 1 && priority != 0x0f))
+ return false;
- // Tilemaps
+ return true;
+}
+void radica_6502_state::draw_tilemaps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int drawpri)
+{
+ /* this doesn't handle 8x8 4bpp, haven't seen it used
+ nor is there support for horizontal scrolling etc.
+ for the same reasons
+ */
int scroll = (m_bg_scroll[1] << 8) | m_bg_scroll[0];
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
@@ -475,10 +519,15 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
if (realstartrow >= 28)
realstartrow -= 28;
- int base = (((realstartrow + y)&0x1f)*8)+x;
- int tile = m_vram[base * 4] + (m_vram[(base * 4)+1] << 8);
- int attr = m_vram[(base * 4)+ 2];
+ int base = (((realstartrow + y) & 0x1f) * 8) + x;
+
+ int tile,attr,unk2;
+
+ if (!get_tile_data(base, drawpri, tile,attr,unk2))
+ continue;
+ int colour = attr & 0xf0;
+
if (m_5027_data & 0x20) // 4bpp mode
{
tile = (tile & 0xf) + ((tile & ~0xf) * 16);
@@ -507,8 +556,8 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
{
int realaddr = ((tile + i * 16) << 3) + (xx >> 1);
uint8_t pix = fullbankspace.read_byte(realaddr);
- row[x * 16 + xx + 0] = ((pix & 0xf0) >> 4) + attr;
- row[x * 16 + xx + 1] = ((pix & 0x0f) >> 0) + attr;
+ row[x * 16 + xx + 0] = ((pix & 0xf0) >> 4) + colour;
+ row[x * 16 + xx + 1] = ((pix & 0x0f) >> 0) + colour;
}
}
else // 8bpp
@@ -517,7 +566,7 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
{
int realaddr = ((tile + i * 32) << 3) + xx;
uint8_t pix = fullbankspace.read_byte(realaddr);
- row[x * 16 + xx] = pix;// + attr;
+ row[x * 16 + xx] = (pix + ((colour & 0x70) << 1)) & 0xff;
}
}
@@ -541,9 +590,14 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
if (realstartrow >= 56)
realstartrow -= 56;
- int base = (((realstartrow)&0x3f)*32)+x;
- int tile = m_vram[base * 4] + (m_vram[(base * 4)+1] << 8);
- //int attr = m_vram[(base * 4)+ 2];
+ int base = (((realstartrow) & 0x3f) * 32) + x;
+
+ int tile,attr,unk2;
+
+ if (!get_tile_data(base, drawpri, tile,attr,unk2))
+ continue;
+
+ int colour = attr & 0xf0;
tile = (tile & 0x1f) + ((tile & ~0x1f) * 8);
tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
@@ -552,7 +606,7 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
{
int drawline = (y * 8) + i;
drawline -= scroll & 0x7;
-
+
if ((drawline >= 0) && (drawline < 256))
{
uint16_t* row = &bitmap.pix16(drawline);
@@ -561,15 +615,60 @@ uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &b
{
int realaddr = ((tile + i * 32) << 3) + xx;
uint8_t pix = fullbankspace.read_byte(realaddr);
- row[x * 8 + xx] = pix;// + attr;
+ row[x * 8 + xx] = (pix + ((colour & 0x70) << 1)) & 0xff;
}
}
}
}
}
}
+}
+
+
+
+uint32_t radica_6502_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(0, cliprect);
+
+ // Palette
+ int offs = 0;
+ for (int index = 0;index < 256; index++)
+ {
+ uint16_t dat = m_palram[offs++] << 8;
+ dat |= m_palram[offs++];
+
+ // llll lsss ---h hhhh
+ int l_raw = (dat & 0xf800) >> 11;
+ int sl_raw = (dat & 0x0700) >> 8;
+ int h_raw = (dat & 0x001f) >> 0;
+
+ double l = (double)l_raw / 31.0f;
+ double s = (double)sl_raw / 7.0f;
+ double h = (double)h_raw / 24.0f;
+
+ double r, g, b;
+
+ if (s == 0) {
+ r = g = b = l; // greyscale
+ } else {
+ double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
+ double p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3.0f);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1/3.0f);
+ }
+
+ int r_real = r * 255.0f;
+ int g_real = g * 255.0f;
+ int b_real = b * 255.0f;
+
+ m_palette->set_pen_color(index, r_real, g_real, b_real);
+ }
+
+ draw_tilemaps(screen,bitmap,cliprect,0);
draw_sprites(screen,bitmap,cliprect);
+ draw_tilemaps(screen,bitmap,cliprect,1);
return 0;
}
@@ -1327,7 +1426,7 @@ static MACHINE_CONFIG_START( radicasi )
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
MCFG_SCREEN_PALETTE("palette")
- MCFG_PALETTE_ADD("palette", 1024)
+ MCFG_PALETTE_ADD("palette", 256)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", radicasi_fake)