diff options
author | 2018-01-16 21:11:20 +0000 | |
---|---|---|
committer | 2018-01-16 16:11:20 -0500 | |
commit | c97f56c83f7a550a9893bcd14270de8beed182a0 (patch) | |
tree | b61939a079fdd5ff942de5b6fdde21110e642e74 | |
parent | 0f59e5b7205f479618da373c1723b4663c498a6c (diff) |
Radica 6502: some hacks to improve the video, (#3074)
* Radica 6502: some hacks to improve the video, lack of test cases / makes these tricky to figure out properly
* at least these aren't *my* bugs.. (nw)
-rw-r--r-- | src/mame/drivers/radicasi.cpp | 221 |
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) |