Compare commits
4 commits
49464a58a5
...
1e4a478d1f
Author | SHA1 | Date | |
---|---|---|---|
Alex Janka | 1e4a478d1f | ||
Alex Janka | bc8da0212d | ||
Alex Janka | 0cb78d5a8f | ||
Alex Janka | 31d269852c |
19
Cargo.toml
19
Cargo.toml
|
@ -29,3 +29,22 @@ baseview = { git = "https://git.alexjanka.com/alex/baseview" }
|
|||
|
||||
[patch.crates-io]
|
||||
anymap = { git = "https://git.alexjanka.com/alex/anymap" }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
pedantic = "warn"
|
||||
cast_precision_loss = { level = "allow", priority = 1 }
|
||||
doc_markdown = { level = "allow", priority = 1 }
|
||||
if_not_else = { level = "allow", priority = 1 }
|
||||
items_after_statements = { level = "allow", priority = 1 }
|
||||
match_wildcard_for_single_variants = { level = "allow", priority = 1 }
|
||||
missing_errors_doc = { level = "allow", priority = 1 }
|
||||
missing_panics_doc = { level = "allow", priority = 1 }
|
||||
module_inception = { level = "allow", priority = 1 }
|
||||
needless_pass_by_value = { level = "allow", priority = 1 }
|
||||
similar_names = { level = "allow", priority = 1 }
|
||||
too_many_lines = { level = "allow", priority = 1 }
|
||||
type_complexity = { level = "allow", priority = 1 }
|
||||
unreadable_literal = { level = "allow", priority = 1 }
|
||||
unused_self = { level = "allow", priority = 1 }
|
||||
cast_possible_truncation = { level = "allow", priority = 1 }
|
||||
default_trait_access = { level = "allow", priority = 1 }
|
||||
|
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
description = "TWINC Game Boy (CGB/DMG) emulator CLI"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bundle]
|
||||
identifier = "com.alexjanka.TWINC.cli"
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ impl From<SerialTargetOption> for SerialTarget {
|
|||
#[command(author, version, about, long_about = None)]
|
||||
#[command(group(ArgGroup::new("saves").args(["save","no_save"])))]
|
||||
#[command(subcommand_negates_reqs = true)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
struct Args {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
|
|
|
@ -4,6 +4,9 @@ version = "0.5.1"
|
|||
edition = "2021"
|
||||
description = "Frontend common library for TWINC Game Boy (CGB/DMG) emulator"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
pixels = ["gb-emu-lib/pixels-renderer"]
|
||||
|
|
|
@ -55,11 +55,12 @@ pub struct Debugger {
|
|||
}
|
||||
|
||||
impl Debugger {
|
||||
#[must_use]
|
||||
pub fn new(core: Box<dyn EmulatorCoreTrait>) -> Self {
|
||||
Self {
|
||||
core,
|
||||
stepping: true,
|
||||
last_command: String::from(""),
|
||||
last_command: String::new(),
|
||||
watches: HashMap::new(),
|
||||
breakpoints: Vec::new(),
|
||||
}
|
||||
|
@ -77,12 +78,12 @@ impl Debugger {
|
|||
let mut line = String::new();
|
||||
line = match io::stdin().read_line(&mut line) {
|
||||
Ok(_) => line,
|
||||
Err(_) => String::from(""),
|
||||
Err(_) => String::new(),
|
||||
};
|
||||
if line.trim().is_empty() {
|
||||
line = self.last_command.clone();
|
||||
line.clone_from(&self.last_command);
|
||||
} else {
|
||||
self.last_command = line.clone();
|
||||
self.last_command.clone_from(&line);
|
||||
}
|
||||
if let Ok(command) = Commands::from_str(&line) {
|
||||
match command {
|
||||
|
@ -95,7 +96,7 @@ impl Debugger {
|
|||
Commands::Continue => self.stepping = false,
|
||||
Commands::Break(address) => {
|
||||
if !self.breakpoints.contains(&address) {
|
||||
self.breakpoints.push(address)
|
||||
self.breakpoints.push(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +117,7 @@ impl Debugger {
|
|||
should_pause = true;
|
||||
println!("Memory at 0x{address:0>4X} changed:");
|
||||
println!(" from 0b{0:0>8b}/0x{0:0>2X}", *data);
|
||||
println!(" to 0b{0:0>8b}/0x{0:0>2X}", new_data);
|
||||
println!(" to 0b{new_data:0>8b}/0x{new_data:0>2X}");
|
||||
*data = new_data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ fn access_config<'a>() -> &'a Configs {
|
|||
CONFIGS.get().expect("accessed config before it was set!")
|
||||
}
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct RunOptions {
|
||||
pub rom: PathBuf,
|
||||
pub save: SramType,
|
||||
|
@ -77,6 +78,7 @@ pub struct RunOptions {
|
|||
}
|
||||
|
||||
impl RunOptions {
|
||||
#[must_use]
|
||||
pub fn new(rom: PathBuf) -> Self {
|
||||
Self {
|
||||
rom,
|
||||
|
|
|
@ -60,9 +60,10 @@ where
|
|||
Backend: RendererBackend,
|
||||
<Backend as RendererBackend>::RendererError: Sync + Send + 'static,
|
||||
{
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
sender: Sender<EmulatorMessage<[u8; 4]>>,
|
||||
_stream: Stream,
|
||||
stream: Stream,
|
||||
record_main: bool,
|
||||
) -> Self {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
@ -80,7 +81,7 @@ where
|
|||
sender,
|
||||
gamepad_handler: Gilrs::new().unwrap(),
|
||||
joypad_state: Default::default(),
|
||||
_stream,
|
||||
_stream: stream,
|
||||
},
|
||||
record_main,
|
||||
}
|
||||
|
@ -340,11 +341,15 @@ where
|
|||
let window = WindowBuilder::new()
|
||||
.with_title("Gameboy")
|
||||
.with_resizable(resizable);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let window = window.with_name("TWINC", "");
|
||||
|
||||
let window = window.build(event_loop)?;
|
||||
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
let real_factor = (window.scale_factor() * factor as f64) as u32;
|
||||
|
||||
let inner_size = window.inner_size();
|
||||
let resolutions = ResolutionData {
|
||||
real_width: inner_size.width,
|
||||
|
@ -415,8 +420,8 @@ where
|
|||
fn process(&mut self) {
|
||||
while let Ok(message) = self.receiver.try_recv() {
|
||||
match message {
|
||||
RendererMessage::Prepare { width, height } => self.attempt_resize(width, height),
|
||||
RendererMessage::Resize { width, height } => self.attempt_resize(width, height),
|
||||
RendererMessage::Resize { width, height }
|
||||
| RendererMessage::Prepare { width, height } => self.attempt_resize(width, height),
|
||||
RendererMessage::Display { buffer } => self.display(buffer),
|
||||
RendererMessage::SetTitle { title } => self.window.set_title(&title),
|
||||
RendererMessage::Rumble { rumble: _ } => todo!(),
|
||||
|
@ -428,6 +433,7 @@ where
|
|||
self.width = width;
|
||||
self.height = height;
|
||||
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
let real_factor = (self.window.scale_factor() * self.factor as f64) as u32;
|
||||
|
||||
let real_width = (width as u32) * real_factor;
|
||||
|
|
|
@ -3,6 +3,9 @@ name = "twinc_emu_vst"
|
|||
version = "0.5.1"
|
||||
edition = "2021"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ impl Default for VstConfig {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
scale_factor: 3,
|
||||
rom: String::from(""),
|
||||
rom: String::new(),
|
||||
force_skip_bootrom: true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ impl Plugin for GameboyEmu {
|
|||
if let Ok(comms) = self.emu_comms.lock() {
|
||||
if let Some(ref comms) = *comms {
|
||||
match comms.sender.send(EmulatorMessage::Exit) {
|
||||
Ok(_) => self.vars = None,
|
||||
Ok(()) => self.vars = None,
|
||||
Err(e) => nih_log!("error {e} sending message to emulator"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ impl Editor for TwincEditor {
|
|||
}
|
||||
|
||||
fn size(&self) -> (u32, u32) {
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
(self.size.width as u32, self.size.height as u32)
|
||||
}
|
||||
|
||||
|
@ -127,6 +128,7 @@ impl TwincEditorWindow {
|
|||
size: Size,
|
||||
shader_path: Option<std::path::PathBuf>,
|
||||
) -> Self {
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
let current_resolution = ResolutionData {
|
||||
real_width: size.width as u32,
|
||||
real_height: size.height as u32,
|
||||
|
@ -152,17 +154,17 @@ impl TwincEditorWindow {
|
|||
if let Some(ref comms) = *comms {
|
||||
while let Ok(e) = comms.receiver.try_recv() {
|
||||
match e {
|
||||
RendererMessage::Display { buffer } => self.latest_buf = buffer,
|
||||
RendererMessage::Prepare {
|
||||
width: _,
|
||||
height: _,
|
||||
} => {}
|
||||
RendererMessage::Resize {
|
||||
}
|
||||
| RendererMessage::Resize {
|
||||
width: _,
|
||||
height: _,
|
||||
} => {}
|
||||
RendererMessage::Display { buffer } => self.latest_buf = buffer,
|
||||
RendererMessage::SetTitle { title: _ } => {}
|
||||
RendererMessage::Rumble { rumble: _ } => {}
|
||||
}
|
||||
| RendererMessage::SetTitle { title: _ }
|
||||
| RendererMessage::Rumble { rumble: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +224,7 @@ impl WindowHandler for TwincEditorWindow {
|
|||
self.joypad_state,
|
||||
),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Ok(()) => {}
|
||||
Err(e) => nih_error!("error sending joypad update: {e:#?}"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
description = "TWINC Game Boy (CGB/DMG) emulator GUI"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bundle]
|
||||
identifier = "com.alexjanka.TWINC.gui"
|
||||
osx_file_extensions = [[["Game Boy ROM", "Viewer"], ["gb", "gbc"]]]
|
||||
|
|
|
@ -81,7 +81,7 @@ impl ObjectImpl for GameListWindow {
|
|||
.and_then(move |v| v.downcast::<GameListEntryObject>().ok())
|
||||
.unwrap()
|
||||
.path()
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ name = "gb-emu-lib"
|
|||
version = "0.5.1"
|
||||
edition = "2021"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = ["config"]
|
||||
clocked-serial = []
|
||||
|
|
|
@ -33,42 +33,39 @@ impl ConfigManager {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn dir(&self) -> PathBuf {
|
||||
#[must_use] pub fn dir(&self) -> PathBuf {
|
||||
self.path.clone()
|
||||
}
|
||||
|
||||
pub fn load_or_create_base_config(&self) -> Config {
|
||||
#[must_use] pub fn load_or_create_base_config(&self) -> Config {
|
||||
self.load_or_create_config()
|
||||
}
|
||||
|
||||
pub fn load_or_create_config<C>(&self) -> C
|
||||
#[must_use] pub fn load_or_create_config<C>(&self) -> C
|
||||
where
|
||||
C: NamedConfig + Serialize + DeserializeOwned + Default + Clone,
|
||||
{
|
||||
match self.load_custom_config::<C>() {
|
||||
Some(v) => {
|
||||
let _ = self.save_custom_config(v.clone());
|
||||
v
|
||||
}
|
||||
None => {
|
||||
let config = C::default();
|
||||
if let Ok(true) = self.path.join(C::name()).try_exists() {
|
||||
log::error!(
|
||||
"Failed to load \"{}\" config, but it exists on disk",
|
||||
C::name()
|
||||
);
|
||||
} else {
|
||||
let result = self.save_custom_config(config.clone());
|
||||
if let Err(e) = result {
|
||||
log::error!("Failed to save \"{}\" config: {e:#?}", C::name());
|
||||
}
|
||||
if let Some(v) = self.load_custom_config::<C>() {
|
||||
let _ = self.save_custom_config(v.clone());
|
||||
v
|
||||
} else {
|
||||
let config = C::default();
|
||||
if let Ok(true) = self.path.join(C::name()).try_exists() {
|
||||
log::error!(
|
||||
"Failed to load \"{}\" config, but it exists on disk",
|
||||
C::name()
|
||||
);
|
||||
} else {
|
||||
let result = self.save_custom_config(config.clone());
|
||||
if let Err(e) = result {
|
||||
log::error!("Failed to save \"{}\" config: {e:#?}", C::name());
|
||||
}
|
||||
config
|
||||
}
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_custom_config<C>(&self) -> Option<C>
|
||||
#[must_use] pub fn load_custom_config<C>(&self) -> Option<C>
|
||||
where
|
||||
C: NamedConfig + DeserializeOwned + Default,
|
||||
{
|
||||
|
|
|
@ -58,8 +58,7 @@ impl RomFile {
|
|||
let save_location = match save {
|
||||
SramType::File(path) => Some(SaveDataLocation::File(path)),
|
||||
SramType::RawBuffer(buf) => Some(SaveDataLocation::Raw(buf)),
|
||||
SramType::Auto => None,
|
||||
SramType::None => None,
|
||||
SramType::Auto | SramType::None => None,
|
||||
};
|
||||
Ok(Rom::load(data, save_location))
|
||||
}
|
||||
|
@ -84,6 +83,7 @@ pub enum RendererMessage<Format: From<Colour>> {
|
|||
}
|
||||
|
||||
impl<Format: From<Colour>> RendererMessage<Format> {
|
||||
#[must_use]
|
||||
pub fn display_message(buffer: Vec<Format>) -> Self {
|
||||
Self::Display { buffer }
|
||||
}
|
||||
|
@ -105,11 +105,13 @@ pub struct AudioOutput {
|
|||
}
|
||||
|
||||
impl AudioOutput {
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
sample_rate: f32,
|
||||
buffers_per_frame: usize,
|
||||
downsample_type: DownsampleType,
|
||||
) -> (Self, AsyncHeapCons<[f32; 2]>) {
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
let rb_len = (sample_rate as usize / 60) / buffers_per_frame;
|
||||
|
||||
let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len);
|
||||
|
@ -190,12 +192,11 @@ where
|
|||
#[allow(unused)]
|
||||
pub(crate) fn tick(&mut self, steps: usize) {
|
||||
if self.counter > 0 {
|
||||
self.counter = match self.counter.checked_sub(steps) {
|
||||
Some(num) => num,
|
||||
None => {
|
||||
self.next_image = Some(self.inner.get_image());
|
||||
0
|
||||
}
|
||||
self.counter = if let Some(num) = self.counter.checked_sub(steps) {
|
||||
num
|
||||
} else {
|
||||
self.next_image = Some(self.inner.get_image());
|
||||
0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +243,7 @@ impl<ColourFormat> EmulatorOptions<ColourFormat>
|
|||
where
|
||||
ColourFormat: From<Colour> + Copy,
|
||||
{
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
window: Option<Sender<RendererMessage<ColourFormat>>>,
|
||||
rom: Rom,
|
||||
|
@ -293,41 +295,49 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_sram_buffer(mut self, buffer: Arc<RwLock<Vec<u8>>>) -> Self {
|
||||
self.save = Some(SramType::RawBuffer(buffer));
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_dmg_bootrom(mut self, dmg_bootrom: Option<RomFile>) -> Self {
|
||||
self.dmg_bootrom = dmg_bootrom;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_cgb_bootrom(mut self, cgb_bootrom: Option<RomFile>) -> Self {
|
||||
self.cgb_bootrom = cgb_bootrom;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_show_bootrom(mut self, show_bootrom: bool) -> Self {
|
||||
self.show_bootrom = show_bootrom;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_no_output(mut self, no_output: bool) -> Self {
|
||||
self.no_output = no_output;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_stdout(mut self) -> Self {
|
||||
self.serial_target = SerialTarget::Stdout(StdoutType::Ascii);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_serial_target(mut self, target: SerialTarget) -> Self {
|
||||
self.serial_target = target;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_tile_window(
|
||||
mut self,
|
||||
window: Option<Sender<RendererMessage<ColourFormat>>>,
|
||||
|
@ -336,6 +346,7 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_layer_window(
|
||||
mut self,
|
||||
window: Option<Sender<RendererMessage<ColourFormat>>>,
|
||||
|
@ -344,6 +355,7 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_cgb_mode(mut self, cgb_mode: bool) -> Self {
|
||||
self.cgb_mode = cgb_mode;
|
||||
self
|
||||
|
|
|
@ -67,7 +67,7 @@ where
|
|||
rom.mbc_type(),
|
||||
if is_cgb_mode { "CGB" } else { "DMG" }
|
||||
),
|
||||
})?
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(Self::new(
|
||||
|
@ -167,7 +167,7 @@ where
|
|||
EmulatorMessage::Start => self.paused = false,
|
||||
EmulatorMessage::Pause => self.paused = true,
|
||||
EmulatorMessage::JoypadUpdate(new_state) => {
|
||||
self.cpu.next_joypad_state = Some(new_state)
|
||||
self.cpu.next_joypad_state = Some(new_state);
|
||||
}
|
||||
EmulatorMessage::NewLayerWindow(new) => self.cpu.memory.gpu.set_layer_window(new),
|
||||
EmulatorMessage::NewTileWindow(new) => self.cpu.memory.gpu.set_tile_window(new),
|
||||
|
|
|
@ -103,9 +103,9 @@ where
|
|||
|
||||
pub(crate) fn set_or_clear_flag(&mut self, flag: Flags, state: bool) {
|
||||
if state {
|
||||
self.set_flag(flag)
|
||||
self.set_flag(flag);
|
||||
} else {
|
||||
self.clear_flag(flag)
|
||||
self.clear_flag(flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ where
|
|||
self.set_or_clear_flag(Flags::Zero, result == 0x0);
|
||||
self.set_or_clear_flag(
|
||||
Flags::HalfCarry,
|
||||
first.get_low_nibble() + second.get_low_nibble() + if with_carry { 1 } else { 0 } > 0xF,
|
||||
first.get_low_nibble() + second.get_low_nibble() + u8::from(with_carry) > 0xF,
|
||||
);
|
||||
result
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ impl Wram {
|
|||
bank_0: Box::new([0; 4096]),
|
||||
banks: if cgb {
|
||||
WramBanks::Cgb {
|
||||
banks: Box::new([[0; 4096]; 8]),
|
||||
banks: crate::util::boxed_array([0; 4096]),
|
||||
selected: 0,
|
||||
}
|
||||
} else {
|
||||
|
@ -218,7 +218,7 @@ where
|
|||
Address::Prohibited(_) => 0xFF,
|
||||
Address::Io(address) => self.get_io(address),
|
||||
Address::Hram(address) => self.cpu_ram[address.get_local() as usize],
|
||||
Address::InterruptEnable(_) => self.interrupts.get_enable_register(),
|
||||
Address::InterruptEnable(()) => self.interrupts.get_enable_register(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,25 +253,25 @@ where
|
|||
Address::CartRam(address) => self.rom.set_ram(address, data),
|
||||
Address::WorkRam(address) => self.ram.bank_0[address.get_local() as usize] = data,
|
||||
Address::BankedWorkRam(address) => {
|
||||
self.ram.set_banked(address.get_local() as usize, data)
|
||||
self.ram.set_banked(address.get_local() as usize, data);
|
||||
}
|
||||
Address::MirroredWorkRam(address) => {
|
||||
self.ram.bank_0[address.get_local() as usize] = data
|
||||
self.ram.bank_0[address.get_local() as usize] = data;
|
||||
}
|
||||
Address::MirroredBankedWorkRam(address) => {
|
||||
self.ram.set_banked(address.get_local() as usize, data)
|
||||
self.ram.set_banked(address.get_local() as usize, data);
|
||||
}
|
||||
Address::Oam(address) => self.gpu.set_oam(address, data),
|
||||
Address::Prohibited(_) => {}
|
||||
Address::Io(address) => {
|
||||
if address.inner() == 0xFF50 {
|
||||
self.bootrom = None
|
||||
self.bootrom = None;
|
||||
} else {
|
||||
self.set_io(address, data)
|
||||
self.set_io(address, data);
|
||||
}
|
||||
}
|
||||
Address::Hram(address) => self.cpu_ram[address.get_local() as usize] = data,
|
||||
Address::InterruptEnable(_) => self.interrupts.set_enable_register(data),
|
||||
Address::InterruptEnable(()) => self.interrupts.set_enable_register(data),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,16 +380,17 @@ where
|
|||
CgbIoAddress::PrepareSpeed => cgb_peripherals.double_speed.set(data),
|
||||
CgbIoAddress::VramBank => self.gpu.vram.set_vram_bank(data),
|
||||
CgbIoAddress::VramDma(address) => {
|
||||
cgb_peripherals.vram_dma.set_register(address, data)
|
||||
cgb_peripherals.vram_dma.set_register(address, data);
|
||||
}
|
||||
CgbIoAddress::Infrared => cgb_peripherals.infrared.set(data),
|
||||
CgbIoAddress::Palette(address) => self.gpu.set_cgb_palette(address, data),
|
||||
CgbIoAddress::ObjPriority => self.gpu.set_obj_priority(data),
|
||||
CgbIoAddress::WramBank => *selected = (data & 0b111).max(1) as usize,
|
||||
CgbIoAddress::Pcm12 => {}
|
||||
CgbIoAddress::Pcm34 => {}
|
||||
CgbIoAddress::Pcm12 | CgbIoAddress::Pcm34 => {}
|
||||
CgbIoAddress::Unused(v) => {
|
||||
log::error!("attempt to set unused address 0x{v:0>4X} to 0x{data:0>2X}")
|
||||
log::error!(
|
||||
"attempt to set unused address 0x{v:0>4X} to 0x{data:0>2X}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ impl AddressMarker for Address {
|
|||
Address::Prohibited(v) => v.inner(),
|
||||
Address::Io(v) => v.inner(),
|
||||
Address::Hram(v) => v.inner(),
|
||||
Address::InterruptEnable(_) => 0xFFFF,
|
||||
Address::InterruptEnable(()) => 0xFFFF,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ impl<const MIN: u16, const MAX: u16> TryInto<BoundedAddress<MIN, MAX>> for u16 {
|
|||
}
|
||||
|
||||
impl<const MIN: u16, const MAX: u16> BoundedAddress<MIN, MAX> {
|
||||
pub(crate) fn get_local(&self) -> u16 {
|
||||
pub(crate) fn get_local(self) -> u16 {
|
||||
self.0 - MIN
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::util::get_bit;
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, Serialize, Deserialize)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
struct InterruptRegister {
|
||||
vblank: bool,
|
||||
lcd_stat: bool,
|
||||
|
@ -12,7 +13,7 @@ struct InterruptRegister {
|
|||
}
|
||||
|
||||
impl InterruptRegister {
|
||||
fn as_register(&self) -> u8 {
|
||||
fn as_register(self) -> u8 {
|
||||
bool_to_shifted(self.vblank, 0)
|
||||
| bool_to_shifted(self.lcd_stat, 1)
|
||||
| bool_to_shifted(self.timer, 2)
|
||||
|
@ -30,7 +31,7 @@ impl InterruptRegister {
|
|||
}
|
||||
|
||||
fn bool_to_shifted(input: bool, shift: u8) -> u8 {
|
||||
(if input { 1 } else { 0 }) << shift
|
||||
u8::from(input) << shift
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
|
|
@ -32,16 +32,16 @@ impl DacSample {
|
|||
}
|
||||
|
||||
fn mix_channel(&self, sums: f32, volume: u8) -> f32 {
|
||||
sums * ((volume + 1) as f32 / (8. * 4.))
|
||||
sums * (f32::from(volume + 1) / (8. * 4.))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Apu {
|
||||
apu_enable: bool,
|
||||
enable: bool,
|
||||
channels: Channels,
|
||||
vin: VinEnable,
|
||||
mixer: Mixer,
|
||||
div_apu: u8,
|
||||
div: u8,
|
||||
converter: Downsampler,
|
||||
output: AudioOutput,
|
||||
}
|
||||
|
@ -49,11 +49,11 @@ pub struct Apu {
|
|||
impl Apu {
|
||||
pub fn new(output: AudioOutput) -> Self {
|
||||
Self {
|
||||
apu_enable: true,
|
||||
enable: true,
|
||||
channels: Channels::default(),
|
||||
vin: VinEnable::default(),
|
||||
mixer: Mixer::default(),
|
||||
div_apu: 0,
|
||||
div: 0,
|
||||
converter: Downsampler::new(output.sample_rate, output.downsample_type),
|
||||
output,
|
||||
}
|
||||
|
@ -65,18 +65,18 @@ impl Apu {
|
|||
}
|
||||
|
||||
pub fn div_apu_tick(&mut self) {
|
||||
self.div_apu = self.div_apu.wrapping_add(1);
|
||||
if self.div_apu % 8 == 0 {
|
||||
self.div = self.div.wrapping_add(1);
|
||||
if self.div % 8 == 0 {
|
||||
// envelope sweep
|
||||
self.channels.one.envelope_tick();
|
||||
self.channels.two.envelope_tick();
|
||||
self.channels.four.envelope_tick();
|
||||
}
|
||||
if self.div_apu % 4 == 0 {
|
||||
if self.div % 4 == 0 {
|
||||
// ch1 frequency sweep
|
||||
self.channels.one.frequency_tick();
|
||||
}
|
||||
if self.div_apu % 2 == 0 {
|
||||
if self.div % 2 == 0 {
|
||||
// tick sound length timers
|
||||
self.channels.one.length_tick();
|
||||
self.channels.two.length_tick();
|
||||
|
@ -124,7 +124,7 @@ impl Apu {
|
|||
}
|
||||
|
||||
pub(crate) fn get_register(&self, addr: AudioAddress) -> u8 {
|
||||
if self.apu_enable {
|
||||
if self.enable {
|
||||
self.make_register(addr)
|
||||
} else {
|
||||
match addr.inner() {
|
||||
|
@ -178,11 +178,7 @@ impl Apu {
|
|||
}
|
||||
0xFF26 => {
|
||||
// NR52 - Sound on/off
|
||||
let mut v = if self.apu_enable {
|
||||
0b11111111
|
||||
} else {
|
||||
0b01111111
|
||||
};
|
||||
let mut v = if self.enable { 0b11111111 } else { 0b01111111 };
|
||||
v = set_or_clear_bit(v, 0, self.channels.one.is_dac_enabled());
|
||||
v = set_or_clear_bit(v, 1, self.channels.two.is_dac_enabled());
|
||||
v = set_or_clear_bit(v, 2, self.channels.three.is_dac_enabled());
|
||||
|
@ -190,7 +186,7 @@ impl Apu {
|
|||
v
|
||||
}
|
||||
// write-only registers
|
||||
0xFF13 | 0xFF18 | 0xFF1B | 0xFF1D | 0xFF20 => 0xFF,
|
||||
0xFF13 | 0xFF18 | 0xFF1B | 0xFF1D | 0xFF20 |
|
||||
// not registers
|
||||
0xFF15 | 0xFF1F => 0xFF,
|
||||
0x0..0xFF10 | 0xFF27..=0xFFFF => unreachable!(),
|
||||
|
@ -198,6 +194,7 @@ impl Apu {
|
|||
}
|
||||
|
||||
pub(crate) fn mmio_write(&mut self, addr: AudioAddress, data: u8) {
|
||||
#[allow(clippy::match_same_arms)]
|
||||
match addr.inner() {
|
||||
0xFF10 => self.channels.one.update_sweep(data),
|
||||
0xFF11 => self.channels.one.update_length_timer_and_duty_cycle(data),
|
||||
|
@ -236,7 +233,7 @@ impl Apu {
|
|||
self.mixer.ch4.left = Volume::from_bool(get_bit(data, 7));
|
||||
}
|
||||
0xFF26 => {
|
||||
if !self.apu_enable {
|
||||
if !self.enable {
|
||||
for i in 0xFF10..0xFF20 {
|
||||
self.mmio_write(i.try_into().unwrap(), 0x0);
|
||||
}
|
||||
|
@ -244,7 +241,7 @@ impl Apu {
|
|||
self.mmio_write(i.try_into().unwrap(), 0x0);
|
||||
}
|
||||
}
|
||||
self.apu_enable = (1 << 7) == (data & 0b10000000);
|
||||
self.enable = (1 << 7) == (data & 0b10000000);
|
||||
}
|
||||
0x0..0xFF10 | 0xFF27..=0xFFFF => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -59,10 +59,10 @@ impl Envelope {
|
|||
self.counter = 0;
|
||||
match self.mode {
|
||||
EnvelopeMode::Increase => {
|
||||
self.current_volume = self.current_volume.saturating_add(1)
|
||||
self.current_volume = self.current_volume.saturating_add(1);
|
||||
}
|
||||
EnvelopeMode::Decrease => {
|
||||
self.current_volume = self.current_volume.saturating_sub(1)
|
||||
self.current_volume = self.current_volume.saturating_sub(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ const FIFTY: [u8; 8] = [1, 0, 0, 0, 0, 1, 1, 1];
|
|||
const SEVENTY_FIVE: [u8; 8] = [0, 1, 1, 1, 1, 1, 1, 0];
|
||||
|
||||
impl DutyCycle {
|
||||
fn get_waveform(&self, index: usize) -> u8 {
|
||||
fn get_waveform(self, index: usize) -> u8 {
|
||||
match self {
|
||||
DutyCycle::TwelvePointFive => TWELVE_POINT_FIVE[index],
|
||||
DutyCycle::TwentyFive => TWENTY_FIVE[index],
|
||||
|
@ -114,7 +114,7 @@ impl DutyCycle {
|
|||
}
|
||||
}
|
||||
|
||||
fn as_u8(&self) -> u8 {
|
||||
fn as_u8(self) -> u8 {
|
||||
match self {
|
||||
DutyCycle::TwelvePointFive => 0b00,
|
||||
DutyCycle::TwentyFive => 0b01,
|
||||
|
@ -190,7 +190,7 @@ impl PwmChannel {
|
|||
|
||||
fn dac(&mut self, digital: u8) -> f32 {
|
||||
self.last = digital;
|
||||
(((digital as f32) * (-2.)) + 1.) * ((self.envelope.current_volume as f32) / 15.)
|
||||
((f32::from(digital) * (-2.)) + 1.) * (f32::from(self.envelope.current_volume) / 15.)
|
||||
}
|
||||
|
||||
pub(super) fn envelope_tick(&mut self) {
|
||||
|
@ -206,7 +206,7 @@ impl PwmChannel {
|
|||
self.sweep.counter += 1;
|
||||
if self.sweep.counter % self.sweep.pace == 0 {
|
||||
self.sweep.counter = 0;
|
||||
let wavelength_diff = self.wavelength / (2_u16.pow(self.sweep.slope as u32));
|
||||
let wavelength_diff = self.wavelength / (2_u16.pow(u32::from(self.sweep.slope)));
|
||||
let new_wavelength = match self.sweep.mode {
|
||||
EnvelopeMode::Increase => self.wavelength + wavelength_diff,
|
||||
EnvelopeMode::Decrease => self.wavelength.saturating_sub(wavelength_diff),
|
||||
|
@ -280,13 +280,13 @@ impl PwmChannel {
|
|||
}
|
||||
|
||||
pub(super) fn update_wavelength_low(&mut self, data: u8) {
|
||||
self.wavelength = (self.wavelength & 0xFF00) | (data as u16);
|
||||
self.wavelength = (self.wavelength & 0xFF00) | u16::from(data);
|
||||
self.set_wave_timer();
|
||||
}
|
||||
|
||||
pub(super) fn update_wavelength_high_and_control(&mut self, data: u8) {
|
||||
self.length_enable = get_bit(data, 6);
|
||||
self.wavelength = (self.wavelength & 0xFF) | (((data & 0b111) as u16) << 8);
|
||||
self.wavelength = (self.wavelength & 0xFF) | (u16::from(data & 0b111) << 8);
|
||||
self.set_wave_timer();
|
||||
if get_bit(data, 7) {
|
||||
self.trigger();
|
||||
|
@ -315,7 +315,7 @@ enum ShiftVolumePercent {
|
|||
}
|
||||
|
||||
impl ShiftVolumePercent {
|
||||
fn as_shift_amount(&self) -> u8 {
|
||||
fn as_shift_amount(self) -> u8 {
|
||||
match self {
|
||||
ShiftVolumePercent::Zero => 8,
|
||||
ShiftVolumePercent::TwentyFive => 2,
|
||||
|
@ -404,7 +404,7 @@ impl WaveChannel {
|
|||
fn dac(&mut self, digital: u8) -> f32 {
|
||||
if self.dac_enabled && self.volume != ShiftVolumePercent::Zero {
|
||||
self.last = digital;
|
||||
((((digital >> self.volume.as_shift_amount()) as f32) * (-2.)) + 1.) / 15.
|
||||
((f32::from(digital >> self.volume.as_shift_amount()) * (-2.)) + 1.) / 15.
|
||||
} else {
|
||||
self.last = 0;
|
||||
0.
|
||||
|
@ -453,13 +453,13 @@ impl WaveChannel {
|
|||
}
|
||||
|
||||
pub(super) fn update_wavelength_low(&mut self, data: u8) {
|
||||
self.wavelength = (self.wavelength & 0xFF00) | (data as u16);
|
||||
self.wavelength = (self.wavelength & 0xFF00) | u16::from(data);
|
||||
self.set_wave_timer();
|
||||
}
|
||||
|
||||
pub(super) fn update_wavelength_high_and_control(&mut self, data: u8) {
|
||||
self.length_enable = get_bit(data, 6);
|
||||
self.wavelength = (self.wavelength & 0xFF) | (((data & 0b111) as u16) << 8);
|
||||
self.wavelength = (self.wavelength & 0xFF) | (u16::from(data & 0b111) << 8);
|
||||
self.set_wave_timer();
|
||||
if get_bit(data, 7) {
|
||||
self.trigger();
|
||||
|
@ -472,9 +472,10 @@ impl WaveChannel {
|
|||
|
||||
pub(super) fn update_wave_ram(&mut self, addr: WaveRamAddress, data: u8) {
|
||||
let real_addr = addr.get_local() as usize;
|
||||
if real_addr >= self.wave_ram.data.len() {
|
||||
panic!("sent the wrong address to update_wave_ram");
|
||||
}
|
||||
assert!(
|
||||
real_addr < self.wave_ram.data.len(),
|
||||
"sent the wrong address to update_wave_ram"
|
||||
);
|
||||
self.wave_ram.data[real_addr] = data;
|
||||
}
|
||||
|
||||
|
@ -506,8 +507,8 @@ struct Lfsr {
|
|||
|
||||
impl Lfsr {
|
||||
fn update(&mut self) {
|
||||
self.interval = (1_u16 << (self.clock_shift as u16))
|
||||
.wrapping_mul(1 + (2 * self.clock_divider as u16))
|
||||
self.interval = (1_u16 << u16::from(self.clock_shift))
|
||||
.wrapping_mul(1 + (2 * u16::from(self.clock_divider)))
|
||||
.wrapping_mul(8);
|
||||
}
|
||||
|
||||
|
@ -520,21 +521,13 @@ impl Lfsr {
|
|||
}
|
||||
|
||||
fn next_value(&mut self) {
|
||||
let next = if (self.register & 0b1) == ((self.register >> 1) & 0b1) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let next = u16::from((self.register & 0b1) == ((self.register >> 1) & 0b1));
|
||||
self.register = (self.register & !(0b1 << 15)) | (next << 15);
|
||||
if self.width == LfsrWidth::SevenBit {
|
||||
self.register = (self.register & !(0b1 << 7)) | (next << 7);
|
||||
}
|
||||
self.register >>= 1;
|
||||
self.current_value = if (self.register & 0b1) == 0b1 {
|
||||
0x1
|
||||
} else {
|
||||
0x0
|
||||
};
|
||||
self.current_value = u8::from((self.register & 0b1) == 0b1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,7 +594,7 @@ impl NoiseChannel {
|
|||
|
||||
fn dac(&mut self, digital: u8) -> f32 {
|
||||
self.last = digital;
|
||||
(((digital as f32) * (-2.)) + 1.) * ((self.envelope.current_volume as f32) / 15.)
|
||||
((f32::from(digital) * (-2.)) + 1.) * (f32::from(self.envelope.current_volume) / 15.)
|
||||
}
|
||||
|
||||
pub(super) fn envelope_tick(&mut self) {
|
||||
|
|
|
@ -15,7 +15,7 @@ impl Default for Averager {
|
|||
}
|
||||
|
||||
impl Averager {
|
||||
fn push(&mut self, next: &[f32; 2]) {
|
||||
fn push(&mut self, next: [f32; 2]) {
|
||||
self.accum[0] += next[0];
|
||||
self.accum[1] += next[1];
|
||||
self.num += 1;
|
||||
|
@ -58,7 +58,7 @@ impl Downsampler {
|
|||
pub fn push(&mut self, signal: [f32; 2]) -> Option<[f32; 2]> {
|
||||
self.time_accum += 1.;
|
||||
if let Some(ref mut averager) = self.average {
|
||||
averager.push(&signal);
|
||||
averager.push(signal);
|
||||
}
|
||||
if self.time_accum >= self.ratio {
|
||||
self.time_accum -= self.ratio;
|
||||
|
|
|
@ -34,14 +34,14 @@ pub(super) enum Volume {
|
|||
}
|
||||
|
||||
impl Volume {
|
||||
pub(super) fn gate(&self, val: f32) -> f32 {
|
||||
pub(super) fn gate(self, val: f32) -> f32 {
|
||||
match self {
|
||||
Volume::Muted => 0.,
|
||||
Volume::Enabled => val,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn bool(&self) -> bool {
|
||||
pub(super) fn bool(self) -> bool {
|
||||
match self {
|
||||
Volume::Muted => false,
|
||||
Volume::Enabled => true,
|
||||
|
|
|
@ -8,8 +8,8 @@ pub(crate) struct DoubleSpeed {
|
|||
}
|
||||
|
||||
impl DoubleSpeed {
|
||||
pub(crate) fn get(&self) -> u8 {
|
||||
0b01111110 | if self.current { 0b1 << 7 } else { 0 } | if self.prepared { 0b1 } else { 0 }
|
||||
pub(crate) fn get(self) -> u8 {
|
||||
0b01111110 | if self.current { 0b1 << 7 } else { 0 } | u8::from(self.prepared)
|
||||
}
|
||||
|
||||
pub(crate) fn set(&mut self, data: u8) {
|
||||
|
|
|
@ -9,8 +9,8 @@ pub struct Infrared {
|
|||
}
|
||||
|
||||
impl Infrared {
|
||||
pub(crate) fn get(&self) -> u8 {
|
||||
0b111110 | if self.led { 1 } else { 0 } | if self.read_enable { 0b11 << 6 } else { 0 }
|
||||
pub(crate) fn get(self) -> u8 {
|
||||
0b111110 | u8::from(self.led) | if self.read_enable { 0b11 << 6 } else { 0 }
|
||||
}
|
||||
|
||||
pub(crate) fn set(&mut self, data: u8) {
|
||||
|
|
|
@ -26,10 +26,10 @@ enum DmaMode {
|
|||
}
|
||||
|
||||
impl DmaMode {
|
||||
fn get_byte(&self) -> u8 {
|
||||
fn get_byte(self) -> u8 {
|
||||
match self {
|
||||
DmaMode::Halt(_) => unreachable!(),
|
||||
DmaMode::Hblank(v, _) => *v,
|
||||
DmaMode::Hblank(v, _) => v,
|
||||
DmaMode::Waiting => 0xFF,
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ impl Default for DmaMode {
|
|||
}
|
||||
|
||||
impl VramDma {
|
||||
pub(crate) fn get_register(&self, address: VramDmaAddress) -> u8 {
|
||||
pub(crate) fn get_register(self, address: VramDmaAddress) -> u8 {
|
||||
match address.inner() {
|
||||
0xFF51 => self.source.get_high(),
|
||||
0xFF52 => self.source.get_low(),
|
||||
|
@ -88,7 +88,7 @@ where
|
|||
let returning = if let Some(cgb_peripherals) = &mut self.cgb_peripherals {
|
||||
match cgb_peripherals.vram_dma.mode {
|
||||
DmaMode::Halt(l) => {
|
||||
let length = 16 * ((l as u16) + 1);
|
||||
let length = 16 * (u16::from(l) + 1);
|
||||
copy = Some((
|
||||
cgb_peripherals.vram_dma.source,
|
||||
cgb_peripherals.vram_dma.destination,
|
||||
|
@ -109,7 +109,7 @@ where
|
|||
cgb_peripherals.vram_dma.source += length;
|
||||
cgb_peripherals.vram_dma.destination += length;
|
||||
*progress += 1;
|
||||
if *progress > (l as u16) {
|
||||
if *progress > u16::from(l) {
|
||||
cgb_peripherals.vram_dma.mode = DmaMode::Waiting;
|
||||
cgb_peripherals.vram_dma.reset_registers();
|
||||
}
|
||||
|
|
|
@ -41,10 +41,8 @@ where
|
|||
type BufferType = T;
|
||||
|
||||
fn new_buffer(default: Self::BufferType) -> Self {
|
||||
let mut v: Vec<T> = Vec::new();
|
||||
v.resize(SIZE, default);
|
||||
let temp = v.into_boxed_slice();
|
||||
unsafe { Box::from_raw(Box::into_raw(temp) as *mut [T; SIZE]) }
|
||||
let temp = vec![default; SIZE].into_boxed_slice();
|
||||
unsafe { Box::from_raw(Box::into_raw(temp).cast::<[T; SIZE]>()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +192,7 @@ where
|
|||
|| (self.stat.vblank_interrupt_enabled && (self.stat.mode == DrawMode::VBlank))
|
||||
|| (self.stat.hblank_interrupt_enabled && (self.stat.mode == DrawMode::HBlank));
|
||||
|
||||
interrupts.lcd_stat = this_stat & !self.prev_stat;
|
||||
interrupts.lcd_stat = this_stat && !self.prev_stat;
|
||||
self.prev_stat = this_stat;
|
||||
interrupts
|
||||
}
|
||||
|
@ -204,7 +202,7 @@ where
|
|||
}
|
||||
|
||||
pub(crate) fn set_vram(&mut self, address: VramAddress, data: u8) {
|
||||
self.vram.set(address, data)
|
||||
self.vram.set(address, data);
|
||||
}
|
||||
|
||||
pub(crate) fn get_oam(&self, address: OamAddress) -> u8 {
|
||||
|
@ -217,7 +215,7 @@ where
|
|||
|
||||
pub(crate) fn set_oam(&mut self, address: OamAddress, data: u8) {
|
||||
if self.stat.mode == DrawMode::VBlank || self.stat.mode == DrawMode::HBlank {
|
||||
self.oam.set(address, data)
|
||||
self.oam.set(address, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,8 +358,8 @@ where
|
|||
}
|
||||
let tile_row = object_row % 8;
|
||||
let tile_addr = (TiledataArea::D8000
|
||||
.get_addr(object.tile_index + if object_row >= 8 { 1 } else { 0 })
|
||||
+ (tile_row as u16 * 2))
|
||||
.get_addr(object.tile_index + u8::from(object_row >= 8))
|
||||
+ (u16::from(tile_row) * 2))
|
||||
.unwrap();
|
||||
let bank = if self.is_cgb_mode() {
|
||||
object.flags.cgb_vram_bank
|
||||
|
@ -418,7 +416,7 @@ where
|
|||
layer_window.set(
|
||||
buffer_index + (2 * HEIGHT * WIDTH),
|
||||
colour.rgb_bytes(cgb_data).into(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -445,7 +443,7 @@ where
|
|||
continue;
|
||||
}
|
||||
|
||||
let tilemap_column = (tile_line_x / 8) as u16;
|
||||
let tilemap_column = u16::from(tile_line_x / 8);
|
||||
|
||||
let tilemap_addr = tilemap.get_addr(row_addr + (tilemap_column));
|
||||
let attributes = if self.is_cgb_mode() {
|
||||
|
@ -467,8 +465,8 @@ where
|
|||
self.vram
|
||||
.get_with_bank(tilemap_addr, VramBank::Bank0)
|
||||
.unwrap(),
|
||||
) + tiledata_offset as u16)
|
||||
.unwrap();
|
||||
) + u16::from(tiledata_offset))
|
||||
.unwrap();
|
||||
|
||||
let lsbs = self
|
||||
.vram
|
||||
|
@ -505,7 +503,7 @@ where
|
|||
layer_window.set(
|
||||
(scanline as usize * WIDTH) + x + if is_bg { 0 } else { HEIGHT * WIDTH },
|
||||
colour.rgb_bytes(cgb_data).into(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,12 +37,12 @@ where
|
|||
}
|
||||
|
||||
pub fn get_lcdc(&self) -> u8 {
|
||||
(if self.lcdc.enable { 1 } else { 0 }) << 7
|
||||
u8::from(self.lcdc.enable) << 7
|
||||
| (match self.lcdc.window_tilemap {
|
||||
TilemapArea::T9800 => 0,
|
||||
TilemapArea::T9C00 => 1,
|
||||
}) << 6
|
||||
| (if self.lcdc.window_enable { 1 } else { 0 }) << 5
|
||||
| u8::from(self.lcdc.window_enable) << 5
|
||||
| (match self.lcdc.tile_area {
|
||||
TiledataArea::D8000 => 1,
|
||||
TiledataArea::D9000 => 0,
|
||||
|
@ -55,8 +55,8 @@ where
|
|||
ObjSize::S8x8 => 0,
|
||||
ObjSize::S8x16 => 1,
|
||||
}) << 2
|
||||
| (if self.lcdc.obj_enable { 1 } else { 0 }) << 1
|
||||
| (if self.lcdc.bg_window_enable { 1 } else { 0 })
|
||||
| u8::from(self.lcdc.obj_enable) << 1
|
||||
| u8::from(self.lcdc.bg_window_enable)
|
||||
}
|
||||
|
||||
pub fn update_lcd_status(&mut self, data: u8) {
|
||||
|
|
|
@ -68,7 +68,7 @@ impl CgbPalette {
|
|||
fn set_data(&mut self, data: u8) {
|
||||
self.data[self.index as usize] = data;
|
||||
if self.auto_increment {
|
||||
self.index = (self.index + 1) & 0b111111
|
||||
self.index = (self.index + 1) & 0b111111;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ where
|
|||
.sender
|
||||
.send(RendererMessage::display_message(new_buffer))
|
||||
{
|
||||
Ok(_) => {
|
||||
Ok(()) => {
|
||||
for val in self.buffer.iter_mut() {
|
||||
*val = get_blank_colour(cgb);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ where
|
|||
.sender
|
||||
.send(RendererMessage::display_message(self.buffer.clone()))
|
||||
{
|
||||
Ok(_) => Some(self),
|
||||
Ok(()) => Some(self),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ where
|
|||
tile_bank: bank,
|
||||
..Default::default()
|
||||
};
|
||||
let data_begin = data_begin + ((tile_x * 16) as u16);
|
||||
let data_begin = data_begin + (tile_x * 16);
|
||||
|
||||
for px_y in 0..8_u16 {
|
||||
let lsbs = memory
|
||||
|
|
|
@ -24,7 +24,7 @@ pub(super) enum TilemapArea {
|
|||
}
|
||||
|
||||
impl TilemapArea {
|
||||
pub(super) fn get_addr(&self, addr: u16) -> VramAddress {
|
||||
pub(super) fn get_addr(self, addr: u16) -> VramAddress {
|
||||
match self {
|
||||
TilemapArea::T9800 => (0x9800 + addr).try_into().unwrap(),
|
||||
TilemapArea::T9C00 => (0x9C00 + addr).try_into().unwrap(),
|
||||
|
@ -39,11 +39,11 @@ pub(super) enum TiledataArea {
|
|||
}
|
||||
|
||||
impl TiledataArea {
|
||||
pub(super) fn get_addr(&self, addr: u8) -> VramAddress {
|
||||
pub(super) fn get_addr(self, addr: u8) -> VramAddress {
|
||||
match self {
|
||||
TiledataArea::D8000 => (0x8000 + ((addr as u16) * 16)).try_into().unwrap(),
|
||||
TiledataArea::D8000 => (0x8000 + (u16::from(addr) * 16)).try_into().unwrap(),
|
||||
TiledataArea::D9000 => 0x9000_u16
|
||||
.wrapping_add_signed((as_signed(addr) as i16) * 16)
|
||||
.wrapping_add_signed(i16::from(as_signed(addr)) * 16)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ pub(super) enum ObjSize {
|
|||
}
|
||||
|
||||
impl ObjSize {
|
||||
pub(super) fn get_height(&self) -> u8 {
|
||||
pub(super) fn get_height(self) -> u8 {
|
||||
match self {
|
||||
ObjSize::S8x8 => 8,
|
||||
ObjSize::S8x16 => 16,
|
||||
|
@ -66,6 +66,7 @@ impl ObjSize {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub(super) struct Lcdc {
|
||||
pub(super) enable: bool,
|
||||
pub(super) window_tilemap: TilemapArea,
|
||||
|
@ -105,7 +106,7 @@ pub struct Colour(pub u8, pub u8, pub u8);
|
|||
|
||||
impl From<Colour> for u32 {
|
||||
fn from(value: Colour) -> Self {
|
||||
let (r, g, b) = (value.0 as u32, value.1 as u32, value.2 as u32);
|
||||
let (r, g, b) = (u32::from(value.0), u32::from(value.1), u32::from(value.2));
|
||||
(r << 16) | (g << 8) | b
|
||||
}
|
||||
}
|
||||
|
@ -139,17 +140,16 @@ pub(super) fn rgb_from_bytes(bytes: u16) -> Colour {
|
|||
}
|
||||
|
||||
impl ColourInner {
|
||||
pub(super) fn rgb_bytes(&self, cgb_data: Option<(&CgbPalette, u8)>) -> Colour {
|
||||
pub(super) fn rgb_bytes(self, cgb_data: Option<(&CgbPalette, u8)>) -> Colour {
|
||||
if let Some((cgb_palette, pallete_num)) = cgb_data {
|
||||
let offset: usize = (pallete_num as usize * 2 * 4)
|
||||
+ (if *self == ColourInner::Error {
|
||||
+ (if self == ColourInner::Error {
|
||||
if cfg!(feature = "error-colour") {
|
||||
return ERROR_COLOUR;
|
||||
} else {
|
||||
ColourInner::Zero
|
||||
}
|
||||
ColourInner::Zero
|
||||
} else {
|
||||
*self
|
||||
self
|
||||
} as usize
|
||||
* 2);
|
||||
|
||||
|
@ -180,13 +180,12 @@ impl ColourInner {
|
|||
}
|
||||
}
|
||||
|
||||
fn as_bits(&self) -> u8 {
|
||||
fn as_bits(self) -> u8 {
|
||||
match self {
|
||||
ColourInner::Zero => 0b00,
|
||||
ColourInner::Error | ColourInner::Zero => 0b00,
|
||||
ColourInner::One => 0b01,
|
||||
ColourInner::Two => 0b10,
|
||||
ColourInner::Three => 0b11,
|
||||
ColourInner::Error => 0b00,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,14 +208,14 @@ impl Palette {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn as_byte(&self) -> u8 {
|
||||
pub(super) fn as_byte(self) -> u8 {
|
||||
self.zero.as_bits()
|
||||
| (self.one.as_bits() << 2)
|
||||
| (self.two.as_bits() << 4)
|
||||
| (self.three.as_bits() << 6)
|
||||
}
|
||||
|
||||
pub(super) fn map_bits(&self, lsb: bool, msb: bool) -> (ColourInner, bool) {
|
||||
pub(super) fn map_bits(self, lsb: bool, msb: bool) -> (ColourInner, bool) {
|
||||
match (lsb, msb) {
|
||||
(true, true) => (self.three, false),
|
||||
(true, false) => (self.one, false),
|
||||
|
@ -249,6 +248,7 @@ pub(super) struct Object {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub(super) struct Stat {
|
||||
pub(super) lyc_eq_ly_interrupt_enabled: bool,
|
||||
pub(super) mode_2_interrupt_enabled: bool,
|
||||
|
@ -335,7 +335,7 @@ impl Vram {
|
|||
match self {
|
||||
Vram::Dmg { inner } => inner[address.get_local() as usize] = data,
|
||||
Vram::Cgb { inner, index } => {
|
||||
inner[*index as usize][address.get_local() as usize] = data
|
||||
inner[*index as usize][address.get_local() as usize] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct Joypad {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct JoypadState {
|
||||
pub down: bool,
|
||||
pub up: bool,
|
||||
|
|
|
@ -18,7 +18,7 @@ impl Default for OamDma {
|
|||
}
|
||||
|
||||
impl OamDma {
|
||||
pub(crate) fn get_register(&self) -> u8 {
|
||||
pub(crate) fn get_register(self) -> u8 {
|
||||
self.addr
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ impl OamDma {
|
|||
self.addr = data;
|
||||
}
|
||||
|
||||
pub(crate) fn is_active(&self) -> bool {
|
||||
pub(crate) fn is_active(self) -> bool {
|
||||
self.progress.is_some()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ const BYTE_DELAY: usize = 2000;
|
|||
const CLOCK_DIV: usize = CLOCK_SPEED / 8192;
|
||||
|
||||
impl InputByte {
|
||||
fn advance(&mut self, rx: &Option<Receiver<u8>>) -> u8 {
|
||||
fn advance(&mut self, rx: Option<&Receiver<u8>>) -> u8 {
|
||||
if let Some(byte) = self.byte {
|
||||
let val = (byte >> (7 - self.progress)) & 0b1;
|
||||
self.progress += 1;
|
||||
|
@ -83,7 +83,7 @@ impl InputByte {
|
|||
}
|
||||
}
|
||||
|
||||
fn try_fill(&mut self, rx: &Option<Receiver<u8>>) -> Option<u8> {
|
||||
fn try_fill(&mut self, rx: Option<&Receiver<u8>>) -> Option<u8> {
|
||||
self.byte = None;
|
||||
self.progress = 0;
|
||||
if let Some(rx) = rx {
|
||||
|
@ -96,7 +96,7 @@ impl InputByte {
|
|||
None
|
||||
}
|
||||
|
||||
fn is_ready(&mut self, rx: &Option<Receiver<u8>>) -> bool {
|
||||
fn is_ready(&mut self, rx: Option<&Receiver<u8>>) -> bool {
|
||||
if self.byte.is_none() {
|
||||
self.try_fill(rx);
|
||||
}
|
||||
|
@ -139,9 +139,9 @@ impl Serial {
|
|||
return false;
|
||||
}
|
||||
let rx = if let SerialTarget::Custom { rx, tx: _ } = &self.target {
|
||||
rx
|
||||
rx.as_ref()
|
||||
} else {
|
||||
&None
|
||||
None
|
||||
};
|
||||
for _ in 0..steps {
|
||||
#[cfg(feature = "clocked-serial")]
|
||||
|
@ -212,11 +212,7 @@ impl Serial {
|
|||
|
||||
pub fn get_control(&self) -> u8 {
|
||||
0b01111110
|
||||
| (if self.control.transfer_in_progress {
|
||||
0b1
|
||||
} else {
|
||||
0b0
|
||||
} << 7)
|
||||
| (u8::from(self.control.transfer_in_progress) << 7)
|
||||
| match self.control.clock_source {
|
||||
ClockSource::Internal => 0b1,
|
||||
ClockSource::External => 0b0,
|
||||
|
|
|
@ -20,7 +20,7 @@ impl TimerRate {
|
|||
}
|
||||
}
|
||||
|
||||
fn as_bits(&self) -> u8 {
|
||||
fn as_bits(self) -> u8 {
|
||||
match self {
|
||||
TimerRate::Sixteen => 0b01,
|
||||
TimerRate::SixtyFour => 0b10,
|
||||
|
@ -29,7 +29,7 @@ impl TimerRate {
|
|||
}
|
||||
}
|
||||
|
||||
fn as_num(&self) -> usize {
|
||||
fn as_num(self) -> usize {
|
||||
match self {
|
||||
TimerRate::Sixteen => 16,
|
||||
TimerRate::SixtyFour => 64,
|
||||
|
|
|
@ -119,7 +119,7 @@ pub enum RomSize {
|
|||
}
|
||||
|
||||
impl RomSize {
|
||||
pub fn from(val: u8) -> Option<Self> {
|
||||
#[must_use] pub fn from(val: u8) -> Option<Self> {
|
||||
match val {
|
||||
0x00 => Some(Self::B2),
|
||||
0x01 => Some(Self::B4),
|
||||
|
@ -137,7 +137,7 @@ impl RomSize {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn size_bytes(&self) -> usize {
|
||||
#[must_use] pub fn size_bytes(&self) -> usize {
|
||||
(match self {
|
||||
RomSize::B2 => 2,
|
||||
RomSize::B4 => 4,
|
||||
|
@ -177,7 +177,7 @@ impl RamSize {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn size_bytes(&self) -> usize {
|
||||
#[must_use] pub fn size_bytes(&self) -> usize {
|
||||
match self {
|
||||
RamSize::B2 => 2 * KB,
|
||||
RamSize::B8 => 8 * KB,
|
||||
|
@ -370,7 +370,7 @@ impl Rom {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_title(&self) -> &String {
|
||||
#[must_use] pub fn get_title(&self) -> &String {
|
||||
&self.title
|
||||
}
|
||||
|
||||
|
@ -398,7 +398,7 @@ impl Rom {
|
|||
self.mbc.can_rumble()
|
||||
}
|
||||
|
||||
pub fn mbc_type(&self) -> String {
|
||||
#[must_use] pub fn mbc_type(&self) -> String {
|
||||
self.mbc.mbc_type()
|
||||
}
|
||||
|
||||
|
|
|
@ -134,9 +134,10 @@ pub enum LicenseeCode {
|
|||
}
|
||||
|
||||
impl LicenseeCode {
|
||||
#[must_use]
|
||||
#[allow(clippy::match_same_arms)]
|
||||
pub fn from_header(old_licensee_code: u8, new_code: [u8; 2]) -> Self {
|
||||
match old_licensee_code {
|
||||
0x00 => Self::None,
|
||||
0x01 => Self::Nintendo,
|
||||
0x08 => Self::Capcom,
|
||||
0x09 => Self::HotB,
|
||||
|
|
|
@ -35,7 +35,7 @@ struct Rtc {
|
|||
}
|
||||
|
||||
impl Rtc {
|
||||
fn get_register(&self, rtc_register: &RtcRegister) -> u8 {
|
||||
fn get_register(&self, rtc_register: RtcRegister) -> u8 {
|
||||
let time = self.latched_time.unwrap_or(Instant::now()) - self.base_time;
|
||||
match rtc_register {
|
||||
RtcRegister::Seconds => (time.as_secs() % 60) as u8,
|
||||
|
@ -49,17 +49,22 @@ impl Rtc {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_register(&mut self, rtc_register: &RtcRegister, data: u8) {
|
||||
fn set_register(&mut self, rtc_register: RtcRegister, data: u8) {
|
||||
let seconds_offset = match rtc_register {
|
||||
RtcRegister::Seconds => data as i64 - self.get_register(&RtcRegister::Seconds) as i64,
|
||||
RtcRegister::Seconds => {
|
||||
i64::from(data) - i64::from(self.get_register(RtcRegister::Seconds))
|
||||
}
|
||||
RtcRegister::Minutes => {
|
||||
(data as i64 - self.get_register(&RtcRegister::Minutes) as i64) * 60
|
||||
(i64::from(data) - i64::from(self.get_register(RtcRegister::Minutes))) * 60
|
||||
}
|
||||
RtcRegister::Hours => {
|
||||
(data as i64 - self.get_register(&RtcRegister::Hours) as i64) * 60 * 60
|
||||
(i64::from(data) - i64::from(self.get_register(RtcRegister::Hours))) * 60 * 60
|
||||
}
|
||||
RtcRegister::DayCounterLsb => {
|
||||
(data as i64 - self.get_register(&RtcRegister::DayCounterLsb) as i64) * 60 * 60 * 24
|
||||
(i64::from(data) - i64::from(self.get_register(RtcRegister::DayCounterLsb)))
|
||||
* 60
|
||||
* 60
|
||||
* 24
|
||||
}
|
||||
RtcRegister::Misc => 0,
|
||||
};
|
||||
|
@ -112,7 +117,7 @@ impl Mbc3 {
|
|||
rom_size: rom_size.size_bytes(),
|
||||
ram,
|
||||
ram_bank: RamBank::Ram(0),
|
||||
ram_size: ram_size.map(|s| s.size_bytes()).unwrap_or(0),
|
||||
ram_size: ram_size.map_or(0, |s| s.size_bytes()),
|
||||
ram_enabled: false,
|
||||
rtc: if rtc { Some(Rtc::default()) } else { None },
|
||||
}
|
||||
|
@ -148,7 +153,7 @@ impl Mbc for Mbc3 {
|
|||
}
|
||||
RamBank::Rtc(rtc_register) => {
|
||||
if let Some(rtc) = &self.rtc {
|
||||
return rtc.get_register(rtc_register);
|
||||
return rtc.get_register(*rtc_register);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,7 +210,7 @@ impl Mbc for Mbc3 {
|
|||
}
|
||||
RamBank::Rtc(rtc_register) => {
|
||||
if let Some(ref mut rtc) = self.rtc {
|
||||
rtc.set_register(rtc_register, data);
|
||||
rtc.set_register(*rtc_register, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ impl Mbc5 {
|
|||
rom_size: rom_size.size_bytes(),
|
||||
ram,
|
||||
ram_bank: 0,
|
||||
ram_size: ram_size.map(|s| s.size_bytes()).unwrap_or(0),
|
||||
ram_size: ram_size.map_or(0, |s| s.size_bytes()),
|
||||
ram_enabled: false,
|
||||
rumble,
|
||||
is_rumbling: false,
|
||||
|
@ -82,14 +82,14 @@ impl Mbc for Mbc5 {
|
|||
0x0..0x2000 => {
|
||||
self.ram_enabled = (data & 0xF) == 0xA;
|
||||
}
|
||||
0x2000..0x3000 => self.rom_bank = (self.rom_bank & 0x100) | (data as u16),
|
||||
0x3000..0x4000 => self.rom_bank = (self.rom_bank & 0xFF) | ((data as u16 & 0b1) << 8),
|
||||
0x2000..0x3000 => self.rom_bank = (self.rom_bank & 0x100) | u16::from(data),
|
||||
0x3000..0x4000 => self.rom_bank = (self.rom_bank & 0xFF) | ((u16::from(data) & 0b1) << 8),
|
||||
0x4000..0x6000 => {
|
||||
if self.rumble {
|
||||
self.is_rumbling = get_bit(data, 3);
|
||||
self.ram_bank = data & 0x7;
|
||||
} else {
|
||||
self.ram_bank = data & 0xF
|
||||
self.ram_bank = data & 0xF;
|
||||
}
|
||||
}
|
||||
0x6000..0x8000 => {}
|
||||
|
|
|
@ -72,7 +72,7 @@ where
|
|||
|
||||
fn get_cam_reg(&self, address: CartRamAddress) -> u8 {
|
||||
match address.inner() {
|
||||
0xA000 => (if self.camera.is_capturing() { 0x1 } else { 0x0 }) | self.extra_bits_a000,
|
||||
0xA000 => u8::from(self.camera.is_capturing()) | self.extra_bits_a000,
|
||||
0xA001..=0xA035 => self.camera_ram[(address.inner() - 0xA001) as usize],
|
||||
_ => 0x00,
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ where
|
|||
}
|
||||
0x2000..0x4000 => {
|
||||
if data < 0x40 {
|
||||
self.rom_bank = data
|
||||
self.rom_bank = data;
|
||||
}
|
||||
}
|
||||
0x4000..0x6000 => {
|
||||
|
|
|
@ -20,6 +20,7 @@ pub(crate) enum Direction {
|
|||
Right,
|
||||
}
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct Cpu<ColourFormat>
|
||||
where
|
||||
ColourFormat: From<Colour> + Copy,
|
||||
|
@ -223,10 +224,10 @@ impl SplitRegister for u16 {
|
|||
}
|
||||
|
||||
fn set_low(&mut self, val: u8) {
|
||||
*self = (*self & !0xff) | val as u16;
|
||||
*self = (*self & !0xff) | u16::from(val);
|
||||
}
|
||||
|
||||
fn set_high(&mut self, val: u8) {
|
||||
*self = (*self & !0xff00) | (val as u16) << 8;
|
||||
*self = (*self & !0xff00) | u16::from(val) << 8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,3 +164,8 @@ pub fn scale_buffer_in_place<T: From<Colour> + Copy>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn boxed_array<T: Copy, const SIZE: usize>(default: T) -> Box<[T; SIZE]> {
|
||||
let temp = vec![default; SIZE].into_boxed_slice();
|
||||
unsafe { Box::from_raw(Box::into_raw(temp).cast::<[T; SIZE]>()) }
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ name = "xtask"
|
|||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use clap::Parser;
|
||||
|
||||
use crate::types::*;
|
||||
use crate::types::{Architecture, Binary, Platform, Renderer};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use clap::Parser;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use args::*;
|
||||
use types::*;
|
||||
use args::{Args, BuildArgs, Commands, RunArgs};
|
||||
use types::{Architecture, Binary, CouldntSetOnceLock, Platform, Renderer, get_triple};
|
||||
mod args;
|
||||
mod types;
|
||||
|
||||
|
@ -295,7 +295,7 @@ fn cargo_exec(
|
|||
println!("Building {package} with {renderer} renderer for target {triple}");
|
||||
|
||||
let args=format!("{verb} -q -p {package} --target {triple} {release} --no-default-features -F {renderer} --message-format=json-render-diagnostics");
|
||||
let args = args.split_whitespace().map(|s| s.to_string());
|
||||
let args = args.split_whitespace().map(std::string::ToString::to_string);
|
||||
let args = if let Some(additional_flags) = additional_flags {
|
||||
args.chain(additional_flags).collect::<Vec<_>>()
|
||||
} else {
|
||||
|
@ -338,8 +338,8 @@ fn cargo_exec(
|
|||
Ok(
|
||||
cargo_metadata::Message::parse_stream(std::io::BufReader::new(output)).inspect(move |v| {
|
||||
match v {
|
||||
Ok(cargo_metadata::Message::BuildScriptExecuted(_))
|
||||
| Ok(cargo_metadata::Message::CompilerArtifact(_)) => {
|
||||
Ok(cargo_metadata::Message::BuildScriptExecuted(_) |
|
||||
cargo_metadata::Message::CompilerArtifact(_)) => {
|
||||
if let Some(pb) = pb.as_mut() {
|
||||
pb.inc();
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ fn build_vst(
|
|||
}
|
||||
|
||||
// we need the &str to live for this whole function
|
||||
let triple_str = triple.map(|t| t.to_string());
|
||||
let triple_str = triple.map(std::string::ToString::to_string);
|
||||
if platform != Platform::Mac {
|
||||
args.push("--target");
|
||||
args.push(triple_str.as_ref().unwrap().as_str());
|
||||
|
@ -428,8 +428,8 @@ fn build_vst(
|
|||
|
||||
for v in cargo_metadata::Message::parse_stream(std::io::BufReader::new(output)) {
|
||||
match v {
|
||||
Ok(cargo_metadata::Message::BuildScriptExecuted(_))
|
||||
| Ok(cargo_metadata::Message::CompilerArtifact(_)) => {
|
||||
Ok(cargo_metadata::Message::BuildScriptExecuted(_) |
|
||||
cargo_metadata::Message::CompilerArtifact(_)) => {
|
||||
if pb.as_ref().is_some_and(|pb| pb.is_finish) {
|
||||
pb = build_plan_iter.next().map(|(arch, num)| {
|
||||
let mut pb = pbr::ProgressBar::new(num.try_into().unwrap());
|
||||
|
|
|
@ -8,7 +8,7 @@ pub enum Platform {
|
|||
}
|
||||
|
||||
impl Platform {
|
||||
pub fn as_cargo(&self) -> cfg_expr::targets::Os {
|
||||
pub fn as_cargo(self) -> cfg_expr::targets::Os {
|
||||
match self {
|
||||
Platform::Windows => cfg_expr::targets::Os::windows,
|
||||
Platform::Linux => cfg_expr::targets::Os::linux,
|
||||
|
@ -58,7 +58,7 @@ pub enum Architecture {
|
|||
}
|
||||
|
||||
impl Architecture {
|
||||
pub fn as_cargo(&self) -> cfg_expr::targets::Arch {
|
||||
pub fn as_cargo(self) -> cfg_expr::targets::Arch {
|
||||
match self {
|
||||
Architecture::Aarch64 => cfg_expr::targets::Arch::aarch64,
|
||||
Architecture::X86_64 => cfg_expr::targets::Arch::x86_64,
|
||||
|
@ -131,7 +131,7 @@ impl std::error::Error for CouldntSetOnceLock {
|
|||
None
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
fn description(&self) -> &'static str {
|
||||
"description() is deprecated; use Display"
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue