Wie Java-Float lesen?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Re: Wie Java-Float lesen?

Beitrag von Darie »

Unter Doubles verstehe ich Floatvariablen mit höhere Genauigkeit bzw. grosse Zahlen verbunden mit Genauigkeit im Nachkommastellenbereich. Da ist doch soweit richtig, oder? Jedenfalls möchte ich in Minecraft die Spielerposition aus der Player.dat auslesen. Laut Minecraft-Wiki wird die Position mit Doubles im BigEndian Format gespeichert. Wenn ich die Position des Spielers in Minecraft mit meinen ausgelelesen Werten vergleiche so stimmen sie auch, bis auf die Nachkommastellen, überein. Hier ist der Code dazu, das macht es einfacher:

Code: Alles auswählen

; Procedure BSWAP32(value.l)
;   !mov eax, dword [p.v_value]
;   !bswap eax
;   ProcedureReturn
; EndProcedure
; 
; Procedure BSWAP64(value.i)
;   !mov rax, qword [p.v_value]
;   !bswap rax
;   ProcedureReturn
; EndProcedure

Procedure BSWAP_Double(value.q)
 Zahl.q = value.q
 Zahl = ((Zahl&$FF)<<56)+((Zahl&$FF00)<<40)+((Zahl&$FF0000)<<24)+((Zahl&$FF000000)<<8)+((Zahl&$FF00000000)>>8)+((Zahl&$FF0000000000)>>24)+((Zahl&$FF000000000000)>>40)+((Zahl>>56)&$FF)
 Double.d = PeekD(@Zahl)
 ProcedureReturn Double.d
EndProcedure

EnableExplicit

Global World.s = "Alexander"
Global MCPath.s = GetHomeDirectory() + "AppData\Roaming\.minecraft\saves\" + World 

Define tagId.b, tagLen.w, tagStr.s
Define PTag.s = "Pos"
Define *Mem1,*Mem2,*Offset
Define PlayerPosX.d
Define PlayerPosY.d
Define PlayerPosZ.d
Define PTag_Length = StringByteLength(PTag)
Define i


Debug ptag_length
ReadFile(0, GetCurrentDirectory()+"player_gunzipped.dat")
Define Lof = Lof(0) : *Mem1 = AllocateMemory(Lof) : ReadData(0,*Mem1,Lof)
CloseFile(0)

For i = 0 To Lof
If PeekS(*Mem1+i,3,#PB_UTF8) = PTag : *Offset = *Mem1+i : Break : EndIf
Next i

Debug PeekS(*Offset,3,#PB_UTF8)
Debug PeekB(*Offset+PTag_Length)
Debug PeekB(*Offset+PTag_Length+4)

PlayerPosX = BSWAP_Double(PeekQ(*Offset+PTag_Length+5))
PlayerPosY = BSWAP_Double(PeekQ(*Offset+PTag_Length+13))
PlayerPosZ = BSWAP_Double(PeekQ(*Offset+PTag_Length+21))

Debug PlayerPosX
Debug PlayerPosY
Debug PlayerPosZ
Hier die Spielerpositon im Spiel:
Bild

Code+Player.dat
https://dl.dropboxusercontent.com/u/791 ... xport1.zip

Wie gesagt sind die Spielerdaten laut Minecraft-Wiki http://de.minecraftwiki.net/wiki/Player.dat_Format als Doubles gespeichert, vielleicht handelt es sich aber doch nur um normale Floats. Muss ich gleich mal testen.

Darie
Repeat
PureBasic
ForEver
Derren
Beiträge: 558
Registriert: 23.07.2011 02:08

Re: Wie Java-Float lesen?

Beitrag von Derren »

Du liest doch Doubles und kein Floats in deinem Code oder habe ich was übersehen?

Dein offset ist erst 5 dann 13. Dazwischen liegen also 8 byte, also liest du mit Double-Genauigkeit aus (64bit).
Signatur und so
Kevin
Beiträge: 236
Registriert: 11.06.2007 12:55

Re: Wie Java-Float lesen?

Beitrag von Kevin »

Hi,

Code: Alles auswählen

Procedure BSWAP_Double(value.q)
>>
Procedure.d BSWAP_Double(value.q)
mfg kevin
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Re: Wie Java-Float lesen?

Beitrag von Darie »

Hallo ihr,

leider muss ich zugeben, dass ich ohne eure Hilfe mal wieder aufgeschmissen bin: Ich bräuchte nämlich noch die Konvertierung
von Short bzw. Word, Long und Integer (alles 32 Bit). Leider hab ich vom Bitshiften und so keine Ahnung und kanns nicht selber coden.
Was machen eigentlich die folgenden Codes ? Wandeln die nicht auch von LittleEndian nach BigEndian um? Allerdings kommt eine Fehlermeldung beim Kompilieren.

Code: Alles auswählen

Procedure.w BSWAP16(value.w)
!xor eax,eax
!mov ax, word [p.v_value]
!rol ax, 8
ProcedureReturn
EndProcedure

Procedure BSWAP32(value.l)
  !mov eax, dword [p.v_value]
  !bswap eax
  ProcedureReturn
EndProcedure

Procedure BSWAP64(value.i)
  !mov rax, qword [p.v_value]
  !bswap rax
  ProcedureReturn
EndProcedure
Vielen Dank wieder für eurer emsiges Helfen.
Gruss Alexander
Repeat
PureBasic
ForEver
Kevin
Beiträge: 236
Registriert: 11.06.2007 12:55

Re: Wie Java-Float lesen?

Beitrag von Kevin »

Darie hat geschrieben:Hallo ihr,

leider muss ich zugeben, dass ich ohne eure Hilfe mal wieder aufgeschmissen bin: Ich bräuchte nämlich noch die Konvertierung
von Short bzw. Word, Long und Integer (alles 32 Bit). Leider hab ich vom Bitshiften und so keine Ahnung und kanns nicht selber coden.
Was machen eigentlich die folgenden Codes ? Wandeln die nicht auch von LittleEndian nach BigEndian um? Allerdings kommt eine Fehlermeldung beim Kompilieren.

Code: Alles auswählen

Procedure.w BSWAP16(value.w)
!xor eax,eax
!mov ax, word [p.v_value]
!rol ax, 8
ProcedureReturn
EndProcedure

Procedure BSWAP32(value.l)
  !mov eax, dword [p.v_value]
  !bswap eax
  ProcedureReturn
EndProcedure

Procedure BSWAP64(value.i)
  !mov rax, qword [p.v_value]
  !bswap rax
  ProcedureReturn
EndProcedure
Vielen Dank wieder für eurer emsiges Helfen.
Gruss Alexander
Ich mache das so:

Code: Alles auswählen

Procedure ReverseMemory(*memory.Ascii, length)
  Protected i, length2=length/2, *memend.Ascii = *memory + length - 1
  While *memend > *memory
    Swap *memory\a, *memend\a
    *memory + 1
    *memend - 1
  Wend
EndProcedure

q.q = $8877665544332211
l.l = $44332211
w.w = $2211
a.a = $12

Debug Hex(q, #PB_Quad)
Debug Hex(l, #PB_Long)
Debug Hex(w, #PB_Word)
Debug Hex(a, #PB_Ascii)

ReverseMemory(@q, 8)
ReverseMemory(@l, 4)
ReverseMemory(@w, 2)
ReverseMemory(@a, 1)

Debug Hex(q, #PB_Quad)
Debug Hex(l, #PB_Long)
Debug Hex(w, #PB_Word)
Debug Hex(a, #PB_Ascii)
funktioniert auch mit Floats/Doubles
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Re: Wie Java-Float lesen?

Beitrag von Darie »

Echt :allright: Vielen Dank !
Repeat
PureBasic
ForEver
Antworten