From 74e3c83bedab54114aa3f48994b53e57f4b472da Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 26 Aug 2025 01:42:59 +0600 Subject: [PATCH] Custom EDIDs --- src/86box.c | 3 ++ src/config.c | 14 ++++++++++ src/include/86box/86box.h | 3 ++ src/include/86box/vid_ddc.h | 1 + src/video/vid_ddc.c | 56 +++++++++++++++++++++++++++++++++++-- 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/86box.c b/src/86box.c index 498c86871..7b67e3ba9 100644 --- a/src/86box.c +++ b/src/86box.c @@ -231,6 +231,9 @@ int is_pcjr = 0; /* The current int portable_mode = 0; /* We are running in portable mode (global dirs = exe path) */ +int monitor_edid = 0; /* (C) Which EDID to use. 0=default, 1=custom. */ +char monitor_edid_path[1024] = { 0 }; /* (C) Path to custom EDID */ + // Accelerator key array struct accelKey acc_keys[NUM_ACCELS]; diff --git a/src/config.c b/src/config.c index e88a4753e..af3f39cb8 100644 --- a/src/config.c +++ b/src/config.c @@ -501,6 +501,11 @@ load_video(void) p = "none"; gfxcard[i] = video_get_video_from_internal_name(p); } + + monitor_edid = ini_section_get_int(cat, "monitor_edid", 0); + + monitor_edid_path[0] = 0; + strncpy(monitor_edid_path, ini_section_get_string(cat, "monitor_edid_path", (char*)""), sizeof(monitor_edid_path)); } /* Load "Input Devices" section. */ @@ -2487,6 +2492,15 @@ save_video(void) ini_section_set_string(cat, "gfxcard", video_get_internal_name(gfxcard[0])); + if (monitor_edid) + ini_section_set_int(cat, "monitor_edid", monitor_edid); + else + ini_section_delete_var(cat, "monitor_edid"); + + if (monitor_edid_path[0]) + ini_section_set_string(cat, "monitor_edid_path", monitor_edid_path); + else + ini_section_delete_var(cat, "monitor_edid_path"); if (vid_cga_comp_brightness) ini_section_set_int(cat, "vid_cga_comp_brightness", vid_cga_comp_brightness); diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 521e50965..8696cbabd 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -201,6 +201,9 @@ extern int start_vmm; /* the current execution will start the manag extern int portable_mode; /* we are running in portable mode (global dirs = exe path) */ +extern int monitor_edid; /* (C) Which EDID to use. 0=default, 1=custom. */ +extern char monitor_edid_path[1024]; /* (C) Path to custom EDID */ + #ifndef USE_NEW_DYNAREC extern FILE *stdlog; /* file to log output to */ #endif diff --git a/src/include/86box/vid_ddc.h b/src/include/86box/vid_ddc.h index 144cca406..8d68d0adf 100644 --- a/src/include/86box/vid_ddc.h +++ b/src/include/86box/vid_ddc.h @@ -22,5 +22,6 @@ extern void *ddc_init(void *i2c); extern void ddc_close(void *eeprom); +extern void *ddc_create_default_edid(ssize_t* size_out); #endif /*EMU_VID_DDC_H*/ diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 787e7560e..2d1b78c0d 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -23,6 +23,8 @@ #include #include <86box/86box.h> #include <86box/i2c.h> +#include <86box/vid_ddc.h> +#include <86box/plat.h> #define PIXEL_MM(px) (((px) * 25.4) / 96.0) #define STANDARD_TIMING(slot, width, aspect_ratio, refresh) \ @@ -126,8 +128,8 @@ typedef struct { uint8_t padding[15], checksum2; } edid_t; -void * -ddc_init(void *i2c) +void* +ddc_create_default_edid(ssize_t* size_out) { edid_t *edid = malloc(sizeof(edid_t)); memset(edid, 0, sizeof(edid_t)); @@ -222,7 +224,55 @@ ddc_init(void *i2c) edid->checksum2 += edid_bytes[c]; edid->checksum2 = 256 - edid->checksum2; - return i2c_eeprom_init(i2c, 0x50, edid_bytes, sizeof(edid_t), 0); + if (size_out) + *size_out = sizeof(edid_t); + + return edid; +} + +void * +ddc_init(void *i2c) +{ + ssize_t edid_size = 0; + void* edid_bytes = NULL; + if (monitor_edid == 1 && monitor_edid_path[0]) { + FILE* file = plat_fopen(monitor_edid_path, "rb"); + + if (!file) + goto default_init; + + if (fseek(file, 0, SEEK_END) == -1) { + fclose(file); + goto default_init; + } + + edid_size = ftell(file); + fseek(file, 0, SEEK_SET); + + if (edid_size <= 0) { + fclose(file); + goto default_init; + } + + edid_bytes = calloc(1, edid_size); + if (!edid_bytes) { + fclose(file); + goto default_init; + } + + if (fread(edid_bytes, edid_size, 1, file) <= 0) { + free(edid_bytes); + fclose(file); + goto default_init; + } + + fclose(file); + return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); + } +default_init: + edid_size = sizeof(edid_t); + edid_bytes = ddc_create_default_edid(&edid_size); + return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } void