Jump to content

[Guide] Was ist .spr? - ein kleiner "Guide"


Normynator

Recommended Posts


  • Group:  Developer
  • Topic Count:  7
  • Topics Per Day:  0.00
  • Content Count:  292
  • Reputation:   199
  • Joined:  05/03/13
  • Last Seen:  

Vorwort:

Ich schreibe diesen Guide, da ich mich im Moment mit diesem Thema befasse und mir aufgefallen ist, dass es kaum Dokumentationen über Sprites gibt. Jeder weiß wahrscheinlich was die .spr bedeutet - in der Datei befindet sich ein Charakter, Monster oder Gegenstand Sprite. Wie funktioniert .spr aber nun? In diesem Guide möchte ich versuchen alles zu teilen, was ich darüber weiß, und versuchen es so gut wie es geht zu erklären. Hierbei möchte ich einräumen, dass ich natürlich auch Fehler mache und sich diese einschleichen könnten. Falls ihr also einen Fehler, egal ob Logik, Rechtschreibung oder Grammatik findet, gebt mir Bescheid, damit ich den Guide weiter verbessern kann.

Quellen:

Folgende Quellen habe ich gefunden und genutzt:

Meine Implementierung:

Ich werde am Ende des Guides meine eigene "Proof of Concept" Implementierung verlinken. Geschrieben in Python. Ich möchte anmerken, dass dies kein optimaler und auch sicherlich nicht fehlerfreier Code ist. Der Code ist entstanden während ich gelernt habe wie Sprites aufgebaut sind. Ich habe den Code auch nach dem ersten Schreiben größtenteils unverändert gelassen und hatte nicht das Ziel möglichst sauberen oder effizienten Code zu schreiben. Falls ihr eine viel genutzte, sauberer Implementierung sehen möchtet, verweise ich auf ROChargenPHP

Fehler:

Wie schon erwähnt ist dieser Guide sicherlich nicht fehlerfrei, wenn ihr also einen Fehler findet, schreibt mir auf Discord, nutzt den verlinkten Discord Server oder antwortet einfach im Forum.

Bei Frage und Anregungen: https://discord.gg/fWtj7GB (Ich war mal so frei und hab ein Server erstellt)

Los gehts!

Was ist .spr? - ein kleiner "Guide"

Version 1.0

Header:

Name Size
Sprite Header 2 byte
Indexed Frames 2 byte
RGBA Frames 2 byte

Der Sprite Header muss immer ‚SP‘ sein. Die Version ist entweder 0x0102 oder 0x0002. Nun folgen 2 byte für die Anzahl der Indexed Frames. Danach 2 byte für die Anzahl der RGBA Frames. Einer der beiden Werte ist hierbei immer Null. RGBA Frames und Indexed Frames geben an wie viele Frames des jeweiligen Types in der Datei folgen werden. Wichtig ist noch, dass die Werte immer als ‚little Endian‘ zu interpretieren sind.

Frame Data:

Wir wissen nun aus dem „Header“ Abschnitt wie viele Frames in unserer Datei vorzufinden sind, welche Version vorliegt und ob es Indexed Frames oder RGBA Frames sind.

Indexed Frames:

Bei Indexed Frames ist es wichtig, welche Dateiversion vorliegt. Wir unterscheiden:

Version 0x0102:

Name Size
Width 2 byte
Height 2 byte
Length 2 byte
Data {Length} byte

Die ersten beiden Byte geben die Höhe und die nächsten beiden die Breite des Frames an. Danach kommen noch einmal zwei Byte, die die Anzahl der folgenden Byte, die Daten enthalten angeben.

Wie müssen die Bytes, die als tatsächliche Daten deklariert wurden, nun interpretiert werden? Wichtig hierbei ist zu wissen, dass in Version 0x0102 (in der befinden wir uns grade) der Hintergrund komprimiert ist.

Die Komprimierung funktioniert wie folgt:


  • Wenn ein Byte den Wert 0x00 hat, dann gibt das nächste Byte an, wie oft dieses wiederholt werden muss. (0x00 repräsentiert in der Palette die Hintergrundfarbe)

    Ein Beispiel: 00 05 wird zu 00 00 00 00 00 00

  • Falls ein Byte nicht den Wert 0x00 hat, wird das Byte so übernommen.

    Auch hier ein Beispiel: 05 wird zu 05 (unverändert)

Hier eine kleine Routine, an der man einfach sehen kann wie es als Code aussehen würde:

def parse_frame_data513(data):
    ret_data = {}
    q = 0
    j = 0
    while j < data.__len__():
        if data[j] == 0x00:
            for i in range(data[j + 1]):
                ret_data[q] = 0x00
                q += 1
            j += 1
        else:
            ret_data[q] = data[j]
            q += 1
        j += 1

    return ret_data    

Nun haben wir eine Liste von Bytes, die die Daten des Frames repräsentieren. Wir können diese Daten auch einfach Pixel nennen.

Version 0x0002:

Name Size
Width 2 byte
Height 2 byte
Data {Height * Width} byte

Wie auch in Version 0x0102 werden Höhe und Breite durch die ersten 4 Bytes bestimmt. Einen Unterschied gibt es bei der „Length", denn dieses ist nicht im Frame enthalten, sondern ergibt sich aus Höhe * Breite. Da „Length“ nicht existiert werden die tatsächlichen Daten durch Höhe * Breite deklariert. Die Daten beginnen direkt nach dem beiden Byte für „Height“. In dieser Version gibt es keine Kompression. Also folgt: Data = Pixels

RGBA Frames:

Wird zu einem späteren Zeitpunkt ergänzt.

Quelle: https://github.com/ScDarko/ROChargenPHP/blob/dbe268b01e20635bd2207b383bc8c34cbea668db/loaders/class.Sprite.php

Ein kleiner Ausschnitt aus ROChargenPHP:

for ( $y=$height-1, $i=1; $y>-1; $y-- ) {
   for( $x=0; $x<$width; $x++, $i+=4 ) {
	   if( $pixels[$i+0] > 0 ) {
		   imagesetpixel( $img, $x, $y, $this->getColor(
								$img,
								$pixels[$i+3] * $mult_color[0],
								$pixels[$i+2] * $mult_color[1],
								$pixels[$i+1] * $mult_color[2],
								127 - $pixels[$i+0]/2
			));
		}
	}
}

Für mehr, sollte ihr die oben genannte Quelle aufsuchen.

Palette

Wird bald ergänzt.

Render Image

Wird bald ergänzt

Danke an:

Noil & Dineos

Links:

SPRR: https://github.com/Normynator/SPRR (Implementierung, nur Sprite)

ImgR: https://github.com/Normynator/ImgR (Implementierung, Sprite, Act & Animation)

Edited by Normynator
  • MVP 2
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  7
  • Topics Per Day:  0.00
  • Content Count:  56
  • Reputation:   26
  • Joined:  05/13/16
  • Last Seen:  

Danke für den Guide, sehr verständlich geschrieben, so dass es jeder deutsche Serverbetreiber anwenden kann.

Link to comment
Share on other sites

  • 4 weeks later...

  • Group:  Members
  • Topic Count:  28
  • Topics Per Day:  0.01
  • Content Count:  562
  • Reputation:   152
  • Joined:  02/21/12
  • Last Seen:  

Durfte es ja vorher schon lesen, Finde ich gut das du solche Dinge als Lernprozess verwendest.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...