xref: /StarryEngine/starry_client/src/window.rs (revision bee61dca287acb4b9fd6d747ba3f687aebacab90)
1*bee61dcaSR0ronoa use std::{cell::Cell, fs::File, io::{Seek, SeekFrom, Write}};
2*bee61dcaSR0ronoa 
3*bee61dcaSR0ronoa use crate::base::{color::Color, renderer::{RenderMode, Renderer}};
4*bee61dcaSR0ronoa 
5*bee61dcaSR0ronoa // TODO: 读帧缓冲设备属性
6*bee61dcaSR0ronoa /// 屏幕宽度
7*bee61dcaSR0ronoa const SCREEN_WIDTH: usize = 1440;
8*bee61dcaSR0ronoa /// 屏幕高度
9*bee61dcaSR0ronoa #[allow(dead_code)]
10*bee61dcaSR0ronoa const SCREEN_HEIGHT: usize = 900;
11*bee61dcaSR0ronoa 
12*bee61dcaSR0ronoa #[allow(dead_code)]
13*bee61dcaSR0ronoa pub struct Window {
14*bee61dcaSR0ronoa     /// 窗口左上角的x坐标
15*bee61dcaSR0ronoa     x: i32,
16*bee61dcaSR0ronoa     /// 窗口左上角的y坐标
17*bee61dcaSR0ronoa     y: i32,
18*bee61dcaSR0ronoa     /// 窗口的宽度
19*bee61dcaSR0ronoa     w: u32,
20*bee61dcaSR0ronoa     /// 窗口的高度
21*bee61dcaSR0ronoa     h: u32,
22*bee61dcaSR0ronoa     /// 窗口的标题
23*bee61dcaSR0ronoa     t: String,
24*bee61dcaSR0ronoa     /// TODO
25*bee61dcaSR0ronoa     // window_async: bool,
26*bee61dcaSR0ronoa     /// 窗口是否大小可变
27*bee61dcaSR0ronoa     resizable: bool,
28*bee61dcaSR0ronoa     /// 窗口的渲染模式
29*bee61dcaSR0ronoa     mode: Cell<RenderMode>,
30*bee61dcaSR0ronoa     // TODO
31*bee61dcaSR0ronoa     // file_opt: Option<File>,
32*bee61dcaSR0ronoa     // TODO: 改定长数组
33*bee61dcaSR0ronoa     // data_opt: Option<& 'static mut [Color]>,
34*bee61dcaSR0ronoa     /// 窗口的渲染数据
35*bee61dcaSR0ronoa     data_opt: Option<Box<[Color]>>,
36*bee61dcaSR0ronoa }
37*bee61dcaSR0ronoa 
38*bee61dcaSR0ronoa impl Renderer for Window {
39*bee61dcaSR0ronoa     fn width(&self) -> u32 {
40*bee61dcaSR0ronoa         self.w
41*bee61dcaSR0ronoa     }
42*bee61dcaSR0ronoa 
43*bee61dcaSR0ronoa     fn height(&self) -> u32 {
44*bee61dcaSR0ronoa         self.h
45*bee61dcaSR0ronoa     }
46*bee61dcaSR0ronoa 
47*bee61dcaSR0ronoa     fn data(&self) -> &[Color] {
48*bee61dcaSR0ronoa         self.data_opt.as_ref().unwrap()
49*bee61dcaSR0ronoa     }
50*bee61dcaSR0ronoa 
51*bee61dcaSR0ronoa     fn data_mut(&mut self) -> &mut [Color]{
52*bee61dcaSR0ronoa         self.data_opt.as_mut().unwrap()
53*bee61dcaSR0ronoa     }
54*bee61dcaSR0ronoa 
55*bee61dcaSR0ronoa     /// TODO
56*bee61dcaSR0ronoa     fn sync(&mut self) -> bool {
57*bee61dcaSR0ronoa         true
58*bee61dcaSR0ronoa     }
59*bee61dcaSR0ronoa 
60*bee61dcaSR0ronoa     fn mode(&self) -> &Cell<RenderMode> {
61*bee61dcaSR0ronoa         &self.mode
62*bee61dcaSR0ronoa     }
63*bee61dcaSR0ronoa }
64*bee61dcaSR0ronoa 
65*bee61dcaSR0ronoa #[allow(dead_code)]
66*bee61dcaSR0ronoa impl Window {
67*bee61dcaSR0ronoa     /// TODO: 接收flags
68*bee61dcaSR0ronoa     pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Self {
69*bee61dcaSR0ronoa         Window {
70*bee61dcaSR0ronoa             x: x,
71*bee61dcaSR0ronoa             y: y,
72*bee61dcaSR0ronoa             w: w,
73*bee61dcaSR0ronoa             h: h,
74*bee61dcaSR0ronoa             t: title.to_string(),
75*bee61dcaSR0ronoa             // window_async: false,
76*bee61dcaSR0ronoa             resizable: false,
77*bee61dcaSR0ronoa             mode: Cell::new(RenderMode::Blend),
78*bee61dcaSR0ronoa             // file_opt: None,
79*bee61dcaSR0ronoa             data_opt: Some(vec!(Color::rgb(0, 0, 0); (w * h) as usize).into_boxed_slice()),
80*bee61dcaSR0ronoa         }
81*bee61dcaSR0ronoa 
82*bee61dcaSR0ronoa         // TODO: 与服务器通信
83*bee61dcaSR0ronoa     }
84*bee61dcaSR0ronoa 
85*bee61dcaSR0ronoa     /// # 函数功能
86*bee61dcaSR0ronoa     /// 同步数据至系统帧缓冲
87*bee61dcaSR0ronoa     pub fn sync(&self) {
88*bee61dcaSR0ronoa         let mut fb = File::open("/dev/fb0").expect("Unable to open framebuffer");
89*bee61dcaSR0ronoa 
90*bee61dcaSR0ronoa         for y in 0..self.height() as i32 {
91*bee61dcaSR0ronoa             for x in 0..self.width() as i32 {
92*bee61dcaSR0ronoa                 let pixel = self.get_pixel(x, y);
93*bee61dcaSR0ronoa                 let offset =  (((y + self.y()) * SCREEN_WIDTH as i32) + x + self.x()) * 4;
94*bee61dcaSR0ronoa                 // 写缓冲区
95*bee61dcaSR0ronoa                 fb.seek(SeekFrom::Start(offset as u64)).expect("Unable to seek framebuffer");
96*bee61dcaSR0ronoa                 fb.write_all(&pixel.to_rgba_bytes()).expect("Unable to write framebuffer");
97*bee61dcaSR0ronoa             }
98*bee61dcaSR0ronoa         }
99*bee61dcaSR0ronoa     }
100*bee61dcaSR0ronoa 
101*bee61dcaSR0ronoa     pub fn x(&self) -> i32 {
102*bee61dcaSR0ronoa         self.x
103*bee61dcaSR0ronoa     }
104*bee61dcaSR0ronoa 
105*bee61dcaSR0ronoa     pub fn y(&self) -> i32 {
106*bee61dcaSR0ronoa         self.y
107*bee61dcaSR0ronoa     }
108*bee61dcaSR0ronoa 
109*bee61dcaSR0ronoa     pub fn title(&self) -> String {
110*bee61dcaSR0ronoa         self.t.clone()
111*bee61dcaSR0ronoa     }
112*bee61dcaSR0ronoa 
113*bee61dcaSR0ronoa 
114*bee61dcaSR0ronoa }