PDA

View Full Version : Open a binary file.



TJSonic
22nd July 2010, 17:45
I want to open binary file using Qt. I dave a description of file:


================================================== ===============
IFP file format for Grand Theft Auto III and Vice City animation
Written by Hollower (hollower@hotmail.com)
================================================== ===============
(updated Jan 2004)

This file is intended for programmers only.

First column is the number of bytes. V means that the length varies.
Second column is the suggested data type (C/C++).
Third column is a brief description of the data.
Strings are padded to 4-byte alignment.

This is how I broke up the file for reading in. The section markers
indicate the more "correct" way, but I used this simpler grouping
(ie. why worry about the parent section of "INFO" blocks when they
should always be in this order anyway), and I used the section markers
for error checking. Using my grouping also makes it easier to output
an IFP file that is valid for GTA3/GTA:VC. This may change in future
GTA games.


IFP FILE HEADER
----------------
4 (char[4]) "ANPK" --- section marker
4 (int) Offset to end of file
4 (char[4]) "INFO" --- section marker
4 (int) Offset to end of header
4 (int) Number of anims
V (char[V]) Internal file name (null terminated string)

ANIMATION INFO
----------------
4 (char[4]) "NAME" --- section marker
4 (int) Length of anim name string
V (char[V]) Anim name (null terminated string)
4 (char[4]) "DGAN" --- section marker
4 (int) Offset to end of animation
4 (char[4]) "INFO" --- section marker
4 (int) Offset to first object (usually 8)
4 (int) Number of objects
4 (int) NULL

OBJECT INFO
----------------
4 (char[4]) "CPAN" --- section marker
4 (int) Offset to end of object
4 (char[4]) "ANIM" --- section marker
4 (int) Offset to frame info (usually 48)
28 (char[28]) Object name (null terminated string, padded to 28 bytes)
4 (int) Number of frames
4 (int) NULL
4 (int) Index of last frame (Number of frames - 1)
4 (int) Index of next sibling (-1 if none)
4 (int) Index of previous sibling (-1 if none)

FRAME INFO
----------------
4 (char[4]) Frame type (see below)
4 (int) Length of frame data

FRAME DATA
----------------
Frame data is all floats. Structure depends on frame type.

Frame types:

"KRT0" Root quaternion rotation (float x,y,z,w),
vector translation (float x,y,z),
time (float seconds)

"KR00" Child rotation, time

"KRTS" Scaled rotation, translation, scale (float x,y,z), time


Root frames contain extra data for translating the model in the
world. Child frames are simply rotations, concatenated as they
go up the hierarchy.

You can probably guess, the letters here stand for
(K)eyframe, ®otation, (T)ranslation, (S)cale, (0)None
so presumably there could also be other combinations like "K0T0" but
the above are the only ones found in all of the files I studied.


Notes
----------------

Overall file structure looks like this:

Header
|
+-Animation
| |
| +-Object
| | |
| | +-Frame
| | +-Frame
| | +-Frame
| | +- ...
| |
| +-Object
| | |
| | +-Frame
| | +-Frame
| | +-Frame
| | +- ...
| |
| +- ...
|
+-Animation
| |
| +-Object
| | |

...and so on.

Object names are a reference to the DFF mesh or bone
which will be rotated with the frame data. The string
is not case sensitive.

An animation does not need to reference every part of a
model, only the ones that will move. They also do not
require an equal number of frames or matching time index.

There are sometimes anomalies like anims with 0 objects
or objects with 0 frames.

For reference, the base pose can be viewed by creating
animations with Rotation = {0.0f, 0.0f, 0.0f, 1.0f}.



I hope this file has been helpful. Now let's see some editors!

- Hollower


Ok, how to open it??

My code:


QString str = QFileDialog::getOpenFileName(0, "Open IFP", "", "*.ifp");
QFile file(str);
if(file.open(QIODevice::ReadOnly)) {
QDataStream stream(&file);
qDebug() << stream;


What i must do next??

wysota
22nd July 2010, 17:54
Surely you can't use QDataStream.

TJSonic
22nd July 2010, 18:14
But what should i use?

squidge
22nd July 2010, 19:07
I'd probably use 'map', but you could use 'read', since your reading the file.

TJSonic
22nd July 2010, 19:22
So, what command i must use? Can anyone writean example?

wysota
22nd July 2010, 19:37
So, what command i must use?
QFile::read(), as already said.


Can anyone writean example?
Read the docs for QFile.

Small print: Actually we do know what you are asking for and we're just playing stupid until you are sure if you really want us to write a parser for your file structure (you don't want us to do it, I assure you).

TJSonic
22nd July 2010, 19:58
Ok, can you tel me, how for example read firs section of file and convert in to QString?:)

squidge
22nd July 2010, 20:20
I think I'd prefer to use a QByteArray rather than a QString, considering the binary nature of the file, and you can see from the documentation how to read into a QByteArray.

You can then even convert the tags, such as 'ANPK' to quint32 and compare them that way instread, which is properly what the original designer intended, or cast to an appropriate struct.

Lykurg
22nd July 2010, 20:21
Ok, can you tel me, how for example read firs section of file and convert in to QString?:)
I could! ...but I wont. :p

Read the suggested part of the documentation and your description file and put 1 and 1 together.

(If you ask more detailed question, we will help further.)


Edit: too late.

TJSonic
22nd July 2010, 20:44
void MainWindow::on_action_IFP_triggered()
{
QString str = QFileDialog::getOpenFileName(0, "Open IFP", "", "*.ifp");
QFile file(str);
// QFile::map()
if(file.open(QIODevice::ReadOnly)) {
QByteArray line = file.readLine();
qDebug() << line;
}
}


I recived "ANPKin"
I do this right?

squidge
22nd July 2010, 21:00
You do realise what readLine does, right?

The hint is in the name.

TJSonic
22nd July 2010, 21:06
As i anderstand it reads fil line and goes no next, right? In this case why next line shows "NA" when in hex we have

00000000:41 4e 50 4b ec f1 15 00 49 4e 46 4f 0b 00 00 00 ANPKмс..INFO....
00000010:02 00 00 00 63 6e 74 5f 31 61 00 dc 4e 41 4d 45 ....cnt_1a.ЬNAME
00000020:08 00 00 00 43 53 70 68 69 6c 00 44 47 41 4e ....CSphil.DGAN :confused:



QByteArray line = file.readLine();
QString line1 = file.readLine();
QByteArray line2 = file.readLine();
QByteArray line3 = file.readLine();
QByteArray line4 = file.readLine();
QByteArray line5 = file.readLine();
// process_line(line);
qDebug() << line << line1;
qDebug() << line1;
qDebug() << line2;
qDebug() << line3;
qDebug() << line4;
qDebug() << line4;


I recive :
"ANPKin
"NA"
"A???f?¶eI?o®NADjuA?u?????°?x=lK????f? I??·NAKruAAµ??"""?^a~=»?¤?5??¬TI?EANAzuA`I??«?*???=A ????_?°uH?WCNA??uA˜?C?333?? ?=µ?????? H?CNA?uA?&E??»;?*9~=3U??cq??8H?"ANA\?uA
"?AUuA?E??DDA??O?=?'??3$?+µB?#oIAjOuAXe????E? µ??=©0???[$?¤?B?uOIAoOuA`??III?*7?=?O??rE$?=B??IAIuA ??N?C??=?c˜?qs%?)?A?p?IA§EuA U??UUO???=?u??u-&??'A?r|IAA?uA?G????U? e~=Ak???¬&?u?@?Y`IA??uAi???YY?Zx=
???E2'?]h@?ACIAg±uAaL??""a?0q=(???e'??a??m*IAI¤uA?8??ff??¤ j=?Q??Pz(?Ev??:IA??uA`??«?e??ve=o%??e*(?WX??. uIA¦?uAoE??iii?oeb=}????(?R??}aIA?uA?'??33o? ?d=n????(??<???IIAa?uAP°??ww??µRk='R???A(?)7??Z»IA??u AF»??»u?v?n=/4??`A(?o,??y©IAE©uA0?»?
"@®._=?1|??)????nIAo?uA0?»?II @A?]=? {?/?(?oB??
bIAGCuApe??ii@? a=LA?©?(?A~???[IA?OuA »?@?¶c=z???eb(?????VIA1UuAAC»?33@AAa =??Au'?(y??vKIANYuAe??UU@?o^=? ??W?'??h@?CIA??uAa}??ww@??]=j?L'?;?@?UBIA;auA(?????@Xg\=M?}?WQ'?E?@?IIIA} auAo>???»@µ9[=iH|?iZ'?±?@?
OIA0auA?»???Y@*Z=Y{?4O'??¤@? TIA#auAE???
"@®._=?1|??)????nIAo?uA0?»?II @A?]=? {?/?(?oB??
bIAGCuApe??ii@? a=LA?©?(?A~???[IA?OuA »?@?¶c=z???eb(?????VIA1UuAAC»?33@AAa =??Au'?(y??vKIANYuAe??UU@?o^=? ??W?'??h@?CIA??uAa}??ww@??]=j?L'?;?@?UBIA;auA(?????@Xg\=M?}?WQ'?E?@?IIIA} auAo>???»@µ9[=iH|?iZ'?±?@?
OIA0auA?»???Y@*Z=Y{?4O'??¤@? TIA#auAE???

wysota
22nd July 2010, 21:21
Hint: binary files have no "lines", so readLine() will stop reading at a random place (or exactly when it enounters a \n character).

I suggest you take a piece of paper and write down a concept of how you intend to process the file step by step (the specification in the first post is all help you need). Only then sit down in front of your computer and start implementing it.

squidge
22nd July 2010, 22:32
Like I got told on the first day of my employment induction "Projects are typically 80% documentation and research, and 20% coding." and it's true. There's no point randomly coding stuff and hoping it'll work. Figure it all out first then code it.