osiris_display/display/
gpu.rs1use std::collections::HashMap;
2use std::time::Instant;
3
4use osiris_data::data::identification::Address;
5
6use crate::display::graphic::{Image, Pixel, Sprite};
7use crate::display::screen::{ScreenMemory};
8
9#[derive(Clone, Debug)]
15struct CachedSprite {
16 displayed: bool,
17 sprite: Sprite,
18}
19
20#[derive(Clone, Debug)]
21pub struct Gpu {
22 flag_swap: bool,
23 _frequency: usize,
24 _next: Instant,
25 memory: ScreenMemory,
26 cache: HashMap<Address, CachedSprite>,
27}
28
29impl Default for Gpu {
30 fn default() -> Self { Self::new() }
31}
32
33impl Gpu {
34 pub fn with_frequency(frequency: usize) -> Self {
35 Self {
36 flag_swap: false,
37 _frequency: frequency,
38 _next: Instant::now(),
39 memory: ScreenMemory::new(Pixel::BLACK),
40 cache: HashMap::new(),
41 }
42 }
43 pub fn new() -> Self { Self::with_frequency(60) }
44
45 pub fn store_sprite(&mut self, reference: &Address, sprite: Sprite, displayed: bool) {
46 self.cache.insert(*reference, CachedSprite { displayed, sprite });
47 }
48
49 pub fn free_sprite(&mut self, reference: &Address) {
50 self.cache.remove(reference);
51 }
52
53 fn unwrap_cached(&mut self, reference: &Address) -> &mut CachedSprite { self.cache.get_mut(reference).unwrap() }
55
56 pub fn sprite_display(&mut self, reference: &Address, displayed: bool) {
57 if !self.cache.contains_key(reference) { return; }
58 self.unwrap_cached(reference).displayed = displayed;
59 }
60
61 pub fn sprite_move(&mut self, reference: &Address, x: usize, y: usize) {
62 if !self.cache.contains_key(reference) { return; }
63 let cached = self.unwrap_cached(reference);
64 cached.sprite.translate(x, y);
65 }
66
67 pub fn sprite_replace(&mut self, reference: &Address, sprite: Sprite, displayed: bool) {
68 if !self.cache.contains_key(reference) { return; }
69 let cached = self.unwrap_cached(reference);
70 cached.displayed = displayed;
71 cached.sprite = sprite;
72 }
73
74 pub fn sprite_show(&mut self, reference: &Address) { self.sprite_display(reference, true); }
75
76 pub fn sprite_hide(&mut self, reference: &Address) { self.sprite_display(reference, false); }
77
78 pub fn draw_all(&mut self) {
79 for sprite in &mut self.cache.values() {
80 if sprite.displayed {
81 self.memory.draw_sprite(&sprite.sprite);
82 }
83 }
84 }
85
86 pub fn clear_all(&mut self) { self.cache.clear(); }
87
88 pub fn swap_on(&mut self) {
89 self.flag_swap = true;
90 }
91
92 pub fn update(&mut self) {
93 if self.flag_swap {
94 self.memory.swap_and_clear();
95 self.flag_swap = false;
96 }
97 }
98
99 pub fn get(&self) -> Image { self.memory.shown_screen().image().clone() }
100
101 pub fn clear(&mut self) { self.memory.clear(); }
102
103 pub fn swap_and_copy(&mut self) -> Image {
104 self.swap_on();
105 self.update();
106 self.memory.copy();
107 self.get()
108 }
109
110 pub fn draw(&mut self) -> Image {
111 self.draw_all();
112 self.swap_on();
113 self.update();
114 self.get()
115 }
116}