mirror of
https://github.com/st3fan/ewm.git
synced 2026-10-25 02:02:15 +00:00
Add 4 window pixels of padding around the screen contents (#210)
* Add 4 window pixels of padding around the screen contents Move the canvases from emulated-pixel to window-pixel coordinates and draw the screen texture at an explicit 3x rect inset by PAD, so the contents no longer touch the window border. The dst rect stays an exact integer 3x of the texture, keeping the nearest-neighbor crispness. In the ][+ this also stops the status-bar mode from stretching the screen over the bar strip before overdrawing it: the screen rect is now mode-independent and the bar sits below it inside the side padding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Make the window padding configurable via EWM_WINDOW_PADDING Defaults to 4; missing or unparsable values fall back to the default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f638c535a2
commit
fec25cfec8
4 files changed
+65
-27
No files matched your search
+19
-4
@@ -4,6 +4,7 @@
|
||||
use sdl3::event::Event;
|
||||
use sdl3::keyboard::Keycode;
|
||||
use sdl3::pixels::{Color, PixelFormat};
|
||||
use sdl3::rect::Rect;
|
||||
use sdl3::render::ScaleMode;
|
||||
use sdl3::sys::render::SDL_RendererLogicalPresentation;
|
||||
|
||||
@@ -48,6 +49,8 @@ static MENU: [&str; TTY_ROWS] = [
|
||||
];
|
||||
|
||||
pub fn main(_args: &[String]) -> BooChoice {
|
||||
let pad = sdl::window_padding();
|
||||
|
||||
// Setup SDL
|
||||
|
||||
let context = match sdl3::init() {
|
||||
@@ -60,7 +63,11 @@ pub fn main(_args: &[String]) -> BooChoice {
|
||||
let video = context.video().expect("Failed to initialize SDL video");
|
||||
|
||||
let window = video
|
||||
.window("EWM v0.1 - Bootloader", 280 * 3, 192 * 3)
|
||||
.window(
|
||||
"EWM v0.1 - Bootloader",
|
||||
280 * 3 + 2 * pad,
|
||||
192 * 3 + 2 * pad,
|
||||
)
|
||||
.position_centered()
|
||||
.build()
|
||||
.expect("Failed create window");
|
||||
@@ -72,10 +79,12 @@ pub fn main(_args: &[String]) -> BooChoice {
|
||||
return BooChoice::Quit;
|
||||
}
|
||||
|
||||
// Logical units are window pixels: the tty texture is drawn at 3x into
|
||||
// an explicit rect, leaving pad window pixels around it.
|
||||
canvas
|
||||
.set_logical_size(
|
||||
TTY_PIXEL_WIDTH as u32,
|
||||
TTY_PIXEL_HEIGHT as u32,
|
||||
TTY_PIXEL_WIDTH as u32 * 3 + 2 * pad,
|
||||
TTY_PIXEL_HEIGHT as u32 * 3 + 2 * pad,
|
||||
SDL_RendererLogicalPresentation::LETTERBOX,
|
||||
)
|
||||
.expect("Failed to set logical size");
|
||||
@@ -140,8 +149,14 @@ pub fn main(_args: &[String]) -> BooChoice {
|
||||
texture
|
||||
.update(None, &bytes, TTY_PIXEL_WIDTH * 4)
|
||||
.expect("Failed to update texture");
|
||||
let dst = Rect::new(
|
||||
pad as i32,
|
||||
pad as i32,
|
||||
TTY_PIXEL_WIDTH as u32 * 3,
|
||||
TTY_PIXEL_HEIGHT as u32 * 3,
|
||||
);
|
||||
canvas
|
||||
.copy(&texture, None, None)
|
||||
.copy(&texture, None, dst)
|
||||
.expect("Failed to copy texture");
|
||||
|
||||
canvas.present();
|
||||
|
||||
+15
-4
@@ -12,6 +12,7 @@ use ewm_core::mem::{DeviceHandle, Memory};
|
||||
use sdl3::event::Event;
|
||||
use sdl3::keyboard::{Keycode, Mod};
|
||||
use sdl3::pixels::PixelFormat;
|
||||
use sdl3::rect::Rect;
|
||||
use sdl3::render::ScaleMode;
|
||||
use sdl3::sys::render::SDL_RendererLogicalPresentation;
|
||||
use sdl3::video::FullscreenType;
|
||||
@@ -197,6 +198,8 @@ fn step_cpu(one: &mut One, cycles: u32) {
|
||||
}
|
||||
|
||||
pub fn main(args: &[String]) -> i32 {
|
||||
let pad = sdl::window_padding();
|
||||
|
||||
// Parse Apple 1 specific options. The C default model is the Replica 1.
|
||||
let mut model = OneModel::Replica1;
|
||||
let mut memory: Vec<MemoryOption> = Vec::new();
|
||||
@@ -252,7 +255,7 @@ pub fn main(args: &[String]) -> i32 {
|
||||
let video = context.video().expect("Failed to initialize SDL video");
|
||||
|
||||
let window = video
|
||||
.window("EWM v0.1 - Apple 1", 280 * 3, 192 * 3)
|
||||
.window("EWM v0.1 - Apple 1", 280 * 3 + 2 * pad, 192 * 3 + 2 * pad)
|
||||
.position_centered()
|
||||
.build();
|
||||
let window = match window {
|
||||
@@ -270,10 +273,12 @@ pub fn main(args: &[String]) -> i32 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Logical units are window pixels: the tty texture is drawn at 3x into
|
||||
// an explicit rect, leaving pad window pixels around it.
|
||||
canvas
|
||||
.set_logical_size(
|
||||
TTY_PIXEL_WIDTH as u32,
|
||||
TTY_PIXEL_HEIGHT as u32,
|
||||
TTY_PIXEL_WIDTH as u32 * 3 + 2 * pad,
|
||||
TTY_PIXEL_HEIGHT as u32 * 3 + 2 * pad,
|
||||
SDL_RendererLogicalPresentation::LETTERBOX,
|
||||
)
|
||||
.expect("Failed to set logical size");
|
||||
@@ -375,8 +380,14 @@ pub fn main(args: &[String]) -> i32 {
|
||||
texture
|
||||
.update(None, &bytes, TTY_PIXEL_WIDTH * 4)
|
||||
.expect("Failed to update texture");
|
||||
let dst = Rect::new(
|
||||
pad as i32,
|
||||
pad as i32,
|
||||
TTY_PIXEL_WIDTH as u32 * 3,
|
||||
TTY_PIXEL_HEIGHT as u32 * 3,
|
||||
);
|
||||
canvas
|
||||
.copy(&texture, None, None)
|
||||
.copy(&texture, None, dst)
|
||||
.expect("Failed to copy texture");
|
||||
|
||||
canvas.present();
|
||||
|
||||
@@ -53,6 +53,15 @@ pub fn check_renderer(canvas: &WindowCanvas) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Window pixels between the screen contents and the window border,
|
||||
/// from `EWM_WINDOW_PADDING` (default 4).
|
||||
pub fn window_padding() -> u32 {
|
||||
std::env::var("EWM_WINDOW_PADDING")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(4)
|
||||
}
|
||||
|
||||
/// Port of `ewm_sdl_green`: full green packed for the renderer's format.
|
||||
pub fn green(canvas: &WindowCanvas) -> u32 {
|
||||
match pixel_format(canvas) {
|
||||
|
||||
+22
-19
@@ -620,6 +620,7 @@ pub fn main(args: &[String]) -> i32 {
|
||||
Err(code) => return code,
|
||||
};
|
||||
let fps = options.fps;
|
||||
let pad = sdl::window_padding();
|
||||
|
||||
// Initialize SDL
|
||||
|
||||
@@ -635,7 +636,7 @@ pub fn main(args: &[String]) -> i32 {
|
||||
let controller_subsystem = context.gamepad().ok();
|
||||
|
||||
let window = video
|
||||
.window("EWM v0.1 / Apple ][+", 280 * 3, 192 * 3)
|
||||
.window("EWM v0.1 / Apple ][+", 280 * 3 + 2 * pad, 192 * 3 + 2 * pad)
|
||||
.position(400, 60)
|
||||
.build();
|
||||
let window = match window {
|
||||
@@ -653,10 +654,12 @@ pub fn main(args: &[String]) -> i32 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Logical units are window pixels: the screen texture is drawn at 3x
|
||||
// into an explicit rect, leaving pad window pixels around it.
|
||||
canvas
|
||||
.set_logical_size(
|
||||
SCR_WIDTH as u32,
|
||||
SCR_HEIGHT as u32,
|
||||
SCR_WIDTH as u32 * 3 + 2 * pad,
|
||||
SCR_HEIGHT as u32 * 3 + 2 * pad,
|
||||
SDL_RendererLogicalPresentation::LETTERBOX,
|
||||
)
|
||||
.expect("Failed to set logical size");
|
||||
@@ -855,21 +858,15 @@ pub fn main(args: &[String]) -> i32 {
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let _ = canvas
|
||||
.window_mut()
|
||||
.set_size(SCR_WIDTH as u32 * 3, SCR_HEIGHT as u32 * 3 + extra);
|
||||
let _ = canvas.window_mut().set_size(
|
||||
SCR_WIDTH as u32 * 3 + 2 * pad,
|
||||
SCR_HEIGHT as u32 * 3 + 2 * pad + extra,
|
||||
);
|
||||
let _ = canvas.set_logical_size(
|
||||
SCR_WIDTH as u32 * 3,
|
||||
SCR_HEIGHT as u32 * 3 + extra,
|
||||
SCR_WIDTH as u32 * 3 + 2 * pad,
|
||||
SCR_HEIGHT as u32 * 3 + 2 * pad + extra,
|
||||
SDL_RendererLogicalPresentation::LETTERBOX,
|
||||
);
|
||||
if !status_bar_visible {
|
||||
let _ = canvas.set_logical_size(
|
||||
SCR_WIDTH as u32,
|
||||
SCR_HEIGHT as u32,
|
||||
SDL_RendererLogicalPresentation::LETTERBOX,
|
||||
);
|
||||
}
|
||||
}
|
||||
Keycode::P => paused = !paused,
|
||||
_ => {}
|
||||
@@ -952,8 +949,14 @@ pub fn main(args: &[String]) -> i32 {
|
||||
texture
|
||||
.update(None, &pixels_to_bytes(&scr.pixels), SCR_WIDTH * 4)
|
||||
.expect("Failed to update texture");
|
||||
let screen_dst = Rect::new(
|
||||
pad as i32,
|
||||
pad as i32,
|
||||
SCR_WIDTH as u32 * 3,
|
||||
SCR_HEIGHT as u32 * 3,
|
||||
);
|
||||
canvas
|
||||
.copy(&texture, None, None)
|
||||
.copy(&texture, None, screen_dst)
|
||||
.expect("Failed to copy texture");
|
||||
|
||||
if status_bar_visible {
|
||||
@@ -962,8 +965,8 @@ pub fn main(args: &[String]) -> i32 {
|
||||
.update(None, &pixels_to_bytes(&bar), TTY_PIXEL_WIDTH * 4)
|
||||
.expect("Failed to update bar texture");
|
||||
let dst = Rect::new(
|
||||
0,
|
||||
SCR_HEIGHT as i32 * 3,
|
||||
pad as i32,
|
||||
pad as i32 + SCR_HEIGHT as i32 * 3,
|
||||
SCR_WIDTH as u32 * 3,
|
||||
STATUS_BAR_HEIGHT * 3,
|
||||
);
|
||||
@@ -989,7 +992,7 @@ pub fn main(args: &[String]) -> i32 {
|
||||
TTY_PIXEL_WIDTH * 4,
|
||||
)
|
||||
.expect("Failed to update tty texture");
|
||||
let _ = canvas.copy(&tty_texture, None, None);
|
||||
let _ = canvas.copy(&tty_texture, None, screen_dst);
|
||||
}
|
||||
|
||||
canvas.present();
|
||||
|
||||
Reference in new issue
Block a user