Skip to content

Commit

Permalink
Split buffer apart, play around with textures
Browse files Browse the repository at this point in the history
  • Loading branch information
DDRBoxman committed Oct 11, 2023
1 parent 3bf340c commit 7ec105c
Show file tree
Hide file tree
Showing 9 changed files with 355 additions and 106 deletions.
2 changes: 2 additions & 0 deletions Cappy3ds/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ raw-window-handle = "0.5.2"
futures = "0.3.28"
libusb1-sys = "0.6.4"
libc = "0.2.148"
bytemuck = { version = "1.14", features = [ "derive" ] }
itertools = "0.11.0"

[lib]
name = "cappy3ds"
Expand Down
Binary file added Cappy3ds/resources/test/katsu_example_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Cappy3ds/src/capture/fpga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn configure_fpga<T: UsbContext>(handle: &mut DeviceHandle<T>, bitstream: Ve
// "71038f9db726685e014f0800000230ff6065", //888
"64600200ff00ff600230ff60c2600120ff",
"6107000f003e00f800100056800a0100", // 565
// "6107008f003c00f200380056800a0100" //888
// "6107008f003c00f200380056800a0100" //888
];

for command in end_commands {
Expand Down
140 changes: 83 additions & 57 deletions Cappy3ds/src/capture/image.rs
Original file line number Diff line number Diff line change
@@ -1,77 +1,103 @@
use bytes::{BufMut, BytesMut};
use memchr::memmem;
extern crate libusb1_sys as usbffi;
use image::{ImageBuffer, Rgb};
use itertools::Itertools;

pub fn parse_image_data(data: &Vec<u8>) {
let mut found_frames = 0;

let mut frame_iter = memmem::find_iter(&data, &[0x33, 0xCC, 0x00, 0x00]);
while let Some(frame_start) = frame_iter.next() {
//println!("{}", frame_start);
let finder = memmem::Finder::new(&[0x33, 0xCC, 0x00, 0x00]);

let iter = finder.find_iter(&data);

let result = iter.tuple_windows().collect::<Vec<_>>();

for (start, end) in result {
let mut out_buf = BytesMut::with_capacity(0x40000);
out_buf.put(&data[start..end]);

let (upper_buffer, lower_buffer, sound_buffer) = split_capture_buffer(&out_buf);

//let mut buf = BytesMut::from(data.as_slice());
let thing = &data[frame_start + 3..];



// let mut it = memmem::find(&thing, &[0x33, 0xCC]);
//if let Some(res) = it {
// out_buf.put(&thing[res..res + (720 * 248 * 2)]);
let mut it = memmem::find_iter(&thing, &[0x33, 0xCC]);

while let Some(res) = it.next() {
/*if (thing[res + 2] == 0x90) {
break;
}*/

// Next image is here
if thing[res + 2] == 0x00 && thing[res + 3] == 0x00 {
break;
}
//println!("{}", res);
if res + (248 * 2) > thing.len() {
break;
}
out_buf.put(&thing[res..res + (248 * 2)])
// print lower image
let result = rgb565_to_rgb(240, 320, &lower_buffer);
if let Some(image) = result {
image.save(format!("./img_out/lower_{}.png", found_frames));
}

let mut image_buffer = BytesMut::with_capacity(720 * 248 * 2);
image_buffer.resize(out_buf.len() / 2 * 3, 0);

let mut j = 0;
for i in (0..out_buf.len()).step_by(2) {
let high = (out_buf[i + 1] as u16) << 8;
let c: u16 = out_buf[i] as u16 + high;
let r = (((c & 0xF800) >> 11) << 3) as u8;
let g = (((c & 0x7E0) >> 5) << 2) as u8;
let b = ((c & 0x1F) << 3) as u8;

image_buffer[j] = r;
j += 1;
image_buffer[j] = g;
j += 1;
image_buffer[j] = b;
j += 1;
// print upper image
let result = rgb565_to_rgb(240, 400, &upper_buffer);
if let Some(image) = result {
image.save(format!("./img_out/upper_{}.png", found_frames));
}

use image::{ImageBuffer, Rgb};
let buffer = ImageBuffer::<Rgb<u8>, _>::from_raw(
248,
(out_buf.len() / 2 / 248).try_into().unwrap(),
image_buffer,
)
.unwrap();
// print audio for fun
let result = rgb565_to_rgb(8, 801, &sound_buffer);
if let Some(image) = result {
image.save(format!("./img_out/audio{}.png", found_frames));
}

buffer.save(format!("./test_{}.png", found_frames));
found_frames += 1;
}
}

//let mut file = fs::File::create(format!("./test_{}.bin", found_frames)).expect("WHY NO FILE");
fn split_capture_buffer(data: &BytesMut) -> (BytesMut, BytesMut, BytesMut) {
let mut upper_buffer = BytesMut::with_capacity(400 * 240 * 2);
let mut lower_buffer = BytesMut::with_capacity(320 * 240 * 2);
let mut sound_buffer = BytesMut::with_capacity(720 * 8 * 2);

// split apart buffer into parts
// todo: replace with a nicer byte stream reader
let mut pos = 0;
while pos < data.len() - 496 {
if pos < 81 * 496 {
// copy preamble audio
sound_buffer.extend(&data[pos..pos + 16]);
pos += 496;
} else if pos >= 81 * 496 && pos < 400 * 496 {
sound_buffer.extend(&data[pos..pos + 16]);
pos += 16;
lower_buffer.extend(&data[pos..pos + 480]);
pos += 480;
} else if pos == 400 * 496 {
lower_buffer.extend(&data[pos..pos + 480]);
pos += 480;
sound_buffer.extend(&data[pos..pos + 16]);
pos += 16;
} else if pos > 400 * 496 {
upper_buffer.extend(&data[pos..pos + 480]);
pos += 480;
sound_buffer.extend(&data[pos..pos + 16]);
pos += 16;
}
}

//file.write_all(&out_buf);
return (upper_buffer, lower_buffer, sound_buffer);
}

found_frames += 1;
// }

fn rgb565_to_rgb(
width: u32,
height: u32,
data: &BytesMut,
) -> Option<ImageBuffer<Rgb<u8>, BytesMut>> {
let mut image_buffer = BytesMut::new();
image_buffer.resize((width * height * 3).try_into().unwrap(), 0);

let mut j = 0;
for i in (0..data.len()).step_by(2) {
let high = (data[i + 1] as u16) << 8;
let c: u16 = data[i] as u16 + high;
let r = (((c & 0xF800) >> 11) << 3) as u8;
let g = (((c & 0x7E0) >> 5) << 2) as u8;
let b = ((c & 0x1F) << 3) as u8;

image_buffer[j] = r;
j += 1;
image_buffer[j] = g;
j += 1;
image_buffer[j] = b;
j += 1;
}

ImageBuffer::<Rgb<u8>, _>::from_raw(width, height, image_buffer)
}
44 changes: 21 additions & 23 deletions Cappy3ds/src/capture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,13 @@ pub fn do_capture() {
Err(err) => panic!("could not claim second device: {}", err),
}


// bleh apparently relesase runs fast enough to break this
// add in some sleeps
//if fpga::check_fpga_programmed(&mut handle) {
//} else {
fpga::read_eeprom(&mut handle);
fpga::configure_fpga(&mut handle, bitstream.data.to_vec());
// }
fpga::read_eeprom(&mut handle);
fpga::configure_fpga(&mut handle, bitstream.data.to_vec());
// }
fpga::configure_port(&mut handle);
fpga::fifo_start(&mut handle);

Expand Down Expand Up @@ -118,10 +117,6 @@ extern "system" fn transfer_finished<T: UsbContext>(transfer_ptr: *mut usbffi::l
let buf = transfer.buffer;

let s = unsafe { slice::from_raw_parts(buf, TRANSFER_SIZE) };
/*let mut ss = [0; TRANSFER_SIZE];
ss.copy_from_slice(s);
println!("{:?}", ss);*/

let start = memmem::find(s, &[0x33, 0xCC, 0x00, 0x00]);

Expand All @@ -135,31 +130,34 @@ extern "system" fn transfer_finished<T: UsbContext>(transfer_ptr: *mut usbffi::l

let mut local_offset = 0;
let mut local_end = TRANSFER_SIZE;

if let Some(start) = start {
let mut wait = false;

if let Some(start) = start {
if frame_buffer_len == 0 {
local_offset = start;
} else {
local_end = start;
}
} else if frame_buffer_len == 0 {
wait = true;
}

handler.buffers[current_buffer].extend(&s[local_offset..local_end]);

//handler.buffer_pos = handler.buffer_pos + s.len();
if !wait {
handler.buffers[current_buffer].extend(&s[local_offset..local_end]);

if let Some(start) = start {
if frame_buffer_len > 0 {
//println!("{:}", frame_buffer_len);
handler.current_buffer += 1;
if handler.current_buffer >= NUM_BUFFERS {
handler.current_buffer = 0;
}
if let Some(start) = start {
if frame_buffer_len > 0 {
//println!("{:}", frame_buffer_len);
handler.current_buffer += 1;
if handler.current_buffer >= NUM_BUFFERS {
handler.current_buffer = 0;
}

let current_buffer = handler.current_buffer;
let current_buffer = handler.current_buffer;

handler.buffers[current_buffer].clear();
handler.buffers[current_buffer].extend(&s[start..]);
handler.buffers[current_buffer].clear();
handler.buffers[current_buffer].extend(&s[start..]);
}
}
}

Expand Down
11 changes: 1 addition & 10 deletions Cappy3ds/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,11 @@ pub use render::render::State;

mod capture;

#[no_mangle]
pub extern "C" fn hello_world() {
println!("Hello World!");
}

#[no_mangle]
pub extern "C" fn send_window(app_kit_nsview: *mut ffi::c_void) {
let window = Window {
ns_view: app_kit_nsview,
};
/*let mut window_handle = AppKitWindowHandle::empty();
window_handle.ns_view = appKitNSView;
let handle = RawWindowHandle::AppKit(window_handle);*/

let res = State::new(&window);
let mut v = executor::block_on(res);
Expand All @@ -37,7 +28,7 @@ pub fn send_raw_window<
>(
window: &W,
) {
capture::do_capture();
//capture::do_capture();

let res = State::new(&window);
let mut v = executor::block_on(res);
Expand Down
Loading

0 comments on commit 7ec105c

Please sign in to comment.