Skip to content

Commit f6cca61

Browse files
authored
Implementation of a new terminal frontend (#179)
* working term implementation * Update README.md
1 parent d514d9f commit f6cca61

File tree

10 files changed

+2340
-321
lines changed

10 files changed

+2340
-321
lines changed

Cargo.lock

Lines changed: 1796 additions & 289 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
1-
[workspace]
2-
members = [
3-
"core",
4-
"arm7tdmi",
5-
"utils",
6-
"platform/rustboyadvance-sdl2",
7-
"platform/rustboyadvance-libretro",
8-
# "platform/rustboyadvance-minifb", - DEPRECATED
9-
"platform/rustboyadvance-wasm",
10-
"platform/rustboyadvance-jni",
11-
"fps_bench"
12-
]
13-
14-
default-members = ["platform/rustboyadvance-sdl2"]
15-
16-
17-
[profile.dev]
18-
opt-level = 2
19-
debug = true
20-
21-
[profile.release]
22-
debug = false
23-
24-
[profile.release-dev]
25-
inherits = "release"
26-
opt-level = 3
27-
debug = true
28-
debug-assertions = false
29-
30-
[profile.release-lto]
31-
inherits = "release"
32-
lto = true
1+
[workspace]
2+
members = [
3+
"core",
4+
"arm7tdmi",
5+
"utils",
6+
"platform/rustboyadvance-sdl2",
7+
"platform/rustboyadvance-libretro",
8+
# "platform/rustboyadvance-minifb", - DEPRECATED
9+
"platform/rustboyadvance-wasm",
10+
"platform/rustboyadvance-jni",
11+
"platform/rustboyadvance-term",
12+
"fps_bench"
13+
]
14+
15+
default-members = ["platform/rustboyadvance-sdl2"]
16+
17+
18+
[profile.dev]
19+
opt-level = 2
20+
debug = true
21+
22+
[profile.release]
23+
debug = false
24+
25+
[profile.release-dev]
26+
inherits = "release"
27+
opt-level = 3
28+
debug = true
29+
debug-assertions = false
30+
31+
[profile.release-lto]
32+
inherits = "release"
33+
lto = true

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ WebAssembly Demo: https://michelhe.github.io/rustboyadvance-ng/ ![Deploy](https:
2020
* `platform/rustbodyadvance-sdl2` - Desktop application built with sdl2
2121
* `platform/rustbodyadvance-minifb` - Desktop application built with minifb, *not maintained*.
2222
* `platform/rustbodyadvance-jni` - Java JNI binidngs for the emulator.
23+
* `platform/rustbodyadvance-term` - A full in-terminal frontend implemented via crossterm and viuer by @FRoith.
2324
* `platform/android` - A PoC Android application.
2425

2526
# Progress
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[package]
2+
name = "rustboyadvance-term"
3+
version = "0.1.0"
4+
authors = ["Felix Roithmayr <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
rustboyadvance-core = { path = "../../core/", features = ["elf_support"] }
9+
rustboyadvance-utils = { path = "../../utils/" }
10+
structopt = "0.3"
11+
bit = "^0.1"
12+
tinyaudio = "1.1.0"
13+
tokio = { version = "1.44.2", features = ["full"] }
14+
crossterm = { version = "0.29.0", features = ["event-stream"] }
15+
image = "0.25.6"
16+
futures = "0.3.31"
17+
color-eyre = "0.6.4"
18+
viuer = "0.9.1"
19+
20+
[target.'cfg(windows)'.build-dependencies]
21+
winres = "0.1"
22+
23+
# [features]
24+
# default = ["gdb"]
25+
# debugger = ["rustboyadvance-core/debugger"]
26+
# gdb = ["rustboyadvance-core/gdb"]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use rustboyadvance_core::prelude::SimpleAudioInterface;
2+
3+
use tinyaudio::prelude::*;
4+
5+
pub fn create_audio_player() -> (Box<SimpleAudioInterface>, OutputDevice) {
6+
let desired_spec = OutputDeviceParameters {
7+
sample_rate: 44_100,
8+
channels_count: 2, // stereo
9+
channel_sample_count: 44_100 / 30,
10+
};
11+
12+
let freq = desired_spec.sample_rate as i32;
13+
let ringbuf_size = desired_spec.channel_sample_count * 2;
14+
15+
let (audio_device, mut consumer) =
16+
SimpleAudioInterface::create_channel(freq, Some(ringbuf_size));
17+
18+
let r = run_output_device(desired_spec, move |data| {
19+
'outer: for samples in data.chunks_mut(desired_spec.channels_count) {
20+
for sample in samples {
21+
if let Some(v) = consumer.pop() {
22+
*sample = v as f32 / i16::MAX as f32;
23+
} else {
24+
break 'outer;
25+
}
26+
}
27+
}
28+
})
29+
.unwrap();
30+
31+
(audio_device, r)
32+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: rba-term
2+
author: Felix Roithmayr <[email protected]>
3+
about: RustBoyAdvance port with terminal frontend
4+
args:
5+
- bios:
6+
help: Sets the bios file to use
7+
short: b
8+
required: false
9+
default_value: gba_bios.bin
10+
- game_rom:
11+
long: game-rom
12+
takes_value: true
13+
help: Sets the game-rom file to use
14+
required: false
15+
index: 1
16+
- save_type:
17+
short: s
18+
help: Override save type, useful for troublemaking games that fool the auto detection
19+
required: false
20+
default_value: autodetect
21+
possible_values:
22+
- sram
23+
- flash128k
24+
- flash64k
25+
- eeprom
26+
- autodetect
27+
- rtc:
28+
long: rtc
29+
help: Force cartridge to have RTC
30+
required: false
31+
- skip_bios:
32+
long: skip-bios
33+
help: Skip running bios and start from the ROM instead
34+
- debug:
35+
long: debug
36+
help: Use the custom debugger
37+
- silent:
38+
long: silent
39+
help: Do not output sound
40+
- with_gdbserver:
41+
long: with-gdbserver
42+
help: Start with experimental gdbserver
43+
conflicts_with:
44+
- debug
45+
- script_file:
46+
long: script-file
47+
short: f
48+
takes_value: true
49+
help: Text file with debugger commands to run
50+
required: false
51+
requires:
52+
debug
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use crossterm::event::KeyCode;
2+
use rustboyadvance_core::keypad as gba_keypad;
3+
4+
use bit;
5+
use bit::BitIndex;
6+
7+
pub fn on_keyboard_key_down(key_state: &mut u16, scancode: KeyCode) {
8+
if let Some(key) = scancode_to_keypad(scancode) {
9+
key_state.set_bit(key as usize, false);
10+
}
11+
}
12+
13+
pub fn on_keyboard_key_up(key_state: &mut u16, scancode: KeyCode) {
14+
if let Some(key) = scancode_to_keypad(scancode) {
15+
key_state.set_bit(key as usize, true);
16+
}
17+
}
18+
19+
fn scancode_to_keypad(scancode: KeyCode) -> Option<gba_keypad::Keys> {
20+
match scancode {
21+
KeyCode::Up => Some(gba_keypad::Keys::Up),
22+
KeyCode::Down => Some(gba_keypad::Keys::Down),
23+
KeyCode::Left => Some(gba_keypad::Keys::Left),
24+
KeyCode::Right => Some(gba_keypad::Keys::Right),
25+
KeyCode::Char('z') => Some(gba_keypad::Keys::ButtonB),
26+
KeyCode::Char('x') => Some(gba_keypad::Keys::ButtonA),
27+
KeyCode::Enter => Some(gba_keypad::Keys::Start),
28+
KeyCode::Backspace => Some(gba_keypad::Keys::Select),
29+
KeyCode::Char('a') => Some(gba_keypad::Keys::ButtonL),
30+
KeyCode::Char('s') => Some(gba_keypad::Keys::ButtonR),
31+
_ => None,
32+
}
33+
}

0 commit comments

Comments
 (0)