make rfb handle disconnected pitch better
meh, it works. I really should probably do this in Frontend, but that would be another conversion step. idk
This commit is contained in:
parent
5944c5c1cb
commit
93525cb291
4 changed files with 43 additions and 11 deletions
|
@ -24,7 +24,7 @@ pub(crate) static mut FRONTEND: *mut Frontend = std::ptr::null_mut();
|
||||||
/// Interface for the frontend to call to user code.
|
/// Interface for the frontend to call to user code.
|
||||||
pub trait FrontendInterface {
|
pub trait FrontendInterface {
|
||||||
/// Called when video is updated.
|
/// Called when video is updated.
|
||||||
fn video_update(&mut self, slice: &[u32]);
|
fn video_update(&mut self, slice: &[u32], pitch: u32);
|
||||||
|
|
||||||
/// Called when resize occurs.
|
/// Called when resize occurs.
|
||||||
fn video_resize(&mut self, width: u32, height: u32);
|
fn video_resize(&mut self, width: u32, height: u32);
|
||||||
|
|
|
@ -202,7 +202,7 @@ pub(crate) unsafe extern "C" fn video_refresh_callback(
|
||||||
.resize((pitch * height as usize) as usize, 0);
|
.resize((pitch * height as usize) as usize, 0);
|
||||||
|
|
||||||
// some cores are stupid
|
// some cores are stupid
|
||||||
(*(*FRONTEND).interface).video_resize(pitch as u32, height);
|
(*(*FRONTEND).interface).video_resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this convert from weird pitches to native resolution where possible.
|
// TODO: Make this convert from weird pitches to native resolution where possible.
|
||||||
|
@ -217,7 +217,7 @@ pub(crate) unsafe extern "C" fn video_refresh_callback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*(*FRONTEND).interface).video_update(&(*FRONTEND).converted_pixel_buffer[..]);
|
(*(*FRONTEND).interface).video_update(&(*FRONTEND).converted_pixel_buffer[..], pitch as u32);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let pixel_data_slice = std::slice::from_raw_parts(
|
let pixel_data_slice = std::slice::from_raw_parts(
|
||||||
|
@ -225,7 +225,7 @@ pub(crate) unsafe extern "C" fn video_refresh_callback(
|
||||||
(pitch * height as usize) as usize,
|
(pitch * height as usize) as usize,
|
||||||
);
|
);
|
||||||
|
|
||||||
(*(*FRONTEND).interface).video_update(&pixel_data_slice);
|
(*(*FRONTEND).interface).video_update(&pixel_data_slice, pitch as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,10 +104,10 @@ impl FrontendInterface for App {
|
||||||
self.rfb_server.resize(width as u16, height as u16);
|
self.rfb_server.resize(width as u16, height as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn video_update(&mut self, slice: &[u32]) {
|
fn video_update(&mut self, slice: &[u32], pitch: u32) {
|
||||||
let framebuffer_size = self.get_frontend().get_size();
|
//let framebuffer_size = self.get_frontend().get_size();
|
||||||
self.rfb_server
|
self.rfb_server
|
||||||
.update_buffer(&slice, framebuffer_size.0 as u16, framebuffer_size.1 as u16);
|
.update_buffer(&slice, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn audio_sample(&mut self, _slice: &[i16], _size: usize) {}
|
fn audio_sample(&mut self, _slice: &[i16], _size: usize) {}
|
||||||
|
|
|
@ -18,6 +18,9 @@ pub struct RfbServer {
|
||||||
|
|
||||||
// This follows the same format as libretro joypad buttons.
|
// This follows the same format as libretro joypad buttons.
|
||||||
buttons: [bool; 32],
|
buttons: [bool; 32],
|
||||||
|
|
||||||
|
width: u16,
|
||||||
|
height: u16
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RfbServer {
|
impl RfbServer {
|
||||||
|
@ -53,6 +56,8 @@ impl RfbServer {
|
||||||
ptr: NonNull::new_unchecked(screen),
|
ptr: NonNull::new_unchecked(screen),
|
||||||
framebuffer: Vec::new(),
|
framebuffer: Vec::new(),
|
||||||
buttons: [false; 32],
|
buttons: [false; 32],
|
||||||
|
width: config.width,
|
||||||
|
height: config.height
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disable the normal libvnc cursor (it's annoying)
|
// Disable the normal libvnc cursor (it's annoying)
|
||||||
|
@ -76,6 +81,9 @@ impl RfbServer {
|
||||||
pub fn resize(&mut self, w: u16, h: u16) {
|
pub fn resize(&mut self, w: u16, h: u16) {
|
||||||
let len = (w as usize) * (h as usize);
|
let len = (w as usize) * (h as usize);
|
||||||
|
|
||||||
|
self.width = w;
|
||||||
|
self.height = h;
|
||||||
|
|
||||||
self.framebuffer.resize(len, 0);
|
self.framebuffer.resize(len, 0);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -91,16 +99,40 @@ impl RfbServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_buffer(&mut self, slice: &[u32], width: u16, height: u16) {
|
pub fn update_buffer(&mut self, slice: &[u32], pitch: u32) {
|
||||||
self.framebuffer.copy_from_slice(&slice);
|
|
||||||
|
//self.framebuffer.copy_from_slice(&slice);
|
||||||
|
|
||||||
|
let has_disconnected_pitch = pitch != self.width as u32;
|
||||||
|
|
||||||
|
//if has_disconnected_pitch {
|
||||||
|
// info!("DEBUG: Pitch is not the same as width {}, {}", pitch, self.width);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// copy a line at a time (test)
|
||||||
|
for y in 0..self.height {
|
||||||
|
let src_line_off = (y as u32 * pitch) as usize;
|
||||||
|
let mut dest_line_off = src_line_off;
|
||||||
|
|
||||||
|
// copy only
|
||||||
|
if has_disconnected_pitch {
|
||||||
|
dest_line_off = (y * self.width) as usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create slices repressenting each part
|
||||||
|
let src_slice = &slice[src_line_off..src_line_off + self.width as usize];
|
||||||
|
let dest_slice = &mut self.framebuffer[dest_line_off..dest_line_off + self.width as usize];
|
||||||
|
|
||||||
|
dest_slice.copy_from_slice(src_slice);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
rfb::bindings::rfbMarkRectAsModified(
|
rfb::bindings::rfbMarkRectAsModified(
|
||||||
self.ptr.as_ptr(),
|
self.ptr.as_ptr(),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
width as i32,
|
self.width as i32,
|
||||||
height as i32,
|
self.height as i32,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue