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

add hmt compiler to build custom tiefigher_HMT

This commit is contained in:
dpethes 2014-11-09 14:17:43 +01:00
parent eaa10cba3c
commit acf9b6ebca
4 changed files with 282 additions and 3 deletions

View File

@ -8,6 +8,7 @@ Tools to extract data from Star Wars: Rogue Squadron 3D.
* Image exporter - exports some images to pnm/pgm/tga files (according to their internal format).
* HOB parser - parses mesh data files.
* HMT parser - parses material data files and exports stored textures.
* HMT compiler - builds custom material data files.
* HOB display - utilizes HOB & HMT parsers to view 3d objects used in game. Uses OpenGL and SDL for display & input handling.
Compilation
@ -20,6 +21,7 @@ TODO
-----------
* hmt parser: decode all image subtypes
* hmt compiler: needs some usable interface
* hob parser: parse more header fields
* mesh viewer: reuse hmt & hob parsers to display data
* bundle repack: extract & compile bundle.00x archives

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="hmt_compiler"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<Units Count="2">
<Unit0>
<Filename Value="hmt_compiler.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="..\hmt_parser\hmt_parser.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="hmt_parser"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="hmt_compiler"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\hmt_parser"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,203 @@
program hmt_compiler;
uses
sysutils,
hmt_parser;
var
hmt: THmtFile;
procedure pgm_read(const fname: string; var p: pbyte; var w, h: word);
var
f: file;
c: char;
magic: array [0..1] of char;
s: string;
begin
if not FileExists(fname) then begin
writeln('pgm_read: subor neexistuje: ', fname);
halt;
end;
s := '';
AssignFile (f, fname);
Reset (f, 1);
//precitaj magic id
blockread (f, magic, 2);
if (magic <> 'P5') then begin
writeln (stderr, 'error: bad input type');
halt();
end;
blockread (f, c, 1);
//sirka
blockread (f, c, 1);
while not(c = ' ') do begin
s := s + c;
blockread (f, c, 1);
end;
w := StrToInt(s);
//vyska
s := '';
while not(c in [#10, #13]) do begin
s := s + c;
blockread (f, c, 1);
end;
h := StrToInt(s);
//maxval ignorujeme
repeat blockread (f, c, 1) until (c in [#10, #13]);
//alokuj a nacitaj data
GetMem (p, w * h);
blockread (f, p^, w * h);
CloseFile (f);
end;
procedure Pack8To4bit(const src: PByte; const samples: integer; const dst: PByte);
var
i: Integer;
a, b: byte;
begin
for i := 0 to samples div 2 - 1 do begin
a := src[i * 2];
b := src[i * 2 + 1];
dst[i] := a or (b shr 4);
end;
end;
procedure HmtAddMaterial(const mat_name: string);
var
mat: THmtMaterial;
i: Integer;
begin
mat.hex_a := $a;
mat.type_ := 2;
mat.tex_index := 0;
mat.unknown_float1 := 1.0;
mat.unknown_float2 := 1.0;
for i := 0 to Length(mat_name) do begin
mat.name[i] := byte( mat_name[i+1] );
end;
if mat_name = 'tie_wing' then
mat.type_ := 1;
hmt.material_count += 1;
SetLength(hmt.materials, hmt.material_count);
hmt.materials[hmt.material_count - 1] := mat;
end;
procedure HmtAddTexture(const fname, tex_name: string);
var
w, h: word;
tex: THmtTexture;
i: Integer;
pixbuf: pbyte;
begin
pgm_read(fname, pixbuf, w, h);
tex.image.pixels := getmem(w*h);
Pack8To4bit(pixbuf, w*h, tex.image.pixels);
freemem(pixbuf);
tex.palette_offset := 0;
tex.width := w;
tex.height := h;
for i := 0 to Length(tex_name) do begin
tex.name[i] := byte( tex_name[i+1] );
end;
hmt.texture_count += 1;
SetLength(hmt.textures, hmt.texture_count);
hmt.textures[hmt.texture_count - 1] := tex;
end;
procedure WriteHmt(const fname: string);
var
f: File;
mat: THmtMaterial;
tex: THmtTexture;
i, k: Integer;
zero: integer;
texdata_offset: integer;
texformat: array[0..3] of byte;
alpha: longword;
begin
hmt.texture_offset := hmt.material_count * 36 + 8;
zero := 0;
AssignFile(f, fname);
Rewrite(f, 1);
BlockWrite(f, hmt.material_count, 4);
BlockWrite(f, hmt.texture_offset, 4);
for i := 0 to hmt.material_count - 1 do begin
mat := hmt.materials[i];
BlockWrite(f, mat.type_, 2);
BlockWrite(f, mat.tex_index, 2);
BlockWrite(f, mat.unknown_float1, 4);
BlockWrite(f, mat.unknown_float2, 4);
BlockWrite(f, zero, 4);
BlockWrite(f, mat.hex_a, 4);
BlockWrite(f, mat.name, 16);
end;
//textures
BlockWrite(f, hmt.texture_count, 4);
texdata_offset := FilePos(f) + hmt.texture_count * 52;
for i := 0 to hmt.texture_count - 1 do begin
tex := hmt.textures[i];
k := texdata_offset + 16;
BlockWrite(f, k, 4);
for k := 1 to 7 do
BlockWrite(f, zero, 4);
BlockWrite(f, zero, 4); //palette offset, 0 = no palette
BlockWrite(f, texdata_offset, 4); //texname offset
BlockWrite(f, tex.width, 2);
BlockWrite(f, tex.height, 2);
//format
texformat[0] := 1; //1?
texformat[1] := 0; //?
texformat[2] := 4; //subtype
texformat[3] := $40; //?
BlockWrite(f, texformat, 4);
alpha := $80808080;
BlockWrite(f, alpha, 4); //4B RGBA transparent color?
// texdata_offset += pixsize;
end;
//texdata
for i := 0 to hmt.texture_count - 1 do begin
tex := hmt.textures[i];
BlockWrite(f, tex.name, 16);
BlockWrite(f, tex.image.pixels^, tex.width * tex.height div 2);
end;
Closefile(f);
end;
const
mats: array[0..12] of string[16] = (
'mat_0',
'tie_hull_bk',
'tie_hatch_top',
'tie_hull_frt',
'tie_wingdet',
'arm_frt',
'tie_wing',
'mat_7',
'tie_hull_bk_lod',
'tie_hull_frt_lo',
'tie_wing_lod',
'mat_11',
'mat_12'
);
var
i: integer;
begin
hmt.material_count := 0;
hmt.texture_count := 0;
for i := 0 to 12 do
HmtAddMaterial(mats[i]);
HmtAddTexture('tie_wing.pgm', 'tie_wing');
WriteHmt('tiefighter.HMT');
end.

View File

@ -9,7 +9,8 @@ uses
type
THmtMaterial = record
type1, type2: shortint;
type_: shortint;
tex_index: shortint;
unknown_float1, unknown_float2: single;
zero: integer;
hex_a: integer;
@ -118,8 +119,8 @@ end;
procedure ReadMaterial(var mat: THmtMaterial; var f: TMemoryStream);
begin
mat.type1 := f.ReadWord;
mat.type2 := f.ReadWord;
mat.type_ := f.ReadWord;
mat.tex_index := f.ReadWord;
mat.unknown_float1 := f.ReadDWord;
mat.unknown_float2 := f.ReadDWord;
mat.zero := f.ReadDWord;
@ -129,6 +130,8 @@ begin
writeln(NameToString(mat.name));
if (mat.zero <> 0) or (mat.hex_a <> $A) then
writeln('unusual file');
writeln(' type1: ', mat.type_);
writeln(' type2: ', mat.tex_index);
end;