tetanes_core/ppu/
frame.rs1use crate::{
4 common::{Reset, ResetKind},
5 ppu::Ppu,
6};
7use serde::{Deserialize, Serialize};
8use std::ops::{Deref, DerefMut};
9
10#[derive(Clone, Serialize, Deserialize)]
12#[serde(transparent)]
13#[must_use]
14pub struct Buffer(Vec<u16>);
15
16impl std::fmt::Debug for Buffer {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 write!(f, "Buffer({} elements)", self.0.len())
19 }
20}
21
22impl Default for Buffer {
23 fn default() -> Self {
24 Self(vec![0x00; Ppu::SIZE])
25 }
26}
27
28impl Deref for Buffer {
29 type Target = [u16];
30 fn deref(&self) -> &Self::Target {
31 &self.0
32 }
33}
34
35impl DerefMut for Buffer {
36 fn deref_mut(&mut self) -> &mut Self::Target {
37 &mut self.0
38 }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43#[must_use]
44pub struct Frame {
45 pub count: u32,
46 pub is_odd: bool,
47 #[serde(skip)]
48 pub buffer: Buffer,
49}
50
51impl Default for Frame {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl Frame {
58 pub fn new() -> Self {
59 Self {
60 count: 0,
61 is_odd: false,
62 buffer: Buffer::default(),
63 }
64 }
65
66 pub const fn increment(&mut self) {
67 self.count = self.count.wrapping_add(1);
68 self.is_odd = self.count & 0x01 == 0x01;
69 }
70
71 #[must_use]
72 pub fn pixel(&self, x: u32, y: u32) -> u16 {
73 self.buffer[(x + (y << 8)) as usize]
74 }
75
76 #[inline]
77 pub fn set_pixel(&mut self, x: u32, y: u32, color: u16) {
78 self.buffer[(x + (y << 8)) as usize] = color;
79 }
80
81 #[must_use]
82 pub fn pixel_brightness(&self, x: u32, y: u32) -> u32 {
83 let pixel = self.pixel(x, y);
84 let index = (pixel as usize) * 3;
85 let red = Ppu::NTSC_PALETTE[index];
86 let green = Ppu::NTSC_PALETTE[index + 1];
87 let blue = Ppu::NTSC_PALETTE[index + 2];
88 u32::from(red) + u32::from(green) + u32::from(blue)
89 }
90
91 #[must_use]
92 pub const fn number(&self) -> u32 {
93 self.count
94 }
95
96 #[must_use]
97 pub const fn is_odd(&self) -> bool {
98 self.is_odd
99 }
100
101 #[must_use]
102 #[allow(clippy::missing_const_for_fn)] pub fn buffer(&self) -> &[u16] {
104 &self.buffer
105 }
106}
107
108impl Reset for Frame {
109 fn reset(&mut self, _kind: ResetKind) {
110 self.count = 0;
111 self.buffer = Buffer::default();
112 }
113}