reimplement through character selection
This commit is contained in:
parent
d0bdfc8602
commit
fd81c06348
|
@ -327,10 +327,12 @@ name = "dkgolf"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"crossbeam-channel",
|
||||
"failure",
|
||||
"ferretro",
|
||||
"ferretro-recorder",
|
||||
"ffmpeg-next",
|
||||
"lerp",
|
||||
"libloading",
|
||||
"libretro-sys",
|
||||
"mammut",
|
||||
|
@ -392,7 +394,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ferretro"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@vvn.space:2222/cinnabon/rustro.git?branch=viv/ffmpeg2#3cad3b1e29cfc76116399e3475113b59ee22e312"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"failure",
|
||||
|
@ -404,12 +405,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ferretro-recorder"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@vvn.space:2222/cinnabon/ferretro-recorder.git?branch=main#5b3fe4b9287c6bb192f186cc47c8bcb499c034a3"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"failure",
|
||||
"ferretro",
|
||||
"ffmpeg-next",
|
||||
"lerp",
|
||||
"libloading",
|
||||
"libretro-sys",
|
||||
"mammut",
|
||||
|
@ -756,6 +757,15 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lerp"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b19ac50d419bff1a024a8eb8034bfbee6c1cf8fa3472502f6bd3def327b09e4c"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.98"
|
||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -14,8 +14,12 @@ libloading = "^0.5"
|
|||
num_enum = "^0.4"
|
||||
ffmpeg-next = "4.3.8"
|
||||
rand = "0.8.4"
|
||||
ferretro-recorder = { git = "ssh://git@vvn.space:2222/cinnabon/ferretro-recorder.git", branch = "main" }
|
||||
ferretro = { git = "ssh://git@vvn.space:2222/cinnabon/rustro.git", branch = "viv/ffmpeg2" }
|
||||
#ferretro-recorder = { git = "ssh://git@vvn.space:2222/cinnabon/ferretro-recorder.git", branch = "main" }
|
||||
ferretro = { path = "../rustro" }
|
||||
ferretro-recorder = { path = "../ferretro-recorder" }
|
||||
#ferretro = { git = "ssh://git@vvn.space:2222/cinnabon/rustro.git", branch = "viv/ffmpeg2" }
|
||||
structopt = "^0.3"
|
||||
mammut = "0.13.0"
|
||||
toml = "0.5.8"
|
||||
toml = "0.5.8"
|
||||
crossbeam-channel = "0.5.1"
|
||||
lerp = "0.4.0"
|
|
@ -0,0 +1,84 @@
|
|||
use std::{pin::Pin, sync::{Arc, Mutex}};
|
||||
|
||||
use crossbeam_channel::SendError;
|
||||
use failure::Fallible;
|
||||
use ferretro::retro::constants::JoypadButton;
|
||||
use ferretro_recorder::{driver::{Axes, Command, Driver, MemoryOverwriter}, emulator_runner::RecordedEmulator, inputs::Inputs};
|
||||
|
||||
pub fn dk_behavior(emu: Arc<Mutex<Pin<Box<RecordedEmulator<()>>>>>, mut driver: Driver) -> Result<(), SendError<Command>> {
|
||||
driver.record(false)?;
|
||||
go_to_vs_mode(&mut driver);
|
||||
driver.wait_frames(100);
|
||||
|
||||
|
||||
// and make the computer be a random character
|
||||
// everytthing after 0b is special characters.
|
||||
// 0c: master hand
|
||||
// 0d: metal mario
|
||||
// 0e-19: polygon team
|
||||
// 1a is giant dk
|
||||
let mut random_char = rand::random::<u8>() % 0x1b;
|
||||
if random_char > 0x0b { // if it picked a special character, reroll - i want special characters to be a bit less likely than regular ones
|
||||
random_char = rand::random::<u8>() % 0x1b;
|
||||
}
|
||||
|
||||
charsel_set_p1_p2_chars_secz(emu.clone(), &mut driver, 0x02 /*dk*/, random_char);
|
||||
driver.record(true)?;
|
||||
driver.wait_frames(400);
|
||||
// Announcer says GO! here
|
||||
driver.end();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn go_to_vs_mode(driver: &mut Driver){
|
||||
// Skip intro
|
||||
driver.wait_frames(300);
|
||||
driver.press_buttons(&[JoypadButton::Start], 0);
|
||||
// Enter title screen
|
||||
driver.wait_frames(60);
|
||||
driver.press_buttons(&[JoypadButton::Start], 0);
|
||||
// Select VS mode
|
||||
driver.wait_frames(60);
|
||||
driver.press_buttons(&[JoypadButton::Down], 0);
|
||||
// Enter VS mode
|
||||
driver.press_buttons(&[JoypadButton::B], 0);
|
||||
// VS start
|
||||
driver.press_buttons(&[JoypadButton::B], 0);
|
||||
}
|
||||
|
||||
fn charsel_set_p1_p2_chars_secz(emu: Arc<Mutex<Pin<Box<RecordedEmulator<()>>>>>, driver: &mut Driver, p1_char_byte: u8, p2_char_byte: u8) -> Result<(), SendError<Command>> {
|
||||
driver.move_and_release_analog(vec![
|
||||
(Axes {x: 0.3, y: -1.0}, 0),
|
||||
(Axes {x: 1.0, y: -1.0}, 1),
|
||||
], 25, 5)?;
|
||||
driver.press_buttons(&[JoypadButton::B], 0);
|
||||
driver.press_buttons(&[JoypadButton::B], 1);
|
||||
|
||||
driver.press_buttons(&[JoypadButton::Start], 0);
|
||||
driver.wait_frames(90);
|
||||
driver.press_buttons(&[JoypadButton::Down], 0);
|
||||
driver.press_buttons(&[JoypadButton::Right], 0);
|
||||
driver.press_buttons(&[JoypadButton::Right], 0);
|
||||
|
||||
// Set memory overwrites for P1 and P2 character
|
||||
driver.send_memory_overwrite(MemoryOverwriter {
|
||||
address: 0xa4d28,
|
||||
data: vec![p1_char_byte],
|
||||
memory_region: 2,
|
||||
num_frames_active: 0,
|
||||
expires_after_frames: None,
|
||||
})?;
|
||||
|
||||
driver.send_memory_overwrite(MemoryOverwriter {
|
||||
address: 0xa4d9c,
|
||||
data: vec![p2_char_byte],
|
||||
memory_region: 2,
|
||||
num_frames_active: 0,
|
||||
expires_after_frames: None,
|
||||
})?;
|
||||
|
||||
driver.press_buttons(&[JoypadButton::B], 0);
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
70
src/main.rs
70
src/main.rs
|
@ -2,16 +2,21 @@ extern crate ferretro;
|
|||
extern crate ferretro_recorder;
|
||||
extern crate ffmpeg_next as ffmpeg;
|
||||
extern crate rand;
|
||||
extern crate crossbeam_channel;
|
||||
extern crate lerp;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::pin::Pin;
|
||||
use std::thread;
|
||||
use ferretro_recorder::driver::Driver;
|
||||
use num_enum::IntoPrimitive;
|
||||
|
||||
use ferretro::retro;
|
||||
use ferretro::retro::constants::{InputIndex, JoypadButton};
|
||||
use ferretro::retro::constants::{AnalogAxis, InputIndex, JoypadButton};
|
||||
use ferretro::retro::wrapped_types::InputDeviceId;
|
||||
use ferretro_recorder::emulator_runner::RecordedEmulator;
|
||||
use mammut::apps::{AppBuilder, Scopes};
|
||||
|
@ -19,11 +24,47 @@ use mammut::{Data, Mastodon, MediaBuilder, Registration, StatusBuilder};
|
|||
use structopt::StructOpt;
|
||||
use failure::Fallible;
|
||||
|
||||
mod behavior;
|
||||
|
||||
struct DKState {
|
||||
stay_crouched: bool,
|
||||
active_input: [Inputs; 4]
|
||||
|
||||
}
|
||||
|
||||
struct Inputs {
|
||||
buttons: HashMap<JoypadButton, i16>,
|
||||
analog: HashMap<AnalogAxis, i16>
|
||||
}
|
||||
|
||||
impl Inputs {
|
||||
pub fn new() -> Self {
|
||||
Inputs {
|
||||
buttons: HashMap::new(),
|
||||
analog: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_buttons(&mut self, buttons: &[JoypadButton]) {
|
||||
for button in buttons {
|
||||
self.buttons.insert(*button, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn stateful_input_callback(emu: &mut RecordedEmulator<DKState>, port: u32, device: InputDeviceId, index: InputIndex) -> i16 {
|
||||
let port = port as usize;
|
||||
if port >= emu.state.active_input.len() {
|
||||
eprintln!("Input callback called for port {} but state only contains {}", port, emu.state.active_input.len());
|
||||
return 0;
|
||||
}
|
||||
match device {
|
||||
InputDeviceId::Joypad(button) => *(emu.state.active_input[port].buttons.get(&button).unwrap_or(&0)),
|
||||
InputDeviceId::Analog(axis) => *(emu.state.active_input[port].analog.get(&axis).unwrap_or(&0)),
|
||||
_ => 0
|
||||
}
|
||||
}
|
||||
|
||||
fn dk_input_callback(emu: &mut RecordedEmulator<DKState>, port: u32, device: InputDeviceId, index: InputIndex) -> i16 {
|
||||
match emu.emu_frame {
|
||||
300..=320 => { // push start to get to title screen
|
||||
|
@ -339,11 +380,30 @@ fn main() -> Fallible<()> {
|
|||
};
|
||||
|
||||
let dk_state = DKState {
|
||||
stay_crouched: false
|
||||
stay_crouched: false,
|
||||
active_input: [Inputs::new(), Inputs::new(), Inputs::new(), Inputs::new()] // inputs doesn't implement Copy, so I construct it multiple times
|
||||
|
||||
};
|
||||
|
||||
let result = ferretro_recorder::emulator_runner::run_emulator(paths, 2700, false, dk_input_callback, dk_state);
|
||||
let emu = result.unwrap();
|
||||
let mut driver = Driver::new();
|
||||
let driver_channels = driver.export_channels();
|
||||
|
||||
let mut emu = RecordedEmulator::new(
|
||||
paths.core_path.clone(),
|
||||
&paths.system_path,
|
||||
false,
|
||||
());
|
||||
|
||||
let emu2 = emu.clone();
|
||||
let driver_thread = thread::spawn(move || {
|
||||
behavior::dk_behavior(emu2, driver);
|
||||
});
|
||||
|
||||
ferretro_recorder::emulator_runner::run_emulator(emu.clone(), paths, driver_channels).unwrap();
|
||||
driver_thread.join().unwrap();
|
||||
|
||||
// emulator is done running, so just lock it from here on out.
|
||||
let emu = emu.lock().unwrap();
|
||||
|
||||
|
||||
let character_name = {
|
||||
|
|
Loading…
Reference in New Issue