Skip to content

Commit df793d3

Browse files
CD-i: Add Interlace Graphics (#13997)
* CD-i: Doubles Vertical Resolution Minimal code to double the vertical resolution for #13231 . The result is a slightly crisper looking image on most monitors due to better upscaling on images are have less oblique pixels. This was tested minimally and seems stable. Something closer to a proper interlaced image can be accomplished using the _PA bit, however current screen blanks between frames preventing the parity bit from being able to produce a correct interlace image yet. * CD-i: Remove excess vertical resolution * Use 2x clock multiplier * CD-i: Add Interlaced Graphics Fixes #13231 * CD-i: Toggle Interlace Effect When the interlace bit is off, line-duplication is re-enabled. This ensures the interlace effect is only visible when the game declares the output to be interlaced. * CD-i: Fix interlaced line offset In some cases, such as during startup, the line length of the interlaced line is impacted. This corrects the offset. * CD-i: Fix Interlace Clock Speed
1 parent f3a665c commit df793d3

File tree

3 files changed

+38
-14
lines changed

3 files changed

+38
-14
lines changed

src/mame/philips/cdi.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ void cdi_state::cdimono1_base(machine_config &config)
434434
m_mcd212->int_callback().set(m_maincpu, FUNC(scc68070_device::int1_w));
435435

436436
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
437-
screen.set_raw(14976000, 960, 0, 768, 312, 32, 312);
437+
screen.set_raw(960*(312*2-32)*50, 960, 0, 768, 312*2-32, 32, 312*2-32);
438438
screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
439439
screen.set_screen_update(m_mcd212, FUNC(mcd212_device::screen_update));
440440

src/mame/philips/mcd212.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
CD-i MCD212 Video Decoder and System Controller emulation
77
-------------------
88
9-
written by Ryan Holtz
9+
written by Ryan Holtz, Vincent.Halver
1010
1111
1212
*******************************************************************************
@@ -330,13 +330,13 @@ template <int Path>
330330
void mcd212_device::process_ica()
331331
{
332332
uint16_t *ica = Path ? m_planeb.target() : m_planea.target();
333-
uint32_t addr = 0x200;
334-
uint32_t cmd = 0;
335-
336333
const int max_to_process = m_ica_height * 120;
334+
// LCT depends on the current frame parity
335+
uint32_t addr = (BIT(m_csrr[0], CSR1R_PA_BIT) == 0) ? 0x200 : 0x202;
336+
337337
for (int i = 0; i < max_to_process; i++)
338338
{
339-
cmd = ica[addr++] << 16;
339+
uint32_t cmd = ica[addr++] << 16;
340340
cmd |= ica[addr++];
341341
switch ((cmd & 0xff000000) >> 24)
342342
{
@@ -666,6 +666,11 @@ void mcd212_device::mix_lines(uint32_t *plane_a, bool *transparent_a, uint32_t *
666666
if (icmB == ICM_CLUT4)
667667
mosaic_count_b >>= 1;
668668

669+
// If PAL and 'Standard' bit set, insert a 24px border on the left/right
670+
uint32_t offset = (!BIT(m_dcr[0], DCR_CF_BIT) || BIT(m_csrw[0], CSR1W_ST_BIT)) ? 24 : 0;
671+
std::fill_n(out, offset, s_4bpp_color[0]);
672+
out += offset;
673+
669674
for (int x = 0; x < width; x++)
670675
{
671676
if (transparent_a[x] && transparent_b[x])
@@ -963,12 +968,19 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
963968
bool transparent_a[768];
964969
bool transparent_b[768];
965970

966-
int scanline = screen.vpos();
971+
if (screen.vpos() >= m_total_height)
972+
{
973+
return 0; // Do nothing on the extended rows.
974+
}
967975

976+
int scanline = screen.vpos();
977+
968978
// Process VSR and mix if we're in the visible region
969979
if (scanline >= m_ica_height)
970980
{
971-
uint32_t *out = &bitmap.pix(scanline);
981+
uint32_t bitmap_line = ((scanline - m_ica_height) << 1) + m_ica_height;
982+
uint32_t *out = &bitmap.pix(bitmap_line + (!BIT(m_csrr[0], CSR1R_PA_BIT)));
983+
uint32_t* out2 = &bitmap.pix(bitmap_line + (BIT(m_csrr[0], CSR1R_PA_BIT)));
972984

973985
bool draw_line = true;
974986
if (!BIT(m_dcr[0], DCR_FD_BIT) && BIT(m_csrw[0], CSR1W_ST_BIT))
@@ -985,12 +997,6 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
985997

986998
if (draw_line)
987999
{
988-
// If PAL and 'Standard' bit set, insert a 24px border on the left/right
989-
if (!BIT(m_dcr[0], DCR_CF_BIT) || BIT(m_csrw[0], CSR1W_ST_BIT))
990-
{
991-
std::fill_n(out, 24, s_4bpp_color[0]);
992-
out += 24;
993-
}
9941000

9951001
process_vsr<0>(plane_a, transparent_a);
9961002
process_vsr<1>(plane_b, transparent_b);
@@ -1028,6 +1034,16 @@ uint32_t mcd212_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
10281034

10291035
draw_cursor(out);
10301036
}
1037+
1038+
if (BIT(m_dcr[0], DCR_SM_BIT)) {
1039+
// Interlace Output
1040+
memcpy(out2, m_interlace_field[scanline], 768 * sizeof(uint32_t));
1041+
memcpy(m_interlace_field[scanline], out, 768 * sizeof(uint32_t));
1042+
}
1043+
else {
1044+
// Single Field Output (duplicate lines)
1045+
memcpy(out2, out, 768 * sizeof(uint32_t));
1046+
}
10311047
}
10321048

10331049
// Toggle frame parity at the end of the visible frame (even in non-interlaced mode).
@@ -1118,6 +1134,9 @@ void mcd212_device::device_reset()
11181134
m_ica_height = 32;
11191135
m_total_height = 312;
11201136
m_blink_time = 0;
1137+
for (int i = 0; i < 312; i++) {
1138+
std::fill_n(m_interlace_field[i], 768, 0);
1139+
}
11211140

11221141
m_int_callback(CLEAR_LINE);
11231142

@@ -1197,6 +1216,8 @@ void mcd212_device::device_start()
11971216
save_item(NAME(m_blink_time));
11981217
save_item(NAME(m_blink_active));
11991218

1219+
save_item(NAME(m_interlace_field));
1220+
12001221
m_dca_timer = timer_alloc(FUNC(mcd212_device::dca_tick), this);
12011222
m_dca_timer->adjust(attotime::never);
12021223

src/mame/philips/mcd212.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ class mcd212_device : public device_t,
139139
MC_OP_SHIFT = 20,
140140

141141
CSR1R_PA = 0x20, // Parity
142+
CSR1R_PA_BIT = 5,
142143
CSR1R_DA = 0x80, // Display Active
143144

144145
CSR1W_BE = 0x0001, // Bus Error
@@ -231,6 +232,8 @@ class mcd212_device : public device_t,
231232
required_shared_ptr<uint16_t> m_planea;
232233
required_shared_ptr<uint16_t> m_planeb;
233234

235+
uint32_t m_interlace_field[312][768];
236+
234237
// internal state
235238
bool m_matte_flag[2][768]{};
236239
int m_ica_height = 0;

0 commit comments

Comments
 (0)