2
0
mirror of https://github.com/dpethes/rerogue.git synced 2025-06-07 18:58:32 +02:00

hob parser: parse face groups

This commit is contained in:
dpethes 2014-10-12 19:37:48 +02:00
parent 2dc280bb65
commit 51a5b14b18
2 changed files with 126 additions and 62 deletions

View File

@ -1,22 +1,22 @@
4B entity_count. 0 in empty files, 1 for single objects, N>1 in opkg.hob files 4B entity_count. 0 in empty files, 1 for most single objects, N>1 in opkg.hob files
4B simple offset to vertices/faces - doesn't work all the time. Probably useless? 4B simple offset to vertices/faces - doesn't work all the time. Probably useless?
16B name 16B name
4B facegroups offset 4B facegroups offset
4B always 0x7C 124 4B int ? 0x7C,
4B int 0x88, 0xA8 4B int ? 0x88, 0xA8
12B zero? 12B zero?
4B 94, 0xD4 4B int ? 94, 0xD4
4B 98, 0x100 4B int ? 98, 0x100
4B 9C, 0x104 4B int ? 9C, 0x104
4B float: 4B float ?:
-bark_moon, cldcar: 1.0 -bark_moon, cldcar: 1.0
-sky, e_cor: 0.2 -sky, e_cor: 0.2
-wmvwing: 1.25 -wmvwing: 1.25
12B zero 12B zero
5x4B floats 5x4B floats ?
4B int / bark_moon, e_cor, towc: 0xA = 10 4B int ? -bark_moon, e_cor, towc: 0xA = 10
6x 4B float 6x 4B float ?
2B number of facegroups? NOF 2B number of facegroups? NOF
2B number of facegroups? NOF 2B number of facegroups? NOF
@ -27,7 +27,7 @@ facegoup definitions
4B 0xFFFFFFFF header end marker 4B 0xFFFFFFFF header end marker
NOF * facegroup/meshdef0 { NOF * facegroup/meshdef0 132B {
4B int 4B int
4B int 4B int
4B int 4B int
@ -54,12 +54,12 @@ NOF * facegroup/meshdef1 96B {
52B zero 52B zero
} }
NOF * face definition NOF * face block
{ {
8B zero 8B zero
4B int filepos + 4 4B int filepos + 4
4B int face count FC 4B int face count FC
FC * face block FC * face
{ {
4B int ? 4B int ?
1B int 46/49/4B 1B int 46/49/4B

View File

@ -16,17 +16,31 @@ type
indices: array[0..3] of word; indices: array[0..3] of word;
end; end;
THobFile = record THobFaceGroup = record
name: array[0..15] of byte; meshdef1_offset: integer;
face_block_offset: integer;
face_block_end_offset,
face_block_offset,
vertex_block_offset: integer;
face_count: integer; face_count: integer;
faces: array of THobFace; faces: array of THobFace;
vertex_count: integer; vertex_count: integer;
vertices: array of record vertices: array of record
x, y, z, unknown: smallint; //+-2^15 x, y, z, unknown: smallint; //+-2^15
end; end;
end; end;
THobFile = record
name: array[0..15] of byte;
face_group_offset: integer;
face_group_count: integer;
face_group_count0: integer;
face_groups: array of THobFaceGroup;
end;
function ParseHobFile(const fname: string): THobFile; function ParseHobFile(const fname: string): THobFile;
//************************************************************************************************** //**************************************************************************************************
@ -43,17 +57,27 @@ begin
end; end;
end; end;
procedure ReadFaces(var hob: THobFile; var f: TMemoryStream); procedure ReadFaces(var group: THobFaceGroup; var f: TMemoryStream);
var var
face_count: integer;
i, k: integer; i, k: integer;
face: THobFace; face: THobFace;
unknown: integer; unknown: integer;
file_pos: integer; file_pos: integer;
begin begin
face_count := hob.face_count; unknown := f.ReadDWord;
SetLength(hob.faces, face_count); if (unknown <> 0) then
for i := 0 to face_count - 1 do begin writeln('unusual file: zero');
unknown := f.ReadDWord;
if (unknown <> 0) then
writeln('unusual file: zero');
file_pos := f.ReadDWord;
if file_pos + 4 <> f.Position then
writeln('unusual file: face start position');
group.face_count := f.ReadDWord;
writeln('faces: ', group.face_count);
SetLength(group.faces, group.face_count);
for i := 0 to group.face_count - 1 do begin
file_pos := f.Position; file_pos := f.Position;
face.dw1 := f.ReadDWord; //? face.dw1 := f.ReadDWord; //?
face.b1 := f.ReadByte; //46/49/4B face.b1 := f.ReadByte; //46/49/4B
@ -69,7 +93,7 @@ begin
unknown := f.ReadWord; unknown := f.ReadWord;
if (unknown <> 0) then if (unknown <> 0) then
writeln('unusual file: unknown'); writeln('unusual file: unknown');
face.tex_index := f.ReadWord; face.tex_index := f.ReadWord;
write(' ti: ', face.tex_index); write(' ti: ', face.tex_index);
@ -84,16 +108,65 @@ begin
//read rest of the face block //read rest of the face block
write(' rest: '); write(' rest: ');
for k := f.Position to file_pos + face.bsize - 1 do begin for k := f.Position to file_pos + face.bsize - 1 do begin
write(f.ReadByte: 4); unknown := f.ReadByte;
write(unknown: 4);
end; end;
hob.faces[i] := face;
writeln; writeln;
Flush(stdout);
group.faces[i] := face;
end; end;
end; end;
procedure ReadVertices(var group: THobFaceGroup; var f: TMemoryStream; const vertex_count: integer);
var
i: integer;
begin
SetLength(group.vertices, vertex_count);
for i := 0 to vertex_count - 1 do begin
group.vertices[i].x := f.ReadWord;
group.vertices[i].y := f.ReadWord;
group.vertices[i].z := f.ReadWord;
group.vertices[i].unknown := f.ReadWord;
end;
end;
procedure ReadFaceGroup(var fg: THobFaceGroup; var f: TMemoryStream);
var
filepos: int64;
begin
//save file position before seeking to face/vertex data and restore it, to read next group properly
filepos := f.Position;
//read group/meshdef0
f.Seek(16, fsFromCurrent); //unknown
fg.meshdef1_offset := f.ReadDWord - 4;
writeln('fg meshdef offset:', fg.meshdef1_offset);
//read meshdef1
f.Seek(fg.meshdef1_offset, fsFromBeginning);
fg.face_block_end_offset := f.ReadDWord;
f.Seek(20, fsFromCurrent); //zero
fg.vertex_count := f.ReadDWord;
f.Seek(8, fsFromCurrent); //zero
fg.face_block_offset := f.ReadDWord;
fg.vertex_block_offset := f.ReadDWord;
//faces
writeln('faces at: ', fg.face_block_offset, hexStr(fg.face_block_offset, 4):6);
f.Seek(fg.face_block_offset, fsFromBeginning);
ReadFaces(fg, f);
//vertices
writeln('vertices at: ', fg.vertex_block_offset, hexStr(fg.vertex_block_offset, 4):6);
f.Seek(fg.vertex_block_offset, fsFromBeginning);
ReadVertices(fg, f, fg.vertex_count);
f.Seek(filepos + 132, fsFromBeginning);
end;
function ParseHobFile(const fname: string): THobFile; function ParseHobFile(const fname: string): THobFile;
var var
f: TMemoryStream; f: TMemoryStream;
@ -107,47 +180,38 @@ begin
f := TMemoryStream.Create; f := TMemoryStream.Create;
f.LoadFromFile(fname); f.LoadFromFile(fname);
obj_count := f.ReadDWord; obj_count := f.ReadDWord; //object count
unknown := f.ReadDWord; //sometimes face block start unknown := f.ReadDWord; //sometimes face block start, but useless in general
f.ReadBuffer(hob.name, 16); f.ReadBuffer(hob.name, 16);
hob.face_group_offset := f.ReadDWord;
writeln(NameToString(hob.name)); writeln(NameToString(hob.name));
writeln('objects: ', obj_count); writeln('objects: ', obj_count);
writeln('face group offset: ', hob.face_group_offset);
meshdef_offset := f.ReadDWord; if obj_count = 0 then begin
f.Seek(meshdef_offset + 16, fsFromBeginning); //16B zero result := hob;
exit;
meshdef_offset := f.ReadDWord; end;
f.Seek(meshdef_offset + 32, fsFromBeginning); //32B zero if obj_count > 1 then begin
face_block_offset := f.ReadDWord; writeln('reading failed: cannot read multiple objects yet!');
halt;
//faces end;
f.Seek(face_block_offset + 8, fsFromBeginning); //faceblock start
{ //get face group count
bark_moon: 400 f.Seek(124, fsFromBeginning); //16B zero
428 - 1ky.hob hob.face_group_count := f.ReadWord; //which?
trooper: 840 hob.face_group_count0 := f.ReadWord;
1604 - hvyshut if hob.face_group_count <> hob.face_group_count0 then begin
prbdroid: 756 writeln('reading failed: facegroup counts don''t match!: ', hob.face_group_count, hob.face_group_count0:5);
wmvwng: 1648 halt;
xwing: 18304 end;
}
hob.face_block_offset := f.ReadDWord; //filepos + 4 //read face group defs
hob.face_count := f.ReadDWord; //face count SetLength(hob.face_groups, hob.face_group_count);
ReadFaces(hob, f); f.Seek(hob.face_group_offset, fsFromBeginning);
writeln('filepos: ', f.Position); for i := 0 to hob.face_group_count - 1 do begin
ReadFaceGroup(hob.face_groups[i], f);
//vertices
vertex_count := (f.Size - f.Position) div 8;
SetLength(hob.vertices, vertex_count);
for i := 0 to vertex_count - 1 do begin
hob.vertices[i].x := f.ReadWord;
hob.vertices[i].y := f.ReadWord;
hob.vertices[i].z := f.ReadWord;
hob.vertices[i].unknown := f.ReadWord;
end; end;
hob.vertex_count := vertex_count;
writeln('vertex_count: ', vertex_count);
f.Free; f.Free;
result := hob; result := hob;