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
f85b1b73
Verified
Commit
f85b1b73
authored
2 years ago
by
João Magalhães
Browse files
Options
Downloads
Patches
Plain Diff
feat: initial support for sprite drawing
parent
dbc385d0
No related branches found
No related tags found
1 merge request
!3
Support for sprites/object drawing 💪
Pipeline
#925
failed
2 years ago
Stage: build
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/ppu.rs
+48
-33
48 additions, 33 deletions
src/ppu.rs
with
48 additions
and
33 deletions
src/ppu.rs
+
48
−
33
View file @
f85b1b73
...
@@ -48,19 +48,6 @@ pub struct Tile {
...
@@ -48,19 +48,6 @@ pub struct Tile {
buffer
:
[
u8
;
64
],
buffer
:
[
u8
;
64
],
}
}
#[cfg_attr(feature
=
"wasm"
,
wasm_bindgen)]
#[derive(Clone,
Copy,
PartialEq)]
pub
struct
ObjectData
{
x
:
i16
,
y
:
i16
,
tile
:
u8
,
palette
:
u8
,
xflip
:
bool
,
yflip
:
bool
,
prio
:
u8
,
num
:
u8
,
}
#[cfg_attr(feature
=
"wasm"
,
wasm_bindgen)]
#[cfg_attr(feature
=
"wasm"
,
wasm_bindgen)]
impl
Tile
{
impl
Tile
{
pub
fn
get
(
&
self
,
x
:
usize
,
y
:
usize
)
->
u8
{
pub
fn
get
(
&
self
,
x
:
usize
,
y
:
usize
)
->
u8
{
...
@@ -102,6 +89,29 @@ impl Display for Tile {
...
@@ -102,6 +89,29 @@ impl Display for Tile {
}
}
}
}
#[cfg_attr(feature
=
"wasm"
,
wasm_bindgen)]
#[derive(Clone,
Copy,
PartialEq)]
pub
struct
ObjectData
{
x
:
i16
,
y
:
i16
,
tile
:
u8
,
palette
:
u8
,
xflip
:
bool
,
yflip
:
bool
,
prio
:
u8
,
index
:
u8
,
}
impl
Display
for
ObjectData
{
fn
fmt
(
&
self
,
f
:
&
mut
Formatter
<
'_
>
)
->
fmt
::
Result
{
write!
(
f
,
"Index => {} X => {} Y => {} Tile => {}"
,
self
.index
,
self
.x
,
self
.y
,
self
.tile
)
}
}
/// Represents the Game Boy PPU (Pixel Processing Unit) and controls
/// Represents the Game Boy PPU (Pixel Processing Unit) and controls
/// all of the logic behind the graphics processing and presentation.
/// all of the logic behind the graphics processing and presentation.
/// Should store both the VRAM and HRAM together with the internal
/// Should store both the VRAM and HRAM together with the internal
...
@@ -236,7 +246,7 @@ impl Ppu {
...
@@ -236,7 +246,7 @@ impl Ppu {
xflip
:
false
,
xflip
:
false
,
yflip
:
false
,
yflip
:
false
,
prio
:
0
,
prio
:
0
,
num
:
0
,
index
:
0
,
};
OBJ_COUNT
],
};
OBJ_COUNT
],
palette
:
[[
0u8
;
RGB_SIZE
];
PALETTE_SIZE
],
palette
:
[[
0u8
;
RGB_SIZE
];
PALETTE_SIZE
],
palette_obj_0
:
[[
0u8
;
RGB_SIZE
];
PALETTE_SIZE
],
palette_obj_0
:
[[
0u8
;
RGB_SIZE
];
PALETTE_SIZE
],
...
@@ -534,16 +544,17 @@ impl Ppu {
...
@@ -534,16 +544,17 @@ impl Ppu {
if
obj_index
>=
OBJ_COUNT
{
if
obj_index
>=
OBJ_COUNT
{
return
;
return
;
}
}
let
mut
obj
_data
=
self
.obj_data
[
obj_index
];
let
mut
obj
=
self
.obj_data
[
obj_index
]
.borrow_mut
()
;
match
addr
&
0x03
{
match
addr
&
0x03
{
0x00
=>
obj
_data
.y
=
value
as
i16
-
16
,
0x00
=>
obj
.y
=
value
as
i16
-
16
,
0x01
=>
obj
_data
.x
=
value
as
i16
-
16
,
0x01
=>
obj
.x
=
value
as
i16
-
8
,
0x02
=>
obj
_data
.tile
=
value
,
0x02
=>
obj
.tile
=
value
,
0x03
=>
{
0x03
=>
{
obj_data
.palette
=
if
value
&
0x10
==
0x10
{
1
}
else
{
0
};
obj
.palette
=
if
value
&
0x10
==
0x10
{
1
}
else
{
0
};
obj_data
.xflip
=
if
value
&
0x20
==
0x20
{
true
}
else
{
false
};
obj
.xflip
=
if
value
&
0x20
==
0x20
{
true
}
else
{
false
};
obj_data
.yflip
=
if
value
&
0x40
==
0x40
{
true
}
else
{
false
};
obj
.yflip
=
if
value
&
0x40
==
0x40
{
true
}
else
{
false
};
obj_data
.prio
=
if
value
&
0x80
==
0x80
{
1
}
else
{
0
};
obj
.prio
=
if
value
&
0x80
==
0x80
{
1
}
else
{
0
};
obj
.index
=
obj_index
as
u8
;
}
}
_
=>
(),
_
=>
(),
}
}
...
@@ -628,18 +639,20 @@ impl Ppu {
...
@@ -628,18 +639,20 @@ impl Ppu {
fn
render_objects
(
&
mut
self
)
{
fn
render_objects
(
&
mut
self
)
{
for
index
in
0
..
OBJ_COUNT
{
for
index
in
0
..
OBJ_COUNT
{
let
obj_data
=
self
.obj_data
[
index
];
// obtains the meta data of the object that is currently
// under iteration to be checked for drawing
let
obj
=
self
.obj_data
[
index
];
// verifies if the sprite is currently located at the
// verifies if the sprite is currently located at the
// current line that is going to be drawn and skips it
// current line that is going to be drawn and skips it
// in case it's not
// in case it's not
let
is_contained
=
(
obj_data
.y
<=
self
.ly
as
i16
)
let
is_contained
=
&&
((
obj
_data
.y
+
TILE_HEIGHT
as
i16
)
>
self
.ly
as
i16
);
(
obj
.y
<=
self
.ly
as
i16
)
&&
((
obj
.y
+
TILE_HEIGHT
as
i16
)
>
self
.ly
as
i16
);
if
!
is_contained
{
if
!
is_contained
{
continue
;
continue
;
}
}
let
palette
=
if
obj
_data
.palette
==
0
{
let
palette
=
if
obj
.palette
==
0
{
self
.palette_obj_0
self
.palette_obj_0
}
else
{
}
else
{
self
.palette_obj_1
self
.palette_obj_1
...
@@ -648,20 +661,20 @@ impl Ppu {
...
@@ -648,20 +661,20 @@ impl Ppu {
// calculates the offset in the frame buffer for the sprite
// calculates the offset in the frame buffer for the sprite
// that is going to be drawn, this is going to be the starting
// that is going to be drawn, this is going to be the starting
// point for the draw operation to be performed
// point for the draw operation to be performed
let
mut
frame_offset
=
(
self
.ly
as
usize
*
DISPLAY_WIDTH
+
obj
_data
.x
as
usize
)
*
RGB_SIZE
;
let
mut
frame_offset
=
(
self
.ly
as
usize
*
DISPLAY_WIDTH
+
obj
.x
as
usize
)
*
RGB_SIZE
;
let
tile_offset
=
self
.ly
as
i16
-
obj
_data
.y
;
let
tile_offset
=
self
.ly
as
i16
-
obj
.y
;
let
tile_row
:
&
[
u8
];
let
tile_row
:
&
[
u8
];
if
obj_data
.yflip
{
if
obj
.yflip
{
tile_row
=
tile_row
=
self
.tiles
[
obj
.tile
as
usize
]
.get_row
((
7
-
tile_offset
)
as
usize
);
self
.tiles
[
obj_data
.tile
as
usize
]
.get_row
((
7
-
tile_offset
)
as
usize
);
}
else
{
}
else
{
tile_row
=
self
.tiles
[
obj
_data
.tile
as
usize
]
.get_row
((
tile_offset
)
as
usize
);
tile_row
=
self
.tiles
[
obj
.tile
as
usize
]
.get_row
((
tile_offset
)
as
usize
);
}
}
for
x
in
0
..
TILE_WIDTH
{
for
x
in
0
..
TILE_WIDTH
{
let
is_contained
=
(
obj_data
.x
+
x
as
i16
>=
0
)
&&
((
obj_data
.x
+
x
as
i16
)
<
DISPLAY_WIDTH
as
i16
);
let
is_contained
=
(
obj
.x
+
x
as
i16
>=
0
)
&&
((
obj
.x
+
x
as
i16
)
<
DISPLAY_WIDTH
as
i16
);
if
!
is_contained
{
if
!
is_contained
{
continue
;
continue
;
}
}
...
@@ -678,6 +691,8 @@ impl Ppu {
...
@@ -678,6 +691,8 @@ impl Ppu {
self
.frame_buffer
[
frame_offset
+
1
]
=
color
[
1
];
self
.frame_buffer
[
frame_offset
+
1
]
=
color
[
1
];
self
.frame_buffer
[
frame_offset
+
2
]
=
color
[
2
];
self
.frame_buffer
[
frame_offset
+
2
]
=
color
[
2
];
// increments the offset of the frame buffer by the
// size of an RGB pixel (which is 3 bytes)
frame_offset
+=
RGB_SIZE
;
frame_offset
+=
RGB_SIZE
;
}
}
}
}
...
...
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