Homebrew Project Questions
Posted: Thu Feb 04, 2010 11:00 pm
I'm writing a simple word game as a school project, and I figured it would be best to post questions I have all in one thread. The blog for the project is located here, where there is currently a short specification of the game.
Questions:
9. Can hardware scrolling be done on tiled backgrounds, and if so, does it move by pixel or by tile width (8 pixels) and how is it done?
[Solved] 8. How are pixel transparencies handled using 256 paletted color (since there is no transparency bit as in 16-bit color mode)?
7. In dovoto's 4th day tutorial, he says that the 11th and 12th bits in a 16-bit tilemap header are control bits for horizontal and vertical flipping, respectively. I assumed this meant over an imaginary y and x axis so that one tile could be used both for one side of an image, and the opposing, symmetric, side. However, I tried to do this in a demo but the locations in the map which were to be flipped tiles did not appear. Below is a snippet showing the code where I assign the flipped tiles in the map (using & BIT(11)):
[Solved] 6. Why must tile data be written to video memory using a bios call (swiCopy) instead of writing to the space directly?
[Solved] 5. I followed the basic compilation instructions at the bottom of dovoto's day 1 guide to make a demo I wrote, but I don't know what the resultant file should be. Is it arm9.nds? First I thought it should be the combined.nds file but when tested on desmume it produced a demo from drunkencoders.com.
[Solved] 4. How do I enable vblank interrupts to be processed, so as to call swiWaitForVBlank()? In dovoto's tutorial, he calls irqInit() inside main followed by irqEnable(IRQ_VBLANK), but presumably this is outdated since the documentation says irqInit() must be called prior to main, and irqEnable now has the handler as an additional argument. (See code:)
[Solved] 3. Why is touchReadXY(touchPosition*) for ARM9 deprecated and is touchRead(touchPosition*) the new way to get stylus coordinates in ARM9 code?
[Solved] 2. There are many places in the libnds source code where a prototype for a function, but no actual definition, is given. Where are the definitions for these functions?
For example, in nds/interrupts.h there are prototypes for the functions, irqInit(), irqSet(), irqClear(), etc. are given without definition. In nds/input.h it is the same way for
scanKeys(), keysHeld(), keysDown(), etc.
[Solved] 1. In Chris Double's tutorial on rendering graphics to the screen in framebuffer mode, the memory writing code is placed inside the interrupt handling routine and called upon each VBLANK interrupt. In dovoto's tutorial on the same subject, however, the memory writing code is immediately after the SWI call. What is the reasoning behind this difference in the location of memory writes? Is devoto's approach sufficient because there will be ample time upon return from the interrupt handler to write to memory before the hardware renders to the screen again? (See code below:)
Questions:
9. Can hardware scrolling be done on tiled backgrounds, and if so, does it move by pixel or by tile width (8 pixels) and how is it done?
[Solved] 8. How are pixel transparencies handled using 256 paletted color (since there is no transparency bit as in 16-bit color mode)?
7. In dovoto's 4th day tutorial, he says that the 11th and 12th bits in a 16-bit tilemap header are control bits for horizontal and vertical flipping, respectively. I assumed this meant over an imaginary y and x axis so that one tile could be used both for one side of an image, and the opposing, symmetric, side. However, I tried to do this in a demo but the locations in the map which were to be flipped tiles did not appear. Below is a snippet showing the code where I assign the flipped tiles in the map (using & BIT(11)):
Code: Select all
/* create tilemap */
int i;
for (i = 0; i < 21*32; ++i)
mapMemory[i] = 0;
for (; i < 21*32+29; ++i)
mapMemory[i] = 0;
mapMemory[i++] = 1;
mapMemory[i++] = 2;
mapMemory[i++] = 1 & BIT(11);
for (; i < 22*32+29; ++i)
mapMemory[i] = 0;
mapMemory[i++] = 3;
mapMemory[i++] = 6;
mapMemory[i++] = 3 & BIT(11);
for (; i < 23*32+29; ++i)
mapMemory[i] = 0;
mapMemory[i++] = 4;
mapMemory[i++] = 5;
mapMemory[i] = 4 & BIT(11);
[Solved] 5. I followed the basic compilation instructions at the bottom of dovoto's day 1 guide to make a demo I wrote, but I don't know what the resultant file should be. Is it arm9.nds? First I thought it should be the combined.nds file but when tested on desmume it produced a demo from drunkencoders.com.
[Solved] 4. How do I enable vblank interrupts to be processed, so as to call swiWaitForVBlank()? In dovoto's tutorial, he calls irqInit() inside main followed by irqEnable(IRQ_VBLANK), but presumably this is outdated since the documentation says irqInit() must be called prior to main, and irqEnable now has the handler as an additional argument. (See code:)
Code: Select all
int main(void)
{
int i;
irqInit();
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_FB0);
...
[Solved] 2. There are many places in the libnds source code where a prototype for a function, but no actual definition, is given. Where are the definitions for these functions?
For example, in nds/interrupts.h there are prototypes for the functions, irqInit(), irqSet(), irqClear(), etc. are given without definition. In nds/input.h it is the same way for
scanKeys(), keysHeld(), keysDown(), etc.
[Solved] 1. In Chris Double's tutorial on rendering graphics to the screen in framebuffer mode, the memory writing code is placed inside the interrupt handling routine and called upon each VBLANK interrupt. In dovoto's tutorial on the same subject, however, the memory writing code is immediately after the SWI call. What is the reasoning behind this difference in the location of memory writes? Is devoto's approach sufficient because there will be ample time upon return from the interrupt handler to write to memory before the hardware renders to the screen again? (See code below:)
Code: Select all
while(1) {
old_x = shape_x;
old_y = shape_y;
shape_x++;
if(shape_x + shape_width >= SCREEN_WIDTH) {
shape_x = 0;
shape_y += shape_height;
if(shape_y + shape_height >= SCREEN_HEIGHT) {
shape_y = 0;
}
}
swiWaitForVBlank();
}
and
void on_irq()
{
if(REG_IF & IRQ_VBLANK) {
draw_shape(old_x, old_y, VRAM_A, RGB15(0, 0, 0));
draw_shape(shape_x, shape_y, VRAM_A, RGB15(31, 0, 0));
// Tell the DS we handled the VBLANK interrupt
VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK;
REG_IF |= IRQ_VBLANK;
}
else {
// Ignore all other interrupts
REG_IF = REG_IF;
}
}
vs.
while(1) {
swiWaitForVBlank();
for(i = 0; i < NUM_STARS; i++)
{
EraseStar(&stars[i]);
MoveStar(&stars[i]);
DrawStar(&stars[i]);
}
}