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
9aeec374
Verified
Commit
9aeec374
authored
1 year ago
by
João Magalhães
Browse files
Options
Downloads
Patches
Plain Diff
chore: initial working version of the display
parent
247fb798
No related branches found
No related tags found
1 merge request
!29
Support for Libretro
Pipeline
#3072
passed
1 year ago
Stage: build
Stage: test
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
frontends/libretro/src/lib.rs
+51
-5
51 additions, 5 deletions
frontends/libretro/src/lib.rs
src/gb.rs
+8
-1
8 additions, 1 deletion
src/gb.rs
src/ppu.rs
+38
-2
38 additions, 2 deletions
src/ppu.rs
with
97 additions
and
8 deletions
frontends/libretro/src/lib.rs
+
51
−
5
View file @
9aeec374
...
...
@@ -4,17 +4,25 @@ use std::os::raw::{c_char, c_float, c_uint, c_void};
use
boytacean
::{
gb
::
GameBoy
,
ppu
::{
DISPLAY_HEIGHT
,
DISPLAY_WIDTH
},
ppu
::{
DISPLAY_HEIGHT
,
DISPLAY_WIDTH
,
RGB1555_SIZE
},
};
const
RETRO_API_VERSION
:
u32
=
1
;
const
REGION_NTSC
:
u32
=
0
;
//const RETRO_ENVIRONMENT_SET_PIXEL_FORMAT: u32 = 10;
//const RETRO_PIXEL_FORMAT_0RGB1555: usize = 0;
//const RETRO_PIXEL_FORMAT_XRGB8888: usize = 1;
//const RETRO_PIXEL_FORMAT_RGB565: usize = 2;
//const RETRO_MEMORY_SAVE_RAM: u32 = 0;
//const RETRO_MEMORY_SYSTEM_RAM: u32 = 0;
static
mut
EMULATOR
:
Option
<
GameBoy
>
=
None
;
static
mut
ENVIRONMENT_CALLBACK
:
Option
<
extern
"C"
fn
(
u32
,
*
const
c_void
)
->
bool
>
=
None
;
static
mut
VIDEO_REFRESH_CALLBACK
:
Option
<
extern
"C"
fn
(
*
const
u8
)
>
=
None
;
static
mut
VIDEO_REFRESH_CALLBACK
:
Option
<
extern
"C"
fn
(
*
const
u8
,
c_uint
,
c_uint
,
usize
)
>
=
None
;
static
mut
AUDIO_SAMPLE_CALLBACK
:
Option
<
extern
"C"
fn
(
i16
,
i16
)
>
=
None
;
static
mut
AUDIO_SAMPLE_BATCH_CALLBACK
:
Option
<
extern
"C"
fn
(
*
const
i16
,
usize
)
>
=
None
;
static
mut
INPUT_POLL_CALLBACK
:
Option
<
extern
"C"
fn
()
>
=
None
;
...
...
@@ -63,6 +71,10 @@ pub struct RetroSystemTiming {
#[no_mangle]
pub
extern
"C"
fn
retro_init
()
{
println!
(
"retro_init()"
);
unsafe
{
EMULATOR
=
Some
(
GameBoy
::
new
(
None
));
EMULATOR
.as_mut
()
.unwrap
()
.load
(
true
);
}
}
#[no_mangle]
...
...
@@ -118,7 +130,9 @@ pub extern "C" fn retro_set_environment(
}
#[no_mangle]
pub
extern
"C"
fn
retro_set_video_refresh
(
callback
:
Option
<
extern
"C"
fn
(
*
const
u8
)
>
)
{
pub
extern
"C"
fn
retro_set_video_refresh
(
callback
:
Option
<
extern
"C"
fn
(
*
const
u8
,
c_uint
,
c_uint
,
usize
)
>
,
)
{
println!
(
"retro_set_video_refresh()"
);
unsafe
{
VIDEO_REFRESH_CALLBACK
=
callback
;
...
...
@@ -176,7 +190,35 @@ pub extern "C" fn retro_set_controller_port_device() {
#[no_mangle]
pub
extern
"C"
fn
retro_run
()
{
println!
(
"retro_run()"
);
let
emulator
=
unsafe
{
EMULATOR
.as_mut
()
.unwrap
()
};
let
mut
counter_cycles
=
0_u32
;
let
cycle_limit
=
4194304
/
60
;
//@TODO this is super tricky
loop
{
// limits the number of ticks to the typical number
// of cycles expected for the current logic cycle
if
counter_cycles
>=
cycle_limit
{
//pending_cycles = counter_cycles - cycle_limit;
break
;
}
// runs the Game Boy clock, this operation should
// include the advance of both the CPU, PPU, APU
// and any other frequency based component of the system
counter_cycles
+=
emulator
.clock
()
as
u32
;
}
let
frame_buffer
=
emulator
.frame_buffer_rgb1555
();
unsafe
{
VIDEO_REFRESH_CALLBACK
.unwrap
()(
frame_buffer
.as_ptr
(),
DISPLAY_WIDTH
as
u32
,
DISPLAY_HEIGHT
as
u32
,
DISPLAY_WIDTH
*
RGB1555_SIZE
,
);
}
}
#[no_mangle]
...
...
@@ -186,8 +228,12 @@ pub extern "C" fn retro_get_region() -> u32 {
}
#[no_mangle]
pub
extern
"C"
fn
retro_load_game
(
_
game
:
*
const
RetroGameInfo
)
->
bool
{
pub
extern
"C"
fn
retro_load_game
(
game
:
*
const
RetroGameInfo
)
->
bool
{
println!
(
"retro_load_game()"
);
unsafe
{
let
data_buffer
=
std
::
slice
::
from_raw_parts
((
*
game
)
.data
as
*
const
u8
,
(
*
game
)
.size
);
EMULATOR
.as_mut
()
.unwrap
()
.load_rom
(
data_buffer
,
None
);
}
return
true
;
}
...
...
This diff is collapsed.
Click to expand it.
src/gb.rs
+
8
−
1
View file @
9aeec374
...
...
@@ -14,7 +14,10 @@ use crate::{
gen
::{
COMPILATION_DATE
,
COMPILATION_TIME
,
COMPILER
,
COMPILER_VERSION
,
VERSION
},
mmu
::
Mmu
,
pad
::{
Pad
,
PadKey
},
ppu
::{
Ppu
,
PpuMode
,
Tile
,
DISPLAY_HEIGHT
,
DISPLAY_WIDTH
,
FRAME_BUFFER_SIZE
},
ppu
::{
Ppu
,
PpuMode
,
Tile
,
DISPLAY_HEIGHT
,
DISPLAY_WIDTH
,
FRAME_BUFFER_RGB155_SIZE
,
FRAME_BUFFER_SIZE
,
},
rom
::{
Cartridge
,
RamSize
},
serial
::{
NullDevice
,
Serial
,
SerialDevice
},
timer
::
Timer
,
...
...
@@ -950,6 +953,10 @@ impl GameBoy {
&
(
self
.ppu
()
.frame_buffer
)
}
pub
fn
frame_buffer_rgb1555
(
&
mut
self
)
->
[
u8
;
FRAME_BUFFER_RGB155_SIZE
]
{
self
.ppu
()
.frame_buffer_rgb1555
()
}
pub
fn
audio_buffer
(
&
mut
self
)
->
&
VecDeque
<
u8
>
{
self
.apu
()
.audio_buffer
()
}
...
...
This diff is collapsed.
Click to expand it.
src/ppu.rs
+
38
−
2
View file @
9aeec374
...
...
@@ -23,6 +23,7 @@ pub const OAM_SIZE: usize = 260;
pub
const
PALETTE_SIZE
:
usize
=
4
;
pub
const
RGB_SIZE
:
usize
=
3
;
pub
const
RGBA_SIZE
:
usize
=
4
;
pub
const
RGB1555_SIZE
:
usize
=
2
;
pub
const
TILE_WIDTH
:
usize
=
8
;
pub
const
TILE_HEIGHT
:
usize
=
8
;
pub
const
TILE_WIDTH_I
:
usize
=
7
;
...
...
@@ -46,13 +47,19 @@ pub const DISPLAY_WIDTH: usize = 160;
/// The height of the Game Boy screen in pixels.
pub
const
DISPLAY_HEIGHT
:
usize
=
144
;
/// The size in pixels of the display.
pub
const
DISPLAY_SIZE
:
usize
=
DISPLAY_WIDTH
*
DISPLAY_HEIGHT
;
/// The size to be used by the buffer of colors
/// for the Game Boy screen the values there should
/// range from 0 to 3.
pub
const
COLOR_BUFFER_SIZE
:
usize
=
DISPLAY_
WIDTH
*
DISPLAY_HEIGHT
;
pub
const
COLOR_BUFFER_SIZE
:
usize
=
DISPLAY_
SIZE
;
/// The size of the RGB frame buffer in bytes.
pub
const
FRAME_BUFFER_SIZE
:
usize
=
DISPLAY_WIDTH
*
DISPLAY_HEIGHT
*
RGB_SIZE
;
pub
const
FRAME_BUFFER_SIZE
:
usize
=
DISPLAY_SIZE
*
RGB_SIZE
;
/// The size of the RGB1555 frame buffer in bytes.
pub
const
FRAME_BUFFER_RGB155_SIZE
:
usize
=
DISPLAY_SIZE
*
RGB1555_SIZE
;
/// The base colors to be used to populate the
/// custom palettes of the Game Boy.
...
...
@@ -74,6 +81,10 @@ pub type Pixel = [u8; RGB_SIZE];
/// with the size of RGBA (4 bytes).
pub
type
PixelAlpha
=
[
u8
;
RGBA_SIZE
];
/// Defines a pixel with 5 bits per channel plus a padding
/// bit at the beginning.
pub
type
PixelRgb1555
=
[
u8
;
RGB1555_SIZE
];
/// Defines a type that represents a color palette
/// within the Game Boy context.
pub
type
Palette
=
[
Pixel
;
PALETTE_SIZE
];
...
...
@@ -896,6 +907,21 @@ impl Ppu {
}
}
pub
fn
frame_buffer_rgb1555
(
&
self
)
->
[
u8
;
FRAME_BUFFER_RGB155_SIZE
]
{
let
mut
buffer
=
[
0u8
;
FRAME_BUFFER_RGB155_SIZE
];
for
index
in
0
..
DISPLAY_SIZE
{
let
(
r
,
g
,
b
)
=
(
self
.frame_buffer
[
index
*
3
],
self
.frame_buffer
[
index
*
3
+
1
],
self
.frame_buffer
[
index
*
3
+
2
],
);
let
rgb1555
=
Self
::
rgb888_to_rgb1555
(
r
,
g
,
b
);
buffer
[
index
*
2
]
=
rgb1555
[
0
];
buffer
[
index
*
2
+
1
]
=
rgb1555
[
1
];
}
buffer
}
pub
fn
vram
(
&
self
)
->
&
[
u8
;
VRAM_SIZE
]
{
&
self
.vram
}
...
...
@@ -1709,6 +1735,16 @@ impl Ppu {
let
b
=
((
second
&
0x7c
)
>>
2
)
<<
3
;
[
r
,
g
,
b
]
}
fn
rgb888_to_rgb1555
(
first
:
u8
,
second
:
u8
,
third
:
u8
)
->
PixelRgb1555
{
let
r
=
(
first
as
u16
>>
3
)
&
0x1F
;
let
g
=
(
second
as
u16
>>
3
)
&
0x1F
;
let
b
=
(
third
as
u16
>>
3
)
&
0x1F
;
let
a
=
1
;
let
pixel
=
(
a
<<
15
)
|
(
b
<<
10
)
|
(
g
<<
5
)
|
r
;
[
pixel
as
u8
,
(
pixel
>>
8
)
as
u8
]
}
}
impl
Default
for
Ppu
{
...
...
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