Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 43 additions & 13 deletions src/dev/mgras/rss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ pub mod reg {
pub const CONFIG: u32 = 0x112;
pub const XYWIN: u32 = 0x115;
/// Background colour, where an opaque stipple draws its 0 bits: a colour
/// index, or in RGB modes blue (bits 23:12) and green (11:0), 12 bits
/// each, with red in the next register.
/// index, or in RGB modes green (bits 23:12) and red (11:0), 12 bits
/// each, with blue in bits 11:0 of the next register (bkgrd_rg/ba).
pub const BG_COLOR: u32 = 0x140;
pub const BG_COLOR_RED: u32 = 0x141;
pub const BG_COLOR_BLUE: u32 = 0x141;
/// The clip rectangle: x and y ranges, each `min << 16 | max`, and its
/// control (bit 0 enable, bit 4 keep the inside rather than the outside).
pub const CLIP_X: u32 = 0x147;
Expand Down Expand Up @@ -1275,8 +1275,8 @@ impl Rss {
pub(super) fn background(&self) -> u32 {
let bg = self.reg(reg::BG_COLOR);
if self.rgb_mode() {
let red = self.reg(reg::BG_COLOR_RED) & 0xFFF;
pack_rgb(red >> 4, (bg & 0xFFF) >> 4, ((bg >> 12) & 0xFFF) >> 4)
let blue = self.reg(reg::BG_COLOR_BLUE) & 0xFFF;
pack_rgb((bg & 0xFFF) >> 4, ((bg >> 12) & 0xFFF) >> 4, blue >> 4)
} else {
bg & 0xFFF
}
Expand Down Expand Up @@ -2261,24 +2261,54 @@ mod tests {
}

/// In RGB modes the background is three 12-bit components across two
/// registers, as IRIX writes it for a 12-bit window's icon: white
/// is 0xf00f00 (blue, green) and 0xf00 (red). These are the values from
/// a trace of the desktop repainting its Icon Catalog.
/// registers, red lowest like the packed colour. The values are the
/// syserrpanel stop sign from a trace of the desktop repainting its
/// Icon Catalog: red 0xf0 dithered with a light red (0xc0, 0x70, 0x70),
/// which hardware shows as a red sign.
#[test]
fn opaque_stipple_background_in_rgb_modes() {
let mut r = x_server();
r.write(reg::PP1FILLMODE, 0x0C00_4004, false); // RGB pixel type
r.write(reg::COLORMASKLSBSA, 0xFFF, false);
r.write(reg::FILLMODE, FILL_LINE_STIPPLE | FILL_LINE_STIPPLE_OPAQUE, false);
r.write(reg::PACKEDCOLOR, 0xA0_A0A0, false);
r.write(reg::BG_COLOR, 0xC00_700, false);
r.write(reg::BG_COLOR_RED, 0x300, false);
r.write(reg::PACKEDCOLOR, 0xF0, false);
r.write(reg::BG_COLOR, 0x700_C00, false);
r.write(reg::BG_COLOR_BLUE, 0x700, false);
r.write(reg::LINE_STIPPLE, 0xAAAA_AAAA, false);
r.write(reg::IR_ALIAS, 0x15, false);
r.write(reg::LINE_START, 300 << 16 | 40, false);
r.write(reg::LINE_END, 301 << 16 | 40, true);
assert_eq!(px(&r, 300, 40), 0xAA_AAAA);
assert_eq!(px(&r, 301, 40), pack_rgb(0x33, 0x77, 0xCC), "expanded RGB444 background");
assert_eq!(px(&r, 300, 40), 0xFF);
assert_eq!(px(&r, 301, 40), pack_rgb(0xCC, 0x77, 0x77), "expanded RGB444 background");
}

/// The syserrpanel stop sign as traced from 4Dwm (testdata): every
/// pixel of the dithered sign is red or light red, half each, never the
/// green the old background decode gave.
#[test]
fn syserrpanel_stop_sign_trace_dithers_red() {
let mut r = x_server();
for line in include_str!("testdata/syserrpanel_stop_sign.txt").lines() {
let mut f = line.split_whitespace();
let Some(name) = f.next().filter(|n| !n.starts_with('#')) else { continue };
let reg = REG_NAMES.iter().position(|&n| n == name).unwrap_or_else(|| panic!("register {name}"));
let val = u32::from_str_radix(f.next().unwrap().trim_start_matches("0x"), 16).unwrap();
r.write(reg as u32, val, f.next() == Some("x"));
}
let buf = r.target();
let (red, light) = (pack_rgb(0xFF, 0, 0), pack_rgb(0xCC, 0x77, 0x77));
let (mut n_red, mut n_light) = (0u32, 0u32);
for y in 266..=294 {
for x in 740..800 {
match r.mem.get(&buf, x, 767 - y) as u32 {
0 => {}
p if p == red => n_red += 1,
p if p == light => n_light += 1,
p => panic!("({x}, {y}) is {p:#08x}, not red or light red"),
}
}
}
assert!(n_red > 200 && n_red.abs_diff(n_light) < 10, "red {n_red}, light red {n_light}");
}

/// Block type 0 is a fill in the iterated colour, drawn at once (the
Expand Down
2 changes: 1 addition & 1 deletion src/dev/mgras/rss_jit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ fn common_regs(rng: &mut Rng, regs: &mut Regs, gl: bool) {

/// Colours, whichever the primitive uses (data: not in the key).
fn colour_regs(rng: &mut Rng, regs: &mut Regs) {
for r in [reg::FILL_COLOR_R, reg::FILL_COLOR_G, reg::FILL_COLOR_B, reg::FILL_COLOR_B + 1, reg::RED, reg::PACKEDCOLOR, reg::BG_COLOR, reg::BG_COLOR_RED] {
for r in [reg::FILL_COLOR_R, reg::FILL_COLOR_G, reg::FILL_COLOR_B, reg::FILL_COLOR_B + 1, reg::RED, reg::PACKEDCOLOR, reg::BG_COLOR, reg::BG_COLOR_BLUE] {
regs.push((r, rng.u32()));
}
}
Expand Down
105 changes: 105 additions & 0 deletions src/dev/mgras/testdata/syserrpanel_stop_sign.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# The syserrpanel stop sign in the IRIX 6.5 Icon Catalog (12-bit RGB window),
# from an RSS trace (mgras trace, rss): 4Dwm dithers the sign 50/50 with an
# opaque line stipple, red 0xf0 on a light red background (bkgrd_rg 0x700c00,
# bkgrd_ba 0x700). Hardware shows a red sign.
# One RSS register write per line: name value, "x" for the execute address.
xywin 0x2ff0000
winmode 0x0
pp1fillmode 0xc008004
ColorMaskLSBsA 0xfff000
ColorMaskLSBsB 0xfff000
ColorMaskMSBs 0x0
packed_color 0xf0
bkgrd_rg 0x700c00
bkgrd_ba 0x700
DRBpointers 0xb81c0
fillmode 0x60
ir_alias 0x15
lscrl 0xf0000
lspat 0x55555555
xline_xystarti 0x30c010a
xline_xyendi 0x30f010a x
lspat 0xaaaaaaaa
xline_xystarti 0x30a010b
xline_xyendi 0x310010b x
lspat 0x55555555
xline_xystarti 0x308010c
xline_xyendi 0x311010c x
lspat 0x55555555
xline_xystarti 0x305010d
xline_xyendi 0x312010d x
lspat 0xaaaaaaaa
xline_xystarti 0x305010e
xline_xyendi 0x313010e x
lspat 0xaaaaaaaa
xline_xystarti 0x304010f
xline_xyendi 0x313010f x
lspat 0x55555555
xline_xystarti 0x3040110
xline_xyendi 0x3130110 x
lspat 0x55555555
xline_xystarti 0x3030111
xline_xyendi 0x3130111 x
lspat 0xaaaaaaaa
xline_xystarti 0x3030112
xline_xyendi 0x3130112 x
lspat 0xaaaaaaaa
xline_xystarti 0x3020113
xline_xyendi 0x3130113 x
lspat 0x55555555
xline_xystarti 0x3020114
xline_xyendi 0x3130114 x
lspat 0x55555555
xline_xystarti 0x3010115
xline_xyendi 0x3130115 x
lspat 0xaaaaaaaa
xline_xystarti 0x3010116
xline_xyendi 0x3130116 x
lspat 0xaaaaaaaa
xline_xystarti 0x3000117
xline_xyendi 0x3130117 x
lspat 0xaaaaaaaa
xline_xystarti 0x2ff0118
xline_xyendi 0x3130118 x
lspat 0x55555555
xline_xystarti 0x2ff0119
xline_xyendi 0x3130119 x
lspat 0xaaaaaaaa
xline_xystarti 0x2ff011a
xline_xyendi 0x312011a x
lspat 0x55555555
xline_xystarti 0x2ff011b
xline_xyendi 0x312011b x
lspat 0xaaaaaaaa
xline_xystarti 0x2ff011c
xline_xyendi 0x311011c x
lspat 0x55555555
xline_xystarti 0x2ff011d
xline_xyendi 0x311011d x
lspat 0xaaaaaaaa
xline_xystarti 0x2ff011e
xline_xyendi 0x310011e x
lspat 0x55555555
xline_xystarti 0x2ff011f
xline_xyendi 0x310011f x
lspat 0xaaaaaaaa
xline_xystarti 0x2ff0120
xline_xyendi 0x30f0120 x
lspat 0x55555555
xline_xystarti 0x2ff0121
xline_xyendi 0x30f0121 x
lspat 0xaaaaaaaa
xline_xystarti 0x2ff0122
xline_xyendi 0x30e0122 x
lspat 0x55555555
xline_xystarti 0x3010123
xline_xyendi 0x30d0123 x
lspat 0x55555555
xline_xystarti 0x3020124
xline_xyendi 0x30b0124 x
lspat 0x55555555
xline_xystarti 0x3030125
xline_xyendi 0x3090125 x
lspat 0x55555555
xline_xystarti 0x3040126
xline_xyendi 0x3070126 x
Loading