Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
boytacean
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
João Magalhães
boytacean
Commits
c53c2728
Verified
Commit
c53c2728
authored
2 years ago
by
João Magalhães
Browse files
Options
Downloads
Patches
Plain Diff
refactor: small set of simplifications
parent
e675fad1
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!19
Initial tentative audio support 🔉
Pipeline
#2270
failed
2 years ago
Stage: build
Stage: test
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
frontends/sdl/src/main.rs
+29
-20
29 additions, 20 deletions
frontends/sdl/src/main.rs
src/apu.rs
+10
-18
10 additions, 18 deletions
src/apu.rs
src/gb.rs
+2
-8
2 additions, 8 deletions
src/gb.rs
with
41 additions
and
46 deletions
frontends/sdl/src/main.rs
+
29
−
20
View file @
c53c2728
...
@@ -42,6 +42,7 @@ pub struct Emulator {
...
@@ -42,6 +42,7 @@ pub struct Emulator {
system
:
GameBoy
,
system
:
GameBoy
,
graphics
:
Option
<
Graphics
>
,
graphics
:
Option
<
Graphics
>
,
audio
:
Option
<
Audio
>
,
audio
:
Option
<
Audio
>
,
title
:
&
'static
str
,
logic_frequency
:
u32
,
logic_frequency
:
u32
,
visual_frequency
:
f32
,
visual_frequency
:
f32
,
next_tick_time
:
f32
,
next_tick_time
:
f32
,
...
@@ -57,11 +58,12 @@ impl Emulator {
...
@@ -57,11 +58,12 @@ impl Emulator {
system
,
system
,
graphics
:
None
,
graphics
:
None
,
audio
:
None
,
audio
:
None
,
title
:
TITLE
,
logic_frequency
:
GameBoy
::
CPU_FREQ
,
logic_frequency
:
GameBoy
::
CPU_FREQ
,
visual_frequency
:
GameBoy
::
VISUAL_FREQ
*
2.0
,
visual_frequency
:
GameBoy
::
VISUAL_FREQ
,
next_tick_time
:
0.0
,
next_tick_time
:
0.0
,
next_tick_time_i
:
0
,
next_tick_time_i
:
0
,
features
:
vec!
[
"no-vsync"
],
features
:
vec!
[
"video"
,
"audio"
,
"no-vsync"
],
palettes
:
[
palettes
:
[
PaletteInfo
::
new
(
PaletteInfo
::
new
(
"basic"
,
"basic"
,
...
@@ -97,14 +99,18 @@ impl Emulator {
...
@@ -97,14 +99,18 @@ impl Emulator {
pub
fn
start
(
&
mut
self
,
screen_scale
:
f32
)
{
pub
fn
start
(
&
mut
self
,
screen_scale
:
f32
)
{
let
sdl
=
sdl2
::
init
()
.unwrap
();
let
sdl
=
sdl2
::
init
()
.unwrap
();
self
.start_graphics
(
&
sdl
,
screen_scale
);
if
self
.features
.contains
(
&
"video"
)
{
self
.start_audio
(
&
sdl
);
self
.start_graphics
(
&
sdl
,
screen_scale
);
}
if
self
.features
.contains
(
&
"audio"
)
{
self
.start_audio
(
&
sdl
);
}
}
}
pub
fn
start_graphics
(
&
mut
self
,
sdl
:
&
Sdl
,
screen_scale
:
f32
)
{
pub
fn
start_graphics
(
&
mut
self
,
sdl
:
&
Sdl
,
screen_scale
:
f32
)
{
self
.graphics
=
Some
(
Graphics
::
new
(
self
.graphics
=
Some
(
Graphics
::
new
(
&
sdl
,
&
sdl
,
TITLE
,
self
.title
,
DISPLAY_WIDTH
as
u32
,
DISPLAY_WIDTH
as
u32
,
DISPLAY_HEIGHT
as
u32
,
DISPLAY_HEIGHT
as
u32
,
screen_scale
,
screen_scale
,
...
@@ -127,7 +133,7 @@ impl Emulator {
...
@@ -127,7 +133,7 @@ impl Emulator {
.as_mut
()
.as_mut
()
.unwrap
()
.unwrap
()
.window_mut
()
.window_mut
()
.set_title
(
format!
(
"{} [{}]"
,
TITLE
,
rom
.title
())
.as_str
())
.set_title
(
format!
(
"{} [{}]"
,
self
.title
,
rom
.title
())
.as_str
())
.unwrap
();
.unwrap
();
}
}
...
@@ -299,20 +305,23 @@ impl Emulator {
...
@@ -299,20 +305,23 @@ impl Emulator {
last_frame
=
self
.system
.ppu_frame
();
last_frame
=
self
.system
.ppu_frame
();
}
}
// obtains the new audio buffer and queues it into the audio
match
self
.audio
.as_mut
()
{
// subsystem ready to be processed
Some
(
audio
)
=>
{
let
audio_buffer
=
self
// obtains the new audio buffer and queues it into the audio
.system
// subsystem ready to be processed
.audio_buffer
()
let
audio_buffer
=
self
.iter
()
.system
.map
(|
v
|
*
v
as
f32
/
7.0
)
.audio_buffer
()
.collect
::
<
Vec
<
f32
>>
();
.iter
()
self
.audio
.map
(|
v
|
*
v
as
f32
/
14.0
)
.as_mut
()
.collect
::
<
Vec
<
f32
>>
();
.unwrap
()
audio
.device
.queue_audio
(
&
audio_buffer
)
.unwrap
();
.device
}
.queue_audio
(
&
audio_buffer
)
None
=>
(),
.unwrap
();
}
// clears the audio buffer to prevent it from
// "exploding" in size
self
.system
.clear_audio_buffer
();
self
.system
.clear_audio_buffer
();
}
}
...
...
This diff is collapsed.
Click to expand it.
src/apu.rs
+
10
−
18
View file @
c53c2728
...
@@ -48,7 +48,7 @@ pub struct Apu {
...
@@ -48,7 +48,7 @@ pub struct Apu {
wave_ram
:
[
u8
;
16
],
wave_ram
:
[
u8
;
16
],
output_timer
:
u16
,
output_timer
:
u16
,
output_buffer
:
Vec
<
u8
>
output_buffer
:
Vec
<
u8
>
,
}
}
impl
Apu
{
impl
Apu
{
...
@@ -94,18 +94,14 @@ impl Apu {
...
@@ -94,18 +94,14 @@ impl Apu {
wave_ram
:
[
0u8
;
16
],
wave_ram
:
[
0u8
;
16
],
output_timer
:
0
,
output_timer
:
0
,
output_buffer
:
Vec
::
new
()
output_buffer
:
Vec
::
new
()
,
}
}
}
}
pub
fn
clock
(
&
mut
self
,
cycles
:
u8
)
{
pub
fn
clock
(
&
mut
self
,
cycles
:
u8
)
{
self
.clock_f
(
cycles
,
4194304
);
// @TODO the performance here requires improvement
}
pub
fn
clock_f
(
&
mut
self
,
cycles
:
u8
,
freq
:
u32
)
{
// @todo the performance here requires improvement
for
_
in
0
..
cycles
{
for
_
in
0
..
cycles
{
self
.cycle
(
freq
);
self
.cycle
();
}
}
}
}
...
@@ -147,7 +143,6 @@ impl Apu {
...
@@ -147,7 +143,6 @@ impl Apu {
(
self
.ch1_wave_length
&
0x00ff
)
|
(((
value
&
0x07
)
as
u16
)
<<
8
);
(
self
.ch1_wave_length
&
0x00ff
)
|
(((
value
&
0x07
)
as
u16
)
<<
8
);
self
.ch1_sound_length
|
=
value
&
0x40
==
0x40
;
self
.ch1_sound_length
|
=
value
&
0x40
==
0x40
;
self
.ch1_enabled
|
=
value
&
0x80
==
0x80
;
self
.ch1_enabled
|
=
value
&
0x80
==
0x80
;
//println!("CH1 Enabled {}", self.ch1_enabled);
}
}
// 0xFF16 — NR21: Channel 2 length timer & duty cycle
// 0xFF16 — NR21: Channel 2 length timer & duty cycle
...
@@ -174,9 +169,8 @@ impl Apu {
...
@@ -174,9 +169,8 @@ impl Apu {
if
value
&
0x80
==
0x80
{
if
value
&
0x80
==
0x80
{
//self.ch2_timer = 0;
//self.ch2_timer = 0;
//self.ch2_sequence = 0;
//self.ch2_sequence = 0;
//@
todo
improve this reset operation
//@
TODO
improve this reset operation
}
}
//println!("CH2 Enabled {}", self.ch2_enabled);
}
}
// 0xFF1A — NR30: Channel 3 DAC enable
// 0xFF1A — NR30: Channel 3 DAC enable
...
@@ -201,7 +195,6 @@ impl Apu {
...
@@ -201,7 +195,6 @@ impl Apu {
(
self
.ch3_wave_length
&
0x00ff
)
|
(((
value
&
0x07
)
as
u16
)
<<
8
);
(
self
.ch3_wave_length
&
0x00ff
)
|
(((
value
&
0x07
)
as
u16
)
<<
8
);
self
.ch3_sound_length
|
=
value
&
0x40
==
0x40
;
self
.ch3_sound_length
|
=
value
&
0x40
==
0x40
;
self
.ch3_enabled
|
=
value
&
0x80
==
0x80
;
self
.ch3_enabled
|
=
value
&
0x80
==
0x80
;
//println!("CH3 Enabled {}", self.ch3_enabled);
}
}
// 0xFF30-0xFF3F — Wave pattern RAM
// 0xFF30-0xFF3F — Wave pattern RAM
...
@@ -214,11 +207,10 @@ impl Apu {
...
@@ -214,11 +207,10 @@ impl Apu {
}
}
#[inline(always)]
#[inline(always)]
pub
fn
cycle
(
&
mut
self
,
freq
:
u32
)
{
pub
fn
cycle
(
&
mut
self
)
{
self
.ch1_timer
=
self
.ch1_timer
.saturating_sub
(
1
);
self
.ch1_timer
=
self
.ch1_timer
.saturating_sub
(
1
);
if
self
.ch1_timer
==
0
{
if
self
.ch1_timer
==
0
{
let
target_freq
=
1048576.0
/
(
2048.0
-
self
.ch1_wave_length
as
f32
);
self
.ch1_timer
=
(
2048
-
self
.ch1_wave_length
)
<<
2
;
self
.ch1_timer
=
(
freq
as
f32
/
target_freq
)
as
u16
;
self
.ch1_sequence
=
(
self
.ch1_sequence
+
1
)
&
7
;
self
.ch1_sequence
=
(
self
.ch1_sequence
+
1
)
&
7
;
if
self
.ch1_enabled
{
if
self
.ch1_enabled
{
...
@@ -235,8 +227,7 @@ impl Apu {
...
@@ -235,8 +227,7 @@ impl Apu {
self
.ch2_timer
=
self
.ch2_timer
.saturating_sub
(
1
);
self
.ch2_timer
=
self
.ch2_timer
.saturating_sub
(
1
);
if
self
.ch2_timer
==
0
{
if
self
.ch2_timer
==
0
{
let
target_freq
=
1048576.0
/
(
2048.0
-
self
.ch2_wave_length
as
f32
);
self
.ch2_timer
=
(
2048
-
self
.ch2_wave_length
)
<<
2
;
self
.ch2_timer
=
(
freq
as
f32
/
target_freq
)
as
u16
;
self
.ch2_sequence
=
(
self
.ch2_sequence
+
1
)
&
7
;
self
.ch2_sequence
=
(
self
.ch2_sequence
+
1
)
&
7
;
if
self
.ch2_enabled
{
if
self
.ch2_enabled
{
...
@@ -254,7 +245,8 @@ impl Apu {
...
@@ -254,7 +245,8 @@ impl Apu {
self
.output_timer
=
self
.output_timer
.saturating_sub
(
1
);
self
.output_timer
=
self
.output_timer
.saturating_sub
(
1
);
if
self
.output_timer
==
0
{
if
self
.output_timer
==
0
{
self
.output_buffer
.push
(
self
.output
());
self
.output_buffer
.push
(
self
.output
());
self
.output_timer
=
(
freq
as
f32
/
44100.0
)
as
u16
;
// @todo target sampling rate is hardcoded
// @TODO target sampling rate is hardcoded, need to softcode this
self
.output_timer
=
(
4194304.0
/
44100.0
)
as
u16
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
src/gb.rs
+
2
−
8
View file @
c53c2728
...
@@ -54,8 +54,7 @@ pub struct Registers {
...
@@ -54,8 +54,7 @@ pub struct Registers {
}
}
pub
trait
AudioProvider
{
pub
trait
AudioProvider
{
fn
output_apu
(
&
self
)
->
u8
;
fn
audio_output
(
&
self
)
->
u8
;
fn
output_clock_apu
(
&
mut
self
,
cycles
:
u8
,
freq
:
u32
)
->
u8
;
fn
audio_buffer
(
&
self
)
->
&
Vec
<
u8
>
;
fn
audio_buffer
(
&
self
)
->
&
Vec
<
u8
>
;
fn
clear_audio_buffer
(
&
mut
self
);
fn
clear_audio_buffer
(
&
mut
self
);
}
}
...
@@ -384,12 +383,7 @@ pub fn hook_impl(info: &PanicInfo) {
...
@@ -384,12 +383,7 @@ pub fn hook_impl(info: &PanicInfo) {
}
}
impl
AudioProvider
for
GameBoy
{
impl
AudioProvider
for
GameBoy
{
fn
output_apu
(
&
self
)
->
u8
{
fn
audio_output
(
&
self
)
->
u8
{
self
.apu_i
()
.output
()
}
fn
output_clock_apu
(
&
mut
self
,
cycles
:
u8
,
freq
:
u32
)
->
u8
{
self
.apu
()
.clock_f
(
cycles
,
freq
);
self
.apu_i
()
.output
()
self
.apu_i
()
.output
()
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment