WIP on latest Mac version

This commit is contained in:
Daniel Collin 2015-12-06 19:14:34 +01:00
parent 29e744bc19
commit 99e106fe93
3 changed files with 231 additions and 114 deletions

View file

@ -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;
}
*/
}
}

View file

@ -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();
}
}
*/

View file

@ -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)
}
}