///|
pub fn timing_catalog() -> Array[TimingCatalogEntry] {
[
timing_entry(
"est-720x400-70",
EstablishedFamily,
720,
400,
70000,
28320,
true,
"9:5",
"Established 720x400@70",
),
timing_entry(
"est-720x400-88",
EstablishedFamily,
720,
400,
88000,
35500,
true,
"9:5",
"Established 720x400@88",
),
timing_entry(
"est-640x480-60",
EstablishedFamily,
640,
480,
60000,
25175,
true,
"4:3",
"Established 640x480@60",
),
timing_entry(
"est-640x480-67",
EstablishedFamily,
640,
480,
67000,
30240,
true,
"4:3",
"Established 640x480@67",
),
timing_entry(
"est-640x480-72",
EstablishedFamily,
640,
480,
72000,
31500,
true,
"4:3",
"Established 640x480@72",
),
timing_entry(
"est-640x480-75",
EstablishedFamily,
640,
480,
75000,
31500,
true,
"4:3",
"Established 640x480@75",
),
timing_entry(
"est-800x600-56",
EstablishedFamily,
800,
600,
56000,
36000,
true,
"4:3",
"Established 800x600@56",
),
timing_entry(
"est-800x600-60",
EstablishedFamily,
800,
600,
60000,
40000,
true,
"4:3",
"Established 800x600@60",
),
timing_entry(
"est-800x600-72",
EstablishedFamily,
800,
600,
72000,
50000,
true,
"4:3",
"Established 800x600@72",
),
timing_entry(
"est-800x600-75",
EstablishedFamily,
800,
600,
75000,
49500,
true,
"4:3",
"Established 800x600@75",
),
timing_entry(
"est-832x624-75",
EstablishedFamily,
832,
624,
75000,
57284,
true,
"4:3",
"Established 832x624@75",
),
timing_entry(
"est-1024x768-87i",
EstablishedFamily,
1024,
768,
87000,
44900,
false,
"4:3",
"Established 1024x768@87i",
),
timing_entry(
"est-1024x768-60",
EstablishedFamily,
1024,
768,
60000,
65000,
true,
"4:3",
"Established 1024x768@60",
),
timing_entry(
"est-1024x768-70",
EstablishedFamily,
1024,
768,
70000,
75000,
true,
"4:3",
"Established 1024x768@70",
),
timing_entry(
"est-1024x768-75",
EstablishedFamily,
1024,
768,
75000,
78750,
true,
"4:3",
"Established 1024x768@75",
),
timing_entry(
"est-1280x1024-75",
EstablishedFamily,
1280,
1024,
75000,
135000,
true,
"5:4",
"Established 1280x1024@75",
),
timing_entry(
"est-1152x870-75",
EstablishedFamily,
1152,
870,
75000,
100000,
true,
"4:3",
"Established 1152x870@75",
),
timing_entry(
"dmt-640x350-85",
DmtFamily,
640,
350,
85000,
31500,
true,
"64:35",
"DMT 640x350@85",
),
timing_entry(
"dmt-640x400-85",
DmtFamily,
640,
400,
85000,
31500,
true,
"16:10",
"DMT 640x400@85",
),
timing_entry(
"dmt-720x400-70",
DmtFamily,
720,
400,
70000,
28320,
true,
"9:5",
"DMT 720x400@70",
),
timing_entry(
"dmt-720x400-85",
DmtFamily,
720,
400,
85000,
35500,
true,
"9:5",
"DMT 720x400@85",
),
timing_entry(
"dmt-640x480-60",
DmtFamily,
640,
480,
60000,
25175,
true,
"4:3",
"DMT 640x480@60",
),
timing_entry(
"dmt-640x480-72",
DmtFamily,
640,
480,
72000,
31500,
true,
"4:3",
"DMT 640x480@72",
),
timing_entry(
"dmt-640x480-75",
DmtFamily,
640,
480,
75000,
31500,
true,
"4:3",
"DMT 640x480@75",
),
timing_entry(
"dmt-640x480-85",
DmtFamily,
640,
480,
85000,
36000,
true,
"4:3",
"DMT 640x480@85",
),
timing_entry(
"dmt-800x600-56",
DmtFamily,
800,
600,
56000,
36000,
true,
"4:3",
"DMT 800x600@56",
),
timing_entry(
"dmt-800x600-60",
DmtFamily,
800,
600,
60000,
40000,
true,
"4:3",
"DMT 800x600@60",
),
timing_entry(
"dmt-800x600-72",
DmtFamily,
800,
600,
72000,
50000,
true,
"4:3",
"DMT 800x600@72",
),
timing_entry(
"dmt-800x600-75",
DmtFamily,
800,
600,
75000,
49500,
true,
"4:3",
"DMT 800x600@75",
),
timing_entry(
"dmt-800x600-85",
DmtFamily,
800,
600,
85000,
56250,
true,
"4:3",
"DMT 800x600@85",
),
timing_entry(
"dmt-848x480-60",
DmtFamily,
848,
480,
60000,
33750,
true,
"16:9",
"DMT 848x480@60",
),
timing_entry(
"dmt-1024x768-87i",
DmtFamily,
1024,
768,
87000,
44900,
false,
"4:3",
"DMT 1024x768@87i",
),
timing_entry(
"dmt-1024x768-60",
DmtFamily,
1024,
768,
60000,
65000,
true,
"4:3",
"DMT 1024x768@60",
),
timing_entry(
"dmt-1024x768-70",
DmtFamily,
1024,
768,
70000,
75000,
true,
"4:3",
"DMT 1024x768@70",
),
timing_entry(
"dmt-1024x768-75",
DmtFamily,
1024,
768,
75000,
78750,
true,
"4:3",
"DMT 1024x768@75",
),
timing_entry(
"dmt-1024x768-85",
DmtFamily,
1024,
768,
85000,
94500,
true,
"4:3",
"DMT 1024x768@85",
),
timing_entry(
"dmt-1152x864-75",
DmtFamily,
1152,
864,
75000,
108000,
true,
"4:3",
"DMT 1152x864@75",
),
timing_entry(
"dmt-1280x768-60",
DmtFamily,
1280,
768,
60000,
79500,
true,
"5:3",
"DMT 1280x768@60",
),
timing_entry(
"dmt-1280x768-75",
DmtFamily,
1280,
768,
75000,
102250,
true,
"5:3",
"DMT 1280x768@75",
),
timing_entry(
"dmt-1280x768-85",
DmtFamily,
1280,
768,
85000,
117500,
true,
"5:3",
"DMT 1280x768@85",
),
timing_entry(
"dmt-1280x800-60",
DmtFamily,
1280,
800,
60000,
83500,
true,
"16:10",
"DMT 1280x800@60",
),
timing_entry(
"dmt-1280x800-75",
DmtFamily,
1280,
800,
75000,
106500,
true,
"16:10",
"DMT 1280x800@75",
),
timing_entry(
"dmt-1280x800-85",
DmtFamily,
1280,
800,
85000,
122500,
true,
"16:10",
"DMT 1280x800@85",
),
timing_entry(
"dmt-1280x960-60",
DmtFamily,
1280,
960,
60000,
108000,
true,
"4:3",
"DMT 1280x960@60",
),
timing_entry(
"dmt-1280x960-85",
DmtFamily,
1280,
960,
85000,
148500,
true,
"4:3",
"DMT 1280x960@85",
),
timing_entry(
"dmt-1280x1024-60",
DmtFamily,
1280,
1024,
60000,
108000,
true,
"5:4",
"DMT 1280x1024@60",
),
timing_entry(
"dmt-1280x1024-75",
DmtFamily,
1280,
1024,
75000,
135000,
true,
"5:4",
"DMT 1280x1024@75",
),
timing_entry(
"dmt-1280x1024-85",
DmtFamily,
1280,
1024,
85000,
157500,
true,
"5:4",
"DMT 1280x1024@85",
),
timing_entry(
"dmt-1360x768-60",
DmtFamily,
1360,
768,
60000,
85500,
true,
"16:9",
"DMT 1360x768@60",
),
timing_entry(
"dmt-1366x768-60",
DmtFamily,
1366,
768,
60000,
85500,
true,
"16:9",
"DMT 1366x768@60",
),
timing_entry(
"dmt-1400x1050-60",
DmtFamily,
1400,
1050,
60000,
121750,
true,
"4:3",
"DMT 1400x1050@60",
),
timing_entry(
"dmt-1400x1050-75",
DmtFamily,
1400,
1050,
75000,
156000,
true,
"4:3",
"DMT 1400x1050@75",
),
timing_entry(
"dmt-1400x1050-85",
DmtFamily,
1400,
1050,
85000,
179500,
true,
"4:3",
"DMT 1400x1050@85",
),
timing_entry(
"dmt-1440x900-60",
DmtFamily,
1440,
900,
60000,
106500,
true,
"16:10",
"DMT 1440x900@60",
),
timing_entry(
"dmt-1440x900-75",
DmtFamily,
1440,
900,
75000,
136750,
true,
"16:10",
"DMT 1440x900@75",
),
timing_entry(
"dmt-1440x900-85",
DmtFamily,
1440,
900,
85000,
157000,
true,
"16:10",
"DMT 1440x900@85",
),
timing_entry(
"dmt-1600x900-60",
DmtFamily,
1600,
900,
60000,
108000,
true,
"16:9",
"DMT 1600x900@60",
),
timing_entry(
"dmt-1600x1200-60",
DmtFamily,
1600,
1200,
60000,
162000,
true,
"4:3",
"DMT 1600x1200@60",
),
timing_entry(
"dmt-1600x1200-65",
DmtFamily,
1600,
1200,
65000,
175500,
true,
"4:3",
"DMT 1600x1200@65",
),
timing_entry(
"dmt-1600x1200-70",
DmtFamily,
1600,
1200,
70000,
189000,
true,
"4:3",
"DMT 1600x1200@70",
),
timing_entry(
"dmt-1600x1200-75",
DmtFamily,
1600,
1200,
75000,
202500,
true,
"4:3",
"DMT 1600x1200@75",
),
timing_entry(
"dmt-1600x1200-85",
DmtFamily,
1600,
1200,
85000,
229500,
true,
"4:3",
"DMT 1600x1200@85",
),
timing_entry(
"dmt-1680x1050-60",
DmtFamily,
1680,
1050,
60000,
146250,
true,
"16:10",
"DMT 1680x1050@60",
),
timing_entry(
"dmt-1680x1050-75",
DmtFamily,
1680,
1050,
75000,
187000,
true,
"16:10",
"DMT 1680x1050@75",
),
timing_entry(
"dmt-1680x1050-85",
DmtFamily,
1680,
1050,
85000,
214750,
true,
"16:10",
"DMT 1680x1050@85",
),
timing_entry(
"dmt-1792x1344-60",
DmtFamily,
1792,
1344,
60000,
204750,
true,
"4:3",
"DMT 1792x1344@60",
),
timing_entry(
"dmt-1792x1344-75",
DmtFamily,
1792,
1344,
75000,
261000,
true,
"4:3",
"DMT 1792x1344@75",
),
timing_entry(
"dmt-1856x1392-60",
DmtFamily,
1856,
1392,
60000,
218250,
true,
"4:3",
"DMT 1856x1392@60",
),
timing_entry(
"dmt-1856x1392-75",
DmtFamily,
1856,
1392,
75000,
288000,
true,
"4:3",
"DMT 1856x1392@75",
),
timing_entry(
"dmt-1920x1080-60",
DmtFamily,
1920,
1080,
60000,
148500,
true,
"16:9",
"DMT 1920x1080@60",
),
timing_entry(
"dmt-1920x1200-60",
DmtFamily,
1920,
1200,
60000,
193250,
true,
"16:10",
"DMT 1920x1200@60",
),
timing_entry(
"dmt-1920x1200-75",
DmtFamily,
1920,
1200,
75000,
245250,
true,
"16:10",
"DMT 1920x1200@75",
),
timing_entry(
"dmt-1920x1200-85",
DmtFamily,
1920,
1200,
85000,
281250,
true,
"16:10",
"DMT 1920x1200@85",
),
timing_entry(
"dmt-1920x1440-60",
DmtFamily,
1920,
1440,
60000,
234000,
true,
"4:3",
"DMT 1920x1440@60",
),
timing_entry(
"dmt-1920x1440-75",
DmtFamily,
1920,
1440,
75000,
297000,
true,
"4:3",
"DMT 1920x1440@75",
),
timing_entry(
"dmt-2048x1152-60",
DmtFamily,
2048,
1152,
60000,
162000,
true,
"16:9",
"DMT 2048x1152@60",
),
timing_entry(
"dmt-2560x1440-60",
DmtFamily,
2560,
1440,
60000,
241500,
true,
"16:9",
"DMT 2560x1440@60",
),
timing_entry(
"dmt-2560x1600-60",
DmtFamily,
2560,
1600,
60000,
268500,
true,
"16:10",
"DMT 2560x1600@60",
),
timing_entry(
"cta-640x480-60",
CtaFamily,
640,
480,
60000,
25175,
true,
"4:3",
"CTA VIC 1 640x480@60",
),
timing_entry(
"cta-720x480-60",
CtaFamily,
720,
480,
60000,
27000,
true,
"3:2",
"CTA VIC 2 720x480@60",
),
timing_entry(
"cta-1280x720-60",
CtaFamily,
1280,
720,
60000,
74250,
true,
"16:9",
"CTA VIC 4 1280x720@60",
),
timing_entry(
"cta-1920x1080-60i",
CtaFamily,
1920,
1080,
60000,
74250,
false,
"16:9",
"CTA VIC 5 1920x1080@60i",
),
timing_entry(
"cta-720x480-60w",
CtaFamily,
720,
480,
60000,
27000,
true,
"16:9",
"CTA VIC 3 720x480@60",
),
timing_entry(
"cta-720x576-50",
CtaFamily,
720,
576,
50000,
27000,
true,
"4:3",
"CTA VIC 17 720x576@50",
),
timing_entry(
"cta-1280x720-50",
CtaFamily,
1280,
720,
50000,
74250,
true,
"16:9",
"CTA VIC 19 1280x720@50",
),
timing_entry(
"cta-1920x1080-50i",
CtaFamily,
1920,
1080,
50000,
74250,
false,
"16:9",
"CTA VIC 20 1920x1080@50i",
),
timing_entry(
"cta-1920x1080-24",
CtaFamily,
1920,
1080,
24000,
74250,
true,
"16:9",
"CTA VIC 32 1920x1080@24",
),
timing_entry(
"cta-1920x1080-25",
CtaFamily,
1920,
1080,
25000,
74250,
true,
"16:9",
"CTA VIC 33 1920x1080@25",
),
timing_entry(
"cta-1920x1080-30",
CtaFamily,
1920,
1080,
30000,
74250,
true,
"16:9",
"CTA VIC 34 1920x1080@30",
),
timing_entry(
"cta-1920x1080-50",
CtaFamily,
1920,
1080,
50000,
148500,
true,
"16:9",
"CTA VIC 31 1920x1080@50",
),
timing_entry(
"cta-1920x1080-60",
CtaFamily,
1920,
1080,
60000,
148500,
true,
"16:9",
"CTA VIC 16 1920x1080@60",
),
timing_entry(
"cta-3840x2160-24",
CtaFamily,
3840,
2160,
24000,
297000,
true,
"16:9",
"CTA VIC 93 3840x2160@24",
),
timing_entry(
"cta-3840x2160-25",
CtaFamily,
3840,
2160,
25000,
297000,
true,
"16:9",
"CTA VIC 94 3840x2160@25",
),
timing_entry(
"cta-3840x2160-30",
CtaFamily,
3840,
2160,
30000,
297000,
true,
"16:9",
"CTA VIC 95 3840x2160@30",
),
timing_entry(
"cta-3840x2160-50",
CtaFamily,
3840,
2160,
50000,
594000,
true,
"16:9",
"CTA VIC 96 3840x2160@50",
),
timing_entry(
"cta-3840x2160-60",
CtaFamily,
3840,
2160,
60000,
594000,
true,
"16:9",
"CTA VIC 97 3840x2160@60",
),
timing_entry(
"cta-4096x2160-24",
CtaFamily,
4096,
2160,
24000,
297000,
true,
"256:135",
"CTA VIC 98 4096x2160@24",
),
timing_entry(
"cta-4096x2160-25",
CtaFamily,
4096,
2160,
25000,
297000,
true,
"256:135",
"CTA VIC 99 4096x2160@25",
),
timing_entry(
"cta-4096x2160-30",
CtaFamily,
4096,
2160,
30000,
297000,
true,
"256:135",
"CTA VIC 100 4096x2160@30",
),
timing_entry(
"cta-4096x2160-50",
CtaFamily,
4096,
2160,
50000,
594000,
true,
"256:135",
"CTA VIC 101 4096x2160@50",
),
timing_entry(
"cta-4096x2160-60",
CtaFamily,
4096,
2160,
60000,
594000,
true,
"256:135",
"CTA VIC 102 4096x2160@60",
),
timing_entry(
"cvt-1024x576-60",
CvtFamily,
1024,
576,
60000,
46500,
true,
"16:9",
"CVT 1024x576@60",
),
timing_entry(
"cvt-1152x648-60",
CvtFamily,
1152,
648,
60000,
62500,
true,
"16:9",
"CVT 1152x648@60",
),
timing_entry(
"cvt-1280x720-60",
CvtFamily,
1280,
720,
60000,
74500,
true,
"16:9",
"CVT 1280x720@60",
),
timing_entry(
"cvt-1366x768-60",
CvtFamily,
1366,
768,
60000,
85500,
true,
"16:9",
"CVT 1366x768@60",
),
timing_entry(
"cvt-1600x900-60",
CvtFamily,
1600,
900,
60000,
119000,
true,
"16:9",
"CVT 1600x900@60",
),
timing_entry(
"cvt-1920x1080-60",
CvtFamily,
1920,
1080,
60000,
173000,
true,
"16:9",
"CVT 1920x1080@60",
),
timing_entry(
"cvt-2560x1440-60",
CvtFamily,
2560,
1440,
60000,
312250,
true,
"16:9",
"CVT 2560x1440@60",
),
timing_entry(
"cvt-3440x1440-60",
CvtFamily,
3440,
1440,
60000,
419500,
true,
"43:18",
"CVT 3440x1440@60",
),
timing_entry(
"cvt-3840x2160-60",
CvtFamily,
3840,
2160,
60000,
712750,
true,
"16:9",
"CVT 3840x2160@60",
),
timing_entry(
"rb-1280x720-60",
RbFamily,
1280,
720,
60000,
60000,
true,
"16:9",
"CVT-RB 1280x720@60",
),
timing_entry(
"rb-1366x768-60",
RbFamily,
1366,
768,
60000,
72000,
true,
"16:9",
"CVT-RB 1366x768@60",
),
timing_entry(
"rb-1600x900-60",
RbFamily,
1600,
900,
60000,
97000,
true,
"16:9",
"CVT-RB 1600x900@60",
),
timing_entry(
"rb-1920x1080-60",
RbFamily,
1920,
1080,
60000,
138500,
true,
"16:9",
"CVT-RB 1920x1080@60",
),
timing_entry(
"rb-1920x1200-60",
RbFamily,
1920,
1200,
60000,
154000,
true,
"16:10",
"CVT-RB 1920x1200@60",
),
timing_entry(
"rb-2560x1440-60",
RbFamily,
2560,
1440,
60000,
241500,
true,
"16:9",
"CVT-RB 2560x1440@60",
),
timing_entry(
"rb-2560x1600-60",
RbFamily,
2560,
1600,
60000,
268500,
true,
"16:10",
"CVT-RB 2560x1600@60",
),
timing_entry(
"rb-3440x1440-60",
RbFamily,
3440,
1440,
60000,
319750,
true,
"43:18",
"CVT-RB 3440x1440@60",
),
timing_entry(
"rb-3840x2160-60",
RbFamily,
3840,
2160,
60000,
533250,
true,
"16:9",
"CVT-RB 3840x2160@60",
),
timing_entry(
"proj-1024x768-60",
ProjectorFamily,
1024,
768,
60000,
65000,
true,
"4:3",
"Projector XGA 1024x768@60",
),
timing_entry(
"proj-1280x800-60",
ProjectorFamily,
1280,
800,
60000,
83500,
true,
"16:10",
"Projector WXGA 1280x800@60",
),
timing_entry(
"proj-1920x1200-60",
ProjectorFamily,
1920,
1200,
60000,
193250,
true,
"16:10",
"Projector WUXGA 1920x1200@60",
),
]
}
///|
pub fn catalog_entries_by_family(
family : TimingFamily,
) -> Array[TimingCatalogEntry] {
let out : Array[TimingCatalogEntry] = []
for entry in timing_catalog() {
if entry.family == family {
out.push(entry)
}
}
out
}
///|
pub fn catalog_entries_by_resolution(
width : Int,
height : Int,
) -> Array[TimingCatalogEntry] {
let out : Array[TimingCatalogEntry] = []
for entry in timing_catalog() {
if entry.width == width && entry.height == height {
out.push(entry)
}
}
out
}
///|
pub fn find_catalog_entry(id : String) -> TimingCatalogEntry? {
for entry in timing_catalog() {
if entry.id == id {
return Some(entry)
}
}
None
}
///|
pub fn catalog_match_for_mode(mode : DisplayMode) -> TimingCatalogEntry? {
let mut best : TimingCatalogEntry? = None
let mut best_score = 100000000
for entry in timing_catalog() {
let score = catalog_distance(entry, mode)
if score < best_score {
best_score = score
best = Some(entry)
}
}
if best_score <= 1200 {
best
} else {
None
}
}
///|
pub fn catalog_matches_for_edid(edid : Edid) -> Array[TimingCatalogEntry] {
let out : Array[TimingCatalogEntry] = []
for mode in modes_from_edid(edid) {
match catalog_match_for_mode(mode) {
Some(entry) => if !catalog_contains_id(out, entry.id) { out.push(entry) }
None => ()
}
}
out
}
///|
pub fn catalog_summary_for_edid(edid : Edid) -> String {
let entries = catalog_matches_for_edid(edid)
if entries.is_empty() {
"catalog-matches=0"
} else {
let buf = StringBuilder(size_hint=entries.length() * 32)
buf.write_string("catalog-matches=")
buf.write_string(entries.length().to_string())
for entry in entries {
buf.write_string("; ")
buf.write_string(entry.id)
}
buf.to_string()
}
}
///|
pub fn catalog_to_markdown(entries : Array[TimingCatalogEntry]) -> String {
let buf = StringBuilder(size_hint=entries.length() * 80 + 96)
buf.write_string("| ID | Family | Mode | Clock kHz | Name |\n")
buf.write_string("| --- | --- | --- | ---: | --- |")
for entry in entries {
buf.write_char('\n')
buf.write_string("| ")
buf.write_string(entry.id)
buf.write_string(" | ")
buf.write_string(entry.family.name())
buf.write_string(" | ")
buf.write_string(entry.label())
buf.write_string(" | ")
buf.write_string(entry.pixel_clock_khz.to_string())
buf.write_string(" | ")
buf.write_string(entry.name)
buf.write_string(" |")
}
buf.to_string()
}
///|
pub fn highest_catalog_mode() -> TimingCatalogEntry {
let entries = timing_catalog()
let mut best = entries[0]
for entry in entries {
if timing_catalog_score(entry) > timing_catalog_score(best) {
best = entry
}
}
best
}
///|
pub fn high_refresh_catalog_entries() -> Array[TimingCatalogEntry] {
let out : Array[TimingCatalogEntry] = []
for entry in timing_catalog() {
if entry.is_high_refresh() {
out.push(entry)
}
}
out
}
///|
fn timing_entry(
id : String,
family : TimingFamily,
width : Int,
height : Int,
refresh_millihz : Int,
pixel_clock_khz : Int,
progressive : Bool,
aspect : String,
name : String,
) -> TimingCatalogEntry {
{
id,
family,
width,
height,
refresh_millihz,
pixel_clock_khz,
progressive,
aspect,
name,
}
}
///|
fn catalog_distance(entry : TimingCatalogEntry, mode : DisplayMode) -> Int {
let dw = abs_int(entry.width - mode.width)
let dh = abs_int(entry.height - mode.height)
let dr = abs_int(entry.refresh_millihz - mode.refresh_millihz) / 100
dw * 10 + dh * 10 + dr
}
///|
fn timing_catalog_score(entry : TimingCatalogEntry) -> Int {
entry.pixel_count() + (entry.refresh_millihz + 500) / 1000 * 100
}
///|
fn catalog_contains_id(
entries : Array[TimingCatalogEntry],
id : String,
) -> Bool {
for entry in entries {
if entry.id == id {
return true
}
}
false
}
///|
fn abs_int(value : Int) -> Int {
if value < 0 {
0 - value
} else {
value
}
}