Full Metal
C(++) Developer.
- 810
- Posts
- 17
- Years
- In my mind.
- Seen Aug 19, 2018
Warning to you wise-cracks
In no way, am i saying this is 100% accurate; I'm human, and make mistakes. You've been warned, so no flaming, just point somethin out then SHUT UP. Anyways on to the juicy stuff (i decided to start making things look professionalerer the first time so...its a bit more organized than my other threads)
Simple stuff
Terminology
Bit: The absolute smallest storage unit of data, can only be 1 (set) or 0 (unset)
Byte: 8 bits; maximum value of 0xFF (255)
Short: 2 bytes (16 bits); maximum value of 0xFFFF (65,535)
Integer: 4 bytes (32 bits); maximum value of 0xFFFFFF (4,294,967,295)
Color: err..go back to kindergarten, what are you doing here?
Palette: usually 16 or 256 colors
GBA: OK SRSLY WTF R U DOIN HERE?! (jk XD)
The gba has a screen size of 240x160 pixels.
This has the capability of having 30x20 tiles on the screen at a time.
The gba is a 16-bit color system. Meaning all the colors you have available on a computer, are not available on the GBA.
Colors
How colors are stored in the GBA vram
As previously stated, GBA colors are 16 bits a piece. Believe it or not, 1 bit is actually wasted :O.
heres how a gba color looks
[wasted bit][5 bits: Red value][5 bits: Green Value][5 bits: Blue value]
since each of the RGB values are only 5 bits long, there is a maximum of 31 value possibilities to each. You will get the closest match to the actual color, by simply multiplying those values by 8. If you are a programmer, here's how to store colors in GBA format.
#define gba(r,g,b) ( r | g<<5 | b << 10 )
If you aren't, that is simple enough, you should be able to figure it out (again, bitwise logic is needed) << means to shift left X times. Reversing that is as simple as bitshifting to the right the respective amount of times and a little bit of AND'ing to remove the other bits from the remaining colors.
The BG Palette Memory Starts at 0x5000000 and the Sprite Palette Memory starts at: 0x5000200
Un-Compressed Graphics
The Easy Stuff...
The GBA has IO2 (that i know of) different storages of graphics. Compressed, or Uncompressed. Uncompressed graphics are easier to understand. If you are in 4BPP mode, the least amount of pixels you can have is 2.
[4 bits: pixel 2 index][4 bits: pixel 1 index]
What I mean by "index" is which color value on the palette will be used. Usually, 4BPP will be used with tilemaps, but there are other cases (like sprites)
please note that 4 bits restrains you to a value of 15, which is oddly convenient...
8BPP graphics are stored similarly
[8 bits (1 byte): pixel index]
This will allow you access to all 256 colors of either the BG palette, or the Sprite Palette.
GBA Video Modes
How the gba processes the graphics
The gba has different "modes" for graphics display. How the GBA knows which mode to use, is that it reads from the address 0x4000000. That is where the screen mode, and which bg's are enabled is stored. To set the appropriate mode you need to know some bitwise logic (google it if you don't already know it)
the hex values for the different bgs being enabled are:
BG0: 0x100
BG1: 0x200
BG2: 0x400
BG3: 0x800
If sprites are also enabled, you can treat them as a BG as well. They're enabled code is 0x1000
---<bg X enabled code> do that for each bg you are enabling.
OR <Mode, simply the mode number in hex>
Mode 0
--Is tiled
--All 4 "layers" are accessible
--The tilemap can be either 16 or 256 colors
--Rotation and scaling (GBA "specialty functions" only accessible through asm...) are not supported
Mode 1
--Only 3 of the four layers are available
--the third layer (which is actually layer two, because layer 0 is the first layer, i know, it's confusing)
--Always 256 colors
--A maximum of 256 tiles.
Mode 2
--Only applicable to layers 2 & 3
--supports "specialty functions"
--Only 256 colors
--Maximum of 256 tiles
Mode 3
--First "un-tiled" mode
--entire screen (layers don't "exist in this mode; there isn't enough room for more than one...)
--No palette index (uses 2 bytes per pixel)
Mode 4
--"un-tiled" (afaik, not entirely for sure though)
--only layer 2 (the third layer) is available
--supports animation (able to load up to a whole two frames at a time!--WOW xD)
--256 colors (this is an indexed mode)
Mode 5
--Really rare situations are able to use this (as in you probably will never use it)
--Only 160x128 of the gba's pixels are useable
--Layer 2 only
--All colors
--Allows for animation (AKA double buffering, which is why it has two frames, and not the entire screen)
Putting it all together
Some assembly required
To display a 240x160 256 colors image, heres what you need to do.
Store the palette in the ROM
Store the image in the ROM (using tilemoster or etc, so that it's uncompressed)
write a routine, and set the video mode to one appropriate for you (i reccomend mode 4) then add a that will enter a (i usually use C++, so try to bear with me on my terms like "loop") loop, writing the palette to the BG memory. Add another (separate) loop that will copy the bytes from your image offset into the appropriate BG memory (I challenge you to find that with nothing more than VBA, hint hint: check the "map viewer" ;) )
add another (separate) loop. Next write a script that will fade the screen to black/other color, and call your routine (smart asm hackers obviously can call the routine through other methods, but i'm not exactly a "smart" asm hacker...still learning basics...) and voila! u see a nice pretty picture :D
...don't ask me how to return to normal play. Perhaps you could add a "waitforkeypress" to your script, then fade to black (yes, again) then fade from black to normal play. Or maybe you could loop in your routine (after displaying loading palette and pixels) and when a button is pushed the script would continue, which you could just fade into normal play from there. I dont' know branching and whatnot yet, so I can't post an example routine right nao...maybe i still wont' to help inspire others who dont know how either...
Tiles and their maps
Not alot to say...
Well, theres not a lot to these, especially since we have NTME and Cyclone, and PTC (lol, theres' so many...)
simple.
A tile: 8x8 block of pixels
Tilemap: a series of shorts describing which tile goes where on the GBA screen
I'm not going to touch on how to load tilemaps, its' a bit much for me to type out at 11:23 pm...
Tile Insertion
almost a little rant
Ok, so you have this nice set of tiles you'd like to insert right?
But holy shiz! ITS FRIGGIN HUGE!
Have no fear, this tutorial is here!
What I see a lot of is people getting the mis-understanding that tiles you insert have to be as you see them in the map; this is a lie. First let me explain to you what a "block" and a "map" are.
Block: a 2x2 set of tiles, with two layers.
Map: a bunch of tiles, with movement permissions, and events.
Tileset: a bunch of blocks.
So rather than have a 16x16 tile pasted into your tileset, and wasting space (assuming they're identical) you can break it down into perfect 8x8 tiles ;)
How to do this?
well, you could just jump into sphere and convert it...but that could turn out disastrous.
First you need to gather all the tiles you want to insert, that share the same palette.
Open up paint, and paste all the tiles you want in there.
Fill the BG (your going to be indexing this, so be sure not to miss anything) with a transparent color (you want it to be completely unique, so using the paint default colors is perfectly exceptional. Ensure that the bottom-left pixel is the transparent color, and save as a un-indexed bitmap file.
Open up the saved file in irfanview, and index it into 16 colors. Save again (still bitmap format)
download and, maybe, install the GTK+ runtime, the tool "Full Metal Paletted" from here
once that's done, run the program. Click on the 4BPP bitmap option, and load the file from previous steps.
Then click on the save a-map palette button, and save the advance map palette. Open a-map, load your rom, go to a map with the right tileset and load block editor.
Choose the palette to replace, and load it from file (choose the file we saved in with palette editor).
Now comes the tile insertion part.
Open up each individual tile, and make sure it aligns with a pixel spot that, if added by one, is divisible by 8 (if the first pixel on the left is 0) and also make sure the same is true vertically. Save your image. Open up sphere, import->image to map and open the image we previously saved. Set the block size to 8x8 and click yes when it asks to remove duplicate tiles grab the tileset saved with sphere and save it. Open that up in paint, and copy it. Then go back to a-map, and save your tileset (with the palette you want to use). Open up your tileset with pain, paste your clipboard wherever it fits, and load the tileset again with amap. This is important, if you clicked "Write Palette Changes to ROM" then you'll have to load your palette again (from file) and then load your tileset, i'll explain why later. If you didn't click "Write Palette Changes to ROM" then you are good to go, load the tileset, and NOW click "write palette changes to ROM" and may begin block editing ;) read some other tile insertion tutorial to learn how to do that...
So why can't you click "write palette changes to ROM"?
Every tileset image is stored with a .pal file right next to it. The .pal file has all the colors used in your palette, which is how A-map knows which pixel to put where, without using indexed bitmaps. If you have a pixel on your bitmap, that is not in your .pal file, then your tileset, when loaded, will not load the colors right, unless by some unlikely chance, all the colors are divisible by 8 and less than 248. So...why can't we click that button? Because when you do, a-map looses the original colors, and converts them to colors that are GBA compatible (divisible by 8 and less than 248) so when you save the tileset, the colors in the .pal file will NOT match the colors of the content in your clipboard.
In no way, am i saying this is 100% accurate; I'm human, and make mistakes. You've been warned, so no flaming, just point somethin out then SHUT UP. Anyways on to the juicy stuff (i decided to start making things look professionalerer the first time so...its a bit more organized than my other threads)
Simple stuff
Terminology
Bit: The absolute smallest storage unit of data, can only be 1 (set) or 0 (unset)
Byte: 8 bits; maximum value of 0xFF (255)
Short: 2 bytes (16 bits); maximum value of 0xFFFF (65,535)
Integer: 4 bytes (32 bits); maximum value of 0xFFFFFF (4,294,967,295)
Color: err..go back to kindergarten, what are you doing here?
Palette: usually 16 or 256 colors
GBA: OK SRSLY WTF R U DOIN HERE?! (jk XD)
The gba has a screen size of 240x160 pixels.
This has the capability of having 30x20 tiles on the screen at a time.
The gba is a 16-bit color system. Meaning all the colors you have available on a computer, are not available on the GBA.
Colors
How colors are stored in the GBA vram
As previously stated, GBA colors are 16 bits a piece. Believe it or not, 1 bit is actually wasted :O.
heres how a gba color looks
[wasted bit][5 bits: Red value][5 bits: Green Value][5 bits: Blue value]
since each of the RGB values are only 5 bits long, there is a maximum of 31 value possibilities to each. You will get the closest match to the actual color, by simply multiplying those values by 8. If you are a programmer, here's how to store colors in GBA format.
#define gba(r,g,b) ( r | g<<5 | b << 10 )
If you aren't, that is simple enough, you should be able to figure it out (again, bitwise logic is needed) << means to shift left X times. Reversing that is as simple as bitshifting to the right the respective amount of times and a little bit of AND'ing to remove the other bits from the remaining colors.
The BG Palette Memory Starts at 0x5000000 and the Sprite Palette Memory starts at: 0x5000200
Un-Compressed Graphics
The Easy Stuff...
The GBA has IO2 (that i know of) different storages of graphics. Compressed, or Uncompressed. Uncompressed graphics are easier to understand. If you are in 4BPP mode, the least amount of pixels you can have is 2.
[4 bits: pixel 2 index][4 bits: pixel 1 index]
What I mean by "index" is which color value on the palette will be used. Usually, 4BPP will be used with tilemaps, but there are other cases (like sprites)
please note that 4 bits restrains you to a value of 15, which is oddly convenient...
8BPP graphics are stored similarly
[8 bits (1 byte): pixel index]
This will allow you access to all 256 colors of either the BG palette, or the Sprite Palette.
GBA Video Modes
How the gba processes the graphics
The gba has different "modes" for graphics display. How the GBA knows which mode to use, is that it reads from the address 0x4000000. That is where the screen mode, and which bg's are enabled is stored. To set the appropriate mode you need to know some bitwise logic (google it if you don't already know it)
the hex values for the different bgs being enabled are:
BG0: 0x100
BG1: 0x200
BG2: 0x400
BG3: 0x800
If sprites are also enabled, you can treat them as a BG as well. They're enabled code is 0x1000
---<bg X enabled code> do that for each bg you are enabling.
OR <Mode, simply the mode number in hex>
Spoiler:
Mode 0
--Is tiled
--All 4 "layers" are accessible
--The tilemap can be either 16 or 256 colors
--Rotation and scaling (GBA "specialty functions" only accessible through asm...) are not supported
Mode 1
--Only 3 of the four layers are available
--the third layer (which is actually layer two, because layer 0 is the first layer, i know, it's confusing)
--Always 256 colors
--A maximum of 256 tiles.
Mode 2
--Only applicable to layers 2 & 3
--supports "specialty functions"
--Only 256 colors
--Maximum of 256 tiles
Mode 3
--First "un-tiled" mode
--entire screen (layers don't "exist in this mode; there isn't enough room for more than one...)
--No palette index (uses 2 bytes per pixel)
Mode 4
--"un-tiled" (afaik, not entirely for sure though)
--only layer 2 (the third layer) is available
--supports animation (able to load up to a whole two frames at a time!--WOW xD)
--256 colors (this is an indexed mode)
Mode 5
--Really rare situations are able to use this (as in you probably will never use it)
--Only 160x128 of the gba's pixels are useable
--Layer 2 only
--All colors
--Allows for animation (AKA double buffering, which is why it has two frames, and not the entire screen)
Putting it all together
Some assembly required
To display a 240x160 256 colors image, heres what you need to do.
Store the palette in the ROM
Store the image in the ROM (using tilemoster or etc, so that it's uncompressed)
write a routine, and set the video mode to one appropriate for you (i reccomend mode 4) then add a that will enter a (i usually use C++, so try to bear with me on my terms like "loop") loop, writing the palette to the BG memory. Add another (separate) loop that will copy the bytes from your image offset into the appropriate BG memory (I challenge you to find that with nothing more than VBA, hint hint: check the "map viewer" ;) )
add another (separate) loop. Next write a script that will fade the screen to black/other color, and call your routine (smart asm hackers obviously can call the routine through other methods, but i'm not exactly a "smart" asm hacker...still learning basics...) and voila! u see a nice pretty picture :D
...don't ask me how to return to normal play. Perhaps you could add a "waitforkeypress" to your script, then fade to black (yes, again) then fade from black to normal play. Or maybe you could loop in your routine (after displaying loading palette and pixels) and when a button is pushed the script would continue, which you could just fade into normal play from there. I dont' know branching and whatnot yet, so I can't post an example routine right nao...maybe i still wont' to help inspire others who dont know how either...
Tiles and their maps
Not alot to say...
Well, theres not a lot to these, especially since we have NTME and Cyclone, and PTC (lol, theres' so many...)
simple.
A tile: 8x8 block of pixels
Tilemap: a series of shorts describing which tile goes where on the GBA screen
I'm not going to touch on how to load tilemaps, its' a bit much for me to type out at 11:23 pm...
Tile Insertion
almost a little rant
Ok, so you have this nice set of tiles you'd like to insert right?
But holy shiz! ITS FRIGGIN HUGE!
Have no fear, this tutorial is here!
What I see a lot of is people getting the mis-understanding that tiles you insert have to be as you see them in the map; this is a lie. First let me explain to you what a "block" and a "map" are.
Block: a 2x2 set of tiles, with two layers.
Map: a bunch of tiles, with movement permissions, and events.
Tileset: a bunch of blocks.
So rather than have a 16x16 tile pasted into your tileset, and wasting space (assuming they're identical) you can break it down into perfect 8x8 tiles ;)
How to do this?
well, you could just jump into sphere and convert it...but that could turn out disastrous.
First you need to gather all the tiles you want to insert, that share the same palette.
Open up paint, and paste all the tiles you want in there.
Fill the BG (your going to be indexing this, so be sure not to miss anything) with a transparent color (you want it to be completely unique, so using the paint default colors is perfectly exceptional. Ensure that the bottom-left pixel is the transparent color, and save as a un-indexed bitmap file.
Open up the saved file in irfanview, and index it into 16 colors. Save again (still bitmap format)
download and, maybe, install the GTK+ runtime, the tool "Full Metal Paletted" from here
once that's done, run the program. Click on the 4BPP bitmap option, and load the file from previous steps.
Then click on the save a-map palette button, and save the advance map palette. Open a-map, load your rom, go to a map with the right tileset and load block editor.
Choose the palette to replace, and load it from file (choose the file we saved in with palette editor).
Now comes the tile insertion part.
Open up each individual tile, and make sure it aligns with a pixel spot that, if added by one, is divisible by 8 (if the first pixel on the left is 0) and also make sure the same is true vertically. Save your image. Open up sphere, import->image to map and open the image we previously saved. Set the block size to 8x8 and click yes when it asks to remove duplicate tiles grab the tileset saved with sphere and save it. Open that up in paint, and copy it. Then go back to a-map, and save your tileset (with the palette you want to use). Open up your tileset with pain, paste your clipboard wherever it fits, and load the tileset again with amap. This is important, if you clicked "Write Palette Changes to ROM" then you'll have to load your palette again (from file) and then load your tileset, i'll explain why later. If you didn't click "Write Palette Changes to ROM" then you are good to go, load the tileset, and NOW click "write palette changes to ROM" and may begin block editing ;) read some other tile insertion tutorial to learn how to do that...
So why can't you click "write palette changes to ROM"?
Every tileset image is stored with a .pal file right next to it. The .pal file has all the colors used in your palette, which is how A-map knows which pixel to put where, without using indexed bitmaps. If you have a pixel on your bitmap, that is not in your .pal file, then your tileset, when loaded, will not load the colors right, unless by some unlikely chance, all the colors are divisible by 8 and less than 248. So...why can't we click that button? Because when you do, a-map looses the original colors, and converts them to colors that are GBA compatible (divisible by 8 and less than 248) so when you save the tileset, the colors in the .pal file will NOT match the colors of the content in your clipboard.
Last edited: