aboutsummaryrefslogtreecommitdiff
path: root/src/gfx.rs
blob: 316c173f468db3accd506345f82ba977d8d5997b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use ::raw::gfx;

use core::default::Default;
use core::marker::PhantomData;
use core::ops::Drop;

use ::services::gsp::FramebufferFormat;

pub struct Gfx {
    // we do this to prevent people from making a Gfx struct manually
    pd: PhantomData<i32>
}

#[derive(Copy, Clone)]
pub enum Screen {
    Top,
    Bottom
}

#[derive(Copy, Clone)]
pub enum Side {
    Left,
    Right
}

impl From<gfx::gfxScreen_t> for Screen {
    #[inline] fn from(g: gfx::gfxScreen_t) -> Screen {
        use ::raw::gfx::gfxScreen_t::*;
        use self::Screen::*;
        match g {
            GFX_TOP => Top,
            GFX_BOTTOM => Bottom
        }
    }
}

impl From<Screen> for gfx::gfxScreen_t {
    #[inline] fn from(g: Screen) -> gfx::gfxScreen_t {
        use ::raw::gfx::gfxScreen_t::*;
        use self::Screen::*;
        match g {
            Top => GFX_TOP,
            Bottom => GFX_BOTTOM
        }
    }
}

impl From<gfx::gfx3dSide_t> for Side {
    #[inline] fn from(s: gfx::gfx3dSide_t) -> Side {
        use ::raw::gfx::gfx3dSide_t::*;
        use self::Side::*;
        match s {
            GFX_LEFT => Left,
            GFX_RIGHT => Right
        }
    }
}

impl From<Side> for gfx::gfx3dSide_t {
    #[inline] fn from(s: Side) -> gfx::gfx3dSide_t {
        use ::raw::gfx::gfx3dSide_t::*;
        use self::Side::*;
        match s {
            Left => GFX_LEFT,
            Right => GFX_RIGHT
        }
    }
}

impl Gfx {
    pub fn set_3d_enabled(&mut self, enabled: bool) {
        unsafe {
            gfx::gfxSet3D(match enabled { true => 1u8, false => 0u8 });
        }
    }

    pub fn get_framebuffer(& mut self, screen: Screen, side: Side) -> (&'static mut [u8], u16, u16) {
        use core::convert::Into;
        unsafe {
            use core::slice::from_raw_parts_mut;

            let mut w: u16 = 0;
            let mut h: u16 = 0;
            let buf: *mut u8 = gfx::gfxGetFramebuffer(screen.into(), side.into(), &mut w as *mut u16, &mut h as &mut u16);

            let fbfmt = self.get_framebuffer_format(screen);

            (from_raw_parts_mut(buf, (w as usize * h as usize) * fbfmt.pixel_depth_bytes()), w, h)
        }
    }

    pub fn flush_buffers(&mut self) {
        unsafe { gfx::gfxFlushBuffers() };
    }

    pub fn swap_buffers(&mut self) {
        unsafe { gfx::gfxSwapBuffers() };
    }

    pub fn swap_buffers_gpu(&mut self) {
        unsafe { gfx::gfxSwapBuffersGpu() };
    }

    pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat {
        use core::convert::Into;
        unsafe {
            gfx::gfxGetScreenFormat(screen.into()).into()
        }
    }

    pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) {
        use core::convert::Into;
        unsafe {
            gfx::gfxSetScreenFormat(screen.into(), fmt.into())
        }
    }

    pub fn set_double_buffering(&mut self, screen: Screen, enabled: bool) {
        unsafe {
            gfx::gfxSetDoubleBuffering(screen.into(), match enabled { true => 1u8, false => 0u8 })
        };
    }
}

impl Default for Gfx {
    fn default() -> Self {
        unsafe { gfx::gfxInitDefault() };
        Gfx { pd: PhantomData }
    }
}

impl Drop for Gfx {
    fn drop(&mut self) {
        unsafe { gfx::gfxExit() };
    }
}