New version running with keyboard support

This commit is contained in:
Daniel Collin 2015-12-08 22:57:14 +01:00
parent 60e28c4a74
commit d4ca056adc
3 changed files with 180 additions and 166 deletions

View file

@ -6,27 +6,15 @@ const WIDTH: usize = 640;
const HEIGHT: usize = 360;
fn main() {
//let mut noise;
//let mut carry;
//let mut seed = 0xbeefu32;
let mut noise;
let mut carry;
let mut seed = 0xbeefu32;
let mut buffer: [u32; WIDTH * HEIGHT] = [0; WIDTH * HEIGHT];
let window = match macos::Window::new("Noise Test - Press ESC to exit",
WIDTH,
HEIGHT,
Scale::X1,
Vsync::No) {
Ok(window) => window,
Err(info) => {
println!("{}", info);
return;
}
};
let mut window = Window::new("Noise Test - Press ESC to exit", WIDTH, HEIGHT, Scale::X1, Vsync::No).unwrap();
loop {
window.update(&buffer);
/*
while window.update(&buffer) {
for i in buffer.iter_mut() {
noise = seed;
noise >>= 3;
@ -38,6 +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"),
_ => (),
}
}
}
}

View file

@ -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::*;

View file

@ -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);
@ -192,14 +195,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();
@ -252,26 +255,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;
@ -283,11 +299,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);
}
@ -302,12 +323,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());
}
}
}