mirror of
https://github.com/dpethes/rerogue.git
synced 2025-06-07 18:58:32 +02:00
add hmt compiler to build custom tiefigher_HMT
This commit is contained in:
parent
eaa10cba3c
commit
acf9b6ebca
@ -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).
|
* Image exporter - exports some images to pnm/pgm/tga files (according to their internal format).
|
||||||
* HOB parser - parses mesh data files.
|
* HOB parser - parses mesh data files.
|
||||||
* HMT parser - parses material data files and exports stored textures.
|
* 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.
|
* HOB display - utilizes HOB & HMT parsers to view 3d objects used in game. Uses OpenGL and SDL for display & input handling.
|
||||||
|
|
||||||
Compilation
|
Compilation
|
||||||
@ -20,6 +21,7 @@ TODO
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
* hmt parser: decode all image subtypes
|
* hmt parser: decode all image subtypes
|
||||||
|
* hmt compiler: needs some usable interface
|
||||||
* hob parser: parse more header fields
|
* hob parser: parse more header fields
|
||||||
* mesh viewer: reuse hmt & hob parsers to display data
|
* mesh viewer: reuse hmt & hob parsers to display data
|
||||||
* bundle repack: extract & compile bundle.00x archives
|
* bundle repack: extract & compile bundle.00x archives
|
||||||
|
71
hmt_compiler/hmt_compiler.lpi
Normal file
71
hmt_compiler/hmt_compiler.lpi
Normal 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>
|
203
hmt_compiler/hmt_compiler.lpr
Normal file
203
hmt_compiler/hmt_compiler.lpr
Normal 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.
|
||||||
|
|
@ -9,7 +9,8 @@ uses
|
|||||||
|
|
||||||
type
|
type
|
||||||
THmtMaterial = record
|
THmtMaterial = record
|
||||||
type1, type2: shortint;
|
type_: shortint;
|
||||||
|
tex_index: shortint;
|
||||||
unknown_float1, unknown_float2: single;
|
unknown_float1, unknown_float2: single;
|
||||||
zero: integer;
|
zero: integer;
|
||||||
hex_a: integer;
|
hex_a: integer;
|
||||||
@ -118,8 +119,8 @@ end;
|
|||||||
|
|
||||||
procedure ReadMaterial(var mat: THmtMaterial; var f: TMemoryStream);
|
procedure ReadMaterial(var mat: THmtMaterial; var f: TMemoryStream);
|
||||||
begin
|
begin
|
||||||
mat.type1 := f.ReadWord;
|
mat.type_ := f.ReadWord;
|
||||||
mat.type2 := f.ReadWord;
|
mat.tex_index := f.ReadWord;
|
||||||
mat.unknown_float1 := f.ReadDWord;
|
mat.unknown_float1 := f.ReadDWord;
|
||||||
mat.unknown_float2 := f.ReadDWord;
|
mat.unknown_float2 := f.ReadDWord;
|
||||||
mat.zero := f.ReadDWord;
|
mat.zero := f.ReadDWord;
|
||||||
@ -129,6 +130,8 @@ begin
|
|||||||
writeln(NameToString(mat.name));
|
writeln(NameToString(mat.name));
|
||||||
if (mat.zero <> 0) or (mat.hex_a <> $A) then
|
if (mat.zero <> 0) or (mat.hex_a <> $A) then
|
||||||
writeln('unusual file');
|
writeln('unusual file');
|
||||||
|
writeln(' type1: ', mat.type_);
|
||||||
|
writeln(' type2: ', mat.tex_index);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user