mirror of
https://github.com/dpethes/rerogue.git
synced 2025-06-07 18:58:32 +02:00
terrain viewer: load directly from dat
This commit is contained in:
parent
6ea0ea6a1a
commit
a6a79620b4
@ -5,7 +5,7 @@ unit rs_world;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
Classes, SysUtils, gvector, rs_dat;
|
||||
|
||||
const
|
||||
TEX_WIDTH = 64;
|
||||
@ -37,6 +37,15 @@ type
|
||||
texture_index_map: array of integer;
|
||||
end;
|
||||
|
||||
TLevelListItem = record
|
||||
name: string;
|
||||
hmp: PRsDatFileNode;
|
||||
texture: PRsDatFileNode;
|
||||
texture_index: PRsDatFileNode;
|
||||
end;
|
||||
TLevelList = specialize TVector<TLevelListItem>;
|
||||
|
||||
|
||||
{ TWorld }
|
||||
|
||||
TWorld = class
|
||||
@ -44,8 +53,8 @@ type
|
||||
world_texture: pbyte;
|
||||
height_texture: pbyte;
|
||||
|
||||
procedure LoadTextures(const tex_fname, texidx_fname: string);
|
||||
procedure LoadHeightmap(fname: string);
|
||||
procedure LoadTextures(tex_node, texindex_node: PRsDatFileNode);
|
||||
procedure LoadHeightmap(node: PRsDatFileNode);
|
||||
|
||||
public
|
||||
heightmap: THeightmap;
|
||||
@ -54,7 +63,7 @@ type
|
||||
property TileWidth: word read heightmap.width;
|
||||
property TileHeight: word read heightmap.height;
|
||||
|
||||
procedure LoadFromFiles(const hmp, tex, texmap: string);
|
||||
procedure LoadFromNodes(level: TLevelListItem);
|
||||
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -135,9 +144,9 @@ end;
|
||||
|
||||
{ TWorld }
|
||||
|
||||
procedure TWorld.LoadTextures(const tex_fname, texidx_fname: string);
|
||||
procedure TWorld.LoadTextures(tex_node, texindex_node: PRsDatFileNode);
|
||||
var
|
||||
f: file;
|
||||
f: TMemoryStream;
|
||||
buf: pbyte;
|
||||
tex_size: integer;
|
||||
i: Integer;
|
||||
@ -146,12 +155,13 @@ var
|
||||
palette_size: Integer;
|
||||
texture_count: integer;
|
||||
begin
|
||||
AssignFile(f, tex_fname);
|
||||
reset(f, 1);
|
||||
f := TMemoryStream.Create;
|
||||
f.WriteBuffer(tex_node^.Data^, tex_node^.size);
|
||||
f.Seek(0, soBeginning);
|
||||
|
||||
palette_size := 48; //16x RGB
|
||||
tex_size := TEX_WIDTH * TEX_HEIGHT div 2;
|
||||
texture_count := filesize(f) div (tex_size + palette_size);
|
||||
texture_count := f.Size div (tex_size + palette_size);
|
||||
//writeln('texture_count: ', texture_count);
|
||||
|
||||
SetLength(heightmap.textures, texture_count);
|
||||
@ -160,27 +170,28 @@ begin
|
||||
buf := getmem(tex_size);
|
||||
for i := 0 to texture_count - 1 do begin
|
||||
image := getmem(TEX_WIDTH * TEX_HEIGHT * 3);
|
||||
Blockread(f, buf^, tex_size);
|
||||
Blockread(f, palette, palette_size);
|
||||
f.Read(buf^, tex_size);
|
||||
f.Read(palette, palette_size);
|
||||
convert_4bit_to_24bit(buf, TEX_WIDTH, TEX_HEIGHT, image, palette);
|
||||
heightmap.textures[i] := image;
|
||||
end;
|
||||
freemem(buf);
|
||||
CloseFile(f);
|
||||
f.Free;
|
||||
|
||||
AssignFile(f, texidx_fname);
|
||||
Reset(f, 1);
|
||||
f := TMemoryStream.Create;
|
||||
f.WriteBuffer(texindex_node^.Data^, texindex_node^.size);
|
||||
f.Seek(0, soBeginning);
|
||||
|
||||
texture_count := filesize(f) div 4 - 1;
|
||||
texture_count := f.Size div 4 - 1; //should match previous texture_count from texture atlas?
|
||||
SetLength(heightmap.texture_index_map, texture_count);
|
||||
Blockread(f, heightmap.texture_index_map[0], texture_count * 4);
|
||||
f.Read(heightmap.texture_index_map[0], texture_count * 4);
|
||||
|
||||
CloseFile(f);
|
||||
f.Free;
|
||||
end;
|
||||
|
||||
procedure TWorld.LoadHeightmap(fname: string);
|
||||
procedure TWorld.LoadHeightmap(node: PRsDatFileNode);
|
||||
var
|
||||
f: file;
|
||||
f: TMemoryStream;
|
||||
buffer: array[0..15] of byte;
|
||||
tile_offset: integer;
|
||||
blk: pword;
|
||||
@ -188,44 +199,45 @@ var
|
||||
tile_count: word;
|
||||
i: integer;
|
||||
begin
|
||||
AssignFile(f, fname);
|
||||
reset(f, 1);
|
||||
f := TMemoryStream.Create;
|
||||
f.WriteBuffer(node^.Data^, node^.size);
|
||||
f.Seek(0, soBeginning);
|
||||
|
||||
//header
|
||||
Blockread(f, buffer, 12);
|
||||
Blockread(f, buffer, 4);
|
||||
Blockread(f, heightmap.y_scale, 4);
|
||||
Blockread(f, buffer, 4);
|
||||
Blockread(f, tile_count, 2); //tile count
|
||||
Blockread(f, buffer, 2); //2B?
|
||||
Blockread(f, tile_offset, 4); //tile offset
|
||||
Blockread(f, buffer, 4); //offset?
|
||||
Blockread(f, heightmap.width, 2);
|
||||
Blockread(f, heightmap.height, 2);
|
||||
f.Read(buffer, 12);
|
||||
f.Read(buffer, 4);
|
||||
f.Read(heightmap.y_scale, 4); //float
|
||||
f.Read(buffer, 4);
|
||||
tile_count := f.ReadWord;
|
||||
f.Read(buffer, 2);
|
||||
tile_offset := f.ReadDWord;
|
||||
f.Read(buffer, 4);
|
||||
heightmap.width := f.ReadWord;
|
||||
heightmap.height := f.ReadWord;
|
||||
|
||||
//blocks / tile indices
|
||||
blk_size := heightmap.width * heightmap.height * 2;
|
||||
blk := getmem(blk_size);
|
||||
Blockread(f, blk^, blk_size);
|
||||
f.Read(blk^, blk_size);
|
||||
heightmap.blk := blk;
|
||||
|
||||
//tiles
|
||||
//writeln('filepos: ', FilePos(f)); writeln('tile pos: ', tile_offset);
|
||||
Seek(f, tile_offset);
|
||||
f.Seek(tile_offset, soBeginning);
|
||||
heightmap.tile_count := tile_count;
|
||||
heightmap.tiles := getmem(tile_count * 30);
|
||||
for i := 0 to tile_count - 1 do
|
||||
Blockread(f, heightmap.tiles[i], 30);
|
||||
f.Read(heightmap.tiles[i], 30);
|
||||
|
||||
CloseFile(f);
|
||||
f.Free;
|
||||
end;
|
||||
|
||||
procedure TWorld.LoadFromFiles(const hmp, tex, texmap: string);
|
||||
procedure TWorld.LoadFromNodes(level: TLevelListItem);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
LoadHeightmap(hmp);
|
||||
LoadTextures(tex, texmap);
|
||||
LoadHeightmap(level.hmp);
|
||||
LoadTextures(level.texture, level.texture_index);
|
||||
for i := 0 to heightmap.tile_count - 1 do begin
|
||||
heightmap.tiles[i].texture_index := heightmap.texture_index_map[heightmap.tiles[i].texture_index];
|
||||
end;
|
||||
|
@ -48,7 +48,7 @@ type
|
||||
procedure InitBlockStaticData;
|
||||
public
|
||||
destructor Destroy; override;
|
||||
procedure Load(level_idx: integer);
|
||||
procedure Load(level: TLevelListItem);
|
||||
procedure InitGL;
|
||||
procedure DrawGL(opts: TRenderOpts);
|
||||
end;
|
||||
@ -78,6 +78,7 @@ const
|
||||
h_scale = 0.5;
|
||||
var
|
||||
x, y, idx: integer;
|
||||
vx, vy, vz: single;
|
||||
v_scale: single;
|
||||
begin
|
||||
result.texture_index := tile.texture_index;
|
||||
@ -88,11 +89,11 @@ begin
|
||||
for y := 0 to 4 do
|
||||
for x := 0 to 4 do begin
|
||||
idx := y * 5 + x;
|
||||
result.vertices[idx].init( //x,y,z, rotated by 180 around z
|
||||
(basex + x) * h_scale * -1,
|
||||
tile.heights[idx] * v_scale * -1,
|
||||
(basey + y) * h_scale
|
||||
);
|
||||
//x,y,z, rotated by 180 around z
|
||||
vx := (basex + x) * h_scale * -1;
|
||||
vy := tile.heights[idx] * v_scale * -1;
|
||||
vz := (basey + y) * h_scale;
|
||||
result.vertices[idx].init(vx, vy, vz);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -186,19 +187,10 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TTerrainMesh.Load(level_idx: integer);
|
||||
const
|
||||
LevelIds = '0123456789abcdefgh';
|
||||
var
|
||||
c: char;
|
||||
procedure TTerrainMesh.Load(level: TLevelListItem);
|
||||
begin
|
||||
terrain := TWorld.Create;
|
||||
level_idx := level_idx mod length(LevelIds);
|
||||
c := LevelIds[1 + level_idx];
|
||||
terrain.LoadFromFiles(
|
||||
'data\hmp_' + c,
|
||||
'data\lv_'+c+'.text',
|
||||
'data\lv_'+c+'.tex');
|
||||
terrain.LoadFromNodes(level);
|
||||
TransformTiles;
|
||||
InitBlockStaticData;
|
||||
WriteLn(Format('terrain size: %dx%d, tris: %d',
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="9"/>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
@ -17,9 +17,6 @@
|
||||
<i18n>
|
||||
<EnableI18N LFM="False"/>
|
||||
</i18n>
|
||||
<VersionInfo>
|
||||
<StringTable ProductVersion=""/>
|
||||
</VersionInfo>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
</BuildModes>
|
||||
@ -28,36 +25,43 @@
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
<CommandLineParams Value="1"/>
|
||||
</local>
|
||||
<FormatVersion Value="2"/>
|
||||
<Modes Count="1">
|
||||
<Mode0 Name="default">
|
||||
<local>
|
||||
<CommandLineParams Value="1"/>
|
||||
</local>
|
||||
</Mode0>
|
||||
</Modes>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="4">
|
||||
<Units Count="5">
|
||||
<Unit0>
|
||||
<Filename Value="terrain_viewer.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="terrain_viewer"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="terrain_mesh.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="terrain_mesh"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="rs_world.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="rs_world"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="vector_util.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="vector_util"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="..\rs_units\rs_dat.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit4>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
@ -68,11 +72,9 @@
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value="..\rs_units"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Other>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="2">
|
||||
|
@ -22,7 +22,7 @@ program terrain_viewer;
|
||||
uses
|
||||
sysutils, math,
|
||||
gl, glu, glext, sdl,
|
||||
terrain_mesh;
|
||||
terrain_mesh, rs_dat, rs_world;
|
||||
|
||||
const
|
||||
SCR_W_fscrn = 1024;
|
||||
@ -37,6 +37,9 @@ const
|
||||
MouseTranslateMultiply = 0.025;
|
||||
|
||||
var
|
||||
g_rsdata: TRSDatFile;
|
||||
g_levels: TLevelList;
|
||||
|
||||
surface: PSDL_Surface;
|
||||
done,
|
||||
fullscreen: boolean;
|
||||
@ -298,19 +301,68 @@ begin
|
||||
end; {case}
|
||||
end;
|
||||
|
||||
//we only care about HOB and HMT files
|
||||
procedure LoadLevelFilelist;
|
||||
procedure AddFile(const map, level: PRsDatFileNode);
|
||||
var
|
||||
item: TLevelListItem;
|
||||
fnode: PRsDatFileNode;
|
||||
begin
|
||||
item.name := map^.Name; //lv_0
|
||||
for fnode in map^.nodes do
|
||||
if fnode^.name = 'hmp' then
|
||||
item.hmp := fnode;
|
||||
for fnode in level^.nodes do begin
|
||||
if fnode^.name = item.name + '_TEX' then //lv_0_TEX
|
||||
item.texture_index := fnode;
|
||||
if fnode^.name = item.name + '_TEXT' then //lv_0_TEXT
|
||||
item.texture := fnode;
|
||||
end;
|
||||
g_levels.PushBack(item);
|
||||
end;
|
||||
var
|
||||
rs_files: TRsDatFileNodeList;
|
||||
fnode: TRsDatFileNode;
|
||||
data_dir, level_dir, map_dir: PRsDatFileNode;
|
||||
begin
|
||||
//go to data/level/
|
||||
rs_files := g_rsdata.GetStructure();
|
||||
for fnode in rs_files do begin
|
||||
if fnode.is_directory and (fnode.Name = 'data') then begin
|
||||
data_dir := @fnode;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
Assert(data_dir <> nil);
|
||||
for level_dir in data_dir^.nodes do begin
|
||||
if level_dir^.is_directory and (level_dir^.Name = 'level') then
|
||||
break;
|
||||
end;
|
||||
Assert(level_dir <> nil);
|
||||
|
||||
for map_dir in level_dir^.nodes do
|
||||
if map_dir^.is_directory then
|
||||
AddFile(map_dir, level_dir);
|
||||
end;
|
||||
|
||||
//******************************************************************************
|
||||
var
|
||||
sec, frames: integer;
|
||||
in_file: integer;
|
||||
|
||||
begin
|
||||
if Paramcount < 1 then begin
|
||||
writeln('specify HMP file index');
|
||||
if not (FileExists(RS_DATA_HDR) and FileExists(RS_DATA_DAT)) then begin
|
||||
writeln('RS data files not found!');
|
||||
exit;
|
||||
end;
|
||||
in_file := StrToInt( ParamStr(1) );
|
||||
|
||||
writeln('loading data');
|
||||
g_rsdata := TRSDatFile.Create(RS_DATA_HDR, RS_DATA_DAT);
|
||||
g_rsdata.Parse();
|
||||
g_levels := TLevelList.Create;
|
||||
LoadLevelFilelist;
|
||||
|
||||
terrain := TTerrainMesh.Create;
|
||||
terrain.Load(14);
|
||||
terrain.Load(g_levels[0]);
|
||||
|
||||
writeln('Init SDL...');
|
||||
SDL_Init( SDL_INIT_VIDEO );
|
||||
@ -343,5 +395,7 @@ begin
|
||||
|
||||
terrain.Free;
|
||||
SDL_Quit;
|
||||
g_levels.Free;
|
||||
g_rsdata.Free;
|
||||
end.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user