aboutsummaryrefslogtreecommitdiff
path: root/src/services/gspgpu.rs
blob: 6bd972cda2f9b6014deeadbcbe370c880278bb2c (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
use libctru::services::gspgpu;

use std::convert::From;

pub enum Event {
    Psc0,
    Psc1,
    VBlank0,
    VBlank1,
    PPF,
    P3D,
    DMA,
}

#[derive(Copy, Clone)]
pub enum FramebufferFormat {
    Rgba8,
    Bgr8,
    Rgb565,
    Rgb5A1,
    Rgba4,
}

impl FramebufferFormat {
    pub fn pixel_depth_bytes(&self) -> usize {
        use self::FramebufferFormat::*;
        match *self {
            Rgba8 => 4usize,
            Bgr8 => 3usize,
            Rgb565 => 2usize,
            Rgb5A1 => 2usize,
            Rgba4 => 2usize,
        }
    }
}

impl From<gspgpu::GSPGPU_FramebufferFormats> for FramebufferFormat {
    #[inline]
    fn from(g: gspgpu::GSPGPU_FramebufferFormats) -> FramebufferFormat {
        use libctru::services::gspgpu::GSPGPU_FramebufferFormats::*;
        use self::FramebufferFormat::*;
        match g {
            GSP_RGBA8_OES => Rgba8,
            GSP_BGR8_OES => Bgr8,
            GSP_RGB565_OES => Rgb565,
            GSP_RGB5_A1_OES => Rgb5A1,
            GSP_RGBA4_OES => Rgba4,
        }
    }
}

impl From<FramebufferFormat> for gspgpu::GSPGPU_FramebufferFormats {
    #[inline]
    fn from(g: FramebufferFormat) -> gspgpu::GSPGPU_FramebufferFormats {
        use libctru::services::gspgpu::GSPGPU_FramebufferFormats::*;
        use self::FramebufferFormat::*;
        match g {
            Rgba8 => GSP_RGBA8_OES,
            Bgr8 => GSP_BGR8_OES,
            Rgb565 => GSP_RGB565_OES,
            Rgb5A1 => GSP_RGB5_A1_OES,
            Rgba4 => GSP_RGBA4_OES,
        }
    }
}

fn to_raw_event(ev: Event) -> gspgpu::GSPGPU_Event {
    use libctru::services::gspgpu::GSPGPU_Event::*;
    use self::Event::*;

    match ev {
        Psc0 => GSPGPU_EVENT_PSC0,
        Psc1 => GSPGPU_EVENT_PSC1,
        VBlank0 => GSPGPU_EVENT_VBlank0,
        VBlank1 => GSPGPU_EVENT_VBlank1,
        PPF => GSPGPU_EVENT_PPF,
        P3D => GSPGPU_EVENT_P3D,
        DMA => GSPGPU_EVENT_DMA,
    }
}

/// Sleep until GSP event fires.
///
/// # Examples
///
/// Wait for VBlank.
///
/// ```
/// use ctru::services::apt;
/// apt::main_loop(|| {
///     wait_for_event(Event::VBlank0);
/// });
pub fn wait_for_event(ev: Event) -> () {
    unsafe {
        // TODO second argument?
        gspgpu::gspWaitForEvent(to_raw_event(ev), 0);
    }
}