Custom Sprite Tutorial (German) by Darius Einleitung Hallo und herzlich willkommen zu meinem Custom Sprite Tutorial! Ich werde euch zeigen, wie ihr Custom Sprites programmieren könnt. Dazu solltet ihr wissen, wie man Custom Sprites in SMW einfügt – via Romi’s Sprite Tool. Auch die folgenden ASM Befehle solltet ihr beherrschen: LDA + STA (Laden und Speichern) RTS + RTL (Beenden) BEQ, BNE, BCC, BNK, BMI etc. (Branch (= Verzweigungs) Befehle) CMP + AND (Vergleichsbefehle) TAX, TAY, TXA, TXY, TYA, TYX (Transferring) INC, DEC, LSR etc. (Mathematische Befehle) Indexen mit X ($0300,x) oder Y ($0300,y) JSR, JSL, JMP etc. (Jumping Befehle) Und ihr solltet sehr geduldig sein und nicht gleich einen Boss programmieren (wie ich), sondern lieber mit einem Generator oder einem SMB1 Goomba. Danach können wir ja mal einen Boss coden ;D DIESES TUTORIAL ERKLÄRT NOCH DAS CODEN FÜR TRASM – KONVERTIERT EVTL. DEN CODE ZU XKAS (z.B. mit Trashkas) Lesson 1: Der Aufbau eines Sprites – INIT und MAIN Ein Block besteht aus diesen ganzen JMP Below und so, Sprites bestehen aus zwei Hauptroutinen, nämlich der INIT und der MAIN Routine. dcb „INIT“ RTL dcb „MAIN“ RTL dcb (kennt ihr wahrscheinlich von Tabellen) wird benutzt, gefolgt von dem Namen der Routine. Ändern des Namens wäre sehr unpraktisch (Crash). Außerdem MÜSSEN die INIT und die MAIN Routinen mit einem RTL(!) beendet werden (sonst Crash!). Dazu sollte es normalerweise keine Fragen geben, es ist schon fast ZU simpel. Eine INIT und eine MAIN Routine hat JEDER Sprite. Auch wenn in z.B. der INIT Routine nichts steht muss sie geschrieben werden! In einem Generator wäre dies zum Beispiel der Fall (womit wir bei Lesson 2 sind =D)! Lesson 2: Einen simplen Generator erstellen Wir wollen jetzt einen Generator erstellen, der, wenn Mario auf Yoshi sitzt, das Level als ein Unterwasserlevel macht. Dazu benötigen wir zwei Adressen: $85: Unterwasser Flag $187A: Riding Yoshi Flag Das würde dann so aussehen: dcb „INIT“ RTL ; A Generator has no INIT Routine dcb “MAIN” LDA $187A CMP #$01 BCC Return LDA #$01 STA $85 Return: RTL Alles, was ich gemacht habe: 1. Gucken, ob Mario auf Yoshi reitet. 2. Falls das nicht stimmt, spring zu Return. 3. Ansonsten mach das Level Unterwasser. Probiert’s aus! Mehr kann mit Generatoren auch nicht machen als sowas. Du kannst ein HDMA Gradient Code auch in einen Generator machen, aber wozu gibt’s levelASM? Wenn du diesen Code übrigens immer im ganzen Level laufen haben willst, kannst du unseren Code auch in levelASM schreiben. Baer wenn du erst ab einem bestimmten Screen diese Funktion haben willst, füg den Generator einfach in jenem Screen ein! Lesson 3: Der 16x16 Sprite Gut, wenn ihr etwas mit Generatoren herumexperimentiert habt, wollt ihr jetzt sicherlich einen Sprite machen, den man sehen kann. Und genau das lernen wir jetzt hier! Das SNES kann nur zwei verschiedene Größen anzeigen – 8x8 und 16x16. Jetzt denkt ihr bestimmt „Hä? In Brutal Mario sah ich doch Größere…“ und ja, man kann größere Sprites machen. Aber wie? Mit dem Baustein System. Du nimmst einfach ganz viele 16x16 Bausteine und baust sie zu einem größeren (im Beispiel 32x32) Sprite. Du kannst den auch noch viel größer machen 64x64, 128x64 und so weiter. Das funktioniert nicht mit 8x8 Bausteinen -> Die sind also unnötig! Und jetzt fangen wir mit dem Coden an. Wir werden Adressen, die im OAM Bereich liegen, verwenden, denn, der OAM Bereich (großer Platz wo Grafikdaten gespeichert werden) ist für unsere Grafik Sachen zuständig. Wir erstellen nun eine Eisfeuerblume als Grafik. Dazu müssen wir folgendes einstellen: Kein X- oder Y-Flip Palette B Tile 326 Um die Grafiken zu coden benötigen wir eine separate Routine, welche sich GET_DRAW_INFO nennt. Diese könnt ihr in jedem Sprite finden, der Grafiken darstellt. Diese Routine könnt ihr außerdem im tutorials-Ordner von SpriteTool in library.asm finden. Kopiert sie und fügt sie ganz unten in eure ASM Datei ein (sofern ihr schon eine habt!) Ich lege mir jetzt mal eine an. So sieht sie bei mir aus: dcb "INIT" RTL dcb "MAIN" JSR Main RTL Main: JSR Graphics RTS Graphics: JSR GET_DRAW_INFO RTS ---HIER-IST-GET_DRAW_INFO--- Ich habe mal den Hauptcode vom Sprite in eine separate Routine gepackt. Und die Grafiken auch. Unsere Graphics Routine beinhaltet aber zurzeit nur das JSR GET_DRAW_INFO. Jetzt fangen wir mal richtig an! Zuerst speichern wir die X-Position des Sprites minus 1 zu der OAM-Adresse $0300,y. Ach, und ALLE OAM Sachen werden mit Y geindext, Sprites Routinen hingegen mit X. Das machen wir ganz simpel so: LDA #$00 STA $0300,y Ganz einfach. Und das machen wir jetzt mit der Y Position des Sprites welche in $0301,y gespeichert ist: LDA #$01 STA $0301,y Die y-Position ist 1 und nicht null. Warum? Fragt nicht =P. Jetzt speichern wir das Tile. Die Feuerblume ist das Tile 326, aber LDA #$326 macht sich nicht so gut. Deshalb müssen wir nur die letzten zwei Ziffern aufschreiben – Die GFX Seite können wir gleich noch ändern! LDA #$26 STA $0302,y Und zu guter Letzt das Property Byte. Format: YXPPCCCT Y –> 0 = Kein Y-Flip, 1 = Hat Y-Flip X -> Selbes Format wie Y PP -> Priorität (Ganz hinter allen Layern oder unabdeckbar ?) 00 -> Ganz niedrig 01 -> niedrig 10 -> mittel 11 -> hoch CCC -> Palette 000 -> Palette 8 001 -> Palette 9 010 -> Palette A 011 -> Palette B 100 -> Palette C 101 -> Palette D 110 -> Palette E 111 -> Palette F T -> Grafikenseite: 0 = Seite 1 (SP1 & SP2), 1 = Seite 2 (SP3 & SP4) Oh mein Gott, die halbe Seite ist jetzt weg xD. Egal. Ihr habt sicherlich festgestellt, dass das hier in Binär abläuft. Also machen wir mal: LDA #%00010110 STA $0303,y Das würde leider nicht ganz funktionieren. Wir müssen nur ein ORA $64 ergänzen: LDA #%00010110 ORA $64 STA $0303,y So, dann hätten wir jetzt fast alles. Jetzt müssen wir viermal