Page 1 of 3

Homebrew Project Questions

Posted: Thu Feb 04, 2010 11:00 pm
by Tron
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)):

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] 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:)

Code: Select all

int main(void) 
{
	int i;
 
	irqInit();
	irqEnable(IRQ_VBLANK);
 
	videoSetMode(MODE_FB0);
        ...
[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:)

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]);
	}		
}

Re: Homebrew Project

Posted: Thu Feb 04, 2010 11:18 pm
by WinterMute
Chris Double's tutorials should probably be ignored, they're unfortunately rather badly out of date now & most, if not all, of his code will fail to compile with the latest iteration of the tools.

Running rendering code inside the Vblank irq is a technique that has some advantages where you want to absolutely guarantee that your screen gets updated every frame during the vblank period. Under most circumstances it's not necessary or even desirable. It's good for running an animation during a load from disc or some other process that may not return for a relatively large period of time. The majority of homebrew games won't ever encounter this kind of situation.

When there is little or no code in the Vblank interrupt handler the swi call is more than sufficient.

Re: Homebrew Project

Posted: Fri Feb 05, 2010 9:59 am
by Tron
That is unfortunate about the tutorials. Then I will rely mostly on devoto's and soon on experimentation and perusal of the API.

As for the answer to my question: It is as I thought, then - there is usually ample time as the processor is so much faster than the rendering hardware. And I understand the example for when placing the code inside the vblank irq would be appropriate.

Thanks for your response; I am happy you provide such support for the toolchain.

Re: Homebrew Project

Posted: Mon Feb 08, 2010 11:12 am
by Tron
New questions:

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.

3. Why is touchReadXY(touchPosition*) for ARM9 deprecated and is touchRead(touchPosition*) the new way to get stylus coordinates in ARM9 code?

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);
        ...

Re: Homebrew Project Questions

Posted: Mon Feb 08, 2010 1:20 pm
by vuurrobin
2. the actual definition of the functions are in the .c source files. they are already compiled to a binary, so the source files aren't distributed with a normal install. if you want the source files, grab them from the sourceforce page.

3. probably because touchread() not only sets the x and y, but also the pressure and raw values. it shouldn't make much of a difference.

4. interrupts are automaticly initialised for you before main is executed. you can just use swiWaitForVBlank() in your code, no need to do anything else.

Re: Homebrew Project Questions

Posted: Mon Feb 08, 2010 10:09 pm
by Tron
3 & 4: Ok, cool.

2: I thought I was looking at the source - it's labeled libnds-src-1.4.0 on sourceforge.

EDIT: Nevermind, I wasn't looking at the .c files. Now I see the code which I thought was missing.

Re: Homebrew Project Questions

Posted: Mon Feb 08, 2010 11:17 pm
by StevenH
Some functions are defined in .s files, some in .c files..

Most of the functions your trying to see are within the libnds library which scares me when I look at it. Normally you don't need to see how those functions work as they interface directly with the hardware.

Re: Homebrew Project Questions

Posted: Mon Feb 08, 2010 11:20 pm
by Tron
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 showing touch coordinates.

Re: Homebrew Project Questions

Posted: Tue Feb 09, 2010 12:10 am
by vuurrobin
it should produce an .nds file with the name being the same as the name of the folder of your project (the one with has the makefile in it). so if the folder is called arm9, then the file will be called arm9.nds

Re: Homebrew Project Questions

Posted: Tue Feb 09, 2010 12:27 am
by Tron
The name of the folder with the top level Makefile is called "tileDemo1", but when I searched My Computer there was no .nds file with that title created after the make completed without error. There were, however, .nds files created in the two subfolders, arm9 and combined, called arm9.nds and combined.nds.