TMX Datei mit Base64 Encode richtig decodieren

Probleme beim Erstellen von 3D-Modellen und Texturen, keine Ahnung womit man Musik macht? Dies ist dein Forum.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

TMX Datei mit Base64 Encode richtig decodieren

Beitrag von ccode_new »

Hallo Leute,

erstens wer sich fragt was eine "*.tmx"-Datei ist:

Das ist eine Tilemap-Datei die man mit dem Programm "Tiled" erstellen und verarbeiten kann.

So eine Datei lässt sich sehr gut über die XML-Funktionen parsen.

Die Daten-Sektionen können hierbei in base64 oder csv erstellt werden.

Ein Decodieren von CSV ist hierbei kein Problem, aber wie decodiere ich das "base64" richtig ?

So geht es eigentlich:

(Ausschnitt)

Code: Alles auswählen

Procedure DecodeMap(encoding.s, bdata.s)
  If encoding = "base64"
    *bmap = AllocateMemory(2048)
    Base64Decoder(bdata, *bmap, MemorySize(*bmap))
    pstring.s = ""
    For j = 0 To (tmap\width * tmap\height)-1
      pstring = pstring + Str(PeekB(*bmap)) + ","
      *bmap + 4
    Next j
    Debug pstring
  EndIf
EndProcedure
,aber leider ist die Länge (Endbedingung der For-Schleife) nicht korrekt.
(Es werden aber genau so viele Bytes ausgelesen wie auch bei CSV.
Der Anfang der Bytes(tilenummern) ist auch korrekt, aber nach einigen 100 Bytes(Tilenummern) stimmen die ausgelesenen Tilenummern nicht mehr.)

Warum ?

Was ist die korrekte Länge ?

Da diese Frage für Außenstehende (oder generell Alle) wohl sehr schwer nachvollziehbar ist kommt hier eine Anleitung.

Download/Installation von "Tiled" -> Erstelle eine Map (mit CSV-Darstellung) und die selbe Map (mit Base64 (uncompress)).

Decodiere nun die Base64-Darstellung und vergleiche diese mit der CSV-Darstellung.

Kennt sich hier jemand aus ?
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: TMX Datei mit Base64 Encode richtig decodieren

Beitrag von Bisonte »

zuwenig code um helfen zu können.
Am besten eine "tmx" datei hier einstellen (ist wohl reiner text)
und wie du diese einliest.

Als beispiel führe ich an ... Wieso 2048 Bytes Buffer ? Fragen über Fragen ;)
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: TMX Datei mit Base64 Encode richtig decodieren

Beitrag von ccode_new »

Hallo Bisonte,

es hat sich doch noch nicht erledigt.

Hier ein Beispiel:

Map-Stern(csv)

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" tiledversion="1.1.2" orientation="orthogonal" renderorder="right-down" width="19" height="19" tilewidth="32" tileheight="32" infinite="0" nextobjectid="1">
 <tileset firstgid="1" source="tileset_ice.tsx"/>
 <layer name="Kachelebene 1" width="19" height="19" offsetx="20" offsety="-13">
  <data encoding="csv">
0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,
0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,
0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,
0,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0,0,
1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,
1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,
1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,
0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,
0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,1,1,0,0,0,1,1,0,0,0,1,0,0,0,0,
0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,0,0,0,
0,0,0,1,0,0,0,1,1,0,1,1,0,0,1,1,0,0,0,
0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1,1,0,0,
0,0,1,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,
0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,1,1,0,
1,1,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,1,1,
1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1
</data>
 </layer>
</map>
Map_Stern(base64)

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" tiledversion="1.1.2" orientation="orthogonal" renderorder="right-down" width="19" height="19" tilewidth="32" tileheight="32" infinite="0" nextobjectid="1">
 <tileset firstgid="1" source="tileset_ice.tsx"/>
 <layer name="Kachelebene 1" width="19" height="19" offsetx="20" offsety="-13">
  <data encoding="base64">
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAQAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAA==
  </data>
 </layer>
</map>
(Bei diesem Beispiel funktioniert es aber leider.)

Code: Alles auswählen

Structure TMX_Image
  source.s
  width.i
  height.i
EndStructure

Structure TMX_Data
  encoding.s
  bdata.s
EndStructure

Structure TMX_Tileset
  firstGID.i
  lastGID.i
  name.s
  tileWidth.i
  tileHeight.i
  spacing.i
  margin.i
  image.TMX_Image
  offsetX.i
  offsetY.i
EndStructure

Structure TMX_Layer
  name.s
  width.i
  height.i
  opacity.i
  isVisible.i
  offsetX.i
  offsetY.i
  tdata.TMX_Data
EndStructure

Structure TMX_Map
  orientation.s
  width.i
  height.i
  tileWidth.i
  tileHeight.i
  pixelWidth.i
  pixelHeight.i
  bgColor.s
  x.i
  y.i
EndStructure

Global tmap.TMX_Map
Global Dim tlayer.TMX_Layer(100)
Global Dim tileset.TMX_Tileset(100)

Procedure DecodeMap(encoding.s, bdata.s)
  If encoding = "base64"
    *bmap = AllocateMemory(2048)
    Debug bdata
    Base64Decoder(bdata, *bmap, MemorySize(*bmap))
    pstring.s = ""
    For j = 0 To (tmap\width * tmap\height)-1
      pstring = pstring + Str(PeekB(*bmap)) + ","
      *bmap + 4
    Next j
    Debug pstring
  EndIf
EndProcedure

Procedure ParseTMXFile(*CurrentNode, CurrentSublevel)
  Protected i=0, j=0, k=0, n=0
  If XMLNodeType(*CurrentNode) = #PB_XML_Normal
    If GetXMLNodeName(*CurrentNode) = "map"
      If ExamineXMLAttributes(*CurrentNode)
        While NextXMLAttribute(*CurrentNode)
          Select XMLAttributeName(*CurrentNode)
            Case "orientation"
              tmap\orientation = XMLAttributeValue(*CurrentNode)
              Debug tmap\orientation
            Case "width"
              tmap\width = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\width
            Case "height"
              tmap\height = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\height
            Case "tilewidth"
              tmap\tileWidth = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\tileWidth
            Case "tileheight"
              tmap\tileHeight = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\tileHeight
            Case "pixelwidth"
              tmap\pixelWidth = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\pixelWidth
            Case "pixelheight"
              tmap\pixelHeight = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\pixelHeight
            Case "bgcolor"
              tmap\bgColor = XMLAttributeValue(*CurrentNode)
              Debug tmap\bgColor
            Case "x"
              tmap\x = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\x
            Case "y"
              tmap\y = Val(XMLAttributeValue(*CurrentNode))
              Debug tmap\y
          EndSelect
        Wend
      EndIf
    ElseIf GetXMLNodeName(*CurrentNode) = "tileset"
      If ExamineXMLAttributes(*CurrentNode)
        While NextXMLAttribute(*CurrentNode)
          Select XMLAttributeName(*CurrentNode)
            Case "firstgid"
              tileset(i)\firstGID = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\firstGID
            Case "lastgid"
              tileset(i)\lastGID = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\lastGID
            Case "name"
              tileset(i)\name = XMLAttributeValue(*CurrentNode)
              Debug tileset(i)\name
            Case "tilewidth"
              tileset(i)\tileWidth = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\tileWidth
            Case "tileheight"
              tileset(i)\tileHeight = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\tileHeight
            Case "spacing"
              tileset(i)\spacing = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\spacing
            Case "margin"
              tileset(i)\margin = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\margin
            Case "offsetx"
              tileset(i)\offsetX = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\offsetX
            Case "offsety"
              tileset(i)\offsetY = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\offsetY
          EndSelect
        Wend
      EndIf
      i + 1
    ElseIf GetXMLNodeName(*CurrentNode) = "image"
      If ExamineXMLAttributes(*CurrentNode)
        While NextXMLAttribute(*CurrentNode)
          Select XMLAttributeName(*CurrentNode)
            Case "source"
              tileset(j)\image\source = XMLAttributeValue(*CurrentNode)
              Debug tileset(j)\image\source
            Case "width"
              tileset(i)\image\width = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\image\width
            Case "height"
              tileset(i)\image\height = Val(XMLAttributeValue(*CurrentNode))
              Debug tileset(i)\image\height
          EndSelect
        Wend
      EndIf
      j + 1
    ElseIf GetXMLNodeName(*CurrentNode) = "layer"
      If ExamineXMLAttributes(*CurrentNode)
        While NextXMLAttribute(*CurrentNode)
          Select XMLAttributeName(*CurrentNode)
            Case "name"
              tlayer(k)\name = XMLAttributeValue(*CurrentNode)
              Debug tlayer(k)\name
            Case "width"
              tlayer(k)\width = Val(XMLAttributeValue(*CurrentNode))
              Debug tlayer(k)\width
            Case "height"
              tlayer(k)\height = Val(XMLAttributeValue(*CurrentNode))
              Debug tlayer(k)\height
            Case "opacity"
              tlayer(k)\opacity = Val(XMLAttributeValue(*CurrentNode))
              Debug tlayer(k)\opacity
            Case "isvisible"
              tlayer(k)\isVisible = Val(XMLAttributeValue(*CurrentNode))
              Debug tlayer(k)\isVisible
            Case "offsetx"
              tlayer(k)\offsetX = Val(XMLAttributeValue(*CurrentNode))
              Debug tlayer(k)\offsetX
            Case "offsety"
              tlayer(k)\offsetY = Val(XMLAttributeValue(*CurrentNode))
              Debug tlayer(k)\offsetY
          EndSelect
        Wend
      EndIf
      k + 1
    ElseIf GetXMLNodeName(*CurrentNode) = "data"
      If ExamineXMLAttributes(*CurrentNode)
        While NextXMLAttribute(*CurrentNode)
          Select XMLAttributeName(*CurrentNode)
            Case "encoding"
              tlayer(n)\tdata\encoding = XMLAttributeValue(*CurrentNode)
              Debug tlayer(n)\tdata\encoding
              tlayer(n)\tdata\bdata = RTrim(Trim(Trim(Trim(GetXMLNodeText(*CurrentNode),Chr(13)),Chr(10)),Chr(32)),Chr(61))
              Debug tlayer(n)\tdata\bdata
              DecodeMap(tlayer(n)\tdata\encoding, tlayer(n)\tdata\bdata)
          EndSelect
        Wend
      EndIf
      n + 1
    EndIf
    *ChildNode = ChildXMLNode(*CurrentNode)
    While *ChildNode <> 0
      ParseTMXFile(*ChildNode, CurrentSublevel + 1)      
      *ChildNode = NextXMLNode(*ChildNode)
    Wend        
  EndIf
EndProcedure

FileName$ = OpenFileRequester("Wähle eine TMX-Datei.", "", "tmx files (*.tmx)|*.tmx", 0)
If FileName$ <> ""
  If LoadXML(0, FileName$)
    *MainNode = MainXMLNode(0)      
    If *MainNode
      ParseTMXFile(*MainNode, 0)
    EndIf
  EndIf
EndIf
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: TMX Datei mit Base64 Encode richtig decodieren

Beitrag von ccode_new »

Es hat sich erledigt!

Warum: 2048 Bytes ?

Ja warum eigentlich ?

Code: Alles auswählen

Procedure DecodeMap(encoding.s, bdata.s)
  If encoding = "base64"
    *bmap = AllocateMemory(MemorySize(@bdata))
    Debug bdata
    Base64Decoder(bdata, *bmap, MemorySize(*bmap))
    pstring.s = ""
    For j = 0 To (tmap\width * tmap\height)-1
      pstring = pstring + Str(PeekU(*bmap)) + ","
      *bmap + 4
    Next j
    Debug pstring
  EndIf
EndProcedure
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Antworten