Difference between revisions of "Developer Tips/de"

From WiiBrew
Jump to: navigation, search
(Zurückspringen zum Loader)
(Zurückspringen zum Loader)
Line 19: Line 19:
 
</source>
 
</source>
  
==Zurückspringen zum Loader==
+
==Zurückspringen zum Lader==
 
Es ist immer nett, ein Zurückspringen zum "Lader" zu ermöglichen. Ansonsten müsste man die Wii jedesmal neustarten, wenn man eine Homebrew-Applikation beenden möchte.
 
Es ist immer nett, ein Zurückspringen zum "Lader" zu ermöglichen. Ansonsten müsste man die Wii jedesmal neustarten, wenn man eine Homebrew-Applikation beenden möchte.
  

Revision as of 14:43, 24 January 2009

Quellcode Ausschnitte

Video-System-Autoerkennungs-Routine

Die libogc von DevkitPPC r15 setzt den Video-Modus automatisch durch einen Funktionsaufruf.

Hier ist die Video-Erkennungsroutine aus dem DevkitPRO Wii-Beispiel.

#include <gccore.h>
static GXRModeObj *rmode = NULL;
// ...
rmode = VIDEO_GetPreferredMode(NULL);

if( CONF_GetAspectRatio() )
{
	rmode->viWidth = 678;
	rmode->viXOrigin = (VI_MAX_WIDTH_PAL - 678)/2;
}
VIDEO_Configure(rmode);

Zurückspringen zum Lader

Es ist immer nett, ein Zurückspringen zum "Lader" zu ermöglichen. Ansonsten müsste man die Wii jedesmal neustarten, wenn man eine Homebrew-Applikation beenden möchte.

    // Binde einfach die unistd.h-Headerdatei ein und rufe die ''exit()'' Funktion auf, um zum loader zurück zu kommen
    // ''return()'' aus der main Funktion funktioniert ebenso
    #include <stdlib.h>
    // ...
    exit(0);

Anmerkkung: Der __crtmain-Code ist fehlerhaft, da er standardmäßig nicht exit aufruft. Kann man selbst verbessern. Zusätzlich ruft es nicht die Konstruktoren der globalen Objekte in C++ auf. Das kommt davon wenn man unsauber zusammengestrickte Einzeiler verwendet.

Wii Neustarten

#include <gccore.h>
// ...
SYS_ResetSystem(SYS_RESTART,0,0);

Man kann auch mit SYS_RETURNTOMENU das Systemmenü aufrufen, beziehungsweise mit SYS_POWEROFF die Wii ausschalten (je nach WC24-Einstellungen wird der Standby- oder Idlemodus aktiviert. SYS_POWEROFF_STANDBY und SYS_POWEROFF_IDLE können das gezielt erzwingen)

Wiimote Abfragen

How to use the Wiimote (englisch).

Debugging Tipp

Wenn du mit einem Absturz deiner Homebrew konfrontiert wirst, siehst du meist eine Adresse mit einigem Maschinen-Code auf dem Display. Hier ist mein Trick um die Stelle im C++-Code zu lokalisieren.

Angenommen deine Homebrew stürzt ab und folgendes wird angezeigt:

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

Die 800084ac ist die Speicheradresse in Hex an der der Fehler auftrat. 809F0020 ist der Maschinen-Code der den Fehler produziert.

  • Schritt 1:

Ändere in deinem Makefile die CXXFLAGS-Zeile zu:

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

Das -save-temps Attribut speichert ddie assemblierte-Zwischencode-Datei, die interessant sein könnte. Das -Xassembler -aln=$@.lst Attribut erzeugt eine Liste der Dateien die assemblierten und Maschinen-Code enthalten. Jetzt Compiliere dein ganzes Projekt erneut. Anmerkung: Das wirkt sich nur auf C++ Code aus.

  • Schritt 2:

Schaue dir die Map-Datei an die erstellt wurde. Die Map ist dort zu finden wo auch das Wii-Template Makefile ist. Normalerweise ist es im Built-Unterordner, als irgendwas.map Datei. Suche in Map-Datei nach der Speicheradresse die am nähsten an der steht die wir im CORE DUMP gehen haben. Hier ein Beispiel:

    0x80008464                ShooterView::Render(BibGraphicsDevice&)

Das sagt mir, dass der Absturtz 72 Byte in der ShooterView::Render() Funktion war. Jetzt müssen wir die Render() Funktion noch im Code finden

  • Schritt 3:

Suche in der Listen-Datei nach der gesuchten Funktion. Hier ein Beispiel:

   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)

Die Funktionsnamen sind hier beschnitten denn es handelt sich um C++ Code ( Siehe http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B). Die Adresse des ersten Befehls von Render() ist an der Stelle 02d0. Das ist gleichzeitig Zeile 158 in unserer Datei (".loc 1 158 0"). Um den Fehler zu finden müssen wir an Stelle 0x318 ( = 0x2d0 + 72 ) suchen. Wie hier:

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

Hier sehen wir die Maschinen-Adresse 0x318 mit dem Maschinencode. Der nähste .loc Befehl sagt uns, dass das Problem in Zeile 168 in unserer ShooterView.cpp aufgetaucht ist. Für mehr Informationen zu Assembler-Ausgaben, gibt es dieses Manual: http://sourceware.org/binutils/docs-2.18/as/index.html

Grundsätzliche Tipps zum Programmieren

  • Kommentierte deinen Code durchgehend, das hilft anderen Fehler zu finden.
  • Jeder ungenutzte Code sollte aus dem Programm verschwinden, außer es ist ein Programm um anderen etwas zu erklären.
  • Wenn ein anderer ein ähnliches Programm schreibt, wie du, bloss effizienter, akzeptiere es und lerne davon.