IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Problème lecture de fichier binaire


Sujet :

C#

  1. #1
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut Problème lecture de fichier binaire
    Bonjour à tous,

    J'aimerais parser un fichier BSP (map Quake3) mais je ne sais pas du tout comment m'y prendre.

    J'ai :
    - la structure du fichier,
    - un exemple en python (recherche de textures utilisées):

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    import sys
    import construct as cs
     
    class _VMod4(cs.Validator):
        def _validate(self, obj, ctx):
            return obj % 4 == 0
     
    _bsp_f = cs.Struct('bsp',
                       cs.Struct('header',
                                 cs.OneOf(cs.String('magic', 4, encoding=None, padchar='\x00'), ["IBSP"]),
                                 cs.OneOf(cs.SLInt32('version'), [46]),
                                 cs.Array(17,
                                          cs.Struct('direntry',
                                                    cs.SLInt32('offset'),
                                                    _VMod4(cs.SLInt32('length')),
                                                   ),
                                          ),
                                ),
                       cs.Pointer(lambda ctx : ctx.header.direntry[1].offset,
                                  cs.MetaRepeater(lambda ctx : ctx.header.direntry[1].length / 72,
                                                  cs.Struct('texture',
                                                            cs.String('name', 64, encoding=None, padchar='\x00'),
                                                            cs.SLInt32('flags'),
                                                            cs.SLInt32('content'),
                                                           ),
                                                 ),
                                 ),
     
                       )
     
     
    def main():
        if len(sys.argv) < 2:
            print 'usage : python bsp.py map.bsp'
            exit(1)
     
        input = open(sys.argv[1], 'r')
        bsp = _bsp_f.parse(input.read())
        print "\n".join(t.name for t in bsp.texture)
        input.close()
     
    if __name__ == '__main__':
        main()

    - un fichier BSP.

    Merci pour votre aide.

  2. #2
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut Lire un fichier binaire connaissant le format
    Bon bah j'ai un peu avancé mais je bloque toujours dans la lecture de ce fichier.
    Je reviens vers vous car je suis désormais capable de préciser ma question.

    Toujours avec l'aide de ce document, je parviens à lire les valeurs des variables "magic" et "version" du header mais pas le reste.

    Voici ma méthode de lecture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
            /// <summary>
            /// Load a bsp file into a bsp object
            /// </summary>
            /// <param name="file">Path to the bsp file</param>
            /// <returns>Bsp object</returns>
            public static Bsp Load(string file)
            {
                BinaryReader br = new BinaryReader(File.OpenRead(file));
                br.BaseStream.Seek(0, SeekOrigin.Begin);
     
                Bsp bsp = new Bsp();
                //header
                bsp.header = new Header();
                bsp.header.magic = br.ReadChars(4);
                bsp.header.version = br.ReadInt32();
     
                //direntries
                for (int i = 0; i < 17; i++)
                {
                    int offset = br.ReadInt32();
                    int length = br.ReadInt32();
                    //if (length % 4 != 0) length = 0;
                    bsp.header.direntries[i] = new Direntry(offset, length);
                }
     
                //lump 0 - entities
                br.BaseStream.Seek(bsp.header.direntries[0].offset, SeekOrigin.Current);
                Entity ent = new Entity();
                ent.ents = br.ReadChars(bsp.header.direntries[0].length);
     
     
                //lump 1 - textures
                br.BaseStream.Seek(bsp.header.direntries[1].offset, SeekOrigin.Current);
                Texture text = new Texture();
                text.name = br.ReadChars(bsp.header.direntries[1].length);
                text.flags = br.ReadInt32();
                text.contents = br.ReadInt32();
     
                br.Close();
     
                return bsp;
            }
    Si quelqu'un pouvait m'aider à déchiffrer les spécifications détaillées du fichier ca serait cool

  3. #3
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    La lecture des DirEntries me parait aussi correcte.

    La doc spécifiant que les Offset sont relatives au début du fichier, il faudrait utiliser des Seek() avec SeekOrigin.begin au lieu de SeekOrigin.Current.

  4. #4
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Salut Graffito!

    Oui tu as raison pour le SeekOrigin.Begin. J'ai finalement réussi à lire les 3 premiers lumps sur les 17 au total. J'ai compris comment faire grâce à des codes en c (comme celui-la).

    Voici ma fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
            /// <summary>
            /// Load a bsp file into a bsp object
            /// </summary>
            /// <param name="file">Path to the bsp file</param>
            /// <returns>Bsp object</returns>
            public static Bsp Load(string file)
            {
                BinaryReader br = new BinaryReader(File.OpenRead(file));
                br.BaseStream.Seek(0, SeekOrigin.Begin);
     
                Bsp bsp = new Bsp();
                //header
                bsp.Header = new Header();
                bsp.Header.Magic = br.ReadChars(4);
                bsp.Header.Version = br.ReadInt32();
     
                //direntries
                br.BaseStream.Seek(8, SeekOrigin.Begin);
                for (int i = 0; i < 17; i++)
                {
                    int offset = br.ReadInt32();
                    int length = br.ReadInt32();
                    //if (length % 4 != 0) length = 0;
                    bsp.Header.Direntries[i] = new Direntry(offset, length);
                }
     
                //lump 0 - entities
                br.BaseStream.Seek(bsp.Header.Direntries[0].Offset, SeekOrigin.Begin);
                bsp.Entity = new Entity();
                bsp.Entity.Ents = br.ReadChars(bsp.Header.Direntries[0].Length);
     
     
                //lump 1 - textures
                bsp.Textures = new List<Texture>();
                int sizeTexture = (new Texture().Size()) * 6;
                for (int i = 0; i < bsp.Header.Direntries[1].Length / sizeTexture; i++)
                {
                    br.BaseStream.Seek(bsp.Header.Direntries[1].Offset + i * sizeTexture, SeekOrigin.Begin);
                    Texture t = new Texture();
                    t.Name = br.ReadChars(64);
                    t.Flags = br.ReadInt32();
                    t.Contents = br.ReadInt32();
                    bsp.Textures.Add(t);
                }
     
                //lump 2 - planes
                bsp.Planes = new List<Plane>();
                int sizePlane = (new Plane().Size()) * 6;
                for (int i = 0; i < bsp.Header.Direntries[2].Length / sizePlane; i++)
                {
                    br.BaseStream.Seek(bsp.Header.Direntries[2].Offset + i * sizePlane, SeekOrigin.Begin);
                    Plane p = new Plane();
                    p.Normal = new float[3];
                    for (int j = 0; j < 3; j++)
                        p.Normal[j] = br.ReadSingle();
                    p.Dist = br.ReadSingle();
                    bsp.Planes.Add(p);
                }
     
     
                br.Close();
     
     
                return bsp;
            }
    Je n'ai plus qu'à répéter le même code pour les 14 lumps suivant, ce qui ne devrait plus être difficile.

    A la base je voulais juste chercher les textures utilisées dans la map mais je pense que je vais compléter le projet afin d'en faire une DLL pour un autre projet. Pour ceux qui auraient des questions ou qui seraient intéressé par les classes, n’hésitez pas à me demander.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème lecture de fichier / décalage et masquage binaire
    Par Lysan dans le forum Général Python
    Réponses: 2
    Dernier message: 28/07/2013, 17h27
  2. Problème de lecture de fichiers binaires
    Par -Gesicht- dans le forum Débuter
    Réponses: 7
    Dernier message: 05/07/2013, 17h15
  3. Réponses: 7
    Dernier message: 31/10/2010, 15h39
  4. probléme lecture de fichier binaire octer par octet
    Par ousmanesidibe dans le forum C++
    Réponses: 2
    Dernier message: 12/12/2009, 21h34
  5. Réponses: 5
    Dernier message: 26/03/2007, 01h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo