packer : ReadLong=PeekL ????

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

packer : ReadLong=PeekL ????

Message par Thyphoon »

Bonjour,

Apres quelques heures de recherche et autant d'essaie je me décide a poster sur le forum. J'explique
j'ai fait un fichier via le code suivant :

Code : Tout sélectionner

      If CreateFile(0,NomFichier$)
      WriteStringN(NomTableau$) 
      Debug("Nom:"+NomTableau$)
      WriteLong(TablL)
      WriteLong(TablH)
      WriteLong(Thepaysagetype)
      WriteLong(Picture_Front)  
        ;Debug "save"
        For c=0 To 4
          For zx=0 To TablL
            For zy=0 To TablH
              WriteLong(Map(c,zx,zy)) 
            Next
          Next
        Next
        WriteLong(NbObjet)
        For z=1 To NbObjet
         WriteLong(Objet_Anim(z))
         WriteLong(Objet_X(z))
         WriteLong(Objet_Y(z))
         WriteLong(Objet_Mode(z))
         WriteStringN(Objet_Info(z)) 
        Next
        CloseFile(0)
      EndIf
Ensuite ce fichier est packer avec la commande CreatePack puis AddPackFile. Bref jusque là rien de compliqué mon problème vient que je voudrais récupéré ces données directement en mémoire !
donc pour l'instant voilà ce que je fais

Code : Tout sélectionner

OpenPack("data/level/000.dat")
 AdresseMemoire = NextPackFile()
  NomTableau$=PeekS(AdresseMemoire)
  Debug(NomTableau$)
  TablL=PeekL(AdresseMemoire+Len(NomTableau$) +1)
  Debug(Str(TablL))

mais ça ne me donne pas vraiment les bon resultat !
j'ai bien lu tout ce qui a été dit par Comtoie, Denis, Chris ... si j'ai bien compris certain truc ..j'avoue que les notions de pointeur je maitrise pas trop ... est ce que mon Adressememoire fonctionne comme un pointeur ou pas ? Est ce que je suis sur la bonne voie ?
merci d'avance !!

A oui j'oubliais le moteur de mon jeu avance bien ...une demo sera prochainement téléchargeable spécialement pour les membres du forum qui m'on tant aider ! :P
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

la taille du tableau en mémoire dépend du format des valeurs qu'il contient et de sa longeur

Si on fait tableau comme suit

Code : Tout sélectionner

Dim Tableau.l(50, 20)
donc on a @Tableau() qui renvoie la position du tableau en mémoire
et la taille du tableau est à calculer comme ça :

Code : Tout sélectionner

(50 + 1) * (20 + 1) * 4
50 + 1 correspond au nombre de ligne du tableau (+1 car on commence le tableau à 0 et pas à 1). de même pour 20 + 1
4 correspond à la taille en octects de la variable qui est ici un long donc sur 4 octects

ensuite, il suffit d'utiliser un copymemory() pour le remplir.

Code : Tout sélectionner

CopyMemory(Source, @Tableau(), (50 + 1) * (20 + 1) * 4)
PS : N'oublie pas de décompresser les données avant de les copier :roll:
Dernière modification par Le Soldat Inconnu le mar. 21/sept./2004 17:38, modifié 1 fois.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

merci beaucoup !!!ça c'est de l'info interessante ... :o) Bon aller je retourne testé ça !
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

heuuuu question idiote c'est bien comme ça pour decompresser en mémoire ?

Code : Tout sélectionner

OpenPack("data/level/000.dat")
 AdresseMemoire = NextPackFile()
 *Target = AllocateMemory(PackFileSize()+8)
 UnpackMemory(AdresseMemoire, *Target) 
Chez moi ça plante mechant :( Bon je continue a chercher... :P
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Thyphoon a écrit :heuuuu question idiote c'est bien comme ça pour decompresser en mémoire ?

Code : Tout sélectionner

OpenPack("data/level/000.dat")
 AdresseMemoire = NextPackFile()
 *Target = AllocateMemory(PackFileSize()+8)
 UnpackMemory(AdresseMemoire, *Target) 
Chez moi ça plante mechant :( Bon je continue a chercher... :P
OpenPack ouvre un fichier compressé

AdresseMemoire = NextPackFile() -->

Code : Tout sélectionner

Lit et décompresse le prochain fichier trouvé dans le Pack courant, préalablement ouvert avec OpenPack(). AdresseMemoire est partagée et ne devrait jamais être libérée par le programmeur. Pour connaître la taille mémoire utilisée (ex: la taille du fichier décompressé), utilisez PackFileSize(). 
donc l'ensemble est décompressé en mémoire, il ne faut donc pas utiliser UnpackMemory qui
Décompresse une zone mémoire préalablement compressée (avec PackMemory()) vers la zone MemoireDestination.
Ce n'est pas le cas.


Sinon l'instruction

Code : Tout sélectionner

WriteStringN(NomTableau$)
va écrire dans le fichier la chaine sans le 0 de terminaison suivi des codes ASCII OA et OD

OA --> line field --> saut de ligne
OD --> carriage return --> retour chariot

pour lire les données utiles après la chaine tu dois ajouter 2 à la longueur de la chaine pour tomber sur la bonne valeur

Code : Tout sélectionner

TablL=PeekL(AdresseMemoire+Len(NomTableau$) +2)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Super ça marche !! Merci a tous !!! :)
parcontre j'ai trouvé des différences par rapport a ce que vous m'avez indiquer entre autre pour calculer la valeur apres une chaine !
denis m'vait dit de faire :
TablL=PeekL(AdresseMemoire+Len(NomTableau$) +2)
or pour que ça marche j'ai du faire un
AdresseMemoire+Len(NomTableau$)-1
sinon ça ne fonctionnait pas. enfin je vous donne le debut de mon code qui fonctionne ça peut peut être servir a d'autre ;)
voici ce que ça donne

Code : Tout sélectionner

Adr = NextPackFile()
    NomTableau_tmp$ =PeekS(Adr) ;  lecture du nom brut
    NomTableau$=Mid(NomTableau_tmp$, 1, (Len(NomTableau_tmp$)-3) ) ; je supprime les caractères indésirable
    Adr = Adr + Len(NomTableau_tmp$) - 1 ;calcul de l'adresse de la variable suivante
    TablL = PeekL(Adr) : Adr = Adr + 4; lecture de la variable TablL
    TablH = PeekL(Adr) : Adr = Adr + 4
    Thepaysagetype = PeekL(Adr) : Adr = Adr + 4
    Picture_Front = PeekL(Adr) : Adr = Adr + 4
Dans tout les cas un grand merci pour votre aide !
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Je vais regarder de plus près car je me suis rendu compte que la chaine stockée par writestringN n'étant pas terminé par un 0, PeekS ne devrait pas fonctionner correctement puisqu'il me semble que PeekS cherche le code ASCII 0 comme caractère de terminaison de chaine.

La chaine stockée par WriteStringN étant terminé par 0A, 0D (utiliser un éditeur hexa pour vérifier), on doit bien avoir un déplacement de + 2 par rapport à la longueur de la chaîne non brute. Effectivement par rapport à la chaine brute, elle comporte au moins le 0A et 0D en plus, mais je me demande si ce n'est pas un pur hasard que PeekS fonctionne.

Je suis curieux de voir la chaine retournée par PeekS.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Salut denis ! si tu veux mon code avec les données pour fair les essais n'hesite pas a me le demander !
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

C'est bien ce que j'avais subodoré. Ton code marche car tu as de la chance.

Essaye de changer ta ligne

Code : Tout sélectionner

   WriteLong(TablL)
par WriteLong(0) ou par WriteLong(3149642683)

Tu n'auras pas les bons résultats.

Voilà comment ça se passe en détail.

WriteStringN stocke toutes les lettres de la chaine et ajoute les CR, LF (0D, 0A) à la fin puis ensuite écrite le writeLong(TablL)

WriteLong est donc une valeur sur 32 bits soit en hexadecimal une valeur comprise entre 00000000 et FFFFFFFF

Or l'utilisation de PeekS comme le dit la doc PB va lire toute les octets en suivant jusqu'à trouver un 0 qui indique la fin de chaine. PeekS retournera de toute façon la chaine + les 2 caractère 0D et 0A, ensuite tout dépend ou se situe le 0 de fin de chaine qui dépend de la valeur numérique de ta variable.

Donc tu as de la chance!

Maintenant la solution passe par l'écriture d'un 0 de fin de chaine dans ton fichier avant de le compacter. C'est assez simple.

On utilise WriteString au lieu de WrintStringN, car WriteString n'ajoute rien après la chaine, puis on écrit le 0 de fin de chaine derrière avec un simple WriteByte(0) et le tour est joué.

Après, on utilise PeekS sans avoir à modifier quoi que ce soit si ce n'est le pointeur d'adresse.
Chaque fois que tu écrit une chaine dans le fichier, utilise ce procédé (tu écrit 2 chaines dans ton code).

la sauvegarde du tableau devient :

Code : Tout sélectionner

;  ;sauvegarde du tableau
  Procedure Savetableau (NomFichier$)
   If CreateFile(0, NomFichier$)

     WriteString(NomTableau$)      <-- modifié
     WriteByte(0)                     <-- ajouté

     Debug("Nom:" + NomTableau$)
     WriteLong(TablL)
     WriteLong(TablH)
     WriteLong(Thepaysagetype)
     WriteLong(Picture_Front)
     For c = 0 To 4
       For zx = 0 To TablL
         For zy = 0 To TablH
           WriteLong(Map(c, zx, zy))
         Next
       Next
     Next
     WriteLong(NbObjet)
     For z = 1 To NbObjet
       WriteLong(Objet_Anim(z))
       WriteLong(Objet_X(z))
       WriteLong(Objet_Y(z))
       WriteLong(Objet_Mode(z))

       WriteString(Objet_Info(z))      <-- modifié
       WriteByte(0)                     <-- ajouté
     Next
     CloseFile(0)
   EndIf
 EndProcedure

et la procédure chargement du tableau packer devient

Code : Tout sélectionner

Procedure Loadtableaupack(NomFichier$)
  res = FileSize("data/level/" + NomFichier$)
  If res > 0
    OpenPack("data/level/" + NomFichier$)
    Adr = NextPackFile()
    NomTableau =PeekS(Adr)
    Adr + Len(NomTableau$) + 1
    TablL = PeekL(Adr) : Adr = Adr + 4
    TablH = PeekL(Adr) : Adr = Adr + 4
    Thepaysagetype = PeekL(Adr) : Adr = Adr + 4
    Picture_Front = PeekL(Adr) : Adr = Adr + 4
    For c = 0 To 4
      For zx = 0 To TablL
        For zy = 0 To TablH
          Map(c, zx, zy) = PeekL(Adr) : Adr = Adr + 4
        Next
      Next
    Next
    NbObjet = PeekL(Adr) : Adr = Adr + 4
    For z = 1 To NbObjet
      Objet_Anim(z) = PeekL(Adr) : Adr = Adr + 4
      Objet_X(z) = PeekL(Adr) : Adr = Adr + 4
      Objet_Y(z) = PeekL(Adr) : Adr = Adr + 4
      Objet_Mode(z) = PeekL(Adr) : Adr = Adr + 4
      Objet_Info(z) = PeekS(Adr) : Adr +  Len(Objet_Info(z)) + 1
    Next
    ClosePack()
    EndIf
 EndProcedure
fais des tests et dis-moi
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Merci ! Super ! Je vais testé ça de suite ... :o)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Super ça marche Nickel !!! :P
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Dans le morceau de code que tu m'as envoyé, il y avait une procedure

Code : Tout sélectionner

; Procedure Loadtableau (NomFichier$)
que je n'ai pas modifié car je n'ai pas vu son utilité, car si on charge le tableau sans être compressé, à quoi sert cette de compresser le tableau ?

D'ailleurs, elle ne fonctionne plus avec le code que j'ai posté.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

si elle me sert car lorsque je developpe je travaille avec les fichiers séparé ! tandis que lorsque le truc est prêt je pack les fichiers ! c'est plus simple (c'est au niveau de mon editeur de niveau)
Mais j'ai testé et ça fonctionne ...pour l'instant !!!
En tout cas merci
Répondre