mirror of
https://github.com/italicsjenga/gba.git
synced 2025-01-11 11:31:31 +11:00
checkers!
This commit is contained in:
parent
e9b62f1832
commit
9689394d75
|
@ -1,4 +1,4 @@
|
|||
# memory_game
|
||||
# Making A Memory Game
|
||||
|
||||
For this example to show off our new skills we'll make a "memory" game. The idea
|
||||
is that there's some face down cards and you pick one, it flips, you pick a
|
||||
|
@ -6,207 +6,310 @@ second, if they match they both go away, if they don't match they both turn back
|
|||
face down. The player keeps going until all the cards are gone, then we'll deal
|
||||
the cards again.
|
||||
|
||||
For this example, I started with the `light_cycle.rs` example and then just
|
||||
copied it into a new file, `memory_game.rs`. Then I added most all the code from
|
||||
the previous sections right into that file, so we'll assume that all those
|
||||
definitions are in scope.
|
||||
There are many steps to do to get such a simple seeming game going. In fact I
|
||||
stumbled a bit myself when trying to get things set up and going despite having
|
||||
written and explained all the parts so far. Accordingly, we'll take each part
|
||||
very slowly, and review things as we build up our game.
|
||||
|
||||
## Getting Some Images
|
||||
|
||||
First we need some images to show! Let's have one for our little selector thingy
|
||||
that we'll move around to pick cards with. How about some little triangles at
|
||||
the corner of a square like on a picture frame.
|
||||
We'll start back with a nearly blank file, calling it `memory_game.rs`:
|
||||
|
||||
```rust
|
||||
#[rustfmt::skip]
|
||||
pub const CARD_SELECTOR: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x44400444,
|
||||
0x44000044,
|
||||
0x40000004,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x40000004,
|
||||
0x44000044,
|
||||
0x44400444
|
||||
]
|
||||
};
|
||||
```
|
||||
#![feature(start)]
|
||||
#![no_std]
|
||||
|
||||
That weird looking attribute keeps rustfmt from spreading out the values, so
|
||||
that we can see it as an ASCII art. Now that we understand what an individual
|
||||
tile looks like, let's add some mono-color squares.
|
||||
|
||||
```rust
|
||||
#[rustfmt::skip]
|
||||
pub const FULL_ONE: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
]
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const FULL_TWO: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222
|
||||
]
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const FULL_THREE: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
We can control the rest with palbank selection. Since there's 16 palbanks,
|
||||
that's 48 little colored squares we can make, and 16 different selector colors,
|
||||
which should be plenty in both cases.
|
||||
|
||||
## Setup The Images
|
||||
|
||||
### Arrange the PALRAM
|
||||
|
||||
Alright, so, as we went over, the first step is to make sure that we've got our
|
||||
palette data in order. We'll be using this to set our palette values.
|
||||
|
||||
```rust
|
||||
pub fn set_bg_palette(slot: usize, color: u16) {
|
||||
assert!(slot < 256);
|
||||
unsafe { PALRAM_BG_BASE.offset(slot as isize).write(color) }
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
```
|
||||
|
||||
Should the type of `slot` be changed to `u8` instead of `usize`? Well, maybe.
|
||||
Let's not worry about it at the moment.
|
||||
|
||||
Of course, we don't need to set the color black, all the values start as black.
|
||||
We just need to set the other colors we'll be wanting. For this demo, we'll just
|
||||
use the same basic colors for both the BG and Object stuff.
|
||||
|
||||
```rust
|
||||
pub fn init_palette() {
|
||||
// palbank 0: black/white/gray
|
||||
set_bg_palette(2, rgb16(31, 31, 31));
|
||||
set_bg_palette(3, rgb16(15, 15, 15));
|
||||
// palbank 1 is reds
|
||||
set_bg_palette(1 * 16 + 1, rgb16(31, 0, 0));
|
||||
set_bg_palette(1 * 16 + 2, rgb16(22, 0, 0));
|
||||
set_bg_palette(1 * 16 + 3, rgb16(10, 0, 0));
|
||||
// palbank 2 is greens
|
||||
set_bg_palette(2 * 16 + 1, rgb16(0, 31, 0));
|
||||
set_bg_palette(2 * 16 + 2, rgb16(0, 22, 0));
|
||||
set_bg_palette(2 * 16 + 3, rgb16(0, 10, 0));
|
||||
// palbank 2 is blues
|
||||
set_bg_palette(3 * 16 + 1, rgb16(0, 0, 31));
|
||||
set_bg_palette(3 * 16 + 2, rgb16(0, 0, 22));
|
||||
set_bg_palette(3 * 16 + 3, rgb16(0, 0, 10));
|
||||
|
||||
// Direct copy all BG selections into OBJ palette too
|
||||
let mut bgp = PALRAM_BG_BASE;
|
||||
let mut objp = PALRAM_OBJECT_BASE;
|
||||
for _ in 0..(4 * 16) {
|
||||
objp.write(bgp.read());
|
||||
bgp = bgp.offset(1);
|
||||
objp = objp.offset(1);
|
||||
#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
loop {
|
||||
// TODO the whole thing
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Arrange the Objects
|
||||
## Displaying A Background
|
||||
|
||||
So, time to think about objects. I'm thinking we'll have 13 objects in use. One
|
||||
for the selector, and then 12 for the cards (a simple grid that's 4 wide and 3
|
||||
tall).
|
||||
First let's try to get a background going. We'll display a simple checker
|
||||
pattern just so that we know that we did something.
|
||||
|
||||
We want a way to easily clear away all the objects that we're not using, which
|
||||
is all the slots starting at some index and then going to the end.
|
||||
Remember, backgrounds have the following essential components:
|
||||
|
||||
* Background Palette
|
||||
* Background Tiles
|
||||
* Screenblock
|
||||
* IO Registers
|
||||
|
||||
### Background Palette
|
||||
|
||||
To write to the background palette memory we'll want to name a `VolatilePtr` for
|
||||
it. We'll probably also want to be able to cast between different types either
|
||||
right away or later in this program, so we'll add a method for that.
|
||||
|
||||
```rust
|
||||
pub fn clear_objects_starting_with(base_slot: usize) {
|
||||
let mut obj = ObjectAttributes::default();
|
||||
obj.set_rendering(ObjectRenderMode::Disabled);
|
||||
for s in base_slot..128 {
|
||||
set_object_attributes(s, obj);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct VolatilePtr<T>(pub *mut T);
|
||||
impl<T> VolatilePtr<T> {
|
||||
pub unsafe fn read(&self) -> T {
|
||||
core::ptr::read_volatile(self.0)
|
||||
}
|
||||
pub unsafe fn write(&self, data: T) {
|
||||
core::ptr::write_volatile(self.0, data);
|
||||
}
|
||||
pub fn offset(self, count: isize) -> Self {
|
||||
VolatilePtr(self.0.wrapping_offset(count))
|
||||
}
|
||||
pub fn cast<Z>(self) -> VolatilePtr<Z> {
|
||||
VolatilePtr(self.0 as *mut Z)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next we set out the positions of our cards. We set the tile data we need, and
|
||||
then assign the object attributes to go with it. For this, we'll make the
|
||||
position finder function be its own thing since we'll also need it for the card
|
||||
selector to move around. Finally, we set our selector as being at position 0,0
|
||||
of the card grid.
|
||||
Now we give ourselves an easy way to write a color into a palbank slot.
|
||||
|
||||
```rust
|
||||
pub fn position_of_card(card_col: usize, card_row: usize) -> (u16, u16) {
|
||||
(10 + card_col as u16 * 17, 5 + card_row as u16 * 15)
|
||||
pub const BACKGROUND_PALETTE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
|
||||
|
||||
pub fn set_bg_palette_4bpp(palbank: usize, slot: usize, color: u16) {
|
||||
assert!(palbank < 16);
|
||||
assert!(slot > 0 && slot < 16);
|
||||
unsafe {
|
||||
BACKGROUND_PALETTE
|
||||
.cast::<[u16; 16]>()
|
||||
.offset(palbank as isize)
|
||||
.cast::<u16>()
|
||||
.offset(slot as isize)
|
||||
.write(color);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And of course we need to bring back in our ability to build color values, as
|
||||
well as a few named colors to start us off:
|
||||
|
||||
```rust
|
||||
pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
|
||||
blue << 10 | green << 5 | red
|
||||
}
|
||||
|
||||
pub fn arrange_cards() {
|
||||
set_obj_tile_4bpp(1, FULL_ONE);
|
||||
set_obj_tile_4bpp(2, FULL_TWO);
|
||||
set_obj_tile_4bpp(3, FULL_THREE);
|
||||
let mut obj = ObjectAttributes::default();
|
||||
obj.set_tile_index(2); // along with palbank0, this is a white card
|
||||
for card_row in 0..3 {
|
||||
for card_col in 0..4 {
|
||||
let (col, row) = position_of_card(card_col, card_row);
|
||||
obj.set_column(col);
|
||||
obj.set_row(row);
|
||||
set_object_attributes(1 + card_col as usize + (card_row as usize * 3), obj);
|
||||
pub const WHITE: u16 = rgb16(31, 31, 31);
|
||||
pub const LIGHT_GRAY: u16 = rgb16(25, 25, 25);
|
||||
pub const DARK_GRAY: u16 = rgb16(15, 15, 15);
|
||||
```
|
||||
|
||||
Which _finally_ allows us to set our palette colors in `main`:
|
||||
|
||||
```rust
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
```
|
||||
|
||||
### Background Tiles
|
||||
|
||||
So we'll want some light gray tiles and some dark gray tiles. We could use a
|
||||
single tile and then swap it between palbanks to do the color selection, but for
|
||||
now we'll just use two different tiles, since we've got tons of tile space to
|
||||
spare.
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct Tile4bpp {
|
||||
pub data: [u32; 8],
|
||||
}
|
||||
|
||||
pub const ALL_TWOS: Tile4bpp = Tile4bpp {
|
||||
data: [
|
||||
0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222,
|
||||
],
|
||||
};
|
||||
|
||||
pub const ALL_THREES: Tile4bpp = Tile4bpp {
|
||||
data: [
|
||||
0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333,
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
And then we have to have a way to put the tiles into video memory:
|
||||
|
||||
```rust
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Charblock4bpp {
|
||||
pub data: [Tile4bpp; 512],
|
||||
}
|
||||
|
||||
pub const VRAM: VolatilePtr<Charblock4bpp> = VolatilePtr(0x0600_0000 as *mut Charblock4bpp);
|
||||
|
||||
pub fn set_bg_tile_4bpp(charblock: usize, index: usize, tile: Tile4bpp) {
|
||||
assert!(charblock < 4);
|
||||
assert!(index < 512);
|
||||
unsafe { VRAM.offset(charblock as isize).cast::<Tile4bpp>().offset(index as isize).write(tile) }
|
||||
}
|
||||
```
|
||||
|
||||
And finally, we can call that within `main`:
|
||||
|
||||
```rust
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
// bg palette
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
// bg tiles
|
||||
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
||||
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
||||
```
|
||||
|
||||
### Setup A Screenblock
|
||||
|
||||
Screenblocks are a little weird because they take the same space as the
|
||||
charblocks (8 screenblocks per charblock). The GBA will let you mix and match
|
||||
and it's up to you to keep it all straight. We're using tiles at the base of
|
||||
charblock 0, so we'll place our screenblock at the base of charblock 1.
|
||||
|
||||
First, we have to be able to make one single screenblock entry at a time:
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblockEntry(u16);
|
||||
|
||||
impl RegularScreenblockEntry {
|
||||
pub const SCREENBLOCK_ENTRY_TILE_ID_MASK: u16 = 0b11_1111_1111;
|
||||
pub fn from_tile_id(id: u16) -> Self {
|
||||
RegularScreenblockEntry(id & Self::SCREENBLOCK_ENTRY_TILE_ID_MASK)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And then with 32x32 of these things we'll have a whole screenblock. Now, we
|
||||
probably won't actually make values of the screenblock type itself, but we at
|
||||
least need it to have the type declared with the correct size so that we can
|
||||
move our pointers around by the right amount.
|
||||
|
||||
```rust
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblock {
|
||||
pub data: [RegularScreenblockEntry; 32 * 32],
|
||||
}
|
||||
```
|
||||
|
||||
Alright, so, as I said those things are kinda big, we don't really want to be
|
||||
building them up on the stack if we can avoid it, so we'll write one straight
|
||||
into memory at the correct location.
|
||||
|
||||
```rust
|
||||
pub fn checker_screenblock(slot: usize, a_entry: RegularScreenblockEntry, b_entry: RegularScreenblockEntry) {
|
||||
let mut p = VRAM.cast::<RegularScreenblock>().offset(slot as isize).cast::<RegularScreenblockEntry>();
|
||||
let mut checker = true;
|
||||
for _row in 0..32 {
|
||||
for _col in 0..32 {
|
||||
unsafe { p.write(if checker { a_entry } else { b_entry }) };
|
||||
p = p.offset(1);
|
||||
checker = !checker;
|
||||
}
|
||||
checker = !checker;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_selector() {
|
||||
set_obj_tile_4bpp(0, CARD_SELECTOR);
|
||||
let mut obj = ObjectAttributes::default();
|
||||
let (col, row) = position_of_card(0, 0);
|
||||
obj.set_column(col);
|
||||
obj.set_row(row);
|
||||
set_object_attributes(0, obj);
|
||||
}
|
||||
```
|
||||
|
||||
### Arrange the Background
|
||||
And then we add this into `main`
|
||||
|
||||
TODO
|
||||
```rust
|
||||
// screenblock
|
||||
let light_entry = RegularScreenblockEntry::from_tile_id(0);
|
||||
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
|
||||
checker_screenblock(8, light_entry, dark_entry);
|
||||
```
|
||||
|
||||
## Shuffling The Cards
|
||||
### Background IO Registers
|
||||
|
||||
TODO
|
||||
Our most important step is of course the IO register step. There's four
|
||||
different background layers, but each of them has the same format for their
|
||||
control register. For the moment, all that we care about is being able to set
|
||||
the "screen base block" value.
|
||||
|
||||
## Picking One Card
|
||||
```rust
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct BackgroundControlSetting(u16);
|
||||
|
||||
TODO
|
||||
impl BackgroundControlSetting {
|
||||
pub fn from_base_block(sbb: u16) -> Self {
|
||||
BackgroundControlSetting(sbb << 8)
|
||||
}
|
||||
}
|
||||
|
||||
## Picking The Second Card
|
||||
pub const BG0CNT: VolatilePtr<BackgroundControlSetting> = VolatilePtr(0x400_0008 as *mut BackgroundControlSetting);
|
||||
```
|
||||
|
||||
TODO
|
||||
And... that's all it takes for us to be able to add a line into `main`
|
||||
|
||||
## Resetting The Game
|
||||
```rust
|
||||
// bg0 control
|
||||
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
|
||||
```
|
||||
|
||||
TODO
|
||||
### Set The Display Control Register
|
||||
|
||||
We're finally ready to set the display control register and get things going.
|
||||
|
||||
We've slightly glossed over it so far, but when the GBA is first booted most
|
||||
everything within the address space will be all zeroed. However, the display
|
||||
control register has the "Force VBlank" bit enabled by the BIOS, giving you a
|
||||
moment to put the memory in place that you'll need for the first frame.
|
||||
|
||||
So, now that have got all of our memory set, we'll overwrite the initial
|
||||
display control register value with what we'll call "just enable bg0".
|
||||
|
||||
```rust
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct DisplayControlSetting(u16);
|
||||
|
||||
impl DisplayControlSetting {
|
||||
pub const JUST_ENABLE_BG0: DisplayControlSetting = DisplayControlSetting(1 << 8);
|
||||
}
|
||||
|
||||
pub const DISPCNT: VolatilePtr<DisplayControlSetting> = VolatilePtr(0x0400_0000 as *mut DisplayControlSetting);
|
||||
```
|
||||
|
||||
And so finally we have a complete `main`
|
||||
|
||||
```rust
|
||||
#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
// bg palette
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
// bg tiles
|
||||
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
||||
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
||||
// screenblock
|
||||
let light_entry = RegularScreenblockEntry::from_tile_id(0);
|
||||
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
|
||||
checker_screenblock(8, light_entry, dark_entry);
|
||||
// bg0 control
|
||||
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
|
||||
// Display Control
|
||||
unsafe { DISPCNT.write(DisplayControlSetting::JUST_ENABLE_BG0) };
|
||||
loop {
|
||||
// TODO the whole thing
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And _It works, Marty! It works!_
|
||||
|
||||
![screenshot_checkers](screenshot_checkers.png)
|
||||
|
||||
We've got more to go, but we're well on our way.
|
||||
|
|
|
@ -123,14 +123,14 @@ everything all lined up and into place anyway.
|
|||
The final step is to assign the correct attributes to an object. Each object has
|
||||
three `u16` values that make up its overall attributes.
|
||||
|
||||
Before we go into the details, I want to remind you that the hardware will
|
||||
attempt to process every single object every single frame, and also that all of
|
||||
the GBA's memory is cleared to 0 at startup. Why do these two things matter
|
||||
right now? As you'll see in a second an "all zero" set of object attributes
|
||||
causes an 8x8 object to appear at 0,0 using object tile index 0. This is usually
|
||||
_not_ what you want your unused objects to do. When your game first starts you
|
||||
should take a moment to mark any objects you won't be using as objects to not
|
||||
render.
|
||||
Before we go into the details, I want to bring up that the hardware will attempt
|
||||
to process every single object every single frame if the object layer is
|
||||
enabled, and also that all of the GBA's object memory is cleared to 0 at
|
||||
startup. Why do these two things matter right now? As you'll see in a second an
|
||||
"all zero" set of object attributes causes an 8x8 object to appear at 0,0 using
|
||||
object tile index 0. This is usually _not_ what you want your unused objects to
|
||||
do. When your game first starts you should take a moment to mark any objects you
|
||||
won't be using as objects to not render.
|
||||
|
||||
### ObjectAttributes.attr0
|
||||
|
||||
|
|
BIN
book/src/ch03/screenshot_checkers.png
Normal file
BIN
book/src/ch03/screenshot_checkers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html" class="active"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html" class="active"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html" class="active"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html" class="active"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html" class="active"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html" class="active"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html" class="active"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html" class="active"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html" class="active"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html" class="active"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html" class="active"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html" class="active"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html" class="active"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html" class="active"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html" class="active"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html" class="active"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html" class="active"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html" class="active"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html" class="active"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html" class="active"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html" class="active"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html" class="active"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html" class="active"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html" class="active"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html" class="active"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html" class="active"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
1232
docs/ch03/gba_prng.html
Normal file
1232
docs/ch03/gba_prng.html
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,201 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>GBA RNG - Rust GBA Guide</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<link rel="shortcut icon" href="../favicon.png">
|
||||
<link rel="stylesheet" href="../css/variables.css">
|
||||
<link rel="stylesheet" href="../css/general.css">
|
||||
<link rel="stylesheet" href="../css/chrome.css">
|
||||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="../highlight.css">
|
||||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
<body class="light">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">var path_to_root = "../";</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script type="text/javascript">
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = 'light'; }
|
||||
document.body.className = theme;
|
||||
document.querySelector('html').className = theme + ' js';
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script type="text/javascript">
|
||||
var html = document.querySelector('html');
|
||||
var sidebar = 'hidden';
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
}
|
||||
html.classList.remove('sidebar-visible');
|
||||
html.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html" class="active"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
|
||||
<div id="menu-bar" class="menu-bar">
|
||||
<div id="menu-bar-sticky-container">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Rust GBA Guide</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script type="text/javascript">
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<a class="header" href="#gba-rng" id="gba-rng"><h1>GBA RNG</h1></a>
|
||||
<p>TODO</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
<a rel="prev" href="../ch03/regular_objects.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<a rel="next" href="../ch03/memory_game.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
<a href="../ch03/regular_objects.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<a href="../ch03/memory_game.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
|
||||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html" class="active"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html" class="active"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html" class="active"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html" class="active"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
@ -136,15 +136,300 @@
|
|||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<a class="header" href="#memory_game" id="memory_game"><h1>memory_game</h1></a>
|
||||
<p>TODO</p>
|
||||
<a class="header" href="#making-a-memory-game" id="making-a-memory-game"><h1>Making A Memory Game</h1></a>
|
||||
<p>For this example to show off our new skills we'll make a "memory" game. The idea
|
||||
is that there's some face down cards and you pick one, it flips, you pick a
|
||||
second, if they match they both go away, if they don't match they both turn back
|
||||
face down. The player keeps going until all the cards are gone, then we'll deal
|
||||
the cards again.</p>
|
||||
<p>There are many steps to do to get such a simple seeming game going. In fact I
|
||||
stumbled a bit myself when trying to get things set up and going despite having
|
||||
written and explained all the parts so far. Accordingly, we'll take each part
|
||||
very slowly, and review things as we build up our game.</p>
|
||||
<p>We'll start back with a nearly blank file, calling it <code>memory_game.rs</code>:</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">#![feature(start)]
|
||||
#![no_std]
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
loop {
|
||||
// TODO the whole thing
|
||||
}
|
||||
}
|
||||
</code></pre></pre>
|
||||
<a class="header" href="#displaying-a-background" id="displaying-a-background"><h2>Displaying A Background</h2></a>
|
||||
<p>First let's try to get a background going. We'll display a simple checker
|
||||
pattern just so that we know that we did something.</p>
|
||||
<p>Remember, backgrounds have the following essential components:</p>
|
||||
<ul>
|
||||
<li>Background Palette</li>
|
||||
<li>Background Tiles</li>
|
||||
<li>Screenblock</li>
|
||||
<li>IO Registers</li>
|
||||
</ul>
|
||||
<a class="header" href="#background-palette" id="background-palette"><h3>Background Palette</h3></a>
|
||||
<p>To write to the background palette memory we'll want to name a <code>VolatilePtr</code> for
|
||||
it. We'll probably also want to be able to cast between different types either
|
||||
right away or later in this program, so we'll add a method for that.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct VolatilePtr<T>(pub *mut T);
|
||||
impl<T> VolatilePtr<T> {
|
||||
pub unsafe fn read(&self) -> T {
|
||||
core::ptr::read_volatile(self.0)
|
||||
}
|
||||
pub unsafe fn write(&self, data: T) {
|
||||
core::ptr::write_volatile(self.0, data);
|
||||
}
|
||||
pub fn offset(self, count: isize) -> Self {
|
||||
VolatilePtr(self.0.wrapping_offset(count))
|
||||
}
|
||||
pub fn cast<Z>(self) -> VolatilePtr<Z> {
|
||||
VolatilePtr(self.0 as *mut Z)
|
||||
}
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>Now we give ourselves an easy way to write a color into a palbank slot.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
pub const BACKGROUND_PALETTE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
|
||||
|
||||
pub fn set_bg_palette_4bpp(palbank: usize, slot: usize, color: u16) {
|
||||
assert!(palbank < 16);
|
||||
assert!(slot > 0 && slot < 16);
|
||||
unsafe {
|
||||
BACKGROUND_PALETTE
|
||||
.cast::<[u16; 16]>()
|
||||
.offset(palbank as isize)
|
||||
.cast::<u16>()
|
||||
.offset(slot as isize)
|
||||
.write(color);
|
||||
}
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>And of course we need to bring back in our ability to build color values, as
|
||||
well as a few named colors to start us off:</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
|
||||
blue << 10 | green << 5 | red
|
||||
}
|
||||
|
||||
pub const WHITE: u16 = rgb16(31, 31, 31);
|
||||
pub const LIGHT_GRAY: u16 = rgb16(25, 25, 25);
|
||||
pub const DARK_GRAY: u16 = rgb16(15, 15, 15);
|
||||
#}</code></pre></pre>
|
||||
<p>Which <em>finally</em> allows us to set our palette colors in <code>main</code>:</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
</code></pre></pre>
|
||||
<a class="header" href="#background-tiles" id="background-tiles"><h3>Background Tiles</h3></a>
|
||||
<p>So we'll want some light gray tiles and some dark gray tiles. We could use a
|
||||
single tile and then swap it between palbanks to do the color selection, but for
|
||||
now we'll just use two different tiles, since we've got tons of tile space to
|
||||
spare.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct Tile4bpp {
|
||||
pub data: [u32; 8],
|
||||
}
|
||||
|
||||
pub const ALL_TWOS: Tile4bpp = Tile4bpp {
|
||||
data: [
|
||||
0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222,
|
||||
],
|
||||
};
|
||||
|
||||
pub const ALL_THREES: Tile4bpp = Tile4bpp {
|
||||
data: [
|
||||
0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333,
|
||||
],
|
||||
};
|
||||
#}</code></pre></pre>
|
||||
<p>And then we have to have a way to put the tiles into video memory:</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Charblock4bpp {
|
||||
pub data: [Tile4bpp; 512],
|
||||
}
|
||||
|
||||
pub const VRAM: VolatilePtr<Charblock4bpp> = VolatilePtr(0x0600_0000 as *mut Charblock4bpp);
|
||||
|
||||
pub fn set_bg_tile_4bpp(charblock: usize, index: usize, tile: Tile4bpp) {
|
||||
assert!(charblock < 4);
|
||||
assert!(index < 512);
|
||||
unsafe { VRAM.offset(charblock as isize).cast::<Tile4bpp>().offset(index as isize).write(tile) }
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>And finally, we can call that within <code>main</code>:</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
// bg palette
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
// bg tiles
|
||||
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
||||
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
||||
</code></pre></pre>
|
||||
<a class="header" href="#setup-a-screenblock" id="setup-a-screenblock"><h3>Setup A Screenblock</h3></a>
|
||||
<p>Screenblocks are a little weird because they take the same space as the
|
||||
charblocks (8 screenblocks per charblock). The GBA will let you mix and match
|
||||
and it's up to you to keep it all straight. We're using tiles at the base of
|
||||
charblock 0, so we'll place our screenblock at the base of charblock 1.</p>
|
||||
<p>First, we have to be able to make one single screenblock entry at a time:</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblockEntry(u16);
|
||||
|
||||
impl RegularScreenblockEntry {
|
||||
pub const SCREENBLOCK_ENTRY_TILE_ID_MASK: u16 = 0b11_1111_1111;
|
||||
pub fn from_tile_id(id: u16) -> Self {
|
||||
RegularScreenblockEntry(id & Self::SCREENBLOCK_ENTRY_TILE_ID_MASK)
|
||||
}
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>And then with 32x32 of these things we'll have a whole screenblock. Now, we
|
||||
probably won't actually make values of the screenblock type itself, but we at
|
||||
least need it to have the type declared with the correct size so that we can
|
||||
move our pointers around by the right amount.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblock {
|
||||
pub data: [RegularScreenblockEntry; 32 * 32],
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>Alright, so, as I said those things are kinda big, we don't really want to be
|
||||
building them up on the stack if we can avoid it, so we'll write one straight
|
||||
into memory at the correct location.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
pub fn checker_screenblock(slot: usize, a_entry: RegularScreenblockEntry, b_entry: RegularScreenblockEntry) {
|
||||
let mut p = VRAM.cast::<RegularScreenblock>().offset(slot as isize).cast::<RegularScreenblockEntry>();
|
||||
let mut checker = true;
|
||||
for _row in 0..32 {
|
||||
for _col in 0..32 {
|
||||
unsafe { p.write(if checker { a_entry } else { b_entry }) };
|
||||
p = p.offset(1);
|
||||
checker = !checker;
|
||||
}
|
||||
checker = !checker;
|
||||
}
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>And then we add this into <code>main</code></p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
// screenblock
|
||||
let light_entry = RegularScreenblockEntry::from_tile_id(0);
|
||||
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
|
||||
checker_screenblock(8, light_entry, dark_entry);
|
||||
#}</code></pre></pre>
|
||||
<a class="header" href="#background-io-registers" id="background-io-registers"><h3>Background IO Registers</h3></a>
|
||||
<p>Our most important step is of course the IO register step. There's four
|
||||
different background layers, but each of them has the same format for their
|
||||
control register. For the moment, all that we care about is being able to set
|
||||
the "screen base block" value.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct BackgroundControlSetting(u16);
|
||||
|
||||
impl BackgroundControlSetting {
|
||||
pub fn from_base_block(sbb: u16) -> Self {
|
||||
BackgroundControlSetting(sbb << 8)
|
||||
}
|
||||
}
|
||||
|
||||
pub const BG0CNT: VolatilePtr<BackgroundControlSetting> = VolatilePtr(0x400_0008 as *mut BackgroundControlSetting);
|
||||
#}</code></pre></pre>
|
||||
<p>And... that's all it takes for us to be able to add a line into <code>main</code></p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
// bg0 control
|
||||
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
|
||||
#}</code></pre></pre>
|
||||
<a class="header" href="#set-the-display-control-register" id="set-the-display-control-register"><h3>Set The Display Control Register</h3></a>
|
||||
<p>We're finally ready to set the display control register and get things going.</p>
|
||||
<p>We've slightly glossed over it so far, but when the GBA is first booted most
|
||||
everything within the address space will be all zeroed. However, the display
|
||||
control register has the "Force VBlank" bit enabled by the BIOS, giving you a
|
||||
moment to put the memory in place that you'll need for the first frame.</p>
|
||||
<p>So, now that have got all of our memory set, we'll overwrite the initial
|
||||
display control register value with what we'll call "just enable bg0".</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct DisplayControlSetting(u16);
|
||||
|
||||
impl DisplayControlSetting {
|
||||
pub const JUST_ENABLE_BG0: DisplayControlSetting = DisplayControlSetting(1 << 8);
|
||||
}
|
||||
|
||||
pub const DISPCNT: VolatilePtr<DisplayControlSetting> = VolatilePtr(0x0400_0000 as *mut DisplayControlSetting);
|
||||
#}</code></pre></pre>
|
||||
<p>And so finally we have a complete <code>main</code></p>
|
||||
<pre><pre class="playpen"><code class="language-rust">#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
// bg palette
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
// bg tiles
|
||||
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
||||
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
||||
// screenblock
|
||||
let light_entry = RegularScreenblockEntry::from_tile_id(0);
|
||||
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
|
||||
checker_screenblock(8, light_entry, dark_entry);
|
||||
// bg0 control
|
||||
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
|
||||
// Display Control
|
||||
unsafe { DISPCNT.write(DisplayControlSetting::JUST_ENABLE_BG0) };
|
||||
loop {
|
||||
// TODO the whole thing
|
||||
}
|
||||
}
|
||||
</code></pre></pre>
|
||||
<p>And <em>It works, Marty! It works!</em></p>
|
||||
<p><img src="screenshot_checkers.png" alt="screenshot_checkers" /></p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
<a rel="prev" href="../ch03/gba_rng.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="../ch03/gba_prng.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
@ -158,7 +443,7 @@
|
|||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
<a href="../ch03/gba_rng.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a href="../ch03/gba_prng.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html" class="active"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html" class="active"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
@ -204,28 +204,28 @@ the size of that type of tile. Like this:</p>
|
|||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
pub fn bg_tile_4pp(base_block: usize, tile_index: usize) -> Tile4bpp {
|
||||
pub fn bg_tile_4bpp(base_block: usize, tile_index: usize) -> Tile4bpp {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_bg_tile_4pp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
|
||||
pub fn set_bg_tile_4bpp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
|
||||
}
|
||||
|
||||
pub fn bg_tile_8pp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
||||
pub fn bg_tile_8bpp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 256);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_bg_tile_8pp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
|
||||
pub fn set_bg_tile_8bpp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 256);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||
|
@ -277,7 +277,7 @@ appropriately.</p>
|
|||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblock {
|
||||
data: [RegularScreenblockEntry; 32 * 32],
|
||||
pub data: [RegularScreenblockEntry; 32 * 32],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
|
@ -330,7 +330,7 @@ impl RegularScreenblockEntry {
|
|||
}
|
||||
pub fn set_palbank_index(&mut self, palbank_index: u16) {
|
||||
self.0 &= 0b1111_1111_1111;
|
||||
self.0 |= palbank_index;
|
||||
self.0 |= palbank_index << 12;
|
||||
}
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html" class="active"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html" class="active"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
@ -193,6 +193,33 @@ or 8bpp. From this we can determine that there's 512 tile slots in each of the
|
|||
two object charblocks. However, in video modes 3, 4, and 5 the space for the
|
||||
background cuts into the lower charblock, so you can only safely use the upper
|
||||
charblock.</p>
|
||||
<pre><pre class="playpen"><code class="language-rust">
|
||||
# #![allow(unused_variables)]
|
||||
#fn main() {
|
||||
pub fn obj_tile_4bpp(tile_index: usize) -> Tile4bpp {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_obj_tile_4bpp(tile_index: usize, tile: Tile4bpp) {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
|
||||
}
|
||||
|
||||
pub fn obj_tile_8bpp(tile_index: usize) -> Tile8bpp {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_obj_tile_8bpp(tile_index: usize, tile: Tile8bpp) {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>With backgrounds you picked every single tile individually with a bunch of
|
||||
screen entry values. Objects don't do that at all. Instead you pick a base tile,
|
||||
size, and shape, then it figures out the rest from there. However, you may
|
||||
|
@ -217,14 +244,14 @@ everything all lined up and into place anyway.</p>
|
|||
<a class="header" href="#set-the-object-attributes" id="set-the-object-attributes"><h2>Set the Object Attributes</h2></a>
|
||||
<p>The final step is to assign the correct attributes to an object. Each object has
|
||||
three <code>u16</code> values that make up its overall attributes.</p>
|
||||
<p>Before we go into the details, I want to remind you that the hardware will
|
||||
attempt to process every single object every single frame, and also that all of
|
||||
the GBA's memory is cleared to 0 at startup. Why do these two things matter
|
||||
right now? As you'll see in a second an "all zero" set of object attributes
|
||||
causes an 8x8 object to appear at 0,0 using object tile index 0. This is usually
|
||||
<em>not</em> what you want your unused objects to do. When your game first starts you
|
||||
should take a moment to mark any objects you won't be using as objects to not
|
||||
render.</p>
|
||||
<p>Before we go into the details, I want to bring up that the hardware will attempt
|
||||
to process every single object every single frame if the object layer is
|
||||
enabled, and also that all of the GBA's object memory is cleared to 0 at
|
||||
startup. Why do these two things matter right now? As you'll see in a second an
|
||||
"all zero" set of object attributes causes an 8x8 object to appear at 0,0 using
|
||||
object tile index 0. This is usually <em>not</em> what you want your unused objects to
|
||||
do. When your game first starts you should take a moment to mark any objects you
|
||||
won't be using as objects to not render.</p>
|
||||
<a class="header" href="#objectattributesattr0" id="objectattributesattr0"><h3>ObjectAttributes.attr0</h3></a>
|
||||
<ul>
|
||||
<li>8 bits for row coordinate (marks the top of the sprite)</li>
|
||||
|
@ -518,7 +545,7 @@ impl ObjectAttributes {
|
|||
|
||||
|
||||
|
||||
<a rel="next" href="../ch03/gba_rng.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next" href="../ch03/gba_prng.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
@ -536,7 +563,7 @@ impl ObjectAttributes {
|
|||
|
||||
|
||||
|
||||
<a href="../ch03/gba_rng.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a href="../ch03/gba_prng.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
|
|
BIN
docs/ch03/screenshot_checkers.png
Normal file
BIN
docs/ch03/screenshot_checkers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html" class="active"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="../introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="../ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="../ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="../ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="../ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="../ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="../ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="../ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="../ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="../ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="../ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="../ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="../ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="../ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="../ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="../ch03/tile_data.html" class="active"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="../ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="../ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="../ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="../ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
@ -161,13 +161,13 @@ and the index just directly picks which of the 256 colors is used.</li>
|
|||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct Tile4bpp {
|
||||
data: [u32; 8]
|
||||
pub data: [u32; 8]
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct Tile8bpp {
|
||||
data: [u32; 16]
|
||||
pub data: [u32; 16]
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>I hope this makes sense so far. At 4bpp, we have 4 bits per pixel, times 8
|
||||
|
@ -196,13 +196,13 @@ tiles, and with 8bpp there's 256 tiles. So they'd be something like this:</p>
|
|||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Charblock4bpp {
|
||||
data: [Tile4bpp; 512],
|
||||
pub data: [Tile4bpp; 512],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Charblock8bpp {
|
||||
data: [Tile8bpp; 256],
|
||||
pub data: [Tile8bpp; 256],
|
||||
}
|
||||
#}</code></pre></pre>
|
||||
<p>You'll note that we can't even derive <code>Debug</code> or <code>Default</code> any more because the
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
@ -183,6 +183,10 @@ for C, but it's what I based the ordering of this book's sections on.</li>
|
|||
<li><a href="http://problemkaputt.de/gbatek.htm">GBATEK</a>, a homebrew tech manual for
|
||||
GBA/NDS/DSi. We will regularly link to parts of it when talking about various
|
||||
bits of the GBA.</li>
|
||||
<li><a href="https://www.youtube.com/watch?v=t99L3JHhLc0">Getting Something for Nothing</a>
|
||||
by James Munns. RustConf 2018. It specifically talks about zero cost
|
||||
abstraction within an embedded rust context, which is exactly what we're all
|
||||
about.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<ol class="chapter"><li><a href="introduction.html" class="active"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_rng.html"><strong aria-hidden="true">5.5.</strong> GBA RNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
<ol class="chapter"><li><a href="introduction.html" class="active"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="ch00/index.html"><strong aria-hidden="true">2.</strong> Ch 0: Development Setup</a></li><li><a href="ch01/index.html"><strong aria-hidden="true">3.</strong> Ch 1: Hello GBA</a></li><li><ol class="section"><li><a href="ch01/hello1.html"><strong aria-hidden="true">3.1.</strong> hello1</a></li><li><a href="ch01/volatile.html"><strong aria-hidden="true">3.2.</strong> Volatile</a></li><li><a href="ch01/io_registers.html"><strong aria-hidden="true">3.3.</strong> IO Registers</a></li><li><a href="ch01/the_display_control_register.html"><strong aria-hidden="true">3.4.</strong> The Display Control Register</a></li><li><a href="ch01/video_memory_intro.html"><strong aria-hidden="true">3.5.</strong> Video Memory Intro</a></li><li><a href="ch01/hello2.html"><strong aria-hidden="true">3.6.</strong> hello2</a></li></ol></li><li><a href="ch02/index.html"><strong aria-hidden="true">4.</strong> Ch 2: User Input</a></li><li><ol class="section"><li><a href="ch02/the_key_input_register.html"><strong aria-hidden="true">4.1.</strong> The Key Input Register</a></li><li><a href="ch02/the_vcount_register.html"><strong aria-hidden="true">4.2.</strong> The VCount Register</a></li><li><a href="ch02/light_cycle.html"><strong aria-hidden="true">4.3.</strong> light_cycle</a></li></ol></li><li><a href="ch03/index.html"><strong aria-hidden="true">5.</strong> Ch 3: Memory and Objects</a></li><li><ol class="section"><li><a href="ch03/gba_memory_mapping.html"><strong aria-hidden="true">5.1.</strong> GBA Memory Mapping</a></li><li><a href="ch03/tile_data.html"><strong aria-hidden="true">5.2.</strong> Tile Data</a></li><li><a href="ch03/regular_backgrounds.html"><strong aria-hidden="true">5.3.</strong> Regular Backgrounds</a></li><li><a href="ch03/regular_objects.html"><strong aria-hidden="true">5.4.</strong> Regular Objects</a></li><li><a href="ch03/gba_prng.html"><strong aria-hidden="true">5.5.</strong> GBA PRNG</a></li><li><a href="ch03/memory_game.html"><strong aria-hidden="true">5.6.</strong> memory_game</a></li></ol></li></ol>
|
||||
</nav>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
@ -183,6 +183,10 @@ for C, but it's what I based the ordering of this book's sections on.</li>
|
|||
<li><a href="http://problemkaputt.de/gbatek.htm">GBATEK</a>, a homebrew tech manual for
|
||||
GBA/NDS/DSi. We will regularly link to parts of it when talking about various
|
||||
bits of the GBA.</li>
|
||||
<li><a href="https://www.youtube.com/watch?v=t99L3JHhLc0">Getting Something for Nothing</a>
|
||||
by James Munns. RustConf 2018. It specifically talks about zero cost
|
||||
abstraction within an embedded rust context, which is exactly what we're all
|
||||
about.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
|
1393
docs/print.html
1393
docs/print.html
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,9 +1,6 @@
|
|||
#![feature(start)]
|
||||
#![feature(asm)]
|
||||
#![no_std]
|
||||
|
||||
use core::mem::size_of;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
|
@ -11,19 +8,27 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
|
|||
|
||||
#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
unsafe {
|
||||
init_palette();
|
||||
init_background();
|
||||
clear_objects_starting_with(13);
|
||||
arrange_cards();
|
||||
init_selector();
|
||||
loop {
|
||||
// TODO the game
|
||||
}
|
||||
// bg palette
|
||||
set_bg_palette_4bpp(0, 1, WHITE);
|
||||
set_bg_palette_4bpp(0, 2, LIGHT_GRAY);
|
||||
set_bg_palette_4bpp(0, 3, DARK_GRAY);
|
||||
// bg tiles
|
||||
set_bg_tile_4bpp(0, 0, ALL_TWOS);
|
||||
set_bg_tile_4bpp(0, 1, ALL_THREES);
|
||||
// screenblock
|
||||
let light_entry = RegularScreenblockEntry::from_tile_id(0);
|
||||
let dark_entry = RegularScreenblockEntry::from_tile_id(1);
|
||||
checker_screenblock(8, light_entry, dark_entry);
|
||||
// bg0 control
|
||||
unsafe { BG0CNT.write(BackgroundControlSetting::from_base_block(8)) };
|
||||
// Display Control
|
||||
unsafe { DISPCNT.write(DisplayControlSetting::JUST_ENABLE_BG0) };
|
||||
loop {
|
||||
// TODO the whole thing
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct VolatilePtr<T>(pub *mut T);
|
||||
impl<T> VolatilePtr<T> {
|
||||
|
@ -33,129 +38,54 @@ impl<T> VolatilePtr<T> {
|
|||
pub unsafe fn write(&self, data: T) {
|
||||
core::ptr::write_volatile(self.0, data);
|
||||
}
|
||||
pub unsafe fn offset(self, count: isize) -> Self {
|
||||
pub fn offset(self, count: isize) -> Self {
|
||||
VolatilePtr(self.0.wrapping_offset(count))
|
||||
}
|
||||
pub fn cast<Z>(self) -> VolatilePtr<Z> {
|
||||
VolatilePtr(self.0 as *mut Z)
|
||||
}
|
||||
}
|
||||
|
||||
pub const DISPCNT: VolatilePtr<u16> = VolatilePtr(0x04000000 as *mut u16);
|
||||
pub const MODE3: u16 = 3;
|
||||
pub const BG2: u16 = 0b100_0000_0000;
|
||||
pub const BACKGROUND_PALETTE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
|
||||
|
||||
pub const VRAM: usize = 0x600_0000;
|
||||
pub const SCREEN_WIDTH: isize = 240;
|
||||
pub const SCREEN_HEIGHT: isize = 160;
|
||||
pub fn set_bg_palette_4bpp(palbank: usize, slot: usize, color: u16) {
|
||||
assert!(palbank < 16);
|
||||
assert!(slot > 0 && slot < 16);
|
||||
unsafe {
|
||||
BACKGROUND_PALETTE
|
||||
.cast::<[u16; 16]>()
|
||||
.offset(palbank as isize)
|
||||
.cast::<u16>()
|
||||
.offset(slot as isize)
|
||||
.write(color);
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
|
||||
blue << 10 | green << 5 | red
|
||||
}
|
||||
|
||||
pub unsafe fn mode3_clear_screen(color: u16) {
|
||||
let color = color as u32;
|
||||
let bulk_color = color << 16 | color;
|
||||
let mut ptr = VolatilePtr(VRAM as *mut u32);
|
||||
for _ in 0..SCREEN_HEIGHT {
|
||||
for _ in 0..(SCREEN_WIDTH / 2) {
|
||||
ptr.write(bulk_color);
|
||||
ptr = ptr.offset(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub const WHITE: u16 = rgb16(31, 31, 31);
|
||||
pub const LIGHT_GRAY: u16 = rgb16(25, 25, 25);
|
||||
pub const DARK_GRAY: u16 = rgb16(15, 15, 15);
|
||||
|
||||
pub unsafe fn mode3_draw_pixel(col: isize, row: isize, color: u16) {
|
||||
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).write(color);
|
||||
}
|
||||
|
||||
pub unsafe fn mode3_read_pixel(col: isize, row: isize) -> u16 {
|
||||
VolatilePtr(VRAM as *mut u16).offset(col + row * SCREEN_WIDTH).read()
|
||||
}
|
||||
|
||||
pub const KEYINPUT: VolatilePtr<u16> = VolatilePtr(0x400_0130 as *mut u16);
|
||||
|
||||
/// A newtype over the key input state of the GBA.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct KeyInputSetting(u16);
|
||||
|
||||
/// A "tribool" value helps us interpret the arrow pad.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(i32)]
|
||||
pub enum TriBool {
|
||||
Minus = -1,
|
||||
Neutral = 0,
|
||||
Plus = 1,
|
||||
}
|
||||
|
||||
pub fn key_input() -> KeyInputSetting {
|
||||
unsafe { KeyInputSetting(KEYINPUT.read() ^ 0b0000_0011_1111_1111) }
|
||||
}
|
||||
|
||||
pub const KEY_A: u16 = 1 << 0;
|
||||
pub const KEY_B: u16 = 1 << 1;
|
||||
pub const KEY_SELECT: u16 = 1 << 2;
|
||||
pub const KEY_START: u16 = 1 << 3;
|
||||
pub const KEY_RIGHT: u16 = 1 << 4;
|
||||
pub const KEY_LEFT: u16 = 1 << 5;
|
||||
pub const KEY_UP: u16 = 1 << 6;
|
||||
pub const KEY_DOWN: u16 = 1 << 7;
|
||||
pub const KEY_R: u16 = 1 << 8;
|
||||
pub const KEY_L: u16 = 1 << 9;
|
||||
|
||||
impl KeyInputSetting {
|
||||
pub fn contains(&self, key: u16) -> bool {
|
||||
(self.0 & key) != 0
|
||||
}
|
||||
|
||||
pub fn difference(&self, other: KeyInputSetting) -> KeyInputSetting {
|
||||
KeyInputSetting(self.0 ^ other.0)
|
||||
}
|
||||
|
||||
pub fn column_direction(&self) -> TriBool {
|
||||
if self.contains(KEY_RIGHT) {
|
||||
TriBool::Plus
|
||||
} else if self.contains(KEY_LEFT) {
|
||||
TriBool::Minus
|
||||
} else {
|
||||
TriBool::Neutral
|
||||
}
|
||||
}
|
||||
|
||||
pub fn row_direction(&self) -> TriBool {
|
||||
if self.contains(KEY_DOWN) {
|
||||
TriBool::Plus
|
||||
} else if self.contains(KEY_UP) {
|
||||
TriBool::Minus
|
||||
} else {
|
||||
TriBool::Neutral
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const VCOUNT: VolatilePtr<u16> = VolatilePtr(0x0400_0006 as *mut u16);
|
||||
|
||||
pub fn vcount() -> u16 {
|
||||
unsafe { VCOUNT.read() }
|
||||
}
|
||||
|
||||
pub fn wait_until_vblank() {
|
||||
while vcount() < SCREEN_HEIGHT as u16 {}
|
||||
}
|
||||
|
||||
pub fn wait_until_vdraw() {
|
||||
while vcount() >= SCREEN_HEIGHT as u16 {}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct Tile4bpp {
|
||||
pub data: [u32; 8],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct Tile8bpp {
|
||||
pub data: [u32; 16],
|
||||
}
|
||||
pub const ALL_TWOS: Tile4bpp = Tile4bpp {
|
||||
data: [
|
||||
0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222, 0x22222222,
|
||||
],
|
||||
};
|
||||
|
||||
pub const ALL_THREES: Tile4bpp = Tile4bpp {
|
||||
data: [
|
||||
0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333, 0x33333333,
|
||||
],
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
|
@ -163,630 +93,62 @@ pub struct Charblock4bpp {
|
|||
pub data: [Tile4bpp; 512],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub const VRAM: VolatilePtr<Charblock4bpp> = VolatilePtr(0x0600_0000 as *mut Charblock4bpp);
|
||||
|
||||
pub fn set_bg_tile_4bpp(charblock: usize, index: usize, tile: Tile4bpp) {
|
||||
assert!(charblock < 4);
|
||||
assert!(index < 512);
|
||||
unsafe { VRAM.offset(charblock as isize).cast::<Tile4bpp>().offset(index as isize).write(tile) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct Charblock8bpp {
|
||||
pub data: [Tile8bpp; 256],
|
||||
}
|
||||
pub struct RegularScreenblockEntry(u16);
|
||||
|
||||
pub const PALRAM_BG_BASE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16);
|
||||
|
||||
pub fn bg_palette(slot: usize) -> u16 {
|
||||
assert!(slot < 256);
|
||||
unsafe { PALRAM_BG_BASE.offset(slot as isize).read() }
|
||||
}
|
||||
|
||||
pub fn set_bg_palette(slot: usize, color: u16) {
|
||||
assert!(slot < 256);
|
||||
unsafe { PALRAM_BG_BASE.offset(slot as isize).write(color) }
|
||||
}
|
||||
|
||||
pub unsafe fn init_palette() {
|
||||
// palbank 0: black/white/gray
|
||||
set_bg_palette(2, rgb16(31, 31, 31));
|
||||
set_bg_palette(3, rgb16(15, 15, 15));
|
||||
// palbank 1 is reds
|
||||
set_bg_palette(1 * 16 + 1, rgb16(31, 0, 0));
|
||||
set_bg_palette(1 * 16 + 2, rgb16(22, 0, 0));
|
||||
set_bg_palette(1 * 16 + 3, rgb16(10, 0, 0));
|
||||
// palbank 2 is greens
|
||||
set_bg_palette(2 * 16 + 1, rgb16(0, 31, 0));
|
||||
set_bg_palette(2 * 16 + 2, rgb16(0, 22, 0));
|
||||
set_bg_palette(2 * 16 + 3, rgb16(0, 10, 0));
|
||||
// palbank 2 is blues
|
||||
set_bg_palette(3 * 16 + 1, rgb16(0, 0, 31));
|
||||
set_bg_palette(3 * 16 + 2, rgb16(0, 0, 22));
|
||||
set_bg_palette(3 * 16 + 3, rgb16(0, 0, 10));
|
||||
|
||||
// Direct copy all BG selections into OBJ palette too
|
||||
let mut bgp = PALRAM_BG_BASE;
|
||||
let mut objp = PALRAM_OBJECT_BASE;
|
||||
for _ in 0..(4 * 16) {
|
||||
objp.write(bgp.read());
|
||||
bgp = bgp.offset(1);
|
||||
objp = objp.offset(1);
|
||||
impl RegularScreenblockEntry {
|
||||
pub const SCREENBLOCK_ENTRY_TILE_ID_MASK: u16 = 0b11_1111_1111;
|
||||
pub fn from_tile_id(id: u16) -> Self {
|
||||
RegularScreenblockEntry(id & Self::SCREENBLOCK_ENTRY_TILE_ID_MASK)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bg_tile_4bpp(base_block: usize, tile_index: usize) -> Tile4bpp {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_bg_tile_4bpp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
|
||||
}
|
||||
|
||||
pub fn bg_tile_8bpp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 256);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_bg_tile_8bpp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
|
||||
assert!(base_block < 4);
|
||||
assert!(tile_index < 256);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
pub fn obj_tile_4bpp(tile_index: usize) -> Tile4bpp {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_obj_tile_4bpp(tile_index: usize, tile: Tile4bpp) {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock4bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
|
||||
}
|
||||
|
||||
pub fn obj_tile_8bpp(tile_index: usize) -> Tile8bpp {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).read() }
|
||||
}
|
||||
|
||||
pub fn set_obj_tile_8bpp(tile_index: usize, tile: Tile8bpp) {
|
||||
assert!(tile_index < 512);
|
||||
let address = VRAM + size_of::<Charblock8bpp>() * 4 + 32 * tile_index;
|
||||
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblock {
|
||||
data: [RegularScreenblockEntry; 32 * 32],
|
||||
pub data: [RegularScreenblockEntry; 32 * 32],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub fn checker_screenblock(slot: usize, a_entry: RegularScreenblockEntry, b_entry: RegularScreenblockEntry) {
|
||||
let mut p = VRAM.cast::<RegularScreenblock>().offset(slot as isize).cast::<RegularScreenblockEntry>();
|
||||
let mut checker = true;
|
||||
for _row in 0..32 {
|
||||
for _col in 0..32 {
|
||||
unsafe { p.write(if checker { a_entry } else { b_entry }) };
|
||||
p = p.offset(1);
|
||||
checker = !checker;
|
||||
}
|
||||
checker = !checker;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct RegularScreenblockEntry(u16);
|
||||
pub struct BackgroundControlSetting(u16);
|
||||
|
||||
impl RegularScreenblockEntry {
|
||||
pub fn tile_id(self) -> u16 {
|
||||
self.0 & 0b11_1111_1111
|
||||
}
|
||||
pub fn set_tile_id(&mut self, id: u16) {
|
||||
self.0 &= !0b11_1111_1111;
|
||||
self.0 |= id;
|
||||
}
|
||||
pub fn horizontal_flip(self) -> bool {
|
||||
(self.0 & (1 << 0xA)) > 0
|
||||
}
|
||||
pub fn set_horizontal_flip(&mut self, bit: bool) {
|
||||
if bit {
|
||||
self.0 |= 1 << 0xA;
|
||||
} else {
|
||||
self.0 &= !(1 << 0xA);
|
||||
}
|
||||
}
|
||||
pub fn vertical_flip(self) -> bool {
|
||||
(self.0 & (1 << 0xB)) > 0
|
||||
}
|
||||
pub fn set_vertical_flip(&mut self, bit: bool) {
|
||||
if bit {
|
||||
self.0 |= 1 << 0xB;
|
||||
} else {
|
||||
self.0 &= !(1 << 0xB);
|
||||
}
|
||||
}
|
||||
pub fn palbank_index(self) -> u16 {
|
||||
self.0 >> 12
|
||||
}
|
||||
pub fn set_palbank_index(&mut self, palbank_index: u16) {
|
||||
self.0 &= 0b1111_1111_1111;
|
||||
self.0 |= palbank_index << 12;
|
||||
impl BackgroundControlSetting {
|
||||
pub fn from_base_block(sbb: u16) -> Self {
|
||||
BackgroundControlSetting(sbb << 8)
|
||||
}
|
||||
}
|
||||
|
||||
pub const PALRAM_OBJECT_BASE: VolatilePtr<u16> = VolatilePtr(0x500_0200 as *mut u16);
|
||||
pub const BG0CNT: VolatilePtr<BackgroundControlSetting> = VolatilePtr(0x400_0008 as *mut BackgroundControlSetting);
|
||||
|
||||
pub fn object_palette(slot: usize) -> u16 {
|
||||
assert!(slot < 256);
|
||||
unsafe { PALRAM_OBJECT_BASE.offset(slot as isize).read() }
|
||||
}
|
||||
|
||||
pub fn set_object_palette(slot: usize, color: u16) {
|
||||
assert!(slot < 256);
|
||||
unsafe { PALRAM_OBJECT_BASE.offset(slot as isize).write(color) }
|
||||
}
|
||||
|
||||
pub const OAM: usize = 0x700_0000;
|
||||
|
||||
pub fn object_attributes(slot: usize) -> ObjectAttributes {
|
||||
assert!(slot < 128);
|
||||
let ptr = VolatilePtr((OAM + slot * (size_of::<u16>() * 4)) as *mut u16);
|
||||
unsafe {
|
||||
ObjectAttributes {
|
||||
attr0: ptr.read(),
|
||||
attr1: ptr.offset(1).read(),
|
||||
attr2: ptr.offset(2).read(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_object_attributes(slot: usize, obj: ObjectAttributes) {
|
||||
assert!(slot < 128);
|
||||
let ptr = VolatilePtr((OAM + slot * (size_of::<u16>() * 4)) as *mut u16);
|
||||
unsafe {
|
||||
ptr.write(obj.attr0);
|
||||
ptr.offset(1).write(obj.attr1);
|
||||
ptr.offset(2).write(obj.attr2);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_objects_starting_with(base_slot: usize) {
|
||||
let mut obj = ObjectAttributes::default();
|
||||
obj.set_rendering(ObjectRenderMode::Disabled);
|
||||
for s in base_slot..128 {
|
||||
set_object_attributes(s, obj);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn position_of_card(card_col: usize, card_row: usize) -> (u16, u16) {
|
||||
(10 + card_col as u16 * 17, 5 + card_row as u16 * 15)
|
||||
}
|
||||
|
||||
pub fn arrange_cards() {
|
||||
set_obj_tile_4bpp(1, FULL_ONE);
|
||||
set_obj_tile_4bpp(2, FULL_TWO);
|
||||
set_obj_tile_4bpp(3, FULL_THREE);
|
||||
let mut obj = ObjectAttributes::default();
|
||||
obj.set_tile_index(2); // along with palbank0, this is a white card
|
||||
for card_row in 0..3 {
|
||||
for card_col in 0..4 {
|
||||
let (col, row) = position_of_card(card_col, card_row);
|
||||
obj.set_column(col);
|
||||
obj.set_row(row);
|
||||
set_object_attributes(1 + card_col as usize + (card_row as usize * 3), obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_selector() {
|
||||
set_obj_tile_4bpp(0, CARD_SELECTOR);
|
||||
let mut obj = ObjectAttributes::default();
|
||||
let (col, row) = position_of_card(0, 0);
|
||||
obj.set_column(col);
|
||||
obj.set_row(row);
|
||||
set_object_attributes(0, obj);
|
||||
}
|
||||
|
||||
/// BG2 Control
|
||||
pub const BG2CNT: VolatilePtr<u16> = VolatilePtr(0x400_000C as *mut u16);
|
||||
|
||||
pub unsafe fn init_background() {
|
||||
// put the bg tiles in charblock 0
|
||||
set_bg_tile_4bpp(0, 0, FULL_ONE);
|
||||
set_bg_tile_4bpp(0, 1, FULL_THREE);
|
||||
// make a checker pattern, place at screenblock 8 (aka the start of charblock 1)
|
||||
let entry_black = RegularScreenblockEntry::default();
|
||||
let mut entry_gray = RegularScreenblockEntry::default();
|
||||
entry_gray.set_tile_id(1);
|
||||
let mut using_black = true;
|
||||
let mut screenblock: RegularScreenblock = core::mem::zeroed();
|
||||
for entry_mut in screenblock.data.iter_mut() {
|
||||
*entry_mut = if using_black { entry_black } else { entry_gray };
|
||||
using_black = !using_black;
|
||||
}
|
||||
let p: VolatilePtr<RegularScreenblock> = VolatilePtr((VRAM + size_of::<Charblock8bpp>()) as *mut RegularScreenblock);
|
||||
p.write(screenblock);
|
||||
// turn on bg2 and configure it
|
||||
let display_control_value = DISPCNT.read();
|
||||
DISPCNT.write(display_control_value | BG2);
|
||||
const SCREEN_BASE_BLOCK_FIRST_BIT: u32 = 8;
|
||||
BG2CNT.write(8 << SCREEN_BASE_BLOCK_FIRST_BIT);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub struct ObjectAttributes {
|
||||
attr0: u16,
|
||||
attr1: u16,
|
||||
attr2: u16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ObjectRenderMode {
|
||||
Normal,
|
||||
Affine,
|
||||
Disabled,
|
||||
DoubleAreaAffine,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ObjectMode {
|
||||
Normal,
|
||||
AlphaBlending,
|
||||
ObjectWindow,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ObjectShape {
|
||||
Square,
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ObjectOrientation {
|
||||
Normal,
|
||||
HFlip,
|
||||
VFlip,
|
||||
BothFlip,
|
||||
Affine(u8),
|
||||
}
|
||||
|
||||
impl ObjectAttributes {
|
||||
pub fn row(&self) -> u16 {
|
||||
self.attr0 & 0b1111_1111
|
||||
}
|
||||
pub fn column(&self) -> u16 {
|
||||
self.attr1 & 0b1_1111_1111
|
||||
}
|
||||
pub fn rendering(&self) -> ObjectRenderMode {
|
||||
match (self.attr0 >> 8) & 0b11 {
|
||||
0 => ObjectRenderMode::Normal,
|
||||
1 => ObjectRenderMode::Affine,
|
||||
2 => ObjectRenderMode::Disabled,
|
||||
3 => ObjectRenderMode::DoubleAreaAffine,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
pub fn mode(&self) -> ObjectMode {
|
||||
match (self.attr0 >> 0xA) & 0b11 {
|
||||
0 => ObjectMode::Normal,
|
||||
1 => ObjectMode::AlphaBlending,
|
||||
2 => ObjectMode::ObjectWindow,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
pub fn mosaic(&self) -> bool {
|
||||
((self.attr0 << 3) as i16) < 0
|
||||
}
|
||||
pub fn two_fifty_six_colors(&self) -> bool {
|
||||
((self.attr0 << 2) as i16) < 0
|
||||
}
|
||||
pub fn shape(&self) -> ObjectShape {
|
||||
match (self.attr0 >> 0xE) & 0b11 {
|
||||
0 => ObjectShape::Square,
|
||||
1 => ObjectShape::Horizontal,
|
||||
2 => ObjectShape::Vertical,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
pub fn orientation(&self) -> ObjectOrientation {
|
||||
if (self.attr0 >> 8) & 1 > 0 {
|
||||
ObjectOrientation::Affine((self.attr1 >> 9) as u8 & 0b1_1111)
|
||||
} else {
|
||||
match (self.attr1 >> 0xC) & 0b11 {
|
||||
0 => ObjectOrientation::Normal,
|
||||
1 => ObjectOrientation::HFlip,
|
||||
2 => ObjectOrientation::VFlip,
|
||||
3 => ObjectOrientation::BothFlip,
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn size(&self) -> u16 {
|
||||
self.attr1 >> 0xE
|
||||
}
|
||||
pub fn tile_index(&self) -> u16 {
|
||||
self.attr2 & 0b11_1111_1111
|
||||
}
|
||||
pub fn priority(&self) -> u16 {
|
||||
self.attr2 >> 0xA
|
||||
}
|
||||
pub fn palbank(&self) -> u16 {
|
||||
self.attr2 >> 0xC
|
||||
}
|
||||
//
|
||||
pub fn set_row(&mut self, row: u16) {
|
||||
self.attr0 &= !0b1111_1111;
|
||||
self.attr0 |= row & 0b1111_1111;
|
||||
}
|
||||
pub fn set_column(&mut self, col: u16) {
|
||||
self.attr1 &= !0b1_1111_1111;
|
||||
self.attr2 |= col & 0b1_1111_1111;
|
||||
}
|
||||
pub fn set_rendering(&mut self, rendering: ObjectRenderMode) {
|
||||
const RENDERING_MASK: u16 = 0b11 << 8;
|
||||
self.attr0 &= !RENDERING_MASK;
|
||||
self.attr0 |= (rendering as u16) << 8;
|
||||
}
|
||||
pub fn set_mode(&mut self, mode: ObjectMode) {
|
||||
const MODE_MASK: u16 = 0b11 << 0xA;
|
||||
self.attr0 &= MODE_MASK;
|
||||
self.attr0 |= (mode as u16) << 0xA;
|
||||
}
|
||||
pub fn set_mosaic(&mut self, bit: bool) {
|
||||
const MOSAIC_BIT: u16 = 1 << 0xC;
|
||||
if bit {
|
||||
self.attr0 |= MOSAIC_BIT
|
||||
} else {
|
||||
self.attr0 &= !MOSAIC_BIT
|
||||
}
|
||||
}
|
||||
pub fn set_two_fifty_six_colors(&mut self, bit: bool) {
|
||||
const COLOR_MODE_BIT: u16 = 1 << 0xD;
|
||||
if bit {
|
||||
self.attr0 |= COLOR_MODE_BIT
|
||||
} else {
|
||||
self.attr0 &= !COLOR_MODE_BIT
|
||||
}
|
||||
}
|
||||
pub fn set_shape(&mut self, shape: ObjectShape) {
|
||||
self.attr0 &= 0b0011_1111_1111_1111;
|
||||
self.attr0 |= (shape as u16) << 0xE;
|
||||
}
|
||||
pub fn set_orientation(&mut self, orientation: ObjectOrientation) {
|
||||
const AFFINE_INDEX_MASK: u16 = 0b1_1111 << 9;
|
||||
self.attr1 &= !AFFINE_INDEX_MASK;
|
||||
let bits = match orientation {
|
||||
ObjectOrientation::Affine(index) => (index as u16) << 9,
|
||||
ObjectOrientation::Normal => 0,
|
||||
ObjectOrientation::HFlip => 1 << 0xC,
|
||||
ObjectOrientation::VFlip => 1 << 0xD,
|
||||
ObjectOrientation::BothFlip => 0b11 << 0xC,
|
||||
};
|
||||
self.attr1 |= bits;
|
||||
}
|
||||
pub fn set_size(&mut self, size: u16) {
|
||||
self.attr1 &= 0b0011_1111_1111_1111;
|
||||
self.attr1 |= size << 14;
|
||||
}
|
||||
pub fn set_tile_index(&mut self, index: u16) {
|
||||
self.attr2 &= !0b11_1111_1111;
|
||||
self.attr2 |= 0b11_1111_1111 & index;
|
||||
}
|
||||
pub fn set_priority(&mut self, priority: u16) {
|
||||
self.attr2 &= !0b0000_1100_0000_0000;
|
||||
self.attr2 |= (priority & 0b11) << 0xA;
|
||||
}
|
||||
pub fn set_palbank(&mut self, palbank: u16) {
|
||||
self.attr2 &= !0b1111_0000_0000_0000;
|
||||
self.attr2 |= (palbank & 0b1111) << 0xC;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn div_modulus(numerator: i32, denominator: i32) -> (i32, i32) {
|
||||
assert!(denominator != 0);
|
||||
{
|
||||
let div_out: i32;
|
||||
let mod_out: i32;
|
||||
unsafe {
|
||||
asm!(/* assembly template */ "swi 0x06"
|
||||
:/* output operands */ "={r0}"(div_out), "={r1}"(mod_out)
|
||||
:/* input operands */ "{r0}"(numerator), "{r1}"(denominator)
|
||||
:/* clobbers */ "r3"
|
||||
:/* options */
|
||||
);
|
||||
}
|
||||
(div_out, mod_out)
|
||||
}
|
||||
}
|
||||
pub fn div(numerator: i32, denominator: i32) -> i32 {
|
||||
div_modulus(numerator, denominator).0
|
||||
}
|
||||
|
||||
pub fn modulus(numerator: i32, denominator: i32) -> i32 {
|
||||
div_modulus(numerator, denominator).1
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct RandRangeU16 {
|
||||
range: u16,
|
||||
threshold: u16,
|
||||
}
|
||||
|
||||
impl RandRangeU16 {
|
||||
pub fn new(mut range: u16) -> Self {
|
||||
let mut threshold = range.wrapping_neg();
|
||||
if threshold >= range {
|
||||
threshold -= range;
|
||||
if threshold >= range {
|
||||
threshold = modulus(threshold as i32, range as i32) as u16;
|
||||
}
|
||||
}
|
||||
RandRangeU16 { range, threshold }
|
||||
}
|
||||
|
||||
pub fn roll_random(&self, rng: &mut impl FnMut() -> u16) -> u16 {
|
||||
let mut x: u16 = rng();
|
||||
let mut m: u32 = x as u32 * self.range as u32;
|
||||
let mut l: u16 = m as u16;
|
||||
if l < self.range {
|
||||
while l < self.threshold {
|
||||
x = rng();
|
||||
m = x as u32 * self.range as u32;
|
||||
l = m as u16;
|
||||
}
|
||||
}
|
||||
(m >> 16) as u16
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bounded_rand32(rng: &mut impl FnMut() -> u32, mut range: u32) -> u32 {
|
||||
let mut mask: u32 = !0;
|
||||
range -= 1;
|
||||
mask >>= (range | 1).leading_zeros();
|
||||
let mut x = rng() & mask;
|
||||
while x > range {
|
||||
x = rng() & mask;
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
pub const TM0D: VolatilePtr<u16> = VolatilePtr(0x400_0100 as *mut u16);
|
||||
pub const TM0CNT: VolatilePtr<u16> = VolatilePtr(0x400_0102 as *mut u16);
|
||||
|
||||
pub const TM1D: VolatilePtr<u16> = VolatilePtr(0x400_0104 as *mut u16);
|
||||
pub const TM1CNT: VolatilePtr<u16> = VolatilePtr(0x400_0106 as *mut u16);
|
||||
|
||||
pub const TM2D: VolatilePtr<u16> = VolatilePtr(0x400_0108 as *mut u16);
|
||||
pub const TM2CNT: VolatilePtr<u16> = VolatilePtr(0x400_010A as *mut u16);
|
||||
|
||||
pub const TM3D: VolatilePtr<u16> = VolatilePtr(0x400_010C as *mut u16);
|
||||
pub const TM3CNT: VolatilePtr<u16> = VolatilePtr(0x400_010E as *mut u16);
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct TimerControl(u16);
|
||||
pub struct DisplayControlSetting(u16);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum TimerFrequency {
|
||||
One = 0,
|
||||
SixFour = 1,
|
||||
TwoFiveSix = 2,
|
||||
OneZeroTwoFour = 3,
|
||||
impl DisplayControlSetting {
|
||||
pub const JUST_ENABLE_BG0: DisplayControlSetting = DisplayControlSetting(1 << 8);
|
||||
}
|
||||
|
||||
impl TimerControl {
|
||||
pub fn frequency(self) -> TimerFrequency {
|
||||
match self.0 & 0b11 {
|
||||
0 => TimerFrequency::One,
|
||||
1 => TimerFrequency::SixFour,
|
||||
2 => TimerFrequency::TwoFiveSix,
|
||||
3 => TimerFrequency::OneZeroTwoFour,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
pub fn cascading(self) -> bool {
|
||||
self.0 & 0b100 > 0
|
||||
}
|
||||
pub fn interrupt(self) -> bool {
|
||||
self.0 & 0b100_0000 > 0
|
||||
}
|
||||
pub fn enabled(self) -> bool {
|
||||
self.0 & 0b1000_0000 > 0
|
||||
}
|
||||
//
|
||||
pub fn set_frequency(&mut self, frequency: TimerFrequency) {
|
||||
self.0 &= !0b11;
|
||||
self.0 |= frequency as u16;
|
||||
}
|
||||
pub fn set_cascading(&mut self, bit: bool) {
|
||||
if bit {
|
||||
self.0 |= 0b100;
|
||||
} else {
|
||||
self.0 &= !0b100;
|
||||
}
|
||||
}
|
||||
pub fn set_interrupt(&mut self, bit: bool) {
|
||||
if bit {
|
||||
self.0 |= 0b100_0000;
|
||||
} else {
|
||||
self.0 &= !0b100_0000;
|
||||
}
|
||||
}
|
||||
pub fn set_enabled(&mut self, bit: bool) {
|
||||
if bit {
|
||||
self.0 |= 0b1000_0000;
|
||||
} else {
|
||||
self.0 &= !0b1000_0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Mucks with the settings of Timers 0 and 1.
|
||||
unsafe fn u32_from_user_wait() -> u32 {
|
||||
let mut t = TimerControl::default();
|
||||
t.set_enabled(true);
|
||||
t.set_cascading(true);
|
||||
TM1CNT.write(t.0);
|
||||
t.set_cascading(false);
|
||||
TM0CNT.write(t.0);
|
||||
while key_input().0 == 0 {}
|
||||
t.set_enabled(false);
|
||||
TM0CNT.write(t.0);
|
||||
TM1CNT.write(t.0);
|
||||
let low = TM0D.read() as u32;
|
||||
let high = TM1D.read() as u32;
|
||||
(high << 32) | low
|
||||
}
|
||||
|
||||
/// For the user's "cursor" to select a card
|
||||
#[rustfmt::skip]
|
||||
pub const CARD_SELECTOR: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x11100111,
|
||||
0x11000011,
|
||||
0x10000001,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x10000001,
|
||||
0x11000011,
|
||||
0x11100111
|
||||
]
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const FULL_ONE: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
0x11111111,
|
||||
]
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const FULL_TWO: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222,
|
||||
0x22222222
|
||||
]
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const FULL_THREE: Tile4bpp = Tile4bpp {
|
||||
data : [
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333,
|
||||
0x33333333
|
||||
]
|
||||
};
|
||||
pub const DISPCNT: VolatilePtr<DisplayControlSetting> = VolatilePtr(0x0400_0000 as *mut DisplayControlSetting);
|
||||
|
|
Loading…
Reference in a new issue