Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcfb75fead | ||
|
|
7654666a17 | ||
|
|
9fc9e4c4d9 | ||
|
|
5a5c5d4d9b | ||
|
|
fb6f09fce5 | ||
|
|
f2d3f5ec07 | ||
|
|
e96ce2af07 | ||
|
|
25c7f29735 |
Generated
+1
-1
@@ -1807,7 +1807,7 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "lemur"
|
||||
version = "0.4.1"
|
||||
version = "0.4.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"atoi",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ description = "An emulator for the Virtual Boy."
|
||||
repository = "https://git.virtual-boy.com/PVB/lemur"
|
||||
publish = false
|
||||
license = "MIT"
|
||||
version = "0.4.1"
|
||||
version = "0.4.3"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
+1
-1
Submodule shrooms-vb-core updated: 185362e6cd...b2412d9487
+31
-1
@@ -291,6 +291,26 @@ impl Emulator {
|
||||
);
|
||||
}
|
||||
|
||||
fn frame_advance(&mut self) {
|
||||
if self
|
||||
.state
|
||||
.compare_exchange(
|
||||
EmulatorState::Paused,
|
||||
EmulatorState::Stepping,
|
||||
Ordering::AcqRel,
|
||||
Ordering::Acquire,
|
||||
)
|
||||
.is_err_and(|s| s == EmulatorState::Running)
|
||||
{
|
||||
let _ = self.state.compare_exchange(
|
||||
EmulatorState::Running,
|
||||
EmulatorState::Stepping,
|
||||
Ordering::AcqRel,
|
||||
Ordering::Relaxed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn save_sram(&mut self, sim_id: SimId) -> Result<()> {
|
||||
let sim = self.sims.get_mut(sim_id.to_index());
|
||||
let cart = self.carts[sim_id.to_index()].as_mut();
|
||||
@@ -366,6 +386,7 @@ impl Emulator {
|
||||
debugger.stop_reason = None;
|
||||
true
|
||||
}
|
||||
|
||||
fn debug_step(&mut self, sim_id: SimId) {
|
||||
if self.debug_continue(sim_id) {
|
||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
||||
@@ -428,7 +449,7 @@ impl Emulator {
|
||||
// Don't emulate if the state is "paused", or if any sim is paused in the debugger
|
||||
let running = match state {
|
||||
EmulatorState::Paused => false,
|
||||
EmulatorState::Running => true,
|
||||
EmulatorState::Running | EmulatorState::Stepping => true,
|
||||
EmulatorState::Debugging => self.debuggers.values().all(|d| d.stop_reason.is_none()),
|
||||
};
|
||||
let p1_running = running && p1_state == SimState::Ready;
|
||||
@@ -442,6 +463,10 @@ impl Emulator {
|
||||
self.sims[SimId::Player2.to_index()].emulate();
|
||||
}
|
||||
|
||||
if state == EmulatorState::Stepping {
|
||||
self.state.store(EmulatorState::Paused, Ordering::Release);
|
||||
}
|
||||
|
||||
// Debug state
|
||||
if state == EmulatorState::Debugging {
|
||||
for sim_id in SimId::values() {
|
||||
@@ -539,6 +564,9 @@ impl Emulator {
|
||||
EmulatorCommand::Resume => {
|
||||
self.resume_sims();
|
||||
}
|
||||
EmulatorCommand::FrameAdvance => {
|
||||
self.frame_advance();
|
||||
}
|
||||
EmulatorCommand::StartDebugging(sim_id, debugger) => {
|
||||
self.start_debugging(sim_id, debugger);
|
||||
}
|
||||
@@ -665,6 +693,7 @@ pub enum EmulatorCommand {
|
||||
StopSecondSim,
|
||||
Pause,
|
||||
Resume,
|
||||
FrameAdvance,
|
||||
StartDebugging(SimId, DebugSender),
|
||||
StopDebugging(SimId),
|
||||
DebugInterrupt(SimId),
|
||||
@@ -700,6 +729,7 @@ pub enum SimState {
|
||||
pub enum EmulatorState {
|
||||
Paused,
|
||||
Running,
|
||||
Stepping,
|
||||
Debugging,
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ impl GameWindow {
|
||||
let is_ready = self.client.sim_state(self.sim_id) == SimState::Ready;
|
||||
let can_pause = is_ready && state == EmulatorState::Running;
|
||||
let can_resume = is_ready && state == EmulatorState::Paused;
|
||||
let can_frame_advance = is_ready && state != EmulatorState::Debugging;
|
||||
if state == EmulatorState::Running {
|
||||
if ui.add_enabled(can_pause, Button::new("Pause")).clicked() {
|
||||
self.client.send_command(EmulatorCommand::Pause);
|
||||
@@ -100,6 +101,14 @@ impl GameWindow {
|
||||
.send_command(EmulatorCommand::Reset(self.sim_id));
|
||||
ui.close_menu();
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_enabled(can_frame_advance, Button::new("Frame Advance"))
|
||||
.clicked()
|
||||
{
|
||||
self.client.send_command(EmulatorCommand::FrameAdvance);
|
||||
ui.close_menu();
|
||||
}
|
||||
});
|
||||
ui.menu_button("Options", |ui| self.show_options_menu(ctx, ui));
|
||||
ui.menu_button("Multiplayer", |ui| {
|
||||
|
||||
@@ -3,12 +3,12 @@ use egui::{Color32, Image, ImageSource, Response, Sense, TextureOptions, Ui, Wid
|
||||
pub const GENERIC_PALETTE: [u8; 4] = [0, 32, 64, 128];
|
||||
|
||||
pub fn shade(brt: u8, color: Color32) -> Color32 {
|
||||
let corrected = if brt & 0x80 != 0 {
|
||||
255
|
||||
let corrected = if brt > 132 {
|
||||
255.0
|
||||
} else {
|
||||
(brt << 1) | (brt >> 6)
|
||||
(brt as f32 * 255.0 / 133.0).round()
|
||||
};
|
||||
color.gamma_multiply(corrected as f32 / 255.0)
|
||||
color.gamma_multiply(corrected / 255.0)
|
||||
}
|
||||
|
||||
pub fn generic_palette(color: Color32) -> [Color32; 4] {
|
||||
|
||||
+17
-6
@@ -643,6 +643,15 @@ impl WorldRenderer {
|
||||
shades.map(|s| shade(s, params.right_color)),
|
||||
]
|
||||
};
|
||||
let palettes = {
|
||||
let palettes = self.palettes.borrow().read::<[u8; 8]>(0);
|
||||
[
|
||||
utils::parse_palette(palettes[0]),
|
||||
utils::parse_palette(palettes[2]),
|
||||
utils::parse_palette(palettes[4]),
|
||||
utils::parse_palette(palettes[6]),
|
||||
]
|
||||
};
|
||||
|
||||
let chardata = self.chardata.borrow();
|
||||
let bgmaps = self.bgmaps.borrow();
|
||||
@@ -667,7 +676,8 @@ impl WorldRenderer {
|
||||
let row = (sy & 0x7) as usize;
|
||||
let col = (sx & 0x7) as usize;
|
||||
let pixel = utils::read_char_pixel(char, cell.hflip, cell.vflip, row, col);
|
||||
image.add((dx as usize, dy as usize), colors[0][pixel as usize]);
|
||||
let shade = palettes[cell.palette_index][pixel as usize];
|
||||
image.add((dx as usize, dy as usize), colors[0][shade as usize]);
|
||||
}
|
||||
|
||||
let dx = x + world.dst_x + world.dst_parallax;
|
||||
@@ -680,7 +690,8 @@ impl WorldRenderer {
|
||||
let row = (sy & 0x7) as usize;
|
||||
let col = (sx & 0x7) as usize;
|
||||
let pixel = utils::read_char_pixel(char, cell.hflip, cell.vflip, row, col);
|
||||
image.add((dx as usize, dy as usize), colors[1][pixel as usize]);
|
||||
let shade = palettes[cell.palette_index][pixel as usize];
|
||||
image.add((dx as usize, dy as usize), colors[1][shade as usize]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -976,8 +987,8 @@ impl<'a> SourceCoordCalculator<'a> {
|
||||
(sx, sy)
|
||||
}
|
||||
SourceParam::Affine(affine) => {
|
||||
let sx = affine_coord(affine.src_x, x, affine.dx, affine.src_parallax.min(0).abs());
|
||||
let sy = affine_coord(affine.src_y, x, affine.dy, affine.src_parallax.min(0).abs());
|
||||
let sx = affine_coord(affine.src_x, x, affine.dx, affine.src_parallax.min(0));
|
||||
let sy = affine_coord(affine.src_y, x, affine.dy, affine.src_parallax.min(0));
|
||||
(sx, sy)
|
||||
}
|
||||
}
|
||||
@@ -997,8 +1008,8 @@ impl<'a> SourceCoordCalculator<'a> {
|
||||
(sx, sy)
|
||||
}
|
||||
SourceParam::Affine(affine) => {
|
||||
let sx = affine_coord(affine.src_x, x, affine.dx, -affine.src_parallax.max(0));
|
||||
let sy = affine_coord(affine.src_y, x, affine.dy, -affine.src_parallax.max(0));
|
||||
let sx = affine_coord(affine.src_x, x, affine.dx, affine.src_parallax.max(0));
|
||||
let sy = affine_coord(affine.src_y, x, affine.dy, affine.src_parallax.max(0));
|
||||
(sx, sy)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user