#94406 - Turambar - Mon Jul 24, 2006 7:47 pm
I have a problem with 8 bit backgrounds. I'm trying to draw a red box with this code:
Code: |
int main(void) {
irqInit();
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetMainBanks( VRAM_A_MAIN_BG_0x6000000, VRAM_B_MAIN_BG_0x6020000,
VRAM_C_SUB_BG , VRAM_D_LCD);
BG3_CR = BG_BMP8_512x256;
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0;
u16* frontBuffer = (u16*)(0x06000000);
BG_PALETTE[3] = 0x1F;
//draw a box
for(int iy = 0; iy < 50; iy++)
for(int ix = 0; ix < 50; ix++)
frontBuffer[iy * 512 + ix] = 3;
while(1) {
swiWaitForVBlank();
}
} |
But this doesn't draw the pixels together, since I'm using a u16* buffer, and the pixels are 8bit. Of course I tried changing frontBuffer to a u8*, but then it draws nothing...
What's the problem?
#94424 - Lazy1 - Mon Jul 24, 2006 8:28 pm
You have to write 2 pixels at a time in 8bit mode...
2pixels = ( pixel #1 << 8 ) | pixel #2
#94618 - silent_code - Tue Jul 25, 2006 2:56 pm
if you want to draw one pixel, this code works for me:
Code: |
((uint16*)SCREEN_BASE_BLOCK(0))[pixel] &= even ? 0xFF00 : 0x00FF; // clear the pixel first or you won't get the right color!
((uint16*)SCREEN_BASE_BLOCK(0))[pixel] |= even ? color : color << 8;
|
happy coding ;)
#94738 - Turambar - Wed Jul 26, 2006 12:18 am
Thanks! I was beginning to think I would have to read the adjacent pixel every time I wanted to write one.
#94751 - Cearn - Wed Jul 26, 2006 1:10 am
silent_code wrote: |
if you want to draw one pixel, this code works for me:
Code: |
((uint16*)SCREEN_BASE_BLOCK(0))[pixel] &= even ? 0xFF00 : 0x00FF; // clear the pixel first or you won't get the right color!
((uint16*)SCREEN_BASE_BLOCK(0))[pixel] |= even ? color : color << 8;
|
happy coding ;) |
Turambar wrote: |
Thanks! I was beginning to think I would have to read the adjacent pixel every time I wanted to write one. |
That code is reading the adjacent pixel. Twice (probably). Remember, &= and |= mean reading the thing too.
#94752 - tepples - Wed Jul 26, 2006 1:11 am
In 8-bit extended rotation backgrounds on both the GBA and DS, read-modify-write is the usual operation for writing a single pixel, but you can write a group of two or four at a time. This means horizontal lines (such as in the middle of a rectangle fill, circle fill, polygon fill, or flood fill) are still fast to draw.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#94894 - silent_code - Wed Jul 26, 2006 7:36 pm
well, there is no other way if you want to write single pixels. but this code works for me and i'm drawing like 2k particles (or even more - with some having three to six or more pixels per particle). ;)
#94901 - DekuTree64 - Wed Jul 26, 2006 8:04 pm
On DS, you can write single pixels by turning on the cache for VRAM. AFAIK there are no libnds functions for fiddling with protection region settings, but if you don't mind a bit of assembly, it can be done.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#94914 - Mighty Max - Wed Jul 26, 2006 9:05 pm
There is a problem with that.
The VRAM falls into the HW-Registers region (0) and you don't want to have those cached. You'll have to find a region you can drop or merge with another one in order to cache the VRAM.
You could merge the wram and its mirror, this has the negative, that caching the region the IPC struct is within isnt recommented, and having this combined region uncached slowes down every access to wram.
:edit: however that enabled my exec_stub now long filenames & such without the need to do this in _slower_ arm7 code (which has native 8bit access to vram) *g* Thanks for the hint
_________________
GBAMP Multiboot
#94917 - DekuTree64 - Wed Jul 26, 2006 9:28 pm
You could combine IO regs and uncached main RAM by making a giant region that covers the entire memory space. Sort of a catch-all region that has uncached read/write/execute access. The regions have priority, so if 2 overlap, the higher numbered region will be used. So if you use 0 for the catch-all, the rest will still work as before.
Actually, the only difference between the settings for IO regs, GBA slot, ITCM, DTCM, and uncached main RAM are the read/write/execute settings. Unless you're writing an operating system or something where you actually plan to recover from exceptions, those don't do a whole lot of good anyway.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#94922 - Mighty Max - Wed Jul 26, 2006 9:55 pm
DekuTree64 wrote: |
The regions have priority, so if 2 overlap, the higher numbered region will be used. So if you use 0 for the catch-all, the rest will still work as before.
|
Just a small correction: the smaller the region the higher its priority. The number is irrelevant for different sized regions.
Ontop of that, with the current possibility to catch accesses to regions that are not good to access (i.e. NULL pointer references) it might not be wise to disable this feature by a "allow all".
_________________
GBAMP Multiboot
#94945 - DekuTree64 - Wed Jul 26, 2006 11:41 pm
Mighty Max wrote: |
Just a small correction: the smaller the region the higher its priority. The number is irrelevant for different sized regions. |
Where did you read that? The ARM ARM says it's based on region number:
ARM ARM wrote: |
Protection regions can legitimately overlap eachother. If an address lies within more than one protection region, the attributes of the highest-numbered protection region apply to it. |
For your other comment, I agree null accesses are common enough that they should be trapped. Another place you could maybe snatch a region would be to combine cached main RAM and IWRAM, covering the range from 0x2000000 through 0x3ffffff.
Either that or leave IWRAM without a region at all, since it's usually more useful to allocate it to ARM7 anyway, so it has more work space without causing conflicts over main RAM. And if you do want it cached, just allocate the user region to it.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#94997 - Mighty Max - Thu Jul 27, 2006 8:06 am
DekuTree64 wrote: |
Mighty Max wrote: | Just a small correction: the smaller the region the higher its priority. The number is irrelevant for different sized regions. |
Where did you read that? The ARM ARM says it's based on region number:
ARM ARM wrote: | Protection regions can legitimately overlap eachother. If an address lies within more than one protection region, the attributes of the highest-numbered protection region apply to it. |
|
Hmm indeed, memory was serving me wrong then. sorry
_________________
GBAMP Multiboot