Developer tips

From WiiBrew
Jump to navigation Jump to search

Code Snippets

Video Auto-Detect Routine

Please include an autodetect routine (VIDEO_GetCurrentTVMode()) to detect HDTV/EDTV and set the appropriate video mode.

The current video autodetect routine doesn't work with PAL60 (480i @ 60 Hz in PAL Wii) using the offical Nintendo RGB cable for Wii.

Here is the video detect code from the DevKitPro Wii example.

   rmode = VIDEO_GetPreferredMode(NULL);

Forum thread

Reboot Wii

It's a good idea to include a way to reboot the Wii in all Homebrew. Here's the source code to do it.

void Reboot()
	// Thanks to hell_hibou
	int fd = IOS_Open("/dev/stm/immediate", 0);
	IOS_Ioctl(fd, 0x2001, NULL, 0, NULL, 0);

Exit to Loader

It's a good idea to add some way to return to the loader, otherwise you have to reboot you Wii to exit.

   // Just call the exit() function to go back to the loader
   // Returning from main also works, since that calls exit for you
   // ....

Note: The floating around __crtmain code is faulty in the aspect that it does not call exit as the standard requires. Fix it your self. In addition, it also does not call the constructors for global objects in c++. But that's what you get when using quickly hacked together one liners.

if all else fails

    //cleanup system for exit
    //load boot loader address to function pointer and call it all in one step

you can put this all in one line since it is essentially a non-library dependent exit as from above. not good practice on a general purpose machine, but this is an embedded system.

How to use the Wiimote

A separate article is available: How to use the Wiimote.

Debugging Tip

When faced with a crash in your Homebrew, often you'll see a code dump with an address and some machine code. Here's my trick to track that back to a line of C++ code.

For example if your homebrew game crashes it might show something like this:

    800084ac:   809F0020 2F840000 ...
    800084bc:   ...
    800084cc:   ...

The 800084ac is the memory address in hex of where the crash occured. 809F0020 is the machine code for the offending instruction.

  • Step 1:

In your makefile change the CXXFLAGS line to the following:

  CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS)

The "-save-temps" will save the assembly language file, which can be interesting. The "-Xassembler -aln=$@.lst" creates a list file which contains the assembly and the machine code. Now recompile your entire project. Note, this just affects C++ code.

  • Step 2:

Look at the map file that was built. The mapfile is on by default in the Wii template makefile. Typically it's in the build subdirectory and called Look in that mapfile for the nearest memory address that doesn't go over the one found in the CODE DUMP. Here is an example:

    0x80008464                ShooterView::Render(BibGraphicsDevice&)

This tells me that the crash was 72 bytes into the ShooterView::Render() function. Now to find the line number in Render()

  • Step 3:

Look at the list file for the relevant function. Here's an example:

   473              		.globl _ZN11ShooterView6RenderER17BibGraphicsDevice
   474              		.type	_ZN11ShooterView6RenderER17BibGraphicsDevice, @function
   475              	_ZN11ShooterView6RenderER17BibGraphicsDevice:
   476              	.LFB1465:
   477              		.loc 1 158 0
   478              	.LVL20:
   479 02d0 9421FF00 		stwu 1,-256(1)

The function names are mangled because this is C++ code. See The address of the first instruction of Render() is at 02d0. This is also line 158 in the file (".loc 1 158 0"). To find the error location, just look at 0x2d0 + 72 = 0x318. See below:

                               .loc 1 168 0
   528 0314 809F0020 		lwz 4,32(31)
   529 0318 2F840000 		cmpwi 7,4,0

This shows machine address 0x318 has the proper machine code and the nearest .loc statement says the problem is at line 168 of the ShooterView.cpp. For more info on the assember output see the manual here:

General Programming Tips

  • Keep your code commented throughout; it helps others help you.
  • Any unused code should be deleted out of the program, unless it is a program for teaching people.
  • If someone does the same thing in a more efficient way (i.e. faster and/or in less code), accept it and learn from it.