mirror of
https://github.com/gopher64/gopher64.git
synced 2026-07-11 01:25:20 +02:00
remove custom stack size (#698)
* remove custom stack size * new command * more * more * more * more * more * more * more * more * more * more * more * more * more * more * more * more * more * more * more * config * more * more
This commit is contained in:
@@ -4,6 +4,9 @@ rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
||||
[target.'cfg(any(target_os = "windows", target_os = "macos"))']
|
||||
linker = "rust-lld"
|
||||
|
||||
[target.'cfg(target_os = "windows")']
|
||||
rustflags = ["-C", "link-arg=/STACK:8388608"]
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")']
|
||||
rustflags = ["-C", "target-cpu=x86-64-v3"]
|
||||
|
||||
|
||||
@@ -206,6 +206,4 @@ fn main() {
|
||||
|
||||
let netplay_id = std::env::var("NETPLAY_ID").unwrap_or("gopher64".to_string());
|
||||
println!("cargo:rustc-env=NETPLAY_ID={netplay_id}");
|
||||
|
||||
println!("cargo:rustc-env=N64_STACK_SIZE={}", 8 * 1024 * 1024);
|
||||
}
|
||||
|
||||
@@ -179,11 +179,7 @@ pub fn process(device: &mut device::Device, channel: usize) {
|
||||
device.pif.ram[device.pif.channels[channel].rx_buf.unwrap()] = 0;
|
||||
}
|
||||
JCMD_VRU_READ => {
|
||||
let index = if let Some(weak) = &device.ui.weak {
|
||||
ui::vru::prompt_for_match(&device.vru.words, weak, device.vi.frame_time)
|
||||
} else {
|
||||
0x7FFF
|
||||
};
|
||||
let index = ui::vru::prompt_for_match(&device.vru.words, device.vi.frame_time);
|
||||
let num_results = if index == 0x7FFF { 0 } else { 1 };
|
||||
let data: HashMap<usize, u16> = HashMap::from([
|
||||
(0, 0x8000),
|
||||
|
||||
+88
-51
@@ -18,62 +18,65 @@ use ui::gui;
|
||||
struct Args {
|
||||
game: Option<String>,
|
||||
#[arg(short, long)]
|
||||
fullscreen: bool,
|
||||
fullscreen: Option<bool>,
|
||||
#[arg(long)]
|
||||
overclock: Option<bool>,
|
||||
#[arg(long)]
|
||||
disable_expansion_pak: Option<bool>,
|
||||
#[arg(long, value_name = "CHEATS_FILE", hide = true)]
|
||||
cheats: Option<String>,
|
||||
#[arg(long, value_name = "NETPLAY_PEER_ADDR", hide = true)]
|
||||
netplay_peer_addr: Option<String>,
|
||||
#[arg(long, value_name = "NETPLAY_PLAYER_NUMBER", hide = true)]
|
||||
netplay_player_number: Option<u8>,
|
||||
#[arg(long, value_name = "GB_ROM_PATH", hide = true)]
|
||||
gb_rom: Option<Vec<String>>,
|
||||
#[arg(long, value_name = "GB_RAM_PATH", hide = true)]
|
||||
gb_ram: Option<Vec<String>>,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
value_name = "PROFILE_NAME",
|
||||
help = "Create a new input profile (keyboard/gamepad mappings)"
|
||||
)]
|
||||
configure_input_profile: Option<String>,
|
||||
#[arg(long, help = "Use DirectInput when configuring a new input profile")]
|
||||
use_dinput: Option<bool>,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
help = "Use DirectInput when configuring a new input profile"
|
||||
)]
|
||||
use_dinput: bool,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
value_name = "DEADZONE_PERCENTAGE",
|
||||
help = "Used along with --configure-input-profile to set the deadzone for analog sticks"
|
||||
)]
|
||||
deadzone: Option<i32>,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
value_name = "PROFILE_NAME",
|
||||
help = "Must also specify --port. Used to bind a previously created profile to a port"
|
||||
)]
|
||||
bind_input_profile: Option<String>,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
help = "Lists connected controllers which can be used in --assign-controller"
|
||||
)]
|
||||
list_controllers: bool,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
value_name = "CONTROLLER_NUMBER",
|
||||
help = "Must also specify --port. Used to assign a controller listed in --list-controllers to a port"
|
||||
)]
|
||||
assign_controller: Option<i32>,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
value_name = "PORT",
|
||||
help = "Valid values: 1-4. To be used alongside --bind-input-profile and --assign-controller"
|
||||
)]
|
||||
port: Option<usize>,
|
||||
#[arg(
|
||||
short = 'z',
|
||||
short,
|
||||
long,
|
||||
help = "Clear all input profile bindings and controller assignments"
|
||||
)]
|
||||
clear_input_bindings: bool,
|
||||
#[arg(
|
||||
short = 's',
|
||||
long,
|
||||
value_name = "SLOT",
|
||||
help = "Load savestate from slot 0-9 when starting the game"
|
||||
@@ -81,18 +84,12 @@ struct Args {
|
||||
load_state: Option<u32>,
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.worker_threads(4)
|
||||
.thread_name("n64")
|
||||
.thread_stack_size(env!("N64_STACK_SIZE").parse().unwrap())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let dirs = ui::get_dirs();
|
||||
|
||||
std::fs::create_dir_all(dirs.config_dir)?;
|
||||
std::fs::create_dir_all(dirs.cache_dir)?;
|
||||
std::fs::create_dir_all(dirs.data_dir.join("saves"))?;
|
||||
std::fs::create_dir_all(dirs.data_dir.join("states"))?;
|
||||
let args = Args::parse();
|
||||
@@ -111,29 +108,71 @@ fn main() -> std::io::Result<()> {
|
||||
return Err(Error::other("Savestate slot must be between 0 and 9"));
|
||||
}
|
||||
|
||||
let handle = runtime.spawn(async move {
|
||||
let mut device = device::Device::new();
|
||||
let overclock = device.ui.config.emulation.overclock;
|
||||
let disable_expansion_pak = device.ui.config.emulation.disable_expansion_pak;
|
||||
let mut device = device::Device::new();
|
||||
let fullscreen = args.fullscreen.unwrap_or(device.ui.config.video.fullscreen);
|
||||
let overclock = args
|
||||
.overclock
|
||||
.unwrap_or(device.ui.config.emulation.overclock);
|
||||
let disable_expansion_pak = args
|
||||
.disable_expansion_pak
|
||||
.unwrap_or(device.ui.config.emulation.disable_expansion_pak);
|
||||
let cheats = if let Some(cheats_file) = args.cheats
|
||||
&& let Ok(data) = std::fs::read(cheats_file)
|
||||
&& let Ok(cheats) = serde_json::from_slice(&data)
|
||||
{
|
||||
cheats
|
||||
} else {
|
||||
let game_crc = ui::storage::get_game_crc(&rom_contents);
|
||||
ui::config::Cheats::new()
|
||||
.cheats
|
||||
.get(&game_crc)
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
let game_cheats = {
|
||||
let game_crc = ui::storage::get_game_crc(&rom_contents);
|
||||
let cheats = ui::config::Cheats::new();
|
||||
cheats.cheats.get(&game_crc).cloned().unwrap_or_default()
|
||||
};
|
||||
device::run_game(
|
||||
&mut device,
|
||||
rom_contents,
|
||||
ui::gui::GameSettings {
|
||||
fullscreen: args.fullscreen,
|
||||
overclock,
|
||||
disable_expansion_pak,
|
||||
cheats: game_cheats,
|
||||
load_savestate_slot: args.load_state,
|
||||
},
|
||||
);
|
||||
});
|
||||
runtime.block_on(handle).unwrap()
|
||||
let mut shutdown_tx = None;
|
||||
|
||||
if let Some(peer_addr) = args.netplay_peer_addr
|
||||
&& let Some(player_number) = args.netplay_player_number
|
||||
{
|
||||
device.netplay = Some(netplay::init(peer_addr.parse().unwrap(), player_number));
|
||||
} else {
|
||||
if let Some(gb_roms) = args.gb_rom
|
||||
&& let Some(gb_rams) = args.gb_ram
|
||||
{
|
||||
for i in 0..4 {
|
||||
if let Some(gb_rom) = gb_roms.get(i)
|
||||
&& let Some(gb_ram) = gb_rams.get(i)
|
||||
{
|
||||
device.transferpaks[i].cart.rom = std::fs::read(gb_rom).unwrap();
|
||||
device.transferpaks[i].cart.ram = std::fs::read(gb_ram).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if device.ui.config.emulation.usb {
|
||||
(shutdown_tx, device.ui.usb) = ui::usb::init();
|
||||
}
|
||||
}
|
||||
|
||||
device::run_game(
|
||||
&mut device,
|
||||
rom_contents,
|
||||
ui::gui::GameSettings {
|
||||
fullscreen,
|
||||
overclock,
|
||||
disable_expansion_pak,
|
||||
cheats,
|
||||
load_savestate_slot: args.load_state,
|
||||
},
|
||||
);
|
||||
|
||||
if device.netplay.is_some() {
|
||||
netplay::close(&mut device);
|
||||
}
|
||||
if let Some(shutdown_tx) = &shutdown_tx {
|
||||
ui::usb::close(shutdown_tx);
|
||||
}
|
||||
} else if std::env::args().count() > 1 {
|
||||
let mut ui = ui::Ui::new();
|
||||
|
||||
@@ -157,7 +196,7 @@ fn main() -> std::io::Result<()> {
|
||||
ui::input::configure_input_profile(
|
||||
&mut ui,
|
||||
profile,
|
||||
args.use_dinput,
|
||||
args.use_dinput.unwrap_or(false),
|
||||
args.deadzone.unwrap_or(ui::input::DEADZONE_DEFAULT),
|
||||
);
|
||||
return Ok(());
|
||||
@@ -175,10 +214,8 @@ fn main() -> std::io::Result<()> {
|
||||
ui::input::bind_input_profile(&mut ui, profile, port);
|
||||
}
|
||||
} else {
|
||||
runtime.block_on(async {
|
||||
gui::app_window();
|
||||
});
|
||||
gui::app_window();
|
||||
}
|
||||
runtime.shutdown_timeout(std::time::Duration::from_secs(1));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ pub mod vru;
|
||||
pub struct Dirs {
|
||||
pub config_dir: std::path::PathBuf,
|
||||
pub data_dir: std::path::PathBuf,
|
||||
pub cache_dir: std::path::PathBuf,
|
||||
}
|
||||
|
||||
pub struct Audio {
|
||||
@@ -53,7 +54,6 @@ pub struct Ui {
|
||||
pub storage: Storage,
|
||||
pub video: Video,
|
||||
pub usb: Usb,
|
||||
pub weak: Option<slint::Weak<gui::AppWindow>>,
|
||||
}
|
||||
|
||||
impl Drop for Ui {
|
||||
@@ -94,19 +94,18 @@ pub fn get_dirs() -> Dirs {
|
||||
let exe_path = std::env::current_exe().unwrap();
|
||||
let portable_dir = exe_path.parent();
|
||||
let portable = portable_dir.unwrap().join("portable.txt").exists();
|
||||
let config_dir;
|
||||
let data_dir;
|
||||
if portable {
|
||||
config_dir = portable_dir.unwrap().join("portable_data").join("config");
|
||||
data_dir = portable_dir.unwrap().join("portable_data").join("data");
|
||||
Dirs {
|
||||
config_dir: portable_dir.unwrap().join("portable_data").join("config"),
|
||||
data_dir: portable_dir.unwrap().join("portable_data").join("data"),
|
||||
cache_dir: portable_dir.unwrap().join("portable_data").join("cache"),
|
||||
}
|
||||
} else {
|
||||
config_dir = dirs::config_dir().unwrap().join("gopher64");
|
||||
data_dir = dirs::data_dir().unwrap().join("gopher64");
|
||||
};
|
||||
|
||||
Dirs {
|
||||
config_dir,
|
||||
data_dir,
|
||||
Dirs {
|
||||
config_dir: dirs::config_dir().unwrap().join("gopher64"),
|
||||
data_dir: dirs::data_dir().unwrap().join("gopher64"),
|
||||
cache_dir: dirs::cache_dir().unwrap().join("gopher64"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +195,6 @@ impl Ui {
|
||||
usb_tx: None,
|
||||
cart_rx: None,
|
||||
},
|
||||
weak: None,
|
||||
dirs,
|
||||
with_sdl,
|
||||
}
|
||||
|
||||
+58
-71
@@ -1,5 +1,3 @@
|
||||
use crate::device;
|
||||
use crate::netplay;
|
||||
use crate::ui;
|
||||
use slint::Model;
|
||||
|
||||
@@ -60,23 +58,15 @@ fn check_latest_version(weak: slint::Weak<AppWindow>) {
|
||||
});
|
||||
}
|
||||
|
||||
fn local_game_window(app: &AppWindow, controller_paths: &[Option<String>], usb: ui::Usb) {
|
||||
fn local_game_window(app: &AppWindow, controller_paths: &[Option<String>]) {
|
||||
let dirs = ui::get_dirs();
|
||||
let weak = app.as_weak();
|
||||
let controller_paths = controller_paths.to_owned();
|
||||
app.on_open_rom_button_clicked(move || {
|
||||
let controller_paths = controller_paths.clone();
|
||||
let mut usb_tx = None;
|
||||
if let Some(usb_tx_inner) = usb.usb_tx.as_ref() {
|
||||
usb_tx = Some(usb_tx_inner.clone());
|
||||
}
|
||||
let mut cart_rx = None;
|
||||
if let Some(cart_rx_inner) = usb.cart_rx.as_ref() {
|
||||
cart_rx = Some(cart_rx_inner.resubscribe());
|
||||
}
|
||||
weak.upgrade_in_event_loop(move |handle| {
|
||||
save_settings(&handle, &controller_paths);
|
||||
open_rom(&handle, ui::Usb { usb_tx, cart_rx })
|
||||
open_rom(&handle)
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
@@ -222,18 +212,25 @@ fn controller_window(
|
||||
weak_dialog
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
handle.hide().unwrap();
|
||||
let profile_name = handle.get_profile_name().into();
|
||||
let profile_name = handle.get_profile_name();
|
||||
let dinput = handle.get_dinput();
|
||||
let deadzone = handle.get_deadzone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut game_ui = ui::Ui::new();
|
||||
ui::input::configure_input_profile(
|
||||
&mut game_ui,
|
||||
profile_name,
|
||||
dinput,
|
||||
deadzone,
|
||||
);
|
||||
std::process::Command::new(std::env::current_exe().unwrap())
|
||||
.args([
|
||||
"--configure-input-profile",
|
||||
&profile_name,
|
||||
"--use-dinput",
|
||||
&dinput.to_string(),
|
||||
"--deadzone",
|
||||
&deadzone.to_string(),
|
||||
])
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
let game_ui = ui::Ui::new();
|
||||
update_input_profiles(&weak_app, &game_ui.config);
|
||||
});
|
||||
})
|
||||
@@ -304,11 +301,6 @@ fn about_window(app: &AppWindow) {
|
||||
pub fn app_window() {
|
||||
let app = AppWindow::new().unwrap();
|
||||
about_window(&app);
|
||||
let mut usb = ui::Usb {
|
||||
usb_tx: None,
|
||||
cart_rx: None,
|
||||
};
|
||||
let mut shutdown_tx = None;
|
||||
let mut controller_paths;
|
||||
{
|
||||
let game_ui = ui::Ui::new();
|
||||
@@ -318,76 +310,72 @@ pub fn app_window() {
|
||||
controller_paths.insert(0, None);
|
||||
settings_window(&app, &game_ui.config);
|
||||
controller_window(&app, &game_ui.config, &controller_names, &controller_paths);
|
||||
|
||||
if game_ui.config.emulation.usb {
|
||||
(shutdown_tx, usb) = ui::usb::init(app.as_weak());
|
||||
}
|
||||
}
|
||||
local_game_window(&app, &controller_paths, usb);
|
||||
local_game_window(&app, &controller_paths);
|
||||
ui::netplay::netplay_window(&app, &controller_paths);
|
||||
ui::cheats::cheats_window(&app);
|
||||
app.run().unwrap();
|
||||
if let Some(shutdown_tx) = &shutdown_tx {
|
||||
ui::usb::close(shutdown_tx);
|
||||
}
|
||||
save_settings(&app, &controller_paths);
|
||||
}
|
||||
|
||||
pub fn run_rom(
|
||||
gb_paths: GbPaths,
|
||||
file_path: std::path::PathBuf,
|
||||
mut game_settings: GameSettings,
|
||||
game_settings: GameSettings,
|
||||
netplay: Option<NetplayDevice>,
|
||||
usb: ui::Usb,
|
||||
weak: slint::Weak<AppWindow>,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
weak.upgrade_in_event_loop(move |handle| handle.set_game_running(true))
|
||||
.unwrap();
|
||||
|
||||
let mut device = device::Device::new();
|
||||
device.ui.config.rom_dir = file_path.parent().unwrap().to_path_buf();
|
||||
let mut command = std::process::Command::new(std::env::current_exe().unwrap());
|
||||
command.args([
|
||||
"--fullscreen",
|
||||
&game_settings.fullscreen.to_string(),
|
||||
"--overclock",
|
||||
&game_settings.overclock.to_string(),
|
||||
"--disable-expansion-pak",
|
||||
&game_settings.disable_expansion_pak.to_string(),
|
||||
]);
|
||||
let cheats_path = ui::get_dirs().cache_dir.join("cheats.json");
|
||||
if let Some(netplay_device) = netplay {
|
||||
let f = std::fs::File::create(cheats_path.to_str().unwrap()).unwrap();
|
||||
serde_json::to_writer_pretty(f, &game_settings.cheats).unwrap();
|
||||
|
||||
command.args([
|
||||
"--netplay-peer-addr",
|
||||
&netplay_device.peer_addr.to_string(),
|
||||
"--netplay-player-number",
|
||||
&netplay_device.player_number.to_string(),
|
||||
"--cheats",
|
||||
cheats_path.to_str().unwrap(),
|
||||
]);
|
||||
}
|
||||
|
||||
for i in 0..4 {
|
||||
if gb_paths.rom[i].is_some() && gb_paths.ram[i].is_some() {
|
||||
device.transferpaks[i].cart.rom =
|
||||
std::fs::read(gb_paths.rom[i].as_ref().unwrap()).unwrap();
|
||||
|
||||
device.transferpaks[i].cart.ram =
|
||||
std::fs::read(gb_paths.ram[i].as_ref().unwrap()).unwrap();
|
||||
command.args([
|
||||
"--gb-rom",
|
||||
gb_paths.rom[i].as_ref().unwrap().to_str().unwrap(),
|
||||
"--gb-ram",
|
||||
gb_paths.ram[i].as_ref().unwrap().to_str().unwrap(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
device.ui.usb.usb_tx = usb.usb_tx;
|
||||
device.ui.usb.cart_rx = usb.cart_rx;
|
||||
command
|
||||
.arg(file_path.to_str().unwrap())
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
|
||||
device.ui.weak = Some(weak.clone());
|
||||
let _ = std::fs::remove_file(cheats_path.to_str().unwrap());
|
||||
|
||||
if let Some(rom_contents) = device::get_rom_contents(file_path.as_path()) {
|
||||
if let Some(netplay_device) = netplay {
|
||||
device.netplay = Some(netplay::init(
|
||||
netplay_device.peer_addr,
|
||||
netplay_device.player_number,
|
||||
));
|
||||
} else {
|
||||
game_settings.cheats = {
|
||||
let game_crc = ui::storage::get_game_crc(&rom_contents);
|
||||
let cheats = ui::config::Cheats::new();
|
||||
cheats.cheats.get(&game_crc).cloned().unwrap_or_default()
|
||||
};
|
||||
}
|
||||
device::run_game(&mut device, rom_contents, game_settings);
|
||||
if device.netplay.is_some() {
|
||||
netplay::close(&mut device);
|
||||
}
|
||||
} else {
|
||||
println!("Could not read rom file");
|
||||
}
|
||||
|
||||
let rom_dir = device.ui.config.rom_dir.clone();
|
||||
weak.upgrade_in_event_loop(move |handle| {
|
||||
if let Some(rom_dir_str) = rom_dir.to_str() {
|
||||
handle.set_rom_dir(rom_dir_str.into());
|
||||
if let Some(rom_dir) = file_path.parent().unwrap().to_str() {
|
||||
handle.set_rom_dir(rom_dir.into());
|
||||
}
|
||||
handle.set_game_running(false);
|
||||
})
|
||||
@@ -395,7 +383,7 @@ pub fn run_rom(
|
||||
});
|
||||
}
|
||||
|
||||
fn open_rom(app: &AppWindow, usb: ui::Usb) {
|
||||
fn open_rom(app: &AppWindow) {
|
||||
let rom_dir = app.get_rom_dir();
|
||||
let select_rom = if !rom_dir.is_empty()
|
||||
&& let Ok(exists) = std::fs::exists(&rom_dir)
|
||||
@@ -462,7 +450,6 @@ fn open_rom(app: &AppWindow, usb: ui::Usb) {
|
||||
load_savestate_slot: None,
|
||||
},
|
||||
None,
|
||||
usb,
|
||||
weak,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ export component Settings inherits Page {
|
||||
HorizontalBox {
|
||||
alignment: start;
|
||||
CheckBox {
|
||||
text: @tr("Emulate UNFLoader (reload emulator after changing)");
|
||||
text: @tr("Emulate UNFLoader");
|
||||
checked: SettingsData.emulate_usb;
|
||||
toggled => {
|
||||
SettingsData.emulate_usb = self.checked;
|
||||
|
||||
@@ -1112,10 +1112,6 @@ fn setup_wait_window(
|
||||
peer_addr: socket_addr,
|
||||
player_number: player_number as u8,
|
||||
}),
|
||||
ui::Usb {
|
||||
usb_tx: None,
|
||||
cart_rx: None,
|
||||
},
|
||||
weak_app,
|
||||
);
|
||||
})
|
||||
|
||||
+3
-46
@@ -26,53 +26,12 @@ fn respond_to_handshake(usb_tx: &tokio::sync::broadcast::Sender<UsbData>, data:
|
||||
}
|
||||
}
|
||||
|
||||
fn upload_rom(
|
||||
weak: slint::Weak<ui::gui::AppWindow>,
|
||||
rom: Vec<u8>,
|
||||
usb_tx: &tokio::sync::broadcast::Sender<UsbData>,
|
||||
cart_rx: &tokio::sync::broadcast::Receiver<UsbData>,
|
||||
) {
|
||||
let weak_clone = weak.clone();
|
||||
let usb_tx = usb_tx.clone();
|
||||
let cart_rx = cart_rx.resubscribe();
|
||||
|
||||
weak.upgrade_in_event_loop(move |handle| {
|
||||
let dir = std::env::temp_dir();
|
||||
let rom_path = dir.join("rom_upload.bin");
|
||||
std::fs::write(rom_path.clone(), rom).unwrap();
|
||||
|
||||
ui::gui::run_rom(
|
||||
ui::gui::GbPaths {
|
||||
rom: [None, None, None, None],
|
||||
ram: [None, None, None, None],
|
||||
},
|
||||
rom_path,
|
||||
ui::gui::GameSettings {
|
||||
fullscreen: handle.get_fullscreen(),
|
||||
overclock: handle.get_overclock_n64_cpu(),
|
||||
disable_expansion_pak: handle.get_disable_expansion_pak(),
|
||||
cheats: std::collections::HashMap::new(), // will be filled in later
|
||||
load_savestate_slot: None,
|
||||
},
|
||||
None,
|
||||
ui::Usb {
|
||||
usb_tx: Some(usb_tx),
|
||||
cart_rx: Some(cart_rx),
|
||||
},
|
||||
weak_clone,
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn handle_connection(
|
||||
conn: tokio::net::TcpStream,
|
||||
mut shutdown_rx: tokio::sync::watch::Receiver<()>,
|
||||
mut usb_rx: tokio::sync::broadcast::Receiver<UsbData>,
|
||||
usb_tx: tokio::sync::broadcast::Sender<UsbData>,
|
||||
cart_tx: tokio::sync::broadcast::Sender<UsbData>,
|
||||
cart_rx: tokio::sync::broadcast::Receiver<UsbData>,
|
||||
weak: slint::Weak<ui::gui::AppWindow>,
|
||||
) {
|
||||
let (mut incoming, mut outgoing) = conn.into_split();
|
||||
|
||||
@@ -147,7 +106,7 @@ async fn handle_connection(
|
||||
if usb_data.data_type == DATATYPE_TCPTEST {
|
||||
respond_to_handshake(&usb_tx,usb_data.data);
|
||||
} else if usb_data.data_type == DATATYPE_ROMUPLOAD {
|
||||
upload_rom(weak.clone(), usb_data.data,&usb_tx,&cart_rx);
|
||||
panic!("ROM upload not supported");
|
||||
} else {
|
||||
cart_tx.send(usb_data).unwrap();
|
||||
}
|
||||
@@ -168,9 +127,7 @@ async fn handle_connection(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
weak: slint::Weak<ui::gui::AppWindow>,
|
||||
) -> (Option<tokio::sync::watch::Sender<()>>, ui::Usb) {
|
||||
pub fn init() -> (Option<tokio::sync::watch::Sender<()>>, ui::Usb) {
|
||||
let (shutdown_tx, mut shutdown_rx) = tokio::sync::watch::channel(());
|
||||
let (usb_tx, usb_rx): (
|
||||
tokio::sync::broadcast::Sender<UsbData>,
|
||||
@@ -192,7 +149,7 @@ pub fn init(
|
||||
tokio::select! {
|
||||
res = listener.accept() => {
|
||||
if let Ok((c,_)) = res {
|
||||
handle_connection(c,shutdown_rx.clone(),usb_rx.resubscribe(),usb_tx.clone(),cart_tx.clone(),cart_rx.resubscribe(),weak.clone()).await;
|
||||
handle_connection(c,shutdown_rx.clone(),usb_rx.resubscribe(),usb_tx.clone(),cart_tx.clone()).await;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
+22
-29
@@ -1,45 +1,38 @@
|
||||
use crate::gui;
|
||||
use slint::ComponentHandle;
|
||||
|
||||
pub fn prompt_for_match(
|
||||
words: &[String],
|
||||
weak_vru: &slint::Weak<gui::AppWindow>,
|
||||
frame_time: f64,
|
||||
) -> u16 {
|
||||
pub fn prompt_for_match(words: &[String], frame_time: f64) -> u16 {
|
||||
let mut dedup_words = words.to_owned();
|
||||
dedup_words.sort();
|
||||
dedup_words.dedup();
|
||||
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel(1);
|
||||
tokio::spawn(async move {
|
||||
let vru_dialog = gui::VruDialog::new().unwrap();
|
||||
let vru_dialog_weak = vru_dialog.as_weak();
|
||||
|
||||
weak_vru
|
||||
.upgrade_in_event_loop(move |_handle| {
|
||||
let vru_dialog = gui::VruDialog::new().unwrap();
|
||||
let vru_dialog_weak = vru_dialog.as_weak();
|
||||
let tx_clicked = tx.clone();
|
||||
|
||||
let tx_clicked = tx.clone();
|
||||
vru_dialog.on_vru_button_clicked(move |chosen_word| {
|
||||
tx_clicked.try_send(chosen_word.to_string()).unwrap();
|
||||
vru_dialog_weak.unwrap().window().hide().unwrap();
|
||||
});
|
||||
|
||||
vru_dialog.on_vru_button_clicked(move |chosen_word| {
|
||||
tx_clicked.try_send(chosen_word.to_string()).unwrap();
|
||||
vru_dialog_weak.unwrap().window().hide().unwrap();
|
||||
});
|
||||
vru_dialog.window().on_close_requested(move || {
|
||||
tx.try_send("".to_string()).unwrap();
|
||||
slint::CloseRequestResponse::HideWindow
|
||||
});
|
||||
|
||||
vru_dialog.window().on_close_requested(move || {
|
||||
tx.try_send("".to_string()).unwrap();
|
||||
slint::CloseRequestResponse::HideWindow
|
||||
});
|
||||
let words_vec = slint::VecModel::default();
|
||||
for word in dedup_words {
|
||||
words_vec.push(word.into());
|
||||
}
|
||||
let words_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
|
||||
std::rc::Rc::new(words_vec);
|
||||
vru_dialog.set_words(slint::ModelRc::from(words_model));
|
||||
|
||||
let words_vec = slint::VecModel::default();
|
||||
for word in dedup_words {
|
||||
words_vec.push(word.into());
|
||||
}
|
||||
let words_model: std::rc::Rc<slint::VecModel<slint::SharedString>> =
|
||||
std::rc::Rc::new(words_vec);
|
||||
vru_dialog.set_words(slint::ModelRc::from(words_model));
|
||||
|
||||
vru_dialog.show().unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
vru_dialog.run().unwrap();
|
||||
});
|
||||
|
||||
let mut result = rx.try_recv();
|
||||
while result.is_err() {
|
||||
|
||||
Reference in New Issue
Block a user