mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2025-01-09 18:41:32 +11:00
WIP on latest Mac version
This commit is contained in:
parent
29e744bc19
commit
99e106fe93
|
@ -6,15 +6,26 @@ 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 mut buffer: [u32; WIDTH * HEIGHT] = [0; WIDTH * HEIGHT];
|
||||
|
||||
let mut mfb = Minifb::new("Noise Test - Press ESC to exit", WIDTH, HEIGHT).unwrap();
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
while mfb.update(&buffer) {
|
||||
loop {
|
||||
/*
|
||||
for i in buffer.iter_mut() {
|
||||
noise = seed;
|
||||
noise >>= 3;
|
||||
|
@ -26,5 +37,6 @@ fn main() {
|
|||
noise &= 0xFF;
|
||||
*i = (noise << 16) | (noise << 8) | noise;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
197
src/lib.rs
197
src/lib.rs
|
@ -11,20 +11,119 @@ extern crate cocoa;
|
|||
extern crate core_foundation;
|
||||
#[cfg(target_os = "macos")]
|
||||
|
||||
/// Error that can happen while creating a window or a headless renderer.
|
||||
#[derive(Debug)]
|
||||
pub enum CreationError {
|
||||
OsError(String),
|
||||
NotSupported,
|
||||
/// 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
|
||||
/// much higher resolution which would result in that the window is very small.
|
||||
pub enum Scale {
|
||||
/// This mode checks your current screen resolution and will caluclate the largest window size
|
||||
/// that can be used within that limit and resize it. Useful if you have a small buffer to
|
||||
/// display on a high resolution screen.
|
||||
FitScreen,
|
||||
/// 1X scale (which means leave the corrdinates sent into Window::new untouched)
|
||||
X1,
|
||||
/// 2X window scale (Example: 320 x 200 -> 640 x 400)
|
||||
X2,
|
||||
/// 4X window scale (Example: 320 x 200 -> 1280 x 800)
|
||||
X4,
|
||||
/// 8X window scale (Example: 320 x 200 -> 2560 x 1600)
|
||||
X8,
|
||||
/// 16X window scale (Example: 320 x 200 -> 5120 x 3200)
|
||||
X16,
|
||||
/// 32 window scale (Example: 320 x 200 -> 10240 x 6400)
|
||||
X32,
|
||||
}
|
||||
|
||||
impl CreationError {
|
||||
fn to_string(&self) -> &str {
|
||||
match *self {
|
||||
CreationError::OsError(ref text) => &text,
|
||||
CreationError::NotSupported => "Some of the requested attributes are not supported",
|
||||
}
|
||||
}
|
||||
/// Vsync will allow syncronized rendering with the screen refresh rate.
|
||||
pub enum Vsync {
|
||||
/// No vsync
|
||||
No,
|
||||
/// Require accurate vsync. Notice that if the library is unable to to setup an accurate
|
||||
/// syncing the window creation will fail.
|
||||
Accurate,
|
||||
/// Setup a best guess syncing with the screen. This will always succesed but may not be
|
||||
/// accurate. What this means is if the lib is unable to create a accurate syncing approach
|
||||
/// a 'emulated' one will be used (for example using a timer to approximate syncing)
|
||||
BestGuess,
|
||||
}
|
||||
|
||||
///
|
||||
pub enum Key {
|
||||
Space,
|
||||
/// The '1' key over the letters.
|
||||
Key1,
|
||||
/// The '2' key over the letters.
|
||||
Key2,
|
||||
/// The '3' key over the letters.
|
||||
Key3,
|
||||
/// The '4' key over the letters.
|
||||
Key4,
|
||||
/// The '5' key over the letters.
|
||||
Key5,
|
||||
/// The '6' key over the letters.
|
||||
Key6,
|
||||
/// The '7' key over the letters.
|
||||
Key7,
|
||||
/// The '8' key over the letters.
|
||||
Key8,
|
||||
/// The '9' key over the letters.
|
||||
Key9,
|
||||
/// The '0' key over the 'O' and 'P' keys.
|
||||
Key0,
|
||||
|
||||
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,
|
||||
|
||||
Escape,
|
||||
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
F13,
|
||||
F14,
|
||||
F15,
|
||||
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
ArrowUp,
|
||||
ArrowDown,
|
||||
|
||||
Backspace,
|
||||
Delete,
|
||||
Comma,
|
||||
Semicollon
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -38,77 +137,3 @@ pub mod macos;
|
|||
pub use macos::*;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link(name = "Cocoa", kind = "framework")]
|
||||
extern {
|
||||
fn mfb_open(name: *const c_char, width: c_int, height: c_int) -> c_int;
|
||||
fn mfb_update(buffer: *mut c_void) -> c_int;
|
||||
fn mfb_close();
|
||||
}
|
||||
|
||||
/*
|
||||
#[cfg(target_os = "windows")]
|
||||
#[link(name = "gdi32")]
|
||||
extern {
|
||||
fn mfb_open(name: *const c_char, width: c_int, height: c_int) -> c_int;
|
||||
fn mfb_update(buffer: *mut c_void) -> c_int;
|
||||
fn mfb_close();
|
||||
}
|
||||
*/
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[link(name = "X11")]
|
||||
extern {
|
||||
fn mfb_open(name: *const c_char, width: c_int, height: c_int) -> c_int;
|
||||
fn mfb_update(buffer: *mut c_void) -> c_int;
|
||||
fn mfb_close();
|
||||
}
|
||||
|
||||
///
|
||||
/// Open up a window
|
||||
///
|
||||
#[cfg(any(target_os = "linux", target_os = "mac"))]
|
||||
pub fn open(name: &str, width: usize, height: usize) -> bool {
|
||||
let s = CString::new(name).unwrap();
|
||||
let ret;
|
||||
|
||||
unsafe {
|
||||
ret = mfb_open(s.as_ptr(), width as c_int, height as c_int);
|
||||
}
|
||||
|
||||
match ret {
|
||||
0 => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Update
|
||||
///
|
||||
#[cfg(any(target_os = "linux", target_os = "mac"))]
|
||||
pub fn update(buffer: &[u32]) -> bool {
|
||||
let ret;
|
||||
unsafe {
|
||||
ret = mfb_update(transmute(buffer.as_ptr()));
|
||||
}
|
||||
|
||||
if ret < 0 {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Close
|
||||
///
|
||||
#[cfg(any(target_os = "linux", target_os = "mac"))]
|
||||
pub fn close() {
|
||||
unsafe {
|
||||
mfb_close();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
124
src/macos.rs
124
src/macos.rs
|
@ -1,36 +1,69 @@
|
|||
#![cfg(target_os = "macos")]
|
||||
|
||||
use CreationError;
|
||||
use CreationError::OsError;
|
||||
use Scale;
|
||||
use Vsync;
|
||||
use Key;
|
||||
|
||||
use libc;
|
||||
use cocoa::appkit;
|
||||
//use libc;
|
||||
//use cocoa::appkit;
|
||||
use cocoa::appkit::*;
|
||||
use cocoa::appkit::NSEventSubtype::*;
|
||||
//use cocoa::appkit::NSEventSubtype::*;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use cocoa::base::{id, nil};
|
||||
#[allow(unused_imports)]
|
||||
use objc::runtime::{Class, Object, Sel, BOOL, YES, NO};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use cocoa::foundation::{NSAutoreleasePool, NSDate, NSDefaultRunLoopMode, NSPoint, NSRect, NSSize,
|
||||
NSString, NSUInteger};
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
struct Minifb {
|
||||
temp: isize,
|
||||
pub struct Window {
|
||||
view: IdRef,
|
||||
window: IdRef,
|
||||
}
|
||||
|
||||
impl Minifb {
|
||||
pub unsafe fn new(name: &str, width: isize, height: isize) -> Result<Minifb, CreationError> {
|
||||
let app = match Self::create_app() {
|
||||
Some(app) => app,
|
||||
None => { return Err(OsError(format!("Couldn't create NSApplication"))); },
|
||||
};
|
||||
impl Window {
|
||||
pub fn new(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> Result<Window, &str> {
|
||||
unsafe {
|
||||
let app = match Self::create_app() {
|
||||
Some(app) => app,
|
||||
None => {
|
||||
return Err("Couldn't create NSApplication");
|
||||
},
|
||||
};
|
||||
|
||||
let masks = 0u64;
|
||||
let window = match Self::create_window(name, width, height) {
|
||||
Some(window) => window,
|
||||
None => {
|
||||
return Err("Unable to create NSWindow");
|
||||
}
|
||||
};
|
||||
|
||||
//let masks = NSResizableWindowMask as NSUInteger |
|
||||
// NSClosableWindowMask as NSUInteger |
|
||||
// NSTitledWindowMaskas as NSUInteger;
|
||||
let view = match Self::create_view(*window) {
|
||||
Some(view) => view,
|
||||
None => {
|
||||
return Err("Unable to create NSView");
|
||||
}
|
||||
};
|
||||
|
||||
app.activateIgnoringOtherApps_(YES);
|
||||
|
||||
println!("Created window and view");
|
||||
|
||||
return Ok(Window {
|
||||
window: window,
|
||||
view: view
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn create_window(name: &str, width: usize, height: usize) -> Option<IdRef> {
|
||||
let masks = NSResizableWindowMask as NSUInteger |
|
||||
NSClosableWindowMask as NSUInteger |
|
||||
NSTitledWindowMask as NSUInteger;
|
||||
|
||||
let frame = NSRect::new(NSPoint::new(0., 0.), NSSize::new(width as f64, height as f64));
|
||||
|
||||
|
@ -41,9 +74,34 @@ impl Minifb {
|
|||
NO,
|
||||
));
|
||||
|
||||
if window.is_nil() {
|
||||
return Err(OsError(format!("Unable to create window")));
|
||||
}
|
||||
window.non_nil().map(|window| {
|
||||
let title = IdRef::new(NSString::alloc(nil).init_str(name));
|
||||
window.setTitle_(*title);
|
||||
window.center();
|
||||
window
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn create_view(window: id) -> Option<IdRef> {
|
||||
let view = IdRef::new(NSView::alloc(nil).init());
|
||||
view.non_nil().map(|view| {
|
||||
window.setContentView_(*view);
|
||||
view
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(_: &[u32]) {
|
||||
}
|
||||
|
||||
pub fn get_keys() -> Option<Vec<Key>> {
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn is_esc_pressed() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn close() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -58,10 +116,10 @@ impl Minifb {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct IdRef(id);
|
||||
|
||||
impl IdRef {
|
||||
|
@ -82,4 +140,26 @@ impl IdRef {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for IdRef {
|
||||
fn drop(&mut self) {
|
||||
if self.0 != nil {
|
||||
let _: () = unsafe { msg_send![self.0, release] };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for IdRef {
|
||||
type Target = id;
|
||||
fn deref<'a>(&'a self) -> &'a id {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for IdRef {
|
||||
fn clone(&self) -> IdRef {
|
||||
if self.0 != nil {
|
||||
let _: id = unsafe { msg_send![self.0, retain] };
|
||||
}
|
||||
IdRef(self.0)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue