First commit.
[temp2RGB.git] / src / main_loop.rs
1 use std::{
2 sync::{
3 atomic::{AtomicBool, Ordering},
4 Arc,
5 },
6 time::{self, Duration},
7 };
8
9 use crate::{consts, machine, rgb, settings, timer, winring0};
10
11 pub fn main_loop(completed: Arc<AtomicBool>) {
12 if consts::FREQ_REFRESHING_RGB > consts::FREQ_TEMP_POLLING {
13 panic!("Polling frequency must be greater or equal than RGB refresh frequency");
14 }
15
16 if consts::FREQ_TEMP_POLLING % consts::FREQ_REFRESHING_RGB != 0 {
17 panic!("Polling frequency must be a multiple of RGB refresh frequency");
18 }
19
20 init_winring0();
21
22 let sleep = timer::Sleep::new();
23 let settings = settings::Settings::read(consts::FILE_CONF).expect("Cannot load settings");
24 println!("Settings: {settings:?}");
25
26 let mut machine: &mut dyn machine::Machine = &mut machine::MachineJiji::new();
27
28 let mut kernel = [0f32; consts::KERNEL_SIZE_SAMPLES];
29 let mut current_pos = 0usize;
30
31 let mut tick = 0i64;
32 let period = Duration::from_micros(1_000_000u64 / consts::FREQ_TEMP_POLLING as u64);
33
34 loop {
35 if completed.load(Ordering::Relaxed) {
36 break;
37 }
38 let time_beginning_loop = time::Instant::now();
39
40 let temp = (machine.get_cpu_tmp() + machine.get_gpu_tmp()) / 2f32;
41 kernel[current_pos] = temp;
42 current_pos = (current_pos + 1) % consts::KERNEL_SIZE_SAMPLES;
43 let mean_temp = {
44 let mut s = 0f32;
45 for t in kernel {
46 s += t;
47 }
48 s / kernel.len() as f32
49 };
50
51 let normalized_temp = num::clamp(
52 (mean_temp - settings.cold_temperature)
53 / (settings.hot_temperature - settings.cold_temperature),
54 0f32,
55 1f32,
56 ); // Between 0 (cold) and 1 (hot).
57
58 let color =
59 rgb::linear_interpolation(settings.cold_color, settings.hot_color, normalized_temp);
60
61 // println!("normalized_temp: {normalized_temp}");
62
63 if tick % (consts::FREQ_TEMP_POLLING / consts::FREQ_REFRESHING_RGB) as i64 == 0 {
64 println!("Update RGB: {color:?}, temp: {mean_temp}");
65 machine.set_color(&color);
66 }
67
68 let elapsed = time::Instant::now() - time_beginning_loop;
69 if elapsed < period {
70 let to_wait = period - elapsed;
71 sleep.wait(to_wait);
72 }
73 tick += 1;
74 }
75
76 // println!("Press any key to continue...");
77 // std::io::stdin().read_line(&mut String::new()).unwrap();
78
79 unsafe {
80 winring0::DeinitializeOls();
81 }
82 }
83
84 fn init_winring0() {
85 unsafe {
86 let ols_ok = winring0::InitializeOls() != 0;
87 if !ols_ok {
88 panic!("Unable to initalize WingRing0");
89 }
90 let dll_status = winring0::GetDllStatus();
91 if dll_status != 0 {
92 panic!("WingRing0 DLL status error: {}", dll_status);
93 }
94 }
95 }