Skip to content

Commit 962a415

Browse files
committed
Add ability to change simulated ipt time delta
1 parent 10e01a4 commit 962a415

File tree

6 files changed

+43
-23
lines changed

6 files changed

+43
-23
lines changed

schematics/mlogv32.msch

7 Bytes
Binary file not shown.

src/bin/mlogv32.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ struct Cli {
4949

5050
#[arg(long, short)]
5151
verbose: bool,
52+
53+
/// Simulated time delta (0.5 = 120 fps, 1 = 60 fps, 2 = 30 fps)
54+
#[arg(long, default_value_t = 1.0, value_parser = time_delta_parser)]
55+
delta: f64,
56+
}
57+
58+
fn time_delta_parser(s: &str) -> Result<f64, String> {
59+
match s.parse() {
60+
Ok(value) if value > 0. && value <= 6. => Ok(value),
61+
Ok(_) => Err(format!("{s} is not in range (0, 6]")),
62+
Err(_) => Err(format!("{s} is not a valid number")),
63+
}
5264
}
5365

5466
#[derive(Debug, Deserialize)]
@@ -459,7 +471,7 @@ fn main() -> Result<(), Box<dyn Error>> {
459471
let now = Instant::now();
460472
let time = now - start;
461473
if !frozen {
462-
vm.do_tick(time);
474+
vm.do_tick_with_delta(time, cli.delta);
463475
ticks += 1;
464476
}
465477

src/logic/vm/buildings.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl Building {
113113
let data = match name {
114114
MICRO_PROCESSOR => BuildingData::Processor(
115115
ProcessorBuilder {
116-
ipt: 2,
116+
ipt: 2.,
117117
privileged: false,
118118
running_processors: Rc::clone(&builder.vm.running_processors),
119119
time: Rc::clone(&builder.vm.time),
@@ -124,7 +124,7 @@ impl Building {
124124
),
125125
LOGIC_PROCESSOR => BuildingData::Processor(
126126
ProcessorBuilder {
127-
ipt: 8,
127+
ipt: 8.,
128128
privileged: false,
129129
running_processors: Rc::clone(&builder.vm.running_processors),
130130
time: Rc::clone(&builder.vm.time),
@@ -135,7 +135,7 @@ impl Building {
135135
),
136136
HYPER_PROCESSOR => BuildingData::Processor(
137137
ProcessorBuilder {
138-
ipt: 25,
138+
ipt: 25.,
139139
privileged: false,
140140
running_processors: Rc::clone(&builder.vm.running_processors),
141141
time: Rc::clone(&builder.vm.time),
@@ -146,7 +146,7 @@ impl Building {
146146
),
147147
WORLD_PROCESSOR => BuildingData::Processor(
148148
ProcessorBuilder {
149-
ipt: 8,
149+
ipt: 8.,
150150
privileged: true,
151151
running_processors: Rc::clone(&builder.vm.running_processors),
152152
time: Rc::clone(&builder.vm.time),

src/logic/vm/instructions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
},
2323
};
2424

25-
const MAX_IPT: usize = 1000;
25+
const MAX_IPT: i32 = 1000;
2626
const EQUALITY_EPSILON: f64 = 0.000001;
2727
const PRINT_EPSILON: f64 = 0.00001;
2828

@@ -1107,6 +1107,6 @@ pub(super) struct SetRate {
11071107

11081108
impl SimpleInstructionTrait for SetRate {
11091109
fn execute(&self, state: &mut ProcessorState, _: &HashMap<String, LVar>, _: &LogicVM) {
1110-
state.ipt = (self.value.get(state).num() as usize).clamp(1, MAX_IPT);
1110+
state.ipt = self.value.get(state).numi().clamp(1, MAX_IPT) as f64;
11111111
}
11121112
}

src/logic/vm/mod.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,19 @@ impl LogicVM {
8282
}
8383
}
8484

85-
/// Execute one tick of the simulation.
85+
/// Execute one tick of the simulation with a delta of `1.0`.
8686
///
87-
/// Note: `time` is the time elapsed since the *start* of the simulation.
87+
/// `time` is the time elapsed since the *start* of the simulation.
8888
pub fn do_tick(&self, time: Duration) {
89+
self.do_tick_with_delta(time, 1.0);
90+
}
91+
92+
/// Execute one tick of the simulation.
93+
///
94+
/// `time` is the time elapsed since the *start* of the simulation.
95+
///
96+
/// `delta` is the simulated time delta, eg. `1.0` corresponds to 60 fps.
97+
pub fn do_tick_with_delta(&self, time: Duration, delta: f64) {
8998
// never move time backwards
9099
let time = duration_millis_f64(time);
91100
self.time.set(time);
@@ -95,7 +104,7 @@ impl LogicVM {
95104
.data
96105
.borrow_mut()
97106
.unwrap_processor_mut()
98-
.do_tick(self, time);
107+
.do_tick(self, time, delta);
99108
}
100109
}
101110

@@ -1656,7 +1665,7 @@ mod tests {
16561665
for ipt in [8, 1, 10, 1, 1000, 500, 1000, 5] {
16571666
with_processor(&mut vm, (0, 0), |p| {
16581667
assert_eq!(
1659-
p.state.ipt, ipt,
1668+
p.state.ipt, ipt as f64,
16601669
"incorrect ipt at counter {}",
16611670
p.state.counter
16621671
);
@@ -1673,7 +1682,7 @@ mod tests {
16731682
let mut vm = single_processor_vm(MICRO_PROCESSOR, "setrate 10; stop");
16741683
run(&mut vm, 1, true);
16751684
let processor = take_processor(&mut vm, (0, 0));
1676-
assert_eq!(processor.state.ipt, 2);
1685+
assert_eq!(processor.state.ipt, 2.0);
16771686
}
16781687

16791688
const CONDITION_TESTS: &[(&str, &str, &str, bool)] = &[

src/logic/vm/processor.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::{
22
cell::Cell,
3-
cmp::min,
43
collections::{HashMap, HashSet},
54
io::Cursor,
65
rc::Rc,
@@ -23,7 +22,7 @@ use crate::{
2322
};
2423

2524
pub(super) const MAX_TEXT_BUFFER: usize = 400;
26-
const MAX_INSTRUCTION_SCALE: usize = 5;
25+
const MAX_INSTRUCTION_SCALE: f64 = 5.0;
2726

2827
pub struct Processor {
2928
instructions: Vec<Instruction>,
@@ -144,19 +143,19 @@ impl Processor {
144143
Ok(())
145144
}
146145

147-
pub fn do_tick(&mut self, vm: &LogicVM, time: f64) {
146+
pub fn do_tick(&mut self, vm: &LogicVM, time: f64, delta: f64) {
148147
if !self.state.enabled || self.state.wait_end_time > time {
149148
return;
150149
}
151150

152-
self.state.accumulator = min(
153-
self.state.accumulator + self.state.ipt,
151+
self.state.accumulator = f64::min(
152+
self.state.accumulator + self.state.ipt * delta,
154153
MAX_INSTRUCTION_SCALE * self.state.ipt,
155154
);
156155

157-
while self.state.accumulator >= 1 {
156+
while self.state.accumulator >= 1. {
158157
let res = self.step(vm);
159-
self.state.accumulator -= 1;
158+
self.state.accumulator -= 1.;
160159
if let InstructionResult::Yield = res {
161160
break;
162161
}
@@ -213,8 +212,8 @@ pub struct ProcessorState {
213212
linked_positions: HashSet<Point2>,
214213

215214
pub counter: usize,
216-
accumulator: usize,
217-
pub ipt: usize,
215+
accumulator: f64,
216+
pub ipt: f64,
218217

219218
running_processors: Rc<Cell<usize>>,
220219
pub(super) time: Rc<Cell<f64>>,
@@ -302,7 +301,7 @@ pub(super) struct ProcessorLink {
302301

303302
#[derive(Debug)]
304303
pub(super) struct ProcessorBuilder<'a> {
305-
pub ipt: usize,
304+
pub ipt: f64,
306305
pub privileged: bool,
307306
pub running_processors: Rc<Cell<usize>>,
308307
pub time: Rc<Cell<f64>>,
@@ -399,7 +398,7 @@ impl ProcessorBuilder<'_> {
399398
links,
400399
linked_positions: HashSet::new(),
401400
counter: 0,
402-
accumulator: 0,
401+
accumulator: 0.,
403402
ipt,
404403
running_processors,
405404
time,

0 commit comments

Comments
 (0)