Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Jo

Frischling

  • »Jo« ist der Autor dieses Themas
  • Private Nachricht senden

1

27.04.2005, 19:20

3ds Chunks durchlaufen

Ich hab eine 3ds-Datei und will jetzt einfach alle Chunks durchlaufen. Ich habs mal so probiert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
    if ((m_pFile=fopen(cFileName, "rb"))==NULL) {return E_FAIL;}
    
    dsChunk Chunk;

    while (!feof(m_pFile))
    {
        fread(&Chunk, sizeof(dsChunk), 1, m_pFile);

        fseek(m_pFile, Chunk.Size - sizeof(dsChunk), SEEK_CUR);
    }
    return S_OK;

Irgenwie klappt es aber nicht. Der erste Chunk ist ja ein Mainchunk, also 0x4D4D. Das stimmt auch. Aber um zum nächsten Chunk zu kommen, nehme ich jetzt einfach die größe des Chunks. Leider ist die Zahl größer als die Datei lang ist. Ich hab dsChunk so definiert:

C-/C++-Quelltext

1
2
3
4
5
struct dsChunk
    {
        WORD ID;
        DWORD Size;
    };

Kann mir jemand den Fehler zeigen, ich finde ihn einfach nicht.

Dave

Alter Hase

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

2

27.04.2005, 20:28

um zum nächsten chunk zu kommen darfst du den hauptchunk nicht überspringen, sondern musst ihn verarbeiten. das sieht ungefähr so aus:

Quellcode

1
2
3
4
5
 + Hauptchunk
    |
    |----- irgendwelche andere (material, oder objekt chunks)
    |
    |----- irgendwelche andere (material, oder objekt chunks)


die anderen chunks sind dem hauptchunk also untergeordnet und somit in seine größe mit inbegriffen. du müsstest direkt nachdem du den chunkheader des haupchunks eingelesen hast gleich nochmal nen header lesen, ohne den lesezeiger zu versetzen.

Jo

Frischling

  • »Jo« ist der Autor dieses Themas
  • Private Nachricht senden

3

28.04.2005, 18:22

Ich habs jetzt mal so probiert:

C-/C++-Quelltext

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
if ((m_pFile=fopen(cFileName, "rb"))==NULL) {return E_FAIL;}
    
    dsChunk Chunk;
    ZeroMemory(&Chunk, sizeof(dsChunk));

    while (!feof(m_pFile))
    {
        fread(&Chunk, sizeof(dsChunk), 1, m_pFile);

        switch(Chunk.ID)
        {
        case MAIN3DS:
            {
                Log.DebugOut("Main 3ds Chunk:%d Size: %d \n", Chunk.ID, Chunk.Size);
                break;
            }
        case EDIT3DS:
            {
                Log.DebugOut("Edit 3ds Chunk:%d Size: %d \n", Chunk.ID, Chunk.Size);
                break;
            }
        case KEYF3DS:
            {
                Log.DebugOut("Keyframe 3ds Chunk:%d Size: %d \n", Chunk.ID, Chunk.Size);
                break;
            }
        default:
            {
                Log.DebugOut("Unknown Chunk:%d Size: %d \n",Chunk.ID, Chunk.Size);
                fseek(m_pFile, (Chunk.Size-sizeof(dsChunk)), SEEK_CUR);
                break;
            }
        }
    }

Aber leider will es immer noch nicht funktionieren. Was Mir seltsam vorkommt ist, dass der Hex-Code der Chunk.Size nicht der im Hex-viewer der Datei entspricht. Dort steht:
4D 4D DB 64 00 00 02 00 0A 00 00 00 03 00 00 00
Und Chunk.ID und Chunk.Size haben diese Werte:
(4D 4D) (00 02 00 00)
Kann mir dies jemand erklären?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

28.04.2005, 20:37

warum eigentlich 3ds!?
imho gibts bessere formate, die noch dazu voll dokumentiert sind...

aber ok, ich will es dir ersparen so zu leiden wie ich damals gelitten hab ;)

die lösung deines problemes nennt sich vermutlich byte alignment...

C-/C++-Quelltext

1
fread(&Chunk, sizeof(dsChunk), 1, m_pFile);


schau mal was sizeof dsChunk is ;)


C-/C++-Quelltext

1
2
fread(&Chunk.ID, sizeof(WORD), 1, m_pFile);
fread(&Chunk.Size, sizeof(DWORD), 1, m_pFile);


funktioniert vermutlich...


wenn du VC++ hast, sollte es z.b. auch so gehn:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
#pragma pack(1)

struct dsChunk 
{
        WORD ID; 
        DWORD Size;
};

#pragma pack()

fread(&Chunk, sizeof(dsChunk), 1, m_pFile);

Jo

Frischling

  • »Jo« ist der Autor dieses Themas
  • Private Nachricht senden

5

29.04.2005, 17:10

Das hab ich dann auch bemerkt, dass sizeof(dsChunk) als Größe 8 ausgibt. Dann hab ich die erste Version auch schon so probiert, wie du es gesagt hast und es hat irgendwie nicht funktioniert. Jetzt hab ich deine zweite Methode ausprobiert und es funktioniert einwandfrei.
Danke Jo

Werbeanzeige