diff --git a/gx/config.c b/gx/config.c index d13b15b..760b9db 100644 --- a/gx/config.c +++ b/gx/config.c @@ -3,7 +3,7 @@ * * Genesis Plus GX configuration file support * - * Copyright Eke-Eke (2007-2013) + * Copyright Eke-Eke (2007-2014) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -164,6 +164,13 @@ void config_default(void) config.gamma = VI_GM_1_0 / 10.0; #endif + /* NTSC filter options */ + config.ntsc_sharpness = 0.0; + config.ntsc_resolution = 0.0; + config.ntsc_artifacts = 0.0; + config.ntsc_fringing = 0.0; + config.ntsc_bleed = 0.0; + /* controllers options */ config.gun_cursor[0] = 1; config.gun_cursor[1] = 1; diff --git a/gx/config.h b/gx/config.h index 59b773e..6ced1b5 100644 --- a/gx/config.h +++ b/gx/config.h @@ -3,7 +3,7 @@ * * Genesis Plus GX configuration file support * - * Copyright Eke-Eke (2007-2013) + * Copyright Eke-Eke (2007-2014) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -111,6 +111,11 @@ typedef struct float bgm_volume; float sfx_volume; char lastdir[FILETYPE_MAX][TYPE_RECENT][MAXPATHLEN]; + float ntsc_sharpness; + float ntsc_resolution; + float ntsc_artifacts; + float ntsc_fringing; + float ntsc_bleed; } t_config; /* Global data */ diff --git a/gx/gui/menu.c b/gx/gui/menu.c index afb0415..3442dd4 100644 --- a/gx/gui/menu.c +++ b/gx/gui/menu.c @@ -370,9 +370,9 @@ static gui_item items_system[10] = /* Video options */ #ifdef HW_RVL -static gui_item items_video[13] = +static gui_item items_video[18] = #else -static gui_item items_video[11] = +static gui_item items_video[16] = #endif { {NULL,NULL,"Display: PROGRESSIVE", "Select video mode", 56,132,276,48}, @@ -385,6 +385,11 @@ static gui_item items_video[11] = {NULL,NULL,"VI Gamma Correction: 1.0", "Adjust video hardware gamma correction", 56,132,276,48}, #endif {NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/disable NTSC software filtering", 56,132,276,48}, + {NULL,NULL,"NTSC Sharpness: 0.0", "Adjust edge contrast enhancement/blurring", 56,132,276,48}, + {NULL,NULL,"NTSC Resolution: 0.0", "Adjust image resolution", 56,132,276,48}, + {NULL,NULL,"NTSC Artifacts: 0.0", "Adjust artifacts caused by color changes", 56,132,276,48}, + {NULL,NULL,"NTSC Color Bleed: 0.0", "Adjust color resolution reduction", 56,132,276,48}, + {NULL,NULL,"NTSC Color Fringing: 0.0", "Adjust artifacts caused by brightness changes", 56,132,276,48}, {NULL,NULL,"Borders: OFF", "Enable/disable overscan emulation", 56,132,276,48}, {NULL,NULL,"GG screen: ORIGINAL", "Enable/disable Game Gear extended screen", 56,132,276,48}, {NULL,NULL,"Aspect: ORIGINAL (4:3)", "Select display aspect ratio", 56,132,276,48}, @@ -1480,6 +1485,7 @@ static void videomenu () int reinit = 0; gui_menu *m = &menu_video; gui_item *items = m->items; + int ntsc_offset = 0; if (config.render == 1) sprintf (items[0].text,"Display: INTERLACED"); @@ -1514,39 +1520,60 @@ static void videomenu () sprintf (items[VI_OFFSET].text, "NTSC Filter: S-VIDEO"); else if (config.ntsc == 3) sprintf (items[VI_OFFSET].text, "NTSC Filter: RGB"); + else if (config.ntsc == 4) + { + sprintf (items[VI_OFFSET].text, "NTSC Filter: MANUAL"); + sprintf(items[VI_OFFSET+1].text, "NTSC Sharpness: %1.2f", config.ntsc_sharpness); + sprintf(items[VI_OFFSET+2].text, "NTSC Resolution: %1.2f", config.ntsc_resolution); + sprintf(items[VI_OFFSET+3].text, "NTSC Artifacts: %1.2f", config.ntsc_artifacts); + sprintf(items[VI_OFFSET+4].text, "NTSC Color Bleed: %1.2f", config.ntsc_bleed); + sprintf(items[VI_OFFSET+5].text, "NTSC Color Fringing: %1.2f", config.ntsc_fringing); + strcpy(items[VI_OFFSET+1].comment, "Adjust edge contrast enhancement/blurring"); + strcpy(items[VI_OFFSET+2].comment, "Adjust image resolution"); + strcpy(items[VI_OFFSET+3].comment, "Adjust artifacts caused by color changes"); + strcpy(items[VI_OFFSET+4].comment, "Adjust color resolution reduction"); + strcpy(items[VI_OFFSET+5].comment, "Adjust artifacts caused by brightness changes"); + ntsc_offset = 5; + } else sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF"); - if (config.overscan == 3) - sprintf (items[VI_OFFSET+1].text, "Borders: FULL"); - else if (config.overscan == 2) - sprintf (items[VI_OFFSET+1].text, "Borders: H ONLY"); - else if (config.overscan == 1) - sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY"); - else - sprintf (items[VI_OFFSET+1].text, "Borders: NONE"); + strcpy(items[VI_OFFSET+1+ntsc_offset].comment, "Enable/disable overscan emulation"); + strcpy(items[VI_OFFSET+2+ntsc_offset].comment, "Enable/disable Game Gear extended screen"); + strcpy(items[VI_OFFSET+3+ntsc_offset].comment, "Select display aspect ratio"); + strcpy(items[VI_OFFSET+4+ntsc_offset].comment, "Adjust display position"); + strcpy(items[VI_OFFSET+5+ntsc_offset].comment, "Adjust display scaling"); - sprintf(items[VI_OFFSET+2].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL"); + if (config.overscan == 3) + sprintf (items[VI_OFFSET+1+ntsc_offset].text, "Borders: FULL"); + else if (config.overscan == 2) + sprintf (items[VI_OFFSET+1+ntsc_offset].text, "Borders: H ONLY"); + else if (config.overscan == 1) + sprintf (items[VI_OFFSET+1+ntsc_offset].text, "Borders: V ONLY"); + else + sprintf (items[VI_OFFSET+1+ntsc_offset].text, "Borders: NONE"); + + sprintf(items[VI_OFFSET+2+ntsc_offset].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL"); if (config.aspect == 1) - sprintf (items[VI_OFFSET+3].text,"Aspect: ORIGINAL (4:3)"); + sprintf (items[VI_OFFSET+3+ntsc_offset].text,"Aspect: ORIGINAL (4:3)"); else if (config.aspect == 2) - sprintf (items[VI_OFFSET+3].text, "Aspect: ORIGINAL (16:9)"); + sprintf (items[VI_OFFSET+3+ntsc_offset].text, "Aspect: ORIGINAL (16:9)"); else - sprintf (items[VI_OFFSET+3].text, "Aspect: SCALED"); + { + sprintf (items[VI_OFFSET+3+ntsc_offset].text, "Aspect: SCALED"); + m->max_items++; + } - sprintf (items[VI_OFFSET+4].text, "Screen Position: (%s%02d,%s%02d)", + sprintf (items[VI_OFFSET+4+ntsc_offset].text, "Screen Position: (%s%02d,%s%02d)", (config.xshift < 0) ? "":"+", config.xshift, (config.yshift < 0) ? "":"+", config.yshift); - sprintf (items[VI_OFFSET+5].text, "Screen Scaling: (%s%02d,%s%02d)", + sprintf (items[VI_OFFSET+5+ntsc_offset].text, "Screen Scaling: (%s%02d,%s%02d)", (config.xscale < 0) ? "":"+", config.xscale, (config.yscale < 0) ? "":"+", config.yscale); - if (config.aspect) - m->max_items = VI_OFFSET+5; - else - m->max_items = VI_OFFSET+6; + m->max_items = VI_OFFSET + 5 + ntsc_offset + (config.aspect == 0); GUI_InitMenu(m); GUI_SlideMenuTitle(m,strlen("Video ")); @@ -1555,6 +1582,11 @@ static void videomenu () { ret = GUI_RunMenu(m); + if (ret > VI_OFFSET) + { + ret += (5 - ntsc_offset); + } + switch (ret) { case 0: /*** rendering ***/ @@ -1643,64 +1675,135 @@ static void videomenu () #endif case VI_OFFSET: /*** NTSC filter ***/ - config.ntsc = (config.ntsc + 1) & 3; + config.ntsc = (config.ntsc + 1) % 5; if (config.ntsc == 1) + { sprintf (items[VI_OFFSET].text, "NTSC Filter: COMPOSITE"); + } else if (config.ntsc == 2) + { sprintf (items[VI_OFFSET].text, "NTSC Filter: S-VIDEO"); + } else if (config.ntsc == 3) + { sprintf (items[VI_OFFSET].text, "NTSC Filter: RGB"); + } + else if (config.ntsc == 4) + { + sprintf (items[VI_OFFSET].text, "NTSC Filter: MANUAL"); + strcpy(items[VI_OFFSET+5+1].text, items[VI_OFFSET+1].text); + strcpy(items[VI_OFFSET+5+2].text, items[VI_OFFSET+2].text); + strcpy(items[VI_OFFSET+5+3].text, items[VI_OFFSET+3].text); + strcpy(items[VI_OFFSET+5+4].text, items[VI_OFFSET+4].text); + strcpy(items[VI_OFFSET+5+5].text, items[VI_OFFSET+5].text); + strcpy(items[VI_OFFSET+5+1].comment, items[VI_OFFSET+1].comment); + strcpy(items[VI_OFFSET+5+2].comment, items[VI_OFFSET+2].comment); + strcpy(items[VI_OFFSET+5+3].comment, items[VI_OFFSET+3].comment); + strcpy(items[VI_OFFSET+5+4].comment, items[VI_OFFSET+4].comment); + strcpy(items[VI_OFFSET+5+5].comment, items[VI_OFFSET+5].comment); + sprintf(items[VI_OFFSET+1].text, "NTSC Sharpness: %1.1f", config.ntsc_sharpness); + sprintf(items[VI_OFFSET+2].text, "NTSC Resolution: %1.1f", config.ntsc_resolution); + sprintf(items[VI_OFFSET+3].text, "NTSC Artifacts: %1.1f", config.ntsc_artifacts); + sprintf(items[VI_OFFSET+4].text, "NTSC Color Bleed: %1.1f", config.ntsc_bleed); + sprintf(items[VI_OFFSET+5].text, "NTSC Color Fringing: %1.1f", config.ntsc_fringing); + strcpy(items[VI_OFFSET+1].comment, "Adjust edge contrast enhancement/blurring"); + strcpy(items[VI_OFFSET+2].comment, "Adjust image resolution"); + strcpy(items[VI_OFFSET+3].comment, "Adjust artifacts caused by color changes"); + strcpy(items[VI_OFFSET+4].comment, "Adjust color resolution reduction"); + strcpy(items[VI_OFFSET+5].comment, "Adjust artifacts caused by brightness changes"); + ntsc_offset = 5; + m->max_items = VI_OFFSET + 10 + (config.aspect == 0); + } else + { sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF"); + strcpy(items[VI_OFFSET+1].text, items[VI_OFFSET+5+1].text); + strcpy(items[VI_OFFSET+2].text, items[VI_OFFSET+5+2].text); + strcpy(items[VI_OFFSET+3].text, items[VI_OFFSET+5+3].text); + strcpy(items[VI_OFFSET+4].text, items[VI_OFFSET+5+4].text); + strcpy(items[VI_OFFSET+5].text, items[VI_OFFSET+5+5].text); + strcpy(items[VI_OFFSET+1].comment, items[VI_OFFSET+5+1].comment); + strcpy(items[VI_OFFSET+2].comment, items[VI_OFFSET+5+2].comment); + strcpy(items[VI_OFFSET+3].comment, items[VI_OFFSET+5+3].comment); + strcpy(items[VI_OFFSET+4].comment, items[VI_OFFSET+5+4].comment); + strcpy(items[VI_OFFSET+5].comment, items[VI_OFFSET+5+5].comment); + ntsc_offset = 0; + m->max_items = VI_OFFSET + 5 + (config.aspect == 0); + } break; - case VI_OFFSET+1: /*** overscan emulation ***/ + case VI_OFFSET+1: /*** NTSC Sharpness ***/ + GUI_OptionBox(m,update_bgm,"NTSC Sharpness",(void *)&config.ntsc_sharpness,0.01,-1.0,1.0,0); + sprintf(items[VI_OFFSET+1].text, "NTSC Sharpness: %1.2f", config.ntsc_sharpness); + break; + + case VI_OFFSET+2: /*** NTSC Resolution ***/ + GUI_OptionBox(m,update_bgm,"NTSC Resolution",(void *)&config.ntsc_resolution,0.01,0.0,1.0,0); + sprintf(items[VI_OFFSET+2].text, "NTSC Resolution: %1.2f", config.ntsc_resolution); + break; + + case VI_OFFSET+3: /*** NTSC Artifacts ***/ + GUI_OptionBox(m,update_bgm,"NTSC Artifacts",(void *)&config.ntsc_artifacts,0.01,-1.0,0.0,0); + sprintf(items[VI_OFFSET+3].text, "NTSC Artifacts: %1.2f", config.ntsc_artifacts); + break; + + case VI_OFFSET+4: /*** NTSC Color Bleed ***/ + GUI_OptionBox(m,update_bgm,"NTSC Color Bleed",(void *)&config.ntsc_bleed,0.01,-1.0,1.0,0); + sprintf(items[VI_OFFSET+4].text, "NTSC Color Bleed: %1.2f", config.ntsc_bleed); + break; + + case VI_OFFSET+5: /*** NTSC Color Fringing ***/ + GUI_OptionBox(m,update_bgm,"NTSC Color Fringing",(void *)&config.ntsc_fringing,0.01,-1.0,1.0,0); + sprintf(items[VI_OFFSET+5].text, "NTSC Color Fringing: %1.2f", config.ntsc_fringing); + break; + + case VI_OFFSET+6: /*** overscan emulation ***/ config.overscan = (config.overscan + 1) & 3; if (config.overscan == 3) - sprintf (items[VI_OFFSET+1].text, "Borders: FULL"); + sprintf (items[VI_OFFSET+ntsc_offset+1].text, "Borders: FULL"); else if (config.overscan == 2) - sprintf (items[VI_OFFSET+1].text, "Borders: H ONLY"); + sprintf (items[VI_OFFSET+ntsc_offset+1].text, "Borders: H ONLY"); else if (config.overscan == 1) - sprintf (items[VI_OFFSET+1].text, "Borders: V ONLY"); + sprintf (items[VI_OFFSET+ntsc_offset+1].text, "Borders: V ONLY"); else - sprintf (items[VI_OFFSET+1].text, "Borders: NONE"); + sprintf (items[VI_OFFSET+ntsc_offset+1].text, "Borders: NONE"); break; - case VI_OFFSET+2: /*** Game Gear extended screen */ + case VI_OFFSET+7: /*** Game Gear extended screen */ config.gg_extra ^= 1; - sprintf(items[VI_OFFSET+2].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL"); + sprintf(items[VI_OFFSET+ntsc_offset+2].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL"); break; - case VI_OFFSET+3: /*** aspect ratio ***/ + case VI_OFFSET+8: /*** aspect ratio ***/ config.aspect = (config.aspect + 1) % 3; if (config.aspect == 1) - sprintf (items[VI_OFFSET+3].text,"Aspect: ORIGINAL (4:3)"); + sprintf (items[VI_OFFSET+ntsc_offset+3].text,"Aspect: ORIGINAL (4:3)"); else if (config.aspect == 2) - sprintf (items[VI_OFFSET+3].text, "Aspect: ORIGINAL (16:9)"); + sprintf (items[VI_OFFSET+ntsc_offset+3].text, "Aspect: ORIGINAL (16:9)"); else - sprintf (items[VI_OFFSET+3].text, "Aspect: SCALED"); + sprintf (items[VI_OFFSET+ntsc_offset+3].text, "Aspect: SCALED"); if (config.aspect) { /* disable items */ - m->max_items = VI_OFFSET+5; + m->max_items = VI_OFFSET + ntsc_offset + 5; /* reset menu selection */ - if (m->offset > VI_OFFSET) + if (m->selected < 2) { - m->offset = VI_OFFSET; - m->selected = 3; + m->offset = VI_OFFSET + ntsc_offset + 1; + m->selected = 2; } } else { /* enable items */ - m->max_items = VI_OFFSET+6; + m->max_items = VI_OFFSET + ntsc_offset + 6; } break; - case VI_OFFSET+4: /*** screen position ***/ + case VI_OFFSET+9: /*** screen position ***/ if (system_hw) { state[0] = m->arrows[0]->state; @@ -1718,7 +1821,7 @@ static void videomenu () m->arrows[1]->state = state[1]; m->screenshot = 0; strcpy(m->title,"Video Settings"); - sprintf (items[VI_OFFSET+4].text, "Screen Position: (%s%02d,%s%02d)", + sprintf (items[VI_OFFSET+ntsc_offset+4].text, "Screen Position: (%s%02d,%s%02d)", (config.xshift < 0) ? "":"+", config.xshift, (config.yshift < 0) ? "":"+", config.yshift); } @@ -1728,7 +1831,7 @@ static void videomenu () } break; - case VI_OFFSET+5: /*** screen scaling ***/ + case VI_OFFSET+10: /*** screen scaling ***/ if (system_hw) { state[0] = m->arrows[0]->state; @@ -1746,7 +1849,7 @@ static void videomenu () m->arrows[1]->state = state[1]; m->screenshot = 0; strcpy(m->title,"Video Settings"); - sprintf (items[VI_OFFSET+5].text, "Screen Scaling: (%s%02d,%s%02d)", + sprintf (items[VI_OFFSET+ntsc_offset+5].text, "Screen Scaling: (%s%02d,%s%02d)", (config.xscale < 0) ? "":"+", config.xscale, (config.yscale < 0) ? "":"+", config.yscale); } diff --git a/gx/gx_video.c b/gx/gx_video.c index 662d450..81fe570 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -1557,17 +1557,37 @@ void gx_video_Start(void) switch (config.ntsc) { case 1: + { sms_ntsc_init(sms_ntsc, &sms_ntsc_composite); md_ntsc_init(md_ntsc, &md_ntsc_composite); break; + } + case 2: + { sms_ntsc_init(sms_ntsc, &sms_ntsc_svideo); md_ntsc_init(md_ntsc, &md_ntsc_svideo); break; + } + case 3: + { sms_ntsc_init(sms_ntsc, &sms_ntsc_rgb); md_ntsc_init(md_ntsc, &md_ntsc_rgb); + } + + case 4: + { + md_ntsc_setup_t ntsc_custom = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + ntsc_custom.sharpness = config.ntsc_sharpness; + ntsc_custom.resolution = config.ntsc_resolution; + ntsc_custom.artifacts = config.ntsc_artifacts; + ntsc_custom.fringing = config.ntsc_fringing; + ntsc_custom.bleed = config.ntsc_bleed; + sms_ntsc_init(sms_ntsc, (sms_ntsc_setup_t *)&ntsc_custom); + md_ntsc_init(md_ntsc, &ntsc_custom); break; + } } }