mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 19:31:30 +11:00
New version running with keyboard support
This commit is contained in:
parent
6bb0f1f479
commit
0b2911ca30
|
@ -12,9 +12,9 @@ fn main() {
|
|||
|
||||
let mut buffer: [u32; WIDTH * HEIGHT] = [0; WIDTH * HEIGHT];
|
||||
|
||||
let mut mfb = Minifb::new("Noise Test - Press ESC to exit", WIDTH, HEIGHT).unwrap();
|
||||
let mut window = Window::new("Noise Test - Press ESC to exit", WIDTH, HEIGHT, Scale::X1, Vsync::No).unwrap();
|
||||
|
||||
while mfb.update(&buffer) {
|
||||
while window.update(&buffer) {
|
||||
for i in buffer.iter_mut() {
|
||||
noise = seed;
|
||||
noise >>= 3;
|
||||
|
@ -26,5 +26,13 @@ fn main() {
|
|||
noise &= 0xFF;
|
||||
*i = (noise << 16) | (noise << 8) | noise;
|
||||
}
|
||||
|
||||
for key in window.get_keys().iter() {
|
||||
match *key {
|
||||
Key::A => println!("Pressed A"),
|
||||
Key::B => println!("Pressed B"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
82
src/lib.rs
82
src/lib.rs
|
@ -8,7 +8,6 @@ extern crate cgl;
|
|||
extern crate cocoa;
|
||||
#[cfg(target_os = "macos")]
|
||||
extern crate core_foundation;
|
||||
#[cfg(target_os = "macos")]
|
||||
|
||||
/// Scale will scale the frame buffer and the window that is being sent in when calling the update
|
||||
/// function. This is useful if you for example want to display a 320 x 256 window on a screen with
|
||||
|
@ -46,45 +45,44 @@ pub enum Vsync {
|
|||
BestGuess,
|
||||
}
|
||||
|
||||
///
|
||||
pub enum Key {
|
||||
Key1,
|
||||
Key2,
|
||||
Key3,
|
||||
Key4,
|
||||
Key5,
|
||||
Key6,
|
||||
Key7,
|
||||
Key8,
|
||||
Key9,
|
||||
Key0,
|
||||
Key0 = 0,
|
||||
Key1 = 1,
|
||||
Key2 = 2,
|
||||
Key3 = 3,
|
||||
Key4 = 4,
|
||||
Key5 = 5,
|
||||
Key6 = 6,
|
||||
Key7 = 7,
|
||||
Key8 = 8,
|
||||
Key9 = 9,
|
||||
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
A = 10,
|
||||
B = 11,
|
||||
C = 12,
|
||||
D = 13,
|
||||
E = 14,
|
||||
F = 15,
|
||||
G = 16,
|
||||
H = 17,
|
||||
I = 18,
|
||||
J = 19,
|
||||
K = 20,
|
||||
L = 21,
|
||||
M = 22,
|
||||
N = 23,
|
||||
O = 24,
|
||||
P = 25,
|
||||
Q = 26,
|
||||
R = 27,
|
||||
S = 28,
|
||||
T = 29,
|
||||
U = 30,
|
||||
V = 31,
|
||||
W = 32,
|
||||
X = 33,
|
||||
Y = 34,
|
||||
Z = 35,
|
||||
|
||||
F1,
|
||||
F2,
|
||||
|
@ -145,8 +143,8 @@ pub mod windows;
|
|||
#[cfg(target_os = "windows")]
|
||||
pub use windows::*;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod macos;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use macos::*;
|
||||
//#[cfg(target_os = "macos")]
|
||||
//pub mod macos;
|
||||
//#[cfg(target_os = "macos")]
|
||||
//pub use macos::*;
|
||||
|
||||
|
|
233
src/windows.rs
233
src/windows.rs
|
@ -9,6 +9,8 @@ use Scale;
|
|||
use Vsync;
|
||||
use Key;
|
||||
|
||||
//use Keys;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
|
@ -16,6 +18,7 @@ use std::ffi::OsStr;
|
|||
use std::mem;
|
||||
|
||||
use self::winapi::windef::HWND;
|
||||
use self::winapi::windef::HDC;
|
||||
use self::winapi::winuser::WS_OVERLAPPEDWINDOW;
|
||||
use self::winapi::winuser::WNDCLASSW;
|
||||
use self::winapi::wingdi::BITMAPINFOHEADER;
|
||||
|
@ -30,86 +33,85 @@ struct BitmapInfo {
|
|||
pub bmi_colors: [RGBQUAD; 3],
|
||||
}
|
||||
|
||||
fn update_key_state(window: &mut Window, wparam: u32, bool state) {
|
||||
fn update_key_state(window: &mut Window, wparam: u32, state: bool) {
|
||||
match wparam & 0x1ff {
|
||||
0x00B => window.keys[Key::Key0] = state,
|
||||
0x002 => window.keys[Key::Key1] = state,
|
||||
0x003 => window.keys[Key::Key2] = state,
|
||||
0x004 => window.keys[Key::Key3] = state,
|
||||
0x005 => window.keys[Key::Key4] = state,
|
||||
0x006 => window.keys[Key::Key5] = state,
|
||||
0x007 => window.keys[Key::Key6] = state,
|
||||
0x008 => window.keys[Key::Key7] = state,
|
||||
0x009 => window.keys[Key::Key8] = state,
|
||||
0x00A => window.keys[Key::Key9] = state,
|
||||
0x01E => window.keys[Key::A] = state,
|
||||
0x030 => window.keys[Key::B] = state,
|
||||
0x02E => window.keys[Key::C] = state,
|
||||
0x020 => window.keys[Key::D] = state,
|
||||
0x012 => window.keys[Key::E] = state,
|
||||
0x021 => window.keys[Key::F] = state,
|
||||
0x022 => window.keys[Key::G] = state,
|
||||
0x023 => window.keys[Key::H] = state,
|
||||
0x017 => window.keys[Key::I] = state,
|
||||
0x024 => window.keys[Key::J] = state,
|
||||
0x025 => window.keys[Key::K] = state,
|
||||
0x026 => window.keys[Key::L] = state,
|
||||
0x032 => window.keys[Key::M] = state,
|
||||
0x031 => window.keys[Key::N] = state,
|
||||
0x018 => window.keys[Key::O] = state,
|
||||
0x019 => window.keys[Key::P] = state,
|
||||
0x010 => window.keys[Key::Q] = state,
|
||||
0x013 => window.keys[Key::R] = state,
|
||||
0x01F => window.keys[Key::S] = state,
|
||||
0x014 => window.keys[Key::T] = state,
|
||||
0x016 => window.keys[Key::U] = state,
|
||||
0x02F => window.keys[Key::V] = state,
|
||||
0x011 => window.keys[Key::W] = state,
|
||||
0x02D => window.keys[Key::X] = state,
|
||||
0x015 => window.keys[Key::Y] = state,
|
||||
0x02C => window.keys[Key::Z] = state,
|
||||
0x03B => window.keys[Key::F1] = state,
|
||||
0x03C => window.keys[Key::F2] = state,
|
||||
0x03D => window.keys[Key::F3] = state,
|
||||
0x03E => window.keys[Key::F4] = state,
|
||||
0x03F => window.keys[Key::F5] = state,
|
||||
0x040 => window.keys[Key::F6] = state,
|
||||
0x041 => window.keys[Key::F7] = state,
|
||||
0x042 => window.keys[Key::F8] = state,
|
||||
0x043 => window.keys[Key::F9] = state,
|
||||
0x042 => window.keys[Key::F8] = state,
|
||||
0x043 => window.keys[Key::F9] = state,
|
||||
0x044 => window.keys[Key::F10] = state,
|
||||
0x057 => window.keys[Key::F11] = state,
|
||||
0x058 => window.keys[Key::F12] = state,
|
||||
0x150 => window.keys[Key::Down] = state,
|
||||
0x14B => window.keys[Key::Left] = state,
|
||||
0x14D => window.keys[Key::Right] = state,
|
||||
0x148 => window.keys[Key::Up] = state,
|
||||
0x028 => window.keys[Key::Apostrophe] = state,
|
||||
0x02B => window.keys[Key::Backslash] = state,
|
||||
0x033 => window.keys[Key::Comma] = state,
|
||||
0x00D => window.keys[Key::Equal] = state,
|
||||
0x01A => window.keys[Key::LeftBracket] = state,
|
||||
0x00C => window.keys[Key::Minus] = state,
|
||||
0x034 => window.keys[Key::Period] = state,
|
||||
0x01B => window.keys[Key::RightBracket] = state,
|
||||
0x027 => window.keys[Key::Semicolon] = state,
|
||||
0x035 => window.keys[Key::Slash] = state,
|
||||
0x00E => window.keys[Key::Backspace] = state,
|
||||
0x153 => window.keys[Key::Delete] = state,
|
||||
0x14F => window.keys[Key::End] = state,
|
||||
0x01C => window.keys[Key::Enter] = state,
|
||||
0x001 => window.keys[Key::Escape] = state,
|
||||
0x147 => window.keys[Key::Home] = state,
|
||||
0x152 => window.keys[Key::Insert] = state,
|
||||
0x15D => window.keys[Key::Menu] = state,
|
||||
0x151 => window.keys[Key::PageDown] = state,
|
||||
0x149 => window.keys[Key::PageUp] = state,
|
||||
0x045 => window.keys[Key::Pause] = state,
|
||||
0x039 => window.keys[Key::Space] = state,
|
||||
0x00F => window.keys[Key::Tab] = state,
|
||||
0x03A => window.keys[Key::CapsLock] = state,
|
||||
0x00B => window.keys[Key::Key0 as usize] = state,
|
||||
0x002 => window.keys[Key::Key1 as usize] = state,
|
||||
0x003 => window.keys[Key::Key2 as usize] = state,
|
||||
0x004 => window.keys[Key::Key3 as usize] = state,
|
||||
0x005 => window.keys[Key::Key4 as usize] = state,
|
||||
0x006 => window.keys[Key::Key5 as usize] = state,
|
||||
0x007 => window.keys[Key::Key6 as usize] = state,
|
||||
0x008 => window.keys[Key::Key7 as usize] = state,
|
||||
0x009 => window.keys[Key::Key8 as usize] = state,
|
||||
0x00A => window.keys[Key::Key9 as usize] = state,
|
||||
0x01E => window.keys[Key::A as usize] = state,
|
||||
0x030 => window.keys[Key::B as usize] = state,
|
||||
0x02E => window.keys[Key::C as usize] = state,
|
||||
0x020 => window.keys[Key::D as usize] = state,
|
||||
0x012 => window.keys[Key::E as usize] = state,
|
||||
0x021 => window.keys[Key::F as usize] = state,
|
||||
0x022 => window.keys[Key::G as usize] = state,
|
||||
0x023 => window.keys[Key::H as usize] = state,
|
||||
0x017 => window.keys[Key::I as usize] = state,
|
||||
0x024 => window.keys[Key::J as usize] = state,
|
||||
0x025 => window.keys[Key::K as usize] = state,
|
||||
0x026 => window.keys[Key::L as usize] = state,
|
||||
0x032 => window.keys[Key::M as usize] = state,
|
||||
0x031 => window.keys[Key::N as usize] = state,
|
||||
0x018 => window.keys[Key::O as usize] = state,
|
||||
0x019 => window.keys[Key::P as usize] = state,
|
||||
0x010 => window.keys[Key::Q as usize] = state,
|
||||
0x013 => window.keys[Key::R as usize] = state,
|
||||
0x01F => window.keys[Key::S as usize] = state,
|
||||
0x014 => window.keys[Key::T as usize] = state,
|
||||
0x016 => window.keys[Key::U as usize] = state,
|
||||
0x02F => window.keys[Key::V as usize] = state,
|
||||
0x011 => window.keys[Key::W as usize] = state,
|
||||
0x02D => window.keys[Key::X as usize] = state,
|
||||
0x015 => window.keys[Key::Y as usize] = state,
|
||||
0x02C => window.keys[Key::Z as usize] = state,
|
||||
0x03B => window.keys[Key::F1 as usize] = state,
|
||||
0x03C => window.keys[Key::F2 as usize] = state,
|
||||
0x03D => window.keys[Key::F3 as usize] = state,
|
||||
0x03E => window.keys[Key::F4 as usize] = state,
|
||||
0x03F => window.keys[Key::F5 as usize] = state,
|
||||
0x040 => window.keys[Key::F6 as usize] = state,
|
||||
0x041 => window.keys[Key::F7 as usize] = state,
|
||||
0x042 => window.keys[Key::F8 as usize] = state,
|
||||
0x043 => window.keys[Key::F9 as usize] = state,
|
||||
0x044 => window.keys[Key::F10 as usize] = state,
|
||||
0x057 => window.keys[Key::F11 as usize] = state,
|
||||
0x058 => window.keys[Key::F12 as usize] = state,
|
||||
0x150 => window.keys[Key::Down as usize] = state,
|
||||
0x14B => window.keys[Key::Left as usize] = state,
|
||||
0x14D => window.keys[Key::Right as usize] = state,
|
||||
0x148 => window.keys[Key::Up as usize] = state,
|
||||
0x028 => window.keys[Key::Apostrophe as usize] = state,
|
||||
0x02B => window.keys[Key::Backslash as usize] = state,
|
||||
0x033 => window.keys[Key::Comma as usize] = state,
|
||||
0x00D => window.keys[Key::Equal as usize] = state,
|
||||
0x01A => window.keys[Key::LeftBracket as usize] = state,
|
||||
0x00C => window.keys[Key::Minus as usize] = state,
|
||||
0x034 => window.keys[Key::Period as usize] = state,
|
||||
0x01B => window.keys[Key::RightBracket as usize] = state,
|
||||
0x027 => window.keys[Key::Semicolon as usize] = state,
|
||||
0x035 => window.keys[Key::Slash as usize] = state,
|
||||
0x00E => window.keys[Key::Backspace as usize] = state,
|
||||
0x153 => window.keys[Key::Delete as usize] = state,
|
||||
0x14F => window.keys[Key::End as usize] = state,
|
||||
0x01C => window.keys[Key::Enter as usize] = state,
|
||||
0x001 => window.keys[Key::Escape as usize] = state,
|
||||
0x147 => window.keys[Key::Home as usize] = state,
|
||||
0x152 => window.keys[Key::Insert as usize] = state,
|
||||
0x15D => window.keys[Key::Menu as usize] = state,
|
||||
0x151 => window.keys[Key::PageDown as usize] = state,
|
||||
0x149 => window.keys[Key::PageUp as usize] = state,
|
||||
0x045 => window.keys[Key::Pause as usize] = state,
|
||||
0x039 => window.keys[Key::Space as usize] = state,
|
||||
0x00F => window.keys[Key::Tab as usize] = state,
|
||||
0x03A => window.keys[Key::CapsLock as usize] = state,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,21 +126,22 @@ unsafe extern "system" fn wnd_proc(window: winapi::HWND,
|
|||
|
||||
let user_data = user32::GetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA);
|
||||
|
||||
if user_data == 0
|
||||
if user_data == 0 {
|
||||
return user32::DefWindowProcW(window, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
let mut self = user_data as &mut Window;
|
||||
let mut wnd: &mut Window = mem::transmute(user_data);
|
||||
|
||||
match msg {
|
||||
winapi::winuser::WM_KEYDOWN => {
|
||||
update_key_state(self, wparam as u32, true);
|
||||
update_key_state(wnd, (lparam as u32) >> 16, true);
|
||||
if (wparam & 0x1ff) == 27 {
|
||||
CLOSE_APP = true;
|
||||
}
|
||||
}
|
||||
|
||||
winapi::winuser::WM_KEYUP => {
|
||||
update_key_state(self, wparam as u32, false);
|
||||
update_key_state(wnd, (lparam as u32) >> 16, false);
|
||||
}
|
||||
|
||||
winapi::winuser::WM_PAINT => {
|
||||
|
@ -160,7 +163,7 @@ unsafe extern "system" fn wnd_proc(window: winapi::HWND,
|
|||
bitmap_info.bmi_colors[1].rgbGreen = 0xff;
|
||||
bitmap_info.bmi_colors[2].rgbBlue = 0xff;
|
||||
|
||||
gdi32::StretchDIBits(self.dc,
|
||||
gdi32::StretchDIBits(wnd.dc.unwrap(),
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
|
@ -169,7 +172,7 @@ unsafe extern "system" fn wnd_proc(window: winapi::HWND,
|
|||
0,
|
||||
width,
|
||||
height,
|
||||
mem::transmute(self.buffer),
|
||||
mem::transmute(wnd.buffer.as_ptr()),
|
||||
mem::transmute(&bitmap_info),
|
||||
winapi::wingdi::DIB_RGB_COLORS,
|
||||
winapi::wingdi::SRCCOPY);
|
||||
|
@ -193,14 +196,14 @@ fn to_wstring(str: &str) -> *const u16 {
|
|||
}
|
||||
|
||||
pub struct Window {
|
||||
dc: DC,
|
||||
window: HWND,
|
||||
bool keys_down: [bool; 512],
|
||||
buffer: &[u32],
|
||||
dc: Option<HDC>,
|
||||
window: Option<HWND>,
|
||||
keys: [bool; 512],
|
||||
buffer: Vec<u32>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
fn open_window(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> Result<Window, &str> {
|
||||
fn open_window(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> HWND {
|
||||
unsafe {
|
||||
let class_name = to_wstring("minifb_window");
|
||||
let s = CString::new(name).unwrap();
|
||||
|
@ -253,26 +256,39 @@ impl Window {
|
|||
user32::ShowWindow(handle, winapi::SW_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(name: &str, width: usize, height: usize) -> Option<Minifb> {
|
||||
let handle = Minifb::open_window(name, width, height);
|
||||
pub fn new(name: &str, width: usize, height: usize, scale: Scale, vsync: Vsync) -> Result<Window, &str> {
|
||||
unsafe {
|
||||
let handle = Self::open_window(name, width, height, scale, vsync);
|
||||
|
||||
match handle.is_null() {
|
||||
true => None,
|
||||
false => Some(Minifb { window: handle }),
|
||||
if handle.is_null() {
|
||||
return Err("Unable to create Window");
|
||||
}
|
||||
|
||||
let window = Window {
|
||||
dc: Some(user32::GetDC(handle)),
|
||||
window: Some(handle),
|
||||
keys: [false; 512],
|
||||
buffer: Vec::new(),
|
||||
};
|
||||
|
||||
Ok(window)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_keys(&self -> Vec<Key> {
|
||||
let index = 0;
|
||||
pub fn get_keys(&self) -> Vec<Key> {
|
||||
let mut index: u8 = 0;
|
||||
let mut keys: Vec<Key> = Vec::new();
|
||||
|
||||
for i in self.keys {
|
||||
for i in self.keys.iter() {
|
||||
if *i {
|
||||
keys.push(index as Key);
|
||||
unsafe {
|
||||
keys.push(mem::transmute(index));
|
||||
}
|
||||
}
|
||||
|
||||
index += 1;
|
||||
|
@ -284,11 +300,16 @@ impl Window {
|
|||
pub fn update(&mut self, buffer: &[u32]) -> bool {
|
||||
unsafe {
|
||||
let mut msg = mem::uninitialized();
|
||||
let window = self.window.unwrap();
|
||||
|
||||
user32::SetWindowLongPtrW(self.window, winapi::winuser::GWLP_USERDATA, self as i64);
|
||||
user32::InvalidateRect(self.window, ptr::null_mut(), winapi::TRUE);
|
||||
// TODO: Optimize
|
||||
|
||||
while user32::PeekMessageW(&mut msg, self.window, 0, 0, winapi::winuser::PM_REMOVE) != 0 {
|
||||
self.buffer = buffer.iter().cloned().collect();
|
||||
|
||||
user32::SetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA, mem::transmute(self));
|
||||
user32::InvalidateRect(window, ptr::null_mut(), winapi::TRUE);
|
||||
|
||||
while user32::PeekMessageW(&mut msg, window, 0, 0, winapi::winuser::PM_REMOVE) != 0 {
|
||||
user32::TranslateMessage(&mut msg);
|
||||
user32::DispatchMessageW(&mut msg);
|
||||
}
|
||||
|
@ -303,12 +324,12 @@ impl Window {
|
|||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if self.dc.is_valid() {
|
||||
user32::ReleaseDC(self.window, self.dc);
|
||||
if self.dc.is_some() {
|
||||
user32::ReleaseDC(self.window.unwrap(), self.dc.unwrap());
|
||||
}
|
||||
|
||||
if self.hwnd.is_valid() {
|
||||
user32::CloseWindow(self.hwnd);
|
||||
if self.window.is_some() {
|
||||
user32::CloseWindow(self.window.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue