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
use sdl2;
use sdl2::pixels::PixelFormatEnum;

use std::error;

use texture::Texture;
use types::*;


pub trait Screen {
    fn display_texture(&mut self, texture: &Texture)
        -> Result<(), Box<error::Error>>;

    fn width (&self) -> Dimension;
    fn height(&self) -> Dimension;
}


#[allow(dead_code)]
pub struct TextScreen {
    w: Dimension,
    h: Dimension,
}

#[allow(dead_code)]
impl TextScreen {
    pub fn new(_: &str, w: Dimension, h: Dimension) -> TextScreen {
        TextScreen {
            w: w,
            h: h,
        }
    }
}

impl Screen for TextScreen {
    fn display_texture(&mut self, texture: &Texture)
        -> Result<(), Box<error::Error>>
    {
        println!("{}", texture);
        Ok(())
    }

    fn width (&self) -> Dimension { self.w }
    fn height(&self) -> Dimension { self.h }
}


#[allow(dead_code)]
pub struct GraphicalScreen<'a> {
    w: Dimension,
    h: Dimension,
    sdl_renderer: sdl2::render::Renderer<'a>,
    texture: sdl2::render::Texture,
}

#[allow(dead_code)]
impl<'a> GraphicalScreen<'a> {
    pub fn new(
        name: &str,
        w: Dimension,
        h: Dimension,
        sdl_context: &sdl2::Sdl
    )
        -> Result<GraphicalScreen<'a>, Box<error::Error>>
    {
        // Make an sdl2 window and get the renderer.
        let video_subsystem = sdl_context.video()?;
        let window = video_subsystem
            .window(name, w, h)
            .position_centered()
            .opengl()
            .build()?;
        let sdl_renderer = window.renderer().build()?;
        let texture = sdl_renderer
            .create_texture_streaming(PixelFormatEnum::RGB24, w, h)?;

        Ok(GraphicalScreen {
            w: w,
            h: h,
            sdl_renderer: sdl_renderer,
            texture: texture,
        })
    }
}

impl<'a> Screen for GraphicalScreen<'a> {
    fn display_texture(&mut self, texture: &Texture)
        -> Result<(), Box<error::Error>>
    {
        assert!(texture.w == self.w && texture.h == self.h);
        self.texture.with_lock(None, |buf: &mut [u8], _: usize| {
            for i in 0 .. texture.pixels.len() {
                let (r,g,b) = texture.pixels[i];
                buf[3 * i]     = r;
                buf[3 * i + 1] = g;
                buf[3 * i + 2] = b;
            }
        })?;

        self.sdl_renderer.copy(&self.texture, None, None)?;
        self.sdl_renderer.present();
        Ok(())
    }

    fn width (&self) -> Dimension { self.w }
    fn height(&self) -> Dimension { self.h }
}