Compare commits

...

33 Commits

Author SHA1 Message Date
Logan McNaughton c3f4b11519 update sdl3 2025-10-30 22:47:45 +01:00
Logan McNaughton 921a0d5362 Rust 1.91 (#599) 2025-10-30 20:14:39 +01:00
Logan McNaughton 24fc5b9638 update parallel-rdp 2025-10-30 13:59:20 +01:00
dependabot[bot] 1559856483 Bump signpath/github-action-submit-signing-request from 1.3 to 2.0 (#597)
Bumps [signpath/github-action-submit-signing-request](https://github.com/signpath/github-action-submit-signing-request) from 1.3 to 2.0.
- [Release notes](https://github.com/signpath/github-action-submit-signing-request/releases)
- [Commits](https://github.com/signpath/github-action-submit-signing-request/compare/v1.3...v2.0)

---
updated-dependencies:
- dependency-name: signpath/github-action-submit-signing-request
  dependency-version: '2.0'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 08:36:02 +01:00
dependabot[bot] 1deb91fc1e Bump actions/upload-artifact from 4 to 5 (#596)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 06:01:31 +01:00
Logan McNaughton 726a58f854 cargo update 2025-10-26 13:45:56 +01:00
Logan McNaughton fe0297690f pump events during vi (#593)
* pump events during vi

* add var

* more

* more
2025-10-26 13:42:25 +01:00
Logan McNaughton 847df61526 Add pause between key bindings (#594) 2025-10-26 13:33:40 +01:00
Logan McNaughton 6de8128f5b cargo update 2025-10-12 12:30:57 +02:00
Logan McNaughton 6c09176d12 add .srm for GB saves 2025-10-11 19:32:35 +02:00
Logan McNaughton 2050098735 fix out of bounds access (#590) 2025-10-06 09:02:50 +02:00
Logan McNaughton d3ecc37da6 fix compare interrupt issue (#588) 2025-10-01 10:05:03 +02:00
Logan McNaughton a0237e9f7d bump to 1.1.9 2025-09-28 10:00:37 +02:00
Logan McNaughton d6d608b674 Revert "more audio cleanup"
This reverts commit f3271cba63.
2025-09-28 09:59:02 +02:00
Logan McNaughton f254bec968 bump to 1.1.8 2025-09-27 21:33:21 +02:00
Logan McNaughton bd4aff2b2c cargo update 2025-09-27 21:32:27 +02:00
Logan McNaughton 0bf70a77ea correct load block size 2025-09-26 18:52:27 +02:00
Logan McNaughton e23e7f33c1 Re-add wgpu
I didn't see any evidence of crashing
2025-09-26 07:23:48 +02:00
Logan McNaughton 9d0516545e reorder items 2025-09-25 16:14:48 +02:00
Logan McNaughton e3023a902f further depth buffer tracking tweaks (#583) 2025-09-25 15:59:58 +02:00
Logan McNaughton 431c7c2a8d cargo update 2025-09-25 13:32:23 +02:00
Logan McNaughton cf99539f85 remove wgpu (#576) 2025-09-25 07:36:23 +02:00
Logan McNaughton c2493b829e watch z-buffer reads as well (#581) 2025-09-24 23:00:39 +02:00
Logan McNaughton 2f25de55d7 change depth buffer tracking (#580) 2025-09-24 20:06:39 +02:00
Logan McNaughton 116ffe9845 fix clippy warning 2025-09-22 09:15:41 +02:00
Logan McNaughton f3271cba63 more audio cleanup 2025-09-21 18:36:03 +02:00
Logan McNaughton 9037680cda cleanup audio code (#579) 2025-09-21 16:30:11 +02:00
Logan McNaughton fc41e26a6d expose 8x resolution (#578) 2025-09-21 13:36:13 +02:00
Logan McNaughton d1f28bb7a8 optimize rdp_check_framebuffers (#577) 2025-09-21 10:43:49 +02:00
Logan McNaughton 9db831fdef disable repeat mode on MI_CLR_INIT 2025-09-20 17:21:06 +02:00
Logan McNaughton 004b603e96 support basic mi repeat mode (#575)
* support basic mi repeat mode

* more

* more
2025-09-20 17:09:30 +02:00
Logan McNaughton 8661e2c9b1 always enable lto 2025-09-20 08:37:55 +02:00
Logan McNaughton c712f2a288 bump to 1.1.7 2025-09-19 12:57:05 +02:00
19 changed files with 908 additions and 832 deletions
+4 -4
View File
@@ -61,7 +61,7 @@ jobs:
mkdir output
cp target/${{ matrix.target }}/release/gopher64 output/gopher64-${{ matrix.arch }}
- name: Upload file
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: gopher64-${{ matrix.arch }}
path: output/gopher64-${{ matrix.arch }}
@@ -104,13 +104,13 @@ jobs:
cp target/${{ matrix.target }}/release/gopher64.exe output/gopher64-${{ matrix.arch }}.exe
- name: Upload unsigned artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: gopher64-${{ matrix.arch }}
path: output/gopher64-${{ matrix.arch }}.exe
- name: SignPath
if: ${{ github.ref_type == 'tag' }}
uses: signpath/github-action-submit-signing-request@v1.3
uses: signpath/github-action-submit-signing-request@v2.0
with:
api-token: "${{ secrets.SIGNPATH_API_TOKEN }}"
organization-id: "${{ secrets.SIGNPATH_ORG_ID }}"
@@ -146,7 +146,7 @@ jobs:
env:
AR: ar
- name: Upload file
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: gopher64-${{ matrix.arch }}
path: output/gopher64-${{ matrix.arch }}
Generated
+772 -737
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -1,16 +1,16 @@
[package]
name = "gopher64"
version = "1.1.6"
version = "1.1.9"
edition = "2024"
rust-version = "1.90"
rust-version = "1.91"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dirs = "6.0"
zip = "5.1"
zip = "6.0"
governor = "0.10"
sevenz-rust2 = { version = "0.18", default-features = false }
sevenz-rust2 = { version = "0.19", default-features = false }
chrono = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@@ -26,7 +26,7 @@ spin_sleep = "1.3"
encoding_rs = "0.8"
mimalloc = "0.1"
regex = "1.11"
tokio-tungstenite = "0.27"
tokio-tungstenite = "0.28"
futures = "0.3"
socket2 = { version = "0.6", features = ["all"] }
rand_chacha = "0.9"
+4 -6
View File
@@ -73,7 +73,6 @@ fn main() {
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let profile = std::env::var("PROFILE").unwrap();
let opt_flag = if arch == "x86_64" {
"-march=x86-64-v3"
} else if arch == "aarch64" {
@@ -96,11 +95,10 @@ fn main() {
.unwrap();
}
if profile == "release" {
volk_build.flag("-flto=thin");
rdp_build.flag("-flto=thin");
simd_build.flag("-flto=thin");
}
volk_build.flag("-flto=thin");
rdp_build.flag("-flto=thin");
simd_build.flag("-flto=thin");
volk_build.compile("volk");
rdp_build.compile("parallel-rdp");
+47 -27
View File
@@ -64,6 +64,7 @@ typedef struct
uint32_t texture_pixel_size;
uint32_t texture_width;
uint32_t framebuffer_height;
bool depth_buffer_enabled;
} FrameBufferInfo;
typedef struct
@@ -274,6 +275,11 @@ void rdp_new_processor(GFX_INFO _gfx_info)
flags |= RDP::COMMAND_PROCESSOR_FLAG_SUPER_SAMPLED_DITHER_BIT;
flags |= RDP::COMMAND_PROCESSOR_FLAG_UPSCALING_4X_BIT;
}
else if (gfx_info.upscale == 8)
{
flags |= RDP::COMMAND_PROCESSOR_FLAG_SUPER_SAMPLED_DITHER_BIT;
flags |= RDP::COMMAND_PROCESSOR_FLAG_UPSCALING_8X_BIT;
}
processor = new RDP::CommandProcessor(wsi->get_device(), gfx_info.RDRAM, 0, gfx_info.RDRAM_SIZE, gfx_info.RDRAM_SIZE / 2, flags);
}
@@ -570,17 +576,18 @@ void rdp_check_framebuffers(uint32_t address, uint32_t length)
{
address >>= 3;
length = (length + 7) >> 3;
for (uint32_t i = 0; i < length; i++)
if (address >= rdram_dirty.size())
return;
uint32_t end_addr = std::min(address + length, static_cast<uint32_t>(rdram_dirty.size()));
auto it = std::find(rdram_dirty.begin() + address, rdram_dirty.begin() + end_addr, true);
if (it != rdram_dirty.begin() + end_addr)
{
if (address + i >= rdram_dirty.size())
return;
if (rdram_dirty[address + i])
{
processor->wait_for_timeline(sync_signal);
rdram_dirty.assign(gfx_info.RDRAM_SIZE >> 3, false);
sync_signal = 0;
return;
}
processor->wait_for_timeline(sync_signal);
rdram_dirty.assign(gfx_info.RDRAM_SIZE >> 3, false);
sync_signal = 0;
}
}
}
@@ -689,21 +696,14 @@ uint64_t rdp_process_commands()
switch (RDP::Op(command))
{
case RDP::Op::FillZBufferTriangle:
case RDP::Op::TextureZBufferTriangle:
case RDP::Op::ShadeZBufferTriangle:
case RDP::Op::ShadeTextureZBufferTriangle:
{
uint32_t offset_address = (rdp_device.frame_buffer_info.depthbuffer_address + pixel_size(2, rdp_device.frame_buffer_info.framebuffer_y_offset * rdp_device.frame_buffer_info.framebuffer_width)) >> 3;
if (offset_address < rdram_dirty.size() && !rdram_dirty[offset_address])
{
std::fill_n(rdram_dirty.begin() + offset_address, (pixel_size(2, rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height) + 7) >> 3, true);
}
}
case RDP::Op::FillTriangle:
case RDP::Op::FillZBufferTriangle:
case RDP::Op::TextureTriangle:
case RDP::Op::TextureZBufferTriangle:
case RDP::Op::ShadeTriangle:
case RDP::Op::ShadeZBufferTriangle:
case RDP::Op::ShadeTextureTriangle:
case RDP::Op::ShadeTextureZBufferTriangle:
case RDP::Op::TextureRectangle:
case RDP::Op::TextureRectangleFlip:
case RDP::Op::FillRectangle:
@@ -711,7 +711,18 @@ uint64_t rdp_process_commands()
uint32_t offset_address = (rdp_device.frame_buffer_info.framebuffer_address + pixel_size(rdp_device.frame_buffer_info.framebuffer_pixel_size, rdp_device.frame_buffer_info.framebuffer_y_offset * rdp_device.frame_buffer_info.framebuffer_width)) >> 3;
if (offset_address < rdram_dirty.size() && !rdram_dirty[offset_address])
{
std::fill_n(rdram_dirty.begin() + offset_address, (pixel_size(rdp_device.frame_buffer_info.framebuffer_pixel_size, rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height) + 7) >> 3, true);
uint32_t end_addr = std::min(offset_address + ((pixel_size(rdp_device.frame_buffer_info.framebuffer_pixel_size, rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height) + 7) >> 3), static_cast<uint32_t>(rdram_dirty.size()));
std::fill(rdram_dirty.begin() + offset_address, rdram_dirty.begin() + end_addr, true);
}
if (rdp_device.frame_buffer_info.depth_buffer_enabled)
{
offset_address = (rdp_device.frame_buffer_info.depthbuffer_address + pixel_size(2, rdp_device.frame_buffer_info.framebuffer_y_offset * rdp_device.frame_buffer_info.framebuffer_width)) >> 3;
if (offset_address < rdram_dirty.size() && !rdram_dirty[offset_address])
{
uint32_t end_addr = std::min(offset_address + ((pixel_size(2, rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height) + 7) >> 3), static_cast<uint32_t>(rdram_dirty.size()));
std::fill(rdram_dirty.begin() + offset_address, rdram_dirty.begin() + end_addr, true);
}
}
}
break;
@@ -723,19 +734,21 @@ uint64_t rdp_process_commands()
if (offset_address < rdram_dirty.size() && !rdram_dirty[offset_address])
{
uint32_t lower_right_t = (w2 & 0xFFF) >> 2;
std::fill_n(rdram_dirty.begin() + offset_address, (pixel_size(rdp_device.frame_buffer_info.texture_pixel_size, (lower_right_t - upper_left_t) * rdp_device.frame_buffer_info.texture_width) + 7) >> 3, true);
uint32_t end_addr = std::min(offset_address + ((pixel_size(rdp_device.frame_buffer_info.texture_pixel_size, (lower_right_t - upper_left_t) * rdp_device.frame_buffer_info.texture_width) + 7) >> 3), static_cast<uint32_t>(rdram_dirty.size()));
std::fill(rdram_dirty.begin() + offset_address, rdram_dirty.begin() + end_addr, true);
}
}
break;
case RDP::Op::LoadBlock:
{
uint32_t upper_left_s = ((w1 >> 12) & 0xFFF) >> 2;
uint32_t upper_left_t = (w1 & 0xFFF) >> 2;
uint32_t upper_left_s = ((w1 >> 12) & 0xFFF);
uint32_t upper_left_t = (w1 & 0xFFF);
uint32_t offset_address = (rdp_device.frame_buffer_info.texture_address + pixel_size(rdp_device.frame_buffer_info.texture_pixel_size, upper_left_s + upper_left_t * rdp_device.frame_buffer_info.texture_width)) >> 3;
if (offset_address < rdram_dirty.size() && !rdram_dirty[offset_address])
{
uint32_t lower_right_s = ((w2 >> 12) & 0xFFF) >> 2;
std::fill_n(rdram_dirty.begin() + offset_address, (pixel_size(rdp_device.frame_buffer_info.texture_pixel_size, lower_right_s - upper_left_s) + 7) >> 3, true);
uint32_t lower_right_s = ((w2 >> 12) & 0xFFF);
uint32_t end_addr = std::min(offset_address + ((pixel_size(rdp_device.frame_buffer_info.texture_pixel_size, lower_right_s - upper_left_s) + 7) >> 3), static_cast<uint32_t>(rdram_dirty.size()));
std::fill(rdram_dirty.begin() + offset_address, rdram_dirty.begin() + end_addr, true);
}
}
break;
@@ -771,6 +784,13 @@ uint64_t rdp_process_commands()
rdp_device.frame_buffer_info.framebuffer_height = lower_right_y - upper_left_y;
}
break;
case RDP::Op::SetOtherModes:
{
uint8_t cycle_type = (w1 >> 20) & 3;
uint8_t depth_read_write = (w2 >> 4) & 3;
rdp_device.frame_buffer_info.depth_buffer_enabled = ((cycle_type & 2) == 0) && (depth_read_write != 0);
}
break;
case RDP::Op::SyncFull:
sync_signal = processor->signal_timeline();
+1 -1
View File
@@ -1,2 +1,2 @@
[toolchain]
channel = "1.90.0"
channel = "1.91.0"
+1
View File
@@ -322,6 +322,7 @@ impl Device {
pif: pif::Pif {
rom: [0; 1984],
ram: [0; 64],
input_gathered: false,
channels: [pif::PifChannel {
tx: None,
tx_buf: None,
-1
View File
@@ -18,7 +18,6 @@ pub fn check_pending_interrupts(device: &mut device::Device) {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] = device::cop0::COP0_CAUSE_IP2;
} else if device.cpu.cop0.pending_compare_interrupt {
device.cpu.cop0.regs[device::cop0::COP0_CAUSE_REG as usize] = device::cop0::COP0_CAUSE_IP7;
device.cpu.cop0.pending_compare_interrupt = false;
}
if (device.cpu.cop0.regs[device::cop0::COP0_STATUS_REG as usize]
+2 -2
View File
@@ -22,8 +22,8 @@ pub fn write_mem(device: &mut device::Device, address: u64, value: u32, mask: u3
let data = std::str::from_utf8(
&device.cart.is_viewer_buffer[0x20_usize..(0x20 + length) as usize],
);
if data.is_ok() {
print!("{}", data.unwrap());
if let Ok(data) = data {
print!("{}", data);
}
} else {
let mut data = u32::from_be_bytes(
+10 -5
View File
@@ -1,6 +1,6 @@
use crate::device;
const MI_INIT_MODE_REG: u32 = 0;
pub const MI_INIT_MODE_REG: u32 = 0;
const MI_VERSION_REG: u32 = 1;
pub const MI_INTR_REG: u32 = 2;
pub const MI_INTR_MASK_REG: u32 = 3;
@@ -29,7 +29,7 @@ const MI_CLR_DP: u32 = 1 << 10;
const MI_SET_DP: u32 = 1 << 11;
/* mode read */
const MI_INIT_MODE: u32 = 1 << 7;
pub const MI_INIT_MODE: u32 = 1 << 7;
const MI_EBUS_MODE: u32 = 1 << 8;
const MI_RDRAM_MODE: u32 = 1 << 9;
@@ -42,7 +42,7 @@ const MI_CLR_DP_INTR: u32 = 1 << 11;
const MI_CLR_RDRAM: u32 = 1 << 12;
const MI_SET_RDRAM: u32 = 1 << 13;
const MI_INIT_LENGTH_MASK: u32 = 0b1111111;
pub const MI_INIT_LENGTH_MASK: u32 = 0b1111111;
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Mi {
@@ -78,11 +78,16 @@ fn update_init_mode(device: &mut device::Device, w: u32) {
device.mi.regs[MI_INIT_MODE_REG as usize] |= w & MI_INIT_LENGTH_MASK;
if w & MI_CLR_INIT != 0 {
for i in 0..(0x3F00000 >> 16) {
device.memory.memory_map_write[i] = device::rdram::write_mem;
}
device.mi.regs[MI_INIT_MODE_REG as usize] &= !MI_INIT_MODE
}
if w & MI_SET_INIT != 0 {
panic!("MI_SET_INIT not implemented")
//device.mi.regs[MI_INIT_MODE_REG as usize] |= MI_INIT_MODE
for i in 0..(0x3F00000 >> 16) {
device.memory.memory_map_write[i] = device::rdram::write_mem_repeat;
}
device.mi.regs[MI_INIT_MODE_REG as usize] |= MI_INIT_MODE
}
if w & MI_CLR_EBUS != 0 {
device.mi.regs[MI_INIT_MODE_REG as usize] &= !MI_EBUS_MODE
+4
View File
@@ -8,6 +8,7 @@ pub struct Pif {
#[serde(with = "serde_big_array::BigArray")]
pub ram: [u8; 64],
pub channels: [PifChannel; 5],
pub input_gathered: bool,
}
#[derive(Copy, Clone, serde::Serialize, serde::Deserialize)]
@@ -95,6 +96,9 @@ fn process_channel(device: &mut device::Device, channel: usize) -> usize {
}
pub fn update_pif_ram(device: &mut device::Device) -> u64 {
unsafe { sdl3_sys::events::SDL_PumpEvents() };
device.pif.input_gathered = true;
let mut active_channels = 0;
for k in 0..PIF_CHANNELS_COUNT {
active_channels += process_channel(device, k)
+33
View File
@@ -85,6 +85,39 @@ pub fn write_mem(device: &mut device::Device, address: u64, value: u32, mask: u3
.copy_from_slice(&data.to_ne_bytes());
}
pub fn write_mem_repeat(device: &mut device::Device, address: u64, value: u32, mask: u32) {
if mask != 0xFFFFFFFF {
panic!("RDRAM write_mem_repeat called with mask {:#x}", mask);
}
let repeat_length = (device.mi.regs[device::mi::MI_INIT_MODE_REG as usize]
& device::mi::MI_INIT_LENGTH_MASK)
+ 1;
if !repeat_length.is_multiple_of(4) {
panic!(
"RDRAM write_mem_repeat called with non-word-aligned length {}",
repeat_length
);
}
ui::video::check_framebuffers(address as u32, repeat_length);
for i in (0..repeat_length as u64).step_by(4) {
device
.rdram
.mem
.get_mut((address + i) as usize..(address + i) as usize + 4)
.unwrap_or(&mut [0; 4])
.copy_from_slice(&value.to_ne_bytes());
}
device.mi.regs[device::mi::MI_INIT_MODE_REG as usize] &= !device::mi::MI_INIT_MODE;
for i in 0..(0x3F00000 >> 16) {
device.memory.memory_map_write[i] = device::rdram::write_mem;
}
}
pub fn read_regs(
device: &mut device::Device,
address: u64,
+4
View File
@@ -159,6 +159,10 @@ pub fn vertical_interrupt_event(device: &mut device::Device) {
if device.netplay.is_none() && paused {
ui::video::pause_loop();
} else if !device.pif.input_gathered {
unsafe { sdl3_sys::events::SDL_PumpEvents() }; // in case the game isn't prompting for input
} else {
device.pif.input_gathered = false;
}
/*
-4
View File
@@ -15,9 +15,7 @@ pub struct Dirs {
}
pub struct Audio {
pub audio_device_spec: sdl3_sys::audio::SDL_AudioSpec,
pub audio_stream: *mut sdl3_sys::audio::SDL_AudioStream,
pub audio_device: u32,
pub gain: f32,
}
@@ -183,9 +181,7 @@ impl Ui {
game_id: String::new(),
game_hash: String::new(),
audio: Audio {
audio_device_spec: Default::default(),
audio_stream: std::ptr::null_mut(),
audio_device: 0,
gain: 1.0,
},
video: Video {
+9 -34
View File
@@ -3,32 +3,6 @@ use crate::ui;
pub fn init(ui: &mut ui::Ui, frequency: u64) {
ui::sdl_init(sdl3_sys::init::SDL_INIT_AUDIO);
let device_audio_spec = sdl3_sys::audio::SDL_AudioSpec {
format: sdl3_sys::audio::SDL_AUDIO_S16LE,
freq: 48000,
channels: 2,
};
ui.audio.audio_device = unsafe {
sdl3_sys::audio::SDL_OpenAudioDevice(
sdl3_sys::audio::SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,
&device_audio_spec,
)
};
if ui.audio.audio_device == 0 {
panic!("Could not open audio device");
}
if !unsafe {
sdl3_sys::audio::SDL_GetAudioDeviceFormat(
ui.audio.audio_device,
&mut ui.audio.audio_device_spec,
std::ptr::null_mut(),
)
} {
panic!("Could not get audio device format");
}
init_game_audio(ui, frequency);
}
@@ -40,25 +14,26 @@ pub fn init_game_audio(ui: &mut ui::Ui, frequency: u64) {
};
ui.audio.audio_stream = unsafe {
sdl3_sys::audio::SDL_CreateAudioStream(&game_audio_spec, &ui.audio.audio_device_spec)
sdl3_sys::audio::SDL_OpenAudioDeviceStream(
sdl3_sys::audio::SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,
&game_audio_spec,
None,
std::ptr::null_mut(),
)
};
if ui.audio.audio_stream.is_null() {
return;
panic!("Could not create audio stream");
}
if !unsafe {
sdl3_sys::audio::SDL_SetAudioStreamGain(ui.audio.audio_stream, ui.audio.gain)
&& sdl3_sys::audio::SDL_BindAudioStream(ui.audio.audio_device, ui.audio.audio_stream)
&& sdl3_sys::audio::SDL_ResumeAudioStreamDevice(ui.audio.audio_stream)
} {
panic!("Could not bind audio stream");
panic!("Could not resume audio stream");
}
}
pub fn close(ui: &mut ui::Ui) {
close_game_audio(ui);
unsafe {
sdl3_sys::audio::SDL_CloseAudioDevice(ui.audio.audio_device);
ui.audio.audio_device = 0;
}
}
pub fn close_game_audio(ui: &mut ui::Ui) {
+3 -2
View File
@@ -111,6 +111,7 @@ fn settings_window(app: &AppWindow, config: &ui::config::Config) {
1 => 0,
2 => 1,
4 => 2,
8 => 3,
_ => 0,
};
app.set_resolution(combobox_value);
@@ -249,7 +250,7 @@ pub fn save_settings(app: &AppWindow, controller_paths: &[Option<String>]) {
config.emulation.overclock = app.get_overclock_n64_cpu();
config.emulation.disable_expansion_pak = app.get_disable_expansion_pak();
config.emulation.usb = app.get_emulate_usb();
let upscale_values = [1, 2, 4];
let upscale_values = [1, 2, 4, 8];
config.video.upscale = upscale_values[app.get_resolution() as usize];
config.input.emulate_vru = app.get_emulate_vru();
@@ -471,7 +472,7 @@ fn open_rom(app: &AppWindow, usb: ui::Usb) {
select_gb_ram[i] = Some(
rfd::AsyncFileDialog::new()
.set_title(format!("GB RAM P{}", i + 1))
.add_filter("GB RAM files", &["sav", "ram", "SAV", "RAM"])
.add_filter("GB RAM files", &["sav", "ram", "srm", "SAV", "RAM", "SRM"])
.pick_file(),
);
}
+1 -1
View File
@@ -29,7 +29,7 @@ export component Settings inherits Page {
}
ComboBox {
model: ["1x", "2x", "4x"];
model: ["1x", "2x", "4x", "8x"];
current-index: SettingsData.resolution;
selected => {
SettingsData.resolution = self.current-index;
+7 -2
View File
@@ -385,8 +385,6 @@ pub fn get_controller_paths(game_ui: &ui::Ui) -> Vec<Option<String>> {
}
pub fn get(ui: &ui::Ui, channel: usize) -> InputData {
unsafe { sdl3_sys::events::SDL_PumpEvents() };
let profile_name = ui.config.input.input_profile_binding[channel].clone();
let profile = ui.config.input.input_profiles.get(&profile_name).unwrap();
let mut keys = 0;
@@ -702,6 +700,13 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool, d
}
}
}
ui::video::draw_text(
format!("Binding set for {key}").as_str(),
renderer,
text_engine,
font,
);
std::thread::sleep(std::time::Duration::from_millis(200));
}
close_controllers(open_joysticks, open_controllers);