1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::clock::{Ts, VFrameTs, VideoTs, VideoTsData2};
use crate::video::{
VideoFrame,
frame_cache::PlusVidFrameDataIterator
};
use crate::memory::ScreenArray;
use crate::chip::{
ula::frame_cache::UlaFrameCache,
ula128::frame_cache::vc_to_line,
scld::frame_cache::{
SourceMode, ScldFrameRef, ScldFrameProducer
}
};
pub struct PlusFrameProducer<'a, V, IM, IS> {
scld_frame_prod: ScldFrameProducer<'a, V, IM>,
shadow_frame: ScldFrameRef<'a, V>,
screen_changes: IS,
swap_at: VFrameTs<V>,
}
impl<'a, V, IM, IS> PlusVidFrameDataIterator for PlusFrameProducer<'a, V, IM, IS>
where V: VideoFrame,
IM: Iterator<Item=VideoTsData2>,
IS: Iterator<Item=VideoTs>
{
fn next_line(&mut self) {
self.scld_frame_prod.next_line();
self.swap_at.vc -= 1;
}
}
impl<'a, V, IM, IS> PlusFrameProducer<'a, V, IM, IS>
where V: VideoFrame,
IM: Iterator<Item=VideoTsData2>,
IS: Iterator<Item=VideoTs>
{
#[allow(clippy::too_many_arguments)]
pub fn new(
swap_screens: bool,
source: SourceMode,
screen0: &'a ScreenArray,
frame_cache0: &'a UlaFrameCache<V>,
screen1: &'a ScreenArray,
frame_cache1: &'a UlaFrameCache<V>,
screen_shadow0: &'a ScreenArray,
frame_cache_shadow0: &'a UlaFrameCache<V>,
screen_shadow1: &'a ScreenArray,
frame_cache_shadow1: &'a UlaFrameCache<V>,
mut screen_changes: IS,
source_changes: IM
) -> Self
{
let swap_at = screen_changes.next()
.map(|ts| vc_to_line::<V>(ts, 0))
.unwrap_or_else(VFrameTs::max_value);
let mut scld_frame_prod = ScldFrameProducer::new(
source,
screen0, frame_cache0,
screen1, frame_cache1,
source_changes
);
let mut shadow_frame = ScldFrameRef::new(
screen_shadow0, frame_cache_shadow0,
screen_shadow1, frame_cache_shadow1,
);
if swap_screens {
scld_frame_prod.swap_frame(&mut shadow_frame);
}
PlusFrameProducer {
scld_frame_prod,
shadow_frame,
screen_changes,
swap_at
}
}
fn swap_frames(&mut self) {
self.scld_frame_prod.swap_frame(&mut self.shadow_frame);
}
}
impl<'a, V, IM, IS> Iterator for PlusFrameProducer<'a, V, IM, IS>
where V: VideoFrame,
IM: Iterator<Item=VideoTsData2>,
IS: Iterator<Item=VideoTs>
{
type Item = (u8, u8, Ts);
fn next(&mut self) -> Option<Self::Item> {
while self.swap_at.vc <= 0 {
if self.swap_at.vc < 0 || self.swap_at.hc < self.scld_frame_prod.peek_hts() {
self.swap_frames();
self.swap_at = self.screen_changes.next()
.map(|ts| vc_to_line::<V>(ts, self.scld_frame_prod.line() as Ts))
.unwrap_or_else(VFrameTs::max_value)
}
else {
break;
}
}
self.scld_frame_prod.next()
}
}