diff options
| author | 2025-07-24 09:10:29 -0700 | |
|---|---|---|
| committer | 2025-07-24 12:10:29 -0400 | |
| commit | 1f8fb7ec52aa6776cf31533e6d18ef5b15dd93b9 (patch) | |
| tree | 52d070b5984f5d339d742e53934db117b9c78b2b | |
| parent | a44c797462a368392e7ce20b20c5c9a4f9dd9930 (diff) | |
CD-i: Add Undefined Matte Behavior and fix RGB Transparency (#13978)
* CD-i: Add Undefined Matte Behavior
Fixes #13976
Greenbook says not to change the MF flag within a line. However, if you do, the behavior is undefined.
Console verification shows that the real console will use these values. The non-spec behavior is explained in a comment.
Additionally, this tidies up the Matte function.
* CD-i: Fix RGB Transparency
This fixes RGB transparency checks.
Previously it was checking the high bit. This would pass when checking the false condition (mode 10) but not on the true condition (mode 2).
| -rw-r--r-- | src/mame/philips/mcd212.cpp | 73 |
1 files changed, 20 insertions, 53 deletions
diff --git a/src/mame/philips/mcd212.cpp b/src/mame/philips/mcd212.cpp index b1e65211854..24e24628dbd 100644 --- a/src/mame/philips/mcd212.cpp +++ b/src/mame/philips/mcd212.cpp @@ -54,17 +54,14 @@ inline ATTR_FORCE_INLINE uint8_t mcd212_device::get_matte_op(const uint32_t matt void mcd212_device::update_matte_arrays() { - bool latched_mf[2]{ false, false }; - uint8_t latched_wfa = m_weight_factor[0][0]; - uint8_t latched_wfb = m_weight_factor[1][0]; const int width = get_screen_width(); - const int num_mattes = BIT(m_image_coding_method, ICM_NM_BIT) ? 2 : 1; - const bool matte_flag = BIT(m_matte_control[0], MC_MF_BIT); // MF bit must be the same. See 5.10.2 Matte Commands + bool latched_mf[2]{ false, false }; + uint8_t latched_wf[2] = { m_weight_factor[0][0], m_weight_factor[1][0] }; int matte_idx[2] = { 0, 4 }; - int x = 0; - for (; x < width; x++) + + for (int x = 0; x < width; x++) { for (int matte = 0; matte < num_mattes; matte++) { @@ -74,69 +71,39 @@ void mcd212_device::update_matte_arrays() continue; } const uint32_t matte_ctrl = m_matte_control[matte_idx[matte]]; - const uint32_t matte_op = get_matte_op(matte_idx[matte]); - const int flag = (num_mattes == 2) ? matte : matte_flag; if (x == (matte_ctrl & MC_X)) { + const uint32_t matte_op = get_matte_op(matte_idx[matte]); + const int flag = (num_mattes == 2) ? matte : BIT(m_matte_control[matte_idx[matte]], MC_MF_BIT); + // See 5.10.2 Matte Commands. Changing the MF-bit inside a line is undefined. Greenbook says don't do it. + // Console validation shows the 220 reads and uses this value anyway. switch (matte_op) { case 0: // Disregard all commands in higher registers. See 5.10.2 - matte_idx[matte] = max_matte_id; - break; - case 1: - case 2: - case 3: // Not used - break; - case 4: // Change weight of plane A - latched_wfa = get_weight_factor(matte_idx[matte]); - break; - case 5: // Not used - break; - case 6: // Change weight of plane B - latched_wfb = get_weight_factor(matte_idx[matte]); - break; - case 7: // Not used - break; - case 8: // Reset matte flag - latched_mf[flag] = false; - break; - case 9: // Set matte flag - latched_mf[flag] = true; - break; - case 10: // Not used - case 11: // Not used + matte_idx[matte] = 8; break; - case 12: // Reset matte flag and change weight of plane A - latched_wfa = get_weight_factor(matte_idx[matte]); - latched_mf[flag] = false; + case 1: case 2: case 3: case 5: case 7: case 10: case 11: // Not used break; - case 13: // Set matte flag and change weight of plane A - latched_wfa = get_weight_factor(matte_idx[matte]); - latched_mf[flag] = true; + case 4: case 6: // Change weight of plane (A or B) + latched_wf[BIT(matte_op, 1)] = get_weight_factor(matte_idx[matte]); break; - case 14: // Reset matte flag and change weight of plane B - latched_wfb = get_weight_factor(matte_idx[matte]); - latched_mf[flag] = false; + case 8: case 9: // (Reset or Set) matte flag + latched_mf[flag] = BIT(matte_op, 0); break; - case 15: // Set matte flag and change weight of plane B - latched_wfb = get_weight_factor(matte_idx[matte]); - latched_mf[flag] = true; + case 12: case 13: case 14: case 15: // Change weight of plane (A or B) and (Reset or Set) matte flag + latched_wf[BIT(matte_op, 1)] = get_weight_factor(matte_idx[matte]); + latched_mf[flag] = BIT(matte_op, 0); break; } matte_idx[matte]++; } } - m_weight_factor[0][x] = latched_wfa; - m_weight_factor[1][x] = latched_wfb; + m_weight_factor[0][x] = latched_wf[0]; + m_weight_factor[1][x] = latched_wf[1]; m_matte_flag[0][x] = latched_mf[0]; m_matte_flag[1][x] = latched_mf[1]; } - // Fill the remainder. - std::fill_n(m_weight_factor[0] + x, std::size(m_weight_factor[0]) - x, latched_wfa); - std::fill_n(m_weight_factor[1] + x, std::size(m_weight_factor[1]) - x, latched_wfb); - std::fill_n(m_matte_flag[0] + x, std::size(m_matte_flag[0]) - x, latched_mf[0]); - std::fill_n(m_matte_flag[1] + x, std::size(m_matte_flag[1]) - x, latched_mf[1]); } template <int Path> @@ -628,7 +595,7 @@ void mcd212_device::process_vsr(uint32_t *pixels, bool *transparent) const uint8_t blue = (byte & 0b11111) << 3; const uint8_t green = ((byte & 0b11100000) >> 2) + ((byte1 & 0b11) << 6); const uint8_t red = (byte1 & 0b01111100) << 1; - rgb_tp_bit = (use_rgb_tp_bit && ((byte1 & 0x80) == tp_check_parity)); + rgb_tp_bit = (use_rgb_tp_bit && (BIT(byte1,7) == tp_check_parity)); color1 = color0 = (uint32_t(red) << 16) | (uint32_t(green) << 8) | blue; } else if (icm == ICM_CLUT4) |
