]> git.seodisparate.com - LudumDare45_StartWithNothing/commitdiff
Work on impl of some of raylib_impl
authorStephen Seo <seo.disparate@gmail.com>
Sun, 19 Feb 2023 07:52:52 +0000 (16:52 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sun, 19 Feb 2023 07:52:52 +0000 (16:52 +0900)
build.rs
src/agnostic_interface.rs
src/agnostic_interface/raylib_impl.rs

index 989e72ad34430495b84ce1a2903e5d8df87e99b9..fd45ada70a19509eb2b65f038226f5b9e46c8721 100644 (file)
--- a/build.rs
+++ b/build.rs
@@ -9,8 +9,7 @@ fn linking_raylib() {
 }
 
 #[cfg(feature = "no_link_raylib")]
-fn linking_raylib() {
-}
+fn linking_raylib() {}
 
 fn main() {
     linking_raylib();
index ca1e7778f5438c289b78c1879648c71e1938f9c9..0c09bda5e4d12b0b27e556e3a5c8c97c96da846f 100644 (file)
@@ -41,6 +41,7 @@ pub trait MusicInterface {
     fn pause(&mut self) -> Result<(), String>;
     fn stop(&mut self) -> Result<(), String>;
     fn set_loop(&mut self, loop_enable: bool) -> Result<(), String>;
+    fn update(&mut self) -> Result<(), String>;
 }
 
 pub trait CameraInterface {
index 957e814153bc263d4199a04ccb053a91b9262515..9faa8928d1c6ffe41ce4921b7fdf4fbc15000c4f 100644 (file)
@@ -7,65 +7,310 @@ mod ffi {
     include!(concat!(env!("OUT_DIR"), "/raylib_bindings.rs"));
 }
 
-use super::GameInterface;
+use std::{
+    cell::RefCell,
+    collections::HashMap,
+    ffi::CString,
+    os::raw::{c_char, c_int},
+    rc::Rc,
+};
+
+use super::{FontInterface, GameInterface, ImageInterface, MusicInterface, SoundInterface};
+
+fn fqcolor_to_color(c: crate::faux_quicksilver::Color) -> ffi::Color {
+    ffi::Color {
+        r: c.r,
+        g: c.g,
+        b: c.b,
+        a: c.a,
+    }
+}
+
+#[derive(Clone, Debug)]
+struct RaylibImage {
+    image: ffi::Image,
+}
+
+#[derive(Clone, Debug)]
+struct RaylibImageHandler {
+    image: Rc<RaylibImage>,
+}
+
+impl ImageInterface for RaylibImageHandler {
+    fn draw(
+        &mut self,
+        x: f32,
+        y: f32,
+        color: crate::faux_quicksilver::Color,
+    ) -> Result<(), String> {
+        todo!()
+    }
+
+    fn draw_sub(
+        &mut self,
+        sub_rect: crate::faux_quicksilver::Rectangle,
+        x: f32,
+        y: f32,
+        color: crate::faux_quicksilver::Color,
+    ) -> Result<(), String> {
+        todo!()
+    }
+
+    fn draw_transform(
+        &mut self,
+        x: f32,
+        y: f32,
+        color: crate::faux_quicksilver::Color,
+        transform: crate::faux_quicksilver::Transform,
+    ) -> Result<(), String> {
+        todo!()
+    }
+
+    fn draw_sub_transform(
+        &mut self,
+        sub_rect: crate::faux_quicksilver::Rectangle,
+        x: f32,
+        y: f32,
+        color: crate::faux_quicksilver::Color,
+        transform: crate::faux_quicksilver::Transform,
+    ) -> Result<(), String> {
+        todo!()
+    }
+
+    fn get_w(&self) -> usize {
+        todo!()
+    }
+
+    fn get_h(&self) -> usize {
+        todo!()
+    }
+
+    fn get_wh_rect(&self) -> crate::faux_quicksilver::Rectangle {
+        todo!()
+    }
+}
+
+#[derive(Clone, Debug)]
+struct RaylibFont {
+    font: ffi::Font,
+}
+
+#[derive(Clone, Debug)]
+struct RaylibFontHandler {
+    font: Rc<RaylibFont>,
+}
+
+impl FontInterface for RaylibFontHandler {
+    fn draw(
+        &mut self,
+        s: &str,
+        size: u32,
+        x: f32,
+        y: f32,
+        color: crate::faux_quicksilver::Color,
+    ) -> Result<(), String> {
+        todo!()
+    }
+}
+
+#[derive(Clone, Debug)]
+struct RaylibSound {
+    sound: ffi::Sound,
+}
+
+#[derive(Clone, Debug)]
+struct RaylibSoundHandler {
+    sound: Rc<RaylibSound>,
+}
+
+impl SoundInterface for RaylibSoundHandler {
+    fn play(&mut self, vol: f32) -> Result<(), String> {
+        unsafe {
+            ffi::PlaySound(self.sound.sound);
+        }
+        Ok(())
+    }
+}
+
+#[derive(Clone, Debug)]
+struct RaylibMusic {
+    music: ffi::Music,
+}
+
+impl RaylibMusic {
+    pub fn update(&mut self) {
+        unsafe {
+            ffi::UpdateMusicStream(self.music);
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+struct RaylibMusicHandler {
+    music: Rc<RefCell<RaylibMusic>>,
+}
+
+impl MusicInterface for RaylibMusicHandler {
+    fn play(&mut self, vol: f32) -> Result<(), String> {
+        unsafe {
+            ffi::SetMusicVolume(self.music.borrow().music, vol);
+            ffi::PlayMusicStream(self.music.borrow().music);
+        }
+        Ok(())
+    }
+
+    fn pause(&mut self) -> Result<(), String> {
+        unsafe {
+            ffi::PauseMusicStream(self.music.borrow().music);
+        }
+        Ok(())
+    }
+
+    fn stop(&mut self) -> Result<(), String> {
+        unsafe {
+            ffi::StopMusicStream(self.music.borrow().music);
+        }
+        Ok(())
+    }
+
+    fn set_loop(&mut self, loop_enable: bool) -> Result<(), String> {
+        self.music.borrow_mut().music.looping = loop_enable;
+        Ok(())
+    }
+
+    fn update(&mut self) -> Result<(), String> {
+        self.music.borrow_mut().update();
+        Ok(())
+    }
+}
 
 struct RaylibGame {
-    width: f32,
-    height: f32,
+    images: HashMap<String, Rc<RaylibImage>>,
+    fonts: HashMap<String, Rc<RaylibFont>>,
+    sounds: HashMap<String, Rc<RaylibSound>>,
+    music: HashMap<String, Rc<RefCell<RaylibMusic>>>,
 }
 
 impl RaylibGame {
-    pub fn new_boxed(width: f32, height: f32) -> Box<dyn GameInterface> {
+    pub fn new_boxed(width: u32, height: u32) -> Box<dyn GameInterface> {
+        unsafe {
+            let string = "One and All LD45\0";
+            ffi::InitWindow(
+                width as c_int,
+                height as c_int,
+                string.as_ptr() as *const c_char,
+            );
+        }
         Box::new(Self {
-            width,
-            height,
+            images: HashMap::new(),
+            fonts: HashMap::new(),
+            sounds: HashMap::new(),
+            music: HashMap::new(),
         })
     }
 }
 
+impl Drop for RaylibGame {
+    fn drop(&mut self) {
+        unsafe {
+            for (_, image) in &self.images {
+                ffi::UnloadImage(image.image);
+            }
+            for (_, font) in &self.fonts {
+                ffi::UnloadFont(font.font);
+            }
+            for (_, sound) in &self.sounds {
+                ffi::UnloadSound(sound.sound);
+            }
+            for (_, music) in &self.music {
+                ffi::UnloadMusicStream(music.borrow().music);
+            }
+            ffi::CloseWindow();
+        }
+    }
+}
+
 impl GameInterface for RaylibGame {
     fn get_dimensions(&self) -> Result<(f32, f32), String> {
-        Ok((self.width, self.height))
+        unsafe { Ok((ffi::GetScreenWidth() as f32, ffi::GetScreenHeight() as f32)) }
     }
 
     fn get_key_pressed(&mut self, key: char) -> Result<bool, String> {
-        todo!()
+        unsafe { Ok(ffi::IsKeyPressed(key.to_ascii_uppercase() as c_int)) }
     }
 
     fn get_mouse_pressed(&mut self) -> Result<Option<(f32, f32)>, String> {
-        todo!()
+        unsafe {
+            if ffi::IsMouseButtonPressed(0) {
+                Ok(Some((ffi::GetTouchX() as f32, ffi::GetTouchY() as f32)))
+            } else {
+                Ok(None)
+            }
+        }
     }
 
     fn get_mouse_down(&mut self) -> Result<Option<(f32, f32)>, String> {
-        todo!()
+        unsafe {
+            if ffi::IsMouseButtonDown(0) {
+                Ok(Some((ffi::GetTouchX() as f32, ffi::GetTouchY() as f32)))
+            } else {
+                Ok(None)
+            }
+        }
     }
 
     fn get_mouse_xy(&self) -> Result<(f32, f32), String> {
-        todo!()
+        unsafe { Ok((ffi::GetTouchX() as f32, ffi::GetTouchY() as f32)) }
     }
 
     fn get_mouse_xy_vec(&self) -> Result<crate::faux_quicksilver::Vector, String> {
-        todo!()
+        unsafe {
+            Ok(crate::faux_quicksilver::Vector {
+                x: ffi::GetTouchX() as f32,
+                y: ffi::GetTouchY() as f32,
+            })
+        }
     }
 
     fn get_delta_time(&self) -> f32 {
-        todo!()
+        unsafe { ffi::GetFrameTime() }
     }
 
     fn clear_window(&mut self, color: crate::faux_quicksilver::Color) -> Result<(), String> {
-        todo!()
+        unsafe {
+            ffi::ClearBackground(fqcolor_to_color(color));
+        }
+        Ok(())
     }
 
     fn begin_drawing(&mut self) -> Result<(), String> {
-        todo!()
+        unsafe {
+            ffi::BeginDrawing();
+        }
+        Ok(())
     }
 
     fn end_drawing(&mut self) -> Result<(), String> {
-        todo!()
+        unsafe {
+            ffi::EndDrawing();
+        }
+        Ok(())
     }
 
-    fn draw_circle(&mut self, circle: crate::faux_quicksilver::Circle, color: crate::faux_quicksilver::Color) -> Result<(), String> {
-        todo!()
+    fn draw_circle(
+        &mut self,
+        circle: crate::faux_quicksilver::Circle,
+        color: crate::faux_quicksilver::Color,
+    ) -> Result<(), String> {
+        unsafe {
+            ffi::DrawCircle(
+                circle.x.round() as i32,
+                circle.y.round() as i32,
+                circle.r,
+                fqcolor_to_color(color),
+            );
+        }
+        Ok(())
     }
 
     fn draw_circle_ex(
@@ -87,8 +332,21 @@ impl GameInterface for RaylibGame {
         todo!()
     }
 
-    fn draw_rect(&mut self, rect: crate::faux_quicksilver::Rectangle, color: crate::faux_quicksilver::Color) -> Result<(), String> {
-        todo!()
+    fn draw_rect(
+        &mut self,
+        rect: crate::faux_quicksilver::Rectangle,
+        color: crate::faux_quicksilver::Color,
+    ) -> Result<(), String> {
+        unsafe {
+            ffi::DrawRectangle(
+                rect.x.round() as i32,
+                rect.y.round() as i32,
+                rect.w.round() as i32,
+                rect.h.round() as i32,
+                fqcolor_to_color(color),
+            );
+        }
+        Ok(())
     }
 
     fn draw_rect_ex(
@@ -110,20 +368,84 @@ impl GameInterface for RaylibGame {
         todo!()
     }
 
-    fn load_image(&mut self, path: &std::path::Path) -> Result<Box<dyn super::ImageInterface>, String> {
-        todo!()
+    fn load_image(
+        &mut self,
+        path: &std::path::Path,
+    ) -> Result<Box<dyn super::ImageInterface>, String> {
+        unsafe {
+            let path_str = path
+                .to_str()
+                .ok_or_else(|| format!("Failed to convert \"{path:?}\" to str!"))?;
+            let path_buf: Vec<u8> = path_str.as_bytes().into();
+            let cstring: CString = CString::from_vec_unchecked(path_buf);
+            let image = ffi::LoadImage(cstring.as_ptr());
+            let raylib_image_handler = RaylibImageHandler {
+                image: Rc::new(RaylibImage { image }),
+            };
+            self.images
+                .insert(path_str.to_owned(), raylib_image_handler.image.clone());
+            Ok(Box::new(raylib_image_handler))
+        }
     }
 
-    fn load_font(&mut self, path: &std::path::Path) -> Result<Box<dyn super::FontInterface>, String> {
-        todo!()
+    fn load_font(
+        &mut self,
+        path: &std::path::Path,
+    ) -> Result<Box<dyn super::FontInterface>, String> {
+        unsafe {
+            let path_str = path
+                .to_str()
+                .ok_or_else(|| format!("Failed to convert \"{path:?}\" to str!"))?;
+            let path_buf: Vec<u8> = path_str.as_bytes().into();
+            let cstring: CString = CString::from_vec_unchecked(path_buf);
+            let font = ffi::LoadFont(cstring.as_ptr());
+            let raylib_font_handler = RaylibFontHandler {
+                font: Rc::new(RaylibFont { font }),
+            };
+            self.fonts
+                .insert(path_str.to_owned(), raylib_font_handler.font.clone());
+            Ok(Box::new(raylib_font_handler))
+        }
     }
 
-    fn load_sound(&mut self, path: &std::path::Path) -> Result<Box<dyn super::SoundInterface>, String> {
-        todo!()
+    fn load_sound(
+        &mut self,
+        path: &std::path::Path,
+    ) -> Result<Box<dyn super::SoundInterface>, String> {
+        unsafe {
+            let path_str = path
+                .to_str()
+                .ok_or_else(|| format!("Failed to convert \"{path:?}\" to str!"))?;
+            let path_buf: Vec<u8> = path_str.as_bytes().into();
+            let cstring: CString = CString::from_vec_unchecked(path_buf);
+            let sound = ffi::LoadSound(cstring.as_ptr());
+            let raylib_sound_handler = RaylibSoundHandler {
+                sound: Rc::new(RaylibSound { sound }),
+            };
+            self.sounds
+                .insert(path_str.to_owned(), raylib_sound_handler.sound.clone());
+            Ok(Box::new(raylib_sound_handler))
+        }
     }
 
-    fn load_music(&mut self, path: &std::path::Path) -> Result<Box<dyn super::MusicInterface>, String> {
-        todo!()
+    fn load_music(
+        &mut self,
+        path: &std::path::Path,
+    ) -> Result<Box<dyn super::MusicInterface>, String> {
+        unsafe {
+            let path_str = path
+                .to_str()
+                .ok_or_else(|| format!("Failed to convert \"{path:?}\" to str!"))?;
+            let path_buf: Vec<u8> = path_str.as_bytes().into();
+            let cstring: CString = CString::from_vec_unchecked(path_buf);
+            let music = ffi::LoadMusicStream(cstring.as_ptr());
+            let raylib_music_handler = RaylibMusicHandler {
+                music: Rc::new(RefCell::new(RaylibMusic { music })),
+            };
+            self.music
+                .insert(path_str.to_owned(), raylib_music_handler.music.clone());
+            Ok(Box::new(raylib_music_handler))
+        }
     }
 
     fn get_camera(&mut self) -> Result<Box<dyn super::CameraInterface>, String> {