Skip to content

Commit c62feeb

Browse files
committed
7Seg LED dynamic lighting
1 parent 5b4dec1 commit c62feeb

4 files changed

Lines changed: 93 additions & 42 deletions

File tree

src/simulator.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,27 @@ mod views;
1616
pub struct Simulator {
1717
emulator: Option<Emulator>,
1818
emulator_exec_rx: Option<Receiver<Result<Emulator, String>>>,
19+
speed: f64,
1920
ui_states: SimulatorUiStates,
2021
message_window: MessageWindow,
2122
terminal: Terminal,
2223
io_port: IoPort,
23-
prev_timing: time::Instant,
24+
onesec_timing: time::Instant,
25+
emulator_state: usize,
2426
}
2527

2628
impl Simulator {
2729
pub fn new() -> Self {
2830
let mut simulator = Simulator {
2931
emulator: None,
3032
emulator_exec_rx: None,
33+
speed: 0f64,
3134
ui_states: SimulatorUiStates::new(),
3235
message_window: MessageWindow::new(),
3336
terminal: Terminal::new(),
3437
io_port: IoPort::new(),
35-
prev_timing: time::Instant::now(),
38+
onesec_timing: time::Instant::now(),
39+
emulator_state: 0,
3640
};
3741
simulator.io_port.init_led();
3842
simulator.io_port.init_switches();
@@ -50,18 +54,22 @@ impl Simulator {
5054
}
5155
}
5256

57+
// Finished emulator
5358
if let Some(emulator) = self.emulator.as_mut() {
5459
if emulator.socket_receiver_handle.is_finished() && emulator.process.try_wait().is_ok()
5560
{
5661
self.pop_emulator_messages();
5762
self.emulator = None;
63+
self.io_port.init_led();
5864
}
5965
}
6066

6167
self.pop_emulator_messages();
6268
}
6369

6470
fn execute_emulator(&mut self, ctx: &egui::Context) {
71+
self.emulator_state = 0;
72+
self.speed = 1.0f64;
6573
self.io_port.init_led();
6674
self.message_window.clear_messages();
6775
self.terminal.clear();
@@ -104,4 +112,9 @@ impl Simulator {
104112
}
105113
};
106114
}
115+
116+
fn get_corrected_current_emulator_state(&self) -> usize {
117+
let elapsed_from_1sec = self.onesec_timing.elapsed().as_secs_f64() * self.speed;
118+
self.emulator_state + (elapsed_from_1sec * 20_000_000f64) as usize
119+
}
107120
}

src/simulator/ioport.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
pub struct IoPort {
2-
port4: u8,
2+
port4: Vec<(u8, usize)>,
33
port5: u8,
44
portb: u8,
55
}
66

77
impl IoPort {
88
pub fn new() -> Self {
99
Self {
10-
port4: 0,
10+
port4: Vec::new(),
1111
port5: 0,
1212
portb: 0,
1313
}
1414
}
1515

1616
pub fn read(&self, port: u8) -> Option<u8> {
1717
return match port {
18-
4 => Some(self.port4),
1918
5 => Some(self.port5),
2019
0xb => Some(self.portb),
2120
_ => None,
@@ -24,19 +23,41 @@ impl IoPort {
2423

2524
pub fn write(&mut self, port: u8, value: u8, emulator_state: usize) {
2625
return match port {
27-
4 => self.port4 = value,
26+
4 => self.port4.push((value, emulator_state)),
2827
5 => self.port5 = value,
2928
0xb => self.portb = value,
3029
_ => (),
3130
};
3231
}
3332

33+
pub fn filter_port4(&mut self, threshold_state: usize) {
34+
let latest = match self.port4.last() {
35+
Some(latest) => *latest,
36+
None => return,
37+
};
38+
39+
self.port4 = self
40+
.port4
41+
.clone()
42+
.into_iter()
43+
.filter(|port| port.1 >= threshold_state)
44+
.collect();
45+
46+
if self.port4.is_empty() {
47+
self.port4.push(latest);
48+
}
49+
}
50+
51+
pub fn read_port4(&self) -> &Vec<(u8, usize)> {
52+
return &self.port4;
53+
}
54+
3455
pub fn init_led(&mut self) {
3556
// LED
3657
self.write(0xb, 0xff, 0);
3758

3859
// 7Seg LED
39-
self.write(4, 0, 0);
60+
self.port4.clear();
4061
}
4162

4263
pub fn init_switches(&mut self) {

src/simulator/parse_messages.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,21 @@ impl Simulator {
1717
self.send_initial_ioport(emulator);
1818

1919
emulator.send_message("cmd:start");
20-
self.prev_timing = time::Instant::now();
20+
self.onesec_timing = time::Instant::now();
2121
}
2222
}
2323
"1sec" => {
24-
let duration = self.prev_timing.elapsed();
25-
self.prev_timing = time::Instant::now();
26-
self.ui_states.speed = 1f32 / duration.as_secs_f32();
24+
if list.len() != 2 {
25+
return;
26+
}
27+
if let Ok(state) = list[1].parse::<usize>() {
28+
self.emulator_state = state;
29+
} else {
30+
return;
31+
}
32+
let duration = self.onesec_timing.elapsed();
33+
self.onesec_timing = time::Instant::now();
34+
self.speed = 1f64 / duration.as_secs_f64();
2735
}
2836
_ => (),
2937
}

src/simulator/views.rs

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use std::{
1010
pub struct SimulatorUiStates {
1111
pub elf_path: Arc<Mutex<String>>,
1212
pub elf_args: String,
13-
pub speed: f32,
1413
pub toggle_switches: RefCell<[bool; 5]>,
1514
pub push_switches: RefCell<[bool; 5]>,
1615
}
@@ -20,7 +19,6 @@ impl SimulatorUiStates {
2019
SimulatorUiStates {
2120
elf_path: Arc::new(Mutex::new(String::new())),
2221
elf_args: String::new(),
23-
speed: 0f32,
2422
toggle_switches: RefCell::new([false; 5]),
2523
push_switches: RefCell::new([false; 5]),
2624
}
@@ -92,7 +90,7 @@ impl Simulator {
9290
} else {
9391
ui.label("Emulator is stopped.");
9492
}
95-
ui.label(format!("Speed: x{}", self.ui_states.speed));
93+
ui.label(format!("Speed: x{:.6}", self.speed));
9694

9795
ui.separator();
9896

@@ -157,36 +155,47 @@ impl Simulator {
157155
fn show_digit_led(&mut self, ui: &mut egui::Ui) {
158156
use egui::text::LayoutJob;
159157

160-
ui.strong("7Seg LED");
161-
162-
let red_text = TextFormat {
163-
color: Color32::RED,
164-
font_id: FontId::monospace(24.0),
165-
..Default::default()
166-
};
167-
let transparent_text = TextFormat {
168-
color: Color32::TRANSPARENT,
169-
font_id: FontId::monospace(24.0),
170-
..Default::default()
171-
};
172-
173-
let mut job = LayoutJob::default();
174-
175-
let port4 = self.io_port.read(4).unwrap();
176-
for i in 0..4 {
177-
let leading_space = if i == 0 { 0.0 } else { 4.0 };
178-
if (port4 >> i) & 1 == 1 {
179-
job.append(
180-
(port4 >> 4).to_string().as_str(),
181-
leading_space,
182-
red_text.clone(),
183-
);
184-
} else {
185-
job.append("0", leading_space, transparent_text.clone());
158+
ui.add_enabled_ui(self.emulator.is_some(), |ui| {
159+
ui.strong("7Seg LED");
160+
161+
let red_text = TextFormat {
162+
color: Color32::RED,
163+
font_id: FontId::monospace(24.0),
164+
..Default::default()
165+
};
166+
let transparent_text = TextFormat {
167+
color: Color32::TRANSPARENT,
168+
font_id: FontId::monospace(24.0),
169+
..Default::default()
170+
};
171+
172+
self.io_port.filter_port4(
173+
self.get_corrected_current_emulator_state()
174+
.saturating_sub(200_000 * 3),
175+
);
176+
let port4 = self.io_port.read_port4();
177+
178+
let mut diaplay_num: [Option<u8>; 4] = [None; 4];
179+
for item in port4 {
180+
for i in 0..4 {
181+
if (item.0 >> i) & 1 == 1 {
182+
diaplay_num[i] = Some(item.0 >> 4);
183+
}
184+
}
186185
}
187-
}
188186

189-
ui.label(job);
187+
let mut job = LayoutJob::default();
188+
for (i, num) in diaplay_num.iter().enumerate() {
189+
let leading_space = if i == 0 { 0.0 } else { 4.0 };
190+
if let Some(num) = num {
191+
job.append(num.to_string().as_str(), leading_space, red_text.clone());
192+
} else {
193+
job.append("0", leading_space, transparent_text.clone());
194+
}
195+
}
196+
197+
ui.label(job);
198+
});
190199
}
191200

192201
fn show_toggle_switches(&mut self, ui: &mut egui::Ui) {

0 commit comments

Comments
 (0)