From f815e1ccba6faa84bcdb9c90069d3f9db0ce6fc3 Mon Sep 17 00:00:00 2001 From: lantos1618 Date: Tue, 29 Sep 2026 23:27:25 -0400 Subject: [PATCH] Zoom effect: no ghosting at high resolutions The scope's screen effect (a warp: copies of the screen scaled a little from the center, blended outside the scope's mask) spreads its copies by a radius in the Xbox's pixels. At 640x480 the few copies blended into a radial blur; at several screen pixels to the Xbox's one they stood apart as sharp ghosts. The native builds keep the spread and split it into that many times the passes (halo_screen_scale), each a step of it. (cherry picked from commit b7fa7f742a72924514eef69d50daf31ef7f7f836) (cherry picked from commit d1b40a6fc74ab46641313a6e0095e596494a1e7b) Without its #ifdef HALO_LINUX, which OpenCE's builds never define (it compiled to nothing), and with the copied parameters declared with the others (gnu89). (cherry picked from commit 763567dcc7ad8e6a851fec6bb5cb9f9e10452579) --- port/linux/include/halo_linux_source_fixups.h | 2 ++ port/linux/src/d3d8_gl.c | 8 +++++++ .../xbox/rasterizer_xbox_screen_effect.c | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/port/linux/include/halo_linux_source_fixups.h b/port/linux/include/halo_linux_source_fixups.h index 83c4b95f..3b7ea4b5 100644 --- a/port/linux/include/halo_linux_source_fixups.h +++ b/port/linux/include/halo_linux_source_fixups.h @@ -47,6 +47,8 @@ unsigned char custom_edition_vehicle_placement_allowed(struct scenario_object_da /* the width of the screen the game draws, 480 lines tall: the device's or the display's shape, or 640 (port/linux/src/d3d8_gl.c) */ long halo_screen_width(void); +/* the screen's pixels to the Xbox's one (port/linux/src/d3d8_gl.c) */ +float halo_screen_scale(void); /* takes up a new width between frames (F11); returns the width */ long halo_screen_commit(void); /* the shadow maps' pixels for each of their 128 texels each way, a power of diff --git a/port/linux/src/d3d8_gl.c b/port/linux/src/d3d8_gl.c index 3f1a1bc7..df1d7a1b 100644 --- a/port/linux/src/d3d8_gl.c +++ b/port/linux/src/d3d8_gl.c @@ -242,6 +242,14 @@ float halo_screen_pixel_scale(void) return screen_scale[1]; } +/* how many pixels the screen's targets draw to the Xbox's one, the larger +of the two ways (the screen effects' convolutions: rasterizer_xbox_screen_effect.c) */ +float halo_screen_scale(void) +{ + halo_screen_width(); + return screen_scale[0] > screen_scale[1] ? screen_scale[0] : screen_scale[1]; +} + /* display.shadow_resolution: the size the shadow maps are drawn at. Each object's shadow is drawn from above into a 128x128 map, blurred into diff --git a/source/rasterizer/xbox/rasterizer_xbox_screen_effect.c b/source/rasterizer/xbox/rasterizer_xbox_screen_effect.c index 15d82169..68154707 100644 --- a/source/rasterizer/xbox/rasterizer_xbox_screen_effect.c +++ b/source/rasterizer/xbox/rasterizer_xbox_screen_effect.c @@ -492,6 +492,28 @@ void _rasterizer_screen_effect( real_rectangle2d vertex_bounds; unsigned long light_enhancement_input; unsigned long desaturation_input; + struct rasterizer_cinematic_screen_effect_parameters scaled_parameters; + + /* port: the native builds draw the screen at several pixels to the + Xbox's one (halo_screen_scale): a convolution's few copies of the + screen, apart by its radius in the Xbox's pixels, blended into a blur + at 640x480, and at four times the pixels they stand apart as sharp + ghosts (the zoom's warp). The same spread in that many times the + passes, each a step of it, blends them again. */ + if (parameters->convolution_type != _rasterizer_screen_effect_convolution_type_none && !parameters->video_on) + { + long steps = (long)(halo_screen_scale() + 0.999f); + + if (steps > 6) + steps = 6; + if (steps > 1) + { + scaled_parameters = *parameters; + scaled_parameters.convolution_radius /= (real)steps; + parameters = &scaled_parameters; + pass_count *= (short)steps; + } + } if (parameters->video_on) {