diff --git a/targets/mega65/configdb.c b/targets/mega65/configdb.c index 151be8ef..5ce18db6 100644 --- a/targets/mega65/configdb.c +++ b/targets/mega65/configdb.c @@ -107,6 +107,8 @@ static const struct xemutools_configdef_switch_st switch_options[] = { { "noopl3", "Disables OPL3 emulation", &configdb.noopl3 }, { "lockvideostd", "Lock video standard (programs cannot change it)", &configdb.lock_videostd }, { "curskeyjoy", "Cursor keys as joystick [makes your emulator unsable to move cursor in BASIC/etc!]", &hid_joy_on_cursor_keys }, + { "showscanlines", "Show scanlines in V200 modes", &configdb.show_scanlines }, + { "allowscanlines", "Allow user programs to control scanline visibility", &configdb.allow_scanlines }, { NULL } }; diff --git a/targets/mega65/configdb.h b/targets/mega65/configdb.h index a5ec785e..82493584 100644 --- a/targets/mega65/configdb.h +++ b/targets/mega65/configdb.h @@ -72,6 +72,8 @@ struct configdb_st { char *selectedgui; int lock_videostd; int videostd; + int show_scanlines; + int allow_scanlines; int fullborders; int hdosvirt; int show_drive_led; diff --git a/targets/mega65/ui.c b/targets/mega65/ui.c index 1bd77dd4..198ed5e5 100644 --- a/targets/mega65/ui.c +++ b/targets/mega65/ui.c @@ -644,6 +644,13 @@ static void ui_cb_displayenable ( const struct menu_st *m, int *query ) /**** MENU SYSTEM ****/ +static const struct menu_st menu_show_scanlines[] = { + { "Disallow change by programs",XEMUGUI_MENUID_CALLABLE | XEMUGUI_MENUFLAG_SEPARATOR | + XEMUGUI_MENUFLAG_QUERYBACK, xemugui_cb_toggle_int_inverted, (void*)&configdb.allow_scanlines }, + { "Show scanlines", XEMUGUI_MENUID_CALLABLE | + XEMUGUI_MENUFLAG_QUERYBACK, xemugui_cb_toggle_int, (void*)&configdb.show_scanlines }, + { NULL } +}; static const struct menu_st menu_video_standard[] = { { "Disallow change by programs",XEMUGUI_MENUID_CALLABLE | XEMUGUI_MENUFLAG_SEPARATOR | XEMUGUI_MENUFLAG_QUERYBACK, ui_cb_video_standard_disallow_change, NULL }, @@ -681,6 +688,7 @@ static const struct menu_st menu_display[] = { { "Render scale quality", XEMUGUI_MENUID_SUBMENU, NULL, menu_render_scale_quality }, { "Window size / fullscreen", XEMUGUI_MENUID_SUBMENU, NULL, menu_window_size }, { "Video standard", XEMUGUI_MENUID_SUBMENU, NULL, menu_video_standard }, + { "Show scanlines at V200", XEMUGUI_MENUID_SUBMENU, NULL, menu_show_scanlines }, { "Show full borders", XEMUGUI_MENUID_CALLABLE | XEMUGUI_MENUFLAG_QUERYBACK, ui_cb_fullborders, NULL }, { "Show drive LED", XEMUGUI_MENUID_CALLABLE | diff --git a/targets/mega65/vic4.c b/targets/mega65/vic4.c index cce9baa7..1584fe5e 100644 --- a/targets/mega65/vic4.c +++ b/targets/mega65/vic4.c @@ -722,6 +722,8 @@ void vic_write_reg ( unsigned int addr, Uint8 data ) CASE_VIC_4(0x54): vic_registers[0x54] = data; // we need this work-around, since reg-write happens _after_ this switch statement, but machine_set_speed above needs it ... machine_set_speed(0); + if (configdb.allow_scanlines && !in_hypervisor) // FIXME: this is "do now allow to alter show-scanline setting by hypervisor" + configdb.show_scanlines = !!(data & 32); return; // since we DID the write, it's OK to return here and not using "break" CASE_VIC_4(0x55): CASE_VIC_4(0x56): CASE_VIC_4(0x57): break; CASE_VIC_4(0x58): CASE_VIC_4(0x59): @@ -1555,10 +1557,13 @@ int vic4_render_scanline ( void ) // FIXME: is this really correct? ie even sprites cannot be set to Y pos finer than V200 or ... // ... having resolution finer than V200 with some "VIC-IV magic"? if (!EFFECTIVE_V400 && (ycounter & 1)) { - //for (int i = 0; i < TEXTURE_WIDTH; i++, current_pixel++) - // *current_pixel = /* user_scanlines_setting ? 0 : */ *(current_pixel - TEXTURE_WIDTH); - memcpy(current_pixel, current_pixel - TEXTURE_WIDTH, TEXTURE_WIDTH * 4); - current_pixel += TEXTURE_WIDTH; + if (XEMU_UNLIKELY(configdb.show_scanlines)) { + for (int i = 0; i < TEXTURE_WIDTH; i++, current_pixel++) + *current_pixel = ((*(current_pixel - TEXTURE_WIDTH) >> 1) & 0x7F7F7F7FU) | black_colour; // "| black_colour" is used to correct the messed-up alpha channel to $FF + } else { + memcpy(current_pixel, current_pixel - TEXTURE_WIDTH, TEXTURE_WIDTH * 4); + current_pixel += TEXTURE_WIDTH; + } } else { // Top and bottom borders if (ycounter < BORDER_Y_TOP || ycounter >= BORDER_Y_BOTTOM || !REG_DISPLAYENABLE) {