Moved rendering to ActiveState
[kaka/rust-sdl-test.git] / src / game / app.rs
index 0ec34ee..f6adba0 100644 (file)
@@ -2,21 +2,17 @@ use boll::*;
 use common::{Point2D, Rect};
 use point; // defined in common, but loaded from main...
 use rand::Rng;
-use sdl2::event::Event;
-use sdl2::event::WindowEvent;
+use sdl2::event::{Event, WindowEvent};
 use sdl2::gfx::primitives::DrawRenderer;
 use sdl2::keyboard::Keycode;
 use sdl2::pixels::Color;
 use sdl2::rect::Rect as SDLRect;
-use sdl2::render::BlendMode;
-use sdl2::render::Canvas;
-use sdl2::video::FullscreenType;
-use sdl2::video::{SwapInterval, Window};
+use sdl2::render::{BlendMode, Canvas};
+use sdl2::video::{FullscreenType, SwapInterval, Window};
 use sdl2::{EventPump, VideoSubsystem};
 use sprites::SpriteManager;
 use std::f32::consts::PI;
 use time::PreciseTime;
-use {SCREEN_HEIGHT, SCREEN_WIDTH};
 
 pub type Nanoseconds = u64;
 
@@ -77,12 +73,13 @@ impl AppBuilder {
 
         let event_pump = context.event_pump()?;
         let sprites = SpriteManager::new(canvas.texture_creator());
+       let screen = canvas.output_size().unwrap();
 
         Ok(App {
             canvas,
             event_pump,
             sprites,
-            state: self.state.unwrap_or_else(|| Box::new(ActiveState::new())),
+            state: self.state.unwrap_or_else(|| Box::new(ActiveState::new(screen))),
         })
     }
 
@@ -107,15 +104,18 @@ impl AppBuilder {
                 " desktop_display_mode: {:?}",
                 video.desktop_display_mode(display).unwrap()
             );
+           let current = video.current_display_mode(display).unwrap();
             println!(
                 " current_display_mode: {:?}",
-                video.current_display_mode(display).unwrap()
+                current
             );
-            for mode in 0..video.num_display_modes(display).unwrap() {
+            for idx in 0..video.num_display_modes(display).unwrap() {
+               let mode = video.display_mode(display, idx).unwrap();
                 println!(
-                    "  {:2}: {:?}",
-                    mode,
-                    video.display_mode(display, mode).unwrap()
+                    " {}{:2}: {:?}",
+                   if mode == current { "*" } else { " " },
+                    idx,
+                    mode
                 );
             }
         }
@@ -147,186 +147,17 @@ impl App {
         let mut fps_time = PreciseTime::now();
         let mut last_time = PreciseTime::now();
 
-        let mut mario_angle = 0.0;
-
         'running: loop {
-            self.canvas.set_draw_color(Color::RGB(0, 0, 0));
-            self.canvas.clear();
-            {
-                let blocks = 20;
-                let size = 32;
-                let offset = point!(
-                    (SCREEN_WIDTH as i32 - (blocks + 1) * size) / 2,
-                    (SCREEN_HEIGHT as i32 - (blocks + 1) * size) / 2
-                );
-                let block = self.sprites.get("block");
-                for i in 0..blocks {
-                    self.canvas
-                        .copy(
-                            block,
-                            None,
-                            SDLRect::new((i) * size + offset.x, offset.y, size as u32, size as u32),
-                        )
-                        .unwrap();
-                    self.canvas
-                        .copy(
-                            block,
-                            None,
-                            SDLRect::new(
-                                (blocks - i) * size + offset.x,
-                                (blocks) * size + offset.y,
-                                size as u32,
-                                size as u32,
-                            ),
-                        )
-                        .unwrap();
-                    self.canvas
-                        .copy(
-                            block,
-                            None,
-                            SDLRect::new(
-                                offset.x,
-                                (blocks - i) * size + offset.y,
-                                size as u32,
-                                size as u32,
-                            ),
-                        )
-                        .unwrap();
-                    self.canvas
-                        .copy(
-                            block,
-                            None,
-                            SDLRect::new(
-                                (blocks) * size + offset.x,
-                                (i) * size + offset.y,
-                                size as u32,
-                                size as u32,
-                            ),
-                        )
-                        .unwrap();
-                }
-            }
-            {
-                let size = 64;
-                let offset = point!(
-                    (SCREEN_WIDTH as i32 - size) / 2,
-                    (SCREEN_HEIGHT as i32 - size) / 2
-                );
-                let radius = 110.0 + size as f32 * 0.5;
-                let angle = (mario_angle as f32 - 90.0) * PI / 180.0;
-                let offset2 = point!((angle.cos() * radius) as i32, (angle.sin() * radius) as i32);
-                self.canvas
-                    .copy_ex(
-                        self.sprites.get("mario"),
-                        None,
-                        SDLRect::new(
-                            offset.x + offset2.x,
-                            offset.y + offset2.y,
-                            size as u32,
-                            size as u32,
-                        ),
-                        mario_angle,
-                        sdl2::rect::Point::new(size / 2, size / 2),
-                        false,
-                        false,
-                    )
-                    .unwrap();
-                mario_angle += 1.0;
-                if mario_angle >= 360.0 {
-                    mario_angle -= 360.0
-                }
-            }
-            {
-                let p = point!((SCREEN_WIDTH / 2) as i16, (SCREEN_HEIGHT / 2) as i16);
-                self.canvas
-                    .circle(p.x, p.y, 100, Color::RGB(255, 255, 255))
-                    .unwrap();
-                self.canvas
-                    .aa_circle(p.x, p.y, 110, Color::RGB(255, 255, 255))
-                    .unwrap();
-                self.canvas
-                    .ellipse(p.x, p.y, 50, 100, Color::RGB(255, 255, 255))
-                    .unwrap();
-                self.canvas
-                    .aa_ellipse(p.x, p.y, 110, 55, Color::RGB(255, 255, 255))
-                    .unwrap();
-            }
-
-            //        window.gl_swap_window();
-            for event in self.event_pump.poll_iter() {
-                match event {
-                    Event::Quit { .. }
-                    | Event::KeyDown {
-                        keycode: Some(Keycode::Escape),
-                        ..
-                    } => {
-                        break 'running;
-                    }
-                    Event::KeyDown {
-                        keycode: Some(Keycode::F11),
-                        ..
-                    } => {
-                        match self.canvas.window().fullscreen_state() {
-                            FullscreenType::Off => self
-                                .canvas
-                                .window_mut()
-                                .set_fullscreen(FullscreenType::Desktop),
-                            _ => self.canvas.window_mut().set_fullscreen(FullscreenType::Off),
-                        }
-                        .unwrap();
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::Resized(x, y),
-                        ..
-                    } => {
-                        println!("window resized({}, {})", x, y)
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::Maximized,
-                        ..
-                    } => {
-                        println!("window maximized")
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::Restored,
-                        ..
-                    } => {
-                        println!("window restored")
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::Enter,
-                        ..
-                    } => {
-                        println!("window enter")
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::Leave,
-                        ..
-                    } => {
-                        println!("window leave")
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::FocusGained,
-                        ..
-                    } => {
-                        println!("window focus gained")
-                    }
-                    Event::Window {
-                        win_event: WindowEvent::FocusLost,
-                        ..
-                    } => {
-                        println!("window focus lost")
-                    }
-                    _ => self.state.on_event(event),
-                }
-            }
+           if let Err(_) = self.handle_events() {
+               break 'running;
+           }
 
             let duration =
                 last_time.to(PreciseTime::now()).num_nanoseconds().unwrap() as Nanoseconds;
             last_time = PreciseTime::now();
             self.state.update(duration);
-            self.state.render(&mut self.canvas);
-            self.canvas.present();
+
+           self.render();
 
             frame_count += 1;
             if frame_count == FPS as u64 {
@@ -340,27 +171,110 @@ impl App {
 
         self.state.leave();
     }
+
+    fn handle_events(&mut self) -> Result<(), ()> {
+        for event in self.event_pump.poll_iter() {
+            match event {
+                Event::Quit { .. }
+                | Event::KeyDown {
+                    keycode: Some(Keycode::Escape),
+                    ..
+                } => {
+                   return Err(())
+                }
+                Event::KeyDown {
+                    keycode: Some(Keycode::F11),
+                    ..
+                } => {
+                    match self.canvas.window().fullscreen_state() {
+                        FullscreenType::Off => self
+                            .canvas
+                            .window_mut()
+                            .set_fullscreen(FullscreenType::Desktop),
+                        _ => self.canvas.window_mut().set_fullscreen(FullscreenType::Off),
+                    }
+                    .unwrap();
+                }
+                Event::Window {
+                    win_event: WindowEvent::Resized(x, y),
+                    ..
+                } => {
+                    println!("window resized({}, {})", x, y)
+                }
+                Event::Window {
+                    win_event: WindowEvent::Maximized,
+                    ..
+                } => {
+                    println!("window maximized")
+                }
+                Event::Window {
+                    win_event: WindowEvent::Restored,
+                    ..
+                } => {
+                    println!("window restored")
+                }
+                Event::Window {
+                    win_event: WindowEvent::Enter,
+                    ..
+                } => {
+                    println!("window enter")
+                }
+                Event::Window {
+                    win_event: WindowEvent::Leave,
+                    ..
+                } => {
+                    println!("window leave")
+                }
+                Event::Window {
+                    win_event: WindowEvent::FocusGained,
+                    ..
+                } => {
+                    println!("window focus gained")
+                }
+                Event::Window {
+                    win_event: WindowEvent::FocusLost,
+                    ..
+                } => {
+                    println!("window focus lost")
+                }
+                _ => self.state.on_event(event),
+            }
+        }
+       Ok(())
+    }
+
+    fn render(&mut self) {
+        self.canvas.set_draw_color(Color::RGB(0, 0, 0));
+        self.canvas.clear();
+        self.state.render(&mut self.canvas, &mut self.sprites);
+        self.canvas.present();
+    }
 }
 
 pub trait AppState {
     fn update(&mut self, dt: Nanoseconds);
-    fn render(&self, canvas: &mut Canvas<Window>);
+    fn render(&mut self, canvas: &mut Canvas<Window>, sprites: &mut SpriteManager);
     fn leave(&self);
     fn on_event(&mut self, event: Event);
 }
 
 type Bollar = Vec<Box<dyn Boll>>;
 
+#[derive(Default)]
 pub struct ActiveState {
+    screen: Rect<u32>,
     bolls: Bollar,
     boll_size: u32,
+    mario_angle: f64,
 }
 
 impl ActiveState {
-    pub fn new() -> ActiveState {
+    pub fn new(screen: (u32, u32)) -> ActiveState {
         ActiveState {
             bolls: Bollar::new(),
             boll_size: 1,
+           screen: Rect::from(screen),
+           ..Default::default()
         }
     }
 
@@ -381,8 +295,8 @@ impl ActiveState {
         let mut rng = rand::thread_rng();
         self.bolls.push(Box::new(SquareBoll {
             pos: point!(
-                rng.gen_range(0, SCREEN_WIDTH) as f64,
-                rng.gen_range(0, SCREEN_HEIGHT) as f64
+                rng.gen_range(0, self.screen.width) as f64,
+                rng.gen_range(0, self.screen.height) as f64
             ),
             vel: point!(rng.gen_range(-2.0, 2.0), rng.gen_range(-2.0, 2.0)),
         }));
@@ -402,7 +316,106 @@ impl AppState for ActiveState {
         }
     }
 
-    fn render(&self, canvas: &mut Canvas<Window>) {
+    fn render(&mut self, canvas: &mut Canvas<Window>, sprites: &mut SpriteManager) {
+        /* draw square of blocks */ {
+            let blocks = 20;
+            let size = 32;
+            let offset = point!(
+                (self.screen.width as i32 - (blocks + 1) * size) / 2,
+                (self.screen.height as i32 - (blocks + 1) * size) / 2
+            );
+            let block = sprites.get("block");
+            for i in 0..blocks {
+                canvas
+                    .copy(
+                        block,
+                        None,
+                        SDLRect::new((i) * size + offset.x, offset.y, size as u32, size as u32),
+                    )
+                    .unwrap();
+                canvas
+                    .copy(
+                        block,
+                        None,
+                        SDLRect::new(
+                            (blocks - i) * size + offset.x,
+                            (blocks) * size + offset.y,
+                            size as u32,
+                            size as u32,
+                        ),
+                    )
+                    .unwrap();
+                canvas
+                    .copy(
+                        block,
+                        None,
+                        SDLRect::new(
+                            offset.x,
+                            (blocks - i) * size + offset.y,
+                            size as u32,
+                            size as u32,
+                        ),
+                    )
+                    .unwrap();
+                canvas
+                    .copy(
+                        block,
+                        None,
+                        SDLRect::new(
+                            (blocks) * size + offset.x,
+                            (i) * size + offset.y,
+                            size as u32,
+                            size as u32,
+                        ),
+                    )
+                    .unwrap();
+            }
+        }
+
+        /* draw mario */ {
+            let size = 64;
+            let offset = point!(
+                (self.screen.width as i32 - size) / 2,
+                (self.screen.height as i32 - size) / 2
+            );
+            let radius = 110.0 + size as f32 * 0.5;
+            let angle = (self.mario_angle as f32 - 90.0) * PI / 180.0;
+            let offset2 = point!((angle.cos() * radius) as i32, (angle.sin() * radius) as i32);
+            canvas
+                .copy_ex(
+                    sprites.get("mario"),
+                    None,
+                    SDLRect::new(
+                        offset.x + offset2.x,
+                        offset.y + offset2.y,
+                        size as u32,
+                        size as u32,
+                    ),
+                    self.mario_angle,
+                    sdl2::rect::Point::new(size / 2, size / 2),
+                    false,
+                    false,
+                )
+                .unwrap();
+           self.mario_angle = (self.mario_angle + 1.0) % 360.0;
+        }
+
+        /* draw circles and ellipses*/ {
+            let p = point!((self.screen.width / 2) as i16, (self.screen.height / 2) as i16);
+            canvas
+                .circle(p.x, p.y, 100, Color::RGB(255, 255, 255))
+                .unwrap();
+            canvas
+                .aa_circle(p.x, p.y, 110, Color::RGB(255, 255, 255))
+                .unwrap();
+            canvas
+                .ellipse(p.x, p.y, 50, 100, Color::RGB(255, 255, 255))
+                .unwrap();
+            canvas
+                .aa_ellipse(p.x, p.y, 110, 55, Color::RGB(255, 255, 255))
+                .unwrap();
+        }
+
         for b in &self.bolls {
             b.draw(canvas, self.boll_size);
         }