mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-24 03:11:29 +11:00
better make those examples build
This commit is contained in:
parent
a547eb07fc
commit
423a2f584b
|
@ -18,6 +18,6 @@
|
||||||
* [GBA Memory Mapping](ch03/gba_memory_mapping.md)
|
* [GBA Memory Mapping](ch03/gba_memory_mapping.md)
|
||||||
* [Tile Data](ch03/tile_data.md)
|
* [Tile Data](ch03/tile_data.md)
|
||||||
* [Regular Backgrounds](ch03/regular_backgrounds.md)
|
* [Regular Backgrounds](ch03/regular_backgrounds.md)
|
||||||
* [Object Basics](ch03/object_basics.md)
|
* [Regular Objects](ch03/regular_objects.md)
|
||||||
* [GBA RNG](ch03/gba_rng.md)
|
* [GBA RNG](ch03/gba_rng.md)
|
||||||
* [memory_game](ch03/memory_game.md)
|
* [memory_game](ch03/memory_game.md)
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Object Basics
|
|
||||||
TODO
|
|
|
@ -23,6 +23,9 @@ When you want regular tiled display, you must use video mode 0 or 1.
|
||||||
We will not cover affine backgrounds in this chapter, so we will naturally be
|
We will not cover affine backgrounds in this chapter, so we will naturally be
|
||||||
using video mode 0.
|
using video mode 0.
|
||||||
|
|
||||||
|
Also, note that you have to enable each background layer that you want to use
|
||||||
|
within the display control register.
|
||||||
|
|
||||||
## Get Your Palette Ready
|
## Get Your Palette Ready
|
||||||
|
|
||||||
Background palette starts at `0x5000000` and is 256 `u16` values long. It'd
|
Background palette starts at `0x5000000` and is 256 `u16` values long. It'd
|
||||||
|
@ -36,12 +39,12 @@ pub const PALRAM_BG_BASE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16)
|
||||||
|
|
||||||
pub fn bg_palette(slot: usize) -> u16 {
|
pub fn bg_palette(slot: usize) -> u16 {
|
||||||
assert!(slot < 256);
|
assert!(slot < 256);
|
||||||
PALRAM_BG_BASE.offset(slot as isize).read()
|
unsafe { PALRAM_BG_BASE.offset(slot as isize).read() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bg_palette(slot: usize, color: u16) {
|
pub fn set_bg_palette(slot: usize, color: u16) {
|
||||||
assert!(slot < 256);
|
assert!(slot < 256);
|
||||||
PALRAM_BG_BASE.offset(slot as isize).write(color)
|
unsafe { PALRAM_BG_BASE.offset(slot as isize).write(color) }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -77,28 +80,28 @@ pub fn bg_tile_4pp(base_block: usize, tile_index: usize) -> Tile4bpp {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 512);
|
assert!(tile_index < 512);
|
||||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile4bpp).read()
|
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_4pp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 512);
|
assert!(tile_index < 512);
|
||||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile4bpp).write(tile)
|
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bg_tile_8pp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
pub fn bg_tile_8pp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 256);
|
assert!(tile_index < 256);
|
||||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile8bpp).read()
|
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_8pp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 256);
|
assert!(tile_index < 256);
|
||||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile8bpp).write(tile)
|
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -218,9 +221,10 @@ As long as you stay within the background memory region for charblocks (that is,
|
||||||
rendering to reach outside of the background charblocks you'll get an
|
rendering to reach outside of the background charblocks you'll get an
|
||||||
implementation defined result. It's not the dreaded "undefined behavior" we're
|
implementation defined result. It's not the dreaded "undefined behavior" we're
|
||||||
often worried about in programming, but the results _are_ determined by what
|
often worried about in programming, but the results _are_ determined by what
|
||||||
you're running the game on. With real hardware, you get a bizarre result
|
you're running the game on. With GBA hardware you get a bizarre result
|
||||||
(basically another way to put garbage on the screen). If you use an emulator it
|
(basically another way to put garbage on the screen). With a DS it acts as if
|
||||||
might or might not allow for you to do this, it's up to the emulator writers.
|
the tiles were all 0s. If you use an emulator it might or might not allow for
|
||||||
|
you to do this, it's up to the emulator writers.
|
||||||
|
|
||||||
## Set Your IO Registers
|
## Set Your IO Registers
|
||||||
|
|
||||||
|
@ -287,9 +291,12 @@ it will loop.
|
||||||
|
|
||||||
As a special effect, you can apply mosaic to backgrounds and objects. It's just
|
As a special effect, you can apply mosaic to backgrounds and objects. It's just
|
||||||
a single flag for each background, so all backgrounds will use the same mosaic
|
a single flag for each background, so all backgrounds will use the same mosaic
|
||||||
settings when they have it enabled.
|
settings when they have it enabled. What it actually does is split the normal
|
||||||
|
image into "blocks" and then each block gets the color of the top left pixel of
|
||||||
|
that block. This is the effect you see when link hits an electric foe with his
|
||||||
|
sword and the whole screen "buzzes" at you.
|
||||||
|
|
||||||
The mosaic control is a read/write `u16` IO register at `0x400_004C`.
|
The mosaic control is a _write only_ `u16` IO register at `0x400_004C`.
|
||||||
|
|
||||||
There's 4 bits each for:
|
There's 4 bits each for:
|
||||||
|
|
||||||
|
@ -298,4 +305,11 @@ There's 4 bits each for:
|
||||||
* Horizontal object stretch
|
* Horizontal object stretch
|
||||||
* Vertical object stretch
|
* Vertical object stretch
|
||||||
|
|
||||||
The
|
The inputs should be 1 _less_ than the desired block size. So if you set a
|
||||||
|
stretch value of 5 then pixels 0-5 would be part of the first block (6 pixels),
|
||||||
|
then 6-11 is the next block (another 6 pixels) and so on.
|
||||||
|
|
||||||
|
If you need to make a pixel other than the top left part of each block the one
|
||||||
|
that determines the mosaic color you can carefully offset the background or
|
||||||
|
image by a tiny bit, but of course that makes every mosaic block change its
|
||||||
|
target pixel. You can't change the target pixel on a block by block basis.
|
||||||
|
|
15
book/src/ch03/regular_objects.md
Normal file
15
book/src/ch03/regular_objects.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Regular Objects
|
||||||
|
|
||||||
|
As with backgrounds, objects can be used in both an affine and non-affine way.
|
||||||
|
For this section we'll focus on the non-affine elements, and then we'll do all
|
||||||
|
the affine stuff in a later chapter.
|
||||||
|
|
||||||
|
TODO: tio afero ke mi diris
|
||||||
|
|
||||||
|
## Objects vs Sprites
|
||||||
|
|
||||||
|
## Ready the Palette
|
||||||
|
|
||||||
|
## Ready the Tiles
|
||||||
|
|
||||||
|
## Set the Object Attributes
|
|
@ -27,7 +27,9 @@ if you want to get them that way.
|
||||||
## Expected Knowledge
|
## Expected Knowledge
|
||||||
|
|
||||||
I will try not to ask too much of the reader ahead of time, but you are expected
|
I will try not to ask too much of the reader ahead of time, but you are expected
|
||||||
to have already read [The Rust Book](https://doc.rust-lang.org/book/).
|
to have already read [The Rust Book](https://doc.rust-lang.org/book/). Having
|
||||||
|
also read through the [Rustonomicon](https://doc.rust-lang.org/nomicon/) is
|
||||||
|
appreciated but not required.
|
||||||
|
|
||||||
It's very difficult to know when you've said something that someone else won't
|
It's very difficult to know when you've said something that someone else won't
|
||||||
already know about, or if you're presenting ideas out of order. If things aren't
|
already know about, or if you're presenting ideas out of order. If things aren't
|
||||||
|
@ -56,6 +58,3 @@ resources as well:
|
||||||
* [GBATEK](http://problemkaputt.de/gbatek.htm), a homebrew tech manual for
|
* [GBATEK](http://problemkaputt.de/gbatek.htm), a homebrew tech manual for
|
||||||
GBA/NDS/DSi. We will regularly link to parts of it when talking about various
|
GBA/NDS/DSi. We will regularly link to parts of it when talking about various
|
||||||
bits of the GBA.
|
bits of the GBA.
|
||||||
* [CowBite](https://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm) is another
|
|
||||||
tech specification that's more GBA specific. It's sometimes got more ASCII
|
|
||||||
art diagrams and example C struct layouts than GBATEK does.
|
|
||||||
|
|
|
@ -204,40 +204,40 @@ pub const PALRAM_BG_BASE: VolatilePtr<u16> = VolatilePtr(0x500_0000 as *mut u16)
|
||||||
|
|
||||||
pub fn bg_palette(slot: usize) -> u16 {
|
pub fn bg_palette(slot: usize) -> u16 {
|
||||||
assert!(slot < 256);
|
assert!(slot < 256);
|
||||||
PALRAM_BG_BASE.offset(slot as isize).read()
|
unsafe { PALRAM_BG_BASE.offset(slot as isize).read() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bg_palette(slot: usize, color: u16) {
|
pub fn set_bg_palette(slot: usize, color: u16) {
|
||||||
assert!(slot < 256);
|
assert!(slot < 256);
|
||||||
PALRAM_BG_BASE.offset(slot as isize).write(color)
|
unsafe { PALRAM_BG_BASE.offset(slot as isize).write(color) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bg_tile_4pp(base_block: usize, tile_index: usize) -> Tile4bpp {
|
pub fn bg_tile_4pp(base_block: usize, tile_index: usize) -> Tile4bpp {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 512);
|
assert!(tile_index < 512);
|
||||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile4bpp).read()
|
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_4pp(base_block: usize, tile_index: usize, tile: Tile4bpp) {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 512);
|
assert!(tile_index < 512);
|
||||||
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock4bpp>() * base_block + size_of::<Tile4bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile4bpp).write(tile)
|
unsafe { VolatilePtr(address as *mut Tile4bpp).write(tile) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bg_tile_8pp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
pub fn bg_tile_8pp(base_block: usize, tile_index: usize) -> Tile8bpp {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 256);
|
assert!(tile_index < 256);
|
||||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile8bpp).read()
|
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_8pp(base_block: usize, tile_index: usize, tile: Tile8bpp) {
|
||||||
assert!(base_block < 4);
|
assert!(base_block < 4);
|
||||||
assert!(tile_index < 256);
|
assert!(tile_index < 256);
|
||||||
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
let address = VRAM + size_of::<Charblock8bpp>() * base_block + size_of::<Tile8bpp>() * tile_index;
|
||||||
VolatilePtr(address as *mut Tile8bpp).write(tile)
|
unsafe { VolatilePtr(address as *mut Tile8bpp).write(tile) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|
Loading…
Reference in a new issue